From f6fb7f61bf506d9b9270999216af87ff947b443c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:00:21 +0000 Subject: [PATCH 1/9] Initial plan From c8a6632b3b816d0416d30ba180ca5b608885d30a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:18:07 +0000 Subject: [PATCH 2/9] Add 8 comprehensive guide files for dhamps-vdb features Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- .gitmodules | 3 + docs/.hugo_build.lock | 0 docs/archetypes/default.md | 5 + docs/config.toml | 9 + docs/content/_index.md | 54 + docs/content/api/_index.md | 39 + docs/content/api/endpoints/_index.md | 41 + docs/content/concepts/_index.md | 24 + docs/content/concepts/architecture.md | 341 +++ docs/content/concepts/embeddings.md | 466 +++ docs/content/concepts/llm-services.md | 428 +++ docs/content/concepts/metadata.md | 552 ++++ docs/content/concepts/projects.md | 439 +++ docs/content/concepts/similarity-search.md | 445 +++ docs/content/concepts/users-and-auth.md | 368 +++ docs/content/deployment/_index.md | 35 + docs/content/development/_index.md | 47 + docs/content/getting-started/_index.md | 31 + docs/content/getting-started/configuration.md | 156 + docs/content/getting-started/docker.md | 537 ++++ docs/content/getting-started/first-project.md | 415 +++ docs/content/getting-started/installation.md | 129 + docs/content/getting-started/quick-start.md | 292 ++ docs/content/guides/_index.md | 23 + docs/content/guides/batch-operations.md | 718 +++++ docs/content/guides/instance-management.md | 634 ++++ docs/content/guides/metadata-filtering.md | 468 +++ docs/content/guides/metadata-validation.md | 665 +++++ docs/content/guides/ownership-transfer.md | 406 +++ docs/content/guides/project-sharing.md | 333 +++ docs/content/guides/public-projects.md | 420 +++ docs/content/guides/rag-workflow.md | 393 +++ docs/content/reference/_index.md | 20 + docs/public/404.html | 4 + docs/public/asciinema/asciinema-auto.js | 7 + docs/public/asciinema/asciinema-player.css | 2389 +++++++++++++++ docs/public/asciinema/asciinema-player.min.js | 1 + ...87344917b325208841feca0968fe450f570575.css | 1 + docs/public/categories/index.html | 3 + docs/public/categories/index.xml | 1 + ...ecbe5ed12ab4d8e11ba873c2f11161202b945.json | 1 + ...4c0460e5894c72e7286c511967078b24f321f5e.js | 1 + docs/public/favicon.png | Bin 0 -> 298 bytes docs/public/favicon.svg | 1 + docs/public/fuse.min.js | 9 + docs/public/icons/menu.svg | 1 + docs/public/index.html | 3 + docs/public/index.xml | 1 + docs/public/katex/auto-render.min.js | 1 + docs/public/katex/fonts/KaTeX_AMS-Regular.ttf | Bin 0 -> 63632 bytes .../public/katex/fonts/KaTeX_AMS-Regular.woff | Bin 0 -> 33516 bytes .../katex/fonts/KaTeX_AMS-Regular.woff2 | Bin 0 -> 28076 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.ttf | Bin 0 -> 12368 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.woff | Bin 0 -> 7716 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.woff2 | Bin 0 -> 6912 bytes .../katex/fonts/KaTeX_Caligraphic-Regular.ttf | Bin 0 -> 12344 bytes .../fonts/KaTeX_Caligraphic-Regular.woff | Bin 0 -> 7656 bytes .../fonts/KaTeX_Caligraphic-Regular.woff2 | Bin 0 -> 6908 bytes .../public/katex/fonts/KaTeX_Fraktur-Bold.ttf | Bin 0 -> 19584 bytes .../katex/fonts/KaTeX_Fraktur-Bold.woff | Bin 0 -> 13296 bytes .../katex/fonts/KaTeX_Fraktur-Bold.woff2 | Bin 0 -> 11348 bytes .../katex/fonts/KaTeX_Fraktur-Regular.ttf | Bin 0 -> 19572 bytes .../katex/fonts/KaTeX_Fraktur-Regular.woff | Bin 0 -> 13208 bytes .../katex/fonts/KaTeX_Fraktur-Regular.woff2 | Bin 0 -> 11316 bytes docs/public/katex/fonts/KaTeX_Main-Bold.ttf | Bin 0 -> 51336 bytes docs/public/katex/fonts/KaTeX_Main-Bold.woff | Bin 0 -> 29912 bytes docs/public/katex/fonts/KaTeX_Main-Bold.woff2 | Bin 0 -> 25324 bytes .../katex/fonts/KaTeX_Main-BoldItalic.ttf | Bin 0 -> 32968 bytes .../katex/fonts/KaTeX_Main-BoldItalic.woff | Bin 0 -> 19412 bytes .../katex/fonts/KaTeX_Main-BoldItalic.woff2 | Bin 0 -> 16780 bytes docs/public/katex/fonts/KaTeX_Main-Italic.ttf | Bin 0 -> 33580 bytes .../public/katex/fonts/KaTeX_Main-Italic.woff | Bin 0 -> 19676 bytes .../katex/fonts/KaTeX_Main-Italic.woff2 | Bin 0 -> 16988 bytes .../public/katex/fonts/KaTeX_Main-Regular.ttf | Bin 0 -> 53580 bytes .../katex/fonts/KaTeX_Main-Regular.woff | Bin 0 -> 30772 bytes .../katex/fonts/KaTeX_Main-Regular.woff2 | Bin 0 -> 26272 bytes .../katex/fonts/KaTeX_Math-BoldItalic.ttf | Bin 0 -> 31196 bytes .../katex/fonts/KaTeX_Math-BoldItalic.woff | Bin 0 -> 18668 bytes .../katex/fonts/KaTeX_Math-BoldItalic.woff2 | Bin 0 -> 16400 bytes docs/public/katex/fonts/KaTeX_Math-Italic.ttf | Bin 0 -> 31308 bytes .../public/katex/fonts/KaTeX_Math-Italic.woff | Bin 0 -> 18748 bytes .../katex/fonts/KaTeX_Math-Italic.woff2 | Bin 0 -> 16440 bytes .../katex/fonts/KaTeX_SansSerif-Bold.ttf | Bin 0 -> 24504 bytes .../katex/fonts/KaTeX_SansSerif-Bold.woff | Bin 0 -> 14408 bytes .../katex/fonts/KaTeX_SansSerif-Bold.woff2 | Bin 0 -> 12216 bytes .../katex/fonts/KaTeX_SansSerif-Italic.ttf | Bin 0 -> 22364 bytes .../katex/fonts/KaTeX_SansSerif-Italic.woff | Bin 0 -> 14112 bytes .../katex/fonts/KaTeX_SansSerif-Italic.woff2 | Bin 0 -> 12028 bytes .../katex/fonts/KaTeX_SansSerif-Regular.ttf | Bin 0 -> 19436 bytes .../katex/fonts/KaTeX_SansSerif-Regular.woff | Bin 0 -> 12316 bytes .../katex/fonts/KaTeX_SansSerif-Regular.woff2 | Bin 0 -> 10344 bytes .../katex/fonts/KaTeX_Script-Regular.ttf | Bin 0 -> 16648 bytes .../katex/fonts/KaTeX_Script-Regular.woff | Bin 0 -> 10588 bytes .../katex/fonts/KaTeX_Script-Regular.woff2 | Bin 0 -> 9644 bytes .../katex/fonts/KaTeX_Size1-Regular.ttf | Bin 0 -> 12228 bytes .../katex/fonts/KaTeX_Size1-Regular.woff | Bin 0 -> 6496 bytes .../katex/fonts/KaTeX_Size1-Regular.woff2 | Bin 0 -> 5468 bytes .../katex/fonts/KaTeX_Size2-Regular.ttf | Bin 0 -> 11508 bytes .../katex/fonts/KaTeX_Size2-Regular.woff | Bin 0 -> 6188 bytes .../katex/fonts/KaTeX_Size2-Regular.woff2 | Bin 0 -> 5208 bytes .../katex/fonts/KaTeX_Size3-Regular.ttf | Bin 0 -> 7588 bytes .../katex/fonts/KaTeX_Size3-Regular.woff | Bin 0 -> 4420 bytes .../katex/fonts/KaTeX_Size3-Regular.woff2 | Bin 0 -> 3624 bytes .../katex/fonts/KaTeX_Size4-Regular.ttf | Bin 0 -> 10364 bytes .../katex/fonts/KaTeX_Size4-Regular.woff | Bin 0 -> 5980 bytes .../katex/fonts/KaTeX_Size4-Regular.woff2 | Bin 0 -> 4928 bytes .../katex/fonts/KaTeX_Typewriter-Regular.ttf | Bin 0 -> 27556 bytes .../katex/fonts/KaTeX_Typewriter-Regular.woff | Bin 0 -> 16028 bytes .../fonts/KaTeX_Typewriter-Regular.woff2 | Bin 0 -> 13568 bytes docs/public/katex/katex.min.css | 1 + docs/public/katex/katex.min.js | 1 + docs/public/manifest.json | 15 + docs/public/mermaid.min.js | 2659 +++++++++++++++++ docs/public/sitemap.xml | 1 + docs/public/tags/index.html | 3 + docs/public/tags/index.xml | 1 + ...s_b807c86e8030af4cdc30edccea379f5f.content | 1 + ...scss_b807c86e8030af4cdc30edccea379f5f.json | 1 + docs/themes/book | 1 + 119 files changed, 14044 insertions(+) create mode 100644 .gitmodules create mode 100644 docs/.hugo_build.lock create mode 100644 docs/archetypes/default.md create mode 100644 docs/config.toml create mode 100644 docs/content/_index.md create mode 100644 docs/content/api/_index.md create mode 100644 docs/content/api/endpoints/_index.md create mode 100644 docs/content/concepts/_index.md create mode 100644 docs/content/concepts/architecture.md create mode 100644 docs/content/concepts/embeddings.md create mode 100644 docs/content/concepts/llm-services.md create mode 100644 docs/content/concepts/metadata.md create mode 100644 docs/content/concepts/projects.md create mode 100644 docs/content/concepts/similarity-search.md create mode 100644 docs/content/concepts/users-and-auth.md create mode 100644 docs/content/deployment/_index.md create mode 100644 docs/content/development/_index.md create mode 100644 docs/content/getting-started/_index.md create mode 100644 docs/content/getting-started/configuration.md create mode 100644 docs/content/getting-started/docker.md create mode 100644 docs/content/getting-started/first-project.md create mode 100644 docs/content/getting-started/installation.md create mode 100644 docs/content/getting-started/quick-start.md create mode 100644 docs/content/guides/_index.md create mode 100644 docs/content/guides/batch-operations.md create mode 100644 docs/content/guides/instance-management.md create mode 100644 docs/content/guides/metadata-filtering.md create mode 100644 docs/content/guides/metadata-validation.md create mode 100644 docs/content/guides/ownership-transfer.md create mode 100644 docs/content/guides/project-sharing.md create mode 100644 docs/content/guides/public-projects.md create mode 100644 docs/content/guides/rag-workflow.md create mode 100644 docs/content/reference/_index.md create mode 100644 docs/public/404.html create mode 100644 docs/public/asciinema/asciinema-auto.js create mode 100644 docs/public/asciinema/asciinema-player.css create mode 100644 docs/public/asciinema/asciinema-player.min.js create mode 100644 docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css create mode 100644 docs/public/categories/index.html create mode 100644 docs/public/categories/index.xml create mode 100644 docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json create mode 100644 docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js create mode 100644 docs/public/favicon.png create mode 100644 docs/public/favicon.svg create mode 100644 docs/public/fuse.min.js create mode 100644 docs/public/icons/menu.svg create mode 100644 docs/public/index.html create mode 100644 docs/public/index.xml create mode 100644 docs/public/katex/auto-render.min.js create mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.woff create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.woff create mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff create mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.woff create mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff create mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.woff create mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.ttf create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.woff2 create mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf create mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff create mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff2 create mode 100644 docs/public/katex/katex.min.css create mode 100644 docs/public/katex/katex.min.js create mode 100644 docs/public/manifest.json create mode 100644 docs/public/mermaid.min.js create mode 100644 docs/public/sitemap.xml create mode 100644 docs/public/tags/index.html create mode 100644 docs/public/tags/index.xml create mode 100644 docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content create mode 100644 docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json create mode 160000 docs/themes/book diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6cb7e5c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "docs/themes/book"] + path = docs/themes/book + url = https://github.com/alex-shpak/hugo-book diff --git a/docs/.hugo_build.lock b/docs/.hugo_build.lock new file mode 100644 index 0000000..e69de29 diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md new file mode 100644 index 0000000..25b6752 --- /dev/null +++ b/docs/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +date = '{{ .Date }}' +draft = true +title = '{{ replace .File.ContentBaseName "-" " " | title }}' ++++ diff --git a/docs/config.toml b/docs/config.toml new file mode 100644 index 0000000..6b5d75c --- /dev/null +++ b/docs/config.toml @@ -0,0 +1,9 @@ +baseURL = 'https://mpilhlt.github.io/dhamps-vdb/' +languageCode = 'en-us' +title = 'dhamps-vdb Documentation' +theme = 'book' + +[params] + BookRepo = 'https://github.com/mpilhlt/dhamps-vdb' + BookEditPath = 'edit/main' + BookSearch = true diff --git a/docs/content/_index.md b/docs/content/_index.md new file mode 100644 index 0000000..62e336a --- /dev/null +++ b/docs/content/_index.md @@ -0,0 +1,54 @@ +--- +title: dhamps-vdb Documentation +type: docs +--- + +# dhamps-vdb Documentation + +Welcome to the documentation for **dhamps-vdb**, a vector database designed for Digital Humanities applications at the Max Planck Society initiative. + +## What is dhamps-vdb? + +dhamps-vdb is a PostgreSQL-backed vector database with pgvector support, providing a RESTful API for managing embeddings in Retrieval Augmented Generation (RAG) workflows. It offers multi-user support, project management, and flexible embedding configurations. + +## Key Features + +- **Multi-user Support**: Role-based access control (admin, owner, reader, editor) +- **Project Management**: Organize embeddings into projects with sharing capabilities +- **LLM Service Management**: Flexible service definitions and instances with encrypted API keys +- **Metadata Support**: JSON Schema validation and filtering in similarity search +- **PostgreSQL Backend**: Reliable storage with pgvector extension +- **RESTful API**: OpenAPI-documented endpoints +- **Docker Ready**: Easy deployment with Docker Compose + +## Quick Links + +- [Getting Started](/getting-started/) - Installation and first steps +- [Concepts](/concepts/) - Understand how dhamps-vdb works +- [API Reference](/api/) - Complete API documentation +- [Guides](/guides/) - How-to guides for common tasks + +## Getting Help + +- 📖 Browse this documentation +- 🐛 [Report issues](https://github.com/mpilhlt/dhamps-vdb/issues) +- 💬 [GitHub Discussions](https://github.com/mpilhlt/dhamps-vdb/discussions) + +## Quick Example + +```bash +# Start the service with Docker +./docker-setup.sh +docker-compose up -d + +# Create a user +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{"user_handle": "alice", "name": "Alice Smith"}' + +# Create a project and start working with embeddings +# See the Getting Started guide for a complete walkthrough +``` + +Ready to get started? Head over to the [Installation Guide](/getting-started/installation/). diff --git a/docs/content/api/_index.md b/docs/content/api/_index.md new file mode 100644 index 0000000..5930d11 --- /dev/null +++ b/docs/content/api/_index.md @@ -0,0 +1,39 @@ +--- +title: "API Reference" +weight: 4 +--- + +# API Reference + +Complete reference for the dhamps-vdb REST API. + +## API Version + +Current version: **v1** + +All endpoints are prefixed with `/v1/` (e.g., `POST /v1/embeddings/{user}/{project}`). + +## API Documentation + +The complete, always up-to-date API specification is available at: + +- **OpenAPI YAML**: `/openapi.yaml` +- **Interactive Documentation**: `/docs` + +## Reference Sections + +- [Authentication](authentication/) - API key authentication +- [Endpoints](endpoints/) - All available API endpoints +- [Query Parameters](query-parameters/) - Filtering and pagination +- [PATCH Updates](patch-updates/) - Partial resource updates +- [Error Handling](error-handling/) - Error responses and codes + +## Quick Example + +```bash +# Authenticate with API key +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer your_api_key_here" +``` + +All API requests require authentication except for public project read operations. diff --git a/docs/content/api/endpoints/_index.md b/docs/content/api/endpoints/_index.md new file mode 100644 index 0000000..f7a9d92 --- /dev/null +++ b/docs/content/api/endpoints/_index.md @@ -0,0 +1,41 @@ +--- +title: "Endpoints" +weight: 1 +--- + +# API Endpoints + +Complete reference for all dhamps-vdb API endpoints. + +## Endpoint Categories + +- [Users](users/) - User management +- [Projects](projects/) - Project operations +- [LLM Services](llm-services/) - LLM service instances +- [API Standards](api-standards/) - API standard definitions +- [Embeddings](embeddings/) - Embedding storage and retrieval +- [Similars](similars/) - Similarity search + +## Endpoint Format + +All endpoints follow the pattern: + +``` +{METHOD} /v1/{resource}/{user}/{identifier} +``` + +Where: +- `METHOD`: HTTP method (GET, POST, PUT, DELETE, PATCH) +- `resource`: Resource type (users, projects, embeddings, etc.) +- `user`: User handle (owner of the resource) +- `identifier`: Specific resource identifier + +## Authentication + +Most endpoints require authentication via the `Authorization` header: + +``` +Authorization: Bearer your_api_key_here +``` + +Public projects allow unauthenticated access to read operations. diff --git a/docs/content/concepts/_index.md b/docs/content/concepts/_index.md new file mode 100644 index 0000000..9d49ae0 --- /dev/null +++ b/docs/content/concepts/_index.md @@ -0,0 +1,24 @@ +--- +title: "Concepts" +weight: 2 +--- + +# Core Concepts + +Understanding the key concepts behind dhamps-vdb helps you make the most of its features. This section explains the fundamental building blocks and how they work together. + +## Overview + +dhamps-vdb is a vector database designed for Retrieval Augmented Generation (RAG) workflows. It stores embeddings with metadata and provides fast similarity search capabilities. + +## Key Components + +- **Users** - Individual accounts with authentication +- **Projects** - Containers for embeddings with access control +- **Embeddings** - Vector representations of text with metadata +- **LLM Services** - Configurations for embedding models +- **Similarity Search** - Find similar documents using vector distance + +## Architecture + +dhamps-vdb uses PostgreSQL with the pgvector extension for vector operations. It provides a RESTful API with token-based authentication and supports multi-user environments with project sharing. diff --git a/docs/content/concepts/architecture.md b/docs/content/concepts/architecture.md new file mode 100644 index 0000000..1151663 --- /dev/null +++ b/docs/content/concepts/architecture.md @@ -0,0 +1,341 @@ +--- +title: "Architecture" +weight: 1 +--- + +# Architecture + +dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research. + +## System Overview + +``` +┌─────────────┐ +│ Client │ +│ Application │ +└──────┬──────┘ + │ HTTP/REST + │ +┌──────▼──────────────────────────┐ +│ dhamps-vdb API Server │ +│ ┌──────────────────────────┐ │ +│ │ Authentication Layer │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Request Handlers │ │ +│ │ (Users, Projects, etc) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Validation Layer │ │ +│ │ (Dimensions, Metadata) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ SQLC Queries │ │ +│ │ (Type-safe SQL) │ │ +│ └────────┬─────────────────┘ │ +└───────────┼──────────────────────┘ + │ + ┌───────▼──────────────┐ + │ PostgreSQL + 16 │ + │ with pgvector 0.7 │ + │ │ + │ ┌────────────────┐ │ + │ │ Vector Index │ │ + │ │ (HNSW/IVFFlat) │ │ + │ └────────────────┘ │ + └──────────────────────┘ +``` + +## Core Components + +### API Layer + +Built with [Huma](https://huma.rocks/) framework on top of Go's `http.ServeMux`: + +- OpenAPI documentation generation +- Automatic request/response validation +- JSON schema support +- REST endpoint routing + +### Authentication + +Token-based authentication using API keys: + +- **Admin key**: For administrative operations (user creation, system management) +- **User keys**: SHA-256 hashed, unique per user +- **Bearer token**: Transmitted in `Authorization` header + +### Data Storage + +PostgreSQL with pgvector extension: + +- **Vector storage**: Native pgvector support for embeddings +- **Vector search**: Cosine similarity using `<=>` operator +- **ACID compliance**: Transactional consistency +- **Relational integrity**: Foreign keys and constraints + +### Code Generation + +Uses [sqlc](https://sqlc.dev/) for type-safe database queries: + +- SQL queries → Go functions +- Compile-time type checking +- No ORM overhead +- Direct PostgreSQL integration + +## Data Model + +### Core Entities + +``` +users + ├── projects (1:many) + │ ├── embeddings (1:many) + │ └── instance (1:1) + │ + └── instances (1:many) + └── definition (many:1, optional) + +_system (special user) + └── definitions (1:many) +``` + +### Key Relationships + +**Users → Projects** +- One user owns many projects +- Projects can be shared with other users (reader/editor roles) +- Projects can be public (unauthenticated read access) + +**Projects → Instances** +- Each project references exactly one LLM service instance +- Instance defines embedding dimensions and configuration + +**Projects → Embeddings** +- One project contains many embeddings +- Each embedding has a unique text_id within the project +- Embeddings store vector, metadata, and optional text + +**Users → Instances** +- Users own their instances +- Instances can be shared with other users +- Instances store encrypted API keys + +**Instances → Definitions** +- Instances can optionally reference a definition (template) +- System definitions (`_system` owner) provide defaults +- User definitions allow custom templates + +## Request Flow + +### 1. Create Embedding + +``` +Client Request + ↓ +Authentication Middleware + ↓ +Authorization Check (owner/editor?) + ↓ +Dimension Validation (vector_dim matches instance?) + ↓ +Metadata Validation (matches project schema?) + ↓ +Database Insert (with transaction) + ↓ +Response +``` + +### 2. Similarity Search + +``` +Client Request (text_id or vector) + ↓ +Authentication Middleware (or public check) + ↓ +Authorization Check (owner/reader/public?) + ↓ +Dimension Validation (if raw vector) + ↓ +Vector Similarity Query + ├── Cosine distance calculation + ├── Threshold filtering + ├── Metadata filtering (exclude matches) + └── Limit/offset pagination + ↓ +Results (sorted by similarity) + ↓ +Response +``` + +## Storage Architecture + +### Vector Index + +pgvector supports multiple index types: + +- **IVFFlat**: Faster build, approximate search +- **HNSW**: Slower build, better recall + +Current implementation uses HNSW for better accuracy. + +### Vector Storage Format + +```sql +CREATE TABLE embeddings ( + embedding_id SERIAL PRIMARY KEY, + text_id TEXT NOT NULL, + project_id INT REFERENCES projects, + vector vector(3072), -- Dimension varies + vector_dim INT NOT NULL, + metadata JSONB, + text TEXT, + ... +) +``` + +### Index Strategy + +```sql +CREATE INDEX embedding_vector_idx +ON embeddings +USING hnsw (vector vector_cosine_ops); +``` + +Optimized for cosine similarity searches. + +## Security Architecture + +### API Key Encryption + +- **Algorithm**: AES-256-GCM +- **Key Source**: `ENCRYPTION_KEY` environment variable +- **Key Derivation**: SHA-256 hash to ensure 32-byte key +- **Storage**: Binary (BYTEA) in database + +### Access Control + +**Three-tier access model:** + +1. **Owner**: Full control (read, write, delete, share, transfer) +2. **Editor**: Read and write embeddings +3. **Reader**: Read-only access to embeddings and search + +**Special access:** +- **Admin**: System-wide operations (user management, sanity checks) +- **Public**: Unauthenticated read access (if `public_read=true`) + +### Data Isolation + +- Users can only access their own resources or shared resources +- Cross-user queries are prevented at the database level +- Project ownership enforced via foreign keys + +## Migration System + +Uses [tern](https://github.com/jackc/tern) for database migrations: + +``` +migrations/ + ├── 001_create_initial_scheme.sql + ├── 002_create_emb_index.sql + ├── 003_add_public_read_flag.sql + └── 004_refactor_llm_services_architecture.sql +``` + +Migrations run automatically on startup with rollback support. + +## Performance Characteristics + +### Vector Search Performance + +- **Small datasets** (<10K embeddings): <10ms per query +- **Medium datasets** (10K-100K): 10-50ms per query +- **Large datasets** (>100K): 50-200ms per query + +Performance depends on: +- Vector dimensions +- Index type and parameters +- Hardware (CPU, RAM, disk) +- Number of results requested + +### Scaling Considerations + +**Vertical Scaling:** +- More RAM = faster searches (more vectors in memory) +- Faster CPUs = faster vector comparisons +- SSD storage = faster index scans + +**Horizontal Scaling:** +- Read replicas for search queries +- Separate write/read workloads +- Connection pooling for concurrent requests + +## Technology Stack + +### Core Technologies + +- **Language**: Go 1.21+ +- **Web Framework**: Huma 2.x +- **Database**: PostgreSQL 16+ +- **Vector Extension**: pgvector 0.7.4 +- **Query Generator**: sqlc 1.x +- **Migration Tool**: tern 2.x + +### Development Tools + +- **Testing**: Go standard library + testcontainers +- **Documentation**: OpenAPI 3.0 (auto-generated) +- **Building**: Docker multi-stage builds +- **Deployment**: Docker Compose + +## Design Principles + +### 1. Type Safety + +- sqlc generates type-safe Go code from SQL +- Strong typing prevents SQL injection +- Compile-time validation of queries + +### 2. Simplicity + +- REST API (not GraphQL) +- Straightforward URL patterns +- Standard HTTP methods + +### 3. Security + +- API key encryption at rest +- No API keys in responses +- Role-based access control + +### 4. Validation + +- Automatic dimension validation +- Optional metadata schema validation +- Request/response validation via OpenAPI + +### 5. Extensibility + +- User-defined metadata schemas +- Custom LLM service configurations +- Flexible sharing model + +## Limitations + +### Current Constraints + +- **No multi-tenancy**: Each installation is single-tenant +- **No replication**: Manual setup required for HA +- **No caching**: All queries hit database +- **Synchronous API**: No async/batch upload endpoints + +### Future Enhancements + +See [Roadmap](../../reference/roadmap/) for planned improvements. + +## Next Steps + +- [Learn about users and authentication](users-and-auth/) +- [Understand projects](projects/) +- [Explore LLM services](llm-services/) diff --git a/docs/content/concepts/embeddings.md b/docs/content/concepts/embeddings.md new file mode 100644 index 0000000..a2e057d --- /dev/null +++ b/docs/content/concepts/embeddings.md @@ -0,0 +1,466 @@ +--- +title: "Embeddings" +weight: 4 +--- + +# Embeddings + +Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval. + +## What are Embeddings? + +Embeddings are numerical representations (vectors) of text that capture semantic meaning: + +- **Vector**: Array of floating-point numbers (e.g., 1536 or 3072 dimensions) +- **Dimensions**: Fixed length determined by LLM model +- **Similarity**: Vectors of similar text are close in vector space +- **Purpose**: Enable semantic search and retrieval + +## Embedding Structure + +### Required Fields + +- **text_id**: Unique identifier for the document (max 300 characters) +- **instance_handle**: LLM service instance that generated the embedding +- **vector**: Array of float32 values (embedding vector) +- **vector_dim**: Declared dimension count (must match vector length) + +### Optional Fields + +- **text**: Original text content (for reference) +- **metadata**: Structured JSON data about the document + +### Example + +```json +{ + "text_id": "doc-123", + "instance_handle": "my-openai", + "text": "Introduction to machine learning concepts", + "vector": [0.023, -0.015, 0.087, ..., 0.042], + "vector_dim": 3072, + "metadata": { + "title": "ML Introduction", + "author": "Alice", + "year": 2024, + "category": "tutorial" + } +} +``` + +## Creating Embeddings + +### Single Embedding + +```bash +POST /v1/embeddings/alice/research-docs + +{ + "embeddings": [ + { + "text_id": "doc1", + "instance_handle": "my-openai", + "vector": [0.1, 0.2, ..., 0.3], + "vector_dim": 3072, + "metadata": {"author": "Alice"} + } + ] +} +``` + +### Batch Upload + +```bash +POST /v1/embeddings/alice/research-docs + +{ + "embeddings": [ + { + "text_id": "doc1", + "instance_handle": "my-openai", + "vector": [...], + "vector_dim": 3072 + }, + { + "text_id": "doc2", + "instance_handle": "my-openai", + "vector": [...], + "vector_dim": 3072 + }, + ... + ] +} +``` + +**Batch upload tips:** +- Upload 100-1000 embeddings per request +- Use consistent instance_handle +- Ensure all vectors have same dimensions +- Include metadata for searchability + +## Text Identifiers + +### Format + +Text IDs can be any string up to 300 characters: + +**Common patterns:** +- **URLs**: `https://id.example.com/doc/123` +- **URNs**: `urn:example:doc:123` +- **Paths**: `/corpus/section1/doc123` +- **IDs**: `doc-abc-123-xyz` + +### URL Encoding + +URL-encode text IDs when using them in API paths: + +```bash +# Original ID +text_id="https://id.example.com/texts/W0017:1.3.1" + +# URL-encoded for API +encoded="https%3A%2F%2Fid.example.com%2Ftexts%2FW0017%3A1.3.1" + +# Use in API call +GET /v1/embeddings/alice/project/$encoded +``` + +### Uniqueness + +Text IDs must be unique within a project: +- Same ID in different projects: ✅ Allowed +- Same ID twice in one project: ❌ Conflict error + +## Validation + +### Dimension Validation + +The system automatically validates vector dimensions: + +**Checks performed:** +1. `vector_dim` matches declared instance dimensions +2. Actual `vector` array length matches `vector_dim` +3. All embeddings in project have consistent dimensions + +**Example error:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'my-openai' expects 1536 dimensions" +} +``` + +### Metadata Validation + +If project has a metadata schema, all embeddings are validated: + +**Example error:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc1': metadata validation failed:\n - author is required\n - year must be integer" +} +``` + +See [Metadata Validation Guide](../guides/metadata-validation/) for details. + +## Retrieving Embeddings + +### List All Embeddings + +```bash +GET /v1/embeddings/alice/research-docs?limit=100&offset=0 +``` + +Returns paginated list of embeddings with: +- text_id +- metadata +- vector_dim +- created_at + +Vectors are included by default (can be large). + +### Get Single Embedding + +```bash +GET /v1/embeddings/alice/research-docs/doc1 +``` + +Returns complete embedding including vector. + +### Pagination + +Use `limit` and `offset` for large projects: + +```bash +# First page (0-99) +GET /v1/embeddings/alice/research-docs?limit=100&offset=0 + +# Second page (100-199) +GET /v1/embeddings/alice/research-docs?limit=100&offset=100 + +# Third page (200-299) +GET /v1/embeddings/alice/research-docs?limit=100&offset=200 +``` + +## Updating Embeddings + +Currently, embeddings cannot be updated directly. To modify: + +1. **Delete** existing embedding +2. **Upload** new version with same text_id + +```bash +# Delete old version +DELETE /v1/embeddings/alice/research-docs/doc1 + +# Upload new version +POST /v1/embeddings/alice/research-docs +{ + "embeddings": [{ + "text_id": "doc1", + "instance_handle": "my-openai", + "vector": [...new vector...], + "vector_dim": 3072, + "metadata": {...updated metadata...} + }] +} +``` + +## Deleting Embeddings + +### Delete Single Embedding + +```bash +DELETE /v1/embeddings/alice/research-docs/doc1 +``` + +### Delete All Embeddings + +```bash +DELETE /v1/embeddings/alice/research-docs +``` + +**Warning:** This deletes all embeddings in the project permanently. + +## Metadata + +### Purpose + +Metadata provides structured information about documents: + +- **Filtering**: Exclude documents in similarity searches +- **Organization**: Categorize and group documents +- **Context**: Store additional document information +- **Validation**: Ensure consistent structure (with schema) + +### Structure + +Metadata is stored as JSONB in PostgreSQL: + +```json +{ + "author": "William Shakespeare", + "title": "Hamlet", + "year": 1603, + "act": 1, + "scene": 1, + "genre": "drama", + "language": "English" +} +``` + +### Nested Metadata + +Complex structures are supported: + +```json +{ + "author": { + "name": "William Shakespeare", + "birth_year": 1564, + "nationality": "English" + }, + "publication": { + "year": 1603, + "publisher": "First Folio", + "edition": 1 + }, + "tags": ["tragedy", "revenge", "madness"] +} +``` + +### Filtering by Metadata + +Use metadata to exclude documents from similarity searches: + +```bash +# Exclude documents from same author +GET /v1/similars/alice/project/doc1?metadata_path=author&metadata_value=Shakespeare +``` + +See [Metadata Filtering Guide](../guides/metadata-filtering/) for details. + +## Storage Considerations + +### Vector Storage + +Vectors are stored using pgvector extension: + +- **Type**: `vector(N)` where N is dimension count +- **Size**: 4 bytes per dimension + overhead +- **Example**: 3072-dimension vector ≈ 12KB + +### Storage Calculation + +Estimate storage per embedding: + +``` +Vector: 4 bytes × dimensions +Text ID: length in bytes (avg ~50 bytes) +Text: length in bytes (optional) +Metadata: JSON size (varies, avg ~500 bytes) +Overhead: ~100 bytes (indexes, etc.) + +Example (3072-dim with metadata): +4 × 3072 + 50 + 500 + 100 ≈ 13KB per embedding +``` + +### Large Projects + +For projects with millions of embeddings: + +- Use pagination when listing +- Consider partial indexes for metadata +- Monitor database size +- Plan backup strategy + +## Performance + +### Upload Performance + +- **Small batches** (1-10): ~100ms per request +- **Medium batches** (100-500): ~500ms-2s per request +- **Large batches** (1000+): ~2-10s per request + +### Retrieval Performance + +- **Single embedding**: <10ms +- **Paginated list** (100 items): ~50ms +- **Large project scan**: Use pagination + +### Optimization Tips + +- Batch uploads when possible +- Use appropriate page sizes +- Include only needed fields +- Monitor query performance + +## Common Patterns + +### Document Chunking + +Split long documents into chunks: + +```json +{ + "embeddings": [ + { + "text_id": "doc1:chunk1", + "text": "First part of document...", + "vector": [...], + "metadata": {"doc_id": "doc1", "chunk": 1} + }, + { + "text_id": "doc1:chunk2", + "text": "Second part of document...", + "vector": [...], + "metadata": {"doc_id": "doc1", "chunk": 2} + } + ] +} +``` + +### Versioned Documents + +Track document versions: + +```json +{ + "text_id": "doc1:v2", + "vector": [...], + "metadata": { + "doc_id": "doc1", + "version": 2, + "updated_at": "2024-01-15T10:30:00Z" + } +} +``` + +### Multi-Language Documents + +Store embeddings for different languages: + +```json +{ + "embeddings": [ + { + "text_id": "doc1:en", + "text": "English version...", + "vector": [...], + "metadata": {"doc_id": "doc1", "language": "en"} + }, + { + "text_id": "doc1:de", + "text": "Deutsche Version...", + "vector": [...], + "metadata": {"doc_id": "doc1", "language": "de"} + } + ] +} +``` + +## Troubleshooting + +### Dimension Mismatch + +**Error**: "vector dimension mismatch" + +**Cause**: Vector dimensions don't match instance configuration + +**Solution**: +- Check instance dimensions: `GET /v1/llm-services/owner/instance` +- Regenerate embeddings with correct model +- Ensure `vector_dim` matches actual vector length + +### Metadata Validation Failed + +**Error**: "metadata validation failed" + +**Cause**: Metadata doesn't match project schema + +**Solution**: +- Check project schema: `GET /v1/projects/owner/project` +- Update metadata to match schema +- Or update schema to accept metadata + +### Text ID Conflict + +**Error**: "embedding with text_id already exists" + +**Cause**: Attempting to upload duplicate text_id + +**Solution**: +- Use different text_id +- Delete existing embedding first +- Check for unintended duplicates + +## Next Steps + +- [Learn about similarity search](similarity-search/) +- [Explore metadata filtering](../guides/metadata-filtering/) +- [Understand LLM services](llm-services/) diff --git a/docs/content/concepts/llm-services.md b/docs/content/concepts/llm-services.md new file mode 100644 index 0000000..d1c74b9 --- /dev/null +++ b/docs/content/concepts/llm-services.md @@ -0,0 +1,428 @@ +--- +title: "LLM Services" +weight: 5 +--- + +# LLM Services + +LLM Services configure embedding generation, defining models, dimensions, and API access. + +## Architecture + +dhamps-vdb separates LLM services into two concepts: + +### LLM Service Definitions + +Reusable configuration templates owned by `_system` or users: + +- **Purpose**: Provide standard configurations +- **Ownership**: `_system` (global) or individual users +- **Contents**: Endpoint, model, dimensions, API standard +- **API Keys**: Not stored (templates only) +- **Usage**: Templates for creating instances + +### LLM Service Instances + +User-specific configurations with encrypted API keys: + +- **Purpose**: Actual service configurations users employ +- **Ownership**: Individual users +- **Contents**: Endpoint, model, dimensions, API key (encrypted) +- **Sharing**: Can be shared with other users +- **Projects**: Each project references exactly one instance + +## System Definitions + +### Available Definitions + +The `_system` user provides default definitions: + +| Handle | Model | Dimensions | API Standard | +|--------|-------|------------|--------------| +| openai-large | text-embedding-3-large | 3072 | openai | +| openai-small | text-embedding-3-small | 1536 | openai | +| cohere-v4 | embed-multilingual-v4.0 | 1536 | cohere | +| gemini-embedding-001 | text-embedding-004 | 3072 | gemini | + +### Viewing System Definitions + +```bash +GET /v1/llm-services/_system +Authorization: Bearer user_vdb_key +``` + +Returns list of available system definitions. + +## Creating Instances + +### From System Definition + +Use a predefined system configuration: + +```bash +PUT /v1/llm-services/alice/my-openai + +{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "description": "My OpenAI embeddings", + "api_key_encrypted": "sk-proj-your-openai-key" +} +``` + +Inherits endpoint, model, dimensions from system definition. + +### From User Definition + +Reference a user-created definition: + +```bash +PUT /v1/llm-services/alice/custom-instance + +{ + "definition_owner": "alice", + "definition_handle": "my-custom-config", + "api_key_encrypted": "your-api-key" +} +``` + +### Standalone Instance + +Create without a definition: + +```bash +PUT /v1/llm-services/alice/standalone + +{ + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "Standalone OpenAI instance", + "api_key_encrypted": "sk-proj-your-key" +} +``` + +All fields must be specified. + +## Instance Properties + +### Core Fields + +- **instance_handle**: Unique identifier (3-20 characters) +- **owner**: User who owns the instance +- **endpoint**: API endpoint URL +- **api_standard**: Authentication mechanism (openai, cohere, gemini) +- **model**: Model identifier +- **dimensions**: Vector dimensionality +- **description**: Human-readable description (optional) +- **definition_id**: Reference to definition (optional) + +### API Key Storage + +- **Write-only**: Provided on create/update +- **Encrypted**: AES-256-GCM encryption +- **Never returned**: Not included in GET responses +- **Secure**: Cannot be retrieved after creation + +## API Standards + +### Supported Standards + +| Standard | Key Method | Documentation | +|----------|------------|---------------| +| openai | Authorization: Bearer | [OpenAI Docs](https://platform.openai.com/docs/api-reference/embeddings) | +| cohere | Authorization: Bearer | [Cohere Docs](https://docs.cohere.com/reference/embed) | +| gemini | x-goog-api-key header | [Gemini Docs](https://ai.google.dev/gemini-api/docs/embeddings) | + +### Creating API Standards + +Admins can add new standards: + +```bash +POST /v1/api-standards +Authorization: Bearer ADMIN_KEY + +{ + "api_standard_handle": "custom", + "description": "Custom LLM API", + "key_method": "auth_bearer", + "key_field": null +} +``` + +## Instance Management + +### List Instances + +List all accessible instances (owned + shared): + +```bash +GET /v1/llm-services/alice +Authorization: Bearer alice_vdb_key +``` + +Returns instances where alice is owner or has been granted access. + +### Get Instance Details + +```bash +GET /v1/llm-services/alice/my-openai +Authorization: Bearer alice_vdb_key +``` + +Returns instance configuration (API key not included). + +### Update Instance + +```bash +PATCH /v1/llm-services/alice/my-openai + +{ + "description": "Updated description", + "api_key_encrypted": "new-api-key" +} +``` + +Only owner can update instances. + +### Delete Instance + +```bash +DELETE /v1/llm-services/alice/my-openai +Authorization: Bearer alice_vdb_key +``` + +**Constraints:** +- Cannot delete instance used by projects +- Delete projects first, then instance + +## Instance Sharing + +### Share with User + +```bash +POST /v1/llm-services/alice/my-openai/share + +{ + "share_with_handle": "bob", + "role": "reader" +} +``` + +**Shared users can:** +- Use instance in their projects +- View instance configuration +- **Cannot:** + - See API key + - Modify instance + - Delete instance + +### Unshare from User + +```bash +DELETE /v1/llm-services/alice/my-openai/share/bob +``` + +### List Shared Users + +```bash +GET /v1/llm-services/alice/my-openai/shared-with +``` + +Only owner can view shared users. + +## Instance References + +### In Projects + +Projects reference instances by owner and handle: + +```json +{ + "project_handle": "my-project", + "instance_owner": "alice", + "instance_handle": "my-openai" +} +``` + +### In Embeddings + +Embeddings reference instances by handle: + +```json +{ + "text_id": "doc1", + "instance_handle": "my-openai", + "vector": [...] +} +``` + +The instance owner is inferred from the project. + +### Shared Instance Format + +When using shared instances: + +**Own instance**: `"instance_handle": "my-openai"` +**Shared instance**: Reference via project configuration + +## Encryption + +### API Key Encryption + +API keys are encrypted using AES-256-GCM: + +**Encryption process:** +1. User provides plaintext API key +2. Server encrypts using `ENCRYPTION_KEY` from environment +3. Encrypted bytes stored in database +4. Key derivation: SHA-256 hash ensures 32-byte key + +**Decryption:** +- Only occurs internally for LLM API calls +- Never exposed via API responses +- Requires same `ENCRYPTION_KEY` + +### Security Notes + +- **Encryption key**: Set via `ENCRYPTION_KEY` environment variable +- **Key loss**: Losing encryption key means losing access to API keys +- **Key rotation**: Not currently supported +- **Backup**: Back up encryption key securely + +## LLM Processing + +### Current Status + +LLM processing (generating embeddings) is **not yet implemented**. + +### Future Implementation + +Planned features: +- Process text to generate embeddings +- Call external LLM APIs +- Store generated embeddings +- Batch processing support + +### Current Workflow + +Users must generate embeddings externally: + +1. Generate embeddings using LLM API (OpenAI, Cohere, etc.) +2. Upload pre-generated embeddings to dhamps-vdb +3. Use dhamps-vdb for storage and similarity search + +## Common Patterns + +### Per-Environment Instances + +```bash +# Development instance +PUT /v1/llm-services/alice/dev-embeddings +{ + "definition_owner": "_system", + "definition_handle": "openai-small", + "api_key_encrypted": "dev-api-key" +} + +# Production instance +PUT /v1/llm-services/alice/prod-embeddings +{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "prod-api-key" +} +``` + +### Team Shared Instance + +```bash +# Owner creates instance +PUT /v1/llm-services/team-lead/team-embeddings +{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "team-api-key" +} + +# Share with team members +POST /v1/llm-services/team-lead/team-embeddings/share +{"share_with_handle": "member1", "role": "reader"} + +POST /v1/llm-services/team-lead/team-embeddings/share +{"share_with_handle": "member2", "role": "reader"} + +# Members use in their projects +POST /v1/projects/member1 +{ + "project_handle": "my-project", + "instance_owner": "team-lead", + "instance_handle": "team-embeddings" +} +``` + +### Multi-Model Setup + +```bash +# Large model for important documents +PUT /v1/llm-services/alice/high-quality +{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "api-key" +} + +# Small model for drafts +PUT /v1/llm-services/alice/fast-processing +{ + "definition_owner": "_system", + "definition_handle": "openai-small", + "api_key_encrypted": "api-key" +} +``` + +## Troubleshooting + +### Cannot Create Instance + +**Possible causes:** +- Instance handle already exists +- Referenced definition doesn't exist +- Missing required fields +- Invalid API standard + +**Solutions:** +- Choose different handle +- Verify definition: `GET /v1/llm-services/_system` +- Include all required fields +- Use valid API standard: `GET /v1/api-standards` + +### Cannot Use Instance in Project + +**Possible causes:** +- Instance doesn't exist +- Instance not owned or shared with user +- Incorrect owner/handle reference + +**Solutions:** +- Verify instance exists +- Check instance is accessible +- Confirm spelling of owner and handle + +### Dimension Mismatch + +**Error**: "dimension validation failed" + +**Cause**: Embedding dimensions don't match instance + +**Solutions:** +- Check instance dimensions +- Regenerate embeddings with correct model +- Create instance with correct dimensions + +## Next Steps + +- [Understand projects](projects/) +- [Learn about embeddings](embeddings/) +- [Explore instance management](../guides/instance-management/) diff --git a/docs/content/concepts/metadata.md b/docs/content/concepts/metadata.md new file mode 100644 index 0000000..36ddc48 --- /dev/null +++ b/docs/content/concepts/metadata.md @@ -0,0 +1,552 @@ +--- +title: "Metadata" +weight: 7 +--- + +# Metadata + +Structured JSON data attached to embeddings for organization, validation, and filtering. + +## Overview + +Metadata provides context and structure for your embeddings: + +- **Organization**: Categorize and group documents +- **Filtering**: Exclude documents in similarity searches +- **Validation**: Ensure consistent structure (optional) +- **Context**: Store additional document information + +## Metadata Structure + +### Format + +Metadata is JSON stored as JSONB in PostgreSQL: + +```json +{ + "author": "William Shakespeare", + "title": "Hamlet", + "year": 1603, + "genre": "drama" +} +``` + +### Types + +Supported JSON types: +- **String**: `"author": "Shakespeare"` +- **Number**: `"year": 1603` +- **Boolean**: `"published": true` +- **Array**: `"tags": ["tragedy", "revenge"]` +- **Object**: `"author": {"name": "...", "id": "..."}` +- **Null**: `"notes": null` + +### Nested Structure + +Complex hierarchies are supported: + +```json +{ + "document": { + "id": "W0017", + "type": "manuscript" + }, + "author": { + "name": "John Milton", + "birth_year": 1608, + "nationality": "English" + }, + "publication": { + "year": 1667, + "publisher": "First Edition", + "location": "London" + }, + "tags": ["poetry", "epic", "religious"] +} +``` + +## Metadata Schemas + +### Purpose + +JSON Schema validation ensures consistent metadata across all project embeddings. + +### Defining a Schema + +Include `metadataScheme` when creating/updating project: + +```bash +POST /v1/projects/alice + +{ + "project_handle": "research", + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}" +} +``` + +### Schema Format + +Use [JSON Schema](https://json-schema.org/) (draft-07+): + +```json +{ + "type": "object", + "properties": { + "author": { + "type": "string", + "minLength": 1 + }, + "year": { + "type": "integer", + "minimum": 1000, + "maximum": 2100 + }, + "genre": { + "type": "string", + "enum": ["poetry", "prose", "drama"] + } + }, + "required": ["author", "year"] +} +``` + +### Validation Behavior + +**With schema defined:** +- All embeddings validated on upload +- Invalid metadata rejected with detailed error +- Schema enforced consistently + +**Without schema:** +- Any JSON metadata accepted +- No validation performed +- Maximum flexibility + +### Common Patterns + +See [Metadata Validation Guide](../guides/metadata-validation/) for examples. + +## Using Metadata + +### On Upload + +Include metadata with each embedding: + +```bash +POST /v1/embeddings/alice/research + +{ + "embeddings": [ + { + "text_id": "doc1", + "instance_handle": "my-embeddings", + "vector": [...], + "metadata": { + "author": "Shakespeare", + "title": "Hamlet", + "year": 1603 + } + } + ] +} +``` + +### In Responses + +Metadata returned when retrieving embeddings: + +```bash +GET /v1/embeddings/alice/research/doc1 +``` + +```json +{ + "text_id": "doc1", + "metadata": { + "author": "Shakespeare", + "title": "Hamlet", + "year": 1603 + }, + "vector": [...], + ... +} +``` + +## Metadata Filtering + +### Exclusion Filter + +Exclude documents where metadata matches value: + +```bash +GET /v1/similars/alice/research/doc1?metadata_path=author&metadata_value=Shakespeare +``` + +**Result**: Returns similar documents **excluding** those with `metadata.author == "Shakespeare"`. + +### Path Syntax + +Use JSON path notation: + +**Simple field:** +``` +metadata_path=author +``` + +**Nested field:** +``` +metadata_path=author.name +``` + +**Array element** (not currently supported): +``` +metadata_path=tags[0] +``` + +### URL Encoding + +Encode special characters: + +```bash +# Space +metadata_value=John%20Doe + +# Quotes (if needed) +metadata_value=%22quoted%20value%22 +``` + +### Use Cases + +**Exclude same work:** +```bash +?metadata_path=title&metadata_value=Hamlet +``` + +**Exclude same author:** +```bash +?metadata_path=author&metadata_value=Shakespeare +``` + +**Exclude same source:** +```bash +?metadata_path=source_id&metadata_value=corpus-a +``` + +**Exclude same category:** +```bash +?metadata_path=category&metadata_value=draft +``` + +See [Metadata Filtering Guide](../guides/metadata-filtering/) for detailed examples. + +## Validation Examples + +### Simple Schema + +```json +{ + "type": "object", + "properties": { + "author": {"type": "string"}, + "year": {"type": "integer"} + }, + "required": ["author"] +} +``` + +**Valid metadata:** +```json +{"author": "Shakespeare", "year": 1603} +{"author": "Milton"} +``` + +**Invalid metadata:** +```json +{"year": 1603} // Missing required 'author' +{"author": 123} // Wrong type (should be string) +``` + +### Schema with Constraints + +```json +{ + "type": "object", + "properties": { + "title": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "rating": { + "type": "number", + "minimum": 0, + "maximum": 5 + }, + "tags": { + "type": "array", + "items": {"type": "string"}, + "minItems": 1, + "maxItems": 10 + } + } +} +``` + +### Schema with Enums + +```json +{ + "type": "object", + "properties": { + "language": { + "type": "string", + "enum": ["en", "de", "fr", "es", "la"] + }, + "status": { + "type": "string", + "enum": ["draft", "review", "published"] + } + } +} +``` + +## Storage and Performance + +### Storage + +Metadata stored as JSONB in PostgreSQL: + +- **Efficient**: Binary storage format +- **Indexable**: Can create indexes on fields +- **Queryable**: Use PostgreSQL JSON operators + +### Size Considerations + +Typical metadata sizes: + +- **Simple**: 50-200 bytes +- **Moderate**: 200-1000 bytes +- **Complex**: 1-5KB +- **Very large**: >5KB (consider storing elsewhere) + +### Performance + +**Metadata filtering:** +- JSONB queries are efficient +- Add indexes for frequently filtered fields +- Keep metadata reasonably sized + +**Example index (if needed):** +```sql +CREATE INDEX idx_embeddings_author +ON embeddings ((metadata->>'author')); +``` + +## Common Patterns + +### Document Provenance + +Track document source and history: + +```json +{ + "source": { + "corpus": "Shakespeare Works", + "collection": "Tragedies", + "document_id": "hamlet", + "version": 2 + }, + "imported_at": "2024-01-15T10:30:00Z", + "imported_by": "researcher1" +} +``` + +### Hierarchical Documents + +Structure for nested documents: + +```json +{ + "work": "Paradise Lost", + "book": 1, + "line": 1, + "chapter": null, + "section": "Invocation" +} +``` + +### Multi-Language Content + +Track language and translation info: + +```json +{ + "language": "en", + "original_language": "la", + "translated_by": "John Smith", + "translation_year": 1850 +} +``` + +### Research Metadata + +Academic paper metadata: + +```json +{ + "doi": "10.1234/example.2024.001", + "authors": ["Alice Smith", "Bob Jones"], + "journal": "Digital Humanities Review", + "year": 2024, + "keywords": ["NLP", "embeddings", "RAG"] +} +``` + +## Updating Metadata + +### Current Limitation + +Metadata cannot be updated directly. To change: + +1. Delete embedding +2. Re-upload with updated metadata + +```bash +# Delete +DELETE /v1/embeddings/alice/project/doc1 + +# Re-upload with new metadata +POST /v1/embeddings/alice/project +{ + "embeddings": [{ + "text_id": "doc1", + "metadata": {...updated...}, + ... + }] +} +``` + +## Schema Updates + +### Updating Project Schema + +Use PATCH to update schema: + +```bash +PATCH /v1/projects/alice/research + +{ + "metadataScheme": "{...new schema...}" +} +``` + +### Effect on Existing Embeddings + +- **Existing embeddings**: Not revalidated +- **New embeddings**: Validated against new schema +- **Updates**: Validated against current schema + +### Migration Strategy + +When updating schema: + +1. Update project schema +2. Verify new embeddings work +3. Optionally re-upload existing embeddings + +## Validation Errors + +### Common Errors + +**Missing required field:** +```json +{ + "status": 400, + "detail": "metadata validation failed: author is required" +} +``` + +**Wrong type:** +```json +{ + "status": 400, + "detail": "metadata validation failed: year must be integer" +} +``` + +**Enum violation:** +```json +{ + "status": 400, + "detail": "metadata validation failed: genre must be one of [poetry, prose, drama]" +} +``` + +### Debugging + +To debug validation errors: + +1. Check project schema: `GET /v1/projects/owner/project` +2. Validate metadata with online tool: [jsonschemavalidator.net](https://www.jsonschemavalidator.net/) +3. Review error message for specific field +4. Update metadata or schema as needed + +## Best Practices + +### Schema Design + +- Start simple, add complexity as needed +- Use required fields for critical data +- Use enums for controlled vocabularies +- Document your schema + +### Metadata Content + +- Keep metadata focused and relevant +- Avoid redundant data +- Use consistent field names +- Consider future queries and filters + +### Performance + +- Keep metadata reasonably sized (<5KB) +- Index frequently queried fields +- Avoid deeply nested structures when possible + +## Troubleshooting + +### Validation Fails + +**Problem**: Metadata doesn't validate + +**Solutions:** +- Check project schema +- Verify metadata structure +- Test with JSON Schema validator +- Review error message details + +### Filtering Not Working + +**Problem**: Metadata filter doesn't exclude documents + +**Solutions:** +- Verify field path is correct +- Check value matches exactly (case-sensitive) +- URL-encode special characters +- Confirm metadata field exists + +### Schema Too Restrictive + +**Problem**: Cannot upload valid documents + +**Solutions:** +- Make fields optional (remove from `required`) +- Broaden type constraints +- Use `oneOf` for multiple valid formats +- Remove unnecessary validations + +## Next Steps + +- [Learn about metadata validation](../guides/metadata-validation/) +- [Explore metadata filtering](../guides/metadata-filtering/) +- [Understand similarity search](similarity-search/) diff --git a/docs/content/concepts/projects.md b/docs/content/concepts/projects.md new file mode 100644 index 0000000..18fecb2 --- /dev/null +++ b/docs/content/concepts/projects.md @@ -0,0 +1,439 @@ +--- +title: "Projects" +weight: 3 +--- + +# Projects + +Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation. + +## What is a Project? + +A project is a collection of document embeddings that share: + +- A single LLM service instance (embedding configuration) +- Optional metadata schema for validation +- Access control (ownership and sharing) +- Consistent vector dimensions + +## Project Properties + +### Core Fields + +- **project_handle**: Unique identifier within owner's namespace (3-20 characters) +- **owner**: User who owns the project +- **description**: Human-readable project description +- **instance_id**: Reference to LLM service instance (required, 1:1 relationship) +- **metadataScheme**: Optional JSON Schema for metadata validation +- **public_read**: Boolean flag for public read access +- **created_at**: Creation timestamp +- **updated_at**: Last modification timestamp + +### Unique Constraints + +Projects are uniquely identified by `(owner, project_handle)`: +- User "alice" can have project "research" +- User "bob" can also have project "research" +- Same user cannot have two projects with same handle + +## Creating Projects + +### Basic Project + +```bash +POST /v1/projects/alice + +{ + "project_handle": "literature-study", + "description": "Literary text analysis", + "instance_owner": "alice", + "instance_handle": "my-openai" +} +``` + +### Project with Metadata Schema + +```bash +POST /v1/projects/alice + +{ + "project_handle": "research-papers", + "description": "Academic papers with structured metadata", + "instance_owner": "alice", + "instance_handle": "my-embeddings", + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"doi\":{\"type\":\"string\"}},\"required\":[\"author\",\"year\"]}" +} +``` + +### Public Project + +```bash +POST /v1/projects/alice + +{ + "project_handle": "open-dataset", + "description": "Publicly accessible research data", + "instance_owner": "alice", + "instance_handle": "my-embeddings", + "public_read": true +} +``` + +### Shared Project + +```bash +POST /v1/projects/alice + +{ + "project_handle": "collaborative", + "description": "Team collaboration project", + "instance_owner": "alice", + "instance_handle": "my-embeddings", + "shared_with": [ + { + "user_handle": "bob", + "role": "editor" + }, + { + "user_handle": "charlie", + "role": "reader" + } + ] +} +``` + +## Project-Instance Relationship + +### One-to-One Constraint + +Each project references exactly one LLM service instance: + +``` +Project → Instance (1:1) + ├── Defines vector dimensions + ├── Specifies embedding model + └── Contains API configuration +``` + +**Why 1:1?** +- Ensures consistent dimensions across all embeddings +- Prevents dimension mismatches in similarity searches +- Simplifies validation and error handling + +### Specifying Instance + +Use owner and handle to reference an instance: + +```json +{ + "instance_owner": "alice", + "instance_handle": "my-openai" +} +``` + +The instance can be: +- Owned by project owner: `"instance_owner": "alice"` +- Shared with project owner: `"instance_owner": "bob"` (if bob shared with alice) + +## Metadata Schemas + +### Purpose + +Metadata schemas ensure consistent, structured metadata across all embeddings in a project. + +### Schema Format + +Use JSON Schema (draft-07 or later): + +```json +{ + "type": "object", + "properties": { + "author": {"type": "string"}, + "title": {"type": "string"}, + "year": { + "type": "integer", + "minimum": 1000, + "maximum": 2100 + }, + "genre": { + "type": "string", + "enum": ["fiction", "non-fiction", "poetry"] + } + }, + "required": ["author", "title", "year"] +} +``` + +### Validation Behavior + +- **With schema**: All embeddings validated on upload +- **Without schema**: Any JSON metadata accepted +- **Validation failure**: Upload rejected with detailed error +- **Schema updates**: Only apply to new/updated embeddings + +### Example Schemas + +See [Metadata Validation Guide](../guides/metadata-validation/) for detailed examples. + +## Access Control + +### Ownership + +- **Owner**: User who created the project +- **Full control**: Read, write, delete, share, transfer +- **Cannot be removed**: Owner always has access + +### Sharing + +Projects can be shared with specific users: + +**Reader Role** +- View embeddings +- Search for similar documents +- View project metadata +- Cannot modify anything + +**Editor Role** +- All reader permissions +- Add embeddings +- Modify embeddings +- Delete embeddings +- Cannot delete project or change settings + +**Managing Sharing:** + +```bash +# Share with user +POST /v1/projects/alice/my-project/share +{ + "share_with_handle": "bob", + "role": "reader" +} + +# Unshare from user +DELETE /v1/projects/alice/my-project/share/bob + +# List shared users +GET /v1/projects/alice/my-project/shared-with +``` + +### Public Access + +Projects can allow unauthenticated read access: + +```bash +PATCH /v1/projects/alice/my-project +{ + "public_read": true +} +``` + +With `public_read: true`: +- Anyone can view embeddings (no authentication) +- Anyone can search for similar documents +- Write operations still require authentication + +See [Public Projects Guide](../guides/public-projects/) for details. + +## Project Operations + +### List Projects + +List all projects owned by a user: + +```bash +GET /v1/projects/alice +Authorization: Bearer alice_vdb_key +``` + +Returns array of project objects. + +### Get Project Details + +```bash +GET /v1/projects/alice/research +Authorization: Bearer alice_vdb_key +``` + +Returns full project object including: +- Configuration +- Instance reference +- Metadata schema +- Sharing information (owner only) + +### Update Project + +Use PATCH for partial updates: + +```bash +PATCH /v1/projects/alice/research +{ + "description": "Updated description" +} +``` + +Use PUT for full replacement: + +```bash +PUT /v1/projects/alice/research +{ + "project_handle": "research", + "description": "Complete project configuration", + "instance_owner": "alice", + "instance_handle": "my-embeddings", + "metadataScheme": "{...}" +} +``` + +### Delete Project + +```bash +DELETE /v1/projects/alice/research +Authorization: Bearer alice_vdb_key +``` + +**Cascading deletion:** +- All embeddings in project deleted +- All sharing grants removed +- Project metadata removed + +## Ownership Transfer + +Transfer project to another user: + +```bash +POST /v1/projects/alice/research/transfer-ownership +{ + "new_owner_handle": "bob" +} +``` + +**Effects:** +- Project owner changes to bob +- Project URL changes: `/v1/projects/bob/research` +- Alice loses all access (unless re-shared) +- All embeddings transferred +- Bob cannot already have project with same handle + +See [Ownership Transfer Guide](../guides/ownership-transfer/) for details. + +## Project Limits + +### Current Implementation + +No enforced limits on: +- Number of embeddings per project +- Project storage size +- Number of shared users + +### Recommended Practices + +For large projects: +- Use pagination when listing embeddings +- Batch upload embeddings +- Monitor database size +- Consider archiving old projects + +## Common Patterns + +### Research Project Workflow + +```bash +# 1. Create project +POST /v1/projects/alice +{ + "project_handle": "study-2024", + "description": "2024 Research Study", + "instance_owner": "alice", + "instance_handle": "my-embeddings" +} + +# 2. Upload data +POST /v1/embeddings/alice/study-2024 +{ ... embeddings ... } + +# 3. Share with team +POST /v1/projects/alice/study-2024/share +{"share_with_handle": "bob", "role": "reader"} + +# 4. Make public when published +PATCH /v1/projects/alice/study-2024 +{"public_read": true} +``` + +### Multi-Project Organization + +```bash +# Development project +POST /v1/projects/alice +{ + "project_handle": "dev-experiments", + "instance_owner": "alice", + "instance_handle": "dev-embeddings" +} + +# Production project +POST /v1/projects/alice +{ + "project_handle": "prod-dataset", + "instance_owner": "alice", + "instance_handle": "prod-embeddings", + "metadataScheme": "{...}" +} + +# Archive project +POST /v1/projects/alice +{ + "project_handle": "archive-2023", + "instance_owner": "alice", + "instance_handle": "archive-embeddings", + "public_read": true +} +``` + +## Troubleshooting + +### Cannot Create Project + +**Possible causes:** +- Project handle already exists for this user +- Invalid project handle format +- Instance doesn't exist or not accessible +- Missing required fields + +**Solutions:** +- Choose different project handle +- Verify instance exists: `GET /v1/llm-services/owner` +- Check instance is owned or shared with you +- Include all required fields (instance_owner, instance_handle) + +### Metadata Validation Fails + +**Possible causes:** +- Metadata doesn't match schema +- Invalid JSON Schema format +- Schema too restrictive + +**Solutions:** +- Test schema with online validator +- Verify embedding metadata matches schema +- Update schema or metadata as needed + +### Cannot Share Project + +**Possible causes:** +- Not project owner +- Target user doesn't exist +- Invalid role specified + +**Solutions:** +- Only owner can share projects +- Verify user exists: `GET /v1/users/target` +- Use valid role: "reader" or "editor" + +## Next Steps + +- [Learn about embeddings](embeddings/) +- [Explore metadata validation](../guides/metadata-validation/) +- [Understand project sharing](../guides/project-sharing/) diff --git a/docs/content/concepts/similarity-search.md b/docs/content/concepts/similarity-search.md new file mode 100644 index 0000000..6e13155 --- /dev/null +++ b/docs/content/concepts/similarity-search.md @@ -0,0 +1,445 @@ +--- +title: "Similarity Search" +weight: 6 +--- + +# Similarity Search + +Find documents with similar semantic meaning using vector similarity. + +## How it Works + +Similarity search compares embedding vectors using cosine distance: + +1. **Query vector**: Either from stored embedding or raw vector +2. **Comparison**: Calculate cosine similarity with all project embeddings +3. **Filtering**: Apply threshold and metadata filters +4. **Ranking**: Sort by similarity score (highest first) +5. **Return**: Top N most similar documents + +## Search Methods + +### Stored Document Search (GET) + +Find documents similar to an already-stored embedding: + +```bash +GET /v1/similars/alice/research/doc1?count=10&threshold=0.7 +``` + +**Use cases:** +- Find related documents +- Discover similar passages +- Identify duplicates + +### Raw Vector Search (POST) + +Search using a new embedding without storing it: + +```bash +POST /v1/similars/alice/research?count=10&threshold=0.7 + +{ + "vector": [0.023, -0.015, ..., 0.042] +} +``` + +**Use cases:** +- Query without saving +- Test embeddings +- Real-time search + +## Query Parameters + +### count + +Number of similar documents to return. + +- **Type**: Integer +- **Range**: 1-200 +- **Default**: 10 + +```bash +GET /v1/similars/alice/project/doc1?count=5 +``` + +### threshold + +Minimum similarity score (0-1). + +- **Type**: Float +- **Range**: 0.0-1.0 +- **Default**: 0.5 +- **Meaning**: 1.0 = identical, 0.0 = unrelated + +```bash +GET /v1/similars/alice/project/doc1?threshold=0.8 +``` + +### limit + +Maximum number of results (same as count). + +- **Type**: Integer +- **Range**: 1-200 +- **Default**: 10 + +### offset + +Skip first N results (pagination). + +- **Type**: Integer +- **Minimum**: 0 +- **Default**: 0 + +```bash +# First page +GET /v1/similars/alice/project/doc1?limit=10&offset=0 + +# Second page +GET /v1/similars/alice/project/doc1?limit=10&offset=10 +``` + +### metadata_path + +JSON path to metadata field for filtering. + +- **Type**: String +- **Purpose**: Specify metadata field to filter +- **Must be used with**: metadata_value + +```bash +?metadata_path=author +``` + +### metadata_value + +Value to **exclude** from results. + +- **Type**: String +- **Purpose**: Exclude documents matching this value +- **Must be used with**: metadata_path + +```bash +?metadata_path=author&metadata_value=Shakespeare +``` + +**Important**: Excludes matches, doesn't include them. + +## Similarity Scores + +### Cosine Similarity + +dhamps-vdb uses cosine similarity: + +``` +similarity = 1 - cosine_distance +``` + +**Score ranges:** +- **1.0**: Identical vectors +- **0.9-1.0**: Very similar +- **0.7-0.9**: Similar +- **0.5-0.7**: Somewhat similar +- **<0.5**: Not similar + +### Interpreting Scores + +Typical thresholds: + +- **0.9+**: Duplicates or near-duplicates +- **0.8+**: Strong semantic similarity +- **0.7+**: Related topics +- **0.5-0.7**: Weak relation +- **<0.5**: Unrelated + +Optimal threshold depends on your use case and model. + +## Metadata Filtering + +### Exclude by Field + +Exclude documents where metadata field matches value: + +```bash +# Exclude documents from same author +GET /v1/similars/alice/lit-study/hamlet-act1?metadata_path=author&metadata_value=Shakespeare +``` + +**Result**: Returns similar documents, excluding those with `metadata.author == "Shakespeare"`. + +### Nested Fields + +Use dot notation for nested metadata: + +```bash +# Exclude documents from same author.name +GET /v1/similars/alice/project/doc1?metadata_path=author.name&metadata_value=John%20Doe +``` + +### Common Patterns + +**Exclude same work:** +```bash +?metadata_path=title&metadata_value=Hamlet +``` + +**Exclude same source:** +```bash +?metadata_path=source_id&metadata_value=corpus-A +``` + +**Exclude same category:** +```bash +?metadata_path=category&metadata_value=tutorial +``` + +See [Metadata Filtering Guide](../guides/metadata-filtering/) for details. + +## Response Format + +```json +{ + "user_handle": "alice", + "project_handle": "research", + "results": [ + { + "id": "doc2", + "similarity": 0.95 + }, + { + "id": "doc5", + "similarity": 0.87 + }, + { + "id": "doc8", + "similarity": 0.82 + } + ] +} +``` + +**Fields:** +- **user_handle**: Project owner +- **project_handle**: Project identifier +- **results**: Array of similar documents + - **id**: Document text_id + - **similarity**: Similarity score (0-1) + +Results are sorted by similarity (highest first). + +## Performance + +### Query Speed + +Typical performance: +- **<10K embeddings**: <10ms +- **10K-100K embeddings**: 10-50ms +- **100K-1M embeddings**: 50-200ms +- **>1M embeddings**: 200-1000ms + +### Optimization + +**HNSW Index:** +- Faster queries than IVFFlat +- Better recall +- Larger index size + +**Query optimization:** +- Use appropriate threshold (higher = fewer results) +- Limit result count (lower = faster) +- Consider dimension reduction for large projects + +### Scaling + +For large datasets: +- Monitor query performance +- Consider read replicas +- Use connection pooling +- Cache frequent queries (application level) + +## Common Use Cases + +### RAG Workflow + +Retrieval Augmented Generation: + +```bash +# 1. User query +query="What is machine learning?" + +# 2. Generate query embedding (external) +query_vector=[...] + +# 3. Find similar documents +POST /v1/similars/alice/knowledge-base?count=5&threshold=0.7 +{"vector": $query_vector} + +# 4. Retrieve full text for top results +for each result: + GET /v1/embeddings/alice/knowledge-base/$result_id + +# 5. Send context to LLM for generation +``` + +### Duplicate Detection + +Find near-duplicate documents: + +```bash +# High threshold for duplicates +GET /v1/similars/alice/corpus/doc1?count=10&threshold=0.95 +``` + +Documents with similarity > 0.95 are likely duplicates. + +### Content Discovery + +Find related content: + +```bash +# Moderate threshold for recommendations +GET /v1/similars/alice/articles/article1?count=10&threshold=0.7&metadata_path=article_id&metadata_value=article1 +``` + +Excludes the source article itself. + +### Topic Clustering + +Find documents on similar topics: + +```bash +# For each document, find similar ones +for doc in documents: + GET /v1/similars/alice/corpus/$doc?count=20&threshold=0.8 +``` + +Group documents by similarity for clustering. + +## Dimension Consistency + +### Automatic Filtering + +Similarity queries only compare embeddings with matching dimensions: + +``` +Project embeddings: + - doc1: 3072 dimensions + - doc2: 3072 dimensions + - doc3: 1536 dimensions (different model) + +Query for doc1 similars: + → Only compares with doc2 + → Ignores doc3 (dimension mismatch) +``` + +### Multiple Instances + +Projects can have embeddings from multiple instances (if dimensions match): + +```json +{ + "text_id": "doc1", + "instance_handle": "openai-large", + "vector_dim": 3072 +} + +{ + "text_id": "doc2", + "instance_handle": "custom-model", + "vector_dim": 3072 +} +``` + +Both searchable together (same dimensions). + +## Access Control + +### Authentication + +Similarity search respects project access control: + +**Owner**: Full access +**Editor**: Can search (read permission) +**Reader**: Can search (read permission) +**Public** (if public_read=true): Can search (no auth required) + +### Public Projects + +Public projects allow unauthenticated similarity search: + +```bash +# No Authorization header needed +GET /v1/similars/alice/public-project/doc1?count=10 +``` + +See [Public Projects Guide](../guides/public-projects/). + +## Limitations + +### Current Constraints + +- **No cross-project search**: Similarity search is per-project only +- **No filtering by multiple metadata fields**: One field at a time +- **No custom distance metrics**: Cosine similarity only +- **No approximate search tuning**: Uses default HNSW parameters + +### Workarounds + +**Cross-project search:** +- Query each project separately +- Merge results in application + +**Multiple metadata filters:** +- Filter by one field in query +- Apply additional filters in application + +## Troubleshooting + +### No Results Returned + +**Possible causes:** +- Threshold too high +- No embeddings in project +- Dimension mismatch +- All results filtered by metadata + +**Solutions:** +- Lower threshold (try 0.5) +- Verify embeddings exist +- Check dimensions match +- Remove metadata filter + +### Unexpected Results + +**Possible causes:** +- Threshold too low +- Poor quality embeddings +- Incorrect model used +- Metadata filter excluding desired results + +**Solutions:** +- Increase threshold +- Regenerate embeddings +- Verify correct model/dimensions +- Adjust metadata filter + +### Slow Queries + +**Possible causes:** +- Large dataset (>100K embeddings) +- No vector index +- High result count +- Complex metadata filtering + +**Solutions:** +- Reduce result count +- Check index exists +- Optimize database +- Use read replicas + +## Next Steps + +- [Learn about metadata filtering](../guides/metadata-filtering/) +- [Understand RAG workflows](../guides/rag-workflow/) +- [Explore embeddings](embeddings/) diff --git a/docs/content/concepts/users-and-auth.md b/docs/content/concepts/users-and-auth.md new file mode 100644 index 0000000..c1c7c1f --- /dev/null +++ b/docs/content/concepts/users-and-auth.md @@ -0,0 +1,368 @@ +--- +title: "Users and Authentication" +weight: 2 +--- + +# Users and Authentication + +dhamps-vdb uses token-based authentication with API keys for all operations. + +## User Model + +### User Properties + +- **user_handle**: Unique identifier (3-20 characters, alphanumeric + underscore) +- **name**: Full name (optional) +- **email**: Email address (unique, required) +- **vdb_key**: API key (SHA-256 hash, 64 characters) +- **created_at**: Timestamp of creation +- **updated_at**: Timestamp of last update + +### Special Users + +**`_system` User** + +- Created automatically during database migration +- Owns system-wide LLM service definitions +- Cannot be used for authentication +- Provides default configurations for all users + +## Authentication Flow + +### API Key Authentication + +All requests (except public endpoints) require authentication: + +```http +GET /v1/projects/alice/my-project +Authorization: Bearer 024v2013621509245f2e24... +``` + +### Authentication Process + +1. Client sends API key in `Authorization` header with `Bearer` prefix +2. Server extracts key and looks up user in database +3. If user found, request proceeds with user context +4. If not found or missing, returns `401 Unauthorized` + +### Admin Authentication + +Administrative operations require the admin API key: + +```bash +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{"user_handle":"alice","email":"alice@example.com"}' +``` + +Admin key is set via `SERVICE_ADMINKEY` environment variable. + +## User Creation + +### By Admin + +Only admin users can create new users: + +```bash +POST /v1/users +Authorization: Bearer ADMIN_KEY + +{ + "user_handle": "researcher1", + "name": "Research User", + "email": "researcher@example.com" +} +``` + +**Response:** + +```json +{ + "user_handle": "researcher1", + "name": "Research User", + "email": "researcher@example.com", + "vdb_key": "024v2013621509245f2e24abcdef...", + "created_at": "2024-01-15T10:30:00Z" +} +``` + +**Important:** Save the `vdb_key` immediately - it cannot be recovered later. + +### User Handle Restrictions + +- Must be 3-20 characters +- Alphanumeric characters and underscores only +- Must be unique +- Cannot be `_system` + +## User Management + +### Retrieve User Information + +Users can view their own information: + +```bash +GET /v1/users/alice +Authorization: Bearer alice_vdb_key +``` + +Admins can view any user: + +```bash +GET /v1/users/alice +Authorization: Bearer ADMIN_KEY +``` + +### List All Users + +Only admins can list all users: + +```bash +GET /v1/users +Authorization: Bearer ADMIN_KEY +``` + +Returns array of user handles (not full user objects). + +### Update User + +Users can update their own information: + +```bash +PATCH /v1/users/alice +Authorization: Bearer alice_vdb_key + +{ + "name": "Alice Smith-Jones", + "email": "alice.smith@example.com" +} +``` + +### Delete User + +Users can delete their own account: + +```bash +DELETE /v1/users/alice +Authorization: Bearer alice_vdb_key +``` + +Admins can delete any user: + +```bash +DELETE /v1/users/alice +Authorization: Bearer ADMIN_KEY +``` + +**Cascading Deletion:** +- All user's projects are deleted +- All user's LLM service instances are deleted +- All embeddings in user's projects are deleted +- Sharing grants from this user to others are removed + +## Authorization Model + +### Resource Ownership + +Users own three types of resources: + +1. **Projects**: Collections of embeddings +2. **LLM Service Instances**: Embedding configurations with API keys +3. **LLM Service Definitions**: Reusable configuration templates (optional) + +### Access Levels + +**Owner** +- Full control over resource +- Can read, write, delete +- Can share with others +- Can transfer ownership (projects only) + +**Editor** (via sharing) +- Read and write access +- Cannot delete resource +- Cannot modify sharing +- Cannot change project settings + +**Reader** (via sharing) +- Read-only access +- Can view embeddings +- Can search for similar documents +- Cannot modify anything + +**Public** (if project.public_read = true) +- Unauthenticated read access +- Can view embeddings +- Can search for similar documents +- Cannot write or modify + +## Security Best Practices + +### API Key Management + +**Storage** +- Store API keys securely (e.g., environment variables, secret managers) +- Never commit API keys to version control +- Use different keys for development and production + +**Rotation** +- Currently, API keys cannot be rotated +- To change a key, delete and recreate the user +- Plan key rotation strategy before production deployment + +**Transmission** +- Always use HTTPS in production +- API keys are transmitted in Authorization header +- Never pass API keys in URL query parameters + +### User Key vs. LLM API Keys + +dhamps-vdb handles two types of keys: + +1. **User API keys** (`vdb_key`): Authenticate users to dhamps-vdb + - Stored as SHA-256 hash in database + - Never encrypted (one-way hash) + - Returned only once on user creation + +2. **LLM API keys** (`api_key_encrypted`): Authenticate to LLM services + - Stored encrypted (AES-256-GCM) in database + - Never returned in API responses + - Used internally for LLM processing + +## Multi-User Workflows + +### Collaboration Pattern + +1. **Admin** creates user accounts for team members +2. **Project Owner** creates project with embeddings +3. **Owner** shares project with collaborators +4. **Readers** can search and view embeddings +5. **Editors** can add/modify embeddings + +### Organization Pattern + +1. **Admin** creates organizational users +2. **Each user** creates LLM service instances with their own API keys +3. **Users** create projects using their instances +4. **Projects** shared within organization as needed + +### Public Access Pattern + +1. **User** creates project with research data +2. **User** sets `public_read: true` +3. **Anyone** can access embeddings and search without authentication +4. **Only owner** can modify project + +## User Limits + +### Current Implementation + +No enforced limits on: +- Number of projects per user +- Number of embeddings per project +- Number of LLM service instances per user +- Storage size per user + +### Recommended Limits + +For production deployments, consider implementing: +- Rate limiting per API key +- Storage quotas per user +- Maximum project count per user + +## Example Workflows + +### Create and Use User Account + +```bash +# Admin creates user +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer $ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "researcher1", + "email": "researcher@example.com", + "name": "Research User" + }' + +# Save returned vdb_key +export USER_KEY="returned-vdb-key" + +# User verifies access +curl -X GET http://localhost:8880/v1/users/researcher1 \ + -H "Authorization: Bearer $USER_KEY" + +# User creates project +curl -X POST http://localhost:8880/v1/projects/researcher1 \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-project", + "description": "My research project" + }' +``` + +### Share Resources + +```bash +# User shares project with colleague +curl -X POST http://localhost:8880/v1/projects/researcher1/my-project/share \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "colleague1", + "role": "reader" + }' + +# Colleague accesses shared project +curl -X GET http://localhost:8880/v1/projects/researcher1/my-project \ + -H "Authorization: Bearer $COLLEAGUE_KEY" +``` + +## Troubleshooting + +### 401 Unauthorized + +**Possible causes:** +- Missing Authorization header +- Incorrect API key +- Expired or invalid key +- Using user key instead of admin key (or vice versa) + +**Solution:** +- Verify API key is correct +- Check Authorization header format: `Bearer KEY` +- Ensure operation matches key type (admin vs. user) + +### 403 Forbidden + +**Possible causes:** +- User doesn't own resource +- User not granted access to shared resource +- Insufficient permissions (reader trying to edit) + +**Solution:** +- Verify resource ownership +- Check sharing grants +- Ensure user has required role (editor for writes) + +### User Creation Failed + +**Possible causes:** +- User handle already exists +- Email already registered +- Invalid user handle format +- Not using admin key + +**Solution:** +- Choose different user handle +- Use unique email address +- Check user handle format (3-20 chars, alphanumeric + underscore) +- Verify using admin API key + +## Next Steps + +- [Learn about projects](projects/) +- [Understand LLM services](llm-services/) +- [Explore project sharing](../guides/project-sharing/) diff --git a/docs/content/deployment/_index.md b/docs/content/deployment/_index.md new file mode 100644 index 0000000..f423702 --- /dev/null +++ b/docs/content/deployment/_index.md @@ -0,0 +1,35 @@ +--- +title: "Deployment" +weight: 5 +--- + +# Deployment Guide + +Deploy dhamps-vdb to production environments. + +## Deployment Options + +dhamps-vdb can be deployed in several ways: + +- **Docker Compose** - Simplest option, includes PostgreSQL +- **Docker with External Database** - Production-ready setup +- **Standalone Binary** - For custom environments +- **Kubernetes** - For orchestrated deployments + +## Production Considerations + +When deploying to production: + +- Use strong, randomly generated keys +- Enable HTTPS/TLS for all API endpoints +- Configure database backups +- Set up monitoring and logging +- Restrict network access to database +- Use environment variables for sensitive configuration + +## Guides + +- [Docker Deployment](docker/) - Complete Docker guide +- [Database Setup](database/) - PostgreSQL configuration +- [Environment Variables](environment-variables/) - All configuration options +- [Security](security/) - Security best practices diff --git a/docs/content/development/_index.md b/docs/content/development/_index.md new file mode 100644 index 0000000..367e09a --- /dev/null +++ b/docs/content/development/_index.md @@ -0,0 +1,47 @@ +--- +title: "Development" +weight: 6 +--- + +# Development Guide + +Information for developers contributing to dhamps-vdb. + +## Getting Started with Development + +This section covers: + +- Setting up a development environment +- Running tests +- Understanding the codebase architecture +- Contributing guidelines +- Performance optimization + +## Project Structure + +``` +dhamps-vdb/ +├── main.go # Application entry point +├── internal/ +│ ├── auth/ # Authentication logic +│ ├── database/ # Database layer (sqlc) +│ ├── handlers/ # HTTP handlers +│ └── models/ # Data models +├── testdata/ # Test fixtures +└── docs/ # Documentation +``` + +## Development Workflow + +1. Make changes to code +2. Generate sqlc code if database queries changed: `sqlc generate` +3. Run tests: `go test -v ./...` +4. Build: `go build -o dhamps-vdb main.go` +5. Submit pull request + +## Resources + +- [Testing](testing/) - How to run tests +- [Contributing](contributing/) - Contribution guidelines +- [Architecture](architecture/) - Technical deep-dive +- [Performance](performance/) - Optimization notes diff --git a/docs/content/getting-started/_index.md b/docs/content/getting-started/_index.md new file mode 100644 index 0000000..2b30682 --- /dev/null +++ b/docs/content/getting-started/_index.md @@ -0,0 +1,31 @@ +--- +title: "Getting Started" +weight: 1 +--- + +# Getting Started with dhamps-vdb + +This section helps you get dhamps-vdb up and running quickly. Whether you're using Docker or compiling from source, you'll find everything you need to start using the vector database API. + +## What You'll Learn + +- How to install and run dhamps-vdb +- How to configure the service for your environment +- Basic usage patterns and workflows +- Creating your first project and embeddings + +## Prerequisites + +Before you begin, ensure you have: + +- PostgreSQL 11+ with pgvector extension (or use the provided Docker setup) +- Go 1.21+ (if compiling from source) +- Docker and Docker Compose (for containerized deployment) + +## Quick Links + +- [Installation](installation/) - Compile and install dhamps-vdb +- [Docker Deployment](docker/) - Run with Docker (recommended) +- [Configuration](configuration/) - Environment variables and options +- [Quick Start](quick-start/) - Your first API requests +- [First Project](first-project/) - Complete walkthrough diff --git a/docs/content/getting-started/configuration.md b/docs/content/getting-started/configuration.md new file mode 100644 index 0000000..8997b24 --- /dev/null +++ b/docs/content/getting-started/configuration.md @@ -0,0 +1,156 @@ +--- +title: "Configuration" +weight: 2 +--- + +# Configuration + +Configure dhamps-vdb using environment variables or command-line options. + +## Environment Variables + +All configuration can be set via environment variables. Use a `.env` file to keep sensitive information secure. + +### Service Configuration + +| Variable | Description | Default | Required | +|----------|-------------|---------|----------| +| `SERVICE_DEBUG` | Enable debug logging | `true` | No | +| `SERVICE_HOST` | Hostname to listen on | `localhost` | No | +| `SERVICE_PORT` | Port to listen on | `8880` | No | + +### Database Configuration + +| Variable | Description | Default | Required | +|----------|-------------|---------|----------| +| `SERVICE_DBHOST` | Database hostname | `localhost` | Yes | +| `SERVICE_DBPORT` | Database port | `5432` | No | +| `SERVICE_DBUSER` | Database username | `postgres` | Yes | +| `SERVICE_DBPASSWORD` | Database password | `password` | Yes | +| `SERVICE_DBNAME` | Database name | `postgres` | Yes | + +### Security Configuration + +| Variable | Description | Default | Required | +|----------|-------------|---------|----------| +| `SERVICE_ADMINKEY` | Admin API key for administrative operations | - | Yes | +| `ENCRYPTION_KEY` | Encryption key for API keys (32+ characters) | - | Yes | + +## Configuration File + +Create a `.env` file in the project root: + +```bash +# Service Configuration +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 + +# Database Configuration +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=secure_password +SERVICE_DBNAME=dhamps_vdb + +# Security +SERVICE_ADMINKEY=your-secure-admin-key-here +ENCRYPTION_KEY=your-32-character-encryption-key-minimum +``` + +## Command-Line Options + +You can also provide configuration via command-line flags: + +```bash +./dhamps-vdb \ + --debug \ + -p 8880 \ + --db-host localhost \ + --db-port 5432 \ + --db-user dhamps_user \ + --db-password secure_password \ + --db-name dhamps_vdb \ + --admin-key your-admin-key +``` + +## Generating Secure Keys + +### Admin Key + +Generate a secure admin key: + +```bash +openssl rand -base64 32 +``` + +### Encryption Key + +Generate a secure encryption key (minimum 32 characters): + +```bash +openssl rand -hex 32 +``` + +## Configuration Priority + +Configuration is loaded in the following order (later sources override earlier ones): + +1. Default values (from `options.go`) +2. Environment variables +3. `.env` file +4. Command-line flags + +## Security Best Practices + +- **Never commit `.env` files** to version control +- Use **strong, randomly generated keys** for production +- Ensure `.env` file permissions are restrictive (`chmod 600 .env`) +- **Store encryption key securely** - losing it means losing access to encrypted API keys +- Use different keys for development and production environments + +## Example Configuration + +### Development + +```bash +# .env (development) +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8880 +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=password +SERVICE_DBNAME=dhamps_vdb_dev +SERVICE_ADMINKEY=dev-admin-key-change-me +ENCRYPTION_KEY=dev-encryption-key-32-chars-min +``` + +### Production + +```bash +# .env (production) +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 +SERVICE_DBHOST=prod-db.example.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_prod +SERVICE_DBPASSWORD=$(cat /run/secrets/db_password) +SERVICE_DBNAME=dhamps_vdb +SERVICE_ADMINKEY=$(cat /run/secrets/admin_key) +ENCRYPTION_KEY=$(cat /run/secrets/encryption_key) +``` + +## Validation + +The service validates configuration on startup and will exit with an error if required variables are missing. + +## Next Steps + +After configuration: + +1. [Run the Quick Start tutorial](quick-start/) +2. [Create your first project](first-project/) +3. Review [deployment options](../deployment/) diff --git a/docs/content/getting-started/docker.md b/docs/content/getting-started/docker.md new file mode 100644 index 0000000..82504d8 --- /dev/null +++ b/docs/content/getting-started/docker.md @@ -0,0 +1,537 @@ +--- +title: "Docker Deployment" +weight: 2 +--- + +# Docker Deployment + +Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users. + +## Quick Start + +The fastest way to get dhamps-vdb running with Docker: + +```bash +# Clone the repository +git clone https://github.com/mpilhlt/dhamps-vdb.git +cd dhamps-vdb + +# Run automated setup (generates secure keys) +./docker-setup.sh + +# Start services with docker-compose +docker-compose up -d + +# Check logs +docker-compose logs -f dhamps-vdb + +# Access the API +curl http://localhost:8880/docs +``` + +## What's Included + +The Docker Compose setup includes: + +- **dhamps-vdb**: The vector database API service +- **PostgreSQL 16**: Database with pgvector extension +- **Persistent storage**: Named volume for database data + +## Configuration Files + +### .env File + +All configuration is managed through environment variables. Copy the template: + +```bash +cp .env.docker.template .env +``` + +Edit `.env` to set required values: + +```bash +# Admin API key for administrative operations +SERVICE_ADMINKEY=your-secure-admin-key-here + +# Encryption key for API keys (32+ characters) +ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars + +# Database password +SERVICE_DBPASSWORD=secure-database-password + +# Optional: Debug mode +SERVICE_DEBUG=false + +# Optional: Change ports +API_PORT=8880 +POSTGRES_PORT=5432 +``` + +### docker-compose.yml + +The compose file defines two services: + +```yaml +services: + postgres: + image: pgvector/pgvector:0.7.4-pg16 + # PostgreSQL with pgvector support + + dhamps-vdb: + build: . + # The API service + depends_on: + - postgres +``` + +## Deployment Options + +### Option 1: Docker Compose with Included Database (Recommended) + +Use the provided `docker-compose.yml`: + +```bash +docker-compose up -d +``` + +**Advantages:** +- Everything included +- Automatic networking +- Data persistence +- Easy to manage + +**Use when:** +- Getting started +- Development/testing +- Small to medium deployments + +### Option 2: Standalone Container with External Database + +Run only the dhamps-vdb container: + +```bash +# Build the image +docker build -t dhamps-vdb:latest . + +# Run the container +docker run -d \ + --name dhamps-vdb \ + -p 8880:8880 \ + -e SERVICE_DBHOST=your-db-host \ + -e SERVICE_DBPORT=5432 \ + -e SERVICE_DBUSER=dbuser \ + -e SERVICE_DBPASSWORD=dbpass \ + -e SERVICE_DBNAME=dhamps_vdb \ + -e SERVICE_ADMINKEY=admin-key \ + -e ENCRYPTION_KEY=encryption-key \ + dhamps-vdb:latest +``` + +**Use when:** +- You have an existing PostgreSQL server +- Production deployments +- Need database separation + +### Option 3: Docker Compose with External Database + +Modify `docker-compose.yml` to remove the postgres service: + +```yaml +services: + dhamps-vdb: + build: . + ports: + - "${API_PORT:-8880}:8880" + environment: + SERVICE_DBHOST: external-db.example.com + # ... other variables +``` + +## Building the Image + +### Standard Build + +```bash +docker build -t dhamps-vdb:latest . +``` + +### Custom Tag + +```bash +docker build -t dhamps-vdb:v0.1.0 . +``` + +### Clean Build (No Cache) + +```bash +docker build --no-cache -t dhamps-vdb:latest . +``` + +### Multi-Stage Build Details + +The Dockerfile uses multi-stage builds for efficiency: + +1. **Builder stage**: Compiles Go code with sqlc generation +2. **Runtime stage**: Minimal Alpine image with only the binary + +Result: Small, secure image (~20MB vs 800MB+) + +## Managing Services + +### Start Services + +```bash +# Start in background +docker-compose up -d + +# Start with logs visible +docker-compose up + +# Rebuild and start +docker-compose up -d --build +``` + +### View Logs + +```bash +# All logs +docker-compose logs + +# Follow logs in real-time +docker-compose logs -f + +# Specific service +docker-compose logs -f dhamps-vdb +docker-compose logs -f postgres +``` + +### Stop Services + +```bash +# Stop containers (keeps data) +docker-compose stop + +# Stop and remove containers (keeps data) +docker-compose down + +# Stop and remove everything including data +docker-compose down -v +``` + +### Restart Services + +```bash +# Restart all +docker-compose restart + +# Restart specific service +docker-compose restart dhamps-vdb +``` + +## Data Persistence + +### Docker Volumes + +The compose file creates a named volume: + +```yaml +volumes: + postgres_data: +``` + +This ensures database data persists across container restarts. + +### View Volumes + +```bash +docker volume ls +``` + +### Inspect Volume + +```bash +docker volume inspect dhamps-vdb_postgres_data +``` + +### Backup Database + +```bash +# Create backup +docker-compose exec postgres pg_dump -U postgres dhamps_vdb > backup.sql + +# Restore from backup +docker-compose exec -T postgres psql -U postgres dhamps_vdb < backup.sql +``` + +## Networking + +### Access from Host + +The API is accessible at: + +``` +http://localhost:8880 +``` + +### Access from Other Containers + +Use the service name as hostname: + +``` +http://dhamps-vdb:8880 +``` + +### Custom Network + +To use an existing Docker network: + +```yaml +networks: + default: + external: + name: your-network-name +``` + +## Security + +### Required Environment Variables + +Two critical environment variables must be set: + +1. **SERVICE_ADMINKEY**: Admin API key +2. **ENCRYPTION_KEY**: For encrypting user API keys (32+ chars) + +### Generating Secure Keys + +```bash +# Admin key +openssl rand -base64 32 + +# Encryption key +openssl rand -hex 32 +``` + +### Production Checklist + +- [ ] Use strong, randomly generated keys +- [ ] Never commit `.env` to version control +- [ ] Run behind reverse proxy (nginx, Traefik) +- [ ] Enable HTTPS/TLS +- [ ] Restrict database network access +- [ ] Set resource limits +- [ ] Enable logging and monitoring +- [ ] Use specific image tags (not `latest`) +- [ ] Regular security updates +- [ ] Backup database regularly + +## Verification + +### Check Service Status + +```bash +# Check if containers are running +docker-compose ps + +# Expected: both services "running" or "healthy" +``` + +### Test API Access + +```bash +# Get OpenAPI documentation +curl http://localhost:8880/docs + +# Should return HTML page +``` + +### Test Database Connection + +```bash +# Connect to PostgreSQL +docker-compose exec postgres psql -U postgres -d dhamps_vdb + +# Check pgvector extension +\dx + +# Should show vector extension +``` + +### Create Test User + +```bash +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "testuser", + "full_name": "Test User" + }' +``` + +## Troubleshooting + +### Container Won't Start + +Check logs: +```bash +docker-compose logs dhamps-vdb +``` + +Common issues: +- Missing `SERVICE_ADMINKEY` or `ENCRYPTION_KEY` +- Database connection failure +- Port already in use + +### Database Connection Errors + +```bash +# Check postgres health +docker-compose ps + +# Check database logs +docker-compose logs postgres + +# Test connection +docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT 1;" +``` + +### Can't Connect to API + +```bash +# Check if container is running +docker ps + +# Check port mapping +docker port dhamps-vdb + +# Test from inside container +docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs + +# Test from host +curl http://localhost:8880/docs +``` + +### Permission Issues + +The container runs as non-root user `appuser` (UID 1000). If you have permission errors: + +```bash +# Check volume permissions +docker volume inspect dhamps-vdb_postgres_data +``` + +### Reset Everything + +```bash +# Stop and remove everything +docker-compose down -v + +# Remove images +docker rmi dhamps-vdb:latest +docker rmi pgvector/pgvector:0.7.4-pg16 + +# Start fresh +docker-compose up -d --build +``` + +### Build Failures + +If Docker build fails with network errors: + +```bash +# Try with host network +docker build --network=host -t dhamps-vdb:latest . +``` + +## Advanced Configuration + +### Resource Limits + +Add to `docker-compose.yml`: + +```yaml +services: + dhamps-vdb: + deploy: + resources: + limits: + cpus: '2' + memory: 2G + reservations: + cpus: '0.5' + memory: 512M +``` + +### Health Checks + +The Dockerfile includes a health check: + +```dockerfile +HEALTHCHECK --interval=30s --timeout=3s \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8880/ || exit 1 +``` + +View health status: + +```bash +docker inspect --format='{{.State.Health.Status}}' dhamps-vdb +``` + +### Custom Dockerfile Builds + +You can customize the build: + +```bash +docker build \ + --build-arg GO_VERSION=1.24 \ + -t dhamps-vdb:custom . +``` + +## External Database Setup + +If using an external PostgreSQL database: + +### Prepare Database + +```sql +-- Create database +CREATE DATABASE dhamps_vdb; + +-- Create user +CREATE USER dhamps_user WITH PASSWORD 'secure_password'; + +-- Grant privileges +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; + +-- Connect to database +\c dhamps_vdb + +-- Grant schema permissions +GRANT ALL ON SCHEMA public TO dhamps_user; + +-- Enable pgvector +CREATE EXTENSION IF NOT EXISTS vector; +``` + +### Configure dhamps-vdb + +Update `.env`: + +```bash +SERVICE_DBHOST=external-db.example.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=secure_password +SERVICE_DBNAME=dhamps_vdb +``` + +Then run only the dhamps-vdb service or use a standalone container. + +## Next Steps + +After successful deployment: + +1. [Configure the service](../configuration/) +2. [Create your first user](../quick-start/) +3. [Set up a project](../first-project/) +4. Review [security best practices](../../deployment/security/) diff --git a/docs/content/getting-started/first-project.md b/docs/content/getting-started/first-project.md new file mode 100644 index 0000000..a29c571 --- /dev/null +++ b/docs/content/getting-started/first-project.md @@ -0,0 +1,415 @@ +--- +title: "First Project" +weight: 4 +--- + +# First Project + +Step-by-step guide to creating your first complete project in dhamps-vdb. + +## Overview + +This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow: + +1. Set up authentication +2. Configure an LLM service +3. Create a project with metadata validation +4. Upload document embeddings +5. Search for similar documents +6. Share your project with collaborators + +## Step 1: Authentication Setup + +### Get Your API Key + +If you're an admin, create your first user: + +```bash +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "researcher1", + "name": "Research User", + "email": "researcher@example.com" + }' +``` + +Save the returned `vdb_key` to a variable: + +```bash +export USER_KEY="your-returned-vdb-key" +``` + +### Verify Authentication + +Test your API key: + +```bash +curl -X GET http://localhost:8880/v1/users/researcher1 \ + -H "Authorization: Bearer $USER_KEY" +``` + +## Step 2: Configure LLM Service + +### Option A: Use System Definition + +List available system definitions: + +```bash +curl -X GET http://localhost:8880/v1/llm-services/_system \ + -H "Authorization: Bearer $USER_KEY" +``` + +Create an instance from a system definition: + +```bash +curl -X PUT http://localhost:8880/v1/llm-services/researcher1/my-embeddings \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "description": "My OpenAI embeddings instance", + "api_key_encrypted": "sk-proj-your-openai-api-key" + }' +``` + +### Option B: Create Custom Instance + +Create a standalone instance with custom configuration: + +```bash +curl -X PUT http://localhost:8880/v1/llm-services/researcher1/custom-embeddings \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-small", + "dimensions": 1536, + "description": "Custom OpenAI small embeddings", + "api_key_encrypted": "sk-proj-your-api-key" + }' +``` + +## Step 3: Create Project with Metadata Schema + +Define a metadata schema to ensure consistent document metadata: + +```bash +curl -X POST http://localhost:8880/v1/projects/researcher1 \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "literature-analysis", + "description": "Literary texts for research analysis", + "instance_owner": "researcher1", + "instance_handle": "my-embeddings", + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\",\"enum\":[\"poetry\",\"prose\",\"drama\"]},\"language\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\",\"year\"]}" + }' +``` + +This schema requires `author`, `title`, and `year` fields, with optional `genre` and `language` fields. + +## Step 4: Upload Document Embeddings + +### Prepare Your Data + +Create a file `embeddings.json` with your document embeddings: + +```json +{ + "embeddings": [ + { + "text_id": "hamlet-act1-scene1", + "instance_handle": "my-embeddings", + "text": "Who's there? Nay, answer me: stand, and unfold yourself.", + "vector": [0.023, -0.015, 0.087, ...], + "vector_dim": 3072, + "metadata": { + "author": "William Shakespeare", + "title": "Hamlet", + "year": 1603, + "genre": "drama", + "language": "English" + } + }, + { + "text_id": "paradise-lost-book1-line1", + "instance_handle": "my-embeddings", + "text": "Of Man's first disobedience, and the fruit...", + "vector": [0.045, -0.032, 0.091, ...], + "vector_dim": 3072, + "metadata": { + "author": "John Milton", + "title": "Paradise Lost", + "year": 1667, + "genre": "poetry", + "language": "English" + } + } + ] +} +``` + +### Upload Embeddings + +```bash +curl -X POST http://localhost:8880/v1/embeddings/researcher1/literature-analysis \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d @embeddings.json +``` + +### Verify Upload + +List all embeddings: + +```bash +curl -X GET "http://localhost:8880/v1/embeddings/researcher1/literature-analysis?limit=10" \ + -H "Authorization: Bearer $USER_KEY" +``` + +Get a specific embedding: + +```bash +curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \ + -H "Authorization: Bearer $USER_KEY" +``` + +## Step 5: Search Similar Documents + +### Basic Similarity Search + +Find passages similar to Hamlet Act 1: + +```bash +curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&threshold=0.7" \ + -H "Authorization: Bearer $USER_KEY" +``` + +**Response:** + +```json +{ + "user_handle": "researcher1", + "project_handle": "literature-analysis", + "results": [ + { + "id": "hamlet-act2-scene1", + "similarity": 0.89 + }, + { + "id": "macbeth-act1-scene3", + "similarity": 0.82 + }, + { + "id": "othello-act3-scene3", + "similarity": 0.76 + } + ] +} +``` + +### Search with Metadata Filtering + +Exclude passages from the same work: + +```bash +curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&metadata_path=title&metadata_value=Hamlet" \ + -H "Authorization: Bearer $USER_KEY" +``` + +This excludes all documents where `metadata.title` equals "Hamlet". + +### Search with Raw Embeddings + +Search using a new embedding without storing it: + +```bash +curl -X POST "http://localhost:8880/v1/similars/researcher1/literature-analysis?count=5&threshold=0.7" \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [0.034, -0.021, 0.092, ...] + }' +``` + +## Step 6: Share Your Project + +### Share with Collaborators + +Grant read-only access to another user: + +```bash +curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "colleague1", + "role": "reader" + }' +``` + +Grant edit access: + +```bash +curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "colleague2", + "role": "editor" + }' +``` + +### Make Project Public + +Enable public read access (no authentication required): + +```bash +curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "public_read": true + }' +``` + +Now anyone can read embeddings and search without authentication: + +```bash +# No Authorization header needed +curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 +``` + +### View Shared Users + +List all users with access to your project: + +```bash +curl -X GET http://localhost:8880/v1/projects/researcher1/literature-analysis/shared-with \ + -H "Authorization: Bearer $USER_KEY" +``` + +## Step 7: Manage Your Project + +### Update Project Description + +```bash +curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated: Shakespearean and Renaissance literature analysis" + }' +``` + +### Update Metadata Schema + +```bash +curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\"},\"language\":{\"type\":\"string\"},\"act\":{\"type\":\"integer\"},\"scene\":{\"type\":\"integer\"}},\"required\":[\"author\",\"title\",\"year\"]}" + }' +``` + +### Delete Specific Embeddings + +```bash +curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \ + -H "Authorization: Bearer $USER_KEY" +``` + +### Delete All Embeddings + +```bash +curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis \ + -H "Authorization: Bearer $USER_KEY" +``` + +## Common Patterns + +### Batch Upload Script + +```bash +#!/bin/bash + +USER_KEY="your-vdb-key" +PROJECT="researcher1/literature-analysis" +API_URL="http://localhost:8880" + +# Process multiple files +for file in data/*.json; do + echo "Uploading $file..." + curl -X POST "$API_URL/v1/embeddings/$PROJECT" \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d @"$file" +done +``` + +### Search and Filter Workflow + +```bash +# 1. Find similar documents +SIMILAR=$(curl -s -X GET "$API_URL/v1/similars/$PROJECT/doc1?count=20" \ + -H "Authorization: Bearer $USER_KEY") + +# 2. Extract IDs +IDS=$(echo $SIMILAR | jq -r '.results[].id') + +# 3. Retrieve full embeddings for similar documents +for id in $IDS; do + curl -X GET "$API_URL/v1/embeddings/$PROJECT/$id" \ + -H "Authorization: Bearer $USER_KEY" +done +``` + +## Troubleshooting + +### Validation Errors + +If metadata validation fails: + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc1': year is required" +} +``` + +Check your metadata schema and ensure all required fields are present. + +### Dimension Mismatches + +If vector dimensions don't match: + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: expected 3072 dimensions, got 1536" +} +``` + +Verify your LLM service configuration and embedding dimensions. + +### Authentication Errors + +If you get 401 Unauthorized: + +- Check your API key is correct +- Ensure `Authorization: Bearer` prefix is included +- Verify the user owns the resource or has been granted access + +## Next Steps + +- [Learn about metadata validation](../guides/metadata-validation/) +- [Explore batch operations](../guides/batch-operations/) +- [Understand similarity search](../concepts/similarity-search/) +- [Review API documentation](../api/) diff --git a/docs/content/getting-started/installation.md b/docs/content/getting-started/installation.md new file mode 100644 index 0000000..ae9bcb1 --- /dev/null +++ b/docs/content/getting-started/installation.md @@ -0,0 +1,129 @@ +--- +title: "Installation" +weight: 1 +--- + +# Installation + +Install dhamps-vdb by compiling from source. + +## Prerequisites + +- **Go 1.21 or later** +- **PostgreSQL 11+** with pgvector extension +- **sqlc** for code generation + +## Quick Install + +```bash +# Clone the repository +git clone https://github.com/mpilhlt/dhamps-vdb.git +cd dhamps-vdb + +# Install dependencies and generate code +go get ./... +sqlc generate --no-remote + +# Build the binary +go build -o build/dhamps-vdb main.go +``` + +## Detailed Steps + +### 1. Install Dependencies + +Download all Go module dependencies: + +```bash +go get ./... +``` + +### 2. Generate Database Code + +Generate type-safe database queries using sqlc: + +```bash +sqlc generate --no-remote +``` + +This creates Go code from SQL queries in `internal/database/queries/`. + +### 3. Build the Application + +Compile the application: + +```bash +go build -o build/dhamps-vdb main.go +``` + +The binary will be created at `build/dhamps-vdb`. + +## Running Without Building + +You can run the application directly without building a binary: + +```bash +go run main.go +``` + +This is useful during development but slower than running a pre-built binary. + +## Verify Installation + +Check that the binary was created successfully: + +```bash +./build/dhamps-vdb --help +``` + +You should see the available command-line options. + +## Next Steps + +After installation, you need to: + +1. [Set up the database](../deployment/database/) +2. [Configure environment variables](configuration/) +3. [Run the service](quick-start/) + +## System Requirements + +- **Memory**: Minimum 512MB RAM (2GB+ recommended for production) +- **Disk**: Minimal (< 50MB for binary, database size varies) +- **CPU**: Any modern CPU (multi-core recommended for concurrent requests) + +## Troubleshooting + +### sqlc Command Not Found + +Install sqlc: + +```bash +go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest +``` + +Make sure `$GOPATH/bin` is in your PATH. + +### Build Errors + +Ensure you're using Go 1.21 or later: + +```bash +go version +``` + +Clean the build cache if you encounter issues: + +```bash +go clean -cache +go build -o build/dhamps-vdb main.go +``` + +### Missing Dependencies + +Force update all dependencies: + +```bash +go mod download +go get -u ./... +``` diff --git a/docs/content/getting-started/quick-start.md b/docs/content/getting-started/quick-start.md new file mode 100644 index 0000000..5237db1 --- /dev/null +++ b/docs/content/getting-started/quick-start.md @@ -0,0 +1,292 @@ +--- +title: "Quick Start" +weight: 3 +--- + +# Quick Start + +Complete walkthrough from installation to searching similar documents using curl. + +## Prerequisites + +- dhamps-vdb installed and running +- Admin API key configured +- PostgreSQL with pgvector ready + +## 1. Create a User + +Create a new user with the admin API key: + +```bash +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "alice", + "name": "Alice Smith", + "email": "alice@example.com" + }' +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Smith", + "email": "alice@example.com", + "vdb_key": "024v2013621509245f2e24...", + "created_at": "2024-01-15T10:30:00Z" +} +``` + +**Save the `vdb_key`** - it cannot be recovered later. + +## 2. Create an LLM Service Instance + +Create an LLM service configuration: + +```bash +curl -X PUT http://localhost:8880/v1/llm-services/alice/my-openai \ + -H "Authorization: Bearer alice_vdb_key" \ + -H "Content-Type: application/json" \ + -d '{ + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "OpenAI large embeddings", + "api_key_encrypted": "sk-proj-your-openai-key" + }' +``` + +**Response:** + +```json +{ + "instance_id": 1, + "instance_handle": "my-openai", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "model": "text-embedding-3-large", + "dimensions": 3072 +} +``` + +## 3. Create a Project + +Create a project to organize your embeddings: + +```bash +curl -X POST http://localhost:8880/v1/projects/alice \ + -H "Authorization: Bearer alice_vdb_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-docs", + "description": "Research document embeddings", + "instance_owner": "alice", + "instance_handle": "my-openai" + }' +``` + +**Response:** + +```json +{ + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Research document embeddings", + "instance_id": 1, + "created_at": "2024-01-15T10:35:00Z" +} +``` + +## 4. Upload Embeddings + +Upload document embeddings to your project: + +```bash +curl -X POST http://localhost:8880/v1/embeddings/alice/research-docs \ + -H "Authorization: Bearer alice_vdb_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + { + "text_id": "doc1", + "instance_handle": "my-openai", + "text": "Introduction to machine learning", + "vector": [0.1, 0.2, 0.3, ..., 0.5], + "vector_dim": 3072, + "metadata": { + "title": "ML Intro", + "author": "Alice", + "year": 2024 + } + }, + { + "text_id": "doc2", + "instance_handle": "my-openai", + "text": "Deep learning fundamentals", + "vector": [0.15, 0.25, 0.35, ..., 0.55], + "vector_dim": 3072, + "metadata": { + "title": "DL Fundamentals", + "author": "Bob", + "year": 2024 + } + } + ] + }' +``` + +**Response:** + +```json +{ + "message": "2 embeddings uploaded successfully" +} +``` + +## 5. Search for Similar Documents + +### Option A: Search Using Stored Document + +Find documents similar to an already-stored document: + +```bash +curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_vdb_key" +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "project_handle": "research-docs", + "results": [ + { + "id": "doc2", + "similarity": 0.92 + }, + { + "id": "doc5", + "similarity": 0.85 + } + ] +} +``` + +### Option B: Search Using Raw Embeddings + +Search without storing the query embedding: + +```bash +curl -X POST "http://localhost:8880/v1/similars/alice/research-docs?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_vdb_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [0.12, 0.22, 0.32, ..., 0.52] + }' +``` + +## 6. Filter by Metadata + +Exclude documents from a specific author when searching: + +```bash +curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&metadata_path=author&metadata_value=Alice" \ + -H "Authorization: Bearer alice_vdb_key" +``` + +This excludes all documents where `metadata.author` equals "Alice". + +## 7. Retrieve Embeddings + +Get all embeddings in your project: + +```bash +curl -X GET "http://localhost:8880/v1/embeddings/alice/research-docs?limit=10&offset=0" \ + -H "Authorization: Bearer alice_vdb_key" +``` + +Get a specific embedding: + +```bash +curl -X GET http://localhost:8880/v1/embeddings/alice/research-docs/doc1 \ + -H "Authorization: Bearer alice_vdb_key" +``` + +## Complete Workflow Example + +Here's a complete script to get started: + +```bash +#!/bin/bash + +# Configuration +API_URL="http://localhost:8880" +ADMIN_KEY="your-admin-key" + +# 1. Create user +USER_RESPONSE=$(curl -s -X POST "$API_URL/v1/users" \ + -H "Authorization: Bearer $ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{"user_handle":"alice","name":"Alice Smith","email":"alice@example.com"}') + +USER_KEY=$(echo $USER_RESPONSE | jq -r '.vdb_key') +echo "User created with key: $USER_KEY" + +# 2. Create LLM service instance +curl -X PUT "$API_URL/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-your-key" + }' + +# 3. Create project +curl -X POST "$API_URL/v1/projects/alice" \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-docs", + "description": "Research documents", + "instance_owner": "alice", + "instance_handle": "my-openai" + }' + +# 4. Upload embeddings +curl -X POST "$API_URL/v1/embeddings/alice/research-docs" \ + -H "Authorization: Bearer $USER_KEY" \ + -H "Content-Type: application/json" \ + -d @embeddings.json + +# 5. Search similar +curl -X GET "$API_URL/v1/similars/alice/research-docs/doc1?count=5" \ + -H "Authorization: Bearer $USER_KEY" + +echo "Setup complete!" +``` + +## API Documentation + +For complete API documentation, visit: + +```bash +curl http://localhost:8880/docs +``` + +Or open http://localhost:8880/docs in your browser. + +## Next Steps + +- [Learn about projects](../concepts/projects/) +- [Understand embeddings](../concepts/embeddings/) +- [Explore sharing projects](../guides/project-sharing/) +- [Set up metadata validation](../guides/metadata-validation/) diff --git a/docs/content/guides/_index.md b/docs/content/guides/_index.md new file mode 100644 index 0000000..9b042cf --- /dev/null +++ b/docs/content/guides/_index.md @@ -0,0 +1,23 @@ +--- +title: "Guides" +weight: 3 +--- + +# User Guides + +Step-by-step guides for common tasks and workflows with dhamps-vdb. + +## Available Guides + +This section contains practical guides for using dhamps-vdb in real-world scenarios: + +- **RAG Workflows** - Implement Retrieval Augmented Generation +- **Project Sharing** - Collaborate with other users +- **Public Projects** - Enable unauthenticated access +- **Ownership Transfer** - Move projects between users +- **Metadata Validation** - Ensure data quality with schemas +- **Metadata Filtering** - Exclude documents from similarity search +- **Batch Operations** - Work with multiple embeddings efficiently +- **Instance Management** - Configure LLM service instances + +These guides complement the API reference by providing context and best practices for common use cases. diff --git a/docs/content/guides/batch-operations.md b/docs/content/guides/batch-operations.md new file mode 100644 index 0000000..aaac38c --- /dev/null +++ b/docs/content/guides/batch-operations.md @@ -0,0 +1,718 @@ +--- +title: "Batch Operations Guide" +weight: 7 +--- + +# Batch Operations Guide + +This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb. + +## Overview + +For production workloads and large datasets, efficient batch operations are essential. This guide covers: +- Uploading multiple embeddings in a single request +- Pagination strategies for large result sets +- Best practices for performance and reliability +- Error handling in batch operations + +## Batch Upload Basics + +### Single Request with Multiple Embeddings + +Upload multiple embeddings in one API call using the `embeddings` array: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + { + "text_id": "doc001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "text": "First document content", + "metadata": {"category": "science"} + }, + { + "text_id": "doc002", + "instance_handle": "openai-large", + "vector": [0.11, 0.21, 0.31, ...], + "vector_dim": 3072, + "text": "Second document content", + "metadata": {"category": "history"} + }, + { + "text_id": "doc003", + "instance_handle": "openai-large", + "vector": [0.12, 0.22, 0.32, ...], + "vector_dim": 3072, + "text": "Third document content", + "metadata": {"category": "literature"} + } + ] + }' +``` + +**Response:** +```json +{ + "message": "Embeddings uploaded successfully", + "count": 3 +} +``` + +## Optimal Batch Sizes + +### Recommended Batch Sizes + +Based on typical embedding dimensions and network constraints: + +| Embedding Dimensions | Recommended Batch Size | Maximum Batch Size | +|---------------------|------------------------|-------------------| +| 384 (small models) | 500-1000 | 2000 | +| 768 (BERT-base) | 300-500 | 1000 | +| 1536 (OpenAI small) | 100-300 | 500 | +| 3072 (OpenAI large) | 50-100 | 200 | + +**Factors to consider:** +- Network bandwidth and latency +- API gateway timeout limits +- Database transaction size +- Memory constraints +- Client-side serialization limits + +### Finding Your Optimal Batch Size + +Test different batch sizes to find the sweet spot: + +```python +import time +import requests + +def test_batch_size(embeddings, batch_size): + """Test upload performance with given batch size""" + start_time = time.time() + + for i in range(0, len(embeddings), batch_size): + batch = embeddings[i:i+batch_size] + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" + }, + json={"embeddings": batch} + ) + response.raise_for_status() + + elapsed = time.time() - start_time + throughput = len(embeddings) / elapsed + print(f"Batch size {batch_size}: {throughput:.1f} embeddings/sec") + +# Test different batch sizes +for size in [50, 100, 200, 500]: + test_batch_size(my_embeddings, size) +``` + +## Pagination for Large Datasets + +### Retrieving All Embeddings with Pagination + +Use `limit` and `offset` parameters to paginate through large result sets: + +```bash +# Get first page (embeddings 0-99) +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=0" \ + -H "Authorization: Bearer alice_api_key" + +# Get second page (embeddings 100-199) +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=100" \ + -H "Authorization: Bearer alice_api_key" + +# Get third page (embeddings 200-299) +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=200" \ + -H "Authorization: Bearer alice_api_key" +``` + +### Pagination Best Practices + +**Default Values:** +- `limit`: 10 (if not specified) +- `offset`: 0 (if not specified) +- Maximum `limit`: 200 + +**Example: Download Entire Project** + +```python +import requests + +def download_all_embeddings(owner, project): + """Download all embeddings from a project""" + all_embeddings = [] + offset = 0 + limit = 100 + + while True: + response = requests.get( + f"https://api.example.com/v1/embeddings/{owner}/{project}", + headers={"Authorization": "Bearer api_key"}, + params={"limit": limit, "offset": offset} + ) + response.raise_for_status() + + batch = response.json()['embeddings'] + if not batch: + break # No more results + + all_embeddings.extend(batch) + offset += len(batch) + + print(f"Downloaded {len(all_embeddings)} embeddings...") + + return all_embeddings + +# Usage +embeddings = download_all_embeddings("alice", "my-project") +print(f"Total: {len(embeddings)} embeddings") +``` + +## Efficient Batch Upload Strategies + +### Strategy 1: Simple Sequential Upload + +Good for small to medium datasets (< 10,000 embeddings): + +```python +def upload_sequential(embeddings, batch_size=100): + """Upload embeddings sequentially in batches""" + for i in range(0, len(embeddings), batch_size): + batch = embeddings[i:i+batch_size] + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" + }, + json={"embeddings": batch} + ) + response.raise_for_status() + print(f"Uploaded batch {i//batch_size + 1}, total: {i+len(batch)}") +``` + +### Strategy 2: Parallel Upload with Threading + +Good for larger datasets with stable network: + +```python +import concurrent.futures +import requests + +def upload_batch(batch, batch_num): + """Upload a single batch""" + try: + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" + }, + json={"embeddings": batch}, + timeout=60 + ) + response.raise_for_status() + return batch_num, True, None + except Exception as e: + return batch_num, False, str(e) + +def upload_parallel(embeddings, batch_size=100, max_workers=4): + """Upload embeddings in parallel""" + batches = [ + embeddings[i:i+batch_size] + for i in range(0, len(embeddings), batch_size) + ] + + failed = [] + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + futures = { + executor.submit(upload_batch, batch, i): i + for i, batch in enumerate(batches) + } + + for future in concurrent.futures.as_completed(futures): + batch_num, success, error = future.result() + if success: + print(f"✓ Batch {batch_num+1}/{len(batches)} uploaded") + else: + print(f"✗ Batch {batch_num+1} failed: {error}") + failed.append((batch_num, batches[batch_num])) + + return failed + +# Usage +failed_batches = upload_parallel(my_embeddings, batch_size=100, max_workers=4) +if failed_batches: + print(f"Failed batches: {len(failed_batches)}") +``` + +### Strategy 3: Retry with Exponential Backoff + +Robust strategy for unreliable networks: + +```python +import time +import random + +def upload_with_retry(batch, max_retries=3): + """Upload batch with exponential backoff retry""" + for attempt in range(max_retries): + try: + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" + }, + json={"embeddings": batch}, + timeout=60 + ) + response.raise_for_status() + return True + except requests.exceptions.RequestException as e: + if attempt < max_retries - 1: + wait = (2 ** attempt) + random.uniform(0, 1) + print(f"Retry attempt {attempt+1} after {wait:.1f}s: {e}") + time.sleep(wait) + else: + print(f"Failed after {max_retries} attempts: {e}") + return False + +def upload_robust(embeddings, batch_size=100): + """Upload with robust error handling""" + failed = [] + for i in range(0, len(embeddings), batch_size): + batch = embeddings[i:i+batch_size] + if not upload_with_retry(batch): + failed.append((i, batch)) + else: + print(f"✓ Uploaded {i+batch_size}/{len(embeddings)}") + + return failed +``` + +## Progress Tracking and Resumability + +### Checkpoint-Based Upload + +For very large datasets, implement checkpointing to resume after failures: + +```python +import json +import os + +class CheckpointUploader: + def __init__(self, checkpoint_file="upload_progress.json"): + self.checkpoint_file = checkpoint_file + self.progress = self.load_progress() + + def load_progress(self): + """Load upload progress from checkpoint file""" + if os.path.exists(self.checkpoint_file): + with open(self.checkpoint_file, 'r') as f: + return json.load(f) + return {"uploaded_count": 0, "failed_batches": []} + + def save_progress(self): + """Save current progress""" + with open(self.checkpoint_file, 'w') as f: + json.dump(self.progress, f) + + def upload(self, embeddings, batch_size=100): + """Upload with checkpointing""" + start_idx = self.progress["uploaded_count"] + + for i in range(start_idx, len(embeddings), batch_size): + batch = embeddings[i:i+batch_size] + + try: + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" + }, + json={"embeddings": batch}, + timeout=60 + ) + response.raise_for_status() + + self.progress["uploaded_count"] = i + len(batch) + self.save_progress() + print(f"✓ Progress: {self.progress['uploaded_count']}/{len(embeddings)}") + + except Exception as e: + print(f"✗ Failed at index {i}: {e}") + self.progress["failed_batches"].append(i) + self.save_progress() + raise + +# Usage +uploader = CheckpointUploader() +try: + uploader.upload(my_embeddings, batch_size=100) + print("Upload complete!") +except: + print("Upload interrupted. Run again to resume.") +``` + +## Error Handling + +### Validation Errors + +If any embedding in a batch fails validation, the entire batch is rejected: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + { + "text_id": "doc001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3], + "vector_dim": 3072, + "metadata": {"author": "Alice"} + }, + { + "text_id": "doc002", + "instance_handle": "openai-large", + "vector": [0.1, 0.2], + "vector_dim": 3072, + "metadata": {"author": "Bob"} + } + ] + }' +``` + +**Error Response:** +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector length mismatch for text_id 'doc002': actual vector has 2 elements but vector_dim declares 3072" +} +``` + +**Solution:** Validate all embeddings before batching, or handle errors and retry failed items. + +### Pre-Upload Validation + +```python +def validate_embeddings(embeddings, expected_dim): + """Validate embeddings before upload""" + errors = [] + + for i, emb in enumerate(embeddings): + # Check vector length + if len(emb['vector']) != expected_dim: + errors.append(f"Index {i} (text_id: {emb['text_id']}): " + f"vector length {len(emb['vector'])} != {expected_dim}") + + # Check declared dimension + if emb.get('vector_dim') != expected_dim: + errors.append(f"Index {i} (text_id: {emb['text_id']}): " + f"vector_dim {emb.get('vector_dim')} != {expected_dim}") + + # Check required fields + if not emb.get('text_id'): + errors.append(f"Index {i}: missing text_id") + + if not emb.get('instance_handle'): + errors.append(f"Index {i}: missing instance_handle") + + return errors + +# Usage +errors = validate_embeddings(my_embeddings, 3072) +if errors: + print("Validation errors:") + for error in errors: + print(f" - {error}") +else: + print("All embeddings valid, proceeding with upload...") +``` + +## Performance Optimization Tips + +### 1. Minimize Payload Size + +Exclude unnecessary fields: + +```python +# Include text only if needed for retrieval +embeddings_with_text = [ + { + "text_id": doc_id, + "instance_handle": "openai-large", + "vector": vector, + "vector_dim": 3072, + "text": text, # Include if needed + "metadata": metadata + } + for doc_id, vector, text, metadata in documents +] + +# Exclude text if not needed (smaller payload) +embeddings_without_text = [ + { + "text_id": doc_id, + "instance_handle": "openai-large", + "vector": vector, + "vector_dim": 3072, + "metadata": metadata + } + for doc_id, vector, metadata in documents +] +``` + +### 2. Compress Requests + +Use gzip compression for large payloads: + +```python +import gzip +import json + +def upload_compressed(embeddings): + """Upload with gzip compression""" + payload = json.dumps({"embeddings": embeddings}) + compressed = gzip.compress(payload.encode('utf-8')) + + response = requests.post( + "https://api.example.com/v1/embeddings/alice/my-project", + headers={ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json", + "Content-Encoding": "gzip" + }, + data=compressed + ) + return response +``` + +### 3. Use Connection Pooling + +Reuse HTTP connections for multiple requests: + +```python +session = requests.Session() +session.headers.update({ + "Authorization": "Bearer alice_api_key", + "Content-Type": "application/json" +}) + +for batch in batches: + response = session.post( + "https://api.example.com/v1/embeddings/alice/my-project", + json={"embeddings": batch} + ) + response.raise_for_status() +``` + +### 4. Monitor Upload Rate + +Track and display upload progress: + +```python +import time + +class ProgressTracker: + def __init__(self, total): + self.total = total + self.uploaded = 0 + self.start_time = time.time() + + def update(self, count): + self.uploaded += count + elapsed = time.time() - self.start_time + rate = self.uploaded / elapsed if elapsed > 0 else 0 + percent = (self.uploaded / self.total) * 100 + eta = (self.total - self.uploaded) / rate if rate > 0 else 0 + + print(f"\rProgress: {self.uploaded}/{self.total} ({percent:.1f}%) " + f"Rate: {rate:.1f} emb/s ETA: {eta:.0f}s", end="") + +# Usage +tracker = ProgressTracker(len(all_embeddings)) +for batch in batches: + upload_batch(batch) + tracker.update(len(batch)) +print() # New line after completion +``` + +## Complete Example: Production-Grade Uploader + +```python +import requests +import time +import json +import logging +from concurrent.futures import ThreadPoolExecutor, as_completed +from typing import List, Dict, Tuple + +class ProductionUploader: + def __init__(self, api_base: str, api_key: str, + owner: str, project: str): + self.api_base = api_base + self.api_key = api_key + self.owner = owner + self.project = project + self.session = requests.Session() + self.session.headers.update({ + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + }) + + logging.basicConfig(level=logging.INFO) + self.logger = logging.getLogger(__name__) + + def upload_batch(self, batch: List[Dict], batch_num: int, + max_retries: int = 3) -> Tuple[int, bool, str]: + """Upload a single batch with retry logic""" + url = f"{self.api_base}/v1/embeddings/{self.owner}/{self.project}" + + for attempt in range(max_retries): + try: + response = self.session.post( + url, + json={"embeddings": batch}, + timeout=60 + ) + response.raise_for_status() + return batch_num, True, "" + except Exception as e: + if attempt < max_retries - 1: + wait = 2 ** attempt + self.logger.warning( + f"Batch {batch_num} attempt {attempt+1} failed: {e}. " + f"Retrying in {wait}s..." + ) + time.sleep(wait) + else: + return batch_num, False, str(e) + + def upload(self, embeddings: List[Dict], batch_size: int = 100, + max_workers: int = 4) -> Dict: + """Upload embeddings with parallel processing and progress tracking""" + batches = [ + embeddings[i:i+batch_size] + for i in range(0, len(embeddings), batch_size) + ] + + results = { + "total": len(embeddings), + "uploaded": 0, + "failed": [], + "start_time": time.time() + } + + self.logger.info(f"Uploading {len(embeddings)} embeddings in " + f"{len(batches)} batches...") + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + futures = { + executor.submit(self.upload_batch, batch, i): i + for i, batch in enumerate(batches) + } + + for future in as_completed(futures): + batch_num, success, error = future.result() + + if success: + results["uploaded"] += len(batches[batch_num]) + percent = (results["uploaded"] / results["total"]) * 100 + self.logger.info( + f"✓ Batch {batch_num+1}/{len(batches)} " + f"({percent:.1f}% complete)" + ) + else: + results["failed"].append({ + "batch_num": batch_num, + "error": error, + "embeddings": batches[batch_num] + }) + self.logger.error(f"✗ Batch {batch_num+1} failed: {error}") + + results["elapsed"] = time.time() - results["start_time"] + results["rate"] = results["uploaded"] / results["elapsed"] + + self.logger.info( + f"\nUpload complete: {results['uploaded']}/{results['total']} " + f"in {results['elapsed']:.1f}s ({results['rate']:.1f} emb/s)" + ) + + if results["failed"]: + self.logger.warning(f"Failed batches: {len(results['failed'])}") + + return results + +# Usage +uploader = ProductionUploader( + api_base="https://api.example.com", + api_key="alice_api_key", + owner="alice", + project="my-project" +) + +results = uploader.upload( + embeddings=my_embeddings, + batch_size=100, + max_workers=4 +) + +# Save failed batches for retry +if results["failed"]: + with open("failed_batches.json", "w") as f: + json.dump(results["failed"], f) +``` + +## Best Practices Summary + +1. **Batch Size**: Test to find optimal size (typically 50-500 depending on dimensions) +2. **Parallelism**: Use 2-8 parallel workers for large uploads +3. **Retry Logic**: Implement exponential backoff for network errors +4. **Validation**: Pre-validate embeddings before upload +5. **Progress Tracking**: Monitor upload rate and ETA +6. **Checkpointing**: Save progress for resumable uploads +7. **Error Logging**: Log all errors with sufficient context +8. **Connection Reuse**: Use session objects for connection pooling +9. **Compression**: Use gzip for large payloads +10. **Testing**: Test with small batches before full upload + +## Related Documentation + +- [RAG Workflow Guide](./rag-workflow.md) - Complete RAG implementation +- [Metadata Validation Guide](./metadata-validation.md) - Schema validation +- [Instance Management Guide](./instance-management.md) - Managing LLM instances + +## Troubleshooting + +### Timeout Errors + +**Problem:** Requests timing out with large batches + +**Solution:** Reduce batch size or increase timeout value + +### Memory Issues + +**Problem:** Out of memory when processing large datasets + +**Solution:** Process embeddings in streaming fashion, don't load all into memory + +### Rate Limiting + +**Problem:** Getting rate limited by API + +**Solution:** Reduce parallelism (max_workers) or add delays between requests diff --git a/docs/content/guides/instance-management.md b/docs/content/guides/instance-management.md new file mode 100644 index 0000000..e09a871 --- /dev/null +++ b/docs/content/guides/instance-management.md @@ -0,0 +1,634 @@ +--- +title: "Instance Management Guide" +weight: 8 +--- + +# Instance Management Guide + +This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings. + +## Overview + +LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes: +- API endpoint and credentials +- Model name and version +- Vector dimensions +- API standard (protocol) + +Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work. + +## Instance Architecture + +### System Definitions + +The system provides pre-configured templates for common LLM services: + +```bash +# List available system definitions (no auth required) +curl -X GET "https://api.example.com/v1/llm-service-definitions/_system" +``` + +**Default System Definitions:** +- `openai-large`: OpenAI text-embedding-3-large (3072 dimensions) +- `openai-small`: OpenAI text-embedding-3-small (1536 dimensions) +- `cohere-v4`: Cohere Embed v4 (1536 dimensions) +- `gemini-embedding-001`: Google Gemini embedding-001 (3072 dimensions, default size) + +### User Instances + +Users create instances for their own use. Instances contain: +- Configuration (endpoint, model, dimensions) +- Encrypted API keys (write-only, never returned) +- Optional reference to a definition template + +## Creating LLM Service Instances + +### Option 1: Standalone Instance + +Create an instance by specifying all configuration fields: + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "my-openai", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "OpenAI large embedding model for research", + "api_key_encrypted": "sk-proj-your-openai-api-key-here" + }' +``` + +**Response:** +```json +{ + "instance_id": 123, + "instance_handle": "my-openai", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "OpenAI large embedding model for research" +} +``` + +**Note:** The `api_key_encrypted` field is not returned in the response for security reasons. + +### Option 2: From System Definition + +Create an instance based on a system template (only requires API key): + +```bash +curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai-instance" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "my-openai-instance", + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "sk-proj-your-openai-api-key-here" + }' +``` + +This inherits configuration from the `_system/openai-large` definition and only requires you to provide your API key. + +### Option 3: From User Definition + +Users can create their own definitions as templates: + +```bash +# Step 1: Create a custom definition +curl -X PUT "https://api.example.com/v1/llm-service-definitions/alice/my-custom-config" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "definition_handle": "my-custom-config", + "endpoint": "https://custom-api.example.com/embeddings", + "api_standard": "openai", + "model": "custom-model-v2", + "dimensions": 2048, + "description": "Custom embedding service" + }' + +# Step 2: Create instance from that definition +curl -X POST "https://api.example.com/v1/llm-services/alice/custom-instance" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "custom-instance", + "definition_owner": "alice", + "definition_handle": "my-custom-config", + "api_key_encrypted": "your-api-key-here" + }' +``` + +## Managing Instances + +### List Your Instances + +Get all instances you own or have access to: + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** +```json +{ + "owned_instances": [ + { + "instance_id": 123, + "instance_handle": "my-openai", + "endpoint": "https://api.openai.com/v1/embeddings", + "model": "text-embedding-3-large", + "dimensions": 3072 + }, + { + "instance_id": 124, + "instance_handle": "my-cohere", + "endpoint": "https://api.cohere.ai/v1/embed", + "model": "embed-english-v4.0", + "dimensions": 1536 + } + ], + "shared_instances": [ + { + "instance_id": 456, + "instance_handle": "team-openai", + "owner": "bob", + "endpoint": "https://api.openai.com/v1/embeddings", + "model": "text-embedding-3-large", + "dimensions": 3072, + "role": "reader" + } + ] +} +``` + +### Get Instance Details + +Retrieve details for a specific instance: + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" +``` + +### Update Instance + +Update instance configuration (owner only): + +```bash +curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated description", + "api_key_encrypted": "sk-proj-new-api-key-here" + }' +``` + +### Delete Instance + +Delete an instance (owner only): + +```bash +curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Note:** Cannot delete instances that are used by existing projects. + +## API Key Encryption + +### How Encryption Works + +API keys are encrypted using AES-256-GCM encryption: + +1. **Encryption Key Source**: `ENCRYPTION_KEY` environment variable +2. **Key Derivation**: SHA256 hash of the environment variable (ensures 32-byte key) +3. **Algorithm**: AES-256-GCM (authenticated encryption) +4. **Storage**: Encrypted bytes stored in `api_key_encrypted` column + +### Setting Up Encryption + +Add to your environment configuration: + +```bash +# .env file +ENCRYPTION_KEY="your-secure-random-32-character-key-or-longer" +``` + +**Important Security Notes:** +- Keep this key secure and backed up +- Losing the key means losing access to encrypted API keys +- Use a strong, random string (32+ characters) +- Never commit the key to version control +- Rotate the key periodically (requires re-encrypting all API keys) + +### API Key Security + +API keys are **write-only** in the API: + +```bash +# Upload API key (works) +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-instance" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"api_key_encrypted": "sk-..."}' + +# Retrieve instance (API key NOT returned) +curl -X GET "https://api.example.com/v1/llm-services/alice/my-instance" \ + -H "Authorization: Bearer alice_api_key" + +# Response does NOT include api_key_encrypted field +{ + "instance_id": 123, + "instance_handle": "my-instance", + "endpoint": "https://api.openai.com/v1/embeddings", + "model": "text-embedding-3-large", + "dimensions": 3072 + // No api_key_encrypted field! +} +``` + +This protects API keys from: +- Accidental exposure in logs +- Unauthorized access via shared instances +- Client-side data breaches + +## Instance Sharing + +### Share an Instance + +Grant another user access to your instance: + +```bash +curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "bob", + "role": "reader" + }' +``` + +**Roles:** +- `reader`: Can use the instance in projects (read-only) +- `editor`: Can use the instance (currently same as reader) +- `owner`: Full control (only one owner, the creator) + +### List Shared Users + +See who has access to your instance: + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai/shared-with" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** +```json +{ + "instance_handle": "my-openai", + "owner": "alice", + "shared_with": [ + {"user_handle": "bob", "role": "reader"}, + {"user_handle": "charlie", "role": "reader"} + ] +} +``` + +### Unshare an Instance + +Revoke access: + +```bash +curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai/share/bob" \ + -H "Authorization: Bearer alice_api_key" +``` + +### Using Shared Instances + +Bob can reference Alice's shared instance in his projects: + +```bash +# Bob creates a project using Alice's instance +curl -X PUT "https://api.example.com/v1/projects/bob/my-project" \ + -H "Authorization: Bearer bob_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-project", + "description": "Using shared instance", + "instance_owner": "alice", + "instance_handle": "my-openai" + }' + +# Bob uploads embeddings using the shared instance +curl -X POST "https://api.example.com/v1/embeddings/bob/my-project" \ + -H "Authorization: Bearer bob_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc001", + "instance_handle": "alice/my-openai", + "vector": [0.1, 0.2, ...], + "vector_dim": 3072 + }] + }' +``` + +**Important:** Bob can use the instance but cannot see Alice's API key. + +## Instance Sharing Patterns + +### Team Shared Instance + +A team lead creates and shares an instance for the team: + +```bash +# Team lead creates instance +curl -X PUT "https://api.example.com/v1/llm-services/team_lead/team-openai" \ + -H "Authorization: Bearer team_lead_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "team-openai", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-proj-team-api-key" + }' + +# Share with team members +for member in alice bob charlie; do + curl -X POST "https://api.example.com/v1/llm-services/team_lead/team-openai/share" \ + -H "Authorization: Bearer team_lead_api_key" \ + -H "Content-Type: application/json" \ + -d "{\"share_with_handle\": \"$member\", \"role\": \"reader\"}" +done +``` + +### Organization-Wide Instance + +Create a shared instance for organization-wide use: + +```bash +# Organization admin creates instance +curl -X PUT "https://api.example.com/v1/llm-services/org_admin/org-embeddings" \ + -H "Authorization: Bearer org_admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "org-embeddings", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "Organization-wide embedding service", + "api_key_encrypted": "sk-proj-org-api-key" + }' +``` + +### Per-Project Instance + +Each project maintainer creates their own instance: + +```bash +# Alice creates her own instance for her project +curl -X PUT "https://api.example.com/v1/llm-services/alice/research-embeddings" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "research-embeddings", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-proj-alice-research-key" + }' +``` + +## Common Configurations + +### OpenAI Configuration + +```json +{ + "instance_handle": "openai-large", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-proj-..." +} +``` + +### Cohere Configuration + +```json +{ + "instance_handle": "cohere-english", + "endpoint": "https://api.cohere.ai/v1/embed", + "api_standard": "cohere", + "model": "embed-english-v4.0", + "dimensions": 1536, + "api_key_encrypted": "your-cohere-api-key" +} +``` + +### Google Gemini Configuration + +```json +{ + "instance_handle": "gemini-embedding", + "endpoint": "https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent", + "api_standard": "gemini", + "model": "embedding-001", + "dimensions": 3072, + "api_key_encrypted": "your-gemini-api-key" +} +``` + +### Custom/Self-Hosted Service + +```json +{ + "instance_handle": "custom-service", + "endpoint": "https://custom-api.example.com/v1/embeddings", + "api_standard": "openai", + "model": "custom-model-v2", + "dimensions": 2048, + "description": "Self-hosted embedding service", + "api_key_encrypted": "custom-auth-token" +} +``` + +## Projects and Instances + +### 1:1 Relationship + +Each project must reference exactly one instance: + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-project", + "description": "Project with instance", + "instance_id": 123 + }' +``` + +### Changing Instance + +Update a project to use a different instance: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"instance_id": 456}' +``` + +**Note:** Only switch to instances with matching dimensions, or you'll get validation errors on future uploads. + +### Finding Instance for Project + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" +``` + +The response includes the `instance_id` field. + +## Best Practices + +### 1. Use System Definitions + +Start with system definitions for common services: + +```bash +# Easiest approach +curl -X POST "https://api.example.com/v1/llm-services/alice/my-instance" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "my-instance", + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "sk-..." + }' +``` + +### 2. Descriptive Instance Names + +Use clear, descriptive names: + +```bash +# Good names +"research-openai-large" +"prod-cohere-english" +"test-gemini-embedding" + +# Avoid generic names +"instance1" +"my-instance" +"test" +``` + +### 3. Separate Production and Development + +Create separate instances for different environments: + +```bash +# Development instance +curl -X PUT "https://api.example.com/v1/llm-services/alice/dev-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"instance_handle": "dev-openai", ...}' + +# Production instance +curl -X PUT "https://api.example.com/v1/llm-services/alice/prod-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"instance_handle": "prod-openai", ...}' +``` + +### 4. Document Instance Purpose + +Use the description field: + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/team-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "team-openai", + "description": "Shared OpenAI instance for research team. Contact alice@example.com for access.", + ... + }' +``` + +### 5. Regular Key Rotation + +Periodically update API keys: + +```bash +curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"api_key_encrypted": "sk-proj-new-key-here"}' +``` + +### 6. Monitor Instance Usage + +Track which projects use each instance to avoid deleting in-use instances. + +## Troubleshooting + +### Cannot Delete Instance + +**Error:** "Instance is in use by existing projects" + +**Solution:** Delete or update projects using this instance first. + +### Dimension Mismatch + +**Error:** "vector dimension mismatch" + +**Solution:** Ensure embeddings match the instance's configured dimensions. + +### API Key Not Working + +**Problem:** Embeddings uploads fail with authentication errors + +**Solution:** +1. Verify API key is correct +2. Check API key permissions with the LLM provider +3. Update the API key in the instance + +### Cannot Access Shared Instance + +**Problem:** Getting "Instance not found" errors + +**Solution:** Verify you've been granted access. Contact the instance owner. + +## Related Documentation + +- [RAG Workflow Guide](./rag-workflow.md) - Complete RAG implementation +- [Project Sharing Guide](./project-sharing.md) - Share projects with users +- [Batch Operations Guide](./batch-operations.md) - Upload embeddings efficiently + +## Security Summary + +1. **API keys are encrypted** at rest using AES-256-GCM +2. **API keys are never returned** via GET requests +3. **Shared users cannot see API keys** (write-only field) +4. **Encryption key must be secured** (loss means cannot decrypt keys) +5. **Regular key rotation recommended** for production use diff --git a/docs/content/guides/metadata-filtering.md b/docs/content/guides/metadata-filtering.md new file mode 100644 index 0000000..3a27b48 --- /dev/null +++ b/docs/content/guides/metadata-filtering.md @@ -0,0 +1,468 @@ +--- +title: "Metadata Filtering Guide" +weight: 6 +--- + +# Metadata Filtering Guide + +This guide explains how to use metadata filtering to exclude specific documents from similarity search results. + +## Overview + +When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example: +- Exclude documents from the same author when finding similar writing styles +- Filter out documents from the same source when finding related content +- Exclude documents with the same category when exploring diversity + +dhamps-vdb provides metadata filtering using query parameters that perform **negative matching** - they exclude documents where the metadata field matches the specified value. + +## Query Parameters + +Both similarity search endpoints support metadata filtering: + +- `metadata_path`: The JSON path to the metadata field (e.g., `author`, `source.id`, `tags[0]`) +- `metadata_value`: The value to exclude from results + +Both parameters must be used together. If you specify one without the other, the API returns an error. + +## Basic Filtering Examples + +### Exclude Documents by Author + +Find similar documents but exclude those from the same author: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/literary-corpus/hamlet-soliloquy?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \ + -H "Authorization: Bearer alice_api_key" +``` + +This returns similar documents, excluding any with `metadata.author == "William Shakespeare"`. + +### Exclude Documents from Same Source + +Find similar content from different sources: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/news-articles/article123?count=10&metadata_path=source&metadata_value=NYTimes" \ + -H "Authorization: Bearer alice_api_key" +``` + +This excludes any documents with `metadata.source == "NYTimes"`. + +### Exclude by Category + +Find documents in different categories: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/products/product456?count=10&metadata_path=category&metadata_value=electronics" \ + -H "Authorization: Bearer alice_api_key" +``` + +This excludes any documents with `metadata.category == "electronics"`. + +## Filtering with Raw Embeddings + +Metadata filtering also works when searching with raw embedding vectors: + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/literary-corpus?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [0.032, -0.018, 0.056, ...] + }' +``` + +This searches using the provided vector but excludes documents where `metadata.author == "William Shakespeare"`. + +## Nested Metadata Paths + +For nested metadata objects, use dot notation: + +### Example Metadata Structure + +```json +{ + "author": { + "name": "Jane Doe", + "id": "author123", + "affiliation": "University" + }, + "publication": { + "journal": "Science", + "year": 2023 + } +} +``` + +### Filter by Nested Field + +```bash +# Exclude documents from same author ID +curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=author.id&metadata_value=author123" \ + -H "Authorization: Bearer alice_api_key" + +# Exclude documents from same journal +curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=publication.journal&metadata_value=Science" \ + -H "Authorization: Bearer alice_api_key" +``` + +## Combining with Other Parameters + +Metadata filtering works seamlessly with other search parameters: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/documents/doc123?count=20&threshold=0.8&limit=10&offset=0&metadata_path=source_id&metadata_value=src_456" \ + -H "Authorization: Bearer alice_api_key" +``` + +Parameters: +- `count=20`: Consider top 20 similar documents +- `threshold=0.8`: Only include documents with similarity ≥ 0.8 +- `limit=10`: Return at most 10 results +- `offset=0`: Start from first result (for pagination) +- `metadata_path=source_id`: Filter on this metadata field +- `metadata_value=src_456`: Exclude documents with this value + +## Use Cases + +### 1. Finding Similar Writing Styles Across Authors + +When analyzing writing styles, you want similar texts from different authors: + +```bash +# Upload documents with author metadata +curl -X POST "https://api.example.com/v1/embeddings/alice/writing-styles" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "tolstoy-passage-1", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, ...], + "vector_dim": 3072, + "text": "Happy families are all alike...", + "metadata": { + "author": "Leo Tolstoy", + "work": "Anna Karenina", + "language": "Russian" + } + }] + }' + +# Find similar writing styles from other authors +curl -X GET "https://api.example.com/v1/similars/alice/writing-styles/tolstoy-passage-1?count=10&metadata_path=author&metadata_value=Leo%20Tolstoy" \ + -H "Authorization: Bearer alice_api_key" +``` + +### 2. Cross-Source Content Discovery + +Find related news articles from different sources: + +```bash +# Search for similar content, excluding same source +curl -X GET "https://api.example.com/v1/similars/alice/news-corpus/nyt-article-456?count=15&metadata_path=source&metadata_value=New%20York%20Times" \ + -H "Authorization: Bearer alice_api_key" +``` + +This helps discover how different outlets cover similar topics. + +### 3. Product Recommendations Across Categories + +Find similar products in different categories: + +```bash +# User is viewing a laptop +curl -X GET "https://api.example.com/v1/similars/alice/product-catalog/laptop-001?count=10&threshold=0.7&metadata_path=category&metadata_value=electronics" \ + -H "Authorization: Bearer alice_api_key" +``` + +This could recommend accessories, furniture (for home office), or other complementary items. + +### 4. Research Paper Discovery + +Find related papers from different research groups: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-papers/paper123?count=20&metadata_path=lab_id&metadata_value=lab_abc_001" \ + -H "Authorization: Bearer alice_api_key" +``` + +Helps researchers discover related work from other institutions. + +### 5. Avoiding Duplicate Content + +When building a diverse content feed, exclude items from the same collection: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/blog-posts/post789?count=5&metadata_path=collection_id&metadata_value=series_xyz" \ + -H "Authorization: Bearer alice_api_key" +``` + +### 6. Cross-Language Document Discovery + +Find similar documents in other languages: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/multilingual-docs/doc_en_123?count=10&metadata_path=language&metadata_value=en" \ + -H "Authorization: Bearer alice_api_key" +``` + +This finds semantically similar documents in languages other than English. + +## Working with Multiple Values + +Currently, you can only filter by one metadata field at a time. To exclude multiple values, you need to: + +1. **Make multiple requests** and merge results in your application +2. **Use more specific metadata fields** that combine multiple attributes +3. **Post-process results** on the client side + +### Example: Excluding Multiple Authors + +```python +import requests + +def find_similar_excluding_authors(doc_id, exclude_authors): + """Find similar docs excluding multiple authors""" + all_results = [] + + for author in exclude_authors: + response = requests.get( + f"https://api.example.com/v1/similars/alice/corpus/{doc_id}", + headers={"Authorization": "Bearer alice_api_key"}, + params={ + "count": 20, + "metadata_path": "author", + "metadata_value": author + } + ) + results = response.json()['results'] + all_results.extend(results) + + # Deduplicate and sort by similarity + seen = set() + unique_results = [] + for r in sorted(all_results, key=lambda x: x['similarity'], reverse=True): + if r['id'] not in seen: + seen.add(r['id']) + unique_results.append(r) + + return unique_results[:10] + +# Usage +similar = find_similar_excluding_authors( + "doc123", + ["Author A", "Author B", "Author C"] +) +``` + +## Combining with Metadata Validation + +For reliable filtering, combine with metadata schema validation: + +```bash +# Step 1: Create project with metadata schema +curl -X POST "https://api.example.com/v1/projects/alice/validated-corpus" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "validated-corpus", + "description": "Corpus with validated metadata", + "instance_id": 123, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"source_id\":{\"type\":\"string\"}},\"required\":[\"author\",\"source_id\"]}" + }' + +# Step 2: Upload embeddings with metadata +curl -X POST "https://api.example.com/v1/embeddings/alice/validated-corpus" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, ...], + "vector_dim": 3072, + "metadata": { + "author": "John Doe", + "source_id": "source_123" + } + }] + }' + +# Step 3: Search with guaranteed metadata field existence +curl -X GET "https://api.example.com/v1/similars/alice/validated-corpus/doc001?count=10&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer alice_api_key" +``` + +See the [Metadata Validation Guide](./metadata-validation.md) for more details. + +## Understanding the Filter Logic + +The metadata filter uses **negative matching**: + +``` +INCLUDE document IF: + - document.similarity >= threshold + AND + - document.metadata[metadata_path] != metadata_value +``` + +**Important:** Documents without the specified metadata field are included (not filtered out). + +### Example + +Given this query: +```bash +?metadata_path=author&metadata_value=Alice +``` + +**Included:** +- Documents where `metadata.author == "Bob"` +- Documents where `metadata.author == "Charlie"` +- Documents without an `author` field in metadata + +**Excluded:** +- Documents where `metadata.author == "Alice"` + +## Performance Considerations + +Metadata filtering is performed at the database level using efficient indexing: + +1. **Vector similarity** is computed first +2. **Metadata filter** is applied to the similarity results +3. Results are sorted and limited + +For best performance: +- Use indexed metadata fields when possible +- Keep metadata values relatively small (under 1KB per document) +- Consider using IDs instead of full names for filtering + +## Error Handling + +### Missing One Parameter + +```bash +# Missing metadata_value +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Error:** +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata_path and metadata_value must be used together" +} +``` + +### Non-Existent Metadata Field + +```bash +# Filtering on field that doesn't exist in documents +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?count=10&metadata_path=nonexistent_field&metadata_value=some_value" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Result:** Returns all matching documents (since none have the field, none are excluded). + +### URL Encoding + +Remember to URL-encode metadata values with special characters: + +```bash +# Correct: URL-encoded value +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John%20Doe%20%26%20Jane%20Smith" \ + -H "Authorization: Bearer alice_api_key" + +# Incorrect: Unencoded special characters +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John Doe & Jane Smith" \ + -H "Authorization: Bearer alice_api_key" +``` + +## Complete Example + +Here's a complete workflow demonstrating metadata filtering: + +```bash +# 1. Create project +curl -X POST "https://api.example.com/v1/projects/alice/literature" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "literature", + "instance_id": 123 + }' + +# 2. Upload documents with metadata +curl -X POST "https://api.example.com/v1/embeddings/alice/literature" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + { + "text_id": "tolstoy_1", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, ...], + "vector_dim": 3072, + "text": "All happy families...", + "metadata": {"author": "Tolstoy", "work": "Anna Karenina"} + }, + { + "text_id": "tolstoy_2", + "instance_handle": "openai-large", + "vector": [0.11, 0.21, ...], + "vector_dim": 3072, + "text": "It was the best of times...", + "metadata": {"author": "Tolstoy", "work": "War and Peace"} + }, + { + "text_id": "dickens_1", + "instance_handle": "openai-large", + "vector": [0.12, 0.19, ...], + "vector_dim": 3072, + "text": "It was the age of wisdom...", + "metadata": {"author": "Dickens", "work": "Tale of Two Cities"} + } + ] + }' + +# 3. Find similar to tolstoy_1, excluding Tolstoy's works +curl -X GET "https://api.example.com/v1/similars/alice/literature/tolstoy_1?count=10&metadata_path=author&metadata_value=Tolstoy" \ + -H "Authorization: Bearer alice_api_key" + +# Result: Returns dickens_1, excludes tolstoy_2 +``` + +## Related Documentation + +- [RAG Workflow Guide](./rag-workflow.md) - Complete RAG implementation +- [Metadata Validation Guide](./metadata-validation.md) - Schema validation +- [Batch Operations Guide](./batch-operations.md) - Upload large datasets + +## Troubleshooting + +### No Results Returned + +**Problem:** Filter excludes all results + +**Solution:** +- Verify the metadata field exists in your documents +- Check that the metadata value matches exactly (case-sensitive) +- Try without the filter to ensure there are similar documents + +### Filter Not Working + +**Problem:** Still seeing documents you want to exclude + +**Solution:** +- Check URL encoding of the metadata value +- Verify the metadata path is correct (use dot notation for nested fields) +- Ensure both `metadata_path` and `metadata_value` are specified + +### Want Positive Matching + +**Problem:** Want to include only specific values, not exclude them + +**Solution:** Currently, only negative matching (exclusion) is supported. For positive matching, retrieve all results and filter on the client side, or use multiple negative filters to exclude everything except your target values. diff --git a/docs/content/guides/metadata-validation.md b/docs/content/guides/metadata-validation.md new file mode 100644 index 0000000..c345fd1 --- /dev/null +++ b/docs/content/guides/metadata-validation.md @@ -0,0 +1,665 @@ +--- +title: "Metadata Validation Guide" +weight: 5 +--- + +# Metadata Validation Guide + +This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings. + +## Overview + +dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency. + +Benefits: +- Enforce consistent metadata structure across all embeddings +- Catch data entry errors early +- Document expected metadata fields +- Enable reliable metadata-based filtering + +## Defining a Metadata Schema + +### When Creating a Project + +Include a `metadataScheme` field with a valid JSON Schema when creating a project: + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/validated-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "validated-project", + "description": "Project with metadata validation", + "instance_id": 123, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}" + }' +``` + +### Updating an Existing Project + +Add or update a metadata schema using PATCH: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"},\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"title\",\"author\"]}" + }' +``` + +**Note:** Schema updates only affect new or updated embeddings. Existing embeddings are not retroactively validated. + +## Common Schema Patterns + +### Simple Required Fields + +Require specific fields with basic types: + +```json +{ + "type": "object", + "properties": { + "author": {"type": "string"}, + "year": {"type": "integer"} + }, + "required": ["author"] +} +``` + +Example usage: + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "literary-texts", + "description": "Literary texts with structured metadata", + "instance_id": 123, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}" + }' +``` + +### Using Enums for Controlled Values + +Restrict fields to specific allowed values: + +```json +{ + "type": "object", + "properties": { + "genre": { + "type": "string", + "enum": ["poetry", "prose", "drama", "essay"] + }, + "language": { + "type": "string", + "enum": ["en", "de", "fr", "es", "la"] + } + }, + "required": ["genre"] +} +``` + +Example: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "hamlet-soliloquy", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "author": "William Shakespeare", + "year": 1603, + "genre": "drama" + } + }] + }' +``` + +### Nested Objects + +Define structured metadata with nested objects: + +```json +{ + "type": "object", + "properties": { + "author": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "birth_year": {"type": "integer"}, + "nationality": {"type": "string"} + }, + "required": ["name"] + }, + "publication": { + "type": "object", + "properties": { + "year": {"type": "integer"}, + "publisher": {"type": "string"}, + "city": {"type": "string"} + } + } + }, + "required": ["author"] +} +``` + +Example: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/academic-papers" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "paper001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "author": { + "name": "Jane Smith", + "birth_year": 1975, + "nationality": "USA" + }, + "publication": { + "year": 2023, + "publisher": "Academic Press", + "city": "Boston" + } + } + }] + }' +``` + +### Arrays and Lists + +Define arrays of values: + +```json +{ + "type": "object", + "properties": { + "keywords": { + "type": "array", + "items": {"type": "string"}, + "minItems": 1, + "maxItems": 10 + }, + "categories": { + "type": "array", + "items": { + "type": "string", + "enum": ["philosophy", "literature", "science", "history"] + } + } + } +} +``` + +Example: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "keywords": ["machine learning", "embeddings", "NLP"], + "categories": ["science", "literature"] + } + }] + }' +``` + +### Numeric Constraints + +Apply minimum, maximum, and range constraints: + +```json +{ + "type": "object", + "properties": { + "rating": { + "type": "number", + "minimum": 0, + "maximum": 5 + }, + "page_count": { + "type": "integer", + "minimum": 1 + }, + "confidence": { + "type": "number", + "minimum": 0.0, + "maximum": 1.0 + } + } +} +``` + +### String Constraints + +Apply length and pattern constraints: + +```json +{ + "type": "object", + "properties": { + "title": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "isbn": { + "type": "string", + "pattern": "^[0-9]{13}$" + }, + "doi": { + "type": "string", + "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$" + } + } +} +``` + +## Validation Examples + +### Valid Upload + +When metadata conforms to the schema: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "kant-critique", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "author": "Immanuel Kant", + "year": 1781, + "genre": "prose" + } + }] + }' +``` + +**Response:** +```json +{ + "message": "Embeddings uploaded successfully", + "count": 1 +} +``` + +### Validation Error: Missing Required Field + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "some-text", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "year": 1781 + } + }] + }' +``` + +**Error Response:** +```json +{ + "$schema": "http://localhost:8080/schemas/ErrorModel.json", + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n - author is required" +} +``` + +### Validation Error: Wrong Type + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "some-text", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "author": "John Doe", + "year": "1781" + } + }] + }' +``` + +**Error Response:** +```json +{ + "$schema": "http://localhost:8080/schemas/ErrorModel.json", + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n - year: expected integer, got string" +} +``` + +### Validation Error: Invalid Enum Value + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "some-text", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "author": "John Doe", + "year": 1781, + "genre": "novel" + } + }] + }' +``` + +**Error Response:** +```json +{ + "$schema": "http://localhost:8080/schemas/ErrorModel.json", + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n - genre: value must be one of: poetry, prose, drama, essay" +} +``` + +### Validation Error: Value Out of Range + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/rated-content" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "review001", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": { + "rating": 7.5 + } + }] + }' +``` + +**Error Response:** +```json +{ + "$schema": "http://localhost:8080/schemas/ErrorModel.json", + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'review001': metadata validation failed:\n - rating: must be <= 5" +} +``` + +## Real-World Schema Examples + +### Academic Publications + +```json +{ + "type": "object", + "properties": { + "doi": { + "type": "string", + "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$" + }, + "title": { + "type": "string", + "minLength": 1, + "maxLength": 500 + }, + "authors": { + "type": "array", + "items": {"type": "string"}, + "minItems": 1 + }, + "year": { + "type": "integer", + "minimum": 1900, + "maximum": 2100 + }, + "journal": {"type": "string"}, + "volume": {"type": "integer"}, + "pages": {"type": "string"}, + "keywords": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": ["doi", "title", "authors", "year"] +} +``` + +### Legal Documents + +```json +{ + "type": "object", + "properties": { + "case_number": {"type": "string"}, + "court": {"type": "string"}, + "date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$" + }, + "jurisdiction": { + "type": "string", + "enum": ["federal", "state", "local"] + }, + "category": { + "type": "string", + "enum": ["civil", "criminal", "administrative"] + }, + "parties": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": ["case_number", "court", "date"] +} +``` + +### Product Catalog + +```json +{ + "type": "object", + "properties": { + "sku": { + "type": "string", + "pattern": "^[A-Z]{3}-\\d{6}$" + }, + "name": {"type": "string"}, + "category": { + "type": "string", + "enum": ["electronics", "clothing", "books", "home", "toys"] + }, + "price": { + "type": "number", + "minimum": 0 + }, + "in_stock": {"type": "boolean"}, + "tags": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": ["sku", "name", "category", "price"] +} +``` + +## Admin Sanity Check + +Administrators can verify database integrity using the `/v1/admin/sanity-check` endpoint: + +```bash +curl -X GET "https://api.example.com/v1/admin/sanity-check" \ + -H "Authorization: Bearer admin_api_key" +``` + +**Response:** +```json +{ + "status": "PASSED", + "total_projects": 5, + "issues_count": 0, + "warnings_count": 1, + "warnings": [ + "Project alice/project1 has 100 embeddings but no metadata schema defined" + ] +} +``` + +**Status Values:** +- `PASSED`: No issues or warnings found +- `WARNING`: No critical issues, but warnings exist +- `FAILED`: Validation issues found that need attention + +The sanity check: +- Validates all embeddings have dimensions matching their LLM service +- Validates all metadata against project schemas (if defined) +- Reports projects without schemas as warnings + +## Best Practices + +### 1. Start Simple, Add Complexity Later + +Begin with basic required fields: + +```json +{ + "type": "object", + "properties": { + "source": {"type": "string"} + }, + "required": ["source"] +} +``` + +Add more constraints as your needs evolve. + +### 2. Test Schemas Before Deployment + +Use online JSON Schema validators like [jsonschemavalidator.net](https://www.jsonschemavalidator.net/) to test your schemas before deploying them. + +### 3. Document Your Schema + +Include a description in your project: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Project with metadata schema: author (required string), year (integer), genre (enum)" + }' +``` + +### 4. Version Your Schemas + +If you need to change a schema significantly, consider creating a new project rather than updating the existing one. + +### 5. Optional vs Required + +Be judicious with `required` fields. Too many required fields can make uploads cumbersome. + +### 6. Escape JSON Properly + +When passing JSON schemas in curl commands, escape quotes properly or use single quotes for the outer JSON. + +## Projects Without Schemas + +If you don't provide a `metadataScheme` when creating a project: +- Metadata validation is skipped +- You can upload any valid JSON metadata +- This is useful for exploratory work or heterogeneous data + +## Schema Updates and Existing Data + +When you update a project's metadata schema: +- Existing embeddings are **not** revalidated +- The new schema only applies to new or updated embeddings +- Use the admin sanity check to find existing embeddings that don't conform + +## Removing a Schema + +To remove metadata validation from a project: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"metadataScheme": null}' +``` + +After this, new embeddings can have any metadata structure. + +## Related Documentation + +- [RAG Workflow Guide](./rag-workflow.md) - Complete RAG implementation +- [Metadata Filtering Guide](./metadata-filtering.md) - Filter search results by metadata +- [Batch Operations Guide](./batch-operations.md) - Upload large datasets efficiently + +## Troubleshooting + +### Schema Syntax Errors + +**Error:** "Invalid JSON Schema" + +**Solution:** Validate your schema syntax using an online validator. Common issues: +- Missing commas between properties +- Unescaped quotes +- Invalid JSON structure + +### Uploads Failing After Schema Change + +**Problem:** Uploads worked before, now failing with validation errors + +**Solution:** Check that your metadata matches the new schema requirements. Review the error message for specific validation failures. + +### Want to Fix Non-Conforming Data + +**Problem:** Sanity check shows validation errors in existing data + +**Solution:** Either: +1. Update the schema to accept existing data +2. Re-upload conforming data to replace non-conforming embeddings +3. Delete and re-upload the project with correct metadata diff --git a/docs/content/guides/ownership-transfer.md b/docs/content/guides/ownership-transfer.md new file mode 100644 index 0000000..8c47b2b --- /dev/null +++ b/docs/content/guides/ownership-transfer.md @@ -0,0 +1,406 @@ +--- +title: "Ownership Transfer Guide" +weight: 4 +--- + +# Ownership Transfer Guide + +This guide explains how to transfer project ownership between users in dhamps-vdb. + +## Overview + +Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when: +- A project maintainer is leaving and wants to hand over control +- Organizational changes require reassigning project ownership +- Consolidating projects under a different user account +- Transferring stewardship of research data to a new PI + +## Important Constraints + +Before transferring ownership, understand these constraints: + +1. **Only the current owner can transfer** - Editors and readers cannot initiate transfers +2. **New owner must exist** - The target user must already be registered in the system +3. **No handle conflicts** - The new owner cannot already have a project with the same handle +4. **Old owner loses access** - After transfer, the original owner has no access to the project +5. **Data remains intact** - All embeddings and metadata are preserved during transfer +6. **Shared users remain** - Existing sharing relationships are maintained + +## Transferring Ownership + +### Basic Transfer + +Transfer a project to another user: + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "new_owner_handle": "bob" + }' +``` + +**Response:** +```json +{ + "message": "Project ownership transferred successfully", + "project_handle": "research-data", + "old_owner": "alice", + "new_owner": "bob" +} +``` + +After this operation: +- The project is now accessible at `/v1/projects/bob/research-data` +- Bob has full owner privileges +- Alice no longer has any access to the project +- All embeddings remain unchanged + +### Complete Transfer Example + +Here's a complete workflow showing before and after transfer: + +```bash +# Before transfer - Alice is the owner +curl -X GET "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" + +# Response +{ + "project_handle": "my-project", + "owner": "alice", + "description": "Research project", + "instance_id": 123 +} + +# Alice transfers to Bob +curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' + +# After transfer - Bob is now the owner +curl -X GET "https://api.example.com/v1/projects/bob/my-project" \ + -H "Authorization: Bearer bob_api_key" + +# Response +{ + "project_handle": "my-project", + "owner": "bob", + "description": "Research project", + "instance_id": 123 +} + +# Alice can no longer access it +curl -X GET "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" +# Returns: 404 Not Found +``` + +## Effects of Transfer + +### Project Access Path Changes + +The project URL changes to reflect the new owner: + +**Before:** +``` +/v1/projects/alice/research-data +/v1/embeddings/alice/research-data +/v1/similars/alice/research-data/doc123 +``` + +**After:** +``` +/v1/projects/bob/research-data +/v1/embeddings/bob/research-data +/v1/similars/bob/research-data/doc123 +``` + +**Important:** Update all client code and bookmarks to use the new owner's handle. + +### New Owner Gains Full Control + +Bob (new owner) can now: +- View and modify all embeddings +- Update project settings (description, instance, metadata schema) +- Manage sharing (add/remove shared users) +- Transfer ownership again to someone else +- Delete the project + +### Old Owner Loses All Access + +Alice (old owner) can no longer: +- Access the project in any way +- View or modify embeddings +- See project metadata +- Manage sharing +- Transfer ownership back + +**Note:** If Alice needs continued access, Bob should share the project with her after the transfer. + +### Shared Users Remain + +If the project was shared with other users, those sharing relationships are preserved: + +```bash +# Before transfer - Alice shares with Charlie (editor) +curl -X POST "https://api.example.com/v1/projects/alice/research-data/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"share_with_handle": "charlie", "role": "editor"}' + +# Transfer to Bob +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' + +# After transfer - Charlie still has editor access +curl -X GET "https://api.example.com/v1/projects/bob/research-data" \ + -H "Authorization: Bearer charlie_api_key" +# Works! Charlie can still access as editor +``` + +### Upgrading Shared User to Owner + +If the new owner was previously a shared user, their role is automatically upgraded: + +```bash +# Alice shares project with Bob (editor) +curl -X POST "https://api.example.com/v1/projects/alice/my-project/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"share_with_handle": "bob", "role": "editor"}' + +# Alice transfers ownership to Bob +curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' + +# Bob's previous "editor" sharing role is removed +# Bob now has full owner privileges instead +``` + +## Use Cases + +### PI Leaving Institution + +A principal investigator leaving an institution transfers project ownership to a colleague: + +```bash +curl -X POST "https://api.example.com/v1/projects/prof_jones/lab_data/transfer-ownership" \ + -H "Authorization: Bearer prof_jones_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "prof_smith"}' +``` + +### Account Consolidation + +Consolidate multiple projects under a single organizational account: + +```bash +# Transfer Alice's personal projects to organization account +curl -X POST "https://api.example.com/v1/projects/alice/project1/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "org_datascience"}' + +curl -X POST "https://api.example.com/v1/projects/alice/project2/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "org_datascience"}' +``` + +### Graduated Student Handoff + +A graduating student transfers their research project to their advisor: + +```bash +curl -X POST "https://api.example.com/v1/projects/student_bob/thesis_embeddings/transfer-ownership" \ + -H "Authorization: Bearer student_bob_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "advisor_carol"}' + +# Advisor can then share it back with the student if needed +curl -X POST "https://api.example.com/v1/projects/advisor_carol/thesis_embeddings/share" \ + -H "Authorization: Bearer advisor_carol_api_key" \ + -H "Content-Type: application/json" \ + -d '{"share_with_handle": "student_bob", "role": "reader"}' +``` + +### Department Reorganization + +Projects move to a new department owner: + +```bash +curl -X POST "https://api.example.com/v1/projects/old_dept/resource_library/transfer-ownership" \ + -H "Authorization: Bearer old_dept_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "new_dept"}' +``` + +## Error Conditions + +### New Owner Doesn't Exist + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "nonexistent_user"}' +``` + +**Error:** +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "User 'nonexistent_user' does not exist" +} +``` + +**Solution:** Ensure the target user is registered first. Contact admin to create the user. + +### Handle Conflict + +```bash +# Bob already has a project called "research-data" +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' +``` + +**Error:** +```json +{ + "title": "Conflict", + "status": 409, + "detail": "User 'bob' already has a project with handle 'research-data'" +} +``` + +**Solution:** Either: +1. Rename Alice's project before transferring: + ```bash + curl -X PATCH "https://api.example.com/v1/projects/alice/research-data" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"project_handle": "research-data-alice"}' + ``` +2. Ask Bob to rename or delete their existing project +3. Choose a different target user + +### Not the Owner + +```bash +# Charlie tries to transfer Alice's project +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \ + -H "Authorization: Bearer charlie_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' +``` + +**Error:** +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only the project owner can transfer ownership" +} +``` + +**Solution:** Only the current owner (Alice) can initiate the transfer. + +## Best Practices + +### Before Transferring + +1. **Communicate with New Owner**: Ensure they're willing to accept ownership +2. **Document Current State**: Export or document current embeddings and metadata +3. **Review Shared Users**: Check who has access and whether sharing should continue +4. **Update Client Code**: Identify all systems accessing the project that need updating +5. **Backup Data**: Consider exporting important data before transfer + +### During Transfer + +1. **Transfer at Low-Activity Time**: Minimize disruption by transferring during quiet periods +2. **Test Access First**: Verify new owner can access their other projects +3. **Use Correct Handle**: Double-check the new owner's handle before submitting + +### After Transferring + +1. **Verify New Ownership**: Confirm the transfer succeeded +2. **Update Client Applications**: Change all API calls to use new owner handle +3. **Grant Back Access if Needed**: New owner can share project back to old owner +4. **Update Documentation**: Update any documentation referencing the project path +5. **Notify Shared Users**: Inform shared users about the path change + +## Maintaining Access After Transfer + +If the original owner needs continued access, the new owner should share the project: + +```bash +# Step 1: Alice transfers to Bob +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "bob"}' + +# Step 2: Bob shares back with Alice as editor +curl -X POST "https://api.example.com/v1/projects/bob/research-data/share" \ + -H "Authorization: Bearer bob_api_key" \ + -H "Content-Type: application/json" \ + -d '{"share_with_handle": "alice", "role": "editor"}' + +# Now Alice can still access (but as editor, not owner) +curl -X GET "https://api.example.com/v1/embeddings/bob/research-data" \ + -H "Authorization: Bearer alice_api_key" +``` + +## Checking Current Owner + +To verify current project ownership: + +```bash +curl -X GET "https://api.example.com/v1/projects/{owner}/{project}" \ + -H "Authorization: Bearer your_api_key" +``` + +The `owner` field in the response shows the current owner. + +## Related Documentation + +- [Project Sharing Guide](./project-sharing.md) - Share projects with specific users +- [Public Projects Guide](./public-projects.md) - Make projects publicly accessible + +## Troubleshooting + +### Cannot Find Project After Transfer + +**Problem:** Getting 404 after transfer + +**Solution:** Update the owner in your API calls: +- Old: `/v1/projects/alice/my-project` +- New: `/v1/projects/bob/my-project` + +### Need to Reverse Transfer + +**Problem:** Transferred by mistake, need to reverse + +**Solution:** New owner must transfer back: +```bash +curl -X POST "https://api.example.com/v1/projects/bob/my-project/transfer-ownership" \ + -H "Authorization: Bearer bob_api_key" \ + -H "Content-Type: application/json" \ + -d '{"new_owner_handle": "alice"}' +``` + +### Client Applications Failing + +**Problem:** Applications can't access project after transfer + +**Solution:** Update all hardcoded owner references in your code to use the new owner's handle. diff --git a/docs/content/guides/project-sharing.md b/docs/content/guides/project-sharing.md new file mode 100644 index 0000000..b9276e1 --- /dev/null +++ b/docs/content/guides/project-sharing.md @@ -0,0 +1,333 @@ +--- +title: "Project Sharing Guide" +weight: 2 +--- + +# Project Sharing Guide + +This guide explains how to share projects with specific users for collaborative work in dhamps-vdb. + +## Overview + +Project sharing allows you to grant other users access to your projects with different permission levels: +- **reader**: Read-only access to embeddings and similar documents +- **editor**: Read and write access to embeddings (can add/modify/delete embeddings) + +Only the project owner can manage sharing settings and delete the project. + +## Sharing During Project Creation + +You can specify users to share with when creating a new project using the `shared_with` field: + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "collaborative-project", + "description": "A project shared with team members", + "instance_id": 123, + "shared_with": [ + { + "user_handle": "bob", + "role": "reader" + }, + { + "user_handle": "charlie", + "role": "editor" + } + ] + }' +``` + +In this example: +- `bob` can read embeddings and search for similar documents +- `charlie` can read embeddings, search, and also add/modify/delete embeddings +- `alice` (the owner) has full control including managing sharing and deleting the project + +## Managing Sharing After Creation + +### Share a Project with a User + +Add a user to an existing project: + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "david", + "role": "reader" + }' +``` + +**Response:** +```json +{ + "message": "Project shared successfully", + "user": "david", + "role": "reader" +} +``` + +### Update User's Role + +To change a user's role, simply share again with the new role: + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "david", + "role": "editor" + }' +``` + +This updates David's access from reader to editor. + +### Unshare a Project from a User + +Remove a user's access to a project: + +```bash +curl -X DELETE "https://api.example.com/v1/projects/alice/collaborative-project/share/david" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** +```json +{ + "message": "Project unshared successfully", + "user": "david" +} +``` + +### List Shared Users + +View all users a project is shared with: + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project/shared-with" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** +```json +{ + "project_handle": "collaborative-project", + "owner": "alice", + "shared_with": [ + { + "user_handle": "bob", + "role": "reader" + }, + { + "user_handle": "charlie", + "role": "editor" + } + ] +} +``` + +**Note:** Only the project owner can view the list of shared users. Users who have been granted access cannot see which other users also have access. + +## What Shared Users Can Do + +### As a Reader + +Bob (with reader access) can: + +```bash +# View project metadata +curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project" \ + -H "Authorization: Bearer bob_api_key" + +# Retrieve embeddings +curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project" \ + -H "Authorization: Bearer bob_api_key" + +# Get a specific embedding +curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project/doc123" \ + -H "Authorization: Bearer bob_api_key" + +# Search for similar documents +curl -X GET "https://api.example.com/v1/similars/alice/collaborative-project/doc123?count=5" \ + -H "Authorization: Bearer bob_api_key" +``` + +### As an Editor + +Charlie (with editor access) can do everything a reader can, plus: + +```bash +# Upload new embeddings +curl -X POST "https://api.example.com/v1/embeddings/alice/collaborative-project" \ + -H "Authorization: Bearer charlie_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc456", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": {"author": "Charlie"} + }] + }' + +# Delete specific embeddings +curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project/doc456" \ + -H "Authorization: Bearer charlie_api_key" + +# Delete all embeddings +curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project" \ + -H "Authorization: Bearer charlie_api_key" +``` + +## What Shared Users Cannot Do + +Even with editor access, shared users **cannot**: + +- Delete the project +- Change project settings (description, instance, metadata schema) +- Manage sharing (add/remove other users) +- View the list of other shared users +- Transfer project ownership + +These operations require owner privileges. + +## Permission Summary Table + +| Operation | Owner | Editor | Reader | +|-----------|-------|--------|--------| +| View project metadata | ✅ | ✅ | ✅ | +| Retrieve embeddings | ✅ | ✅ | ✅ | +| Search similar documents | ✅ | ✅ | ✅ | +| Add embeddings | ✅ | ✅ | ❌ | +| Modify embeddings | ✅ | ✅ | ❌ | +| Delete embeddings | ✅ | ✅ | ❌ | +| Update project settings | ✅ | ❌ | ❌ | +| Delete project | ✅ | ❌ | ❌ | +| Manage sharing | ✅ | ❌ | ❌ | +| View shared users list | ✅ | ❌ | ❌ | +| Transfer ownership | ✅ | ❌ | ❌ | + +## Use Cases + +### Research Team Collaboration + +A research team can share a project where: +- The principal investigator (PI) is the owner +- Research assistants have editor access to upload new data +- External collaborators have reader access to query the data + +```bash +# PI creates and shares the project +curl -X PUT "https://api.example.com/v1/projects/pi/research-corpus" \ + -H "Authorization: Bearer pi_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-corpus", + "description": "Research team corpus", + "instance_id": 123, + "shared_with": [ + {"user_handle": "assistant1", "role": "editor"}, + {"user_handle": "assistant2", "role": "editor"}, + {"user_handle": "external_collab", "role": "reader"} + ] + }' +``` + +### Data Pipeline with Read-Only Access + +Share processed embeddings with downstream consumers: + +```bash +# Data processor creates project +curl -X PUT "https://api.example.com/v1/projects/processor/processed-data" \ + -H "Authorization: Bearer processor_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "processed-data", + "description": "Processed embeddings for consumption", + "instance_id": 456, + "shared_with": [ + {"user_handle": "app_backend", "role": "reader"}, + {"user_handle": "analytics_team", "role": "reader"} + ] + }' +``` + +### Temporary Access + +Grant temporary access to a consultant and revoke it later: + +```bash +# Grant access +curl -X POST "https://api.example.com/v1/projects/alice/sensitive-project/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"share_with_handle": "consultant", "role": "reader"}' + +# Revoke access when consultation is complete +curl -X DELETE "https://api.example.com/v1/projects/alice/sensitive-project/share/consultant" \ + -H "Authorization: Bearer alice_api_key" +``` + +## Combining with Public Access + +You can combine user-specific sharing with public access (see [Public Projects Guide](./public-projects.md)): + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/mixed-access-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "mixed-access-project", + "description": "Public read, specific editors", + "instance_id": 123, + "public_read": true, + "shared_with": [ + {"user_handle": "bob", "role": "editor"} + ] + }' +``` + +In this case: +- Anyone can read the project (no authentication required) +- `bob` can also edit (add/modify/delete embeddings) +- `alice` retains full owner privileges + +## Security Considerations + +1. **Choose Roles Carefully**: Only grant editor access to trusted users who need to modify data +2. **Audit Access**: Regularly review the shared users list to ensure appropriate access levels +3. **Revoke Promptly**: Remove access immediately when users no longer need it +4. **Use Reader by Default**: Start with reader access and upgrade to editor only when necessary +5. **Consider Public Access**: For truly open data, use `public_read: true` instead of sharing with many users + +## Related Documentation + +- [Ownership Transfer Guide](./ownership-transfer.md) - Transfer project ownership +- [Public Projects Guide](./public-projects.md) - Make projects publicly accessible +- [Instance Management Guide](./instance-management.md) - Share LLM service instances + +## Troubleshooting + +### Cannot Share Project + +**Error:** "Only the owner can share projects" + +**Solution:** Only the project owner can manage sharing. If you need to share the project, ask the owner to add you, or consider [transferring ownership](./ownership-transfer.md). + +### User Not Found + +**Error:** "User not found" + +**Solution:** The user must exist in the system before you can share a project with them. Ask the admin to create the user first. + +### Cannot View Shared Users List + +**Error:** "Forbidden" + +**Solution:** Only the project owner can view the list of shared users. Shared users cannot see other shared users for privacy reasons. diff --git a/docs/content/guides/public-projects.md b/docs/content/guides/public-projects.md new file mode 100644 index 0000000..c2854fe --- /dev/null +++ b/docs/content/guides/public-projects.md @@ -0,0 +1,420 @@ +--- +title: "Public Projects Guide" +weight: 3 +--- + +# Public Projects Guide + +This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication. + +## Overview + +Projects can be configured to allow unauthenticated (public) read access by setting the `public_read` field to `true`. This is useful for: +- Open datasets and research data +- Public APIs and services +- Shared knowledge bases +- Educational resources + +**Important:** Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication. + +## Creating a Public Project + +Set `public_read` to `true` when creating a project: + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "public-knowledge", + "description": "Publicly accessible knowledge base", + "instance_id": 123, + "public_read": true + }' +``` + +**Response:** +```json +{ + "project_handle": "public-knowledge", + "owner": "alice", + "description": "Publicly accessible knowledge base", + "instance_id": 123, + "public_read": true +} +``` + +## Making an Existing Project Public + +Update an existing project using PATCH: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"public_read": true}' +``` + +## Making a Public Project Private + +To disable public access: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"public_read": false}' +``` + +## Accessing Public Projects Without Authentication + +Once a project has `public_read` enabled, anyone can access it without providing an API key. + +### Get Project Metadata + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge" +``` + +**Response:** +```json +{ + "project_handle": "public-knowledge", + "owner": "alice", + "description": "Publicly accessible knowledge base", + "instance_id": 123, + "public_read": true +} +``` + +### Retrieve All Embeddings + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge?limit=100" +``` + +**Response:** +```json +{ + "embeddings": [ + { + "text_id": "doc001", + "text": "Public document content", + "metadata": {"category": "science"}, + "vector_dim": 3072 + }, + { + "text_id": "doc002", + "text": "Another public document", + "metadata": {"category": "history"}, + "vector_dim": 3072 + } + ] +} +``` + +### Get a Specific Embedding + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001" +``` + +**Response:** +```json +{ + "text_id": "doc001", + "text": "Public document content", + "metadata": {"category": "science"}, + "vector_dim": 3072, + "vector": [0.021, -0.015, 0.043, ...] +} +``` + +### Search for Similar Documents + +```bash +# Search by existing document ID +curl -X GET "https://api.example.com/v1/similars/alice/public-knowledge/doc001?count=5&threshold=0.7" +``` + +**Response:** +```json +{ + "user_handle": "alice", + "project_handle": "public-knowledge", + "results": [ + {"id": "doc002", "similarity": 0.92}, + {"id": "doc003", "similarity": 0.85}, + {"id": "doc004", "similarity": 0.78} + ] +} +``` + +### Search with Raw Embeddings + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/public-knowledge?count=5" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [0.032, -0.018, 0.056, ...] + }' +``` + +## Operations Still Requiring Authentication + +Even for public projects, these operations require authentication: + +### Creating Embeddings (Requires Auth) + +```bash +# This will fail with 401 Unauthorized +curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \ + -H "Content-Type: application/json" \ + -d '{"embeddings": [...]}' + +# This succeeds with valid API key +curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc123", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072 + }] + }' +``` + +### Deleting Embeddings (Requires Auth) + +```bash +# Delete specific embedding (requires auth) +curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001" \ + -H "Authorization: Bearer alice_api_key" + +# Delete all embeddings (requires auth) +curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" +``` + +### Modifying Project Settings (Requires Auth) + +```bash +# Update project description (requires auth) +curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"description": "Updated description"}' +``` + +### Deleting Project (Requires Auth) + +```bash +curl -X DELETE "https://api.example.com/v1/projects/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" +``` + +## Combining Public Access with User Sharing + +You can combine public read access with user-specific editor permissions: + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-public" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "collaborative-public", + "description": "Public read, restricted write", + "instance_id": 123, + "public_read": true, + "shared_with": [ + { + "user_handle": "bob", + "role": "editor" + }, + { + "user_handle": "charlie", + "role": "editor" + } + ] + }' +``` + +In this configuration: +- **Anyone** can read embeddings and search (no auth required) +- **bob** and **charlie** can add/modify/delete embeddings (with auth) +- **alice** (owner) has full control (with auth) + +## Use Cases + +### Open Research Dataset + +Share research data publicly while maintaining write control: + +```bash +curl -X PUT "https://api.example.com/v1/projects/university/research-corpus" \ + -H "Authorization: Bearer university_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-corpus", + "description": "Open research corpus for academic use", + "instance_id": 456, + "public_read": true, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"doi\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"doi\"]}" + }' +``` + +Researchers worldwide can access the data without credentials, but only authorized users can add new data. + +### Public API Backend + +Build a public search API on top of dhamps-vdb: + +```python +import requests + +def public_search_api(query_vector, count=10): + """Public search function requiring no authentication""" + response = requests.post( + "https://api.example.com/v1/similars/company/product-docs", + json={"vector": query_vector}, + params={"count": count, "threshold": 0.6} + ) + return response.json() + +# No API key needed for public projects! +results = public_search_api(query_embedding) +``` + +### Educational Resources + +Share educational content publicly: + +```bash +curl -X PUT "https://api.example.com/v1/projects/edu/learning-materials" \ + -H "Authorization: Bearer edu_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "learning-materials", + "description": "Free educational content embeddings", + "instance_id": 789, + "public_read": true + }' +``` + +Students and educators can access the materials without creating accounts. + +### Community-Driven Knowledge Base + +Open knowledge base with restricted editors: + +```bash +curl -X PUT "https://api.example.com/v1/projects/community/wiki-embeddings" \ + -H "Authorization: Bearer community_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "wiki-embeddings", + "description": "Community wiki embeddings", + "instance_id": 321, + "public_read": true, + "shared_with": [ + {"user_handle": "moderator1", "role": "editor"}, + {"user_handle": "moderator2", "role": "editor"} + ] + }' +``` + +## Security Considerations + +### What is Publicly Visible + +When `public_read` is enabled: +- ✅ Project metadata (name, description, owner) +- ✅ All embedding vectors and text content +- ✅ All embedding metadata +- ✅ Vector dimensions and instance references +- ❌ API keys (never exposed) +- ❌ User passwords or credentials + +### Best Practices + +1. **Review Content First**: Ensure no sensitive information is in embeddings or metadata before enabling public access +2. **Use Metadata Schemas**: Enforce consistent metadata structure with validation +3. **Monitor Usage**: Track access patterns to your public projects +4. **Set Clear Descriptions**: Provide clear project descriptions explaining the data's purpose and licensing +5. **Consider Rate Limiting**: For high-traffic public APIs, implement rate limiting at the application level + +### What to Avoid + +❌ **Don't** make projects public that contain: +- Personal identifiable information (PII) +- Proprietary or confidential data +- Sensitive research data not yet published +- Internal company information + +✅ **Do** make projects public that contain: +- Already-published research data +- Open educational resources +- Public domain content +- Creative Commons licensed materials + +## Disabling Public Access + +If you need to make a public project private again: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"public_read": false}' +``` + +After this change: +- All read operations require authentication +- Existing anonymous access is immediately revoked +- No data is deleted, just access is restricted + +## Checking if a Project is Public + +View project metadata to check the `public_read` flag: + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge" +``` + +Look for `"public_read": true` in the response. + +## Related Documentation + +- [Project Sharing Guide](./project-sharing.md) - Share with specific users +- [RAG Workflow Guide](./rag-workflow.md) - Complete RAG implementation +- [Metadata Validation Guide](./metadata-validation.md) - Enforce data quality + +## Troubleshooting + +### Public Access Not Working + +**Symptom:** Still getting 401 Unauthorized for public project + +**Solutions:** +1. Verify `public_read: true` is set: + ```bash + curl -X GET "https://api.example.com/v1/projects/alice/my-project" + ``` +2. Check you're using GET/POST for similars (not other methods) +3. Ensure the project exists and handle is correct + +### Accidentally Made Project Public + +**Solution:** Immediately disable public access: +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{"public_read": false}' +``` + +### Want to Track Public Usage + +**Solution:** Anonymous requests are logged with user set to "public". Review server logs to monitor public access patterns. diff --git a/docs/content/guides/rag-workflow.md b/docs/content/guides/rag-workflow.md new file mode 100644 index 0000000..30c5138 --- /dev/null +++ b/docs/content/guides/rag-workflow.md @@ -0,0 +1,393 @@ +--- +title: "RAG Workflow Guide" +weight: 1 +--- + +# Complete RAG Workflow Guide + +This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database. + +## Overview + +A typical RAG workflow involves: +1. Generate embeddings from your text content (using an external LLM service) +2. Upload embeddings to dhamps-vdb +3. Search for similar documents based on a query +4. Retrieve the relevant context +5. Use the context with an LLM to generate responses + +## Prerequisites + +- Access to dhamps-vdb API with a valid API key +- An external LLM service for generating embeddings (e.g., OpenAI, Cohere) +- Text content you want to process + +## Step 1: Generate Embeddings Externally + +First, use your chosen LLM service to generate embeddings for your text content. Here's an example using OpenAI's API: + +```python +import openai + +# Initialize OpenAI client +client = openai.OpenAI(api_key="your-openai-key") + +# Generate embeddings for your text +text = "The quick brown fox jumps over the lazy dog" +response = client.embeddings.create( + model="text-embedding-3-large", + input=text, + dimensions=3072 +) + +embedding_vector = response.data[0].embedding +``` + +## Step 2: Create LLM Service Instance + +Before uploading embeddings, create an LLM service instance in dhamps-vdb that matches your embedding configuration: + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "description": "OpenAI large embedding model", + "api_key_encrypted": "sk-proj-your-openai-key" + }' +``` + +**Response:** +```json +{ + "instance_id": 123, + "instance_handle": "my-openai", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "model": "text-embedding-3-large", + "dimensions": 3072 +} +``` + +## Step 3: Create a Project + +Create a project to organize your embeddings: + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/my-documents" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-documents", + "description": "Document embeddings for RAG", + "instance_id": 123 + }' +``` + +## Step 4: Upload Embeddings to dhamps-vdb + +Upload your pre-generated embeddings along with metadata and optional text content: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/my-documents" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [{ + "text_id": "doc001", + "instance_handle": "my-openai", + "vector": [0.021, -0.015, 0.043, ...], + "vector_dim": 3072, + "text": "The quick brown fox jumps over the lazy dog", + "metadata": { + "source": "example.txt", + "author": "Alice", + "category": "animals" + } + }] + }' +``` + +**Tip:** Upload multiple embeddings in batches for efficiency (see [Batch Operations Guide](./batch-operations.md)). + +## Step 5: Search for Similar Documents + +When you need to retrieve relevant context for a query: + +### Option A: Search by Stored Document ID + +If you already have a document in your database that represents your query: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_api_key" +``` + +### Option B: Search with Raw Query Embedding + +Generate an embedding for your query and search without storing it: + +```python +# Generate query embedding +query = "What animals are mentioned?" +query_response = client.embeddings.create( + model="text-embedding-3-large", + input=query, + dimensions=3072 +) +query_vector = query_response.data[0].embedding +``` + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/my-documents?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [0.032, -0.018, 0.056, ...] + }' +``` + +**Response:** +```json +{ + "user_handle": "alice", + "project_handle": "my-documents", + "results": [ + { + "id": "doc001", + "similarity": 0.95 + }, + { + "id": "doc042", + "similarity": 0.87 + }, + { + "id": "doc103", + "similarity": 0.82 + } + ] +} +``` + +## Step 6: Retrieve Context Documents + +Retrieve the full content and metadata for the most similar documents: + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/my-documents/doc001" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** +```json +{ + "text_id": "doc001", + "text": "The quick brown fox jumps over the lazy dog", + "metadata": { + "source": "example.txt", + "author": "Alice", + "category": "animals" + }, + "vector_dim": 3072 +} +``` + +## Step 7: Use Context with LLM + +Combine the retrieved context with your original query to generate an informed response: + +```python +# Collect context from similar documents +context_docs = [] +for result in similarity_results['results'][:3]: + doc = get_document(result['id']) # Your function to fetch document + context_docs.append(doc['text']) + +# Build context string +context = "\n\n".join(context_docs) + +# Generate response with context +response = client.chat.completions.create( + model="gpt-4", + messages=[ + {"role": "system", "content": "Answer based on the provided context."}, + {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"} + ] +) + +answer = response.choices[0].message.content +``` + +## Complete Python Example + +Here's a complete example combining all steps: + +```python +import openai +import requests + +# Configuration +DHAMPS_API = "https://api.example.com" +DHAMPS_KEY = "your-dhamps-api-key" +OPENAI_KEY = "your-openai-key" + +# Initialize OpenAI +client = openai.OpenAI(api_key=OPENAI_KEY) + +def embed_and_store(text_id, text, metadata=None): + """Generate embedding and store in dhamps-vdb""" + # Generate embedding + response = client.embeddings.create( + model="text-embedding-3-large", + input=text, + dimensions=3072 + ) + vector = response.data[0].embedding + + # Upload to dhamps-vdb + requests.post( + f"{DHAMPS_API}/v1/embeddings/alice/my-documents", + headers={ + "Authorization": f"Bearer {DHAMPS_KEY}", + "Content-Type": "application/json" + }, + json={ + "embeddings": [{ + "text_id": text_id, + "instance_handle": "my-openai", + "vector": vector, + "vector_dim": 3072, + "text": text, + "metadata": metadata or {} + }] + } + ) + +def search_similar(query, count=5): + """Search for similar documents using query text""" + # Generate query embedding + response = client.embeddings.create( + model="text-embedding-3-large", + input=query, + dimensions=3072 + ) + query_vector = response.data[0].embedding + + # Search in dhamps-vdb + result = requests.post( + f"{DHAMPS_API}/v1/similars/alice/my-documents?count={count}", + headers={ + "Authorization": f"Bearer {DHAMPS_KEY}", + "Content-Type": "application/json" + }, + json={"vector": query_vector} + ) + return result.json()['results'] + +def retrieve_context(doc_ids): + """Retrieve full document content""" + docs = [] + for doc_id in doc_ids: + response = requests.get( + f"{DHAMPS_API}/v1/embeddings/alice/my-documents/{doc_id}", + headers={"Authorization": f"Bearer {DHAMPS_KEY}"} + ) + docs.append(response.json()) + return docs + +def rag_query(query): + """Complete RAG workflow""" + # Search for similar documents + similar = search_similar(query, count=3) + + # Retrieve context + context_docs = retrieve_context([r['id'] for r in similar]) + context = "\n\n".join([doc['text'] for doc in context_docs]) + + # Generate answer with LLM + response = client.chat.completions.create( + model="gpt-4", + messages=[ + {"role": "system", "content": "Answer based on the provided context."}, + {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"} + ] + ) + + return response.choices[0].message.content + +# Usage +embed_and_store("doc001", "The quick brown fox jumps over the lazy dog", + {"category": "animals"}) +answer = rag_query("What animals are mentioned?") +print(answer) +``` + +## Best Practices + +1. **Batch Upload**: Upload embeddings in batches of 100-1000 for better performance +2. **Use Metadata**: Include rich metadata for better filtering and organization +3. **Set Thresholds**: Use similarity thresholds (e.g., 0.7) to filter low-quality matches +4. **Cache Embeddings**: Cache generated embeddings to avoid redundant API calls +5. **Monitor Dimensions**: Ensure all embeddings use consistent dimensions (3072 for text-embedding-3-large) + +## Advanced Features + +### Metadata Filtering + +Exclude certain documents from search results using metadata filters: + +```bash +# Exclude documents from the same author as the query +curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?metadata_path=author&metadata_value=Alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +See the [Metadata Filtering Guide](./metadata-filtering.md) for more details. + +### Metadata Validation + +Enforce consistent metadata structure using JSON Schema validation: + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/my-documents" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"category\":{\"type\":\"string\"}},\"required\":[\"author\"]}" + }' +``` + +See the [Metadata Validation Guide](./metadata-validation.md) for more details. + +## Related Documentation + +- [Batch Operations Guide](./batch-operations.md) - Efficiently upload large datasets +- [Metadata Filtering Guide](./metadata-filtering.md) - Advanced search filtering +- [Metadata Validation Guide](./metadata-validation.md) - Schema validation +- [Instance Management Guide](./instance-management.md) - Managing LLM service instances + +## Troubleshooting + +### Dimension Mismatch Error + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch" +} +``` + +**Solution**: Ensure the `vector_dim` field matches the dimensions configured in your LLM service instance. + +### No Similar Results + +If searches return no results, try: +- Lowering the similarity threshold (e.g., from 0.8 to 0.5) +- Increasing the count parameter +- Verifying embeddings are uploaded correctly +- Checking that query embeddings use the same model and dimensions diff --git a/docs/content/reference/_index.md b/docs/content/reference/_index.md new file mode 100644 index 0000000..99baa22 --- /dev/null +++ b/docs/content/reference/_index.md @@ -0,0 +1,20 @@ +--- +title: "Reference" +weight: 7 +--- + +# Reference Documentation + +Technical reference materials and specifications. + +## Contents + +- [Configuration Reference](configuration/) - Complete configuration options +- [Database Schema](database-schema/) - Database structure +- [Roadmap](roadmap/) - Planned features and improvements + +## Additional Resources + +- **OpenAPI Specification**: Available at `/openapi.yaml` on any running instance +- **Go Package Documentation**: Coming soon +- **Source Code**: [github.com/mpilhlt/dhamps-vdb](https://github.com/mpilhlt/dhamps-vdb) diff --git a/docs/public/404.html b/docs/public/404.html new file mode 100644 index 0000000..fc52734 --- /dev/null +++ b/docs/public/404.html @@ -0,0 +1,4 @@ +404 Page not found | dhamps-vdb Documentation +

Page +Not +Found

dhamps-vdb Documentation

\ No newline at end of file diff --git a/docs/public/asciinema/asciinema-auto.js b/docs/public/asciinema/asciinema-auto.js new file mode 100644 index 0000000..3ae311c --- /dev/null +++ b/docs/public/asciinema/asciinema-auto.js @@ -0,0 +1,7 @@ +(function() { + document.querySelectorAll(".asciinema").forEach(function(element) { + AsciinemaPlayer.create(element.getAttribute("x-data-cast"), + element, + JSON.parse(element.getAttribute("x-data-opts"))); + }); +}()); \ No newline at end of file diff --git a/docs/public/asciinema/asciinema-player.css b/docs/public/asciinema/asciinema-player.css new file mode 100644 index 0000000..26c9319 --- /dev/null +++ b/docs/public/asciinema/asciinema-player.css @@ -0,0 +1,2389 @@ +div.ap-wrapper { + outline: none; + height: 100%; + display: flex; + justify-content: center; +} +div.ap-wrapper .title-bar { + display: none; + top: -78px; + transition: top 0.15s linear; + position: absolute; + left: 0; + right: 0; + box-sizing: content-box; + font-size: 20px; + line-height: 1em; + padding: 15px; + font-family: sans-serif; + color: white; + background-color: rgba(0, 0, 0, 0.8); +} +div.ap-wrapper .title-bar img { + vertical-align: middle; + height: 48px; + margin-right: 16px; +} +div.ap-wrapper .title-bar a { + color: white; + text-decoration: underline; +} +div.ap-wrapper .title-bar a:hover { + text-decoration: none; +} +div.ap-wrapper:fullscreen { + background-color: #000; + width: 100%; + align-items: center; +} +div.ap-wrapper:fullscreen .title-bar { + display: initial; +} +div.ap-wrapper:fullscreen.hud .title-bar { + top: 0; +} +div.ap-wrapper div.ap-player { + text-align: left; + display: inline-block; + padding: 0px; + position: relative; + box-sizing: content-box; + overflow: hidden; + max-width: 100%; + border-radius: 4px; + font-size: 15px; + background-color: var(--term-color-background); +} +.ap-player { + --term-color-foreground: #ffffff; + --term-color-background: #000000; + --term-color-0: var(--term-color-foreground); + --term-color-1: var(--term-color-foreground); + --term-color-2: var(--term-color-foreground); + --term-color-3: var(--term-color-foreground); + --term-color-4: var(--term-color-foreground); + --term-color-5: var(--term-color-foreground); + --term-color-6: var(--term-color-foreground); + --term-color-7: var(--term-color-foreground); + --term-color-8: var(--term-color-0); + --term-color-9: var(--term-color-1); + --term-color-10: var(--term-color-2); + --term-color-11: var(--term-color-3); + --term-color-12: var(--term-color-4); + --term-color-13: var(--term-color-5); + --term-color-14: var(--term-color-6); + --term-color-15: var(--term-color-7); +} +.ap-player .fg-0 { + --fg: var(--term-color-0); +} +.ap-player .bg-0 { + --bg: var(--term-color-0); +} +.ap-player .fg-1 { + --fg: var(--term-color-1); +} +.ap-player .bg-1 { + --bg: var(--term-color-1); +} +.ap-player .fg-2 { + --fg: var(--term-color-2); +} +.ap-player .bg-2 { + --bg: var(--term-color-2); +} +.ap-player .fg-3 { + --fg: var(--term-color-3); +} +.ap-player .bg-3 { + --bg: var(--term-color-3); +} +.ap-player .fg-4 { + --fg: var(--term-color-4); +} +.ap-player .bg-4 { + --bg: var(--term-color-4); +} +.ap-player .fg-5 { + --fg: var(--term-color-5); +} +.ap-player .bg-5 { + --bg: var(--term-color-5); +} +.ap-player .fg-6 { + --fg: var(--term-color-6); +} +.ap-player .bg-6 { + --bg: var(--term-color-6); +} +.ap-player .fg-7 { + --fg: var(--term-color-7); +} +.ap-player .bg-7 { + --bg: var(--term-color-7); +} +.ap-player .fg-8 { + --fg: var(--term-color-8); +} +.ap-player .bg-8 { + --bg: var(--term-color-8); +} +.ap-player .fg-9 { + --fg: var(--term-color-9); +} +.ap-player .bg-9 { + --bg: var(--term-color-9); +} +.ap-player .fg-10 { + --fg: var(--term-color-10); +} +.ap-player .bg-10 { + --bg: var(--term-color-10); +} +.ap-player .fg-11 { + --fg: var(--term-color-11); +} +.ap-player .bg-11 { + --bg: var(--term-color-11); +} +.ap-player .fg-12 { + --fg: var(--term-color-12); +} +.ap-player .bg-12 { + --bg: var(--term-color-12); +} +.ap-player .fg-13 { + --fg: var(--term-color-13); +} +.ap-player .bg-13 { + --bg: var(--term-color-13); +} +.ap-player .fg-14 { + --fg: var(--term-color-14); +} +.ap-player .bg-14 { + --bg: var(--term-color-14); +} +.ap-player .fg-15 { + --fg: var(--term-color-15); +} +.ap-player .bg-15 { + --bg: var(--term-color-15); +} +.ap-player .fg-8, +.ap-player .fg-9, +.ap-player .fg-10, +.ap-player .fg-11, +.ap-player .fg-12, +.ap-player .fg-13, +.ap-player .fg-14, +.ap-player .fg-15 { + font-weight: bold; +} +pre.ap-terminal { + box-sizing: content-box; + overflow: hidden; + padding: 0; + margin: 0px; + display: block; + white-space: pre; + word-wrap: normal; + word-break: normal; + border-radius: 0; + border-style: solid; + cursor: text; + border-width: 0.75em; + color: var(--term-color-foreground); + background-color: var(--term-color-background); + border-color: var(--term-color-background); + outline: none; + line-height: var(--term-line-height); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; +} +pre.ap-terminal .ap-line { + letter-spacing: normal; + overflow: hidden; +} +pre.ap-terminal .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +pre.ap-terminal .ap-line { + display: block; + width: 100%; + height: var(--term-line-height); + position: relative; +} +pre.ap-terminal .ap-line span { + position: absolute; + left: calc(100% * var(--offset) / var(--term-cols)); + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal .ap-line .ap-inverse { + color: var(--bg); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2580 { + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2581 { + border-bottom: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2582 { + border-bottom: calc(0.25 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2583 { + border-bottom: calc(0.375 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2584 { + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2585 { + border-bottom: calc(0.625 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2586 { + border-bottom: calc(0.75 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2587 { + border-bottom: calc(0.875 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2588 { + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2589 { + border-left: 0.875ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258a { + border-left: 0.75ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258b { + border-left: 0.625ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258c { + border-left: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258d { + border-left: 0.375ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258e { + border-left: 0.25ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258f { + border-left: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2590 { + border-right: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2591 { + background-color: color-mix(in srgb, var(--fg) 25%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2592 { + background-color: color-mix(in srgb, var(--fg) 50%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2593 { + background-color: color-mix(in srgb, var(--fg) 75%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2594 { + border-top: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2595 { + border-right: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2596 { + border-right: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2597 { + border-left: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2598 { + border-right: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2599 { + border-left: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a::before, +pre.ap-terminal .ap-line .cp-259a::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259a::before { + top: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259a::after { + bottom: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259b { + border-left: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259c { + border-right: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259d { + border-left: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e::before, +pre.ap-terminal .ap-line .cp-259e::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259e::before { + top: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259e::after { + bottom: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259f { + border-right: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b0 { + border-left: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b2 { + border-right: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor { + color: var(--bg); + background-color: var(--fg); + border-radius: 0.05em; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor.ap-inverse { + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal:not(.ap-blink) .ap-line .ap-blink { + color: transparent; + border-color: transparent; +} +pre.ap-terminal .ap-bright { + font-weight: bold; +} +pre.ap-terminal .ap-faint { + opacity: 0.5; +} +pre.ap-terminal .ap-underline { + text-decoration: underline; +} +pre.ap-terminal .ap-italic { + font-style: italic; +} +pre.ap-terminal .ap-strikethrough { + text-decoration: line-through; +} +.ap-line span { + --fg: var(--term-color-foreground); + --bg: var(--term-color-background); +} +div.ap-player div.ap-control-bar { + width: 100%; + height: 32px; + display: flex; + justify-content: space-between; + align-items: stretch; + color: var(--term-color-foreground); + box-sizing: content-box; + line-height: 1; + position: absolute; + bottom: 0; + left: 0; + opacity: 0; + transition: opacity 0.15s linear; + user-select: none; + border-top: 2px solid color-mix(in oklab, var(--term-color-background) 80%, var(--term-color-foreground)); + z-index: 30; +} +div.ap-player div.ap-control-bar * { + box-sizing: inherit; +} +div.ap-control-bar svg.ap-icon path { + fill: var(--term-color-foreground); +} +div.ap-control-bar span.ap-button { + display: flex; + flex: 0 0 auto; + cursor: pointer; +} +div.ap-control-bar span.ap-playback-button { + width: 12px; + height: 12px; + padding: 10px; +} +div.ap-control-bar span.ap-playback-button svg { + height: 12px; + width: 12px; +} +div.ap-control-bar span.ap-timer { + display: flex; + flex: 0 0 auto; + min-width: 50px; + margin: 0 10px; + height: 100%; + text-align: center; + font-size: 13px; + line-height: 100%; + cursor: default; +} +div.ap-control-bar span.ap-timer span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-size: inherit; + font-weight: 600; + margin: auto; +} +div.ap-control-bar span.ap-timer .ap-time-remaining { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-elapsed { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-remaining { + display: flex; +} +div.ap-control-bar .ap-progressbar { + display: block; + flex: 1 1 auto; + height: 100%; + padding: 0 10px; +} +div.ap-control-bar .ap-progressbar .ap-bar { + display: block; + position: relative; + cursor: default; + height: 100%; + font-size: 0; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter { + display: block; + position: absolute; + top: 15px; + left: 0; + right: 0; + height: 3px; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-empty { + background-color: color-mix(in oklab, var(--term-color-foreground) 20%, var(--term-color-background)); +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full { + width: 100%; + transform-origin: left center; + background-color: var(--term-color-foreground); + border-radius: 3px; +} +div.ap-control-bar.ap-seekable .ap-progressbar .ap-bar { + cursor: pointer; +} +div.ap-control-bar .ap-fullscreen-button { + width: 14px; + height: 14px; + padding: 9px; +} +div.ap-control-bar .ap-fullscreen-button svg { + width: 14px; + height: 14px; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: inline; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: none; +} +div.ap-control-bar .ap-fullscreen-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-control-bar .ap-kbd-button { + height: 14px; + padding: 9px; + margin: 0 4px; +} +div.ap-control-bar .ap-kbd-button svg { + width: 26px; + height: 14px; +} +div.ap-control-bar .ap-kbd-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-wrapper.ap-hud .ap-control-bar { + opacity: 1; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: none; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: inline; +} +span.ap-progressbar span.ap-marker-container { + display: block; + top: 0; + bottom: 0; + width: 21px; + position: absolute; + margin-left: -10px; +} +span.ap-marker-container span.ap-marker { + display: block; + top: 13px; + bottom: 12px; + left: 7px; + right: 7px; + background-color: color-mix(in oklab, var(--term-color-foreground) 33%, var(--term-color-background)); + position: absolute; + transition: top 0.1s, bottom 0.1s, left 0.1s, right 0.1s, background-color 0.1s; + border-radius: 50%; +} +span.ap-marker-container span.ap-marker.ap-marker-past { + background-color: var(--term-color-foreground); +} +span.ap-marker-container span.ap-marker:hover, +span.ap-marker-container:hover span.ap-marker { + background-color: var(--term-color-foreground); + top: 11px; + bottom: 10px; + left: 5px; + right: 5px; +} +.ap-tooltip-container span.ap-tooltip { + visibility: hidden; + background-color: var(--term-color-foreground); + color: var(--term-color-background); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-weight: bold; + text-align: center; + padding: 0 0.5em; + border-radius: 4px; + position: absolute; + z-index: 1; + white-space: nowrap; + /* Prevents the text from wrapping and makes sure the tooltip width adapts to the text length */ + font-size: 13px; + line-height: 2em; + bottom: 100%; + left: 50%; + transform: translateX(-50%); +} +.ap-tooltip-container:hover span.ap-tooltip { + visibility: visible; +} +.ap-player .ap-overlay { + z-index: 10; + background-repeat: no-repeat; + background-position: center; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; +} +.ap-player .ap-overlay-start { + cursor: pointer; +} +.ap-player .ap-overlay-start .ap-play-button { + font-size: 0px; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + text-align: center; + color: white; + height: 80px; + max-height: 66%; + margin: auto; +} +.ap-player .ap-overlay-start .ap-play-button div { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button div span { + height: 100%; + display: block; +} +.ap-player .ap-overlay-start .ap-play-button div span svg { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button svg { + filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.4)); +} +.ap-player .ap-overlay-loading .ap-loader { + width: 48px; + height: 48px; + border-radius: 50%; + display: inline-block; + position: relative; + border: 10px solid; + border-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.5) rgba(255, 255, 255, 0.7) #ffffff; + border-color: color-mix(in srgb, var(--term-color-foreground) 30%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 50%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 70%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 100%, var(--term-color-background)); + box-sizing: border-box; + animation: ap-loader-rotation 1s linear infinite; +} +.ap-player .ap-overlay-info { + background-color: var(--term-color-background); +} +.ap-player .ap-overlay-info span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + font-size: 2em; + color: var(--term-color-foreground); +} +.ap-player .ap-overlay-info span .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-info span .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help { + background-color: rgba(0, 0, 0, 0.8); + container-type: inline-size; +} +.ap-player .ap-overlay-help > div { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + max-width: 85%; + max-height: 85%; + font-size: 18px; + color: var(--term-color-foreground); + box-sizing: border-box; + margin-bottom: 32px; +} +.ap-player .ap-overlay-help > div .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-help > div .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help > div div { + padding: calc(min(4cqw, 40px)); + font-size: calc(min(1.9cqw, 18px)); + background-color: var(--term-color-background); + border: 1px solid color-mix(in oklab, var(--term-color-background) 90%, var(--term-color-foreground)); + border-radius: 6px; +} +.ap-player .ap-overlay-help > div div p { + font-weight: bold; + margin: 0 0 2em 0; +} +.ap-player .ap-overlay-help > div div ul { + list-style: none; + padding: 0; +} +.ap-player .ap-overlay-help > div div ul li { + margin: 0 0 0.75em 0; +} +.ap-player .ap-overlay-help > div div kbd { + color: var(--term-color-background); + background-color: var(--term-color-foreground); + padding: 0.2em 0.5em; + border-radius: 0.2em; + font-family: inherit; + font-size: 0.85em; + border: none; + margin: 0; +} +.ap-player .ap-overlay-error span { + font-size: 8em; +} +@keyframes ap-loader-rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +.ap-terminal .fg-16 { + --fg: #000000; +} +.ap-terminal .bg-16 { + --bg: #000000; +} +.ap-terminal .fg-17 { + --fg: #00005f; +} +.ap-terminal .bg-17 { + --bg: #00005f; +} +.ap-terminal .fg-18 { + --fg: #000087; +} +.ap-terminal .bg-18 { + --bg: #000087; +} +.ap-terminal .fg-19 { + --fg: #0000af; +} +.ap-terminal .bg-19 { + --bg: #0000af; +} +.ap-terminal .fg-20 { + --fg: #0000d7; +} +.ap-terminal .bg-20 { + --bg: #0000d7; +} +.ap-terminal .fg-21 { + --fg: #0000ff; +} +.ap-terminal .bg-21 { + --bg: #0000ff; +} +.ap-terminal .fg-22 { + --fg: #005f00; +} +.ap-terminal .bg-22 { + --bg: #005f00; +} +.ap-terminal .fg-23 { + --fg: #005f5f; +} +.ap-terminal .bg-23 { + --bg: #005f5f; +} +.ap-terminal .fg-24 { + --fg: #005f87; +} +.ap-terminal .bg-24 { + --bg: #005f87; +} +.ap-terminal .fg-25 { + --fg: #005faf; +} +.ap-terminal .bg-25 { + --bg: #005faf; +} +.ap-terminal .fg-26 { + --fg: #005fd7; +} +.ap-terminal .bg-26 { + --bg: #005fd7; +} +.ap-terminal .fg-27 { + --fg: #005fff; +} +.ap-terminal .bg-27 { + --bg: #005fff; +} +.ap-terminal .fg-28 { + --fg: #008700; +} +.ap-terminal .bg-28 { + --bg: #008700; +} +.ap-terminal .fg-29 { + --fg: #00875f; +} +.ap-terminal .bg-29 { + --bg: #00875f; +} +.ap-terminal .fg-30 { + --fg: #008787; +} +.ap-terminal .bg-30 { + --bg: #008787; +} +.ap-terminal .fg-31 { + --fg: #0087af; +} +.ap-terminal .bg-31 { + --bg: #0087af; +} +.ap-terminal .fg-32 { + --fg: #0087d7; +} +.ap-terminal .bg-32 { + --bg: #0087d7; +} +.ap-terminal .fg-33 { + --fg: #0087ff; +} +.ap-terminal .bg-33 { + --bg: #0087ff; +} +.ap-terminal .fg-34 { + --fg: #00af00; +} +.ap-terminal .bg-34 { + --bg: #00af00; +} +.ap-terminal .fg-35 { + --fg: #00af5f; +} +.ap-terminal .bg-35 { + --bg: #00af5f; +} +.ap-terminal .fg-36 { + --fg: #00af87; +} +.ap-terminal .bg-36 { + --bg: #00af87; +} +.ap-terminal .fg-37 { + --fg: #00afaf; +} +.ap-terminal .bg-37 { + --bg: #00afaf; +} +.ap-terminal .fg-38 { + --fg: #00afd7; +} +.ap-terminal .bg-38 { + --bg: #00afd7; +} +.ap-terminal .fg-39 { + --fg: #00afff; +} +.ap-terminal .bg-39 { + --bg: #00afff; +} +.ap-terminal .fg-40 { + --fg: #00d700; +} +.ap-terminal .bg-40 { + --bg: #00d700; +} +.ap-terminal .fg-41 { + --fg: #00d75f; +} +.ap-terminal .bg-41 { + --bg: #00d75f; +} +.ap-terminal .fg-42 { + --fg: #00d787; +} +.ap-terminal .bg-42 { + --bg: #00d787; +} +.ap-terminal .fg-43 { + --fg: #00d7af; +} +.ap-terminal .bg-43 { + --bg: #00d7af; +} +.ap-terminal .fg-44 { + --fg: #00d7d7; +} +.ap-terminal .bg-44 { + --bg: #00d7d7; +} +.ap-terminal .fg-45 { + --fg: #00d7ff; +} +.ap-terminal .bg-45 { + --bg: #00d7ff; +} +.ap-terminal .fg-46 { + --fg: #00ff00; +} +.ap-terminal .bg-46 { + --bg: #00ff00; +} +.ap-terminal .fg-47 { + --fg: #00ff5f; +} +.ap-terminal .bg-47 { + --bg: #00ff5f; +} +.ap-terminal .fg-48 { + --fg: #00ff87; +} +.ap-terminal .bg-48 { + --bg: #00ff87; +} +.ap-terminal .fg-49 { + --fg: #00ffaf; +} +.ap-terminal .bg-49 { + --bg: #00ffaf; +} +.ap-terminal .fg-50 { + --fg: #00ffd7; +} +.ap-terminal .bg-50 { + --bg: #00ffd7; +} +.ap-terminal .fg-51 { + --fg: #00ffff; +} +.ap-terminal .bg-51 { + --bg: #00ffff; +} +.ap-terminal .fg-52 { + --fg: #5f0000; +} +.ap-terminal .bg-52 { + --bg: #5f0000; +} +.ap-terminal .fg-53 { + --fg: #5f005f; +} +.ap-terminal .bg-53 { + --bg: #5f005f; +} +.ap-terminal .fg-54 { + --fg: #5f0087; +} +.ap-terminal .bg-54 { + --bg: #5f0087; +} +.ap-terminal .fg-55 { + --fg: #5f00af; +} +.ap-terminal .bg-55 { + --bg: #5f00af; +} +.ap-terminal .fg-56 { + --fg: #5f00d7; +} +.ap-terminal .bg-56 { + --bg: #5f00d7; +} +.ap-terminal .fg-57 { + --fg: #5f00ff; +} +.ap-terminal .bg-57 { + --bg: #5f00ff; +} +.ap-terminal .fg-58 { + --fg: #5f5f00; +} +.ap-terminal .bg-58 { + --bg: #5f5f00; +} +.ap-terminal .fg-59 { + --fg: #5f5f5f; +} +.ap-terminal .bg-59 { + --bg: #5f5f5f; +} +.ap-terminal .fg-60 { + --fg: #5f5f87; +} +.ap-terminal .bg-60 { + --bg: #5f5f87; +} +.ap-terminal .fg-61 { + --fg: #5f5faf; +} +.ap-terminal .bg-61 { + --bg: #5f5faf; +} +.ap-terminal .fg-62 { + --fg: #5f5fd7; +} +.ap-terminal .bg-62 { + --bg: #5f5fd7; +} +.ap-terminal .fg-63 { + --fg: #5f5fff; +} +.ap-terminal .bg-63 { + --bg: #5f5fff; +} +.ap-terminal .fg-64 { + --fg: #5f8700; +} +.ap-terminal .bg-64 { + --bg: #5f8700; +} +.ap-terminal .fg-65 { + --fg: #5f875f; +} +.ap-terminal .bg-65 { + --bg: #5f875f; +} +.ap-terminal .fg-66 { + --fg: #5f8787; +} +.ap-terminal .bg-66 { + --bg: #5f8787; +} +.ap-terminal .fg-67 { + --fg: #5f87af; +} +.ap-terminal .bg-67 { + --bg: #5f87af; +} +.ap-terminal .fg-68 { + --fg: #5f87d7; +} +.ap-terminal .bg-68 { + --bg: #5f87d7; +} +.ap-terminal .fg-69 { + --fg: #5f87ff; +} +.ap-terminal .bg-69 { + --bg: #5f87ff; +} +.ap-terminal .fg-70 { + --fg: #5faf00; +} +.ap-terminal .bg-70 { + --bg: #5faf00; +} +.ap-terminal .fg-71 { + --fg: #5faf5f; +} +.ap-terminal .bg-71 { + --bg: #5faf5f; +} +.ap-terminal .fg-72 { + --fg: #5faf87; +} +.ap-terminal .bg-72 { + --bg: #5faf87; +} +.ap-terminal .fg-73 { + --fg: #5fafaf; +} +.ap-terminal .bg-73 { + --bg: #5fafaf; +} +.ap-terminal .fg-74 { + --fg: #5fafd7; +} +.ap-terminal .bg-74 { + --bg: #5fafd7; +} +.ap-terminal .fg-75 { + --fg: #5fafff; +} +.ap-terminal .bg-75 { + --bg: #5fafff; +} +.ap-terminal .fg-76 { + --fg: #5fd700; +} +.ap-terminal .bg-76 { + --bg: #5fd700; +} +.ap-terminal .fg-77 { + --fg: #5fd75f; +} +.ap-terminal .bg-77 { + --bg: #5fd75f; +} +.ap-terminal .fg-78 { + --fg: #5fd787; +} +.ap-terminal .bg-78 { + --bg: #5fd787; +} +.ap-terminal .fg-79 { + --fg: #5fd7af; +} +.ap-terminal .bg-79 { + --bg: #5fd7af; +} +.ap-terminal .fg-80 { + --fg: #5fd7d7; +} +.ap-terminal .bg-80 { + --bg: #5fd7d7; +} +.ap-terminal .fg-81 { + --fg: #5fd7ff; +} +.ap-terminal .bg-81 { + --bg: #5fd7ff; +} +.ap-terminal .fg-82 { + --fg: #5fff00; +} +.ap-terminal .bg-82 { + --bg: #5fff00; +} +.ap-terminal .fg-83 { + --fg: #5fff5f; +} +.ap-terminal .bg-83 { + --bg: #5fff5f; +} +.ap-terminal .fg-84 { + --fg: #5fff87; +} +.ap-terminal .bg-84 { + --bg: #5fff87; +} +.ap-terminal .fg-85 { + --fg: #5fffaf; +} +.ap-terminal .bg-85 { + --bg: #5fffaf; +} +.ap-terminal .fg-86 { + --fg: #5fffd7; +} +.ap-terminal .bg-86 { + --bg: #5fffd7; +} +.ap-terminal .fg-87 { + --fg: #5fffff; +} +.ap-terminal .bg-87 { + --bg: #5fffff; +} +.ap-terminal .fg-88 { + --fg: #870000; +} +.ap-terminal .bg-88 { + --bg: #870000; +} +.ap-terminal .fg-89 { + --fg: #87005f; +} +.ap-terminal .bg-89 { + --bg: #87005f; +} +.ap-terminal .fg-90 { + --fg: #870087; +} +.ap-terminal .bg-90 { + --bg: #870087; +} +.ap-terminal .fg-91 { + --fg: #8700af; +} +.ap-terminal .bg-91 { + --bg: #8700af; +} +.ap-terminal .fg-92 { + --fg: #8700d7; +} +.ap-terminal .bg-92 { + --bg: #8700d7; +} +.ap-terminal .fg-93 { + --fg: #8700ff; +} +.ap-terminal .bg-93 { + --bg: #8700ff; +} +.ap-terminal .fg-94 { + --fg: #875f00; +} +.ap-terminal .bg-94 { + --bg: #875f00; +} +.ap-terminal .fg-95 { + --fg: #875f5f; +} +.ap-terminal .bg-95 { + --bg: #875f5f; +} +.ap-terminal .fg-96 { + --fg: #875f87; +} +.ap-terminal .bg-96 { + --bg: #875f87; +} +.ap-terminal .fg-97 { + --fg: #875faf; +} +.ap-terminal .bg-97 { + --bg: #875faf; +} +.ap-terminal .fg-98 { + --fg: #875fd7; +} +.ap-terminal .bg-98 { + --bg: #875fd7; +} +.ap-terminal .fg-99 { + --fg: #875fff; +} +.ap-terminal .bg-99 { + --bg: #875fff; +} +.ap-terminal .fg-100 { + --fg: #878700; +} +.ap-terminal .bg-100 { + --bg: #878700; +} +.ap-terminal .fg-101 { + --fg: #87875f; +} +.ap-terminal .bg-101 { + --bg: #87875f; +} +.ap-terminal .fg-102 { + --fg: #878787; +} +.ap-terminal .bg-102 { + --bg: #878787; +} +.ap-terminal .fg-103 { + --fg: #8787af; +} +.ap-terminal .bg-103 { + --bg: #8787af; +} +.ap-terminal .fg-104 { + --fg: #8787d7; +} +.ap-terminal .bg-104 { + --bg: #8787d7; +} +.ap-terminal .fg-105 { + --fg: #8787ff; +} +.ap-terminal .bg-105 { + --bg: #8787ff; +} +.ap-terminal .fg-106 { + --fg: #87af00; +} +.ap-terminal .bg-106 { + --bg: #87af00; +} +.ap-terminal .fg-107 { + --fg: #87af5f; +} +.ap-terminal .bg-107 { + --bg: #87af5f; +} +.ap-terminal .fg-108 { + --fg: #87af87; +} +.ap-terminal .bg-108 { + --bg: #87af87; +} +.ap-terminal .fg-109 { + --fg: #87afaf; +} +.ap-terminal .bg-109 { + --bg: #87afaf; +} +.ap-terminal .fg-110 { + --fg: #87afd7; +} +.ap-terminal .bg-110 { + --bg: #87afd7; +} +.ap-terminal .fg-111 { + --fg: #87afff; +} +.ap-terminal .bg-111 { + --bg: #87afff; +} +.ap-terminal .fg-112 { + --fg: #87d700; +} +.ap-terminal .bg-112 { + --bg: #87d700; +} +.ap-terminal .fg-113 { + --fg: #87d75f; +} +.ap-terminal .bg-113 { + --bg: #87d75f; +} +.ap-terminal .fg-114 { + --fg: #87d787; +} +.ap-terminal .bg-114 { + --bg: #87d787; +} +.ap-terminal .fg-115 { + --fg: #87d7af; +} +.ap-terminal .bg-115 { + --bg: #87d7af; +} +.ap-terminal .fg-116 { + --fg: #87d7d7; +} +.ap-terminal .bg-116 { + --bg: #87d7d7; +} +.ap-terminal .fg-117 { + --fg: #87d7ff; +} +.ap-terminal .bg-117 { + --bg: #87d7ff; +} +.ap-terminal .fg-118 { + --fg: #87ff00; +} +.ap-terminal .bg-118 { + --bg: #87ff00; +} +.ap-terminal .fg-119 { + --fg: #87ff5f; +} +.ap-terminal .bg-119 { + --bg: #87ff5f; +} +.ap-terminal .fg-120 { + --fg: #87ff87; +} +.ap-terminal .bg-120 { + --bg: #87ff87; +} +.ap-terminal .fg-121 { + --fg: #87ffaf; +} +.ap-terminal .bg-121 { + --bg: #87ffaf; +} +.ap-terminal .fg-122 { + --fg: #87ffd7; +} +.ap-terminal .bg-122 { + --bg: #87ffd7; +} +.ap-terminal .fg-123 { + --fg: #87ffff; +} +.ap-terminal .bg-123 { + --bg: #87ffff; +} +.ap-terminal .fg-124 { + --fg: #af0000; +} +.ap-terminal .bg-124 { + --bg: #af0000; +} +.ap-terminal .fg-125 { + --fg: #af005f; +} +.ap-terminal .bg-125 { + --bg: #af005f; +} +.ap-terminal .fg-126 { + --fg: #af0087; +} +.ap-terminal .bg-126 { + --bg: #af0087; +} +.ap-terminal .fg-127 { + --fg: #af00af; +} +.ap-terminal .bg-127 { + --bg: #af00af; +} +.ap-terminal .fg-128 { + --fg: #af00d7; +} +.ap-terminal .bg-128 { + --bg: #af00d7; +} +.ap-terminal .fg-129 { + --fg: #af00ff; +} +.ap-terminal .bg-129 { + --bg: #af00ff; +} +.ap-terminal .fg-130 { + --fg: #af5f00; +} +.ap-terminal .bg-130 { + --bg: #af5f00; +} +.ap-terminal .fg-131 { + --fg: #af5f5f; +} +.ap-terminal .bg-131 { + --bg: #af5f5f; +} +.ap-terminal .fg-132 { + --fg: #af5f87; +} +.ap-terminal .bg-132 { + --bg: #af5f87; +} +.ap-terminal .fg-133 { + --fg: #af5faf; +} +.ap-terminal .bg-133 { + --bg: #af5faf; +} +.ap-terminal .fg-134 { + --fg: #af5fd7; +} +.ap-terminal .bg-134 { + --bg: #af5fd7; +} +.ap-terminal .fg-135 { + --fg: #af5fff; +} +.ap-terminal .bg-135 { + --bg: #af5fff; +} +.ap-terminal .fg-136 { + --fg: #af8700; +} +.ap-terminal .bg-136 { + --bg: #af8700; +} +.ap-terminal .fg-137 { + --fg: #af875f; +} +.ap-terminal .bg-137 { + --bg: #af875f; +} +.ap-terminal .fg-138 { + --fg: #af8787; +} +.ap-terminal .bg-138 { + --bg: #af8787; +} +.ap-terminal .fg-139 { + --fg: #af87af; +} +.ap-terminal .bg-139 { + --bg: #af87af; +} +.ap-terminal .fg-140 { + --fg: #af87d7; +} +.ap-terminal .bg-140 { + --bg: #af87d7; +} +.ap-terminal .fg-141 { + --fg: #af87ff; +} +.ap-terminal .bg-141 { + --bg: #af87ff; +} +.ap-terminal .fg-142 { + --fg: #afaf00; +} +.ap-terminal .bg-142 { + --bg: #afaf00; +} +.ap-terminal .fg-143 { + --fg: #afaf5f; +} +.ap-terminal .bg-143 { + --bg: #afaf5f; +} +.ap-terminal .fg-144 { + --fg: #afaf87; +} +.ap-terminal .bg-144 { + --bg: #afaf87; +} +.ap-terminal .fg-145 { + --fg: #afafaf; +} +.ap-terminal .bg-145 { + --bg: #afafaf; +} +.ap-terminal .fg-146 { + --fg: #afafd7; +} +.ap-terminal .bg-146 { + --bg: #afafd7; +} +.ap-terminal .fg-147 { + --fg: #afafff; +} +.ap-terminal .bg-147 { + --bg: #afafff; +} +.ap-terminal .fg-148 { + --fg: #afd700; +} +.ap-terminal .bg-148 { + --bg: #afd700; +} +.ap-terminal .fg-149 { + --fg: #afd75f; +} +.ap-terminal .bg-149 { + --bg: #afd75f; +} +.ap-terminal .fg-150 { + --fg: #afd787; +} +.ap-terminal .bg-150 { + --bg: #afd787; +} +.ap-terminal .fg-151 { + --fg: #afd7af; +} +.ap-terminal .bg-151 { + --bg: #afd7af; +} +.ap-terminal .fg-152 { + --fg: #afd7d7; +} +.ap-terminal .bg-152 { + --bg: #afd7d7; +} +.ap-terminal .fg-153 { + --fg: #afd7ff; +} +.ap-terminal .bg-153 { + --bg: #afd7ff; +} +.ap-terminal .fg-154 { + --fg: #afff00; +} +.ap-terminal .bg-154 { + --bg: #afff00; +} +.ap-terminal .fg-155 { + --fg: #afff5f; +} +.ap-terminal .bg-155 { + --bg: #afff5f; +} +.ap-terminal .fg-156 { + --fg: #afff87; +} +.ap-terminal .bg-156 { + --bg: #afff87; +} +.ap-terminal .fg-157 { + --fg: #afffaf; +} +.ap-terminal .bg-157 { + --bg: #afffaf; +} +.ap-terminal .fg-158 { + --fg: #afffd7; +} +.ap-terminal .bg-158 { + --bg: #afffd7; +} +.ap-terminal .fg-159 { + --fg: #afffff; +} +.ap-terminal .bg-159 { + --bg: #afffff; +} +.ap-terminal .fg-160 { + --fg: #d70000; +} +.ap-terminal .bg-160 { + --bg: #d70000; +} +.ap-terminal .fg-161 { + --fg: #d7005f; +} +.ap-terminal .bg-161 { + --bg: #d7005f; +} +.ap-terminal .fg-162 { + --fg: #d70087; +} +.ap-terminal .bg-162 { + --bg: #d70087; +} +.ap-terminal .fg-163 { + --fg: #d700af; +} +.ap-terminal .bg-163 { + --bg: #d700af; +} +.ap-terminal .fg-164 { + --fg: #d700d7; +} +.ap-terminal .bg-164 { + --bg: #d700d7; +} +.ap-terminal .fg-165 { + --fg: #d700ff; +} +.ap-terminal .bg-165 { + --bg: #d700ff; +} +.ap-terminal .fg-166 { + --fg: #d75f00; +} +.ap-terminal .bg-166 { + --bg: #d75f00; +} +.ap-terminal .fg-167 { + --fg: #d75f5f; +} +.ap-terminal .bg-167 { + --bg: #d75f5f; +} +.ap-terminal .fg-168 { + --fg: #d75f87; +} +.ap-terminal .bg-168 { + --bg: #d75f87; +} +.ap-terminal .fg-169 { + --fg: #d75faf; +} +.ap-terminal .bg-169 { + --bg: #d75faf; +} +.ap-terminal .fg-170 { + --fg: #d75fd7; +} +.ap-terminal .bg-170 { + --bg: #d75fd7; +} +.ap-terminal .fg-171 { + --fg: #d75fff; +} +.ap-terminal .bg-171 { + --bg: #d75fff; +} +.ap-terminal .fg-172 { + --fg: #d78700; +} +.ap-terminal .bg-172 { + --bg: #d78700; +} +.ap-terminal .fg-173 { + --fg: #d7875f; +} +.ap-terminal .bg-173 { + --bg: #d7875f; +} +.ap-terminal .fg-174 { + --fg: #d78787; +} +.ap-terminal .bg-174 { + --bg: #d78787; +} +.ap-terminal .fg-175 { + --fg: #d787af; +} +.ap-terminal .bg-175 { + --bg: #d787af; +} +.ap-terminal .fg-176 { + --fg: #d787d7; +} +.ap-terminal .bg-176 { + --bg: #d787d7; +} +.ap-terminal .fg-177 { + --fg: #d787ff; +} +.ap-terminal .bg-177 { + --bg: #d787ff; +} +.ap-terminal .fg-178 { + --fg: #d7af00; +} +.ap-terminal .bg-178 { + --bg: #d7af00; +} +.ap-terminal .fg-179 { + --fg: #d7af5f; +} +.ap-terminal .bg-179 { + --bg: #d7af5f; +} +.ap-terminal .fg-180 { + --fg: #d7af87; +} +.ap-terminal .bg-180 { + --bg: #d7af87; +} +.ap-terminal .fg-181 { + --fg: #d7afaf; +} +.ap-terminal .bg-181 { + --bg: #d7afaf; +} +.ap-terminal .fg-182 { + --fg: #d7afd7; +} +.ap-terminal .bg-182 { + --bg: #d7afd7; +} +.ap-terminal .fg-183 { + --fg: #d7afff; +} +.ap-terminal .bg-183 { + --bg: #d7afff; +} +.ap-terminal .fg-184 { + --fg: #d7d700; +} +.ap-terminal .bg-184 { + --bg: #d7d700; +} +.ap-terminal .fg-185 { + --fg: #d7d75f; +} +.ap-terminal .bg-185 { + --bg: #d7d75f; +} +.ap-terminal .fg-186 { + --fg: #d7d787; +} +.ap-terminal .bg-186 { + --bg: #d7d787; +} +.ap-terminal .fg-187 { + --fg: #d7d7af; +} +.ap-terminal .bg-187 { + --bg: #d7d7af; +} +.ap-terminal .fg-188 { + --fg: #d7d7d7; +} +.ap-terminal .bg-188 { + --bg: #d7d7d7; +} +.ap-terminal .fg-189 { + --fg: #d7d7ff; +} +.ap-terminal .bg-189 { + --bg: #d7d7ff; +} +.ap-terminal .fg-190 { + --fg: #d7ff00; +} +.ap-terminal .bg-190 { + --bg: #d7ff00; +} +.ap-terminal .fg-191 { + --fg: #d7ff5f; +} +.ap-terminal .bg-191 { + --bg: #d7ff5f; +} +.ap-terminal .fg-192 { + --fg: #d7ff87; +} +.ap-terminal .bg-192 { + --bg: #d7ff87; +} +.ap-terminal .fg-193 { + --fg: #d7ffaf; +} +.ap-terminal .bg-193 { + --bg: #d7ffaf; +} +.ap-terminal .fg-194 { + --fg: #d7ffd7; +} +.ap-terminal .bg-194 { + --bg: #d7ffd7; +} +.ap-terminal .fg-195 { + --fg: #d7ffff; +} +.ap-terminal .bg-195 { + --bg: #d7ffff; +} +.ap-terminal .fg-196 { + --fg: #ff0000; +} +.ap-terminal .bg-196 { + --bg: #ff0000; +} +.ap-terminal .fg-197 { + --fg: #ff005f; +} +.ap-terminal .bg-197 { + --bg: #ff005f; +} +.ap-terminal .fg-198 { + --fg: #ff0087; +} +.ap-terminal .bg-198 { + --bg: #ff0087; +} +.ap-terminal .fg-199 { + --fg: #ff00af; +} +.ap-terminal .bg-199 { + --bg: #ff00af; +} +.ap-terminal .fg-200 { + --fg: #ff00d7; +} +.ap-terminal .bg-200 { + --bg: #ff00d7; +} +.ap-terminal .fg-201 { + --fg: #ff00ff; +} +.ap-terminal .bg-201 { + --bg: #ff00ff; +} +.ap-terminal .fg-202 { + --fg: #ff5f00; +} +.ap-terminal .bg-202 { + --bg: #ff5f00; +} +.ap-terminal .fg-203 { + --fg: #ff5f5f; +} +.ap-terminal .bg-203 { + --bg: #ff5f5f; +} +.ap-terminal .fg-204 { + --fg: #ff5f87; +} +.ap-terminal .bg-204 { + --bg: #ff5f87; +} +.ap-terminal .fg-205 { + --fg: #ff5faf; +} +.ap-terminal .bg-205 { + --bg: #ff5faf; +} +.ap-terminal .fg-206 { + --fg: #ff5fd7; +} +.ap-terminal .bg-206 { + --bg: #ff5fd7; +} +.ap-terminal .fg-207 { + --fg: #ff5fff; +} +.ap-terminal .bg-207 { + --bg: #ff5fff; +} +.ap-terminal .fg-208 { + --fg: #ff8700; +} +.ap-terminal .bg-208 { + --bg: #ff8700; +} +.ap-terminal .fg-209 { + --fg: #ff875f; +} +.ap-terminal .bg-209 { + --bg: #ff875f; +} +.ap-terminal .fg-210 { + --fg: #ff8787; +} +.ap-terminal .bg-210 { + --bg: #ff8787; +} +.ap-terminal .fg-211 { + --fg: #ff87af; +} +.ap-terminal .bg-211 { + --bg: #ff87af; +} +.ap-terminal .fg-212 { + --fg: #ff87d7; +} +.ap-terminal .bg-212 { + --bg: #ff87d7; +} +.ap-terminal .fg-213 { + --fg: #ff87ff; +} +.ap-terminal .bg-213 { + --bg: #ff87ff; +} +.ap-terminal .fg-214 { + --fg: #ffaf00; +} +.ap-terminal .bg-214 { + --bg: #ffaf00; +} +.ap-terminal .fg-215 { + --fg: #ffaf5f; +} +.ap-terminal .bg-215 { + --bg: #ffaf5f; +} +.ap-terminal .fg-216 { + --fg: #ffaf87; +} +.ap-terminal .bg-216 { + --bg: #ffaf87; +} +.ap-terminal .fg-217 { + --fg: #ffafaf; +} +.ap-terminal .bg-217 { + --bg: #ffafaf; +} +.ap-terminal .fg-218 { + --fg: #ffafd7; +} +.ap-terminal .bg-218 { + --bg: #ffafd7; +} +.ap-terminal .fg-219 { + --fg: #ffafff; +} +.ap-terminal .bg-219 { + --bg: #ffafff; +} +.ap-terminal .fg-220 { + --fg: #ffd700; +} +.ap-terminal .bg-220 { + --bg: #ffd700; +} +.ap-terminal .fg-221 { + --fg: #ffd75f; +} +.ap-terminal .bg-221 { + --bg: #ffd75f; +} +.ap-terminal .fg-222 { + --fg: #ffd787; +} +.ap-terminal .bg-222 { + --bg: #ffd787; +} +.ap-terminal .fg-223 { + --fg: #ffd7af; +} +.ap-terminal .bg-223 { + --bg: #ffd7af; +} +.ap-terminal .fg-224 { + --fg: #ffd7d7; +} +.ap-terminal .bg-224 { + --bg: #ffd7d7; +} +.ap-terminal .fg-225 { + --fg: #ffd7ff; +} +.ap-terminal .bg-225 { + --bg: #ffd7ff; +} +.ap-terminal .fg-226 { + --fg: #ffff00; +} +.ap-terminal .bg-226 { + --bg: #ffff00; +} +.ap-terminal .fg-227 { + --fg: #ffff5f; +} +.ap-terminal .bg-227 { + --bg: #ffff5f; +} +.ap-terminal .fg-228 { + --fg: #ffff87; +} +.ap-terminal .bg-228 { + --bg: #ffff87; +} +.ap-terminal .fg-229 { + --fg: #ffffaf; +} +.ap-terminal .bg-229 { + --bg: #ffffaf; +} +.ap-terminal .fg-230 { + --fg: #ffffd7; +} +.ap-terminal .bg-230 { + --bg: #ffffd7; +} +.ap-terminal .fg-231 { + --fg: #ffffff; +} +.ap-terminal .bg-231 { + --bg: #ffffff; +} +.ap-terminal .fg-232 { + --fg: #080808; +} +.ap-terminal .bg-232 { + --bg: #080808; +} +.ap-terminal .fg-233 { + --fg: #121212; +} +.ap-terminal .bg-233 { + --bg: #121212; +} +.ap-terminal .fg-234 { + --fg: #1c1c1c; +} +.ap-terminal .bg-234 { + --bg: #1c1c1c; +} +.ap-terminal .fg-235 { + --fg: #262626; +} +.ap-terminal .bg-235 { + --bg: #262626; +} +.ap-terminal .fg-236 { + --fg: #303030; +} +.ap-terminal .bg-236 { + --bg: #303030; +} +.ap-terminal .fg-237 { + --fg: #3a3a3a; +} +.ap-terminal .bg-237 { + --bg: #3a3a3a; +} +.ap-terminal .fg-238 { + --fg: #444444; +} +.ap-terminal .bg-238 { + --bg: #444444; +} +.ap-terminal .fg-239 { + --fg: #4e4e4e; +} +.ap-terminal .bg-239 { + --bg: #4e4e4e; +} +.ap-terminal .fg-240 { + --fg: #585858; +} +.ap-terminal .bg-240 { + --bg: #585858; +} +.ap-terminal .fg-241 { + --fg: #626262; +} +.ap-terminal .bg-241 { + --bg: #626262; +} +.ap-terminal .fg-242 { + --fg: #6c6c6c; +} +.ap-terminal .bg-242 { + --bg: #6c6c6c; +} +.ap-terminal .fg-243 { + --fg: #767676; +} +.ap-terminal .bg-243 { + --bg: #767676; +} +.ap-terminal .fg-244 { + --fg: #808080; +} +.ap-terminal .bg-244 { + --bg: #808080; +} +.ap-terminal .fg-245 { + --fg: #8a8a8a; +} +.ap-terminal .bg-245 { + --bg: #8a8a8a; +} +.ap-terminal .fg-246 { + --fg: #949494; +} +.ap-terminal .bg-246 { + --bg: #949494; +} +.ap-terminal .fg-247 { + --fg: #9e9e9e; +} +.ap-terminal .bg-247 { + --bg: #9e9e9e; +} +.ap-terminal .fg-248 { + --fg: #a8a8a8; +} +.ap-terminal .bg-248 { + --bg: #a8a8a8; +} +.ap-terminal .fg-249 { + --fg: #b2b2b2; +} +.ap-terminal .bg-249 { + --bg: #b2b2b2; +} +.ap-terminal .fg-250 { + --fg: #bcbcbc; +} +.ap-terminal .bg-250 { + --bg: #bcbcbc; +} +.ap-terminal .fg-251 { + --fg: #c6c6c6; +} +.ap-terminal .bg-251 { + --bg: #c6c6c6; +} +.ap-terminal .fg-252 { + --fg: #d0d0d0; +} +.ap-terminal .bg-252 { + --bg: #d0d0d0; +} +.ap-terminal .fg-253 { + --fg: #dadada; +} +.ap-terminal .bg-253 { + --bg: #dadada; +} +.ap-terminal .fg-254 { + --fg: #e4e4e4; +} +.ap-terminal .bg-254 { + --bg: #e4e4e4; +} +.ap-terminal .fg-255 { + --fg: #eeeeee; +} +.ap-terminal .bg-255 { + --bg: #eeeeee; +} +.asciinema-player-theme-asciinema { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: hsl(0, 0%, 0%); + --term-color-1: hsl(343, 70%, 55%); + --term-color-2: hsl(103, 70%, 44%); + --term-color-3: hsl(43, 70%, 55%); + --term-color-4: hsl(193, 70%, 49.5%); + --term-color-5: hsl(283, 70%, 60.5%); + --term-color-6: hsl(163, 70%, 60.5%); + --term-color-7: hsl(0, 0%, 85%); + --term-color-8: hsl(0, 0%, 30%); + --term-color-9: hsl(343, 70%, 55%); + --term-color-10: hsl(103, 70%, 44%); + --term-color-11: hsl(43, 70%, 55%); + --term-color-12: hsl(193, 70%, 49.5%); + --term-color-13: hsl(283, 70%, 60.5%); + --term-color-14: hsl(163, 70%, 60.5%); + --term-color-15: hsl(0, 0%, 100%); +} +/* + Based on Dracula: https://draculatheme.com + */ +.asciinema-player-theme-dracula { + --term-color-foreground: #f8f8f2; + --term-color-background: #282a36; + --term-color-0: #21222c; + --term-color-1: #ff5555; + --term-color-2: #50fa7b; + --term-color-3: #f1fa8c; + --term-color-4: #bd93f9; + --term-color-5: #ff79c6; + --term-color-6: #8be9fd; + --term-color-7: #f8f8f2; + --term-color-8: #6272a4; + --term-color-9: #ff6e6e; + --term-color-10: #69ff94; + --term-color-11: #ffffa5; + --term-color-12: #d6acff; + --term-color-13: #ff92df; + --term-color-14: #a4ffff; + --term-color-15: #ffffff; +} +/* Based on Monokai from base16 collection - https://github.com/chriskempson/base16 */ +.asciinema-player-theme-monokai { + --term-color-foreground: #f8f8f2; + --term-color-background: #272822; + --term-color-0: #272822; + --term-color-1: #f92672; + --term-color-2: #a6e22e; + --term-color-3: #f4bf75; + --term-color-4: #66d9ef; + --term-color-5: #ae81ff; + --term-color-6: #a1efe4; + --term-color-7: #f8f8f2; + --term-color-8: #75715e; + --term-color-15: #f9f8f5; +} +/* + Based on Nord: https://github.com/arcticicestudio/nord + Via: https://github.com/neilotoole/asciinema-theme-nord + */ +.asciinema-player-theme-nord { + --term-color-foreground: #eceff4; + --term-color-background: #2e3440; + --term-color-0: #3b4252; + --term-color-1: #bf616a; + --term-color-2: #a3be8c; + --term-color-3: #ebcb8b; + --term-color-4: #81a1c1; + --term-color-5: #b48ead; + --term-color-6: #88c0d0; + --term-color-7: #eceff4; +} +.asciinema-player-theme-seti { + --term-color-foreground: #cacecd; + --term-color-background: #111213; + --term-color-0: #323232; + --term-color-1: #c22832; + --term-color-2: #8ec43d; + --term-color-3: #e0c64f; + --term-color-4: #43a5d5; + --term-color-5: #8b57b5; + --term-color-6: #8ec43d; + --term-color-7: #eeeeee; + --term-color-15: #ffffff; +} +/* + Based on Solarized Dark: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-dark { + --term-color-foreground: #839496; + --term-color-background: #002b36; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657b83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +/* + Based on Solarized Light: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-light { + --term-color-foreground: #657b83; + --term-color-background: #fdf6e3; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657c83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-fill { + fill: var(--term-color-1); +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-stroke { + stroke: var(--term-color-1); +} +/* + Based on Tango: https://en.wikipedia.org/wiki/Tango_Desktop_Project + */ +.asciinema-player-theme-tango { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: #000000; + --term-color-1: #cc0000; + --term-color-2: #4e9a06; + --term-color-3: #c4a000; + --term-color-4: #3465a4; + --term-color-5: #75507b; + --term-color-6: #06989a; + --term-color-7: #d3d7cf; + --term-color-8: #555753; + --term-color-9: #ef2929; + --term-color-10: #8ae234; + --term-color-11: #fce94f; + --term-color-12: #729fcf; + --term-color-13: #ad7fa8; + --term-color-14: #34e2e2; + --term-color-15: #eeeeec; +} +/* + Based on gruvbox: https://github.com/morhetz/gruvbox + */ +.asciinema-player-theme-gruvbox-dark { + --term-color-foreground: #fbf1c7; + --term-color-background: #282828; + --term-color-0: #282828; + --term-color-1: #cc241d; + --term-color-2: #98971a; + --term-color-3: #d79921; + --term-color-4: #458588; + --term-color-5: #b16286; + --term-color-6: #689d6a; + --term-color-7: #a89984; + --term-color-8: #7c6f65; + --term-color-9: #fb4934; + --term-color-10: #b8bb26; + --term-color-11: #fabd2f; + --term-color-12: #83a598; + --term-color-13: #d3869b; + --term-color-14: #8ec07c; + --term-color-15: #fbf1c7; +} diff --git a/docs/public/asciinema/asciinema-player.min.js b/docs/public/asciinema/asciinema-player.min.js new file mode 100644 index 0000000..1bdb365 --- /dev/null +++ b/docs/public/asciinema/asciinema-player.min.js @@ -0,0 +1 @@ +var AsciinemaPlayer=function(A){"use strict";function g(A){return"number"==typeof A?A:"string"==typeof A?A.split(":").reverse().map(parseFloat).reduce(((A,g,I)=>A+g*Math.pow(60,I))):void 0}class I{log(){}debug(){}info(){}warn(){}error(){}}class B{constructor(A,g){this.logger=A,this.prefix=g}log(A){for(var g=arguments.length,I=new Array(g>1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B{throw Error("TextDecoder not available")}};"undefined"!=typeof TextDecoder&&C.decode();let E=null;function V(){return null!==E&&0!==E.byteLength||(E=new Uint8Array(Q.memory.buffer)),E}function i(A,g){return A>>>=0,C.decode(V().subarray(A,A+g))}const e=new Array(128).fill(void 0);e.push(void 0,null,!0,!1);let o=e.length;function t(A){o===e.length&&e.push(e.length+1);const g=o;return o=e[g],e[g]=A,g}function s(A){return e[A]}function n(A){const g=s(A);return function(A){A<132||(e[A]=o,o=A)}(A),g}function r(A){const g=typeof A;if("number"==g||"boolean"==g||null==A)return`${A}`;if("string"==g)return`"${A}"`;if("symbol"==g){const g=A.description;return null==g?"Symbol":`Symbol(${g})`}if("function"==g){const g=A.name;return"string"==typeof g&&g.length>0?`Function(${g})`:"Function"}if(Array.isArray(A)){const g=A.length;let I="[";g>0&&(I+=r(A[0]));for(let B=1;B1))return toString.call(A);if(B=I[1],"Object"==B)try{return"Object("+JSON.stringify(A)+")"}catch(A){return"Object"}return A instanceof Error?`${A.name}: ${A.message}\n${A.stack}`:B}let a=0;const c="undefined"!=typeof TextEncoder?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},D="function"==typeof c.encodeInto?function(A,g){return c.encodeInto(A,g)}:function(A,g){const I=c.encode(A);return g.set(I),{read:A.length,written:I.length}};function w(A,g,I){if(void 0===I){const I=c.encode(A),B=g(I.length,1)>>>0;return V().subarray(B,B+I.length).set(I),a=I.length,B}let B=A.length,Q=g(B,1)>>>0;const C=V();let E=0;for(;E127)break;C[Q+E]=g}if(E!==B){0!==E&&(A=A.slice(E)),Q=I(Q,B,B=E+3*A.length,1)>>>0;const g=V().subarray(Q+E,Q+B);E+=D(A,g).written,Q=I(Q,B,E,1)>>>0}return a=E,Q}let l=null;function h(){return null!==l&&0!==l.byteLength||(l=new Int32Array(Q.memory.buffer)),l}let y=null;function G(A,g){return A>>>=0,(null!==y&&0!==y.byteLength||(y=new Uint32Array(Q.memory.buffer)),y).subarray(A/4,A/4+g)}const k="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((A=>Q.__wbg_vt_free(A>>>0)));class F{static __wrap(A){A>>>=0;const g=Object.create(F.prototype);return g.__wbg_ptr=A,k.register(g,g.__wbg_ptr,g),g}__destroy_into_raw(){const A=this.__wbg_ptr;return this.__wbg_ptr=0,k.unregister(this),A}free(){const A=this.__destroy_into_raw();Q.__wbg_vt_free(A)}feed(A){const g=w(A,Q.__wbindgen_malloc,Q.__wbindgen_realloc),I=a;return n(Q.vt_feed(this.__wbg_ptr,g,I))}resize(A,g){return n(Q.vt_resize(this.__wbg_ptr,A,g))}inspect(){let A,g;try{const C=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_inspect(C,this.__wbg_ptr);var I=h()[C/4+0],B=h()[C/4+1];return A=I,g=B,i(I,B)}finally{Q.__wbindgen_add_to_stack_pointer(16),Q.__wbindgen_free(A,g,1)}}getSize(){try{const B=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_getSize(B,this.__wbg_ptr);var A=h()[B/4+0],g=h()[B/4+1],I=G(A,g).slice();return Q.__wbindgen_free(A,4*g,4),I}finally{Q.__wbindgen_add_to_stack_pointer(16)}}getLine(A){return n(Q.vt_getLine(this.__wbg_ptr,A))}getCursor(){return n(Q.vt_getCursor(this.__wbg_ptr))}}function N(){const A={wbg:{}};return A.wbg.__wbindgen_error_new=function(A,g){return t(new Error(i(A,g)))},A.wbg.__wbindgen_object_drop_ref=function(A){n(A)},A.wbg.__wbindgen_object_clone_ref=function(A){return t(s(A))},A.wbg.__wbindgen_number_new=function(A){return t(A)},A.wbg.__wbindgen_bigint_from_u64=function(A){return t(BigInt.asUintN(64,A))},A.wbg.__wbindgen_string_new=function(A,g){return t(i(A,g))},A.wbg.__wbg_set_f975102236d3c502=function(A,g,I){s(A)[n(g)]=n(I)},A.wbg.__wbg_new_b525de17f44a8943=function(){return t(new Array)},A.wbg.__wbg_new_f841cc6f2098f4b5=function(){return t(new Map)},A.wbg.__wbg_new_f9876326328f45ed=function(){return t(new Object)},A.wbg.__wbindgen_is_string=function(A){return"string"==typeof s(A)},A.wbg.__wbg_set_17224bc548dd1d7b=function(A,g,I){s(A)[g>>>0]=n(I)},A.wbg.__wbg_set_388c4c6422704173=function(A,g,I){return t(s(A).set(s(g),s(I)))},A.wbg.__wbindgen_debug_string=function(A,g){const I=w(r(s(g)),Q.__wbindgen_malloc,Q.__wbindgen_realloc),B=a;h()[A/4+1]=B,h()[A/4+0]=I},A.wbg.__wbindgen_throw=function(A,g){throw new Error(i(A,g))},A}function q(A,g){return Q=A.exports,R.__wbindgen_wasm_module=g,l=null,y=null,E=null,Q}async function R(A){if(void 0!==Q)return Q;const g=N();("string"==typeof A||"function"==typeof Request&&A instanceof Request||"function"==typeof URL&&A instanceof URL)&&(A=fetch(A));const{instance:I,module:B}=await async function(A,g){if("function"==typeof Response&&A instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,g)}catch(g){if("application/wasm"==A.headers.get("Content-Type"))throw g;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",g)}const I=await A.arrayBuffer();return await WebAssembly.instantiate(I,g)}{const I=await WebAssembly.instantiate(A,g);return I instanceof WebAssembly.Instance?{instance:I,module:A}:I}}(await A,g);return q(I,B)}var J=Object.freeze({__proto__:null,Vt:F,create:function(A,g,I){const B=Q.create(A,g,I);return F.__wrap(B)},default:R,initSync:function(A){if(void 0!==Q)return Q;const g=N();return A instanceof WebAssembly.Module||(A=new WebAssembly.Module(A)),q(new WebAssembly.Instance(A,g),A)}});const d=[62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function M(A){return d[A-43]}const u=function(A){let g,I=A.endsWith("==")?2:A.endsWith("=")?1:0,B=A.length,Q=new Uint8Array(B/4*3);for(let I=0,C=0;I>16,Q[C+1]=g>>8&255,Q[C+2]=255&g;return Q.subarray(0,Q.length-I)}("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ACADKQAAIgk3AAggByAEQRRsaiICQqCAgIAQNwIAIAIgCTcACCAAQRBqIANBCGovAAAiADsAACACQRBqIAA7AAAgAUEBaiIAIAVPDQogByAAQRRsaiIAKAIEQQJGBEAgAUECaiIBIAVPDQ0gByABQRRsaiIBQqCAgIAQNwIAIAEgAykAADcACCABQRBqIANBCGovAAA7AAALIABCIDcCACAAQQhqIQRBAiEGDBALIAFBAWoiACAFTw0KIAcgAEEUbGoiAEKggICAEDcCACAAQQhqIQRBACEGDA8LIAEgBUG4ocAAEGwACyAEQYACQfCdwAAQbAALIARBFUGAnsAAEGwACyAGQbQBQZCewAAQbAALIAAgBUHYocAAEGwACyAAIAVByKHAABBsAAsgASAFQeihwAAQbAALIAEgBUGIosAAEGwACyAEIAVBuKLAABBsAAsgACAFQciiwAAQbAALIAAgBUGoosAAEGwACyABIAVB2KLAABBsAAsgBSABQQFrIgFLBEBBASEGIABBATYCBCAAIAI2AgAgByABQRRsaiIBQqCAgIAQNwIAIAEgAykAADcACCABQRBqIANBCGovAAA7AAAgAEEIaiEEDAMLIAEgBUGYosAAEGwACyAAQQE2AgQgACACNgIAIAggAykAADcAACAIQQhqIANBCGovAAA7AAAgASAFSQRAIAcgAUEUbGoiAEKggICAEDcCACAAQQhqIQRBASEGDAILIAEgBUH4ocAAEGwACyAAQQE2AgQgACACNgIAIABBCGohBEEBIQYLIAQgAykAADcAACAEQQhqIANBCGovAAA7AAALIAYLyAgCCX8BfiMAQUBqIgUkAAJAA0AgASgCDEEUayEDIAEoAhAhBAJAAkADQCADQRRqIgIgBEYNASABIANBKGo2AgwgA0EYaiACIQMoAgAiCUUNAAsgASgCCCIGDQEgBUEYaiICQRBqIgQgA0EQaigCADYCACACQQhqIgYgA0EIaikCADcDACAFIAMpAgA3AxhBACEDIAEoAgBFBEAgAUEAEIQBIAEoAgghAwsgASgCBCADQRRsaiICIAUpAxg3AgAgAkEQaiAEKAIANgIAIAJBCGogBikDADcCACABIAEoAghBAWo2AggMAgsgASgCCARAIAEpAgAhCyABQoCAgIDAADcCACAAIAs3AgAgAUEIaiIBKAIAIQIgAUEANgIAIABBCGogAjYCAAwDCyAAQYCAgIB4NgIADAILIANBCGoiCi0AACECAkACQCABKAIEIgggBkEUbGpBFGsiBC0ACCIHQQJGBEAgAkECRw0CDAELIAJBAkYNASACIAdHDQEgB0UEQCAELQAJIANBCWotAABGDQEMAgsgBC0ACSADQQlqLQAARw0BIAQtAAogA0EKai0AAEcNASAELQALIANBC2otAABHDQELIANBDGotAAAhAgJAIAQtAAwiB0ECRgRAIAJBAkcNAgwBCyACQQJGDQEgAiAHRw0BIAdFBEAgBC0ADSADQQ1qLQAARw0CDAELIAQtAA0gA0ENai0AAEcNASAELQAOIANBDmotAABHDQEgBC0ADyADQQ9qLQAARw0BCyAELQAQIANBEGoiBy0AAEcNACAELQARIANBEWotAABHDQAgBCgCACICQfz//wBxQbDBA0YNACACQeD//wBxQYDLAEYNACACQYD+/wBxQYDQAEYNACAEKAIEQQFLDQAgAkGA//8AcUGAygBGDQAgAygCACICQfz//wBxQbDBA0YNACACQeD//wBxQYDLAEYNACACQYD+/wBxQYDQAEYNACAJQQFHDQAgAkGA//8AcUGAygBGDQAgBUEYaiICQRBqIgQgBygCADYCACACQQhqIgcgCikCADcDACAFIAMpAgA3AxggASgCACAGRgR/IAEgBhCEASABKAIEIQggASgCCAUgBgtBFGwgCGoiAiAFKQMYNwIAIAJBEGogBCgCADYCACACQQhqIAcpAwA3AgAgASABKAIIQQFqNgIIDAELCyABKQIAIQsgAUKAgICAwAA3AgAgBUEQaiIEIAFBCGoiAigCADYCACACQQA2AgAgBSALNwMIIAVBGGoiBkEQaiIIIANBEGooAgA2AgAgBkEIaiIGIANBCGopAgA3AwAgBSADKQIANwMYIAFBABCEASABKAIEIAIoAgBBFGxqIgEgBSkDGDcCACABQRBqIAgoAgA2AgAgAUEIaiAGKQMANwIAIAIgAigCAEEBajYCACAAQQhqIAQoAgA2AgAgACAFKQMINwIACyAFQUBrJAALswcCCH8BfiMAQUBqIgUkAAJAA0AgASgCDEEUayECIAEoAhAhBAJAAkADQCACQRRqIgMgBEYNASABIAJBKGo2AgwgAkEYaiADIQIoAgBF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aiAFQQhqKQIANwIADAILIAhBgICAgHg2AgAgBSgCACICRQ0BIAUoAgQgAkEUbEEEEOUBDAELIANBAEGQpMAAEGwACyAFQSBqJAAgAUEIaiAIQQhqKQIANwIAIAEgBikCKDcCACAAQQhqIAdBCGopAgA3AgAgACAGKQIINwIADAQLIAAgBikCCDcCACAAQQhqIAZBEGopAgA3AgAMAwsCQCACIAxHBEAgASACQRBqIgo2AhAgAigCACIEQYCAgIB4Rw0BCyAGQQA7ATggBkECOgA0IAZBAjoAMCAGQqCAgIAQNwIoIAYgCSADazYCPCAGQQhqIgEgBkEoahAwIAAgBikCCDcCACAGQQA6ABQgAEEIaiABQQhqKQIANwIADAMLIA8gAikCBDcCACAQIAJBDGooAgA2AgAgBiAENgIYIAZBKGohByAGQRhqIQMjAEEgayICJAACQCAJIAZBCGoiBSgCCCIEayIIRQRAIAdBAToAACAHIAMpAgA3AgQgB0EMaiADQQhqKQIANwIADAELIAUtAAxFBEAgAiAINgIcIAJBADsBGCACQQI6ABQgAkECOgAQIAJCoICAgBA3AgggBSACQQhqEDAgB0EBOgAAIAcgAykCADcCBCAHQQxqIANBCGopAgA3AgAMAQsgAy0ADEUEQCADEGILIAMoAgQhCyADKAIIIg0gCE0EQCAFIAsgCyANQRRsahB6QQAhCAJAIAMtAAwNACAFQQA6AAxBASEIIAUoAggiBCAJTw0AIAJBADsBGCACQQI6ABQgAkECOgAQIAJCoICAgBA3AgggAiAJIARrNgIcIAUgAkEIahAwCyAHQYCAgIB4NgIEIAcgCDoAACADKAIAIgNFDQEgCyADQRRsQQQQ5QEMAQsCQCALIAhBFGxqKAIERQRAIARBAWshDSAERQ0BIAJBEGoiESAFKAIEIgsgDUEUbGoiDUEQai8AADsBACACIA0pAAg3AwggBSgCACAERgRAIAUgBBCEASAFKAIEIQsgBSgCCCEECyAEQRRsIAtqIgQgAikDCDcCCCAEQqCAgIAQNwIAIARBEGogES8BADsBACAFIAUoAghBAWo2AgggCEEBayEICwJAIAMoAggiBCAITwRAIAMoAgQhBCACIAg2AgQgAiAENgIADAELIAggBEGApMAAEOsBAAsgBSACKAIAIgQgBCACKAIE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BCABIAURAABFDQALDAILIAItAAoiAUEKIAFBCksbIQAgASACLQALIgMgASADSxshBgNAIAEgBkYNASACIAFBAWoiAzoACiAAIAFGDQMgASACaiEIIAMhASAEIAgtAAAgBREAAEUNAAsMAQsgBEEnIAURAAAhBwsgAkEQaiQAIAcPCyAAQQpBnIzBABBsAAvMAgACQAJAAkACQAJAAkACQCADQQFrDgYAAQIDBAUGCyAAKAIYIQMgACACQeSlwAAQigEiBEEAOgAMIAQgASADIAUQLiAAIAJBAWogACgCHCAFEFIPCyAAKAIYIQMgACACQfSlwAAQigFBACABQQFqIgEgAyABIANJGyAFEC4gAEEAIAIgBRBSDwsgAEEAIAAoAhwgBRBSDwsgACgCGCEDIAAgAkGEpsAAEIoBIgAgASADIAUQLiAAQQA6AAwPCyAAKAIYIQMgACACQZSmwAAQigFBACABQQFqIgAgAyAAIANJGyAFEC4PCyAAKAIYIQEgACACQaSmwAAQigEiAEEAIAEgBRAuIABBADoADA8LIAAoAhghAyAAIAJB1KXAABCKASIAIAEgASAEIAMgAWsiASABIARLG2oiASAFEC4gASADRgRAIABBADoADAsLuwIBAn8CQAJAAkACQAJAIAAoAggiBCABRg0AIAEgBE8NASAAKAIEIgUgAUEUbGooAgRFBEAgAUEBayIAIARPDQMgBSAAQRRsaiIAQqCAgIAQNwIAIAAgAykAADcACCAAQRBqIANBCGovAAA7AAALIAEgAksNAyACIARLDQQgBSACQRRsaiEAIAEgAkcEQCAFIAFBFGxqIQEgA0EIaiEFA0AgAUKggICAEDcCACABIAMpAAA3AAggAUEQaiAFLwAAOwAAIAAgAUEUaiIBRw0ACwsgAiAETw0AIAAoAgQNACAAQqCAgIAQNwIAIAAgAykAADcACCAAQRBqIANBCGovAAA7AAALDwsgASAEQYihwAAQbAALIAAgBEGYocAAEGwACyABIAJBqKHAABDtAQALIAIgBEGoocAAEOsBAAuUAgEDfyMAQRBrIgIkAAJAAn8CQCABQYABTwRAIAJBADYCDCABQYAQSQ0BIAFBgIAESQRAIAIgAUEMdkHgAXI6AAwgAiABQQZ2QT9xQYABcjoADUECIQNBAwwDCyACIAFBBnZBP3FBgAFy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aigCADYCACACQRBqJAALugEBAX8jAEEQayILJAAgACgCFCABIAIgACgCGCgCDBEBACEBIAtBADoADSALIAE6AAwgCyAANgIIIAtBCGogAyAEIAUgBhAnIAcgCCAJIAoQJyECIAstAAwhAQJ/IAFBAEcgCy0ADUUNABpBASABDQAaIAIoAgAiAC0AHEEEcUUEQCAAKAIUQbv5wABBAiAAKAIYKAIMEQEADAELIAAoAhRBuvnAAEEBIAAoAhgoAgwRAQALIAtBEGokAAuwAQEDf0EBIQRBBCEGAkAgAUUNACACQQBIDQACfwJAAkACfyADKAIEBEAgAygCCCIBRQRAIAJFBEAMBAtBiZPBAC0AABogAkEBENcBDAILIAMoAgAgAUEBIAIQzQEMAQsgAkUEQAwCC0GJk8EALQAAGiACQQEQ1wELIgRFDQELIAAgBDYCBEEADAELIABBATYCBEEBCyEEQQghBiACIQULIAAgBmogBTYCACAAIAQ2AgALwwEBAn8jAEFAaiICJAACQCABBEAgASgCACIDQX9GDQEgASADQQFqNgIAIAJBATYCFCACQeSGwAA2AhAgAkIBNwIcIAJBEzYCLCACIAFBBGo2AiggAiACQShqNgIYIAJBMGoiAyACQRBqECQgASABKAIAQQFrNgIAIAJBCGogAxDbASACKAIIIQEgAiACKAIMNgIEIAIgATYCACACKAIEIQEgACACKAIANgIAIAAgATYCBCACQUBrJAAPCxD+AQALEP8BAAu4AQEDfwJAIAAoAoQEIgFBf0cEQCABQQFqIQIgAUEgSQ0BIAJBIEHMl8AAEOsBAAtBzJfAABCqAQALIABBBGohASAAIAJBBHRqQQRqIQMDQAJAIAEoAgAiAkF/RwRAIAJBBkkNASACQQFqQQZB3JzAABDrAQALQdycwAAQqgEACyABQQRqQQAgAkEBdEECahCJAhogAUEANgIAIAMgAUEQaiIBRw0ACyAAQYCAxAA2AgAgAEEANgKEBAvmAgEEfyMAQSBrIgMkACADQQxqIQICQCABLQAgRQRAIAJBADYCAAwBCyABQQA6ACACQCABKAIABEAgASgCFCIFIAEoAhxrIgQgASgCCEsNAQsgAkEANgIADAELIAQgASgCBGsiBCAFTQRAIAFBADYCFCACIAQ2AgwgAiAFIARrNgIQIAIgAUEMajYCCCACIAEoAhAiBTYCACACIAUgBEEEdGo2AgQMAQsgBCAFQdCWwAAQ6wEACyADKAIMIQICfwJAAkAgAS0AvAFFBEAgAg0BDAILIAJFDQEgA0EMahA1DAELQYmTwQAtAAAaQRRBBBDXASIBBEAgASADKQIMNwIAIAFBEGogA0EMaiICQRBqKAIANgIAIAFBCGogAkEIaikCADcCAEHYrMAADAILQQRBFEHEk8EAKAIAIgBB3gAgABsRAgAAC0EBIQFBvKzAAAshAiAAIAI2AgQgACABNgIAIANBIGokAAuaAQEBfyAAIgQCfwJAAn8CQAJAIAEEQCACQQBIDQEgAygCBARAIAMoAggiAARAIAMoAgAgACABIAIQzQEMBQsLIAJFDQJBiZPBAC0AABogAiABENcBDAMLIARBADYCBAwDCyAEQQA2AgQMAgsgAQsiAARAIAQgAjYCCCAEIAA2AgRBAAwCCyAEIAI2AgggBCABNgIEC0EBCzYCAAubAQEBfwJAAkAgAQRAIAJBAEgNAQJ/IAMoAgQEQAJAIAMoAggiBEUEQAwBCyADKAIAIAQgASACEM0BDAILCyABIAJFDQAaQYmTwQAtAAAaIAIgARDXAQsiAwRAIAAgAjYCCCAAIAM2AgQgAEEANgIADwsgACACNgIIIAAgATYCBAwCCyAAQQA2AgQMAQsgAEEANgIECyAAQQE2AgALuQEBBH8CQAJAIAJFBEAgASgCACEDIAEoAgQhBQwBCyABKAIEIQUgASgCACEEA0AgBCAFRg0CIAEgBEEQaiIDNgIAIAQoAgAiBgRAIAZBgICAgHhGDQMgBCgCBCAGQRRsQQQQ5QELIAMhBCACQQFrIgINAAsLIAMgBUYEQCAAQYCAgIB4NgIADwsgASADQRBqNgIAIAAgAykCADcCACAAQQhqIANBCGopAgA3AgAPCyAAQYCAgIB4NgIAC5wNARJ/IwBBEGsiECQAIBBBCGohESAAKAKcASEJIAAoAqABIQ0gACgCaCELIAAoAmwhByMAQUBqIgMkAEEAIAAoAhQiBCAAKAIcIghrIAdqIgEgBGsiAiABIAJJGyEOIAAoAhAhDCAAKAIYIQ8CQCAERQ0AIAFFDQAgBCAHaiAIQX9zaiEFIAxBDGohBiAEQQR0QRBrIQEDQCAKIA9qQQAgBi0AACICGyEKIA4gAkEBc2ohDiAFRQ0BIAZBEGohBiAFQQFrIQUgASICQRBrIQEgAg0ACwsCQCAJIA9GDQAgCiALaiEKIABBADYCFCADQQA2AiAgAyAENgIcIAMgAEEMaiIHNgIYIAMgDCAEQQR0ajYCFCADIAw2AhAgAyAJNgIkIANBgICAgHg2AgAgA0EoaiELIwBB0ABrIgEkACABQRhqIAMQGwJAAkACQCABKAIYQYCAgIB4RgRAIAtBADYCCCALQoCAgIDAADcCACADELABDAELQYmTwQAtAAAaQcAAQQQQ1wEiAkUNASACIAEpAhg3AgAgAUEMaiIEQQhqIg9BATYCACACQQhqIAFBIGopAgA3AgAgASACNgIQIAFBBDYCDCABQShqIgwgA0EoEIoCGiMAQRBrIgIkACACIAwQGyACKAIAQYCAgIB4RwRAIAQoAggiBUEEdCEGA0AgBCgCACAFRgRAIAQgBUEBEIYBCyAEIAVBAWoiBTYCCCAEKAIEIAZqIhIgAikCADcCACASQQhqIAJBCGopAgA3AgAgAiAMEBsgBkEQaiEGIAIoAgBBgICAgHhHDQALCyAMELABIAJBEGokACALQQhqIA8oAgA2AgAgCyABKQIMNwIACyABQdAAaiQADAELQQRBwABBxJPBACgCACIAQd4AIAAbEQIAAAsgAygCMEEEdCEFIAMoAiwhBgJAA0AgBUUNASAFQRBrIQUgBigCCCAGQRBqIQYgCUYNAAtB9KfAAEE3QayowAAQnAEACyADQQhqIgEgA0EwaigCADYCACADIAMpAig3AwAgBxCMASAHKAIAIgIEQCAAKAIQIAJBBHRBBBDlAQsgByADKQMANwIAIAdBCGogASgCADYCACAIIAAoAhQiBEsEQCADQQA7ARAgA0ECOgAMIANBAjoACCADQqCAgIAQNwIAIANBKGoiASADIAkQVyADIAggBGs2AjggA0EAOgA0IAcgARBAIAAoAhQhBAtBACEFAkAgDkUNACAEQQFrIgJFDQAgACgCEEEMaiEGQQAhAQNAAkAgBCAFRwRAIAVBAWohBSAOIAEgBi0AAEEBc2oiAUsNAQwDCyAEIARBtKfAABBsAAsgBkEQaiEGIAIgBUsNAAsLAkACQCAJIApLDQAgBSAEIAQgBUkbIQEgACgCECAFQQR0akEMaiEGA0AgASAFRg0CIAYtAABFDQEgBkEQaiEGIAVBAWohBSAKIAlrIgogCU8NAAsLIAogCUEBayIBIAEgCksbIQsgBSAIIARraiIBQQBOIQIgAUEAIAIbIQcgCEEAIAEgAhtrIQgMAQsgASAEQaSnwAAQbAALIABBDGohAQJAAkACQEF/IAggDUcgCCANSxtB/wFxDgICAAELQQAgBCAIayICIAIgBEsbIgUgDSAIayICIAIgBUsbIgRBACAHIAhJGyAHaiEHIAIgBU0NASADQQA7ARAgA0ECOgAMIANBAjoACCADQqCAgIAQNwIAIANBKGoiBSADIAkQVyADIAIgBGs2AjggA0EAOgA0IAEgBRBADAELAkAgCCANayIFIAggB0F/c2oiAiACIAVLGyIGRQ0AAkAgBCAGayICIAEoAggiBEsNACABIAI2AgggAiAERg0AIAQgAmshBCABKAIEIAJBBHRqIQEDQCABKAIAIgIEQCABQQRqKAIAIAJBFGxBBBDlAQsgAUEQaiEBIARBAWsiBA0ACwsgACgCFCIBBEAgACgCECABQQR0akEEa0EAOgAADAELQZSnwAAQ7wEACyAHIAVrIAZqIQcLIABBAToAICAAIA02AhwgACAJNgIYIBEgBzYCBCARIAs2AgAgA0FAayQAIAAgECkDCDcCaCAAQdwAaiECAkAgACgCoAEiASAAKAJkIgNNBEAgACABNgJkDAELIAIgASADa0EAEFwgACgCoAEhAQsgAkEAIAEQeyAAKAKcASIBIAAoAnRNBEAgACABQQFrNgJ0CyAAKAKgASIBIAAoAnhNBEAgACABQQFrNgJ4CyAQQRBqJAAL+AIBA38jAEEwayIEJAAgACgCGCEFIARBLGogA0EIai8AADsBACAEQqCAgIAQNwIcIAQgAykAADcCJCAEQQxqIARBHGogBRBXIARBADoAGCAEIAAQmQECQCABIAJNBEAgBCgCBCIAIAJJDQEgBCgCACABQQR0aiEAIARBDGohAyMAQRBrIgUkAAJAIAIgAWsiAUUEQCADKAIAIgBFDQEgAygCBCAAQRRsQQQQ5QEMAQsgACABQQFrIgJBBHRqIQEgAgRAIAMtAAwhAgNAIAUgAxBhIAAoAgAiBgRAIAAoAgQgBkEUbEEEEOUBCyAAIAUpAwA3AgAgACACOgAMIABBCGogBUEIaigCADYCACABIABBEGoiAEcNAAsLIAEoAgAiAARAIAEoAgQgAEEUbEEEEOUBCyABIAMpAgA3AgAgAUEIaiADQQhqKQIANwIACyAFQRBqJAAgBEEwaiQADwsgASACQeSnwAAQ7QEACyACIABB5KfAABDrAQALjgEBA38jAEGAAWsiBCQAIAAoAgAhAANAIAIgBGpB/wBqIABBD3EiA0EwciADQdcAaiADQQpJGzoAACACQQFrIQIgAEEQSSAAQQR2IQBFDQALIAJBgAFqIgBBgQFPBEAgAEGAAUHg+cAAEOoBAAsgAUHw+cAAQQIgAiAEakGAAWpBACACaxAYIARBgAFqJAALlgEBA38jAEGAAWsiBCQAIAAtAAAhAkEAIQADQCAAIARqQf8AaiACQQ9xIgNBMHIgA0E3aiADQQpJGzoAACAAQQFrIQAgAkH/AXEiA0EEdiECIANBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIARqQYABakEAIABrEBggBEGAAWokAAuXAQEDfyMAQYABayIEJAAgAC0AACECQQAhAANAIAAgBGpB/wBqIAJBD3EiA0EwciADQdcAaiADQQpJGzoAACAAQQFrIQAgAkH/AXEiA0EEdiECIANBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIARqQYABakEAIABrEBggBEGAAWokAAuNAQEDfyMAQYABayIEJAAgACgCACEAA0AgAiAEakH/AGogAEEPcSIDQTByIANBN2ogA0EKSRs6AAAgAkEBayECIABBEEkgAEEEdiEARQ0ACyACQYABaiIAQYEBTwRAIABBgAFB4PnAABDqAQALIAFB8PnAAEECIAIgBGpBgAFqQQAgAmsQGCAEQYABaiQAC/ICAQZ/IwBBEGsiBiQAAkACQAJAIAJFBEBBBCEDDAELIAJB5syZM0sNASACQRRsIgRBAEgNAUGJk8EALQAAGiAEQQQQ1wEiA0UNAgsgBkEEaiIFQQhqIghBADYCACAGIAM2AgggBiACNgIEIAIgBSgCACAFKAIIIgNrSwRAIAUgAyACEIkBIAUoAgghAwsgBSgCBCADQRRsaiEEAkACQCACQQJPBEAgAkEBayEHA0AgBCABKQIANwIAIARBEGogAUEQaigCADYCACAEQQhqIAFBCGopAgA3AgAgBEEUaiEEIAdBAWsiBw0ACyACIANqQQFrIQMMAQsgAkUNAQsgBCABKQIANwIAIARBEGogAUEQaigCADYCACAEQQhqIAFBCGopAgA3AgAgA0EBaiEDCyAFIAM2AgggAEEIaiAIKAIANgIAIAAgBikCBDcCACAGQRBqJAAPCxCoAQALQQQgBEHEk8EAKAIAIgBB3gAgABsRAgAAC/EDAQZ/IwBBMGsiBSQAIAUgAjcDCCAAIQgCQCABLQACRQRAIAJCgICAgICAgBBaBEAgBUECNgIUIAVBxJTAADYCECAFQgE3AhwgBUE7NgIsIAUgBUEoajYCGCAFIAVBCGo2AihBASEBIwBBEGsiAyQAIAVBEGoiACgCDCEEAkACQAJAAkACQAJAAkAgACgCBA4CAAECCyAEDQFB/JPAACEGQQAhAAwCCyAEDQAgACgCACIEKAIEIQAgBCgCACEGDAELIANBBGogABAkIAMoAgwhACADKAIIIQQMAQsgA0EEaiIEAn8gAEUEQCAEQoCAgIAQNwIEQQAMAQsgAEEASARAIARBADYCBEEBDAELQYmTwQAtAAAaIABBARDXASIHBEAgBCAHNgIIIAQgADYCBEEADAELIAQgADYCCCAEQQE2AgRBAQs2AgAgAygCBARAIAMoAggiAEUNAiAAIAMoAgxBxJPBACgCACIAQd4AIAAbEQIAAAsgAygCCCEHIAMoAgwiBCAGIAAQigIhBiADIAA2AgwgAyAGNgIIIAMgBzYCBAsgBCAAEAAhACADQQRqEMkBIANBEGokAAwBCxCoAQALDAILQQAhASACuhADIQAMAQtBACEBIAIQBCEACyAIIAA2AgQgCCABNgIAIAVBMGokAAuSAQEEfyAALQC8AQRAIABBADoAvAEDQCAAIAFqIgJBiAFqIgMoAgAhBCADIAJB9ABqIgIoAgA2AgAgAiAENgIAIAFBBGoiAUEURw0AC0EAIQEDQCAAIAFqIgJBJGoiAygCACEEIAMgAigCADYCACACIAQ2AgAgAUEEaiIBQSRHDQALIABB3ABqQQAgACgCoAEQewsLkgQBCX8jAEEgayIEJAACQCABBEAgASgCACICQX9GDQEgASACQQFqNgIAIARBFGohAkGJk8EALQAAGiABQQRqIgMoAqABIQUgAygCnAEhBkEIQQQQ1wEiA0UEQEEEQQhBxJPBACgCACIAQd4AIAAbEQIAAAsgAyAFNgIEIAMgBjYCACACQQI2AgggAiADNgIEIAJBAjYCACABIAEoAgBBAWs2AgAjAEEQayIDJAACQAJAAkAgAigCCCIFIAIoAgBPDQAgA0EIaiEHIwBBIGsiASQAAkAgBSACKAIAIgZNBEACf0GBgICAeCAGRQ0AGiAGQQJ0IQggAigCBCEJAkAgBUUEQEEEIQogCSAIQQQQ5QEMAQtBBCAJIAhBBCAFQQJ0IgYQzQEiCkUNARoLIAIgBTYCACACIAo2AgRBgYCAgHgLIQIgByAGNgIEIAcgAjYCACABQSBqJAAMAQsgAUEBNgIMIAFBjInAADYCCCABQgA3AhQgAUHoiMAANgIQIAFBCGpB4InAABCjAQALIAMoAggiAUGBgICAeEYNACABRQ0BIAEgAygCDEHEk8EAKAIAIgBB3gAgABsRAgAACyADQRBqJAAMAQsQqAEACyAEKAIYIQEgBEEIaiICIAQoAhw2AgQgAiABNgIAIAQoAgwhASAAIAQoAgg2AgAgACABNgIEIARBIGokAA8LEP4BAAsQ/wEAC5EBAgR/AX4jAEEgayICJAAgASgCAEGAgICAeEYEQCABKAIMIQMgAkEUaiIEQQhqIgVBADYCACACQoCAgIAQNwIUIARB8O7AACADEB0aIAJBEGogBSgCACIDNgIAIAIgAikCFCIGNwMIIAFBCGogAzYCACABIAY3AgALIABBxPHAADYCBCAAIAE2AgAgAkEgaiQAC3gBA38gASAAKAIAIAAoAggiA2tLBEAgACADIAEQhwEgACgCCCEDCyAAKAIEIgUgA2ohBAJAAkAgAUECTwRAIAQgAiABQQFrIgEQiQIaIAUgASADaiIDaiEEDAELIAFFDQELIAQgAjoAACADQQFqIQMLIAAgAzYCCAumAQEDfyMAQRBrIgYkACAGQQhqIAAgASACQeSmwAAQZSAGKAIIIQcgAyACIAFrIgUgAyAFSRsiAyAGKAIMIgVLBEBBoJ/AAEEhQcSfwAAQnAEACyAFIANrIgUgByAFQQR0aiADEBUgACABIAEgA2ogBBBSIAEEQCAAIAFBAWtB9KbAABCKAUEAOgAMCyAAIAJBAWtBhKfAABCKAUEAOgAMIAZBEGokAAu+AQEFfwJAIAAoAggiAgRAIAAoAgQhBiACIQQDQCAGIAJBAXYgA2oiAkECdGooAgAiBSABRg0CIAIgBCABIAVJGyIEIAJBAWogAyABIAVLGyIDayECIAMgBEkNAAsLIAAoAggiAiAAKAIARgRAIAAgAhCFAQsgACgCBCADQQJ0aiEEAkAgAiADTQRAIAIgA0YNASADIAIQawALIARBBGogBCACIANrQQJ0EIgCCyAEIAE2AgAgACACQQFqNgIICwuOAgEFfwJAIAAoAggiAkUNACAAKAIEIQYgAiEDA0AgBiACQQF2IARqIgJBAnRqKAIAIgUgAUcEQCACIAMgASAFSRsiAyACQQFqIAQgASAFSxsiBGshAiADIARLDQEMAgsLAkAgACgCCCIBIAJLBEAgACgCBCACQQJ0aiIDKAIAGiADIANBBGogASACQX9zakECdBCIAiAAIAFBAWs2AggMAQsjAEEwayIAJAAgACABNgIEIAAgAjYCACAAQSxqQd0ANgIAIABBAzYCDCAAQcD1wAA2AgggAEICNwIUIABB3QA2AiQgACAAQSBqNgIQIAAgAEEEajYCKCAAIAA2AiAgAEEIakGQr8AAEKMBAAsLC8JXAhp/AX4jAEEQayITJAACQCAABEAgACgCAA0BIABBfzYCACMAQSBrIgQkACAEIAI2AhwgBCABNgIYIAQgAjYCFCAEQQhqIARBFGoQ2wEgE0EIaiAEKQMINwMAIARBIGokACATKAIIIRcgEygCDCEUIwBBIGsiDiQAIA5BCGohFSAAQQRqIQMgFyEBIwBBMGsiECQAAkAgFEUNACADQcQBaiEGIAEgFGohGgNAAn8gASwAACICQQBOBEAgAkH/AXEhAiABQQFqDAELIAEtAAFBP3EhBSACQR9xIQQgAkFfTQRAIARBBnQgBXIhAiABQQJqDAELIAEtAAJBP3EgBUEGdHIhBSACQXBJBEAgBSAEQQx0ciECIAFBA2oMAQsgBEESdEGAgPAAcSABLQADQT9xIAVBBnRyciICQYCAxABGDQIgAUEEagshASAQQSBqIQVBwQAgAiACQZ8BSxshBAJAAkACQAJAAkACQAJAAkACQCAGLQCIBCIIDgUAAwMDAQMLIARBIGtB4ABJDQEMAgsgBEEwa0EMTw0BDAILIAUgAjYCBCAFQSE6AAAMBQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIARB/wFxIgdBG0cEQCAHQdsARg0BIAgODQMEBQYHDAgMDAwCDAkMCyAGQQE6AIgEIAYQTAwkCwJAIAgODQIABAUGDAcMDAwBDAgMCyAGQQM6AIgEIAYQTAwjCyAEQSBrQd8ASQ0iDAkLIARBGEkNHyAEQRlGDR8gBEH8AXFBHEcNCAwfCyAEQfABcUEgRg0FIARBMGtBIEkNISAEQdEAa0EHSQ0hAkACQCAEQf8BcUHZAGsOBSMjACMBAAsgBEHgAGtBH08NCAwiCyAGQQw6AIgEDCALIARBMGtBzwBPDQYMIAsgBEEvSwRAIARBO0cgBEE6T3FFBEAgBkEEOgCIBAwfCyAEQUBqQT9JDSELIARB/AFxQTxHDQUgBiACNgIAIAZBBDoAiAQMHgsgBEFAakE/SQ0fIARB/AFxQTxHDQQgBkEGOgCIBAwdCyAEQUBqQT9PDQMgBkEAOgCIBAwcCyAEQSBrQeAASQ0bAkAgBEH/AXEiB0HPAE0EQCAHQRhrDgMGBQYBCyAHQZkBa0ECSQ0FIAdB0ABGDRwMBAsgB0EHRg0BDAMLIAYgAjYCACAGQQI6AIgEDBoLIAZBADoAiAQMGQsCQCAEQf8BcSIHQRhrDgMCAQIACyAHQZkBa0ECSQ0BIAdB0ABHDQAgCEEBaw4KAgQICQoTCwwNDhgLIARB8AFxIgdBgAFGDQAgBEGRAWtBBksNAgsgBkEAOgCIBAwUCyAGQQc6AIgEIAYQTAwVCwJAIAhBAWsOCgMCBQAHDwgJCgsPCyAHQSBHDQUgBiACNgIAIAZBBToAiAQMFAsgBEHwAXEhBwsgB0EgRw0BDA8LIARBGEkNDyAEQf8BcSIHQdgAayIJQQdLDQpBASAJdEHBAXFFDQogBkENOgCIBAwRCyAEQRhJDQ4gBEEZRg0OIARB/AFxQRxGDQ4MCgsgBEEYSQ0NIARBGUYNDSAEQfwBcUEcRg0NIARB8AFxQSBHDQkgBiACNgIAIAZBBToAiAQMDwsgBEEYSQ0MIARBGUYNDCAEQfwBcUEcRg0MDAgLIARBQGpBP08EQCAEQfABcSIHQSBGDQsgB0EwRw0IIAZBBjoAiAQMDgsMDwsgBEH8AXFBPEYNAyAEQfABcUEgRg0EIARBQGpBP08NBiAGQQo6AIgEDAwLIARBL00NBSAEQTpJDQogBEE7Rg0KIARBQGpBPksNBSAGQQo6AIgEDAsLIARBQGpBP08NBCAGQQo6AIgEDAoLIARBGEkNCSAEQRlGDQkgBEH8AXFBHEYNCQwDCyAGIAI2AgAgBkEIOgCIBAwICyAGIAI2AgAgBkEJOgCIBAwHCyAHQRlGDQQgBEH8AXFBHEYNBAsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAEQf8BcSIHQZABaw4QAwYGBgYGBgYABgYEAQIAAAULIAZBDToAiAQMFAsgBkEAOgCIBAwTCyAGQQw6AIgEDBILIAZBBzoAiAQgBhBMDBELIAZBAzoAiAQgBhBMDBALAkAgB0E6aw4CBAIACyAHQRlGDQILIAhBA2sOBwgOAwkECgYOCyAIQQNrDgcHDQ0IBAkGDQsgCEEDaw4HBgwKBwwIBQwLAkAgCEEDaw4HBgwMBwAIBQwLIAZBCzoAiAQMCwsgBEEYSQ0IIARB/AFxQRxHDQoMCAsgBEEwa0EKTw0JCyAGQQg6AIgEDAcLIARB8AFxQSBGDQQLIARB8AFxQTBHDQYgBkELOgCIBAwGCyAEQTpHDQUgBkEGOgCIBAwFCyAEQRhJDQIgBEEZRg0CIARB/AFxQRxHDQQMAgsgBEHwAXFBIEcEQCAEQTpHIARB/AFxQTxHcQ0EIAZBCzoAiAQMBAsgBiACNgIAIAZBCToAiAQMAwsgBiACNgIADAILIAUgAhBnDAQLIAYoAoQEIQQCQAJAAkACQAJAIAJBOmsOAgEAAgsgBkEfIARBAWoiAiACQSBGGzYChAQMAwsgBEEgSQ0BIARBIEHcl8AAEGwACyAEQSBPBEAgBEEgQeyXwAAQbAALIAYgBEEEdGpBBGoiCCgCACIEQQZJBEAgCCAEQQF0akEEaiIEIAQvAQBBCmwgAkEwa0H/AXFqOwEADAILIARBBkHsnMAAEGwACyAGIARBBHRqQQRqIgQoAgBBAWohAiAEIAJBBSACQQVJGzYCAAsLIAVBMjoAAAwCCyAGQQA6AIgEAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAGKAIAIgRBgIDEAEYEQCACQeD//wBxQcAARg0BIAJBN2sOAgMEAgsgAkEwRg0GIAJBOEYNBSAEQShrDgIJCwwLIAUgAkFAa0GfAXEQZwwMCyACQeMARg0CDAoLIAVBEToAAAwKCyAFQQ86AAAMCQsgBUEkOgAAIAZBADoAiAQMCAsgBEEjaw4HAQYGBgYDBQYLIARBKGsOAgEDBQsgBUEOOgAADAULIAVBmgI7AQAMBAsgBUEaOwEADAMLIAVBmQI7AQAMAgsgBUEZOwEADAELIAVBMjoAAAsMAQsgBkEAOgCIBCMAQUBqIggkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBigCACIEQYCAxABGBEAgAkFAag42AQIDBAUGBwgJCgsMDQ43Nw83NxARNzcSEzcUNzc3NzcVFhc3GBkaGxw3NzcdHjc3NzcfIDIhNwsCQCACQewAaw4FNTc3NzMACyACQegARg0zDDYLIAVBHToAACAFIAYvAQg7AQIMNgsgBUEMOgAAIAUgBi8BCDsBAgw1CyAFQQk6AAAgBSAGLwEIOwECDDQLIAVBCjoAACAFIAYvAQg7AQIMMwsgBUEIOgAAIAUgBi8BCDsBAgwyCyAFQQQ6AAAgBSAGLwEIOwECDDELIAVBBToAACAFIAYvAQg7AQIMMAsgBUECOgAAIAUgBi8BCDsBAgwvCyAFQQs6AAAgBSAGLwEYOwEEIAUgBi8BCDsBAgwuCyAFQQM6AAAgBSAGLwEIOwECDC0LIAYvAQgOBBcYGRoWCyAGLwEIDgMbHB0aCyAFQR46AAAgBSAGLwEIOwECDCoLIAVBFToAACAFIAYvAQg7AQIMKQsgBUENOgAAIAUgBi8BCDsBAgwoCyAFQS06AAAgBSAGLwEIOwECDCcLIAVBKDoAACAFIAYvAQg7AQIMJgsgBi8BCA4GGRgaGBgbGAsgBUEWOgAAIAUgBi8BCDsBAgwkCyAFQQE6AAAgBSAGLwEIOwECDCMLIAVBAjoAACAFIAYvAQg7AQIMIgsgBUEKOgAAIAUgBi8BCDsBAgwhCyAFQSI6AAAgBSAGLwEIOwECDCALIAVBLzoAACAFIAYvAQg7AQIMHwsgBUEwOgAAIAUgBi8BCDsBAgweCyAFQQs6AAAgBSAGLwEYOwEEIAUgBi8BCDsBAgwdCyAGLwEIDgQUExMVEwsgCEEIaiAGQQRqIAYoAoQEQfyXwAAQngEgCEE0aiICIAgoAggiBCAEIAgoAgxBBHRqEEIgCEEwaiACQQhqKAIANgAAIAggCCkCNDcAKCAFQSs6AAAgBSAIKQAlNwABIAVBCGogCEEsaikAADcAAAwbCyAIQRBqIAZBBGogBigChARBjJjAABCeASAIQTRqIgIgCCgCECIEIAQgCCgCFEEEdGoQQiAIQTBqIAJBCGooAgA2AAAgCCAIKQI0NwAoIAVBJToAACAFIAgpACU3AAEgBUEIaiAIQSxqKQAANwAADBoLIAhBGGogBkEEaiAGKAKEBEGcmMAAEJ4BIAhBNGohCyAIKAIYIQIgCCgCHCEEIwBBIGsiByQAIAcgBDYCCCAHIAI2AgQgB0EbaiAHQQRqEBACQAJAAkAgBy0AG0ESRgRAIAtBADYCCCALQoCAgIAQNwIADAELQYmTwQAtAAAaQRRBARDXASICRQ0BIAIgBygAGzYAACAHQQxqIgRBCGoiG0EBNgIAIAdBBDYCDCACQQRqIAdBH2otAAA6AAAgByACNgIQIAcoAgQhAiAHKAIIIQojAEEQayIJJAAgCSAKNgIEIAkgAjYCACAJQQtqIAkQECAJLQALQRJHBEAgBCgCCCINQQVsIREDQCAEKAIAIA1GBEACQCAEIQIjAEEQayIMJAAgDEEIaiEYIwBBIGsiCiQAAn9BACANQQFqIhIgDUkNABpBASEPIAIoAgAiGUEBdCIWIBIgEiAWSRsiEkEEIBJBBEsbIhZBBWwhHCASQZqz5swBSSESAkAgGUUEQEEAIQ8MAQsgCiAZQQVsNgIcIAogAigCBDYCFAsgCiAPNgIYIApBCGogEiAcIApBFGoQTiAKKAIIRQRAIAooAgwhDyACIBY2AgAgAiAPNgIEQYGAgIB4DAELIAooAhAhAiAKKAIMCyEPIBggAjYCBCAYIA82AgAgCkEgaiQAAkAgDCgCCCICQYGAgIB4RwRAIAJFDQEgAiAMKAIMQcSTwQAoAgAiAEHeACAAGxECAAALIAxBEGokAAwBCxCoAQALCyAEIA1BAWoiDTYCCCAEKAIEIBFqIgIgCSgACzYAACACQQRqIAlBC2oiAkEEai0AADoAACARQQVqIREgAiAJEBAgCS0AC0ESRw0ACwsgCUEQaiQAIAtBCGogGygCADYCACALIAcpAgw3AgALIAdBIGokAAwBC0EBQRRBxJPBACgCACIAQd4AIAAbEQIAAAsgCEEwaiALQQhqKAIANgAAIAggCCkCNDcAKCAFQSk6AAAgBSAIKQAlNwABIAVBCGogCEEsaikAADcAAAwZCyAFQRM6AAAgBSAGLwEYOwEEIAUgBi8BCDsBAgwYCyAFQSc6AAAMFwsgBUEmOgAADBYLIAVBMjoAAAwVCyAFQRc7AQAMFAsgBUGXAjsBAAwTCyAFQZcEOwEADBILIAVBlwY7AQAMEQsgBUEyOgAADBALIAVBGDsBAAwPCyAFQZgCOwEADA4LIAVBmAQ7AQAMDQsgBUEyOgAADAwLIAVBBzsBAAwLCyAFQYcCOwEADAoLIAVBhwQ7AQAMCQsgBUEyOgAADAgLIAVBLjsBAAwHCyAFQa4COwEADAYLIAYvAQhBCEYNAyAFQTI6AAAMBQsgBEEhRw0DIAVBFDoAAAwECyAEQT9HDQICQCAGKAKEBCICQX9HBEAgAkEBaiEEIAJBIEkNASAEQSBBrJjAABDrAQALQayYwAAQqgEACyAIQTRqIgIgBkEEaiIHIAcgBEEEdGoQOyAIQTBqIAJBCGooAgA2AAAgCCAIKQI0NwAoIAVBEjoAACAFIAgpACU3AAEgBUEIaiAIQSxqKQAANwAADAMLIARBP0cNAQJAIAYoAoQEIgJBf0cEQCACQQFqIQQgAkEgSQ0BIARBIEG8mMAAEOsBAAtBvJjAABCqAQALIAhBNGoiAiAGQQRqIgcgByAEQQR0ahA7IAhBMGogAkEIaigCADYAACAIIAgpAjQ3ACggBUEQOgAAIAUgCCkAJTcAASAFQQhqIAhBLGopAAA3AAAMAgsgBUExOgAAIAUgBi8BGDsBBCAFIAYvASg7AQIMAQsgBUEyOgAACyAIQUBrJAALIBAtACBBMkcEQAJAQQAhByMAQeAAayIIJAACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBBBIGoiAi0AAEEBaw4xAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMQALIAMCfyADKAJoIgIgAygCnAEiBEcEQEEAIAJBAWsiAiAEQQFrIAIgBEkbIAJBAEgbDAELQQAgAkECayIEIAJBAWsgAkEBSxsgBEEASBsLNgJoDDILIAIvAQIhBCMAQRBrIgkkACAJQQhqIQsgAygCaCENIANB0ABqIgIoAgQhCiAKIAIoAghBAnRqIQICQAJAIARBASAEQQFLGyIEQQFrIgwEQEEBIQUDQCACQQRrIQQgB0EBaiEHA0AgBCICQQRqIApGDQMgBQRAIAJBBGshBCACKAIAIA1PDQELC0EAIQUgByAMRw0ACwsDQCACIApGDQEgAkEEayICKAIAIQRBASEFIAwNAiAEIA1PDQALDAELQQAhBQsgCyAENgIEIAsgBTYCACADIAkoAgxBACAJKAIIGyICIAMoApwBIgRBAWsgAiAESRs2AmggCUEQaiQADDELIAMgAi8BAiICQQEgAkEBSxtBAWsiAiADKAKcASIEQQFrIAIgBEkbNgJoDDALIAIvAQIhBCMAQRBrIgkkACAJQQhqIQogAygCaCELIANB0ABqIgUoAgQhAiACIAUoAghBAnRqIQ0CfwJAIARBASAEQQFLGyIFQQFrIgwEQEEBIQUDQCAHQQFqIQcgBUEBcSEFA0AgDSACIgRGDQMgBQRAIARBBGohAiAEKAIAIAtNDQELCyAEQQRqIQJBACEFIAcgDEcNAAsgBEEEaiECCyACIQQDQCAEIA1GDQECQCAMBEAgAigCACEFDAELIAQoAgAhBSAEQQRqIQQgBSALTQ0BCwtBAQwBC0EACyECIAogBTYCBCAKIAI2AgAgAyAJKAIMIAMoApwBIgJBAWsiBCAJKAIIGyIFIAQgAiAFSxs2AmggCUEQaiQADC8LIANBADYCaCADIAMoAqABQQFrIAMoAqwBIgQgBCADKAJsIgRJGyIFIAQgAi8BAiICQQEgAkEBSxtqIgIgAiAFSxs2AmwMLgsgA0EANgJoIANBACADKAKoASIEIAQgAygCbCIESxsiBSAEIAIvAQIiAkEBIAJBAUsbayICIAIgBUgbNgJsDC0LIANBADYCaAwsCwJAAkACQAJAIAItAAFBAWsOAgECAAsgAygCaCICRQ0CIAIgAygCnAFPDQIgA0HQAGogAhBeDAILIANB0ABqIAMoAmgQXwwBCyADQQA2AlgLDCsLIANBACADKAJoIgQgAi8BAiICQQEgAkEBSxsiAkF/c0EAIAJrIAMoApwBIgIgBEYbaiIEIAJBAWsgAiAESxsgBEEASBs2AmgMKgsgAyADKAJoIgQgAygCnAFBAWsiBSAEIAVJGzYCaCADIAMoAqABQQFrIAMoAqwBIgQgBCADKAJsIgRJGyIFIAQgAi8BAiICQQEgAkEBSxtqIgIgAiAFSxs2AmwMKQsgA0EAIAMoAmggAi8BAiICQQEgAkEBSxtqIgIgAygCnAEiBEEBayACIARJGyACQQBIGzYCaAwoCyACLwECIQQgAyACLwEEIgJBASACQQFLG0EBayIFIAMoApwBIgdBAWsiAiAFIAdJGyIFIAIgAiAFSxs2AmggAyAEQQEgBEEBSxsgAygCqAFBACADLQC+ASIEGyICakEBayIFIAIgAiAFSRsiAiADKAKsASADKAKgAUEBayAEGyIEIAIgBEkbNgJsDCcLIAMgAygCaCIEIAMoApwBQQFrIgUgBCAFSRs2AmggA0EAIAMoAqgBIgQgBCADKAJsIgRLGyIFIAQgAi8BAiICQQEgAkEBSxtrIgIgAiAFSBs2AmwMJgsgAi8BAiEEIAMoAmgiAiADKAKcASIFTwRAIAMgBUEBayICNgJoCyAEQQEgBEEBSxsiBCADKAIYIAJrIgUgBCAFSRshCiADQbIBaiEHAkACQAJAIAMgAygCbCIEQcSlwAAQigEiDSgCCCIFIAJLBEAgDSgCBCILIAJBFGxqIgkoAgRFBEAgAkEBayIMIAVPDQIgCyAMQRRsaiIMQqCAgIAQNwIAIAwgBykAADcACCAMQRBqIAdBCGovAAA7AAALIAkgBSACayAKELMBIAkoAgRFBEAgCUKggICAEDcCACAJIAcpAAA3AAggCUEQaiAHQQhqLwAAOwAACyAFIAprIQIgBSAKSQ0CIAoEQCALIAVBFGxqIQUgCyACQRRsaiECIAdBCGohCQNAIAJCoICAgBA3AgAgAiAHKQAANwAIIAJBEGogCS8AADsAACAFIAJBFGoiAkcNAAsLDAMLIAIgBUHAo8AAEGwACyAMIAVB0KPAABBsAAsgAiAFQeCjwAAQ6gEACyANQQA6AAwgBCADKAJkIgJPDSYgAygCYCAEakEBOgAADCULQQAhAiMAQRBrIgUkAAJAAkAgAygCoAEiCgRAIAMoAmAhCyADKAJkIQcgAygCnAEhCQNAIAkEQEEAIQQDQCAFQQA7AA4gBUECOgAKIAVBAjoABiADIAJBlKXAABCKASAEQcUAIAVBBmoQERogCSAEQQFqIgRHDQALCyACIAdGDQIgAiALakEBOgAAIAogAkEBaiICRw0ACwsgBUEQaiQADAELIAcgB0GIsMAAEGwACwwkCyADIAMpAnQ3AmggAyADKQF8NwGyASADIAMvAYYBOwG+ASADQboBaiADQYQBai8BADsBAAwjCyACQQRqIgIoAgQhBCACKAIAIQogAigCCCICBEAgAkEBdCEHIANBsgFqIQUgA0H8AGohCSAEIQIDQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAi8BACILQQFrDgcCAQEBAQMEAAsgC0GXCGsOAwUGBwQLAAsgA0EAOgDBAQwHCyADQgA3AmggA0EAOgC+AQwGCyADQQA6AL8BDAULIANBADoAcAwECyADEFkMAgsgAyADKQJ0NwJoIAUgCSkBADcBACADIAMvAYYBOwG+ASAFQQhqIAlBCGovAQA7AQAMAgsgAxBZIAMgAykCdDcCaCAFIAkpAQA3AQAgBUEIaiAJQQhqLwEAOwEAIAMgAy8BhgE7Ab4BCyADEFELIAJBAmohAiAHQQJrIgcNAAsLIAoEQCAEIApBAXRBAhDlAQsMIgsgAyADKAJsNgJ4IAMgAykBsgE3AXwgAyADLwG+ATsBhgEgA0GEAWogA0G6AWovAQA7AQAgAyADKAJoIgIgAygCnAFBAWsiBCACIARJGzYCdAwhCyACQQRqIgIoAgQhBCACKAIAIQ0gAigCCCICBEAgAkEBdCEHIANB/ABqIQkgA0GyAWohCiAEIQIDQAJAAkACQAJAAkACQAJAAkACQAJAIAIvAQAiBUEBaw4HAgEBAQEDBAALIAVBlwhrDgMHBQYECwALIANBAToAwQEMBgsgA0EBOgC+ASADQQA2AmggAyADKAKoATYCbAwFCyADQQE6AL8BDAQLIANBAToAcAwDCyADIAMoAmw2AnggCSAKKQEANwEAIAMgAy8BvgE7AYYBIAlBCGogCkEIai8BADsBACADIAMoAmgiBSADKAKcAUEBayILIAUgC0kbNgJ0DAILIAMgAygCbDYCeCAJIAopAQA3AQAgAyADLwG+ATsBhgEgCUEIaiAKQQhqLwEAOwEAIAMgAygCaCIFIAMoApwBQQFrIgsgBSALSRs2AnQLQQAhBSMAQTBrIgskACADLQC8AUUEQCADQQE6ALwBA0AgAyAFaiIMQYgBaiIRKAIAIQ8gESAMQfQAaiIMKAIANgIAIAwgDzYCACAFQQRqIgVBFEcNAAtBACEFA0AgAyAFaiIMQSRqIhEoAgAhDyARIAwoAgA2AgAgDCAPNgIAIAVBBGoiBUEkRw0ACyALQQxqIAMoApwBIAMoAqABIgVBAUEAIANBsgFqEDEgA0EMahCMASADKAIMIgwEQCADKAIQIAxBBHRBBBDlAQsgAyALQQxqQSQQigJB3ABqQQAgBRB7CyALQTBqJAAgAxBRCyACQQJqIQIgB0ECayIHDQALCyANBEAgBCANQQF0QQIQ5QELDCALAkAgAi8BAiIEQQEgBEEBSxtBAWsiBCACLwEEIgIgAygCoAEiBSACG0EBayICSSACIAVJcUUEQCADKAKoASEEDAELIAMgAjYCrAEgAyAENgKoAQsgA0EANgJoIAMgBEEAIAMtAL4BGzYCbAwfCyADQQE6AHAgA0EAOwC9ASADQQA7AboBIANBAjoAtgEgA0ECOgCyASADQQA7AbABIANCADcCpAEgA0GAgIAINgKEASADQQI6AIABIANBAjoAfCADQgA3AnQgAyADKAKgAUEBazYCrAEMHgsgAygCoAEgAygCrAEiBEEBaiAEIAMoAmwiBEkbIQUgAyAEIAUgAi8BAiICQQEgAkEBSxsgA0GyAWoQIiADQdwAaiAEIAUQewwdCyADIAMoAmggAygCbCIEQQAgAi8BAiICQQEgAkEBSxsgA0GyAWoQLSAEIAMoAmQiAk8NHSADKAJgIARqQQE6AAAMHAsCQAJAAkACQCACLQABQQFrDgMBAgMACyADIAMoAmggAygCbEEBIAMgA0GyAWoQLSADQdwAaiADKAJsIAMoAqABEHsMAgsgAyADKAJoIAMoAmxBAiADIANBsgFqEC0gA0HcAGpBACADKAJsQQFqEHsMAQsgA0EAIAMoAhwgA0GyAWoQUiADQdwAakEAIAMoAqABEHsLDBsLIAMgAygCaCADKAJsIgQgAi0AAUEEaiADIANBsgFqEC0gBCADKAJkIgJPDRsgAygCYCAEakEBOgAADBoLIAMgAi0AAToAsQEMGQsgAyACLQABOgCwAQwYCyADKAJYQQJ0IQIgAygCVCEFIAMoAmghBwJAAkADQCACRQ0BIAJBBGshAiAFKAIAIQQgBUEEaiEFIAQgB00NAAsgAygCnAEiAkEBayEFDAELIAMoApwBIgJBAWsiBSEECyADIAQgBSACIARLGzYCaAwXCyADKAJoIgJFDRYgAiADKAKcAU8NFiADQdAAaiACEF4MFgsgAi8BAiEEIwBBEGsiBSQAIAMoAmgiAiADKAKcASIKRgRAIAMgAkEBayICNgJoCyADKAIYIAJrIQkgAyADKAJsIgdBtKXAABCKASACIARBASAEQQFLGyIEIAogAmsiCiAEIApJGyIEIAkgBCAJSRsgA0GyAWoiCRA2IAIgBGogAksEQANAIAVBCGogCUEIai8AADsBACAFIAkpAAA3AwAgAyAHQZSlwAAQigEgAkEgIAUQERogAkEBaiECIARBAWsiBA0ACwsCQCADKAJkIgIgB0sEQCADKAJgIAdqQQE6AAAgBUEQaiQADAELIAcgAkGIsMAAEGwACwwVCyADKAKgASADKAKsASIEQQFqIAQgAygCbCIESRshBSADIAQgBSACLwECIgJBASACQQFLGyADQbIBahBdIANB3ABqIAQgBRB7DBQLIAMQeCADLQDAAUUNEyADQQA2AmgMEwsgAxB4IANBADYCaAwSCyADIAIoAgQQHgwRCyADKAJoIgRFDRAgAi8BAiICQQEgAkEBSxshAiAEQQFrIQUgAygCbCEHIwBBEGsiBCQAIARBCGogAxCYAQJAAkAgBCgCDCIJIAdLBEAgBCgCCCAHQQR0aiIHKAIIIgkgBU0NASAHKAIEIARBEGokACAFQRRsaiEEDAILIAcgCUHwrcAAEGwACyAFIAlB8K3AABBsAAsgBCgCACEEA0AgAyAEEB4gAkEBayICDQALDBALIAMoAmwiAiADKAKoASIERg0OIAJFDQ8gAyADKAJoIgUgAygCnAFBAWsiByAFIAdJGzYCaCADIAIgBEEAIAMtAL4BIgQbIgJqQQFrIgUgAiACIAVJGyICIAMoAqwBIAMoAqABQQFrIAQbIgQgAiAESRs2AmwMDwsgCEEIaiADKAKcASICIAMoAqABIgQgAygCSCADKAJMQQAQMSAIQSxqIAIgBEEBQQBBABAxIANBDGoQjAEgAygCDCICBEAgAygCECACQQR0QQQQ5QELIAMgCEEIakEkEIoCIgJBMGoQjAEgAkEkaiACKAIwIgUEQCACKAI0IAVBBHRBBBDlAQsgCEEsakEkEIoCGiACQQA6ALwBIAhB0ABqIAIoApwBEEggAkHQAGohBCACKAJQIgUEQCACKAJUIAVBAnRBBBDlAQsgBCAIKQJQNwIAIARBCGogCEHQAGoiBEEIaiIFKAIANgIAIAJBADsBugEgAkECOgC2ASACQQI6ALIBIAJBAToAcCACQgA3AmggAkEAOwGwASACQYCABDYAvQEgAkIANwKkASACQYCAgAg2ApgBIAJBAjoAlAEgAkECOgCQASACQQA2AowBIAJCgICACDcChAEgAkECOgCAASACQQI6AHwgAkIANwJ0IAIgAigCoAEiB0EBazYCrAEgBCAHEDwgAkHcAGohBCACKAJcIgcEQCACKAJgIAdBARDlAQsgBCAIKQNQNwIAIARBCGogBSgCADYCAAwOCyACKAIIIQQgAigCBCEHIAIoAgwiAgRAIAJBAXQhBSAEIQIDQAJAIAIvAQBBFEcEQCADQQA6AL0BDAELIANBADoAwAELIAJBAmohAiAFQQJrIgUNAAsLIAdFDQ0gBCAHQQF0QQIQ5QEMDQsgAyADKQJ0NwJoIAMgAykBfDcBsgEgAyADLwGGATsBvgEgA0G6AWogA0GEAWovAQA7AQAMDAsgAyADKAJsNgJ4IAMgAykBsgE3AXwgAyADLwG+ATsBhgEgA0GEAWogA0G6AWovAQA7AQAgAyADKAJoIgIgAygCnAFBAWsiBCACIARJGzYCdAwLCyADIAIvAQIiAkEBIAJBAUsbELEBDAoLIAJBBGoiAigCBCEEIAIoAgAhBwJAIAIoAggiAkUNACAEIAJBBWxqIQogAy0AuwEhBSAEIQIDQCACKAABIQkCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACLQAAQQFrDhIAAQIDBAUGBwgJCgsMDQ8QERQOCyADQQE6ALoBDBELIANBAjoAugEMEAsgAyAFQQFyIgU6ALsBDA8LIAMgBUECciIFOgC7AQwOCyADIAVBCHIiBToAuwEMDQsgAyAFQRByIgU6ALsBDAwLIAMgBUEEciIFOgC7AQwLCyADQQA6ALoBDAoLIAMgBUH+AXEiBToAuwEMCQsgAyAFQf0BcSIFOgC7AQwICyADIAVB9wFxIgU6ALsBDAcLIAMgBUHvAXEiBToAuwEMBgsgAyAFQfsBcSIFOgC7AQwFCyADIAk2AbIBDAQLQQAhBSADQQA7AboBIANBAjoAtgELIANBAjoAsgEMAgsgAyAJNgG2AQwBCyADQQI6ALYBCyAKIAJBBWoiAkcNAAsLIAcEQCAEIAdBBWxBARDlAQsMCQsgA0EANgKkAQwICyACKAIIIQQgAigCBCEHIAIoAgwiAgRAIAJBAXQhBSAEIQIDQAJAIAIvAQBBFEcEQCADQQE6AL0BDAELIANBAToAwAELIAJBAmohAiAFQQJrIgUNAAsLIAdFDQcgBCAHQQF0QQIQ5QEMBwsgA0EBNgKkAQwGCyADIAIvAQIiAkEBIAJBAUsbELIBDAULIAItAAFFBEAgA0HQAGogAygCaBBfDAULIANBADYCWAwECyADIAMoAmgiBCADKAKcAUEBayIFIAQgBUkbNgJoIAMgAi8BAiICQQEgAkEBSxsgAygCqAFBACADLQC+ASIEGyICakEBayIFIAIgAiAFSRsiAiADKAKsASADKAKgAUEBayAEGyIEIAIgBEkbNgJsDAMLIAMgAygCaCIEIAMoApwBQQFrIgUgBCAFSRs2AmggAyADKAKgAUEBayADKAKsASIEIAQgAygCbCIESRsiBSAEIAIvAQIiAkEBIAJBAUsbaiICIAIgBUsbNgJsDAILIAMtAMIBRQ0BIAMgAi8BAiIEIAMoApwBIAQbIAIvAQQiAiADKAKgASACGxA9DAELIANBARCxAQsgCEHgAGokAAwBCyAEIAJBiLDAABBsAAsLIAEgGkcNAAsLIBBBFGoiASADEHYgEEEIaiADEE0gECkDCCEdIBVBCGogAUEIaigCADYCACAVIBApAhQ3AgAgFSAdNwIMIBBBMGokACAOQQA2AhwgDiAOQRxqIBUQNCAOKAIEIQEgDigCAARAIA4gATYCHEGUg8AAQSsgDkEcakHAg8AAQcSGwAAQYwALIA5BCGoQpgEgDkEgaiQAIBQEQCAXIBRBARDlAQsgAEEANgIAIBNBEGokACABDwsQ/gEACxD/AQALjQEBA38gASgCBCEEAkACQAJAIAEoAggiAUUEQEEEIQMMAQsgAUHmzJkzSw0BIAFBFGwiAkEASA0BQYmTwQAtAAAaIAJBBBDXASIDRQ0CCyADIAQgAhCKAiECIAAgATYCCCAAIAI2AgQgACABNgIADwsQqAEAC0EEIAJBxJPBACgCACIAQd4AIAAbEQIAAAtrAQV/AkAgACgCCCICRQ0AIAAoAgRBFGshBCACQRRsIQMgAkEBa0H/////A3FBAWohBQJAA0AgAyAEahB0RQ0BIAFBAWohASADQRRrIgMNAAsgBSEBCyABQQFrIAJPDQAgACACIAFrNgIICwt9AQF/IwBBQGoiBSQAIAUgATYCDCAFIAA2AgggBSADNgIUIAUgAjYCECAFQTxqQfUANgIAIAVBAjYCHCAFQYT5wAA2AhggBUICNwIkIAVB9gA2AjQgBSAFQTBqNgIgIAUgBUEQajYCOCAFIAVBCGo2AjAgBUEYaiAEEKMBAAtwAQV/AkAgAUUNACAAKAIEIQUgACgCACECA0ACQAJAIAIgBUcEQCAAIAJBEGoiBjYCACACKAIAIgRFDQIgBEGAgICAeEcNAQsgASEDDAMLIAIoAgQgBEEUbEEEEOUBCyAGIQIgAUEBayIBDQALCyADC2gBAX8jAEEQayIFJAAgBUEIaiABEJkBAkAgAiADTQRAIAUoAgwiASADSQ0BIAUoAgghASAAIAMgAms2AgQgACABIAJBBHRqNgIAIAVBEGokAA8LIAIgAyAEEO0BAAsgAyABIAQQ6wEAC28BAn8jAEEQayIEJAAgBEEIaiABKAIQIAIgAxDOASAEKAIMIQIgBCgCCCIDRQRAAkAgASgCCEUNACABKAIMIgVBhAFJDQAgBRABCyABIAI2AgwgAUEBNgIICyAAIAM2AgAgACACNgIEIARBEGokAAuDAQEBfwJAAkACQAJAAkACQAJAAkACQAJAAkAgAUEIaw4IAQIGBgYDBAUAC0EyIQIgAUGEAWsOCgUGCQkHCQkJCQgJCwwIC0EbIQIMBwtBBiECDAYLQSwhAgwFC0EqIQIMBAtBHyECDAMLQSAhAgwCC0EcIQIMAQtBIyECCyAAIAI6AAALoQMBBX8jAEEgayIGJAAgAUUEQEHQlcAAQTIQ/QEACyAGQRRqIgcgASADIAQgBSACKAIQEQcAIwBBEGsiAyQAAkACQAJAIAcoAggiBCAHKAIATw0AIANBCGohCCMAQSBrIgIkAAJAIAQgBygCACIFTQRAAn9BgYCAgHggBUUNABogBUECdCEJIAcoAgQhCgJAIARFBEBBBCEBIAogCUEEEOUBDAELQQQgCiAJQQQgBEECdCIFEM0BIgFFDQEaCyAHIAQ2AgAgByABNgIEQYGAgIB4CyEBIAggBTYCBCAIIAE2AgAgAkEgaiQADAELIAJBATYCDCACQYDswAA2AgggAkIANwIUIAJB3OvAADYCECACQQhqQdTswAAQowEACyADKAIIIgFBgYCAgHhGDQAgAUUNASABIAMoAgxBxJPBACgCACIAQd4AIAAbEQIAAAsgA0EQaiQADAELEKgBAAsgBkEIaiAHKQIENwMAIAYoAgghASAGIAYoAgw2AgQgBiABNgIAIAYoAgQhASAAIAYoAgA2AgAgACABNgIEIAZBIGokAAtxAQF/IwBBEGsiAiQAIAIgAEEgajYCDCABQayLwABBBkGyi8AAQQUgAEEMakG4i8AAQciLwABBBCAAQRhqQcyLwABBBCAAQRxqQYSLwABB0IvAAEEQIABB4IvAAEHwi8AAQQsgAkEMahA6IAJBEGokAAtxAQF/IwBBEGsiAiQAIAIgAEETajYCDCABQaeMwABBCEGvjMAAQQogAEGEi8AAQbmMwABBCiAAQQRqQcOMwABBAyAAQQhqQciMwABB2IzAAEELIABBEmpB5IzAAEH0jMAAQQ4gAkEMahA6IAJBEGokAAtvAQF/IwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkEsakHdADYCACACQQM2AgwgAkGU9cAANgIIIAJCAjcCFCACQd0ANgIkIAIgAkEgajYCECACIAJBBGo2AiggAiACNgIgIAJBCGpB4JbAABCjAQALbAEBfyMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBLGpB3QA2AgAgA0ECNgIMIANB0PfAADYCCCADQgI3AhQgA0HdADYCJCADIANBIGo2AhAgAyADNgIoIAMgA0EEajYCICADQQhqIAIQowEAC2YBAn8jAEEQayICJAAgACgCACIDQQFqIQACfyADLQAARQRAIAIgADYCCCABQaGCwABBByACQQhqQaiCwAAQQwwBCyACIAA2AgwgAUG4gsAAQQMgAkEMakG8gsAAEEMLIAJBEGokAAtiAQN/IwBBEGsiAyQAIAEoAgghBCADQQhqIAEoAgAgAjUCABBYIAMoAgwhAiAD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QSBrIgMkACMAQSBrIgQkACAAQQRqIgUgASACED0gBEEUaiICIAUQdiAEQQhqIAUQTSAEKQMIIQYgA0EIaiIBQQhqIAJBCGooAgA2AgAgASAEKQIUNwIAIAEgBjcCDCAEQSBqJAAgA0EANgIcIAMgA0EcaiABEDQgAygCBCEBIAMoAgAEQCADIAE2AhxBlIPAAEErIANBHGpBwIPAAEHUhsAAEGMACyADQQhqEKYBIANBIGokACAAQQA2AgAgAQ8LEP4BAAsQ/wEACzsBAX8CQCACQX9HBEAgAkEBaiEEIAJBIEkNASAEQSAgAxDrAQALIAMQqgEACyAAIAQ2AgQgACABNgIACzkAAkACfyACQYCAxABHBEBBASAAIAIgASgCEBEAAA0BGgsgAw0BQQALDwsgACADIAQgASgCDBEBAAvUAgEDfyAAKAIAIQAgASgCHCIDQRBxRQRAIANBIHFFBEAgADMBACABECoPCyMAQYABayIDJAAgAC8BACECQQAhAANAIAAgA2pB/wBqIAJBD3EiBEEwciAEQTdqIARBCkkbOgAAIABBAWshACACQf//A3EiBEEEdiECIARBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIANqQYABakEAIABrEBggA0GAAWokAA8LIwBBgAFrIgMkACAALwEAIQJBACEAA0AgACADakH/AGogAkEPcSIEQTByIARB1wBqIARBCkkbOgAAIABBAWshACACQf//A3EiBEEEdiECIARBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIANqQYABakEAIABrEBggA0GAAWokAAs3AQF/IAAoAgAhACABKAIcIgJBEHFFBEAgAkEgcUUEQCAAIAEQ7gEPCyAAIAEQVA8LIAAgARBVCzcBAX8gACgCACEAIAEoAhwiAkEQcUUEQCACQSBxRQRAIAAgARDsAQ8LIAAgARBWDwsgACABEFMLsAIBAn8jAEEgayICJAAgAkEBOwEcIAIgATYCGCACIAA2AhQgAkGM98AANgIQIAJBiPbAADYCDCMAQRBrIgEkACACQQxqIgAoAggiAkUEQEG08cAAEO8BAAsgASAAKAIMNgIMIAEgADYCCCABIAI2AgQjAEEQayIAJAAgAUEE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QZixwAAQnAEACyACIAAgAkEUbGogASACaxAcCyUAIABBATYCBCAAIAEoAgQgASgCAGtBBHYiATYCCCAAIAE2AgALJQAgAEUEQEHQlcAAQTIQ/QEACyAAIAIgAyAEIAUgASgCEBEIAAswACABKAIUIAAtAABBAnQiAEH8h8AAaigCACAAQcSHwABqKAIAIAEoAhgoAgwRAQALMAAgASgCFCAALQAAQQJ0IgBBuJLAAGooAgAgAEGsksAAaigCACABKAIYKAIMEQEACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQEQUACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERgACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERoACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERwACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQEQoACygBAX8gACgCACIBQYCAgIB4ckGAgICAeEcEQCAAKAIEIAFBARDlAQsLLgAgASgCFEGgjMAAQZuMwAAgACgCAC0AACIAG0EHQQUgABsgASgCGCgCDBEBAAshACAARQRAQdCVwABBMhD9AQALIAAgAiADIAEoAhARAwALHQEBfyAAKAIAIgEEQCAAKAIEIAFBAnRBBBDlAQsLHQEBfyAAKAIAIgEEQCAAKAIEIAFBFGxBBBDlAQsLHQEBfyAAKAIAIgEEQCAAKAIEIAFBBHRBBBDlAQsLIgAgAC0AAEUEQCABQdz7wABBBRAWDwsgAUHh+8AAQQQQFgsrACABKAIUQYeRwABBgJHAACAALQAAIgAbQQlBByAAGyABKAIYKAIMEQEACysAIAEoAhRBuJHAAEGMjMAAIAAtAAAiABtBC0EGIAAbIAEoAhgoAgwRAQALHwAgAEUEQEHQlcAAQTIQ/QEACyAAIAIgASgCEBEAAAsbABAHIQIgAEEANgIIIAAgAjYCBCAAIAE2AgALwQMCAn4Gf0GMk8EAKAIARQRAIwBBMGsiAyQAAn8CQCAABEAgACgCACAAQQA2AgANAQsgA0EQakGQlMAAKQMANwMAIANBiJTAACkDADcDCEEADAELIANBEGogAEEQaikCADcDACADIAApAgg3AwggACgCBAshAEGMk8EA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IgIgAy0AG08NBCADIAJBAWo6ABogAkEKTw0GIANBEGogAmotAAAhAQwBC0EAIQcgDEEANgIAIAMoAhQhASADQgA3AxALIAogASALEQAARQ0ACwwHCyADLQAaIgFBCiABQQpLGyECIAEgAy0AGyIHIAEgB0sbIQwDQCABIAxGDQEgAyABQQFqIgc6ABogASACRg0DIANBEGogAWohECAHIQEgCiAQLQAAIAsRAABFDQALDAYLAn9BASAGQYABSQ0AGkECIAZBgBBJDQAaQQNBBCAGQYCABEkbCyAFaiECCyAFIAlrIABqIQUgACAPRw0BDAILCyACQQpBnIzBABBsAAsgAkUEQEEAIQIMAQsgAiAETwRAIAIgBEYNAQwDCyACIAhqLAAAQb9/TA0CCyAKIAIgCGogBCACayAOKAIMEQEADQAgCkEiIAsRAAAhDQsgA0EgaiQADAILIAggBCACIARB6PvAABDVAQALIAggBCACIAVB+PvAABDVAQALIA0LFAAgAEEANgIIIABCgICAgBA3AgALEQAgACgCBCAAKAIIIAEQhgILqgIBB38jAEEQayIFJAACQAJAAkAgASgCCCIDIAEoAgBPDQAgBUEIaiEGIwBBIGsiAiQAAkAgASgCACIEIANPBEACf0GBgICAeCAERQ0AGiABKAIEIQcCQCADRQRAQQEhCCAHIARBARDlAQwBC0EBIAcgBEEBIAMQzQEiCEUNARoLIAEgAzYCACABIAg2AgRBgYCAgHgLIQQgBiADNgIEIAYgBDYCACACQSBqJAAMAQsgAkEBNgIMIAJB9O3AADYCCCACQgA3AhQgAkHQ7cAANgIQIAJBCGpByO7AABCjAQALIAUoAggiAkGBgICAeEYNACACRQ0BIAIgBSgCDEHEk8EAKAIAIgBB3gAgABsRAgAACyAFQRBqJAAMAQsQqAEACyAAIAEpAgQ3AwALDgAgACABIAEgAmoQjwELIAAgAEKN04Cn1Nuixjw3AwggAELVnsTj3IPBiXs3AwALIgAgAELiq87AwdHBlKl/NwMIIABCivSnla2v+57uADcDAAsgACAAQsH3+ejMk7LRQTcDCCAAQuTex4WQ0IXefTcDAAsTACAAQdTxwAA2AgQgACABNgIACxAAIAEgACgCACAAKAIEEBYLEAAgASgCFCABKAIYIAAQHQupAQEDfyAAKAIAIQIjAEEQayIAJAAgASgCFEHg9sAAQQEgASgCGCgCDBEBACEEIABBBGoiA0EAOgAFIAMgBDoABCADIAE2AgBBDCEBA0AgACACNgIMIABBBGogAEEMakGMgsAAEDIgAkECaiECIAFBAmsiAQ0ACyAAQQRqIgEtAAQEf0EBBSABKAIAIgEoAhRBwvnAAEEBIAEoAhgoAgwRAQALIABBEGokAAsNACAAIAEgAhDcAUEAC2QBAX8CQCAAQQRrKAIAIgNBeHEhAgJAIAJBBEEIIANBA3EiAxsgAWpPBEAgA0EARyACIAFBJ2pLcQ0BIAAQGgwCC0Gx78AAQS5B4O/AABCcAQALQfDvwABBLkGg8MAAEJwBAAsLDQAgACgCACABIAIQBgsNACAAKAIAIAEgAhALCwwAIAAoAgAQCkEBRgsOACAAKAIAGgNADAALAAtsAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0EsakHdADYCACADQQI2AgwgA0G8/MAANgIIIANCAjcCFCADQd0ANgIkIAMgA0EgajYCECADIANBBGo2AiggAyADNgIgIANBCGogAhCjAQALbAEBfyMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBLGpB3QA2AgAgA0ECNgIMIANB3PzAADYCCCADQgI3AhQgA0HdADYCJCADIANBIGo2AhAgAyADQQRqNgIoIAMgAzYCICADQQhqIAIQowEACwsAIAA1AgAgARAqC2wBAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQSxqQd0ANgIAIANBAjYCDCADQZD9wAA2AgggA0ICNwIUIANB3QA2AiQgAyADQSBqNgIQIAMgA0EEajYCKCADIAM2AiAgA0EIaiACEKMBAAsLACAAMQAAIAEQKgsPAEHh9sAAQSsgABCcAQALCwAgACkDACABECoLCwAgACMAaiQAIwALCwAgACgCACABECwLpAsBCX8gACgCACEIIwBBQGoiAyQAIANBADYCDCADQoCAgIAQNwIEIAgoAgghACADIAgoAgQiBzYCNCADQQA2AjAgA0KAgICAwAA3AiggAyAHIABBFGxqNgI4IANBEGogA0EoahATIAMoAhAiCUGAgICAeEcEQANAAkAgAygCGCIKBEAgA0EcaiEGIAMoAhQiB0EIaiEEIwBB0ABrIgIkAEGJk8EALQAAGgJAAkBBA0EBENcBIgAEQCAAQQJqQd6xwAAtAAA6AAAgAEHcscAALwAAOwAAIAJBAzYCECACIAA2AgwgAkEDNgIIAkAgBC0AAEECRg0AIAIgBCgAADYCFCACQcQAaiIAIAJBFGpBHhAZIAJB2AA2AkAgAkEBNgIoIAJB4LHAADYCJCACQgE3AjAgAiAANgI8IAIgAkE8ajYCLCACQRhqIAJBJGoQJCACKAJEIgAEQCACKAJIIABBARDlAQsgAigCGCEAIAJBCGogAigCHCIFIAUgAigCIGoQjwEgAEUNACAFIABBARDlAQsCQCAELQAEQQJGDQAgAiAEKAAENgIUIAJBxABqIgAgAkEUakEoEBkgAkHYADYCQCACQQE2AiggAkHgscAANgIkIAJCATcCMCACIAA2AjwgAiACQTxqNgIsIAJBGGogAkEkahAkIAIoAkQiAARAIAIoAkggAEEBEOUBCyACKAIYIQAgAkEIaiACKAIcIgUgBSACKAIgahCPASAARQ0AIAUgAEEBEOUBC0HoscAAIQACQAJAAkAgBC0ACEEBaw4CAQACC0HqscAAIQALIAJBCGogACAAQQJqEI8BCyAELQAJIgBBAXENAQwCC0EBQQNBxJPBACgCACIAQd4AIAAbEQIAAAsgAkEIakHsscAAQe6xwAAQjwELIABBAnEEQCACQQhqQe6xwABB8LHAABCPAQsgAEEIcQRAIAJBCGpB8LHAAEHyscAAEI8BCyAAQRBxBEAgAkEIakHyscAAQfSxwAAQjwELIABBBHEEQCACQQhqQfSxwABB9rHAABCPAQsgAigCECIAIAIoAghGBEAgAkEIaiAAEIMBIAIoAhAhAAsgACACKAIMakHtADoAACAGIAIpAgg3AgAgBkEIaiACQRBqKAIAQQFqNgIAIAJB0ABqJAAgA0EEaiADKAIgIgAgACADKAIkahCPASADKAIcIgIEQCAAIAJBARDlAQsgByAKQRRsaiEKIAchAANAIAAoAgAiAkGAgMQARg0CAkAgACgCBEUNAAJ/AkAgAkGAAU8EQCADQQA2AhwgAkGAEEkNASACQYCABEkEQCADIAJBDHZB4AFyOgAcIAMgAkEGdkE/cUGAAXI6AB1BAiEGQQMMAwsgAyACQQZ2QT9xQYABcjoAHiADIAJBDHZBP3FBgAFyOgAdIAMgAkESdkEHcUHwAXI6ABxBAyEGQQQMAgsgAygCDCIEIAMoAgRGBEAgA0EEaiAEEIMBIAMoAgwhBAsgBCADKAIIaiACOgAAIAMgAygCDEEBajYCDAwCCyADIAJBBnZBwAFyOgAcQQEhBkECCyEEIAYgA0EcaiIFciACQT9xQYABcjoAACADQQRqIAUgBCAFahCPAQsgCiAAQRRqIgBHDQALDAELQQBBAEGopMAAEGwACyAJBEAgByAJQRRsQQQQ5QELIANBEGogA0EoahATIAMoAhAiCUGAgICAeEcNAAsLIAMoAigiAARAIAMoAiwgAEEUbEEEEOUBCyAILQAMBEAgA0Hin7oENgIoIANBBGogA0EoaiIAIABBA3IQjwELIANBATYCLCADQaCkwAA2AiggA0IBNwI0IANBywA2AiAgAyADQRxqNgIwIAMgA0EEajYCHCABKAIUIAEoAhggA0EoahAdIAMoAgQiAQRAIAMoAgggAUEBEOUBCyADQUBrJAALDAAgACgCACABEMMBCwcAIAAQyQELGQAgASgCFEGcgsAAQQUgASgCGCgCDBEBAAuXAQEBfyAAKAIAIQIjAEFAaiIAJAAgAEIANwM4IABBOGogAigCABANIAAgACgCPCICNgI0IAAgACgCODYCMCAAIAI2AiwgAEHZADYCKCAAQQI2AhAgAEHM68AANgIMIABCATcCGCAAIABBLGoiAjYCJCAAIABBJGo2AhQgASgCFCABKAIYIABBDGoQHSACEMkBIABBQGskAAsHACAAEMABCwwAIAAQjAEgABDCAQuiAQEEf0ECIQMjAEEQayICJAAgASgCFEHg9sAAQQEgASgCGCgCDBEBACEFIAJBBGoiBEEAOgAFIAQgBToABCAEIAE2AgADQCACIAA2AgwgAkEEaiACQQxqQeyBwAAQMiAAQQFqIQAgA0EBayIDDQALIAJBBGoiAC0ABAR/QQEFIAAoAgAiACgCFEHC+cAAQQEgACgCGCgCDBEBAAsgAkEQaiQAC6MBAQN/IwBBEGsiAiQAIAEoAhRB4PbAAEEBIAEoAhgoAgwRAQAhBCACQQRqIgNBADoABSADIAQ6AAQgAyABNgIAQYAEIQEDQCACIAA2AgwgAkEEaiACQQxqQbyBwAAQMiAAQRBqIQAgAUEQayIBDQALIAJBBGoiAC0ABAR/QQEFIAAoAgAiACgCFEHC+cAAQQEgACgCGCgCDBEBAAsgAkEQaiQACwwAIAAoAgAgARDuAQsJACAAIAEQDgALDQBB5OzAAEEbEP0BAAsOAEH/7MAAQc8AEP0BAAsNACAAQdjuwAAgARAdCw0AIABB8O7AACABEB0LDQAgAEGE88AAIAEQHQsZACABKAIUQfzywABBBSABKAIYKAIMEQEAC4YEAQV/IwBBEGsiAyQAAkACfwJAIAFBgAFPBEAgA0EANgIMIAFBgBBJDQEgAUGAgARJBEAgAyABQT9xQYABcjoADiADIAFBDHZB4AFyOgAMIAMgAUEGdkE/cUGAAXI6AA1BAwwDCyADIAFBP3FBgAFyOgAPIAMgAUEGdkE/cUGAAXI6AA4gAyABQQx2QT9xQYABcjoADSADIAFBEnZBB3FB8AFyOgAMQQQMAgsgACgCCCICIAAoAgBGBEAjAEEgayIEJAACQAJAIAJBAWoiAkUNACAAKAIAIgVBAXQiBiACIAIgBkkbIgJBCCACQQhLGyICQX9zQR92IQYgBCAFBH8gBCAFNgIcIAQgACgCBDYCFEEBBUEACzYCGCAEQQhqIAYgAiAEQRRqEEogBCgCCARAIAQoAgwiAEUNASAAIAQoAhBBxJPBACgCACIAQd4AIAAbEQIAAAsgBCgCDCEFIAAgAjYCACAAIAU2AgQgBEEgaiQADAELEKgBAAsgACgCCCECCyAAIAJBAWo2AgggACgCBCACaiABOgAADAILIAMgAUE/cUGAAXI6AA0gAyABQQZ2QcABcjoADEECCyEBIAEgACgCACAAKAIIIgJrSwRAIAAgAiABEEUgACgCCCECCyAAKAIEIAJqIANBDGogARCKAhogACABIAJqNgIICyADQRBqJABBAAsNACAAQZT5wAAgARAdCwoAIAIgACABEBYLCwAgACgCACABECkLkQUBB38CQAJ/AkAgAiIEIAAgAWtLBEAgACAEaiECIAEgBGoiCCAEQRBJDQIaIAJBfHEhA0EAIAJBA3EiBmsgBgRAIAEgBGpBAWshAANAIAJBAWsiAiAALQAAOgAAIABBAWshACACIANLDQALCyADIAQgBmsiBkF8cSIHayECIAhqIglBA3EEQCAHQQBMDQIgCUEDdCIFQRhxIQggCUF8cSIAQQRrIQFBACAFa0EYcSEEIAAoAgAhAANAIAAgBHQhBSADQQRrIgMgBSABKAIAIgAgCHZyNgIAIAFBBGshASACIANJDQALDAILIAdBAEwNASABIAZqQQRrIQEDQCADQQRrIgMgASgCADYCACABQQRrIQEgAiADSQ0ACwwBCwJAIARBEEkEQCAAIQIMAQtBACAAa0EDcSIFIABqIQMgBQRAIAAhAiABIQADQCACIAAtAAA6AAAgAEEBaiEAIAMgAkEBaiICSw0ACwsgBCAFayIJQXxxIgcgA2ohAgJAIAEgBWoiBUEDcQRAIAdBAEwNASAFQQN0IgRBGHEhBiAFQXxxIgBBBGohAUEAIARrQRhxIQggACgCACEAA0AgACAGdiEEIAMgBCABKAIAIgAgCHRyNgIAIAFBBGohASADQQRqIgMgAkkNAAsMAQsgB0EATA0AIAUhAQNAIAMgASgCADYCACABQQRqIQEgA0EEaiIDIAJJDQALCyAJQQNxIQQgBSAHaiEBCyAERQ0CIAIgBGohAANAIAIgAS0AADoAACABQQFqIQEgACACQQFqIgJLDQALDAILIAZBA3EiAEUNASACIABrIQAgCSAHawtBAWshAQNAIAJBAWsiAiABLQAAOgAAIAFBAWshASAAIAJJDQALCwuvAQEDfyABIQUCQCACQRBJBEAgACEBDAELQQAgAGtBA3EiAyAAaiEEIAMEQCAAIQEDQCABIAU6AAAgBCABQQFqIgFLDQALCyACIANrIgJBfHEiAyAEaiEBIANBAEoEQCAFQf8BcUGBgoQIbCEDA0AgBCADNgIAIARBBGoiBCABSQ0ACwsgAkEDcSECCyACBEAgASACaiECA0AgASAFOgAAIAIgAUEBaiIBSw0ACwsgAAu8AgEIfwJAIAIiBkEQSQRAIAAhAgwBC0EAIABrQQNxIgQgAGohBSAEBEAgACECIAEhAwNAIAIgAy0AADoAACADQQFqIQMgBSACQQFqIgJLDQALCyAGIARrIgZBfHEiByAFaiECAkAgASAEaiIEQQNxBEAgB0EATA0BIARBA3QiA0EYcSEJIARBfHEiCEEEaiEBQQAgA2tBGHEhCiAIKAIAIQMDQCADIAl2IQggBSAIIAEoAgAiAyAKdHI2AgAgAUEEaiEBIAVBBGoiBSACSQ0ACwwBCyAHQQBMDQAgBCEBA0AgBSABKAIANgIAIAFBBGohASAFQQRqIgUgAkkNAAsLIAZBA3EhBiAEIAdqIQELIAYEQCACIAZqIQMDQCACIAEtAAA6AAAgAUEBaiEBIAMgAkEBaiICSw0ACwsgAAsJACAAIAEQwwELDQAgAEGAgICAeDYCAAsNACAAQYCAgIB4NgIACwYAIAAQNQsEACABCwMAAQsLw5EBDwBBgIDAAAuLFAEAAAAMAAAABAAAAAIAAAADAAAABAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkABQAAAAAAAAABAAAABgAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3N0cmluZy5ycwBgABAASwAAAPoJAAAOAAAABwAAAAQAAAAEAAAACAAAAAcAAAAEAAAABAAAAAkAAAAHAAAABAAAAAQAAAAKAAAABwAAAAQAAAAEAAAACwAAAAcAAAAEAAAABAAAAAwAAAAHAAAABAAAAAQAAAANAAAARXJyb3JJbmRleGVkBwAAAAQAAAAEAAAADgAAAFJHQgAHAAAABAAAAAQAAAAPAAAAUmdichAAAAABAAAAAQAAABEAAABnYlZ0cGFyc2VyAAAUAAAADAIAAAQAAAAVAAAAdGVybWluYWwUAAAABAAAAAQAAAAWAAAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQAXAAAABAAAAAQAAAAYAAAAR3JvdW5kRXNjYXBlRXNjYXBlSW50ZXJtZWRpYXRlQ3NpRW50cnlDc2lQYXJhbUNzaUludGVybWVkaWF0ZUNzaUlnbm9yZURjc0VudHJ5RGNzUGFyYW1EY3NJbnRlcm1lZGlhdGVEY3NQYXNzdGhyb3VnaERjc0lnbm9yZU9zY1N0cmluZ1Nvc1BtQXBjU3RyaW5nUGFyc2Vyc3RhdGUAABkAAAABAAAAAQAAABoAAABwYXJhbXMAABQAAAAAAgAABAAAABsAAABjdXJfcGFyYW0AAAAUAAAABAAAAAQAAAAcAAAAaW50ZXJtZWRpYXRlFAAAAAQAAAAEAAAAHQAAAEVycm9yAAAAFAAAAAQAAAAEAAAAHgAAAGZnc3JjL2xpYi5yc2JnZmFpbnQBYm9sZGl0YWxpY3VuZGVybGluZXN0cmlrZXRocm91Z2hibGlua2ludmVyc2UjAAAAKAMQAAEAAACUARAAAAAAAJQBEAAAAAAA6gIQAAoAAAAjAAAANgAAAOoCEAAKAAAAKAAAADYAAACUARAAAAAAAOoCEAAKAAAATgAAADEAAADqAhAACgAAAEUAAAAgAAAA6gIQAAoAAABVAAAALwAAAFNlZ21lbnR0ZXh0cGVub2Zmc2V0Y2VsbENvdW50Y2hhcldpZHRoAAAGAAAABgAAABIAAAAIAAAACAAAAA8AAAAJAAAACAAAAAgAAAAPAAAADgAAAAkAAAAJAAAADgAAANABEADWARAA3AEQAO4BEAD2ARAA/gEQAA0CEAAWAhAAHgIQACYCEAA1AhAAQwIQAEwCEABVAhAATWFwIGtleSBpcyBub3QgYSBzdHJpbmcgYW5kIGNhbm5vdCBiZSBhbiBvYmplY3Qga2V5AFRyaWVkIHRvIHNocmluayB0byBhIGxhcmdlciBjYXBhY2l0eWgEEAAkAAAAL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc5QEEABMAAAA5wEAAAkAAABgdW53cmFwX3Rocm93YCBmYWlsZWRQZW5mb3JlZ3JvdW5kAAAfAAAABAAAAAEAAAAgAAAAYmFja2dyb3VuZGludGVuc2l0eQAfAAAAAQAAAAEAAAAhAAAAYXR0cnMAAAAiAAAABAAAAAQAAAAOAAAAVGFicyIAAAAEAAAABAAAACMAAABQYXJhbWN1cl9wYXJ0AAAAIgAAAAQAAAAEAAAAJAAAAHBhcnRzAAAAIgAAAAQAAAAEAAAAJQAAAEJ1ZmZlcmxpbmVzACYAAAAMAAAABAAAACcAAABjb2xzcm93c3Njcm9sbGJhY2tfbGltaXQiAAAADAAAAAQAAAAoAAAAdHJpbV9uZWVkZWQAIgAAAAQAAAAEAAAACQAAAE5vcm1hbEJvbGRGYWludEFzY2lpRHJhd2luZ1NhdmVkQ3R4Y3Vyc29yX2NvbGN1cnNvcl9yb3dwZW4AAB8AAAAKAAAAAQAAACkAAABvcmlnaW5fbW9kZQAfAAAAAQAAAAEAAAAqAAAAYXV0b193cmFwX21vZGUAACsAAAAkAAAABAAAACwAAAAfAAAAAQAAAAEAAAAtAAAAIgAAAAgAAAAEAAAALgAAACIAAAAMAAAABAAAAC8AAAAfAAAAAgAAAAEAAAAwAAAAMQAAAAwAAAAEAAAAMgAAAB8AAAABAAAAAQAAADMAAAAiAAAAFAAAAAQAAAA0AAAANQAAAAwAAAAEAAAANgAAAFRlcm1pbmFsYnVmZmVyb3RoZXJfYnVmZmVyYWN0aXZlX2J1ZmZlcl90eXBlY3Vyc29yY2hhcnNldHNhY3RpdmVfY2hhcnNldHRhYnNpbnNlcnRfbW9kZW5ld19saW5lX21vZGVjdXJzb3Jfa2V5c19tb2RldG9wX21hcmdpbmJvdHRvbV9tYXJnaW5zYXZlZF9jdHhhbHRlcm5hdGVfc2F2ZWRfY3R4ZGlydHlfbGluZXN4dHdpbm9wcwAAyAUQAAQAAADMBRAABAAAABwHEAAGAAAAIgcQAAwAAAAuBxAAEgAAANAFEAAQAAAAQAcQAAYAAABDBhAAAwAAAEYHEAAIAAAATgcQAA4AAABcBxAABAAAAGAHEAALAAAAWAYQAAsAAAB0BhAADgAAAGsHEAANAAAAeAcQABAAAACIBxAACgAAAJIHEAANAAAAnwcQAAkAAACoBxAAEwAAALsHEAALAAAAxgcQAAgAAABQcmltYXJ5QWx0ZXJuYXRlU2Nyb2xsYmFja0xpbWl0c29mdGhhcmQAIgAAAAQAAAAEAAAADAAAAEFwcGxpY2F0aW9uQ3Vyc29yY29scm93dmlzaWJsZU5vbmVTb21lAAAiAAAABAAAAAQAAAA3AAAAIgAAAAQAAAAEAAAAOAAAACIAAAAEAAAABAAAADkAAABEaXJ0eUxpbmVzAAAiAAAABAAAAAQAAAA6AAAABgAAAAQAAAAFAAAADAYQABIGEAAWBhAAY2Fubm90IGFjY2VzcyBhIFRocmVhZCBMb2NhbCBTdG9yYWdlIHZhbHVlIGR1cmluZyBvciBhZnRlciBkZXN0cnVjdGlvbgAAPAAAAAAAAAABAAAAPQAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvc3RkL3NyYy90aHJlYWQvbG9jYWwucnMAnAkQAE8AAAAEAQAAGgAAAAAAAAD//////////wAKEABBmJTAAAveHSBjYW4ndCBiZSByZXByZXNlbnRlZCBhcyBhIEphdmFTY3JpcHQgbnVtYmVy/AkQAAAAAAAYChAALAAAAD4AAAAvaG9tZS9tYXJjaW4vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi9zZXJkZS13YXNtLWJpbmRnZW4tMC42LjUvc3JjL2xpYi5ycwAAAFgKEABlAAAANQAAAA4AAABjbG9zdXJlIGludm9rZWQgcmVjdXJzaXZlbHkgb3IgYWZ0ZXIgYmVpbmcgZHJvcHBlZC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnMAAAILEABMAAAAYAgAACQAAAACCxAATAAAABoGAAAVAAAAL2hvbWUvbWFyY2luLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvYXZ0LTAuMTYuMC9zcmMvcGFyc2VyLnJzAABwCxAAWgAAAMYBAAAiAAAAcAsQAFoAAADaAQAADQAAAHALEABaAAAA3AEAAA0AAABwCxAAWgAAAE0CAAAmAAAAcAsQAFoAAABSAgAAJgAAAHALEABaAAAAWAIAABgAAABwCxAAWgAAAHACAAATAAAAcAsQAFoAAAB0AgAAEwAAAHALEABaAAAABQMAACcAAABwCxAAWgAAAAsDAAAnAAAAcAsQAFoAAAARAwAAJwAAAHALEABaAAAAFwMAACcAAABwCxAAWgAAAB0DAAAnAAAAcAsQAFoAAAAjAwAAJwAAAHALEABaAAAAKQMAACcAAABwCxAAWgAAAC8DAAAnAAAAcAsQAFoAAAA1AwAAJwAAAHALEABaAAAAOwMAACcAAABwCxAAWgAAAEEDAAAnAAAAcAsQAFoAAABHAwAAJwAAAHALEABaAAAATQMAACcAAABwCxAAWgAAAFMDAAAnAAAAcAsQAFoAAABuAwAAKwAAAHALEABaAAAAewMAAC8AAABwCxAAWgAAAIcDAAAvAAAAcAsQAFoAAACMAwAAKwAAAHALEABaAAAAkQMAACcAAABwCxAAWgAAAK0DAAArAAAAcAsQAFoAAAC6AwAALwAAAHALEABaAAAAxgMAAC8AAABwCxAAWgAAAMsDAAArAAAAcAsQAFoAAADQAwAAJwAAAHALEABaAAAA3gMAACcAAABwCxAAWgAAANcDAAAnAAAAcAsQAFoAAACYAwAAJwAAAHALEABaAAAAWgMAACcAAABwCxAAWgAAAGADAAAnAAAAcAsQAFoAAACfAwAAJwAAAHALEABaAAAAZwMAACcAAABwCxAAWgAAAKYDAAAnAAAAcAsQAFoAAADkAwAAJwAAAHALEABaAAAADgQAABMAAABwCxAAWgAAABcEAAAbAAAAcAsQAFoAAAAgBAAAFAAAAC9ob21lL21hcmNpbi8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL3VuaWNvZGUtd2lkdGgtMC4xLjE0L3NyYy90YWJsZXMucnOMDhAAZAAAAIwAAAAVAAAAjA4QAGQAAACRAAAAFQAAAIwOEABkAAAAlwAAABkAAABhc3NlcnRpb24gZmFpbGVkOiBtaWQgPD0gc2VsZi5sZW4oKS9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvY29yZS9zcmMvc2xpY2UvbW9kLnJzQw8QAE0AAABSDQAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IGsgPD0gc2VsZi5sZW4oKQAAAEMPEABNAAAAfQ0AAAkAAAAvcnVzdGMvOWIwMDk1NmU1NjAwOWJhYjJhYTE1ZDdiZmYxMDkxNjU5OWUzZDZkNi9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvbW9kLnJz1A8QAEwAAADWCAAADQAAAC9ob21lL21hcmNpbi8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE2LjAvc3JjL2xpbmUucnMwEBAAWAAAAB0AAAAWAAAAMBAQAFgAAAAeAAAAFwAAADAQEABYAAAAIQAAABMAAAAwEBAAWAAAACsAAAAkAAAAMBAQAFgAAAA9AAAAGwAAADAQEABYAAAAQwAAAB4AAAAwEBAAWAAAAEQAAAAfAAAAMBAQAFgAAABPAAAAGwAAADAQEABYAAAAVwAAABsAAAAwEBAAWAAAAF4AAAAbAAAAMBAQAFgAAABtAAAAGwAAADAQEABYAAAAdQAAABsAAAAwEBAAWAAAAHgAAAAeAAAAMBAQAFgAAAB5AAAAHwAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGUwEBAAWAAAAIAAAAARAAAAMBAQAFgAAACJAAAAJwAAADAQEABYAAAAjQAAABcAAAAwEBAAWAAAAJsAAAAWAAAAMBAQAFgAAACcAAAAFwAAADAQEABYAAAAqAAAABMAAAAwEBAAWAAAAL8AAAAlAAAAMBAQAFgAAADDAAAAJQAAADAQEABYAAAA+QAAACUAAAAgDxAAAAAAADAQEABYAAAATgEAAB4AAAAvaG9tZS9tYXJjaW4vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi9hdnQtMC4xNi4wL3NyYy9idWZmZXIucnMAADgSEABaAAAAWgAAAA0AAAA4EhAAWgAAAF4AAAANAAAAOBIQAFoAAABjAAAADQAAADgSEABaAAAAaAAAAB0AAAA4EhAAWgAAAHUAAAAlAAAAOBIQAFoAAAB/AAAAJQAAADgSEABaAAAAhwAAABUAAAA4EhAAWgAAAJEAAAAlAAAAOBIQAFoAAACYAAAAFQAAADgSEABaAAAAnQAAACUAAAA4EhAAWgAAAKgAAAARAAAAOBIQAFoAAAC3AAAAEQAAADgSEABaAAAAuQAAABEAAAA4EhAAWgAAAMMAAAANAAAAOBIQAFoAAADHAAAAEQAAADgSEABaAAAAygAAAA0AAAA4EhAAWgAAAPQAAAArAAAAOBIQAFoAAAA5AQAALAAAADgSEABaAAAAMgEAABsAAAA4EhAAWgAAAEUBAAAUAAAAOBIQAFoAAABXAQAAGAAAADgSEABaAAAAXAEAABgAAABhc3NlcnRpb24gZmFpbGVkOiBsaW5lcy5pdGVyKCkuYWxsKHxsfCBsLmxlbigpID09IGNvbHMpADgSEABaAAAA9wEAAAUAAAAAAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAhAAAAIgAAACMAAAAkAAAAJQAAACYAAAAnAAAAKAAAACkAAAAqAAAAKwAAACwAAAAtAAAALgAAAC8AAAAwAAAAMQAAADIAAAAzAAAANAAAADUAAAA2AAAANwAAADgAAAA5AAAAOgAAADsAAAA8AAAAPQAAAD4AAAA/AAAAQAAAAEEAAABCAAAAQwAAAEQAAABFAAAARgAAAEcAAABIAAAASQAAAEoAAABLAAAATAAAAE0AAABOAAAATwAAAFAAAABRAAAAUgAAAFMAAABUAAAAVQAAAFYAAABXAAAAWAAAAFkAAABaAAAAWwAAAFwAAABdAAAAXgAAAF8AAABmJgAAkiUAAAkkAAAMJAAADSQAAAokAACwAAAAsQAAACQkAAALJAAAGCUAABAlAAAMJQAAFCUAADwlAAC6IwAAuyMAAAAlAAC8IwAAvSMAABwlAAAkJQAANCUAACwlAAACJQAAZCIAAGUiAADAAwAAYCIAAKMAAADFIgAAfwAAAEwAAAAAAAAAAQAAAE0AAABOAAAATwAAAFAAAABRAAAAFAAAAAQAAABSAAAAUwAAAFQAAABVAAAAL2hvbWUvbWFyY2luLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvYXZ0LTAuMTYuMC9zcmMvdGVybWluYWwucnN0FhAAXAAAAHUCAAAVAAAAdBYQAFwAAACxAgAADgAAAHQWEABcAAAABQQAACMAAAA6NToAABcQAAAAAAAAFxAAAwAAADoyOjoAFxAAAAAAABQXEAADAAAAFxcQAAEAAAAXFxAAAQAAAC9ob21lL21hcmNpbi8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE2LjAvc3JjL3RhYnMucnM4FxAAWAAAABcAAAAUAAAAL2hvbWUvbWFyY2luLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvYXZ0LTAuMTYuMC9zcmMvdGVybWluYWwvZGlydHlfbGluZXMucnOgFxAAaAAAAAwAAAAPAAAAoBcQAGgAAAAQAAAADwAAAGFzc2VydGlvbiBmYWlsZWQ6IG1pZCA8PSBzZWxmLmxlbigpL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tb2QucnNLGBAATQAAAFINAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogayA8PSBzZWxmLmxlbigpAAAASxgQAE0AAAB9DQAACQAAABtbMDvfGBAAAQAAADsxOzI7Mzs0OzU7Nzs5AEGBssAAC4cBAQIDAwQFBgcICQoLDA0OAwMDAwMDAw8DAwMDAwMDDwkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJEAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJAEGBtMAAC58LAQICAgIDAgIEAgUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0CAh4CAgICAgICHyAhIiMCJCUmJygpAioCAgICKywCAgICLS4CAgIvMDEyMwICAgICAjQCAjU2NwI4OTo7PD0+Pzk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OUA5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5QQICQkMCAkRFRkdISQJKOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5SwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjk5OTlMAgICAgJNTk9QAgICUQJSUwICAgICAgICAgICAgJUVQICVgJXAgJYWVpbXF1eX2BhAmJjAmRlZmcCaAJpamtsAgJtbm9wAnFyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdHUCAgICAgICdnc5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OXg5OTk5OTk5OTl5egICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICezk5fDk5fQICAgICAgICAgICAgICAgICAgJ+AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICfwICAoCBggICAgICAgICAgICAgICAoOEAgICAgICAgICAoWGdQIChwICAogCAgICAgICiYoCAgICAgICAgICAgICi4wCjY4Cj5CRkpOUlZYClwICmJmamwICAgICAgICAgI5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTmcHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCdAgICAp6fAgQCBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHQICHgICAgICAgIfICEiIwIkJSYnKCkCKgICAgKgoaKjpKWmLqeoqaqrrK0zAgICAgICrgICNTY3Ajg5Ojs8PT6vOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5TAICAgICsE5PsYWGdQIChwICAogCAgICAgICiYoCAgICAgICAgICAgICi4yys44Cj5CRkpOUlZYClwICmJmamwICAgICAgICAgJVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQby/wAALKVVVVVUVAFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBAEHvv8AAC8QBEEEQVVVVVVVXVVVVVVVVVVVVUVVVAABAVPXdVVVVVVVVVVUVAAAAAABVVVVV/F1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQUAFAAUBFBVVVVVVVVVFVFVVVVVVVVVAAAAAAAAQFVVVVVVVVVVVdVXVVVVVVVVVVVVVVUFAABUVVVVVVVVVVVVVVVVVRUAAFVVUVVVVVVVBRAAAAEBUFVVVVVVVVVVVVUBVVVVVVX/////f1VVVVBVAABVVVVVVVVVVVVVBQBBwMHAAAuYBEBVVVVVVVVVVVVVVVVVRVQBAFRRAQBVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVRAFUVVFVFVVVBVVVVVVVVUVBVVVVVVVVVVVVVVVVVVVUQRUUUFFVVVVVVVVVUFFVVUFVVVVVVVVVVVVVVVVVVVQBEFRRVVVVVQVVVVVVVQUAUVVVVVVVVVVVVVVVVVVVBAFUVVFVAVVVBVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVFVFVVUVUVVVVVVVVVVVVVVVRUVVVVVVVVVVVVVVVVVQRUBQRQVUFVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVFEQFBFBVQVVVBVVVVVVVVVVQVVVVVVVVVVVVVVVVVRVEAVRVQVUVVVUFVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVUUVBURVFVVVVVVVVVVVVVVVVVVVVVVVVVVVUQBAVVUVAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRAABUVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVURUVVVVVVVVVVVVVVVVVUBAABAAARVAQAAAQAAAAAAAAAAVFVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEEAEFBVVVVVVVVUAVUVVVVAVRVVUVBVVFVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAEGAxsAAC5ADVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVVVVVVVBVRVVVVVVVUFVVVVVVVVVQVVVVVVVVVVBVVVVX///ff//ddfd9bV11UQAFBVRQEAAFVXUVVVVVVVVVVVVVUVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVUVUVVAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVcVFFVVVVVVVVVVVVVVVVVVRQBARAEAVBUAABRVVVVVVVVVVVVVVVUAAAAAAAAAQFVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVUAAFAFVVVVVVVVVVVVFQAAVVVVUFVVVVVVVVUFUBBQVVVVVVVVVVVVVVVVVUVQEVBVVVVVVVVVVVVVVVVVVQAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAQAVFFVVFBVVVVVVVVVVVVVVVVVVVVVVQBBoMnAAAuTCFVVFQBVVVVVVVUFQFVVVVVVVVVVVVVVVQAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAAAAAAAAAFRVVVVVVVVVVVX1VVVVaVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/VfXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX1VVVVVVV9VVVVVVVVVVVVVVVX///9VVVVVVVVVVVVV1VVVVVXVVVVVXVX1VVVVVX1VX1V1VVdVVVVVdVX1XXVdVV31VVVVVVVVVVdVVVVVVVVVVXfV31VVVVVVVVVVVVVVVVVVVf1VVVVVVVVXVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVdVXVVVVVVVVVVVVVVVVV11VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVBVVVVVVVVVVVVVVVVVVVX9////////////////X1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAAAAAAqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVWqqqqqqqqqqqqqqqqqqgoAqqqqaqmqqqqqqqqqqqqqqqqqqqqqqqqqqmqBqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlWpqqqqqqqqqqqqqqmqqqqqqqqqqqqqqqqoqqqqqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVlaqqqqqqqqqqqqqqaqqqqqqqqqqqqqpVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVVVVVVVVVVVVVVVVVVVVqqqqVqqqqqqqqqqqqqqqqqpqVVVVVVVVVVVVVVVVVV9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVQAAAUFVVVVVVVVUFVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVRUUVVVVVVVVVQVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVUAAAAAUFVFFVVVVVVVVVVVVQUAUFVVVVVVFQAAUFVVVaqqqqqqqqpWQFVVVVVVVVVVVVVVFQVQUFVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVAUBBQVVVFVVVVFVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVQQUVAVRVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFUUVVVVVWqqqqqqqqqqqpVVVUAAAAAAEAVAEG/0cAAC+EMVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAA8KqqWlUAAAAAqqqqqqqqqqpqqqqqqmqqVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFamqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlZVVVVVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVVVqmpVVQAAVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFQFUBQVUAVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVFVVVVVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVVVVVVVVVVVVVUFAABUVVVVVVVVVVVVVVUFUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVAAAAQFVVVVVVVVVVVVUUVFUVUFVVVVVVVVVVVVVVFUBBVUVVVVVVVVVVVVVVVVVVVVVAVVVVVVVVVVUVAAEAVFVVVVVVVVVVVVVVVVVVFVVVVVBVVVVVVVVVVVVVVVUFAEAFVQEUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUARVRVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUVAEBVVVVVVVBVVVVVVVVVVVVVVVVVFURUVVVVVRVVVVUFAFQAVFVVVVVVVVVVVVVVVVVVVVUAAAVEVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVUUAEQRBFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFQVQVRBUVVVVVVVVUFVVVVVVVVVVVVVVVVVVVVVVVVVVFQBAEVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVEAEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBBRAAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVAABBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVRUEEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAFVVRVVVVVVVVVAQBAVVVVVVVVVVVVFQAEQFUVVVUBQAFVVVVVVVVVVVVVAAAAAEBQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBAABBVVVVVVVVVVVVVVVVVVVVVVVVVVQUAAAAAAAUABEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBQEUQAABVVVVVVVVVVVVVVVVVVVVVVVVQEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVUVVVAVVVVVVVVVVVVVVVVBUBVRFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFQAAAFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBUVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVFUBVVVVVVVVVVVVVVVVVVVVVVVVVqlRVVVpVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVVVVVVVqqpWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqmqaaqqqqqqqqqqalVVVWVVVVVVVVVVallVVVWqVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVVVVVVVVQQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBBq97AAAt1UAAAAAAAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRFQBQAAAABAAQBVVVVVVVVVBVBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVAEGt38AACwJAFQBBu9/AAAvFBlRVUVVVVVRVVVVVFQABAAAAVVVVVVVVVVVVVVVVVVVVVVVVVVUAQAAAAAAUABAEQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXVVVVVVVVVVVVVVVVVVVVVdf3/f1VVVVVVVVVVVVVVVVVVVVVVVfX///////9uVVVVqqq6qqqqqur6v79VqqpWVV9VVVWqWlVVVVVVVf//////////V1VV/f/f///////////////////////3//////9VVVX/////////////f9X/VVVV/////1dX//////////////////////9/9//////////////////////////////////////////////////////////////X////////////////////X1VV1X////////9VVVVVdVVVVVVVVX1VVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVXV////////////////////////////VVVVVVVVVVVVVVVV//////////////////////9fVVd//VX/VVXVV1X//1dVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///9VV1VVVVVVVf//////////////f///3/////////////////////////////////////////////////////////////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////V///V1X//////////////9//X1X1////Vf//V1X//1dVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVVVVVmWVWGqpVmqVVVVVVWVVVVVVVVVVZVVVQBBjubAAAsBAwBBnObAAAvqLFVVVVVVlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFQCWalpaaqoFQKZZlWVVVVVVVVVVVQAAAABVVlVVqVZVVVVVVVVVVVVWVVVVVVVVVVUAAAAAAAAAAFRVVVWVWVlVVWVVVWlVVVVVVVVVVVVVVZVWlWqqqqpVqqpaVVVVWVWqqqpVVVVVZVVVWlVVVVWlZVZVVVWVVVVVVVVVppaalllZZamWqqpmVapVWllVWlZlVVVVaqqlpVpVVVWlqlpVVVlZVVVZVVVVVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVlVfVVVVVpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVqqqqqqqqqqqqVVVVqqqqqqVaVVWaqlpVpaVVWlqllqVaVVVVpVpVlVVVVX1VaVmlVV9VZlVVVVVVVVVVZlX///9VVVWammqaVVVV1VVVVVXVVVWlXVX1VVVVVb1Vr6q6qquqqppVuqr6rrquVV31VVVVVVVVVVdVVVVVWVVVVXfV31VVVVVVVVWlqqpVVVVVVVXVV1VVVVVVVVVVVVVVVVetWlVVVVVVVVVVVaqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAAAAwKqqWlUAAAAAqqqqqqqqqqpqqqqqqmqqVVVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVWqalVVAABUWaqqalWqqqqqqqqqWqqqqqqqqqqqqqqqqqqqWlWqqqqqqqqquv7/v6qqqqpWVVVVVVVVVVVVVVVVVfX///////9Kc1ZhbHVlKCkAAADANRAACAAAAMg1EAABAAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR53DUQACQAAAAvcnVzdGMvOWIwMDk1NmU1NjAwOWJhYjJhYTE1ZDdiZmYxMDkxNjU5OWUzZDZkNi9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJzCDYQAEwAAADnAQAACQAAAG51bGwgcG9pbnRlciBwYXNzZWQgdG8gcnVzdHJlY3Vyc2l2ZSB1c2Ugb2YgYW4gb2JqZWN0IGRldGVjdGVkIHdoaWNoIHdvdWxkIGxlYWQgdG8gdW5zYWZlIGFsaWFzaW5nIGluIHJ1c3QAAFRyaWVkIHRvIHNocmluayB0byBhIGxhcmdlciBjYXBhY2l0edA2EAAkAAAAL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc/w2EABMAAAA5wEAAAkAAABaAAAADAAAAAQAAABbAAAAXAAAAAQAAABfAAAADAAAAAQAAABgAAAAYQAAAGIAAAAvcnVzdC9kZXBzL2RsbWFsbG9jLTAuMi42L3NyYy9kbG1hbGxvYy5yc2Fzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQAiDcQACkAAACoBAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplIDw9IHNpemUgKyBtYXhfb3ZlcmhlYWQAAIg3EAApAAAArgQAAA0AAABBY2Nlc3NFcnJvcm1lbW9yeSBhbGxvY2F0aW9uIG9mICBieXRlcyBmYWlsZWQAAAA7OBAAFQAAAFA4EAANAAAAbGlicmFyeS9zdGQvc3JjL2FsbG9jLnJz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AODhVa7iYVfs5CFZ0OihWSAA7lnwAX9aAHAABwAtAQEBAgECAQFICzAVEAFlBwIGAgIBBCMBHhtbCzoJCQEYBAEJAQMBBSsDPAgqGAEgNwEBAQQIBAEDBwoCHQE6AQEBAgQIAQkBCgIaAQICOQEEAgQCAgMDAR4CAwELAjkBBAUBAgQBFAIWBgEBOgEBAgEECAEHAwoCHgE7AQEBDAEJASgBAwE3AQEDBQMBBAcCCwIdAToBAgECAQMBBQIHAgsCHAI5AgEBAgQIAQkBCgIdAUgBBAECAwEBCAFRAQIHDAhiAQIJCwdJAhsBAQEBATcOAQUBAgULASQJAWYEAQYBAgICGQIEAxAEDQECAgYBDwEAAwADHQIeAh4CQAIBBwgBAgsJAS0DAQF1AiIBdgMEAgkBBgPbAgIBOgEBBwEBAQECCAYKAgEwHzEEMAcBAQUBKAkMAiAEAgIBAzgBAQIDAQEDOggCApgDAQ0BBwQBBgEDAsZAAAHDIQADjQFgIAAGaQIABAEKIAJQAgABAwEEARkCBQGXAhoSDQEmCBkLLgMwAQIEAgInAUMGAgICAgwBCAEvATMBAQMCAgUCAQEqAggB7gECAQQBAAEAEBAQAAIAAeIBlQUAAwECBQQoAwQBpQIABAACUANGCzEEewE2DykBAgIKAzEEAgIHAT0DJAUBCD4BDAI0CQoEAgFfAwIBAQIGAQIBnQEDCBUCOQIBAQEBFgEOBwMFwwgCAwEBFwFRAQIGAQECAQECAQLrAQIEBgIBAhsCVQgCAQECagEBAQIGAQFlAwIEAQUACQEC9QEKAgEBBAGQBAICBAEgCigGAgQIAQkGAgMuDQECAAcBBgEBUhYCBwECAQJ6BgMBAQIBBwEBSAIDAQEBAAILAjQFBQEBAQABBg8ABTsHAAE/BFEBAAIALgIXAAEBAwQFCAgCBx4ElAMANwQyCAEOARYFAQ8ABwERAgcBAgEFZAGgBwABPQQABAAHbQcAYIDwAHsJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjc4LjAgKDliMDA5NTZlNSAyMDI0LTA0LTI5KQZ3YWxydXMGMC4yMC4zDHdhc20tYmluZGdlbhIwLjIuOTIgKDJhNGE0OTM2MikALA90YXJnZXRfZmVhdHVyZXMCKw9tdXRhYmxlLWdsb2JhbHMrCHNpZ24tZXh0");class f{constructor(){let A=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.speed=A,this.startTime=performance.now()}getTime(){return this.speed*(performance.now()-this.startTime)/1e3}setTime(A){this.startTime=performance.now()-A/this.speed*1e3}}class U{constructor(){}getTime(A){}setTime(A){}}class Y{constructor(A,g){this.input="function"==typeof A.next?A:A[Symbol.iterator](),this.xfs=g??[]}map(A){return this.transform(function(A){return g=>I=>{g(A(I))}}(A))}flatMap(A){return this.transform(function(A){return g=>I=>{A(I).forEach(g)}}(A))}filter(A){return this.transform(function(A){return g=>I=>{A(I)&&g(I)}}(A))}take(A){return this.transform(function(A){let g=0;return I=>B=>{gB=>{g+=1,g>A&&I(B)}}(A))}transform(A){return new Y(this.input,this.xfs.concat([A]))}multiplex(A,g){return new Y(new L(this[Symbol.iterator](),A[Symbol.iterator](),g))}toArray(){return Array.from(this)}[Symbol.iterator](){let A=0,g=[],I=!1;const B=(Q=this.xfs,C=A=>g.push(A),Q.reverse().reduce(((A,g)=>{const I=S(g(A.step));return{step:I.step,flush:()=>{I.flush(),A.flush()}}}),S(C)));var Q,C;return{next:()=>{for(A===g.length&&(g=[],A=0);0===g.length;){const A=this.input.next();if(A.done)break;B.step(A.value)}return 0!==g.length||I||(B.flush(),I=!0),g.length>0?{done:!1,value:g[A++]}:{done:!0}}}}}function S(A){return"function"==typeof A?{step:A,flush:()=>{}}:A}class L{constructor(A,g,I){this.left=A,this.right=g,this.comparator=I}[Symbol.iterator](){let A,g;return{next:()=>{if(void 0===A&&void 0!==this.left){const g=this.left.next();g.done?this.left=void 0:A=g.value}if(void 0===g&&void 0!==this.right){const A=this.right.next();A.done?this.right=void 0:g=A.value}if(void 0===A&&void 0===g)return{done:!0};if(void 0===A){const A=g;return g=void 0,{done:!1,value:A}}if(void 0===g){const g=A;return A=void 0,{done:!1,value:g}}if(this.comparator(A,g)){const g=A;return A=void 0,{done:!1,value:g}}{const A=g;return g=void 0,{done:!1,value:A}}}}}}async function p(A){if(A instanceof Response){const g=await A.text(),I=function(A){const g=A.split("\n");let I;try{I=JSON.parse(g[0])}catch(A){return}const B=new Y(g).drop(1).filter((A=>"["===A[0])).map(JSON.parse);return{header:I,events:B}}(g);if(void 0!==I){const{header:A,events:g}=I;if(2===A.version)return H(A,g);if(3===A.version)return m(A,g);throw`asciicast v${A.version} format not supported`}{const A=JSON.parse(g);if(1===A.version)return K(A)}}else{if("object"==typeof A&&1===A.version)return K(A);if(Array.isArray(A)){const g=A[0];if(2===g.version){return H(g,A.slice(1,A.length))}if(3===g.version){return m(g,A.slice(1,A.length))}throw`asciicast v${g.version} format not supported`}}throw"invalid data"}function K(A){let g=0;const I=new Y(A.stdout).map((A=>(g+=A[0],[g,"o",A[1]])));return{cols:A.width,rows:A.height,events:I}}function H(A,g){return{cols:A.width,rows:A.height,theme:b(A.theme),events:g,idleTimeLimit:A.idle_time_limit}}function m(A,g){g instanceof Y||(g=new Y(g));let I=0;return g=g.map((A=>(I+=A[0],[I,A[1],A[2]]))),{cols:A.term.cols,rows:A.term.rows,theme:b(A.term?.theme),events:g,idleTimeLimit:A.idle_time_limit}}function b(A){if(void 0===A)return;const g=/^#[0-9A-Fa-f]{6}$/,I=A?.fg,B=A?.bg,Q=A?.palette;return g.test(I)&&g.test(B)&&/^(#[0-9A-Fa-f]{6}:){7,}#[0-9A-Fa-f]{6}$/.test(Q)?{foreground:I,background:B,palette:Q.split(":")}:void 0}function v(A){return"number"==typeof A?[A,"m",""]:[A[0],"m",A[1]]}function T(){let A=0;return function(g){return"m"===g[1]?[g[0],g[1],{index:A++,time:g[0],label:g[2]}]:g}}class x{constructor(){this.items=[],this.onPush=void 0}push(A){this.items.push(A),void 0!==this.onPush&&(this.onPush(this.popAll()),this.onPush=void 0)}popAll(){if(this.items.length>0){const A=this.items;return this.items=[],A}{const A=this;return new Promise((g=>{A.onPush=g}))}}}function O(A,g,I,B,Q,C,E,V,i){const e=function(A,g,I,B){return function(Q,C){"o"===Q?A(C):"i"===Q?I(C):"r"===Q?g(C.cols,C.rows):"m"===Q&&B(C)}}(g,I,B,Q);if(0===A)return i.debug("using no buffer"),function(A){return{pushEvent(g){A(g[1],g[2])},pushText(g){A("o",g)},stop(){}}}(e);{let g;return"number"==typeof(A=A??{})?(i.debug(`using fixed time buffer (${A} ms)`),g=g=>A):"function"==typeof A?(i.debug("using custom dynamic buffer"),g=A({logger:i})):(i.debug("using adaptive buffer",A),g=function(A,g){let{logger:I}=A,{minTime:B=25,maxLevel:Q=100,interval:C=50,windowSize:E=20,smoothingFactor:V=.2,minImprovementDuration:i=1e3}=g,e=0,o=a(e),t=[],s=0,n=0,r=null;function a(A){return 0===A?B:C*A}return A=>{if(t.push(A),t.lengthgg>A?g:A))}(t);s=B*V+s*(1-V),n=(B-g)*V+n*(1-V);const C=s+n;if(A>o&&I.debug("buffer underrun",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o}),eo)o=a(e+=1),I.debug("jitter increased, raising bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o});else if(e>1&&Ci&&(r=performance.now(),o=a(e-=1),I.debug("jitter decreased, lowering bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o})),o;return r=null,o}}({logger:i},A)),function(A,g,I,B,Q){let C=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1/60,E=performance.now()-1e3*Q,V=A(0);const i=new x;C*=1e3;let e=-C,o=!1;function t(){return performance.now()-E}return setTimeout((async()=>{for(;!o;){const A=await i.popAll();if(o)return;for(const B of A){const A=1e3*B[0]+V;if(A-e0&&(await W(Q),o))return;I(B[0]),g(B[1],B[2]),e=A}}}),0),{pushEvent(g){let I=t()-1e3*g[0];I<0&&(B.debug(`correcting epoch by ${I} ms`),E+=I,I=0),V=A(I),i.push(g)},pushText(A){i.push([t()/1e3,"o",A])},stop(){o=!0,i.push(void 0)}}}(g,e,C,i,E??0,V)}}function W(A){return new Promise((g=>{setTimeout(g,A)}))}const j=1e6;function Z(A){const g=new TextDecoder,I=new TextDecoder;let B,Q=function(A){const g=(new TextDecoder).decode(A);if("ALiS"!==g)throw"not an ALiS v1 live stream";Q=E},C=0;function E(A){const g=new _(new DataView(A)),I=g.getUint8();if(1!==I)throw`expected reset (0x01) frame, got ${I}`;return V(g,A)}function V(A,I){A.decodeVarUint();let E=A.decodeVarUint();B=E,E/=j,C=0;const V=A.decodeVarUint(),e=A.decodeVarUint(),o=A.getUint8();let t;if(8===o){const g=30;t=X(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(16===o){const g=54;t=X(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(0!==o)throw`alis: invalid theme format (${o})`;const s=A.decodeVarUint();let n;return s>0&&(n=g.decode(new Uint8Array(I,A.offset,s))),Q=i,{time:E,term:{size:{cols:V,rows:e},theme:t,init:n}}}function i(i){const e=new _(new DataView(i)),o=e.getUint8();return 1===o?V(e,i):111===o?function(A,I){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=g.decode(new Uint8Array(I,A.offset,C));return[B/j,"o",E]}(e,i):105===o?function(A,g){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=I.decode(new Uint8Array(g,A.offset,C));return[B/j,"i",E]}(e,i):114===o?function(A){A.decodeVarUint();const g=A.decodeVarUint();B+=g;const I=A.decodeVarUint(),Q=A.decodeVarUint();return[B/j,"r",{cols:I,rows:Q}]}(e):109===o?function(A,g){A.decodeVarUint();const I=A.decodeVarUint();B+=I;const Q=A.decodeVarUint(),E=new TextDecoder,V=C++,i=B/j,e=E.decode(new Uint8Array(g,A.offset,Q));return[i,"m",{index:V,time:i,label:e}]}(e,i):4===o?(Q=E,!1):void A.debug(`alis: unknown frame type: ${o}`)}return function(A){return Q(A)}}function X(A){const g=A.length/3,I=P(A[0],A[1],A[2]),B=P(A[3],A[4],A[5]),Q=[];for(let I=2;I1&&void 0!==arguments[1]?arguments[1]:0;this.inner=A,this.offset=g}forward(A){this.offset+=A}getUint8(){const A=this.inner.getUint8(this.offset);return this.offset+=1,A}decodeVarUint(){let A=BigInt(0),g=BigInt(0),I=this.getUint8();for(;I>127;)I&=127,A+=BigInt(I)<(await R(u),J))();class QA{constructor(A){this.core=A,this.driver=A.driver}onEnter(A){}init(){}play(){}pause(){}togglePlay(){}seek(A){return!1}step(A){}stop(){this.driver.stop()}}class CA extends QA{async init(){try{return await this.core._initializeDriver(),this.core._setState("idle")}catch(A){throw this.core._setState("errored"),A}}async play(){this.core._dispatchEvent("play");const A=await this.init();await A.doPlay()}async togglePlay(){await this.play()}async seek(A){const g=await this.init();return await g.seek(A)}async step(A){const g=await this.init();await g.step(A)}stop(){}}class EA extends QA{onEnter(A){let{reason:g,message:I}=A;this.core._dispatchEvent("idle",{message:I}),"paused"===g&&this.core._dispatchEvent("pause")}async play(){this.core._dispatchEvent("play"),await this.doPlay()}async doPlay(){const A=await this.driver.play();!0===A?this.core._setState("playing"):"function"==typeof A&&(this.core._setState("playing"),this.driver.stop=A)}async togglePlay(){await this.play()}seek(A){return this.driver.seek(A)}step(A){this.driver.step(A)}}class VA extends QA{onEnter(){this.core._dispatchEvent("playing")}pause(){!0===this.driver.pause()&&this.core._setState("idle",{reason:"paused"})}togglePlay(){this.pause()}seek(A){return this.driver.seek(A)}}class iA extends QA{onEnter(){this.core._dispatchEvent("loading")}}class eA extends QA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("offline",{message:g})}}class oA extends QA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("ended",{message:g})}async play(){this.core._dispatchEvent("play"),await this.driver.restart()&&this.core._setState("playing")}async togglePlay(){await this.play()}seek(A){return!0===this.driver.seek(A)&&(this.core._setState("idle"),!0)}}class tA extends QA{onEnter(){this.core._dispatchEvent("errored")}}class sA{constructor(A,I){this.logger=I.logger,this.state=new CA(this),this.stateName="uninitialized",this.driver=function(A){if("function"==typeof A)return A;"string"==typeof A&&(A="ws://"==A.substring(0,5)||"wss://"==A.substring(0,6)?{driver:"websocket",url:A}:"clock:"==A.substring(0,6)?{driver:"clock"}:"random:"==A.substring(0,7)?{driver:"random"}:"benchmark:"==A.substring(0,10)?{driver:"benchmark",url:A.substring(10)}:{driver:"recording",url:A});void 0===A.driver&&(A.driver="recording");if("recording"==A.driver&&(void 0===A.parser&&(A.parser="asciicast"),"string"==typeof A.parser)){if(!rA.has(A.parser))throw`unknown parser: ${A.parser}`;A.parser=rA.get(A.parser)}if(nA.has(A.driver)){const g=nA.get(A.driver);return(I,B)=>g(A,I,B)}throw`unsupported driver: ${JSON.stringify(A)}`}(A),this.changedLines=new Set,this.cursor=void 0,this.duration=void 0,this.cols=I.cols,this.rows=I.rows,this.speed=I.speed,this.loop=I.loop,this.autoPlay=I.autoPlay,this.idleTimeLimit=I.idleTimeLimit,this.preload=I.preload,this.startAt=g(I.startAt),this.poster=this._parsePoster(I.poster),this.markers=this._normalizeMarkers(I.markers),this.pauseOnMarkers=I.pauseOnMarkers,this.commandQueue=Promise.resolve(),this.eventHandlers=new Map([["ended",[]],["errored",[]],["idle",[]],["input",[]],["loading",[]],["marker",[]],["metadata",[]],["offline",[]],["pause",[]],["play",[]],["playing",[]],["ready",[]],["reset",[]],["resize",[]],["seeked",[]],["terminalUpdate",[]]])}async init(){this.wasm=await BA;const A=this._feed.bind(this),g=this._now.bind(this),I=this._resetVt.bind(this),B=this._resizeVt.bind(this),Q=this._setState.bind(this),C="npt"===this.poster.type?this.poster.value:void 0;this.driver=this.driver({feed:A,onInput:A=>{this._dispatchEvent("input",{data:A})},onMarker:A=>{let{index:g,time:I,label:B}=A;this._dispatchEvent("marker",{index:g,time:I,label:B})},reset:I,resize:B,now:g,setTimeout:(A,g)=>setTimeout(A,g/this.speed),setInterval:(A,g)=>setInterval(A,g/this.speed),setState:Q,logger:this.logger},{cols:this.cols,rows:this.rows,idleTimeLimit:this.idleTimeLimit,startAt:this.startAt,loop:this.loop,posterTime:C,markers:this.markers,pauseOnMarkers:this.pauseOnMarkers}),"function"==typeof this.driver&&(this.driver={play:this.driver}),(this.preload||void 0!==C)&&this._withState((A=>A.init()));const E="text"===this.poster.type?this._renderPoster(this.poster.value):null,V={isPausable:!!this.driver.pause,isSeekable:!!this.driver.seek,poster:E};if(void 0===this.driver.init&&(this.driver.init=()=>({})),void 0===this.driver.pause&&(this.driver.pause=()=>{}),void 0===this.driver.seek&&(this.driver.seek=A=>!1),void 0===this.driver.step&&(this.driver.step=A=>{}),void 0===this.driver.stop&&(this.driver.stop=()=>{}),void 0===this.driver.restart&&(this.driver.restart=()=>{}),void 0===this.driver.getCurrentTime){const A=this.driver.play;let g=new U;this.driver.play=()=>(g=new f(this.speed),A()),this.driver.getCurrentTime=()=>g.getTime()}this._dispatchEvent("ready",V),this.autoPlay&&this.play()}play(){return this._withState((A=>A.play()))}pause(){return this._withState((A=>A.pause()))}togglePlay(){return this._withState((A=>A.togglePlay()))}seek(A){return this._withState((async g=>{await g.seek(A)&&this._dispatchEvent("seeked")}))}step(A){return this._withState((g=>g.step(A)))}stop(){return this._withState((A=>A.stop()))}getChanges(){const A={};if(this.changedLines.size>0){const g=new Map,I=this.vt.rows;for(const A of this.changedLines)A1&&void 0!==arguments[1]?arguments[1]:{};for(const I of this.eventHandlers.get(A))I(g)}_withState(A){return this._enqueueCommand((()=>A(this.state)))}_enqueueCommand(A){return this.commandQueue=this.commandQueue.then(A),this.commandQueue}_setState(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.stateName===A)return this.state;if(this.stateName=A,"playing"===A)this.state=new VA(this);else if("idle"===A)this.state=new EA(this);else if("loading"===A)this.state=new iA(this);else if("ended"===A)this.state=new oA(this);else if("offline"===A)this.state=new eA(this);else{if("errored"!==A)throw`invalid state: ${A}`;this.state=new tA(this)}return this.state.onEnter(g),this.state}_feed(A){this._doFeed(A),this._dispatchEvent("terminalUpdate")}_doFeed(A){this.vt.feed(A).forEach((A=>this.changedLines.add(A))),this.cursor=void 0}_now(){return performance.now()*this.speed}async _initializeDriver(){const A=await this.driver.init();this.cols=this.cols??A.cols??80,this.rows=this.rows??A.rows??24,this.duration=this.duration??A.duration,this.markers=this._normalizeMarkers(A.markers)??this.markers??[],0===this.cols&&(this.cols=80),0===this.rows&&(this.rows=24),this._initializeVt(this.cols,this.rows);const g=void 0!==A.poster?this._renderPoster(A.poster):null;this._dispatchEvent("metadata",{cols:this.cols,rows:this.rows,duration:this.duration,markers:this.markers,theme:A.theme,poster:g})}_resetVt(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,B=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;this.logger.debug(`core: vt reset (${A}x${g})`),this.cols=A,this.rows=g,this.cursor=void 0,this._initializeVt(A,g),void 0!==I&&""!==I&&this._doFeed(I),this._dispatchEvent("reset",{cols:A,rows:g,theme:B})}_resizeVt(A,g){if(A===this.vt.cols&&g===this.vt.rows)return;this.vt.resize(A,g).forEach((A=>this.changedLines.add(A))),this.cursor=void 0,this.vt.cols=A,this.vt.rows=g,this.logger.debug(`core: vt resize (${A}x${g})`),this._dispatchEvent("resize",{cols:A,rows:g})}_initializeVt(A,g){this.vt=this.wasm.create(A,g,!0,100),this.vt.cols=A,this.vt.rows=g,this.changedLines.clear();for(let A=0;AB.feed(A)));const Q=B.getCursor()??!1,C=[];for(let A=0;A"number"==typeof A?[A,""]:A))}}const nA=new Map([["benchmark",function(A,g){let I,{url:B,iterations:Q=10}=A,{feed:C,setState:E,now:V}=g,i=0;return{async init(){const A=await p(await fetch(B)),{cols:g,rows:Q,events:C}=A;I=Array.from(C).filter((A=>{let[g,I,B]=A;return"o"===I})).map((A=>{let[g,I,B]=A;return[g,B]}));const E=I[I.length-1][0];for(const[A,g]of I)i+=new Blob([g]).size;return{cols:g,rows:Q,duration:E}},play(){const A=V();for(let A=0;A{E("stopped",{reason:"ended"})}),0),!0}}}],["clock",function(A,g,I){let{hourColor:B=3,minuteColor:Q=4,separatorColor:C=9}=A,{feed:E}=g,{cols:V=5,rows:i=1}=I;const e=Math.floor(i/2),o=Math.floor(V/2)-2,t=`[?25l[${e}B`;let s;const n=()=>{const A=new Date,g=A.getHours(),I=A.getMinutes(),E=[];E.push("\r");for(let A=0;A{n().forEach(E)};return{init:()=>{const A=[t].concat(n());return{cols:V,rows:i,duration:1440,poster:A}},play:()=>(E(t),r(),s=setInterval(r,1e3),!0),stop:()=>{clearInterval(s)},getCurrentTime:()=>{const A=new Date;return 60*A.getHours()+A.getMinutes()}}}],["eventsource",function(A,g){let I,Q,{url:C,bufferTime:E,minFrameTime:V}=A,{feed:i,reset:e,resize:o,onInput:t,onMarker:s,setState:n,logger:r}=g;r=new B(r,"eventsource: ");let a=new U;function c(A){void 0!==Q&&Q.stop(),Q=O(E,i,o,t,s,(A=>a.setTime(A)),A,V,r)}return{play:()=>{I=new EventSource(C),I.addEventListener("open",(()=>{r.info("opened"),c()})),I.addEventListener("error",(A=>{r.info("errored"),r.debug({e:A}),n("loading")})),I.addEventListener("message",(A=>{const g=JSON.parse(A.data);if(Array.isArray(g))Q.pushEvent(g);else if(void 0!==g.cols||void 0!==g.width){const A=g.cols??g.width,I=g.rows??g.height;r.debug(`vt reset (${A}x${I})`),n("playing"),c(g.time),e(A,I,g.init??void 0),a=new f,"number"==typeof g.time&&a.setTime(g.time)}else"offline"===g.state&&(r.info("stream offline"),n("offline",{message:"Stream offline"}),a=new U)})),I.addEventListener("done",(()=>{r.info("closed"),I.close(),n("ended",{message:"Stream ended"})}))},stop:()=>{void 0!==Q&&Q.stop(),void 0!==I&&I.close()},getCurrentTime:()=>a.getTime()}}],["random",function(A,g){let{feed:I,setTimeout:B}=g;const Q=" ".charCodeAt(0),C="~".charCodeAt(0)-Q;let E;const V=()=>{const A=Math.pow(5,4*Math.random());E=B(i,A)},i=()=>{V();const A=String.fromCharCode(Q+Math.floor(Math.random()*C));I(A)};return()=>(V(),()=>clearInterval(E))}],["recording",function(A,g,I){let B,Q,C,E,V,i,e,o,t,{feed:s,resize:n,onInput:r,onMarker:a,now:c,setTimeout:D,setState:w,logger:l}=g,{idleTimeLimit:h,startAt:y,loop:G,posterTime:k,markers:F,pauseOnMarkers:N,cols:q,rows:R}=I,J=0,d=0,M=0;async function u(A,g){const I=await fetch(A,g);if(!I.ok)throw`failed fetching recording from ${A}: ${I.status} ${I.statusText}`;return I}function f(){const A=C[J];A?e=D(U,function(A){let g=1e3*A-(c()-o);return g<0&&(g=0),g}(A[0])):p()}function U(){let A,g=C[J];do{d=g[0],J++;if(L(g))return;g=C[J],A=c()-o}while(g&&A>1e3*g[0]);f()}function S(){clearTimeout(e),e=null}function L(A){const[g,I,B]=A;if("o"===I)s(B);else if("i"===I)r(B);else if("r"===I){const[A,g]=B.split("x");n(A,g)}else if("m"===I&&(a(B),N))return K(),t=1e3*g,w("idle",{reason:"paused"}),!0;return!1}function p(){S(),M++,!0===G||"number"==typeof G&&M>"===A?A=I+5:"<<<"===A?A=I-.1*V:">>>"===A?A=I+.1*V:"%"===A[A.length-1]&&(A=parseFloat(A.substring(0,A.length-1))/100*V);else if("object"==typeof A)if("prev"===A.marker)A=b(I)??0,g&&I-A<1&&(A=b(A)??0);else if("next"===A.marker)A=function(A){if(0==E.length)return;let g,I=E.length-1,B=E[I];for(;B&&B[0]>A;)g=B[0],B=E[--I];return g}(I)??V;else if("number"==typeof A.marker){const g=E[A.marker];if(void 0===g)throw`invalid marker index: ${A.marker}`;A=g[0]}const B=Math.min(Math.max(A,0),V);B1&&void 0!==arguments[1]?arguments[1]:1/60;return B=>{let Q=0,C=0;return{step:A=>{Q++,void 0!==g?"o"===A[1]&&"o"===g[1]&&A[0]-g[0]{void 0!==g&&(B(g),C++),A.debug(`batched ${Q} frames to ${C} frames`)}}}}(g,C)).map(function(A,g,I){let B=0,Q=0;return function(C){const E=C[0]-B-A;return B=C[0],E>0&&(Q+=E,C[0]"m"!==A[1])).multiplex(V,((A,g)=>A[0]"i"===A[1]?[A[0]+E,A[1],A[2]]:A)),i.sort(((A,g)=>A[0]-g[0])));const o=i[i.length-1][0],t=B-e.offset;return{...A,events:i,duration:o,effectiveStartAt:t}}(await g(await function(A){let{url:g,data:I,fetchOpts:B={}}=A;if("string"==typeof g)return u(g,B);if(Array.isArray(g))return Promise.all(g.map((A=>u(A,B))));if(void 0!==I)return"function"==typeof I&&(I=I()),I instanceof Promise||(I=Promise.resolve(I)),I.then((A=>"string"==typeof A||A instanceof ArrayBuffer?new Response(A):A));throw"failed fetching recording file: url/data missing in src"}(A),{encoding:t}),l,{idleTimeLimit:h,startAt:y,minFrameTime:I,inputOffset:e,markers_:F});if(({cols:B,rows:Q,events:C,duration:V,effectiveStartAt:i}=s),q=q??B,R=R??Q,0===C.length)throw"recording is missing events";void 0!==o&&function(A,g){const I=document.createElement("a"),B=A.events.map((A=>"m"===A[1]?[A[0],A[1],A[2].label]:A)),Q=function(A){return`${JSON.stringify({version:2,width:A.cols,height:A.rows})}\n${A.events.map(JSON.stringify).join("\n")}\n`}({...A,events:B});I.href=URL.createObjectURL(new Blob([Q],{type:"text/plain"})),I.download=g,I.click()}(s,o);const n=void 0!==k?(r=k,C.filter((A=>A[0]A[2]))):void 0;var r;return E=C.filter((A=>"m"===A[1])).map((A=>[A[0],A[2].label])),{cols:B,rows:Q,duration:V,theme:s.theme,poster:n,markers:E}},play:function(){if(e)throw"already playing";if(void 0===C[J])throw"already ended";return null!==i&&m(i),H(),!0},pause:K,seek:m,step:function(A){let g,I;if(void 0===A&&(A=1),A>0){let B=J;g=C[B];for(let Q=0;Q{const A=I.protocol||"raw";a.info("opened"),a.info(`activating ${A} protocol handler`),"v1.alis"===A?I.onmessage=k(Z(a)):"v2.asciicast"===A?I.onmessage=k(function(){let A=function(I){const B=JSON.parse(I);if(2!==B.version)throw"not an asciicast v2 stream";return A=g,{time:0,term:{size:{cols:B.width,rows:B.height}}}};function g(A){const g=JSON.parse(A);if("r"===g[1]){const[A,I]=g[2].split("x");return[g[0],"r",{cols:A,rows:I}]}return g}return function(g){return A(g)}}()):"raw"===A&&(I.onmessage=k($())),c=setTimeout((()=>{l=0}),1e3)},I.onclose=A=>{if(clearTimeout(D),q(),h||1e3===A.code||1005===A.code)a.info("closed"),r("ended",{message:"Stream ended"});else if(1002===A.code)a.debug(`close reason: ${A.reason}`),r("ended",{message:"Err: Player not compatible with the server"});else{clearTimeout(c);const A=V(l++);a.info(`unclean close, reconnecting in ${A}...`),r("loading"),setTimeout(G,A)}},y=!1}function k(A){return D=setTimeout(N,5e3),function(g){try{const I=A(g.data);if(Q)if(Array.isArray(I))Q.pushEvent(I);else if("string"==typeof I)Q.pushText(I);else if("object"!=typeof I||Array.isArray(I)){if(!1===I)N();else if(void 0!==I)throw`unexpected value from protocol handler: ${I}`}else F(I);else if("object"!=typeof I||Array.isArray(I)){if(void 0!==I)throw clearTimeout(D),`unexpected value from protocol handler: ${I}`;clearTimeout(D),D=setTimeout(N,1e3)}else F(I),clearTimeout(D)}catch(A){throw I.close(),A}}}function F(A){let{time:g,term:I}=A;const{size:B,init:C,theme:V}=I,{cols:c,rows:D}=B;a.info(`stream reset (${c}x${D} @${g})`),r("playing"),q(),Q=O(E,e,t,s,n,(A=>w.setTime(A)),g,i,a),o(c,D,C,V),w=new f,y=!0,"number"==typeof g&&w.setTime(g)}function N(){q(),y?(a.info("stream ended"),r("offline",{message:"Stream ended"})):(a.info("stream offline"),r("offline",{message:"Stream offline"})),w=new U}function q(){Q&&Q.stop(),Q=null}return{play:()=>{G()},stop:()=>{h=!0,q(),void 0!==I&&I.close()},getCurrentTime:()=>w.getTime()}}]]),rA=new Map([["asciicast",p],["typescript",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I);let Q,C,E=(await A[0].text()).split("\n").filter((A=>A.length>0)).map((A=>A.split(" ")));E[0].length<3&&(E=E.map((A=>["O",A[0],A[1]])));const V=await A[1].arrayBuffer(),i=new Uint8Array(V),e=i.findIndex((A=>10==A))+1,o=B.decode(i.subarray(0,e)).match(/COLUMNS="(\d+)" LINES="(\d+)"/);null!==o&&(Q=parseInt(o[1],10),C=parseInt(o[2],10));const t={array:i,cursor:e};let s=t;if(void 0!==A[2]){const g=await A[2].arrayBuffer();s={array:new Uint8Array(g),cursor:e}}const n=[];let r=0;for(const A of E)if(r+=parseFloat(A[1]),"O"===A[0]){const g=parseInt(A[2],10),I=t.array.subarray(t.cursor,t.cursor+g),Q=B.decode(I);n.push([r,"o",Q]),t.cursor+=g}else if("I"===A[0]){const g=parseInt(A[2],10),I=s.array.subarray(s.cursor,s.cursor+g),Q=B.decode(I);n.push([r,"i",Q]),s.cursor+=g}else if("S"===A[0]&&"SIGWINCH"===A[2]){const g=parseInt(A[4].slice(5),10),I=parseInt(A[3].slice(5),10);n.push([r,"r",`${g}x${I}`])}else"H"===A[0]&&"COLUMNS"===A[2]?Q=parseInt(A[3],10):"H"===A[0]&&"LINES"===A[2]&&(C=parseInt(A[3],10));return Q=Q??80,C=C??24,{cols:Q,rows:C,events:n}}],["ttyrec",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I),Q=await A.arrayBuffer(),C=new Uint8Array(Q),E=gA(C),V=E.time,i=B.decode(E.data).match(/\x1b\[8;(\d+);(\d+)t/),e=[];let o=80,t=24;null!==i&&(o=parseInt(i[2],10),t=parseInt(i[1],10));let s=0,n=gA(C);for(;void 0!==n;){const A=n.time-V,g=B.decode(n.data);e.push([A,"o",g]),s+=n.len,n=gA(C.subarray(s))}return{cols:o,rows:t,events:e}}]]);const aA=Symbol("solid-proxy"),cA="function"==typeof Proxy,DA=Symbol("solid-track"),wA={equals:(A,g)=>A===g};let lA=OA;const hA=1,yA=2,GA={owned:null,cleanups:null,context:null,owner:null};var kA=null;let FA=null,NA=null,qA=null,RA=null,JA=0;function dA(A,g){const I=NA,B=kA,Q=0===A.length,C=void 0===g?B:g,E=Q?GA:{owned:null,cleanups:null,context:C?C.context:null,owner:C},V=Q?A:()=>A((()=>YA((()=>XA(E)))));kA=E,NA=null;try{return xA(V,!0)}finally{NA=I,kA=B}}function MA(A,g){const I={value:A,observers:null,observerSlots:null,comparator:(g=g?Object.assign({},wA,g):wA).equals||void 0};return[HA.bind(I),A=>("function"==typeof A&&(A=A(I.value)),mA(I,A))]}function uA(A,g,I){bA(vA(A,g,!1,hA))}function fA(A,g,I){I=I?Object.assign({},wA,I):wA;const B=vA(A,g,!0,0);return B.observers=null,B.observerSlots=null,B.comparator=I.equals||void 0,bA(B),HA.bind(B)}function UA(A){return xA(A,!1)}function YA(A){if(null===NA)return A();const g=NA;NA=null;try{return A()}finally{NA=g}}function SA(A){!function(A,g,I){lA=WA;const B=vA(A,g,!1,hA);I&&I.render||(B.user=!0),RA?RA.push(B):bA(B)}((()=>YA(A)))}function LA(A){return null===kA||(null===kA.cleanups?kA.cleanups=[A]:kA.cleanups.push(A)),A}function pA(){return NA}function KA(A){const g=fA(A),I=fA((()=>zA(g())));return I.toArray=()=>{const A=I();return Array.isArray(A)?A:null!=A?[A]:[]},I}function HA(){if(this.sources&&this.state)if(this.state===hA)bA(this);else{const A=qA;qA=null,xA((()=>jA(this)),!1),qA=A}if(NA){const A=this.observers?this.observers.length:0;NA.sources?(NA.sources.push(this),NA.sourceSlots.push(A)):(NA.sources=[this],NA.sourceSlots=[A]),this.observers?(this.observers.push(NA),this.observerSlots.push(NA.sources.length-1)):(this.observers=[NA],this.observerSlots=[NA.sources.length-1])}return this.value}function mA(A,g,I){let B=A.value;return A.comparator&&A.comparator(B,g)||(A.value=g,A.observers&&A.observers.length&&xA((()=>{for(let g=0;g1e6)throw qA=[],new Error}),!1)),g}function bA(A){if(!A.fn)return;XA(A);const g=JA;!function(A,g,I){let B;const Q=kA,C=NA;NA=kA=A;try{B=A.fn(g)}catch(g){return A.pure&&(A.state=hA,A.owned&&A.owned.forEach(XA),A.owned=null),A.updatedAt=I+1,PA(g)}finally{NA=C,kA=Q}(!A.updatedAt||A.updatedAt<=I)&&(null!=A.updatedAt&&"observers"in A?mA(A,B):A.value=B,A.updatedAt=I)}(A,A.value,g)}function vA(A,g,I,B=hA,Q){const C={fn:A,state:B,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:g,owner:kA,context:kA?kA.context:null,pure:I};return null===kA||kA!==GA&&(kA.owned?kA.owned.push(C):kA.owned=[C]),C}function TA(A){if(0===A.state)return;if(A.state===yA)return jA(A);if(A.suspense&&YA(A.suspense.inFallback))return A.suspense.effects.push(A);const g=[A];for(;(A=A.owner)&&(!A.updatedAt||A.updatedAt=0;I--)if((A=g[I]).state===hA)bA(A);else if(A.state===yA){const I=qA;qA=null,xA((()=>jA(A,g[0])),!1),qA=I}}function xA(A,g){if(qA)return A();let I=!1;g||(qA=[]),RA?I=!0:RA=[],JA++;try{const g=A();return function(A){qA&&(OA(qA),qA=null);if(A)return;const g=RA;RA=null,g.length&&xA((()=>lA(g)),!1)}(I),g}catch(A){I||(RA=null),qA=null,PA(A)}}function OA(A){for(let g=0;g=0;g--)XA(A.tOwned[g]);delete A.tOwned}if(A.owned){for(g=A.owned.length-1;g>=0;g--)XA(A.owned[g]);A.owned=null}if(A.cleanups){for(g=A.cleanups.length-1;g>=0;g--)A.cleanups[g]();A.cleanups=null}A.state=0}function PA(A,g=kA){const I=function(A){return A instanceof Error?A:new Error("string"==typeof A?A:"Unknown error",{cause:A})}(A);throw I}function zA(A){if("function"==typeof A&&!A.length)return zA(A());if(Array.isArray(A)){const g=[];for(let I=0;IA(g||{})))}function gg(){return!0}const Ig={get:(A,g,I)=>g===aA?I:A.get(g),has:(A,g)=>g===aA||A.has(g),set:gg,deleteProperty:gg,getOwnPropertyDescriptor:(A,g)=>({configurable:!0,enumerable:!0,get:()=>A.get(g),set:gg,deleteProperty:gg}),ownKeys:A=>A.keys()};function Bg(A){return(A="function"==typeof A?A():A)?A:{}}function Qg(){for(let A=0,g=this.length;A`Stale read from <${A}>.`;function Eg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B=[],Q=[],C=[],E=0,V=g.length>1?[]:null;return LA((()=>$A(C))),()=>{let i,e,o=A()||[],t=o.length;return o[DA],YA((()=>{let A,g,n,r,a,c,D,w,l;if(0===t)0!==E&&($A(C),C=[],B=[],Q=[],E=0,V&&(V=[])),I.fallback&&(B=[_A],Q[0]=dA((A=>(C[0]=A,I.fallback()))),E=1);else if(0===E){for(Q=new Array(t),e=0;e=c&&w>=c&&B[D]===o[w];D--,w--)n[w]=Q[D],r[w]=C[D],V&&(a[w]=V[D]);for(A=new Map,g=new Array(w+1),e=w;e>=c;e--)l=o[e],i=A.get(l),g[e]=void 0===i?-1:i,A.set(l,e);for(i=c;i<=D;i++)l=B[i],e=A.get(l),void 0!==e&&-1!==e?(n[e]=Q[i],r[e]=C[i],V&&(a[e]=V[i]),e=g[e],A.set(l,e)):C[i]();for(e=c;eA.each),A.children,g||void 0))}function Vg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B,Q=[],C=[],E=[],V=[],i=0;return LA((()=>$A(E))),()=>{const e=A()||[],o=e.length;return e[DA],YA((()=>{if(0===o)return 0!==i&&($A(E),E=[],Q=[],C=[],i=0,V=[]),I.fallback&&(Q=[_A],C[0]=dA((A=>(E[0]=A,I.fallback()))),i=1),C;for(Q[0]===_A&&(E[0](),E=[],Q=[],C=[],i=0),B=0;Be[B])):B>=Q.length&&(C[B]=dA(t));for(;BA.each),A.children,g||void 0))}function ig(A){const g=A.keyed,I=fA((()=>A.when),void 0,void 0),B=g?I:fA(I,void 0,{equals:(A,g)=>!A==!g});return fA((()=>{const Q=B();if(Q){const C=A.children;return"function"==typeof C&&C.length>0?YA((()=>C(g?Q:()=>{if(!YA(B))throw Cg("Show");return I()}))):C}return A.fallback}),void 0,void 0)}function eg(A){const g=KA((()=>A.children)),I=fA((()=>{const A=g(),I=Array.isArray(A)?A:[A];let B=()=>{};for(let A=0;AC()?void 0:Q.when),void 0,void 0),V=Q.keyed?E:fA(E,void 0,{equals:(A,g)=>!A==!g});B=()=>C()||(V()?[g,E,Q]:void 0)}return B}));return fA((()=>{const g=I()();if(!g)return A.fallback;const[B,Q,C]=g,E=C.children;return"function"==typeof E&&E.length>0?YA((()=>E(C.keyed?Q():()=>{if(YA(I)()?.[0]!==B)throw Cg("Match");return Q()}))):E}),void 0,void 0)}function og(A){return A}const tg="_$DX_DELEGATE";function sg(A,g,I,B={}){let Q;return dA((B=>{Q=B,g===document?A():lg(g,A(),g.firstChild?null:void 0,I)}),B.owner),()=>{Q(),g.textContent=""}}function ng(A,g,I,B){let Q;const C=()=>{const g=B?document.createElementNS("http://www.w3.org/1998/Math/MathML","template"):document.createElement("template");return g.innerHTML=A,I?g.content.firstChild.firstChild:B?g.firstChild:g.content.firstChild},E=g?()=>YA((()=>document.importNode(Q||(Q=C()),!0))):()=>(Q||(Q=C())).cloneNode(!0);return E.cloneNode=E,E}function rg(A,g=window.document){const I=g[tg]||(g[tg]=new Set);for(let B=0,Q=A.length;BB.call(A,I[1],g))}else A.addEventListener(g,I,"function"!=typeof I&&I)}function Dg(A,g,I){if(!g)return I?function(A,g,I){null==I?A.removeAttribute(g):A.setAttribute(g,I)}(A,"style"):g;const B=A.style;if("string"==typeof g)return B.cssText=g;let Q,C;for(C in"string"==typeof I&&(B.cssText=I=void 0),I||(I={}),g||(g={}),I)null==g[C]&&B.removeProperty(C),delete I[C];for(C in g)Q=g[C],Q!==I[C]&&(B.setProperty(C,Q),I[C]=Q);return I}function wg(A,g,I){return YA((()=>A(g,I)))}function lg(A,g,I,B){if(void 0===I||B||(B=[]),"function"!=typeof g)return yg(A,g,B,I);uA((B=>yg(A,g(),B,I)),B)}function hg(A){let g=A.target;const I=`$$${A.type}`,B=A.target,Q=A.currentTarget,C=g=>Object.defineProperty(A,"target",{configurable:!0,value:g}),E=()=>{const B=g[I];if(B&&!g.disabled){const Q=g[`${I}Data`];if(void 0!==Q?B.call(g,Q,A):B.call(g,A),A.cancelBubble)return}return g.host&&"string"!=typeof g.host&&!g.host._$host&&g.contains(A.target)&&C(g.host),!0},V=()=>{for(;E()&&(g=g._$host||g.parentNode||g.host););};if(Object.defineProperty(A,"currentTarget",{configurable:!0,get:()=>g||document}),A.composedPath){const I=A.composedPath();C(I[0]);for(let A=0;A{let Q=g();for(;"function"==typeof Q;)Q=Q();I=yg(A,Q,I,B)})),()=>I;if(Array.isArray(g)){const C=[],V=I&&Array.isArray(I);if(Gg(C,g,I,Q))return uA((()=>I=yg(A,C,I,B,!0))),()=>I;if(0===C.length){if(I=Fg(A,I,B),E)return I}else V?0===I.length?kg(A,C,B):function(A,g,I){let B=I.length,Q=g.length,C=B,E=0,V=0,i=g[Q-1].nextSibling,e=null;for(;EB-V){const Q=g[E];for(;V=0;C--){const E=g[C];if(Q!==E){const g=E.parentNode===A;B||C?g&&E.remove():g?A.replaceChild(Q,E):A.insertBefore(Q,I)}else B=!0}}else A.insertBefore(Q,I);return[Q]}const Ng=Symbol("store-raw"),qg=Symbol("store-node"),Rg=Symbol("store-has"),Jg=Symbol("store-self");function dg(A){let g=A[aA];if(!g&&(Object.defineProperty(A,aA,{value:g=new Proxy(A,Sg)}),!Array.isArray(A))){const I=Object.keys(A),B=Object.getOwnPropertyDescriptors(A);for(let Q=0,C=I.length;Qg===Ng||g===aA||g===DA||g===qg||g===Rg||"__proto__"===g||(pA()&&Ug(fg(A,Rg),g)(),g in A),set:()=>!0,deleteProperty:()=>!0,ownKeys:function(A){return Yg(A),Reflect.ownKeys(A)},getOwnPropertyDescriptor:function(A,g){const I=Reflect.getOwnPropertyDescriptor(A,g);return I&&!I.get&&I.configurable&&g!==aA&&g!==qg?(delete I.value,delete I.writable,I.get=()=>A[aA][g],I):I}};function Lg(A,g,I,B=!1){if(!B&&A[g]===I)return;const Q=A[g],C=A.length;void 0===I?(delete A[g],A[Rg]&&A[Rg][g]&&void 0!==Q&&A[Rg][g].$()):(A[g]=I,A[Rg]&&A[Rg][g]&&void 0===Q&&A[Rg][g].$());let E,V=fg(A,qg);if((E=Ug(V,g,Q))&&E.$((()=>I)),Array.isArray(A)&&A.length!==C){for(let g=A.length;g1){B=g.shift();const C=typeof B,E=Array.isArray(A);if(Array.isArray(B)){for(let Q=0;Q1)return void Kg(A[B],g,[B].concat(I));Q=A[B],I=[B].concat(I)}let C=g[0];"function"==typeof C&&(C=C(Q,I),C===Q)||void 0===B&&null==C||(C=ug(C),void 0===B||Mg(Q)&&Mg(C)&&!Array.isArray(C)?pg(Q,C):Lg(A,B,C))}function Hg(...[A,g]){const I=ug(A||{}),B=Array.isArray(I);return[dg(I),function(...A){UA((()=>{B&&1===A.length?function(A,g){if("function"==typeof g&&(g=g(A)),g=ug(g),Array.isArray(g)){if(A===g)return;let I=0,B=g.length;for(;I=E&&i>=E&&(C[V]===A[i]||Q&&C[V]&&A[i]&&C[V][Q]===A[i][Q]);V--,i--)s[i]=C[V];if(E>i||E>V){for(I=E;I<=i;I++)Lg(C,I,A[I]);for(;IA.length&&Lg(C,"length",A.length))}for(o=new Array(i+1),I=i;I>=E;I--)e=A[I],t=Q&&e?e[Q]:e,g=n.get(t),o[I]=void 0===g?-1:g,n.set(t,I);for(g=E;g<=V;g++)e=C[g],t=Q&&e?e[Q]:e,I=n.get(t),void 0!==I&&-1!==I&&(s[I]=C[g],I=o[I],n.set(t,I));for(I=E;IA.length&&Lg(C,"length",A.length))}const V=Object.keys(A);for(let g=0,I=V.length;g{if(!Mg(A)||!Mg(Q))return Q;const g=bg(Q,{[mg]:A},mg,I,B);return void 0===g?A:g}}const Tg=ng("",2);var xg=A=>{const g=fA((()=>{if(1==A.text.length){const g=A.text.codePointAt(0);if(g>=9600&&g<=9631||57520==g||57522==g)return g}})),I=fA((()=>g()?" ":A.text)),B=fA((()=>function(A,g,I){const B=A.get("fg"),Q=A.get("bg");let C={"--offset":g,width:`${I+.01}ch`};"string"==typeof B&&(C["--fg"]=B);"string"==typeof Q&&(C["--bg"]=Q);return C}(A.pen,A.offset,A.cellCount))),Q=fA((()=>function(A,g,I){const B=Og(A.get("fg"),A.get("bold"),"fg-"),Q=Og(A.get("bg"),!1,"bg-");let C=I??"";void 0!==g&&(C+=` cp-${g.toString(16)}`);B&&(C+=" "+B);Q&&(C+=" "+Q);A.has("bold")&&(C+=" ap-bright");A.has("faint")&&(C+=" ap-faint");A.has("italic")&&(C+=" ap-italic");A.has("underline")&&(C+=" ap-underline");A.has("blink")&&(C+=" ap-blink");A.get("inverse")&&(C+=" ap-inverse");return C}(A.pen,g(),A.extraClass)));return(()=>{const A=Tg.cloneNode(!0);return lg(A,I),uA((g=>{const I=Q(),C=B();return I!==g._v$&&ag(A,g._v$=I),g._v$2=Dg(A,C,g._v$2),g}),{_v$:void 0,_v$2:void 0}),A})()};function Og(A,g,I){if("number"==typeof A)return g&&A<8&&(A+=8),`${I}${A}`}const Wg=ng('',2);var jg=A=>(()=>{const g=Wg.cloneNode(!0);return lg(g,Ag(Vg,{get each(){return(()=>{if("number"==typeof A.cursor){const g=[];let I=0,B=0;for(;B0&&g.push({...Q,text:i.slice(0,V).join("")}),g.push({...Q,text:i[V],offset:I+E,cellCount:C,extraClass:"ap-cursor"}),VAg(xg,function(...A){let g=!1;for(let I=0;I=0;I--){const B=Bg(A[I])[g];if(void 0!==B)return B}},has(g){for(let I=A.length-1;I>=0;I--)if(g in Bg(A[I]))return!0;return!1},keys(){const g=[];for(let I=0;I=0;g--){const Q=A[g];if(!Q)continue;const C=Object.getOwnPropertyNames(Q);for(let A=C.length-1;A>=0;A--){const g=C[A];if("__proto__"===g||"constructor"===g)continue;const E=Object.getOwnPropertyDescriptor(Q,g);if(B[g]){const A=I[g];A&&(E.get?A.push(E.get.bind(Q)):void 0!==E.value&&A.push((()=>E.value)))}else B[g]=E.get?{enumerable:!0,configurable:!0,get:Qg.bind(I[g]=[E.get.bind(Q)])}:void 0!==E.value?E:void 0}}const Q={},C=Object.keys(B);for(let A=C.length-1;A>=0;A--){const g=C[A],I=B[g];I&&I.get?Object.defineProperty(Q,g,I):Q[g]=I?I.value:void 0}return Q}(A))})),g})();const Zg=ng('
',2);var Xg=A=>{const g=()=>A.lineHeight??1.3333333333,I=fA((()=>({width:`${A.cols}ch`,height:g()*A.rows+"em","font-size":100*(A.scale||1)+"%","font-family":A.fontFamily,"--term-line-height":`${g()}em`,"--term-cols":A.cols}))),B=fA((()=>A.cursor?.[0])),Q=fA((()=>A.cursor?.[1]));return(()=>{const g=Zg.cloneNode(!0),C=A.ref;return"function"==typeof C?wg(C,g):A.ref=g,lg(g,Ag(Eg,{get each(){return A.lines},children:(A,g)=>Ag(jg,{get segments(){return A.segments},get cursor(){return(A=()=>g()===Q(),fA((()=>A())))()?B():null;var A}})})),uA((B=>{const Q=!(!A.blink&&!A.cursorHold),C=!!A.blink,E=I();return Q!==B._v$&&g.classList.toggle("ap-cursor-on",B._v$=Q),C!==B._v$2&&g.classList.toggle("ap-blink",B._v$2=C),B._v$3=Dg(g,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})()};const Pg=ng('',6),zg=ng('',4),_g=ng('',2),$g=ng('',6),AI=ng('
Keyboard shortcuts (?)Fullscreen (f)
',34),gI=ng('',6);function II(A){let g=Math.floor(A);const I=Math.floor(g/86400);g%=86400;const B=Math.floor(g/3600);g%=3600;const Q=Math.floor(g/60);return g%=60,I>0?`${BI(I)}:${BI(B)}:${BI(Q)}:${BI(g)}`:B>0?`${BI(B)}:${BI(Q)}:${BI(g)}`:`${BI(Q)}:${BI(g)}`}function BI(A){return A<10?`0${A}`:A.toString()}var QI=A=>{const g=A=>g=>{g.preventDefault(),A(g)},I=()=>"number"==typeof A.currentTime?II(A.currentTime):"--:--",B=()=>"number"==typeof A.remainingTime?"-"+II(A.remainingTime):I(),Q=fA((()=>"number"==typeof A.duration?A.markers.filter((g=>g[0]{const g=A.currentTarget.offsetWidth,I=A.currentTarget.getBoundingClientRect(),B=A.clientX-I.left;return 100*Math.max(0,B/g)+"%"},[E,V]=MA(!1),i=function(A,g){let I=!0;return function(){if(I){I=!1;for(var B=arguments.length,Q=new Array(B),C=0;CI=!0),g)}}}(A.onSeekClick,50),e=g=>{g._marker||g.altKey||g.shiftKey||g.metaKey||g.ctrlKey||0!==g.button||(V(!0),A.onSeekClick(C(g)))},o=A=>{A.altKey||A.shiftKey||A.metaKey||A.ctrlKey||E()&&i(C(A))},t=()=>{V(!1)};return document.addEventListener("mouseup",t),LA((()=>{document.removeEventListener("mouseup",t)})),(()=>{const C=AI.cloneNode(!0),E=C.firstChild,V=E.firstChild,i=V.nextSibling,t=E.nextSibling,s=t.nextSibling,n=s.nextSibling,r=A.ref;return"function"==typeof r?wg(r,C):A.ref=C,lg(C,Ag(ig,{get when(){return A.isPausable},get children(){const I=_g.cloneNode(!0);return cg(I,"click",g(A.onPlayClick),!0),lg(I,Ag(eg,{get children(){return[Ag(og,{get when(){return A.isPlaying},get children(){return Pg.cloneNode(!0)}}),Ag(og,{get when(){return!A.isPlaying},get children(){return zg.cloneNode(!0)}})]}})),I}}),E),lg(V,I),lg(i,B),lg(t,Ag(ig,{get when(){return"number"==typeof A.progress||A.isSeekable},get children(){const I=$g.cloneNode(!0),B=I.firstChild.nextSibling;return I.$$mousemove=o,I.$$mousedown=e,lg(I,Ag(Eg,{get each(){return Q()},children:(I,B)=>(()=>{const Q=gI.cloneNode(!0),C=Q.firstChild,E=C.nextSibling;var V;return Q.$$mousedown=A=>{A._marker=!0},cg(Q,"click",(V=B(),g((()=>{A.onSeekClick({marker:V})}))),!0),lg(E,(()=>(A=>""===A[1]?II(A[0]):`${II(A[0])} - ${A[1]}`)(I))),uA((g=>{const B=(g=>g[0]/A.duration*100+"%")(I),E=!!(g=>"number"==typeof A.currentTime&&g[0]<=A.currentTime)(I);return B!==g._v$&&Q.style.setProperty("left",g._v$=B),E!==g._v$2&&C.classList.toggle("ap-marker-past",g._v$2=E),g}),{_v$:void 0,_v$2:void 0}),Q})()}),null),uA((g=>Dg(B,{transform:`scaleX(${A.progress||0}`},g))),I}})),cg(s,"click",g(A.onHelpClick),!0),cg(n,"click",g(A.onFullscreenClick),!0),uA((()=>C.classList.toggle("ap-seekable",!!A.isSeekable))),C})()};rg(["click","mousedown","mousemove"]);const CI=ng('
💥
',4);var EI=A=>CI.cloneNode(!0);const VI=ng('
',4);var iI=A=>VI.cloneNode(!0);const eI=ng('
',4);var oI=A=>(()=>{const g=eI.cloneNode(!0),I=g.firstChild;return lg(I,(()=>A.message)),uA((g=>Dg(I,{"font-family":A.fontFamily},g))),g})();const tI=ng('
',22);var sI=A=>(()=>{const g=tI.cloneNode(!0);var I;return cg(g,"click",(I=A.onClick,A=>{A.preventDefault(),I(A)}),!0),g})();rg(["click"]);const nI=ng("
  • space - pause / resume
  • ",4),rI=ng("
  • / - rewind / fast-forward by 5 seconds
  • ",6),aI=ng("
  • Shift + / - rewind / fast-forward by 10%
  • ",8),cI=ng("
  • [ / ] - jump to the previous / next marker
  • ",6),DI=ng("
  • 0, 1, 2 ... 9 - jump to 0%, 10%, 20% ... 90%
  • ",10),wI=ng("
  • , / . - step back / forward, a frame at a time (when paused)
  • ",6),lI=ng('

    Keyboard shortcuts

    • f - toggle fullscreen mode
    • ? - toggle this help popup
    ',18);var hI=A=>(()=>{const g=lI.cloneNode(!0),I=g.firstChild,B=I.firstChild.firstChild.nextSibling,Q=B.firstChild;var C;return cg(g,"click",(C=A.onClose,A=>{A.preventDefault(),C(A)}),!0),I.$$click=A=>{A.stopPropagation()},lg(B,Ag(ig,{get when(){return A.isPausable},get children(){return nI.cloneNode(!0)}}),Q),lg(B,Ag(ig,{get when(){return A.isSeekable},get children(){return[rI.cloneNode(!0),aI.cloneNode(!0),cI.cloneNode(!0),DI.cloneNode(!0),wI.cloneNode(!0)]}}),Q),uA((I=>Dg(g,{"font-family":A.fontFamily},I))),g})();rg(["click"]);const yI=ng('
    ',4);var GI=A=>{const g=A.logger,I=A.core,B=A.autoPlay,[Q,C]=Hg({lines:[],cursor:void 0,charW:A.charW,charH:A.charH,bordersW:A.bordersW,bordersH:A.bordersH,containerW:0,containerH:0,isPausable:!0,isSeekable:!0,isFullscreen:!1,currentTime:null,remainingTime:null,progress:null,blink:!0,cursorHold:!1}),[E,V]=MA(!1),[i,e]=MA(B?null:"start"),[o,t]=MA(null),[s,n]=MA({cols:A.cols,rows:A.rows},{equals:(A,g)=>A.cols===g.cols&&A.rows===g.rows}),[r,a]=MA(void 0),[c,D]=Hg([]),[w,l]=MA(!1),[h,y]=MA(!1),[G,k]=MA(void 0),F=fA((()=>s().cols||80)),N=fA((()=>s().rows||24)),q=()=>!1===A.controls?0:32;let R,J,d,M,u,f,U,Y,S,L;function p(){gA(),_(),$()}function K(A){UA((()=>{A.rows{L=A}));I.addEventListener("ready",(A=>{let{isPausable:g,isSeekable:I,poster:B}=A;C({isPausable:g,isSeekable:I}),H(B),L()})),I.addEventListener("metadata",(A=>{let{cols:g,rows:I,duration:B,theme:Q,poster:C,markers:E}=A;UA((()=>{K({cols:g,rows:I}),a(B),k(Q),D(E),H(C)}))})),I.addEventListener("play",(()=>{e(null)})),I.addEventListener("playing",(()=>{UA((()=>{V(!0),e(null),T(),AA(),z()}))})),I.addEventListener("idle",(()=>{UA((()=>{V(!1),p()}))})),I.addEventListener("loading",(()=>{UA((()=>{V(!1),p(),e("loader")}))})),I.addEventListener("offline",(A=>{let{message:g}=A;UA((()=>{V(!1),p(),void 0!==g&&(t(g),e("info"))}))}));let b=0;I.addEventListener("ended",(A=>{let{message:I}=A;UA((()=>{V(!1),p(),void 0!==I&&(t(I),e("info"))})),g.debug(`view: render count: ${b}`)})),I.addEventListener("errored",(()=>{e("error")})),I.addEventListener("resize",K),I.addEventListener("reset",(A=>{let{cols:g,rows:I,theme:B}=A;UA((()=>{K({cols:g,rows:I}),k(B),T()}))})),I.addEventListener("seeked",(()=>{$()})),I.addEventListener("terminalUpdate",(()=>{void 0===R&&(R=requestAnimationFrame(T))}));const v=()=>{S=new ResizeObserver(function(A,g){let I;return function(){for(var B=arguments.length,Q=new Array(B),C=0;CA.apply(this,Q)),g)}}((A=>{C({containerW:u.offsetWidth,containerH:u.offsetHeight}),u.dispatchEvent(new CustomEvent("resize",{detail:{el:f}}))}),10)),S.observe(u)};SA((async()=>{g.info("view: mounted"),g.debug("view: font measurements",{charW:Q.charW,charH:Q.charH}),v(),C({containerW:u.offsetWidth,containerH:u.offsetHeight})})),LA((()=>{I.stop(),gA(),_(),S.disconnect()}));const T=async()=>{const A=await I.getChanges();UA((()=>{void 0!==A.lines&&A.lines.forEach(((A,g)=>{C("lines",g,vg(A))})),void 0!==A.cursor&&C("cursor",vg(A.cursor)),C("cursorHold",!0)})),R=void 0,b+=1},x=fA((()=>{const g=Q.charW*F()+Q.bordersW,I=Q.charH*N()+Q.bordersH;let B=A.fit??"width";if("both"===B||Q.isFullscreen){B=Q.containerW/(Q.containerH-q())>g/I?"height":"width"}if(!1===B||"none"===B)return{};if("width"===B){const A=Q.containerW/g;return{scale:A,width:Q.containerW,height:I*A+q()}}if("height"===B){const A=(Q.containerH-q())/I;return{scale:A,width:g*A,height:Q.containerH}}throw`unsupported fit mode: ${B}`})),O=()=>{C("isFullscreen",document.fullscreenElement??document.webkitFullscreenElement)},W=()=>{Q.isFullscreen?(document.exitFullscreen??document.webkitExitFullscreen??(()=>{})).apply(document):(u.requestFullscreen??u.webkitRequestFullscreen??(()=>{})).apply(u)},j=()=>{h()?y(!1):(I.pause(),y(!0))},Z=A=>{if(!(A.altKey||A.metaKey||A.ctrlKey)){if(" "==A.key)I.togglePlay();else if(","==A.key)I.step(-1),$();else if("."==A.key)I.step(),$();else if("f"==A.key)W();else if("["==A.key)I.seek({marker:"prev"});else if("]"==A.key)I.seek({marker:"next"});else if(A.key.charCodeAt(0)>=48&&A.key.charCodeAt(0)<=57){const g=(A.key.charCodeAt(0)-48)/10;I.seek(100*g+"%")}else if("?"==A.key)j();else if("ArrowLeft"==A.key)A.shiftKey?I.seek("<<<"):I.seek("<<");else if("ArrowRight"==A.key)A.shiftKey?I.seek(">>>"):I.seek(">>");else{if("Escape"!=A.key)return;y(!1)}A.stopPropagation(),A.preventDefault()}},X=()=>{Q.isFullscreen&&IA(!0)},P=()=>{Q.isFullscreen||IA(!1)},z=()=>{d=setInterval($,100)},_=()=>{clearInterval(d)},$=async()=>{const A=await I.getCurrentTime(),g=await I.getRemainingTime(),B=await I.getProgress();C({currentTime:A,remainingTime:g,progress:B})},AA=()=>{M=setInterval((()=>{C((A=>{const g={blink:!A.blink};return g.blink&&(g.cursorHold=!1),g}))}),600)},gA=()=>{clearInterval(M),C("blink",!0)},IA=A=>{clearTimeout(J),A&&(J=setTimeout((()=>IA(!1)),2e3)),l(A)},BA=fA((()=>{const g=A.theme||"auto/asciinema";return"auto/"===g.slice(0,5)?{name:g.slice(5),colors:G()}:{name:g}})),QA=()=>{m.then((()=>I.play()))},CA=()=>{m.then((()=>I.togglePlay()))},EA=A=>{m.then((()=>I.seek(A)))},VA=(()=>{const g=yI.cloneNode(!0),I=g.firstChild;"function"==typeof u?wg(u,g):u=g,g.addEventListener("webkitfullscreenchange",O),g.addEventListener("fullscreenchange",O),g.$$mousemove=X,g.$$keydown=Z;return"function"==typeof f?wg(f,I):f=I,I.$$mousemove=()=>IA(!0),I.addEventListener("mouseleave",P),lg(I,Ag(Xg,{get cols(){return F()},get rows(){return N()},get scale(){return x()?.scale},get blink(){return Q.blink},get lines(){return Q.lines},get cursor(){return Q.cursor},get cursorHold(){return Q.cursorHold},get fontFamily(){return A.terminalFontFamily},get lineHeight(){return A.terminalLineHeight},ref(A){"function"==typeof U?U(A):U=A}}),null),lg(I,Ag(ig,{get when(){return!1!==A.controls},get children(){return Ag(QI,{get duration(){return r()},get currentTime(){return Q.currentTime},get remainingTime(){return Q.remainingTime},get progress(){return Q.progress},markers:c,get isPlaying(){return E()},get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable},onPlayClick:CA,onFullscreenClick:W,onHelpClick:j,onSeekClick:EA,ref(A){"function"==typeof Y?Y(A):Y=A}})}}),null),lg(I,Ag(eg,{get children(){return[Ag(og,{get when(){return"start"==i()},get children(){return Ag(sI,{onClick:QA})}}),Ag(og,{get when(){return"loader"==i()},get children(){return Ag(iI,{})}}),Ag(og,{get when(){return"info"==i()},get children(){return Ag(oI,{get message(){return o()},get fontFamily(){return A.terminalFontFamily}})}}),Ag(og,{get when(){return"error"==i()},get children(){return Ag(EI,{})}})]}}),null),lg(I,Ag(ig,{get when(){return h()},get children(){return Ag(hI,{get fontFamily(){return A.terminalFontFamily},onClose:()=>y(!1),get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable}})}}),null),uA((B=>{const Q=!!(!0===A.controls||"auto"===A.controls&&w()),C=`ap-player asciinema-player-theme-${BA().name}`,E=(()=>{const g={};!1!==A.fit&&"none"!==A.fit||void 0===A.terminalFontSize||("small"===A.terminalFontSize?g["font-size"]="12px":"medium"===A.terminalFontSize?g["font-size"]="18px":"big"===A.terminalFontSize?g["font-size"]="24px":g["font-size"]=A.terminalFontSize);const I=x();void 0!==I.width&&(g.width=`${I.width}px`,g.height=`${I.height}px`);const B=BA().colors;return B&&(g["--term-color-foreground"]=B.foreground,g["--term-color-background"]=B.background,B.palette.forEach(((A,I)=>{g[`--term-color-${I}`]=A}))),g})();return Q!==B._v$&&g.classList.toggle("ap-hud",B._v$=Q),C!==B._v$2&&ag(I,B._v$2=C),B._v$3=Dg(I,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})();return VA};function kI(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const B=function(A,g){const I=80,B=24,Q=document.createElement("div");let C;Q.style.height="0px",Q.style.overflow="hidden",Q.style.fontSize="15px",document.body.appendChild(Q);const E=sg((()=>(C=Ag(Xg,{cols:I,rows:B,lineHeight:g,fontFamily:A,lines:[]}),C)),Q),V={charW:C.clientWidth/I,charH:C.clientHeight/B,bordersW:C.offsetWidth-C.clientWidth,bordersH:C.offsetHeight-C.clientHeight};return E(),document.body.removeChild(Q),V}(I.terminalFontFamily,I.terminalLineHeight),Q={core:A,logger:I.logger,cols:I.cols,rows:I.rows,fit:I.fit,controls:I.controls,autoPlay:I.autoPlay,terminalFontSize:I.terminalFontSize,terminalFontFamily:I.terminalFontFamily,terminalLineHeight:I.terminalLineHeight,theme:I.theme,...B};let C;const E=sg((()=>(C=Ag(GI,Q),C)),g);return{el:C,dispose:E}}rg(["keydown","mousemove"]);const FI=["autoPlay","autoplay","cols","idleTimeLimit","loop","markers","pauseOnMarkers","poster","preload","rows","speed","startAt"],NI=["autoPlay","autoplay","cols","controls","fit","rows","terminalFontFamily","terminalFontSize","terminalLineHeight","theme"];return A.create=function(A,g){let B=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const Q=B.logger??new I,C=new sA(A,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return FI.includes(g)})));return I.autoPlay??=I.autoplay,I.speed??=1,{...I,...g}}(B,{logger:Q})),{el:E,dispose:V}=kI(C,g,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return NI.includes(g)})));return I.autoPlay??=I.autoplay,I.controls??="auto",{...I,...g}}(B,{logger:Q})),i=C.init(),e={el:E,dispose:V,getCurrentTime:()=>i.then(C.getCurrentTime.bind(C)),getDuration:()=>i.then(C.getDuration.bind(C)),play:()=>i.then(C.play.bind(C)),pause:()=>i.then(C.pause.bind(C)),seek:A=>i.then((()=>C.seek(A))),addEventListener:(A,g)=>C.addEventListener(A,g.bind(e))};return e},A}({}); diff --git a/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css b/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css new file mode 100644 index 0000000..db845ba --- /dev/null +++ b/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css @@ -0,0 +1 @@ +@charset "UTF-8";:root{--font-size:16px;--font-size-smaller:0.875rem;--font-size-smallest:0.75rem;--body-font-weight:400;--body-background:white;--body-background-tint:transparent;--body-font-color:black;--border-radius:0.25rem}/*!modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize*/*,::before,::after{box-sizing:border-box}html{font-family:system-ui,segoe ui,Roboto,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji;line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,liberation mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:initial}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}.flex{display:flex}.flex.gap{gap:1rem}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-small,small{font-size:.875em}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}html{font-size:var(--font-size);scroll-behavior:smooth;touch-action:manipulation;scrollbar-gutter:stable}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background)var(--body-background-tint);font-weight:var(--body-font-weight);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-weight:inherit}a{flex:auto;align-items:center;gap:.5em;text-decoration:none;cursor:default}a[href],a[role=button]{color:var(--color-link);cursor:pointer}:focus-visible,input.toggle:focus-visible+label{outline-style:auto;outline-color:var(--color-link)}nav ul{padding:0;margin:0;list-style:none}nav ul li{position:relative}nav ul a{padding:.5em 0;display:flex;transition:opacity .1s ease-in-out}nav ul a[href]:hover,nav ul a[role=button]:hover{opacity:.5}nav ul ul{padding-inline-start:1.5em}ul.pagination{display:flex;justify-content:center;list-style-type:none;padding-inline-start:0}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}a .book-icon{height:1em;width:1em}.book-brand{margin-top:0;margin-bottom:1rem}.book-brand img{height:1.5em;width:1.5em}.book-menu{flex:0 0 16rem;font-size:var(--font-size-smaller)}.book-menu .book-menu-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;word-wrap:break-word;display:flex}.book-menu a.active{color:var(--color-link)}.book-menu label>img:last-child{height:1em;width:1em;cursor:pointer;align-self:center;transition:transform .1s ease-in-out}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-menu input.toggle:checked+label+ul{display:block}body[dir=rtl] .book-menu input.toggle+label>img:last-child{transform:rotate(180deg)}body[dir=rtl] .book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-section-flat{margin:1rem 0}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:4rem}.book-post .book-post-date img{height:1em;width:1em;margin-inline-end:.5em}.book-post .book-post-content{margin-top:1rem}.book-post .book-post-thumbnail{flex:0 0 34%}.book-post .book-post-thumbnail img{width:100%;aspect-ratio:4/3;object-fit:cover}.book-header{margin-bottom:1rem}.book-header label{line-height:0}.book-header h3{overflow:hidden;text-overflow:ellipsis;margin:0 1rem}.book-layout-landing .book-header{display:block;position:relative;z-index:1}.book-layout-landing .book-header nav>ul{display:flex;gap:1rem;justify-content:end}.book-layout-landing .book-header nav>ul>li{display:block;white-space:nowrap}.book-layout-landing .book-header nav>ul>li>ul{display:none;position:absolute;padding:0}.book-layout-landing .book-header nav>ul>li:hover>ul,.book-layout-landing .book-header nav>ul>li:focus-within>ul{display:block}.book-search{position:relative;margin:.5rem 0}.book-search input{width:100%;padding:.5rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search ul a{padding-bottom:0}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:var(--font-size-smallest)}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc a{display:block}.book-toc img{height:1em;width:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:var(--font-size-smaller)}.book-footer a{margin:.25rem 0;padding:.25rem 0}.book-comments{margin-top:1rem}.book-copyright{margin-top:1rem}.book-languages{margin-bottom:1rem}.book-languages span{padding:0}.book-languages ul{padding-inline-start:1.5em}.book-menu-content,.book-toc-content{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){.book-menu{visibility:hidden;margin-inline-start:-16rem;z-index:1}.book-menu .book-menu-content{background:var(--body-background)}.book-toc{display:none}.book-header{display:block}.book-post-container{flex-direction:column-reverse}#menu-control,#toc-control{display:inline}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:fixed;top:0;bottom:0;left:0;right:0}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked~main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:inherit;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;margin-inline-start:.25em}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus-visible,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus-visible,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus-visible,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus-visible,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus-visible,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus-visible{opacity:initial;text-decoration:none}.markdown h1{font-size:2rem}.markdown h2{font-size:1.5rem}.markdown h3{font-size:1.25rem}.markdown h4{font-size:1.125rem}.markdown h5{font-size:1rem}.markdown h6{font-size:.875rem}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a[href]:hover{text-decoration:underline}.markdown a[href]:visited{color:var(--color-visited-link)}.markdown img{max-width:100%;height:auto}.markdown code{direction:ltr;unicode-bidi:embed;padding:.125em .25em;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);overflow-x:auto}.markdown pre:focus{outline-style:auto;outline-color:var(--color-link)}.markdown pre code{padding:0;border:0;background:0 0}.markdown p{word-wrap:break-word}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:var(--border-radius)}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200);text-align:start}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem;word-wrap:break-word}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:0;margin-bottom:1rem}.markdown .highlight{direction:ltr;unicode-bidi:embed;border-radius:var(--border-radius)}.markdown .highlight table tbody{border:1px solid var(--gray-200)}.markdown .highlight table tr pre{border:0}.markdown .highlight table tr td pre code>span{display:flex}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;margin:1rem 0;border:1px solid var(--gray-200);border-radius:var(--border-radius)}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer;list-style:none}.markdown details summary::before{content:"›";display:inline-block;margin-inline-end:.5rem;transition:transform .1s ease-in-out}.markdown details[open] summary{margin-bottom:0}.markdown details[open] summary::before{transform:rotate(90deg)}.markdown figure{margin:1rem 0}.markdown figure figcaption{margin-top:1rem}.markdown-inner>:first-child,.markdown .book-steps>ol>li>:first-child,.markdown figure figcaption>:first-child{margin-top:0}.markdown-inner>:last-child,.markdown .book-steps>ol>li>:last-child,.markdown figure figcaption>:last-child{margin-bottom:0}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-columns{gap:1rem}.markdown .book-columns>div{margin:1rem 0;min-width:13.2rem}.markdown .book-columns>ul{list-style:none;display:flex;padding:0;flex-wrap:wrap;gap:1rem}.markdown .book-columns>ul>li{flex:1 1;min-width:13.2rem}.markdown a.book-btn[href]{display:inline-block;font-size:var(--font-size-smaller);color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:var(--border-radius);cursor:pointer}.markdown a.book-btn[href]:hover{text-decoration:none}.markdown .book-hint.note{border-color:var(--color-accent-note);background-color:var(--color-accent-note-tint)}.markdown .book-hint.tip{border-color:var(--color-accent-tip);background-color:var(--color-accent-tip-tint)}.markdown .book-hint.important{border-color:var(--color-accent-important);background-color:var(--color-accent-important-tint)}.markdown .book-hint.warning{border-color:var(--color-accent-warning);background-color:var(--color-accent-warning-tint)}.markdown .book-hint.caution{border-color:var(--color-accent-caution);background-color:var(--color-accent-caution-tint)}.markdown .book-hint.default{border-color:var(--color-accent-default);background-color:var(--color-accent-default-tint)}.markdown .book-hint.info{border-color:var(--color-accent-info);background-color:var(--color-accent-info-tint)}.markdown .book-hint.success{border-color:var(--color-accent-success);background-color:var(--color-accent-success-tint)}.markdown .book-hint.danger{border-color:var(--color-accent-danger);background-color:var(--color-accent-danger-tint)}.markdown .book-badge{display:inline-block;font-size:var(--font-size-smaller);font-weight:var(--body-font-weight);vertical-align:middle;border-radius:var(--border-radius);border:1px solid var(--accent-color);overflow:hidden;text-wrap:nowrap;color:var(--body-font-color)}.markdown .book-badge.note{--accent-color:var(--color-accent-note)}.markdown .book-badge.tip{--accent-color:var(--color-accent-tip)}.markdown .book-badge.important{--accent-color:var(--color-accent-important)}.markdown .book-badge.warning{--accent-color:var(--color-accent-warning)}.markdown .book-badge.caution{--accent-color:var(--color-accent-caution)}.markdown .book-badge.default{--accent-color:var(--color-accent-default)}.markdown .book-badge.info{--accent-color:var(--color-accent-info)}.markdown .book-badge.success{--accent-color:var(--color-accent-success)}.markdown .book-badge.danger{--accent-color:var(--color-accent-danger)}.markdown .book-badge span{display:inline-block;padding:0 .5rem}.markdown .book-badge span.book-badge-value{color:var(--body-background);background-color:var(--accent-color)}.markdown .book-steps{position:relative}.markdown .book-steps>ol{counter-reset:steps;list-style:none;padding-inline-start:1.25rem;margin-top:2rem}.markdown .book-steps>ol>li::before{content:counter(steps);counter-increment:steps;position:absolute;display:flex;justify-content:center;left:.5rem;height:1.5rem;width:1.5rem;padding:.25rem;border-radius:.5rem;white-space:nowrap;line-height:1rem;color:var(--body-background);background:var(--gray-500);outline:.25rem solid var(--body-background)}.markdown .book-steps>ol>li{border-inline-start:1px solid var(--gray-500);padding-inline-start:3rem;padding-bottom:2rem}.markdown .book-steps>ol>li:last-child{border:0}.markdown .book-card{display:block;overflow:hidden;height:100%;border-radius:var(--border-radius);border:1px solid var(--gray-200)}.markdown .book-card>a{display:block;height:100%}.markdown .book-card>a[href],.markdown .book-card>a[href]:visited{color:var(--body-font-color)}.markdown .book-card>a[href]:hover{text-decoration:none;background:var(--gray-100)}.markdown .book-card>a>img,.markdown .book-card>img{width:100%;display:block;aspect-ratio:4/3;object-fit:cover}.markdown .book-card .markdown-inner,.markdown .book-card figure figcaption,.markdown figure .book-card figcaption,.markdown .book-card .book-steps>ol>li{padding:1rem}.markdown .book-image input+img{cursor:zoom-in;transition:transform .2s ease-in-out}.markdown .book-image input:checked+img{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--body-background);object-fit:contain;width:100%;height:100%;z-index:1;cursor:zoom-out;padding:1rem}.markdown .book-asciinema{margin:1rem 0}.markdown .book-hero{min-height:24rem;align-content:center}.markdown .book-hero h1{font-size:3em}.markdown .book-codeblock-filename{background:var(--gray-100);border:1px solid var(--gray-200);border-bottom:0;font-size:var(--font-size-smaller);margin-top:1rem;padding:.25rem .5rem;border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}.markdown .book-codeblock-filename a{color:var(--body-font-color)}.markdown .book-codeblock-filename+.highlight pre{margin-top:0;border-start-start-radius:0;border-start-end-radius:0}:root{--body-background:white;--body-background-tint:none;--body-font-color:black;--color-link:#0055bb;--color-visited-link:#5500bb;--icon-filter:none;--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-accent-default:#64748b;--color-accent-default-tint:rgba(100, 116, 139, 0.1);--color-accent-note:#4486dd;--color-accent-note-tint:rgba(68, 134, 221, 0.1);--color-accent-tip:#3bad3b;--color-accent-tip-tint:rgba(59, 173, 59, 0.1);--color-accent-important:#8144dd;--color-accent-important-tint:rgba(129, 68, 221, 0.1);--color-accent-warning:#f59e42;--color-accent-warning-tint:rgba(245, 158, 66, 0.1);--color-accent-caution:#d84747;--color-accent-caution-tint:rgba(216, 71, 71, 0.1);--color-accent-info:#4486dd;--color-accent-info-tint:rgba(68, 134, 221, 0.1);--color-accent-success:#3bad3b;--color-accent-success-tint:rgba(59, 173, 59, 0.1);--color-accent-danger:#d84747;--color-accent-danger-tint:rgba(216, 71, 71, 0.1)} \ No newline at end of file diff --git a/docs/public/categories/index.html b/docs/public/categories/index.html new file mode 100644 index 0000000..88cde22 --- /dev/null +++ b/docs/public/categories/index.html @@ -0,0 +1,3 @@ +Categories | dhamps-vdb Documentation + +
    \ No newline at end of file diff --git a/docs/public/categories/index.xml b/docs/public/categories/index.xml new file mode 100644 index 0000000..609fa75 --- /dev/null +++ b/docs/public/categories/index.xml @@ -0,0 +1 @@ +Categories on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/categories/Recent content in Categories on dhamps-vdb DocumentationHugoen-us \ No newline at end of file diff --git a/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json b/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js b/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js new file mode 100644 index 0000000..0241b04 --- /dev/null +++ b/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js @@ -0,0 +1 @@ +"use strict";(function(){const o="/dhamps-vdb/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/docs/public/favicon.png b/docs/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..6f545a570a80bd385cfdc27af249c7babe647e31 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj_dQ)4Ln;{Ggf?hJij@#(b6^dom#@~z%SdyL~kcG zYv&2dTggrTEH&wQ;ZCv66P2$DAJ6*q?T%^Em(HugMFiE%XK3moU)_^$#b% z5a#;KXjuDfy+i)YhIdamCaKwEiDx}N^}EimL-~4?+Jd!`8cCgN>(m;Y1P-=tmH4z) ulvO8j-G87@|Nl?rlH~?^l?~)oW` \ No newline at end of file diff --git a/docs/public/fuse.min.js b/docs/public/fuse.min.js new file mode 100644 index 0000000..0d509f3 --- /dev/null +++ b/docs/public/fuse.min.js @@ -0,0 +1,9 @@ +/** + * Fuse.js v7.1.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2025 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?O.getFn:n,u=t.fieldNormWeight,o=void 0===u?O.fieldNormWeight:u;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(j).length;if(n.has(i))return n.get(i);var u=1/Math.pow(i,.5*e),o=parseFloat(Math.round(u*r)/r);return n.set(i,o),o},clear:function(){n.clear()}}}(o,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return u(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,A(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();A(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?O.getFn:r,u=n.fieldNormWeight,o=void 0===u?O.fieldNormWeight:u,c=new I({getFn:i,fieldNormWeight:o});return c.setKeys(e.map(w)),c.setSources(t),c.create(),c}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,u=void 0===i?0:i,o=t.expectedLocation,c=void 0===o?0:o,a=t.distance,s=void 0===a?O.distance:a,h=t.ignoreLocation,l=void 0===h?O.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(c-u);return s?f+d/s:d?1:f}var N=32;function P(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,u=void 0===i?O.location:i,o=r.distance,c=void 0===o?O.distance:o,a=r.threshold,s=void 0===a?O.threshold:a,h=r.findAllMatches,l=void 0===h?O.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?O.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?O.includeMatches:v,y=r.ignoreLocation,p=void 0===y?O.ignoreLocation:y;if(t.length>N)throw new Error("Pattern length exceeds max of ".concat(N,"."));for(var A,m=t.length,C=e.length,k=Math.max(0,Math.min(u,C)),E=s,F=k,M=d>1||g,b=M?Array(C):[];(A=e.indexOf(t,F))>-1;){var D=R(t,{currentLocation:A,expectedLocation:k,distance:c,ignoreLocation:p});if(E=Math.min(D,E),F=A+m,M)for(var B=0;B=$;z-=1){var T=z-1,K=n[e.charAt(T)];if(M&&(b[T]=+!!K),W[z]=(W[z+1]<<1|1)&K,_&&(W[z]|=(x[z+1]|x[z])<<1|1|x[z+1]),W[z]&L&&(w=R(t,{errors:_,currentLocation:T,expectedLocation:k,distance:c,ignoreLocation:p}))<=E){if(E=w,(F=T)<=k)break;$=Math.max(1,2*k-F)}}if(R(t,{errors:_+1,currentLocation:k,expectedLocation:k,distance:c,ignoreLocation:p})>E)break;x=W}var q={isMatch:F>=0,score:Math.max(.001,w)};if(M){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:O.minMatchCharLength,n=[],r=-1,i=-1,u=0,o=e.length;u=t&&n.push([r,i]),r=-1)}return e[u-1]&&u-r>=t&&n.push([r,u-1]),n}(b,d);J.length?g&&(q.indices=J):q.isMatch=!1}return q}function W(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},u=i.location,o=void 0===u?O.location:u,c=i.threshold,a=void 0===c?O.threshold:c,s=i.distance,h=void 0===s?O.distance:s,l=i.includeMatches,f=void 0===l?O.includeMatches:l,d=i.findAllMatches,v=void 0===d?O.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?O.minMatchCharLength:g,p=i.isCaseSensitive,A=void 0===p?O.isCaseSensitive:p,m=i.ignoreDiacritics,C=void 0===m?O.ignoreDiacritics:m,k=i.ignoreLocation,E=void 0===k?O.ignoreLocation:k;if(r(this,e),this.options={location:o,threshold:a,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:A,ignoreDiacritics:C,ignoreLocation:E},t=A?t:t.toLowerCase(),t=C?z(t):t,this.pattern=t,this.chunks=[],this.pattern.length){var F=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},M=this.pattern.length;if(M>N){for(var b=0,D=M%N,B=M-D;b1&&void 0!==arguments[1]?arguments[1]:{},o=u.location,c=void 0===o?O.location:o,a=u.threshold,s=void 0===a?O.threshold:a,h=u.distance,l=void 0===h?O.distance:h,f=u.includeMatches,d=void 0===f?O.includeMatches:f,v=u.findAllMatches,g=void 0===v?O.findAllMatches:v,y=u.minMatchCharLength,p=void 0===y?O.minMatchCharLength:y,A=u.isCaseSensitive,m=void 0===A?O.isCaseSensitive:A,C=u.ignoreDiacritics,k=void 0===C?O.ignoreDiacritics:C,E=u.ignoreLocation,F=void 0===E?O.ignoreLocation:E;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:c,threshold:s,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:m,ignoreDiacritics:k,ignoreLocation:F}),i}return u(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),Y=function(e){c(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return u(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var u=!!r.length;return{isMatch:u,score:u?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Z=[J,Y,V,G,Q,H,U,X],ee=Z.length,te=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,ne=new Set([X.type,Y.type]),re=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,u=void 0===i?O.isCaseSensitive:i,o=n.ignoreDiacritics,c=void 0===o?O.ignoreDiacritics:o,a=n.includeMatches,s=void 0===a?O.includeMatches:a,h=n.minMatchCharLength,l=void 0===h?O.minMatchCharLength:h,f=n.ignoreLocation,d=void 0===f?O.ignoreLocation:f,v=n.findAllMatches,g=void 0===v?O.findAllMatches:v,y=n.location,p=void 0===y?O.location:y,A=n.threshold,m=void 0===A?O.threshold:A,C=n.distance,k=void 0===C?O.distance:C;r(this,e),this.query=null,this.options={isCaseSensitive:u,ignoreDiacritics:c,includeMatches:s,minMatchCharLength:l,findAllMatches:g,ignoreLocation:d,location:p,threshold:m,distance:k},t=u?t:t.toLowerCase(),t=c?z(t):t,this.pattern=t,this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(te).filter((function(e){return e&&!!e.trim()})),r=[],i=0,u=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return he(e)||(e=le(e)),function e(n){var i=Object.keys(n),u=function(e){return!!e[ae]}(n);if(!u&&i.length>1&&!he(n))return e(le(n));if(function(e){return!g(e)&&k(e)&&!he(e)}(n)){var o=u?n[ae]:i[0],c=u?n[se]:n[o];if(!A(c))throw new Error(function(e){return"Invalid value for key ".concat(e)}(o));var a={keyId:L(o),pattern:c};return r&&(a.searcher=ue(c,t)),a}var s={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){s.children.push(e(t))}))})),s}(e)}function de(e,t){var n=e.matches;t.matches=[],E(n)&&n.forEach((function(e){if(E(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}var ge=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},u=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},O),i),this.options.useExtendedSearch,this._keyStore=new x(this.options.keys),this.setCollection(n,u)}return u(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof I))throw new Error("Incorrect 'index' type");this._myIndex=t||$(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){E(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,u=r.includeScore,o=r.shouldSort,c=r.sortFn,a=r.ignoreFieldNorm,s=A(e)?A(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?O.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,u=e.score,o=n?n.weight:null;t*=Math.pow(0===u&&o?Number.EPSILON:u,(o||1)*(r?1:i))})),e.score=t}))}(s,{ignoreFieldNorm:a}),o&&s.sort(c),m(n)&&n>-1&&(s=s.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?O.includeMatches:r,u=n.includeScore,o=void 0===u?O.includeScore:u,c=[];return i&&c.push(de),o&&c.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return c.length&&c.forEach((function(t){t(e,r)})),r}))}(s,this._docs,{includeMatches:i,includeScore:u})}},{key:"_searchStringList",value:function(e){var t=ue(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,u=e.n;if(E(n)){var o=t.searchIn(n),c=o.isMatch,a=o.score,s=o.indices;c&&r.push({item:n,idx:i,matches:[{score:a,value:n,norm:u,indices:s}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=fe(e,this.options),r=function e(n,r,i){if(!n.children){var u=n.keyId,o=n.searcher,c=t._findMatches({key:t._keyStore.get(u),value:t._myIndex.getValueForItemAtKeyId(r,u),searcher:o});return c&&c.length?[{idx:i,item:r,matches:c}]:[]}for(var a=[],s=0,h=n.children.length;s1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?O.getFn:n,i=t.fieldNormWeight,u=void 0===i?O.fieldNormWeight:i,o=e.keys,c=e.records,a=new I({getFn:r,fieldNormWeight:u});return a.setKeys(o),a.setIndexRecords(c),a},ge.config=O,function(){ie.push.apply(ie,arguments)}(re),ge},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); \ No newline at end of file diff --git a/docs/public/icons/menu.svg b/docs/public/icons/menu.svg new file mode 100644 index 0000000..a121a2a --- /dev/null +++ b/docs/public/icons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/index.html b/docs/public/index.html new file mode 100644 index 0000000..71df4c0 --- /dev/null +++ b/docs/public/index.html @@ -0,0 +1,3 @@ +dhamps-vdb Documentation | dhamps-vdb Documentation + +
    \ No newline at end of file diff --git a/docs/public/index.xml b/docs/public/index.xml new file mode 100644 index 0000000..58d695d --- /dev/null +++ b/docs/public/index.xml @@ -0,0 +1 @@ +dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/Recent content on dhamps-vdb DocumentationHugoen-us \ No newline at end of file diff --git a/docs/public/katex/auto-render.min.js b/docs/public/katex/auto-render.min.js new file mode 100644 index 0000000..32a7dd8 --- /dev/null +++ b/docs/public/katex/auto-render.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={757:function(t){t.exports=e}},n={};function r(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o={};r.d(o,{default:function(){return p}});var i=r(757),a=r.n(i);const l=function(e,t,n){let r=n,o=0;const i=e.length;for(;re.left.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"))).join("|")+")");for(;n=e.search(o),-1!==n;){n>0&&(r.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));const o=t.findIndex((t=>e.startsWith(t.left)));if(n=l(t[o].right,e,t[o].left.length),-1===n)break;const i=e.slice(0,n+t[o].right.length),a=s.test(i)?i:e.slice(t[o].left.length,n);r.push({type:"math",data:a,rawData:i,display:t[o].display}),e=e.slice(n+t[o].right.length)}return""!==e&&r.push({type:"text",data:e}),r};const c=function(e,t){const n=d(e,t.delimiters);if(1===n.length&&"text"===n[0].type)return null;const r=document.createDocumentFragment();for(let e=0;e-1===e.indexOf(" "+t+" ")))&&f(r,t)}}};var p=function(e,t){if(!e)throw new Error("No element provided to render");const n={};for(const e in t)t.hasOwnProperty(e)&&(n[e]=t[e]);n.delimiters=n.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\begin{equation}",right:"\\end{equation}",display:!0},{left:"\\begin{align}",right:"\\end{align}",display:!0},{left:"\\begin{alignat}",right:"\\end{alignat}",display:!0},{left:"\\begin{gather}",right:"\\end{gather}",display:!0},{left:"\\begin{CD}",right:"\\end{CD}",display:!0},{left:"\\[",right:"\\]",display:!0}],n.ignoredTags=n.ignoredTags||["script","noscript","style","textarea","pre","code","option"],n.ignoredClasses=n.ignoredClasses||[],n.errorCallback=n.errorCallback||console.error,n.macros=n.macros||{},f(e,n)};return o=o.default}()})); \ No newline at end of file diff --git a/docs/public/katex/fonts/KaTeX_AMS-Regular.ttf b/docs/public/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c6f9a5e7c03f9e64e9c7b4773a8e37ade8eaf406 GIT binary patch literal 63632 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 b/docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0acaaff03d4bb7606de02a827aeee338e5a86910 GIT binary patch literal 28076 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 G2<`xUL{2yW literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f522294ff0f3f8c52dfdaef7ebfaa06ebfcfaabf GIT binary patch literal 12344 zcmb_?3v^t^dEU(2_q}`X-S->2clYit9{a#+u?v8Bae*aBf*?T>BC(_>Vo87x@gWiv zB~r2;wk%sBty+?8#ZGJ=9ow-Q`_#E0qhndMPb9}_?f5ip+6;lzcL=Z=;B_oE2KhhY-e$>yaC(C$X4uMbM` zQm>MS1zFMX`hAqy-+vKH_xrEzVcy$P(F+hYh8HY(t{&^aB~u& z-tR*HsS9hX7glQj0{DAop#BOXXaLIZk^pEcAT;P1^mGn-%z>9y1_nsr|NMLauLDnF z;}4lZ@+W93T0r8fyXq4mGLWy9D}w`}U~q7tT7joJI8YfXS1Zsc1pJ|32!5+j3Gjmb znCZ@({S29%w8c#4vboM7AT<&ggyD&#Dl?=zAhFq9zj59p3WSJ*AupqHs>XShwC={N zt2-9(`qLUKX*|JCJ*ArZy;ZY9dRShm-6I55?2_Ni$1A=-oVd^Y>5tPyU`4m#e(npO z+dV$42)tW^dPw8>FrOan^$`a9%HGF@{%*&=8V`Kr871wGU9J; zN#cP#PE+NaXK1Jlnxq}QoKLDwwZ%{ws+OVE9snZ-DF}XE@YBH*v4GzmBZPuBX=Blu zvylr0DVomwIWx`Uel@8Ty2SZdLI{k7{DXrYPhU<8-BT}gdr~el*q^@y?D3mk>zZ% zQs6o7{*h#A`h^^|%hU2eS`jWU3!YvZRR0EmtNq5&Qd%>pU{55RTi9B3V^ zTJUV50&tW83JO`kZ^Ki;Ki2&NpV?mP-R0>#GW5|pFOlFbB6OTig?xd|D`!^^UzqnN zz~j9Lkz3@eXb9~9kDnTjy1?Uo)W(&{P^D6(Mh$M75{&IAF-a=E@=(R>Gff@@roUVc zq_<5j41$KXb+eL;F$r2{IugO=`SNkexc=-{l1uZf;Pyup@o0o$2%g%ZViqe!a-aK? z530JkTgzTqeyM}Q|54;I%ai&k0sE2@SJU0sPn`^Lm_Q6@K9TkRHD)jgv1SheXNaT@ z?kD=u?|&!F^zMEs9MGd+iv)Og8EjDpTZ~I!3!iO*N_AkO_f4;}aUfaR=xPv|+tn_)@g1G;Xq2{|L!+N5Si!Wrf`SHCKdBE>>4}N~W zek@Q}!}oX13>2!n1>CJ_v8)zR1X*~Mav#b~r!R|p3tHg+G$VZyVL#}iX{ zYcf$3@RTS>N{V5XjLh-r#c#Z>^u!2gT-bP)93*d`1EBFpfLhLp3F=s2yH;x9%^WC9 z)6pO(<0R-IQ1iB;G}dVHrY>wZ+o`*4Z(ewQ`)n>fnr0PlIIKl`O7)A;&bcu+m?9%8 zTV}B%bc z(a-E!>kya@g`%lhVM1VPF1;`cZMoeUJz_AupMHE zPD6bj@Ea-v4FQb{rOIeX5DimO2qcS_4)<$EKa&$m8I>h*zb_GHGo)sA<~1q7NP;Ihxi_t;o~;)b zad_vqTzV8MO!yO@``C&Ua4{Lqr^Gm-N&cQPap&a=FET6+A6~8s?ue^;-xDE%F~<@) zCQBH*uOqzi7G$pvwc=vR4@hOHTFyT0ge>*?cH)Jghi?0+0-(IB#ul@X0Or zk-NbTBSXOmA^<5FxCfs1bpL3&S66j2-TVwK$m# z>q?AO1Zl1-%wk?p({K#%4UJ#E)ODaJfsgcVJj-kc&9{M%gfaCIM|9h|PV(9edE3TR zZR!uLlt!zSYIRdf$P9K9nf0H)ED>=i=+lMgExI zp0L{I4-T4JTPWqCxg5eCPHUj)W&($Fk%NrU+6F3v^k~9k1vU`g70dS}usGxwWFimd zGpfq^V{YfTfj_6n*zMw(!Wa7jYRFj5Dz2U_5^wmttnY~hl_~djEpXV#e`~Ig>_{cZ z?-DIJeDc)GAKpzo35mn;r+)qMV|xWjYac8wOOmeYSUKJ254bY3D_`_-rr`?}W>@Q`FYngE*{u$z4xu-OGRpUl{Kp|x+d3@(Hq)rA}_K7oiLPlC8$I-tK6J#{;`Yw0ij7UQHFnST>>&_x)pfC=oUrm7*@Y z2fTVRlMR##srm0`J% z&S1$Mm9%8$;NIU}+FCpy;X%#giiKUCAm|w1_(S$0`8{+NbiBv$Yuk*@ZUut-;IHKk zkm;y>H|t<^=kN^~4H8}zG`=$isNp;97Rm>HK*6A!Lnzonq=G;1<2jZ~mo+`Wk=?#W z{~D4v=i*eM$g?sp2BTU)4Q4wyIjXC0bP-d8LH)y&9HS2o3n z(JD_8qQG&!PM2ubw?=r`OMaJS7$x~HZ}jIz<^xaRjtpi)UVW-~>wi5x>s48|OZ6&> zkH@;&m52#3?z7*Lcs?qBdw=F23u$L&zVGGg@TWg@eX=Uy4qX%q2?%N)bD{67-!Nn! zWW~RLTg(rbfW3G2An=n=+DY{4zAhkEbvSOD{XSn`)rOf%0*-~$)e1NzaRg6pCN+!l~-mYo|Ql8KW znbK7%b(L}=;Zmamy^(=**jscts%Xc4`saqIg#{+?wO2pckoG+C^p`#yE=yR}@(GFY zYLZla@{j(#3R#(8qQ`mf&gR)Gj|4E2{K_lO7sKF3qZ@BC62!_3_z~nw$RUnmpcnNK z+xCvtTh2s%rR`6EhMh>-AlP9;xyiw$L*cY_ai%^}oZN<8z1y$H0xa)gq>g>(UHHJj zw&BW_l~7>Eu0Yt6PfAKMp;gU;Ffd88OC&>5npw9?B0p4*&hiz*h zXdeQp>FCqi^Ju8sx^(8u_TDe>RClj$f(+&C0HN%g=X8?D=kf{i@OX|$L*dB8=l29z z66=aAUXJ@RL7Xz?mJ&?vMLzwpI{m#=m7PoZw3)=M7jzD>W;bF^;doe$= zC7bF?4J-fcmzUh`D8_JQNMRq=gXSbceKA~`*@jMc{*TW3^e`*JN55MbBt)EM{KQFkbp?>%vEe_HkG{qk1wJw-SmVO4S^I^D%bFJIVxT;t5GFBtOKn`4C#&xBK+peChVoYX%r zGoqX|cowb!eu=@@rT8ODl||d`Z!>lB6?6))=vD5vJM8#(-OXqyJE~LdT03T2aR}V> z&;)^-Pj%BL((OnFc<7eu^}%Zj3M~9OF5$VlZ(!fz!Bg2HqfVsq!9l`!V%?r_!kcuv zjG{MDKN9Ou*j&<+N=7_>H;Ls!tdH5+aFO)TOCdrM%R$cBQk5%F?w!t3J?z)?NPI-q zw@;)aYKY|`Q_Ya6yY((sQBylYJeCGK7Iw!xjHX1q^g6L~RP>dCCf4-7{hw8Z?yXD| zXW&SBrw4gqr~DB4Hd+MK7CUc8KRAbNfBIenT)~NWidj2w+8*VgrxTuLNc&X1r%t$nyC{3!`mU6_iV_z&YUdS_w z#03>bafc$|+P+BAD@>Ks-fWTgdBrZXw3Vl~ru4=)nXTmCpepF?Yn=+)=U^cnV8F06 z6l@j17r+rH2$1*Squl|@4U)g?i+bGdE%DIFV;7@Y-;ko}V#ZHKM_3|}}o zD(bQ1T2=Wu`D$9y{Jt~~xAR+DkIdz~aG}!nZ5Q8uON28Y%XRrUK~3_UJCiHa1e(z{ zezEbN$vR{-dc!Mowr5kh+Uc0u#zvm{vJE&yI29ir|Lr$!;J7fV?6iYwowrka>ns@Y zOplHY#dLFAm(5Hlz5V87Q0-vll3!v4UUUzR2Vvim6S|u_;`at4y$pZxOntLOvLEzPe>BsPzSx$0Lxy`r%y;H_KU*}sL7jD#Ds1qDT`Na|Ja!RDA5C_9 zbT_%`PIv9UwdbUy20ce_PARTLo`eGf5@Bb`O8lv>EiEm`B*JU?uZ@5IU{U65Nq?V} zLDGXD>Db+pRwo#08Y&40?3^x~!$fNXwPkN*X6k%S1i|5gK+SPO7+oTuMSn*#AN9iP z0ZHM{HMYXxiYxkE3>U2Hm`PMG#n@!b70`L!?JASV8|TA1j~Q{q%P{P(|0D>nNk!G8 zCPuq-a@A{GT3B280Ks55>4o2TKxBB4b9eB<+>igemrc)q;i&5F$PN@G!iN{V?l0ZC z^$A_pxb1)W!<{^T>p$H3A2A%#y^*6=?;E~v5ng9wR7QyD1Po3C23tg$PukaxmeO#I z2-(+8z=E2rb&LX&Iq!&VPp%Hw4s1IqY+O`rYEyb&4+fkUHJj&>A+Rm@vWaKXT|VqO zHk$ASWkI6X$Ks1F64AGGL}EU7YWuShQRdW6PE2ML5i6;IodG=wR~on}W8v}hB8f91 zBPe~LNW43m8Go)QigKJNgq-MvlRMKr;P!OIAD06>A3qXfRfBc8yHl}5I2hlusB`%6 zRqwEvB!ZOnX9f4pIhmIxy7un~uxf^9c-a$6#d6)zXzzg-eyTbFF9!gv4 zQ4Tr|Ts7@ONEKehzS^tBwlb=jvEs+Ms3;zomg^R7#= zpguCFMSt^pxUW~qh*yo(uomf_o{wiuS?EZ_d>$$NWL>?pa72ZdEdlI}oI4qZSGhdnj)8CS9D_rT9AmL8GKFqmN`P&_HQcqwM`T5I z!8a}RyQL(02yXQBhkl09bMP6}XfOToww~*_jIZNgk^9IGnR}SG*^}%KxF+`l{xbhd z;i&M(;$iXcq&4Zg@~r$>C850PGF)GGechfP*7(-PfAWc=`qB=a z7vUZR-$%9NKnCA{!%DS);4}YR#AlcGZZ1;LuK+=nEQ{x zcVI0lGZWajhz_yq8*knE5qr_r;eFaS+1HH@`8^h=j=>2g6p^x9kP!8~01brZZjRbA;!#82H?nf-Lzq4zh zWS~Rn<&6!Se=DUnezNg<8;{$((1?(Q3WkO5S*kY-W9~Ji?VYpu{fCyUa?I*#ET1s0 z-LqtoZ1Wo;OnCgbc`TMnS*T&5X>;ZV%rd=PD_Xc<8OtY%7Acr1GgY*hg0XUw@dr?C z+VV{s%geQO;-9XqXPIe>OfOzBESCwybaTaG7p~kOgupabYBipstv9p)uEh-?&Dsqg z_CcR%p@pT@#*HARoJET*SWMmuOfS*(tl;!?iy>yL7}gsL7MnYCqYJCk_2YGmuP>!6 zCfnF|cnO$e*Om-xVF8+^8ZpBfrqpnwVXQmcAW;`IwQ7ddNBjFI=Nk)42B2}RX;|{Y z(lWFdv`?l~g;JH}*m9%MhyhxbYx=l__AOaxjxwj99-FfgluFDsUvs15l;brH9cwgJ znhgu*8;zC*4PyoLF>8&Y#TAUYVX@gJ=p;-pELnnCvqZB77JwnkMT@uL1|*D?b>Ude zpq*6Rm?J*@1it!li|a{2=d^LnxCU#j_i(qkhe7Qlr{nqZl=aWyC1E^EvSE1uwxZ=N%q=dhvnw-=jHRxcSBjRe zFt>MUZoktQOF_HOZub|~k$3u@rFE|tOxUbho;(dXaIM<9PCwl6Vc{Uyg2^r{tkKWUg>{yevBEk>%Xnd(r)5WBU7%&6urAUvSy-27nJ)ku4*nLu z3`ml_Z$ zmmn!pD-PZP&wKH}3z#8W@*$YbnWz5u(*$Inca@g5qu}qrRt5jLGGPv{mvMmVS^+#j zfp;CV48hVIE?U(>DKu8JhTo4B9Q!!1kAR6#Fl&^IS(*|6+8x)f&6=~2f|g+8gRBcX z(l8vL{DAN%IrCY(S!;6})-ug0 zQ+to7CL zLNM^z%A~i~0%sX(V_|>1rn`alth=1Snmd%#6AoCZk$@XeC`Ym%U(*w>sRc@Pj3i3yZ zqPWcpO)o9PU{5v18m09eQW0h_n(!o}6mG)t zpHhc_a@r14K1|#0rF=GZg!0+ceU#6pj?y*jz_v`+q(qahNr_{0O-dZ6Jlla-p*)mW zr96~4L3t=~(w1ums8hCFlsaw8MXCF3xhQqUmWxtnZMi6Q&X$W(=WV$t^#EWzwrRi% zcFmfCj*AYt705LTI%TtJP`dHHyXWW_cQHP`qA8<&@@EGt;Y|i(%U9;zV!XYX9lMYGQKL{fyocTWFkd)ymholT2 z2Hwfd`JT3G_Iw|4NXq_EhotP!z{p8wzGoehGF)>=%5c4KL$Ob`79YF85~dE9CfLgw zwY(*+T1;l)N_#^uBDes4cOM)l@jrvT&bjhkSVuw)Opbaeanl7a2^`8xY)Y)X&P+kK z0z_Bfa@rlSni+v7u=9!z^3Xf*sf2iK=X9came}>h`oA7M`yd`Ltz$&3NdOKz% zpuYfr4vkS7Y7R}{KWD$wq8YRg{ZWf%(E!f0Xb#ozffmi*(XNs;{OMM^hRUprrqKiF z0=f#To`(PWIfWiX2I@k`Q8$zWa69jV|0XQjR6o!Le5<*NF4?^2p|&45PeaRjC|6Md zT6WlU3BCW!{qSzHJ@YV(oP*VyFxo&{VYVh9w2IDwWOG0-0=)$PmoW|WS$p+0pf13O z)4;nAdQZatk)DONHM9*hIuCl#at+#7Va5SevZWuj*LlDBitm{5{Uvzkhy$?dnvD~c z#X$YAem~j*)PwMx068y1`G74ym6c-tkj*s=oP&V=Kh7=``TtkT(6z?U!}e1GgqyJb zDRe)SS72=ivk8#k|DOf#Uhz!J&ds~5eCNsqSo>kHES1Z!ZE?xQ^C9?LftI#~4YV7i zK4)9_{cS{jQU*_=K6B}=S@wh0Ct$UQVYW4UHiv_H8ujb*!0)Vl8EER4YcQTlM}2EQ z`1~#?_kcfA-aF;nb=M5kO7HF&RJPla-My{>QauEJr)~c}2A_1*+xRr?6}O_jP*Pit z!dx_t9|U z005=~06;-9W_tFqFmid1 zCEkAbf%_lOENs2Z0RW&l0Dztd0N~rN@?j8Jni-h_0GR*sbNz#fyO@pTyZEl{zjM-e ze1shUQCQl!dcJG6@7(qzzt>s?f4k*&nPWh?sJ-EAMtJ!^qcT_DEz7&q-}=@992IysHbwK9XSu%lm>Z)bnS7btW3{tKE9b zP0KlHP9y0(+)N8#um}x~QZoR$04R*t&M3YqkO!VXxCA+d%$$6qMJb>>{SY{(>r=RP z(tOhVig^1CI}w7uSp4u5yQ1+%yy*7yroUG{l`FSG^!nF#kQ$<=NVh=ILZ1yeSEyUC zK6%nIaJq@s)8s{gb8}!oAY&=6O8R)DMFOv^N*?gkrT3T{L-u>|Vbs~-)2)H?V(hss z9hy>m&F9U|4t3L59XIy95V2zWn<|98BmR1C3HeS^b&RUa2A^#wESV6*ZGLAkf*hx`DveDJP z60N4r$c$Dh(3G^92X-Y0Lac`u0`tk~{o2=3qqno|?oLjENvkw&vc_}?`0x5gCi`*W zQSt;g6WU2(Ml(+rEFV>>Jn zyk}~1?Yr6TJCmpNeEv5~^q+_wLPamxeBCNBR~3o7y(lPDhH`=i)eQLNMAR&3D2Z*z z4k1gn9_?9;^5GQ6r1JTbU2jBd1ntyAhyalzFs1ZiVO6iZV_QaWnvq!#{PA+ik5UvNzWMCSUmHT6iS@3BWIs=G?slv)@ z`vN2b=;zXkS%*75T>>lfUvH&+=a*kNrZhgN#em&Ba;zJrn=^NS66vIw&Aep>>8ZJ%>*=EXTl*K*X|C(ce0 z6y)Y~rq-H0C+jv5>KK_gs()-S(2U4(RD?=sD5tFk;}XV5C4QuV2k-A2ZB;9sFJe#} zF%aox535fxgVn8TUI7!zX(-A>n9j;&Ay%p%RU6i9Rl@Y>Tj$H}QjK75T6B8vf^OJO zH3&s4Vd{}S*x`I<7hx*rkX+k>N|LqEeLB^{w?nWInP$!hk2C6=~guEDOJU=A0a zxmULlgF5xWBmG5XT-u6pK2VT9P2G$Vr8kRsZ$lq%{Nl&x#P0)kZ$&IcVV9#?C!7HZ zDztPNys!}UU`O5Xh0W&X#q)Y4=|E(k%ovgu%-~9bJqikB;hXV(td6cH=+q)>LpZ%^ zXzRI=x->&!n()JO8+oM=6X_@@I~(bF?+e# z?G*vtsZqQ^2KJpDhV^7xH7ubZPYtEX^BZjKg6;#dON~wXFX&_xzelG0#=SPvmD5=V zXh7JTbS*_1==S~?eLejC+IX8#U7foV=6?Ax_*F&r1U=0#|s{<&3^Q=s-I3xZW;R0j+>=iy**JX7A58)in&t-;w35|!{`pEdu7bp>MhJsZ zb$^Y<85K-&qU1;R_~fjRz!?|e-@rYuQqL_aLwaf$EVmffa+P?>Q$A}os7hq9K<}ZL z<8G1g#XG7LdZ#W+&zK1&ZMJu!uP@q%Vhk{-_>(dG>nL+reW-xsvh=8llAvpM4fm22 z^HpX3RC%@r-Y0y7+^<%>Or+%J8388ous;Rq(4SH`g_~W~;qEb?`8gV0isoDe`Pyp$ z(v5L+ucJ7n4MlH|48N3r6n#lFGhXLv^PQVzL_7!|22F)D?GfYy${NMk`eLgodTh`QWXw^2`@AIm zStTd=hNU0voqVAj+qf{bqq`j;wxk;SK=9bkT*99^OJrnHWCx8ab@ZWucodP7TaIf{ z#PCtn(ab~zjMX~Xume5C4j+QwU0cZo^2mAk8x+p{ft5}7gBDpXri$&#$N)Zh@hBV= z6EgnpCG%FE(4cXjlPzs=ni((u3hm)+WXvs`ydy(@CUn#o!(>Dhr02mT^yhxZ7Ds-; zx|uNE&#!=v@b)(MKLx1zY^F6bP2|y3z$!g?@fDhz+=uH>@laIaVUoefG+g(%ABEgk zu@yqzbweSoqm2t-Mr$a%hYt?Es_C zhX&TS2WV-(9*P9zBvy3$8|j7PY@l9`wEglj$t3?RTo(t2+Qwxqa9+#bb$(D>%GdWT z4ufZYoogmf==bWH$7;TT%(XF_ozuwT<|*T2Z^zVct+t)ovIflVtwyW>r>z&%Ur1>9 zqTGDU9m5qQ>;*ADe|I!BINrj@)YoVk6Cq$N?Zbmm_<9ohf6sPqVc&|eEiaeAj%mzU zeV4R*vYaS+fYCZ8p=Z}YgE|Z6MdbJL=Hrp{b$IbWKB!TU>Wc9uL zo|%>BWlAI&pDJEt{izpTHum_Qt70Fa|DMbR1x6#Fs%Lrxe-! z{7k73^L|PxFjUGbzDNKT+dbMvUCrMy@>Ls7(QYxMmfX^JZb9BJ8~4}>o63gi#O4EO zw98vIb#{h}45)^_ua8msF(jH}QwxK715lsOKAl_tI@{Sqyr)do<+lj*?Jl`NWYZD) zI?${geuIcGTURi06{5xu@Wh?0 zcqM`Yj|c0l;plr_AY+M@LsCTcHcJN|a}1dY%l&rPO(6?Sdd3Kq4@eX}XL@%%!ANm7 z85>SOQK9q>3;2H2`9ZTGtUayZ;2Q62Q~RX@XDXsA%sXD~Ec=MN^XHP4ENkc}fxSrS z`Spetvj85ehMcvoq-ylJ?dYs0fgr4w?k5rsRAItjD(h5$(>ztuwzx%>d-CxFjezba%ty(`U$1lv=1-Fs z-y*O(oNfedHLSww@i%ndcDa_5TSBTeC7*Se@fKSY?S6?bjK|WMHq~|iJ>->&Hz~5e z%B0L)%ywcq3=OSfrDp7h=SFKgXdjSKm}#^9#BubCj=3rxI|4B|L#CO1E!u~aGwq(< z&f*OBfzjfDT?dcCmJ-q9?VzW4)L2p_*=v_qt{$A}H)|Xg%{aa=cfhFBTAtLvq4GUg z0JYwqKq#uXpzv6ZMP$ohs$sD~G9=p$b!{H_GfBSR!D6TJ*!7?i0F2CD67213PTi^0 zs`6;O`I&d5#0Qp6)T~IR)L+=v&o&fr^qPV;aKD{%*kq86LbyGnLcJ2zjTL-!lZrpX zhGf#DElv17IVwP&*k5RHj^$D3vh1I>vhK}i0*_}j1^L#I&sw-Yxcpar1^mBbumV1IO55}BC6Ga^(?jtrRG?{QIM^@N(rR00BKtw@QG63JP7ZJeL(0wXVVaAwmv*;<^ z84`Yb2&o}9!S$tj%9xTdZ!=^N?e&NL+@4|Ra5-}cl*p6A=vpd9jI&grPd6bio*0qw04p~Uy+jjx zLakFSS_nm`=6m&4`SRstVEF}{lej!Wldh^YD|=$u=VCkus}4idJ(jthoOs}(5x=0} z4i{R$NV05i!YhZ3eQU{=%`8C?C#G__y;%bXdCR$Gyi`rCH5=71GcoIkw@3FGRt;d> zY;|=wn`|%9Xcj9VzJQ?MY1r&QZqPypq_}@NDQL(?HGFYQixIqP&r_l?o@D)dRT(jV zPVwbz4vs6{hcYOk7hC%qUrdYsYgp&_QvNg8kZ?(6c@opo>^tS>rMIW24O}>~S>Ksj z9z-y}A5ni{(xLX%J7)kOq^0Uygr=u|BSL#jqYDB(u)S~=E&Y1yHcT$5b4t_&rL^7# zywsO07OLu=&d}7v5w={Ub!7E?V5GdBmGUt`W*yr|YadnZE354=Zj0?1#8go|dVw8> zN~vXJT6R}wJ>NU}AS)KEtsf|={csULpR(e*0~u39EJY_zhKieCck2DE@7I_Vxg5MN zbYDb5mRr4h>n4K?SDf=rfiT)u(VBr(WFOcNgx<9yiX;+2#)tqA!vn8(Oc{|mR_d_L zG3*y{sH~fae!?n!gKa?@N%34YftW%di54^_5Muxo3vKT-;>WT_PZ1~p?h)|4rSsnW z`QL~EasXq1Pf!L>OCWX7FR%r84%!HM4#o}U0oD+90Zte09^M(ogl7m)<98Ho(3 z1*zpf{V^Z_@FQU_#Sm5C4uA?e{+IOswYS|jC$JL;`(1+rK>c^ca}_z78Y&2gH59Np zXFIZ)ESSu`+*exUP@9r0@o}i$#pr9`?R;VD57;31w zZx3X6_-7!P01s~yk)_iMaSyh%t(=92g@%OzqVed^i#EV8I$ht>Gfg^#lx(Jh{1FQe z5BSD|`raV>PfiE~%GjI?2bdfS$qwrUNV@>Yr4@t7qm6ps-XQ58BJbX=-umB81Feey zfYTeqM$gq6jV13jc@*NRHqA7w^1!U&Q_hI!xedgjZ(JL9&%?E)lt=y#bW=Tk_{t|9 z&z6XZ$v%H_)LBB(#=l8*9jsHa=?3*ngg~89(`< z6xg4P!)I+`bgD|7F*d_$Nxa#pwT53ya6w#H=E`qYBF`0NJSL39#~C6>%s?}~rnMk+ z)Stbm4~w}P__o&9H*d&4HyC-ZLy|7A)#od?{3l0g()GBC6bEtr= zkW$qF$~Ajt@S6Q1ghuED=4m~MCw|&c;1gUyurUag!J>i`@_yc9LqaFU-L79iSQva- zvL{qjg?YEctv!mjgTr7i5L)k?rk5@fw2kS=h_p<(E?rHm zmKUT_BSqx2HkDnq|hrT3^VPKeY=P|Ju zETNCZQT17*Kq_2fvxK4iTQEMsE^FGpGs*W7WY{6>HmL1P{|VUXV7}13&b6Wq&((T( ziRx4=G8COud}>!XCpex@-*|bxY@Yp*Df)pf@H0v5&q!~R_t*38m5J1Hi6`f(`bu&6 zUw*<_xurOgOp41uvC)MM)7b986U4Y|uxQf(wLIyL+a4az`C}|4ZA}XoJAc?T^#VAw zROXIb#;097;~NWlF+&t{oN<{6p5$t66-LysmyeL5EUo}i8dJQq@o3oP^F&T~CYsq! zI}^Jyc@8>dnm^&2O%7^g9f48JD$1sERPQy_)x>qW>@|Z!b!pG6noQCGaayX@rn(I2 zm=E2Fg_j{Eh{2B1=dTIv$8t)J=||Wt9M}bTlk?%n-{Z%*EQ-YVZz=en;EBF656BdD znJeQT$@t>zfT~V`J0`U7q+=1G31)ehjky%Q3~%C(T8fxL=>b%}3>I*tW8uMNt`JgM zSs!-r1f``tt&HvE_#~aL>E4I-gam96Os13a*u#&)%k{S`_%A62F)1_2Lzoc>7Rkjb zcYjyNB>r%e9LW|~Ammr132PRg?&VEIg)21c)!;TW2fuM??CV{RSF$bQ{)FXV{z4iS ze@Nu}g@8MqD7Rx08+n7`!OJ?Sa-j&QfR*epR?TBSS{~aYOeQp)Xm2seQiW~o`AJ3F zGh`jX&AY;Wq`}cidM(0942ogE^>EjU+tT#NNTyxTp(n9`)@JSX2nwtBuU;nICW@XW z6pD4E838%B7{kfeB~EZL^>e-2w2`i{ij*B2uB+)R-#+!mN~ScFm(qyBuf|fOoX`~U zY|7A>Wa&wY5sc)Y#)8FD+SGhWF_kXpUQZW7G6^owC`@;)fLWZ1cD-TBVyiX_it#Ug zs$9IZ9!_Nza=oVVCCfL24Idd(I0Pw)z2^}a7OWnA?K@=DMBysCr?9gxUa(RTgLNxBFYMr#tE?3dhb*hiCs=p7k;qZSHaaf_IAKjehwW!JyRoQ`ctt;97M@oU! zBpPlbxm0Q)%BwNhK2ISn61rn()X=iUQnzU=CYN8Km%g|#TmLzJo6x|18?pVMo_VIb zXfIY4-*EP+w$BUWccw(barlImq~P~WdJ@aO0aI>CIQ&>(<;O)#S9tj>bdA7{4let+ z4z7!?%~yRXv+&s^>=ScY?>Eqxny+GwrDzS~e7(`4J#-2!#&IyERy};k%MiaJ z{pK$ib2z8$cGW+>iBVf-On#HHSgl|uK4z^`Qrs?zbDkLeU=eej8Dd|eL7XS<6_ulU zJdwqT!F|N%BGxpIC@CZb^F)*}eM7IWNTer*YF`N3vdTp@)?u>$NAUJ9(EGL0Ww00X zb{pUOve-_wsZ&!jzx&hFR?!hDp9PVxC~8+B?3PN=Y?rMIrFvLEz^nVQQi>3aYAt75 zlk0`Uo#Wwynf^0KJmvj&mFFtwNF#C|3tHHYM-&i51I@^YL8B@@Z2yFRNe1Z{FxTzn3EG0hDA1Imh_ zoBeP7?Sc6mIGxs;cC!7ZDPN3)#6kd2@r7CWSDTF?kZn^MV~9D#bO+po3uFzQ7%l|w ze_EDD@8P`ybyo-Ep^ za?vGvGb}4Bi??H*g?&rN0n3~rVA^A>Y3w3#QB6(8uBkjtO_me-mxh|)dI`axIR}KJ z59M23YtkKBNvxZZVDtJ1vaBsy}_kq9RP zuwqi*)pe(f9rsqy8=8-Ae(huC znPPvS2eY5ILwS7v<}2OI4RLFNjh^VXCggJe>2Gq~@33 zAs^474wNRY$8G$5Tf#8-A?*4U5xV@cw}ADrxGBR66t)1VcyW;6xe`28TE^FOHP)MB z&>2Ud4~l4@vmQ_MKo%I5JZ;<)9@<7RD{xb9ef|3C(&rNtE- z0cD%s!vl9n)X?zF+0EtQ^7i`v>h1d)kilb4_J$1^i3k~>zYKTz Mepdy)y#Y}F4=Hd9=l}o! literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..75344a1f98e37e2c631e178065854c3a81fb842f GIT binary patch literal 6908 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 CFgb+) literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf b/docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4e98259c3b54076d684bf3459baeaeae8dbce97a GIT binary patch literal 19584 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..395f28beac23c7b0f7f3a1e714bd8dac253dd3bc GIT binary patch literal 11348 zcmV-aEUVLZPew8T0RR9104!7h4gdfE08HQj04x0f0RR9100000000000000000000 z00006U;u#x2s{a#3=s$l=RnhY0X7081A=@Dfj|HRAO(ni2ZA6BfhQYjK}92Ka2^Ov z0o}VqRBm=p{=X$q8M1cpbPUxS0!WG`C@4;IjHc?u&;+W>o%jXepM@BXgT+(Np6`yc z(p7IC8)x~5s#)!;6hBM!$6i|TH+G!ojgVxvwMV<>f6hrZ$wC)-SGcn~DA9)}RnL-z*RWekuPpCacmiMm2|#%vBmjodga!vtbS#zLV>nN#tH3xi zx24vQ-W{9R6oCZDJ)7svwFKw8dX5Ertxp852kD0_jPpq2rl)~lVfgktpU>?)kvu~$F8*Uz4iS< zmZ`8fx#t%{j6voQKRzWm;NI(ozQ zRm@Vm{LZwtM0X_?gs}l%&k&q{rMmnT*ngRw@8cYK!5!Jtxe+7lX0q?RCzcT7q#Hmo zE^0*r(`sIkAzpk%0rZDr=EenWnI~e@!ZWRw4&5YkdjWbzW}AA-v&Fz&U5v^$^*x^x z9D>=4oA;0hM2CEuwmS(iI~>@Mq%N%>10q;tU~LSNM4`9p(1S0Dl=;`tIgN5W8&hou zPvN%tJA4SbyjVH=tj?w8eUoobL6Wf2ZzU|Nb`mB zLywc}C%gcA(M%|66)j*4 zN>4qgxgPdPQyNp}{kMs#qQYEb2*2o#q5yL_>0DrUx>q|qT5aF))`^^cJ(QyK?sdw% z5#qW_n-;{pfuk=23r9`Do^BO2Xmd1xLk(tW+f+cT*Gc5gob;BZZcmO401gJ6ok>~S zr*F>a%7h)e=@U5^>@gWP)+L`j;MOKn(o>Y95bLohJz|{O74(Qp)Pk~v=`u&7Rz~5H zIz5}?SCMA>K}5qD1k9-?JM>3HY_A9J#M_dWNQlB++g$JUDn^)0fD`gdC3@zY8lw!H zYeg}GSS#YlJSonktjp~RV@BlFsl@t<%m=O8(LX z6y&&L=2R7_DC01Vw*UGr7d?L}=bU*|n1oeZ%4#CHW_$Z670 zH|hjzE@6De0$j6>L}KJGrL_Ininvg~+uMOTQ;Zpy(l=72h^OU+ixSHSHRP_aEKc0k3BsMrY=JELM3 zRP2g6(GzHr7J7vu%N1HXL>pFJOZMb#q&L_r*sC4(Ngn`HL^LmHSz7nGO9@8+^fgxb z67+4et`qyTi(?%L%ignifXMoovo zDa~GAqTo;v$#-c_OTXhqpS*Z7mM%vJxu*e59{jtNVHwmar>RU!IN<7TB|7>%97?^a zPWk!jl4)mKa){in)E>$tQnAj8*x?xiQxnP93oWKT>XmeIEMjL@w_Gj>2HItrq-7^` zI2p8ThlX|;F%u%Vm?8!wXL)++7IY}HCB(T+?FU93;}J;g zL>%SRb$ecz{m~HAL~75Iml)RFrUf)sm)>b+u64tc|j$3wC$s4>ay3Sn|4k~+;9d0-X>U=pxEkpL2fP$mdP4u7ID0UCu+Cj<=~ z66q5(6~H3VA`a#*8$nq)teS8S?Q7GE;LD$iX58Wf=pk7LZYlYjtp=j@Sz0 zfV;#2_A$UA27cUojVIN3R*e_ccufen#Q^sh_yc-_Pc`^bgKstXNeKAH0KXU}{v`am zU$;w9Ef2D*c>W;Xc{3f+)D#=*iypg8H3a3Nk)h0quG04cx||21OQ86Tlj+4iUT2R8 zo$pTh(whLV-@r*4&-Dj8j$14?y@E8_ z3u)|cq1PMWk8T6VmXP8gDDVF1q}kn3V1Yjad}-$aba;m zr!kQ#MD8v53!c31`Olgkj|rrt5*{ZhG+q)xY0~miDzUri^|hg16<-KumAQqHDgzZI z&o@UE;IJ&v!=)IqNZ;8R>njNyi9S+EdJ$n#kGVimbQ5usVQ)+dIf-8)m8b&1IiNI6 z2Q{Lw=K?#iFr`???bmT(yktyOo#J%U?x`~$TeA<&X0CZ_rP2C*+i7af+&`7Qb+*9Er%^4^6VIy^oewME%bP1f=|h20lY?Ih{0lS`T~|aAmI~ z&V9)5_)@OiQVRSE19I8nz(JqNkarcO{*R`3bk9W@C}nQyDgMRZf8O*3e&$1oVJFU7 z&a^~u8nGb!0Wz%sp6^!uU*lv^C2h5%rwi^CMud^h#YX}irAi8ZWdkbU>3b(mtOn(w zEN{Y4dTFF$s z3dn;iza^VJkQZ_D2MgqINxxJoD$$$d*)3uCP6S zCX~EjSPa*2W~pV2nzQC$Tz{w3{)SNG=a=`vu)2vT0PE#i2p6PUbrdfIw#!!4x%)`Z zU9qajna@(YNplbxj0a`{t5=l^ABncoKifv5k*JI;Y8lUAq+(Y1{EjoM$hC=LVMwb)(vzMiFM=CFeHy z`wM|=yDabV8I$TfVJy0NkcRfCl0U&(1OqJYDS~kt))t`GuY$cl%K!WGF zk;t0Nj0R-U#vkgnLTn?q3#heT{!rfJk|lbU9beJvgg7#&f05aj2k~z+vfOsOaf8if zg*yrB@^$yxr)O z85L|=+UF2qT;_|x`g?0AQ#KvNzM9uU&%u8=C2*t`dR^}wmT?(%Efjz1 zqV|ZE$5q{?)^)7Gyvf6p6P(;?eAAfV8Dv?TA0Ae{yvHzO5U-m*r)3*bCH_&$5J7Dxc7My#z6S!LA2gv4 zqP>$1zvG7+yA++Pz3bv)_)C=5* zo-F_$yDw>k$9T$pVvW4R6hIQvjejViY5b!#=_Z2z z?hjRQ;O8&x#hjavbVQEct^RLIweFBJ$UdWHuAb@;Shy7DMUo54~yHPEsJn9 zlv%M6ffvxf+w8JqF4NJjQ`+4lIZ3Ehvm8$R5#Em@93uzsa^*Ys?0eKCuBGw3yKPzx z@2IO)w~NWk@)o<1cO<$}vh$qOGblK4)(M&WmFb&pE2Y~z9T!*@wF53&AqXJWNnT=N z=mYs3MgPNueoxXV(bJ&#xk-n~zz9hGV}bVcBAQqg0F*!unDZK|6pO#r4NU1+22Te? zXh#n%itXb9jUTRbP8eMIif=bcIy30DwW`Igfr4WcAu>1$blj13hHXnXo2tXU?Ja}=wMVGv>xRYnAAlcF>Xem7r7=A1b*pnc3{jQ578{wO6BQ@ilAsRRzJ814ql6nNft9pRxGC z-HbYVX5(gxtz4Vp{0Ff8hb#AxN4}2LmKA}KyE$+QZJa=9&R$}ldVxchXdsuW%A%bb z4w;mcz3+MKko+#oN(%zd<>VL+deXgDspQlQjGQ%e^fyAkEo|{DdAFPwe@M;HVaBoW zojyoHabdHb-(_i$xu*_s;^*I0Y>d6BYc<*vyj9~ey%sUFHg}zkh3O?Nh`rIwGT8SZ z%wA$T66%{{>5Wu$@llJG47_j2m~NMVnzF+~1&2zrCR^sAj&>e(PYY`Ejar45c!n`| zy0>yTl=KA#2hr|
    8iJi9&VuLl!D?|!}g_M>mOF8Np9hD)!Z1Vi=)NUxj~3huD& zyD|QQ7aI3(({H9Q#J{MlFEJmW^?D~ilCv^kGW^DwJtrX3%3lmPoqYMX$D{1PT>tY- z7&&?qIxCZ(mgn?cQ!37X+$}o(Af39P0>$~7j7f4p+>@Bi9aIj#bOl6-yFQA)naIV7 zp$RaqtO$JzbfPI|iDvvTz%%DZQ;3nI&&ZQvm|GrhS*E--9kMD12pHQ#GI%oy(ufJBQy}WA%+Fg zb{2gTOV|l#(Lp}SWgvO9bUmv48C28iNlXJO5*Z7kk&Cq+N*F$xAJ=R_wbAzj?a!dz z-1?v->KqkvLsOb+HZ+If1+3D6_rR|Lnpd@k|!GPWpb*j{dYXDsT;!&wG%w50@ z!$X2~O&VXQJ!?yxp6*gdc{-qUj^BC*;N4J)Ap{)5$EPb_8sZZA1HK0TH zdTmQk%mOe(F9JU#xBiL!jtTtjOY^dtP;*s{(b(A-qIV`0!Jw}0_{d;lEa@IU>z=9) z^uB3N7mQcy+b?ODY%5#hF(*89hX%5&Euu@f`sUi3jG9dwZF3E(gnRk33%cgDzear= zWK`GHf`>oYT;+2ubmPA&_iFX&PMZSM_+BiZ!Y-#A)*YdckLV7A8r~8g&K+l_Hwyv=a@c>BAIeuPD-ZnjuA4f}pR1E_a3AMFiQ8NasIL{hQ`(;ge= z4?i+&@?@`uvRXQbQl{QpgQ`9m*KK&^Mj1?5Lt$8Tb^d-$Qa5ws_j*=s;2BhiVj`2k zxMy1n+lpghTh;B*nzq*572+(t(wmG7Wl|D|yJHKZNnx?)75o0Ad8(V5Ok{}KKeZyd z9F1<*mPPOxt^jp`MBXAna0f`$#YP+b#`o2U_h?M!Vq&T4&J5gHzO^~h5?NZ#8>-Om zZ~cmMsXj26*%22f#S87gEGzj64&|vZ5^Hy9w>(q%E?uCpqGF;gnP4{b;+~MrqA6&d zoN0?S2EY7pq&ewXKJM-9Nl$wuE%f6WBQfzzTb|g^m1KRg?R^}!y@zTATAup?28~xP zr>jSbAWtz|Clz(Qr%8&3I0qROxN01)nYeLhc}ty!xV80)dQYQ&pm8?KtM#e|t9G|l zZ!0JDNMUaX7IE{WMeu~yU5Tf%7mZKVNsj*_0&_&dzdsiD=4yR3z zF7cDlC-JBYm0daq!H1#XmXX-|%XOdzD?)qcW#)^sJ5CXYS|P%wsFAYMscIlE*@=qw z4>eN#=+(b;3UPS1?#5tW72J+)Bx|IAB2@mhpOGrLNa0c1jP!xXoA)mE`5t}V6+g)B zbEh1QGclhnI%a2W417rsuhJ$mvN^_Hi8-P62X~url|=r2Fz4o;XK^lWIJk93Yc`rq zyBsaeLBSRYvNWFm;)`FV@2&)87VKZMk;88Ni7{*tq7;AJY7+TgsfC~7HhwzeG$;fX z`O6_sW)s>HR~cvqb6cG)Ef@C?Uz**!Qa+e>ZV*>_P;32h$bdqB$U5hRu*zOp4P}@L zMIM;~XxTo~8?6)dFpY3#g}JJr=)1*kmBC2i@lTov$d4CMw`GoIy-z_N1+h(AOJQp$ zOl@sAQ?;U2r4hlWnC&-qjMW&#pw>ogkFuZI;IOhJ6lfAcJ|Q(mHB##476GHV*o5#Z%vGnF>1Xa@muz^z5<@=U3j7k#$?7u*F?=&_}7ehUv$4lqTF1 zdrNPsJ>_*@sTc%q?ZfNU8*X#dbvZ@h2s5b{<5(4YQwb;xO#v;Kf zg00+UVhKk!Do1#9jLotBAOB%*>3|8QKucY+D2ujP?mHgn@RFKU(1v1yQh_)s#cfBG zLTp7syF{)sYb5;I?IIZ9>Gz!J_Vs=jx-p5I7b82hc!NPVPkqBOad;nzMv?qm8lBy0 zohsY-==OIY@}u3v{(Qfgwi@O9mkuL~{IBzNMt3~idRN3h^1b5c_N$v8`>ewR75pXq z&sy^&2W%&}Ce4g;R)U0kZY!R=>g;)#gU-cw^^#G&&&}A3rVjmNYpvf=VO`kKO@3#~ z)haw@4B-`|-BApsAm4f{=VKIe3s7n!-!H7$^3w93-x2|^~2?L z&&?!?^hR~84mnDoHSQm#q;Sr*UMKBq5=y+6j;UTBXfSZthyo(fa(cYc*%fH`e!p4f zz;dKb;lpJJ(s-=|;5HyHWOj4$Crb-$cV1acqn+w1TrIH&32DP(|DfC4t&H)_+E)z% z-H0{bvkaWop(xr=RV;^=uA6yplmq>s&{9uj8N5$gPH4RZE8XL(zGkGRkzTSLB*i%M zVH6zj_o@|v;{@Nu2+it@eXLJiRcNpkceyY>!)KO>?bbFi@r_7zLp*r$14u7Cpso%R$kdP;Bd3b(%3C-a7Z;+eQ8<| z`Rp`L4Cht<-+5F(BMUcgfeR(KUbQ=vNq^3+3WyKv6I!foG>L%TA_##3IZI5}$m)QL zk&zzgt80yI5=P)&#((_kF1<^Bk%N?*#6m^d{qOUOl4wob=z@Nfx`1*g{DyRMcyjQ) zZ5_#u_}=yNJ3NbI?YM_y>UtX2K(jpFwKDF+1G10TkB`jC6|vGyAp*~02zbbxq4~wpE<5^Jz_s_ML8s)Qhx552)Dx-Rw?zbI^K^Mab%;b{;-xo>fHeO!u+B z;pok~fzC(CW@PrfPRM$V3=D?{piBLv4t?qJ4>v$dA)N*8;$No;@Q)M^dTnzSw5RFH z+ja>vgY4+ujBUezJW#*EG%)ySUwYpjgjlF*@{s}Y33p5AhyN~^WKR zZ@c{EN)N2QmF$|IaCyt6n#t;6rJ|;``qm#K{&w}uDgmd|L-$!_5)qXYzaJfMGV19>%7Mct6yNwe?$#%M!6&CG1 z$xuk^7qfk3J_#G{;8<;fLt7_ZzXo_=G869N{15jruSy_=+deVnFOrw<`mz2XSn#5g zqcE_A=lQ%kvkr!Vu^)cD2ByQjsjr79<)$SyzrXlZd8~QeFMm##BZK9>pj6Ftk#P?r zHDD_5p9hbA+MbC?oB#b)rLtAa+8g-42f5h8k?VoOp5UFH_Lfg&jUO?yz0OXZ zCeC;a)NNvt0SD~HBdYmAk~^slIxDRFo0Cd5)1wIovwp#{BQ{~R$Hd5HFEdfaKOOj% zbacdT-3R=$`Bb6Q&19Q<`-42{sryGhds0L?eE-2Na3h5GR!JUg3{Gb5Xmv%I8DdET zwD<^2Xrivi+rc)jYyaIi-w1=M{B~$2R$cC5O_za<=OxC=FclQG8wGsyU?r5g3h5ex zw7s?l*nV|22sb^_<|vv#uZ95J_omLm zKN}{CexLXj(OdCm|BDK4qjAa-$$&m{`jAZsb0qB$1RMd_d=CC=ETb+3%n#mMy28ap zF#o{v9&bA|m`)eExmk2z$l_U92diU zQAN;VfV}fp?&7MH@dZCQ&uYDk>2O7d!}H@hgc)w^aTTw>32G=XD0NO>{@-TRljCI% zH_rk0@UZSq!y`&Hs}?{<&KMgzeU1P)SXWix3O5q#^^4XI6{J1LJP)$uVF~yyBI&Tt z_*@@=;PV$ZYfB5#p53^)O^w6;pFYpNAI0Rx(Zvw3Tt>|`JpGs7F?YgmkAS)d3vLEp zxBLom*$J-PClkCMJoJF3R&`u$rsLiVgc=JE^zy=Hj{4ghnQ$VMqjg zg34RyZ}QjgxDgZNhp0~E`|E&z=@IGaeC{B6Zl^k{cZpi@MY039K!-I;Z0{#kJP0v9 z=@RxjHK3n%^@|GuAa5~P__^eP zd;h*2uDsG}WY4EFbAVr4Hx@XV?BU#5#p&LhWrfaI}BfRk5*{-7Bfq{eL zh_Q(qBwxgNNaRpNN9%*fST1S&BiSX2Y6mi?jrKr5neJl>Wwz^#4;e!4fIG8=* zA?I#{xFEqN7f5P(?M4Uu@)~$qX|;_B5a;mA4M1Al?W?rzp?8T3>ug8SMGCEJ$xokF zv1SeXM32+J@{@gdPz9t;FT$Yb%Y%iWMq2RXDklkaAaJHP={UQNsM~@iq${WBHB?vf zezJkz^!A%&3;*u&Qd1gMUvl&2T9lVE<4@U zrg+QCe)H*w<^>Qg#90rx$mpp=}9AQ)yi8iZz>%K0nPCN_|0 z-PY&G@}KB@Vy0(Rst}wq@G!&{GG**Pi>}S^qglm({`;2~%S=w+ym@DdDkI7~h0?|< zLHqB1rw-F`zxrn>WEe?Z&%*LeNuYMccZf%wZ`3W36uk%B&qxPQ_|lh4@}8cnvSD+c zm1i)md1fs$-#(|Qi}oq5?8>@2adLjykwyISo#K^yTT(%_SygB>d%)K2oXs;`*=Jw` z7YeP3=TEhcPaEtJhOhaJc;ewMcV5n4fr3qcM0R`Ty>C)2pNKT2L#;xktUjE{XHhE2 zc;C@TMDZcZvLNT*bDP!~%UHcWi?IpfY7}dU==X>`+?<=^9|&{JjFFP4e3^xtKm~>G zP;GM;mZUq1(Ni09-}ixoyylqP&z)GA^XZ1UMZb4l65hJ_34K5xIe+Hk-(8^3s$LlS zitP5t{meg-qR|oiTJ;B+m!H3f`Obqu=9C|@H+g%k6|>>xbu#4B_SXU{pSpZI`rt8k zd(SOot!YkLt%y*@!R@+jh@@G#A$+$=I(?-2U?5$LJd22Biy|-ekN)~_{)M9gY zj|&7WebrFeFrD)D)lZpRLf?*66bv=mZq_R=SgKbm6-FB-p_IJ+=5v+Z!b6A0z&J%7 z4;{tax0^oBm54k!acoUXhoXqyqY|`IhZI9YP}ib)n=%yHuQ>2{>{;LjcskGkvZZoQ z&qtbMh{@^QI#grgRy^6hSqUY?nr~B&Y)I5Inm)1?pP(e$jcDRL+MddWc%nX+Rgedm zO7kg)OvMaoftxyAEu)r62|B}-^2!XHF6NXK=RH;)WJ=j3v^`gvOYbD1u#DT}D~C-@ zMW;8VDsWOQ-qC8TR8Vu>IxmU9%gyU1}Fx zn-&9^Ci(eR%@x_QWczx#9-SI7Lw0f{O3hjz`JO3ZgdWkxje9`{^`IWRNo1&VJGPCa zPp=mPqV+h_J&tGGYZAI?*_AzgM8D29t=LXiht$xtF!rboMraR(){nk4s>7;q_;2P5 z@ryKld@cOa{W94v0{Kb(`0tYn18FVI@UV3H*a5$=%-WN`%3tU!`e_ILZb_&5{RgKv z5rpFGyl(QT?8s!SK0&Rq5i1vEY7V}@N)#dsOAwKg=Ao!a_CHa9*7{l}!sI@kdKU6j zfV$pi?~hPA#FTmuyzex%=gHv*t-3z`6f#hq17-Rcp~cL16!*K3_wb$$#b76(j6E5w zKZ2j$N9{Ri{Rv#BUIq`LePvKHaI617HGEg%0e7Rwu;Qgllf~CLIqBtUi1u6- zXVO@-7?S6`0YW-r3(qPpY+BCA0~3QNKSf4~YVP(~8O3PKWi-cPj|uJ)!@;-)HiJ~` zGHe8kCVjfS+@_E3HLM$Mn-(LM81ntqqA3{=E!SL*N5L8-Kf82 z9KvQCv6^96G+k2o#*g<0jVv*M`Q2n6_!2%go^p1c)178_^fj>R|9Bi!B#X`A z^7sOw2pj?u3K|9$4jus!2^j?q0}C4m7Z0C6IUx}-3D>?|atcZnDygVxXjRdvre|Pe zVP#|I;N;@w;Z@7WFCZu+EFvlB}U8T zMzB?gr+a~R;~(48<%7kiMqgf>1?x%Y;Y$Yd5XK)8mpUz%x?)bF$$R&@`ES|j$<79b Wg04?dcHtp;N9jIFDoLeVYTd2ArB>hF(|5OeuI}k$?!$BY92?(bj12}8 zybuUCS-|QU50}}EAz?`zuCN5MSpp>3gb&MqlefYEcKSdD5LAbta{rp*8`$5zo zh@rD^-Mw|{;PC^=f4dW&zW|+R4z8U!1@~Ekm^cQd;^48{w;oAwa;X29AhM-Hn`;~E zp~{~TL|y^+3WwkZQ=>MZ`T|@B4jn&x@sGZ!O~CVhf_VKYx7f z;whxneHg9-aLu1sJHC0Kc<+yZ9-v9~xj*`x zps=Zwy#Dh9P~Xw~1^FHFGen6PASMabCxN1ivT(vAE+x5r5&4 z%nVI47Hc7&6GMWZDdM(FNWc$5BF&lMnkv9kcu2z~`iI`+JkK%KP>)#ak&jQED)!du zj+IfdFJ+!H4&NOLunBL7EIoOThl(6gKJ{R=zHel5qc<9}xxDn5-bduYzHXsQ)?Msf z9GENgb&nj$g$HBCobp}wmUhJgtUN|hX(nW!f8wq0=~^E>jovDDbvO$F(Om`w5`*YD z;vtZmnxL=B3DlMuumS`#%SMvZdt?su+~;gso!+N&d&(B;MnAB0@Ub^+e8uAQUq9Zr=bkwL93mE*Rb(c= zM{qm+nDQ2bStn!ig<=5!ASTJh|148G!j;&R!*5cVa^x4B;`OE6?8*6EDcWY9+WM;h z(E}ZQqqsL0dV%;C@;Sl{z3C-RghG*KM9_^`v{-XumSze?E7lIE!t$=L0wuj%s6$LT zLmow#k%c_=c)aLyIKw1*A>9`U2qwSF<_cK*d_uQ}_j2Aa>-Kp2V60^G6XX}jF-dA_ zIY+Y`CpJ3@JU}K@%up-lYHTo z6Abz0ABS;^$>vXp|4Li{>!YvIB(wm#!e-^46icF5vf(cg+KJ76^i}d}1ijM^S&=BB zB6?AN{Z5`jZ%~teuKvxv3LSNkB*4NV&7Yw^MgIgmbJ%7za%^G90>}mTmyzLPBC+h=K2cEq&zxy4w;1}*^I;jn7fegrEVGYm(=8;w;vcDVJjWGRzkr;a!&3km;8m8H^a^jXNJDcERL_< z8*vJU#s)(Hn^#B>h~*_$SDnT{jZSk+uvt2r_r~m4=(K9O;X8Aevfkaq!oSa`qnR}-h}x| zHAm2=(Tju!OHR@d;2{C1`WE?F&`t<=5IhbRqly8SNi#IFGnC*@lGw|_ z$Ot6ba-Zl+O2+M-o7_t>_0`J!n^!WEF>bJO{(|ZHUl{MWxLgh<$*Y}m4H{W`7LBY| zmmW=yFCe3I9{Q7hJB6^X%{=m<)+vt>hQH7&KxcN);W%Bb7-$O(iqC`RzAR0rIFk$yD(VCQj z`?+Bzy`&T?iWqcKAiz=K+sW)?@uFTIHFS?1u!(QlnA~y{(!sMU#Cn$nGE)3eB9*T%Ctv&_j(sM63JFrdwmq->I6)F1AP;sp#XCA zxeO|hYY^g9sO6_6iWtBoHZg1qVw+xckY4Ut+?@@bA96l=X5-pJqurievx(GDckh;L zgg!mJCmSl#s`OVrbY{af+Wi(!$KpdOZhxWgD2$qE{+xI}`Xa=26O3xmFt^5aQi_q- zFf#3+?r)bCDX63Sr2>1KbhAQSMSli8xu7Sml_3~!yl=YUH8CczaOrfrD@LEv`ju*( z(U$T%(Ct!>ul%F7FT+~0I*miEUiP_aemq8jc!2ymx=qSd6xV1ODcKMBQwICgFTHYv zA>T$z-)J=aPhof?(fkG4BCi2eNi0?MtN4RR4?(bP<=71Ib&EbmN5SU9~%-Q<6%Bv58LDAso~C0*3liyalC|F zOY>!jL7yge0dgHGj9eyT1;aPwL>%R44#op5<6H&e9T*fiyJ9chc6>mchXk=<7l8vU z&U)1Ijpk9!v$m@CXe__CXJ*5ytlQaBxdTrh3ac07yxwK9Th*n* zV@C@Sy~rm_;UTL!5ZCCn*{IVLvKsB32S(PVEbL_}MP4O(fX}^PU-h}sULUqExxd8` zP8FnV3akxGN|bC$!Z_dp`wy#!%tBtGqZp>`>8V~h|@<(ZNjR~4Z2g=#cKQrr=F`&3JaxE z=oNj-!->*TAG%#;WlTDoPCJr`pN!6O|8Zq{AwRN@t>9SJ{2{qXew^qAo#!a5b5J;D zFawDfXjum;m0XRK_h7*Q9$Pn|32sBT64qh?srlMvmrSNnTAibDXWnd+Yt4nxlqTY1 zJygelZF=#sq+>C?8c4o%Wmjy8tg{`t870Fgtpd$1&^)K~2K(KaVV+@CJ~nT<=+f)a z;6nOs(@WZvIozwLPc`;0R)K0KAoWL(?PIDVyhOF+Y(Vw^&`d8?EU*yaLHdjcIV9E@ zPAgipV%Qdntsn~Api``~yz7h{-eOf*OrygA40(A$FF%~HNu$VIFk3&2ZK4|?A0R$8}w z@oJZXF&i!KVEsu0FYBn-rk5V;Su3o>#JA1QM|Y3$Lzi8&T5q$B#~tJuCS zw=xu!>o=?{?KKtndpw36d3T%RWySnlW8YGZ$6C^=6c&NjNIY z`I0mEZAb!~BuPOMbjz1wHd`hU5|a!LyjVM6TJRV%gWU_@2+ISVx+9{E*}{iP-H(N2>gq!P?^%_VrmuLs6Ma?4}0|1&`HoeHSa{Jyd$Y zK388`EYyzm+Z@3Jx$hY&n5>=MeaMg$=bv5K+ZSNR)ro}Xs52VZX5IZl#&Ug?RaWA{ z9WFgf_0Of=IaiN&p6OknmxFQ8V)I{{cajg1|ADB276(G0MR^ejhCq|gfnp?E0rTI{ z5r9rIeB49^Y+_Xbt6)Wv6yO@2N*lvgzd=b}9-DEg>`U5`&mGj*D(-lKqc*?LJxHq* zdbLBPJ?YJCb>v2mofvk;E`?%8`-4JiGB29{a;=sRY5j-Qxv(zQS8&84U&$Z1+)Ytx zrCFgrmh0#ZAD`&WuTH;v^&F11F7N>y;Lr?FS8**H)k&HGASGot$Od|m2>Fo|wR#~W zwKWCA@3;d}r5>AM%bu`DvoCLmO%23P_)XF4d*r%el=AA_VQqYCMpbq0K)KhKev3Bf^7bC^Bk!H zN{uk{S6oX5sn$xu4e(<}3!(Pg{8`ZRIiX9Ax6Ny71w4)lUfPy90WZ|vQr>L5-?M8?s@A$CWpf+iJ_9#y+b@b>cg^u%CVk!CbY9ZLE za)&K0t*na{-@oAYp7Bf|&G_sm-SI*lo)R$c#CCEppd7+^{}JfKEF0SRl`_ zhK^Fl+NT39p+kc-a;-wAH5gT1Z+fpO`o#QQvg$>Ri|I}lXH>G`b;Eo1PY2y!Q1992 zoMz|slt=B-S~WU`RHYrB_otkJv6(ZvD&sYJ+y+^{Et{>B>>l0I0n4UlFz5#AAs))? z;HB;Z>fH?X$(T$l{@MxU*j`(4gAs8|#7+vMu9dK0_<=iycR-o>TuxH4q)OaGdVm#( z*HCcN-==!t&cq~4LW{kSGC+2OKHyzW4tYXHI@~_B%VxIsr+5|ZH5kKBb|RKfYYkc* zXB*4v`tM9y%~n=B>a}#*95NY309OjCM*cAC5Ay21g0J81v>OfeS}NxfT-B1^5z@kv zh(2qG&xz?djv_n5*}23}Bok5UeW|{Oj`HRZXF7h*NAu$yQRE4Q-LoU1cfI}T7;DlU z3fZ<61}$!Hr!QtRjD(|KzWBC$ls!^5JM6o5twfd{4m+G#UyO_OxzxIZMP*P$Z6Q-C zYw!!Zvani#2zT@QR4*W8Kgif2&FerOAThwV1$2&sG!_fgAS(uW$N=uxU|Y_#6)3=5 za9bP$B;iYL2n+s(7;%T_gI>j--NeojV$RvLDfu%B*oxMxEU3cg_y$ zV>)au4!`)qrSuBSi{Lm_= zG+VVUN@ijz=}Rl!Z=Sc2=l!+;Ye8PSEG|n~0M5Yv8!->kuq!a) zTGmh~W--zLbsm_WV6Fik5`;ilkQLApTJWk_i+38P7}&F5ACe?dW6_TH64m*3SD zv?~}7tIsU0mvPhI)4fl@Mh2)-7IZSB0S_w!*nj?es>g~4pMjkUP8KEj6eaY4MFA!-dYG2?VnQSu$<0pvZ(*>d zx0}vRM@uVK4`3h*KvI`k)xeNRCBevVG}~iFfB4*%D)@f@gyBgg9W|A+mGc+{fG18} zhUlZC+i?2wtVd_DJDtuxFCYZ`FI5KLz!HZ5Au*Fun)erq*aZOkAu4cYFmlj3%%LS0 z0C<4h$trmcn4@6(2XFw#03lpyVMOu^Qf}}%KxuRr@3ZO{1?{p&yM1y)_CRk+{F+^;?jVSwMTd%5hT1 zWHXWOl08uSVE@>Dm7X;jW!l7W@ME?Gj@>*b8#HXV1=FP|`=%LOsl^sHmoraaxVy_6 ziN#F^J--8!dF(|?5NCf*ZcB3@2aElN| zXi`9P+O*(yJr^ubS5Mwwdw4usI=1{Vb()KCyv3#}+f25*1J9@DZyS4R|6SQsrPKdT zFV1!zNRw!ES|(U+Ojz{+r1KW^=H%m+Of>%;$5klBQ{iaC4;eGEbLngmmg%02IWIt zY^j83L(buTgx`0-ndx*T)&1eJxab`S7Az~Q&N3J<6_dRVdtcBA+jFS-1K{8pSl=mu zjhdx(YfKc73js?qLoC!C&)i9uICF>{Kl* z=r@HYY=ISxTy=?cI%RT=&+7I*dGQ{uKW11Vlc7HUbJ6g5AKN<+XmrHAr^>SeTYK@z z6_s@MvhLWHjch+A>nslosUqLx=cre zu5Ot-@9_Kq-(fduUioEaaA|a5sGKi%a*R@NX>yBwaUn74@*i^>O>{?6uhhSz9Ql25 zEKaJa{=P1!*sm*9sr*F5h~<||-r{pQ7SPLmwWUh%z5^r9TGTx!JmRlj|3xG`IMn&M zsW;lQZWN_mbN8bjZRbE>cQBr;D7e6QZ}6#L+><)j>-Qir*u@Uy((`+Z%MaE(T}8+5 zIG|auV!U$n1@J#O&lm9;rwOEFv4YGBMQMh^fxi(!T3MLg>>wV?OvJt!WLCsbE97A# z7WP1}(3q*WPQ*P{)Oo**)7tfFe#_adDC8T#@?R;cAu zBOg>mhXe5m%!#8JBwudlqoN&qQtTRE8|PMx1yF5E{dm>}T!6`AU24FEn^nuD!Usd^8%)Oh5a>yJv3~gyB%p#SeV* zEf36;S;`ose2_ou?JG8msWSY^o_^w&$aA-g-L8 zPM>%<7uVVhf@Z4QYjFEI#>1xNVVHL0`(%fEonBRR6%tIAl!wFT4wH1PP`>BFZgnW) zbLjis*`PZ+x15}x;BZ{I*t{QE$(LaVfWFG$y*|Vktel@QShC1^;lk0Jc#-^5?Qebx zSs!%(j%A=`vw1)9`|UU6cqU>JVbjGB67t3K7cPpqqZi2Mq4jTmUvAUl5eW1r=wHb1 z5^@+phIideRz_sRfBU)kwZFBJ-~F}on}4Iho_C=6ZS)iLt(_enhXP5SHzciZ0f3~? zUv_@NUK@rbmeFUU3DW$LSf;AbqkzrA+?hc6y2(UQ1+97ar9{cobAI;`x7tr{ zZtYGcU@m-Obo7@_(?l*VMk+A!V)Jj&X93G@@OX-AQJ%vin~GLQh$O%DTl|7mwjz>= zYpV(XOh0_lfZSmRV(Qs}9A&X%L0mDP&|_5#1Ao(WzCC^$^JV82YcE zWe>>OWi_;9Z2lz9O^uGbV=t)%By!%>^-~;*(h}BbS}lp#5Jta$ol{v(ovErzQl& z8PoJ|cn_+jOyT_sV-TVz+f1P^!ak*o2uk~>u@LXJ;ZruiOnara4P}t46^kAG9TSv7 zs06JX@GPl<&CZR;^ws^b;St)3I?%fCi^FQxxn9oz*BX#lZq4S{s0{Xk0JsF6xR}A6Xp?T?7&tYqfRVBB96_D#uCPhmRUyNaK3*v zXrI>q&{29w*~=JYO8H8dEe7QBJG!ll`*rX3btvMV_s2$3G5ZO@+f35jrgjcRjpnpyKoXUA?#CdMgyFI zL36+l_SP+*nWQ1_!|H8cLrNoQyRB&~eD1@S`Z{OQi-ODo`>C3H6j?Qe6s*>!cA%ik z$S-OmI=N$4k0vJEWcq8J zFEZ*(^gLdUSh?sIluj-+G+pXDH1Du!_GYBDHDmK1NG0$P10Fm(JkXpKudskOYEcOE zf`{6n9s*b)Yq2(-%=9T_NJ%S|a#G>dTq-K$(XIg*6JD}7)iRr)-6HiOI(f`*Tb#Ow zWbvMng*`Q&nwwa%$m3r%DGTGGr*Ertz-rd4ux=a&E6tbCyU^dl2@WS<$D*V0Y~Biv zuz153Mexx8q_(5@z@XPSbzpK>Zn*=|tcxw}4bf#+IrN@K5+gZXU*^pIDUZp&zGqMt z8Mr$a7=|%4%_u|y2jDXUV|2vK*b7UH!fdQi%qMB^iqd`(9O?jFN(hCF)C4Q>7@jcl zN2b-vkVD<8qjd@;937g|8IxpocVbj-eW){wQYRcV-|zavIP-kfs_Rt!N?}%M7)C}0 zrj-`6kW|_HBLUZF*BkndCY5KtmJOM+|Dil(!&adOuk;w4dGY}Uyrve8LHms4pD}P@z!q`^C?r?$iQ}SE z?L=K_3!il>M(gBTBE7T%Da|3xChtf0EDh_mMO6o<{V$c!qQs`LKUfus*VW;S%soU3s<>3H%>?QA$auBwiwc#8A+*F$gpa(oz{w1B0AvMPgE2!6K zO;L}op%r$Nyiey~G(-0YFBN&q`rHd^!bhP`1^5aQWSjtwc_VO)S6`&_ao95gQ#8XQ zVH*k(;I@dReKOe71jwNeFxs#-Ob_K0A+2Z9YNcXMQ5z)>&F^bID{R-3E(n^a*but23*XLwa>g{qDW#uIlU*jzw9pwNJv?UON#1q=miG z+G;T;N?Cz~f3BqzpbRgrFf^QmgFL=%1FN#gw2nv z1&w!j+R=dl?P4ea8x}apBH0zjGn_&IZXnuAXJs+7aBK~jdf~XaqiTpCA1jv^IWyTu zy^YWHjCS&lSDu0U`Gjc61AlG zrm=|H11VXkm-qSQ>ZIRNB~b#ztZt4m+NjCjf&qUduHU!kErGg%m( zuqNYwv~WP7o`^2=CrAAmt7$+zI=ZEw84Ky^e7N8o4Y}OwXYs&OuCDSnS0b+& z&E`5d{gT64+%GD&lpQEx!>?b3KU_pbyW6b+2YQPC^t4EkhnY-%;pp3T&(I&;`L zJEjt1fi8g?OJ~a^Vcu#?s;2JG0!IS)@NM!C0lzIUwe8N@@(nH3v?3=s^fqNb>M|+F z;aHVA@qo*#C=T|&Ge?QFi=zcn6PrhWTukgP^|K}W#p3ThR+=bw zx;s}_BVAaIp6g9C2fO4vT!77hp@1oYV}|`D@Dm2`$}M@qS)?MG8+QAgf&O#agT{4Z z#~%GI#dyLk$`lm&4t7rPI`W5w>v#K~XP&-{I{hoj!V$L&+l8m8gL%_OU=~A|D4Kyq z8aT;-4^|eW{56yZ;6b9!_(d?>Eb}!vso`Q)(n6awG`W|ZbPB!6G{;oMu7d0=Oq;I1 zI1-A?C1j*|vW!aJ@(;^?!y8+=t!k1%_UuH>=hcVh1Ah~G$YhwC*tl2e&g}2$Er0~RyDCX7Z!`17X=v04bgTFS%GLvz+7LrF^Uv#v6}=%?s;?{fv+xhs*gf^jZP|T4$qX` zW}dd+6kXR>V6EpH^!W=oy81_{azK|enb?ft)v>iB*}IuJ0dx?=D)9!G5#v8dvtjP_ zIDETwu-GI08R0|<{?|op5Z@wxf;iL-vEm8zEP4S>`u>9f%;?W zx=fHQ$WF+flZ*0?(@J`S{vy-M{GmdvSXF#NnNhx3RaL#H?pJ?ZGo$%|wyJ%<_E)-# z`jGxH*2tb@A7S6aKF9vV&}rB-e8})!qt$rG_+jJUnH;7=rYB54F_+9o%%3*@jEi%3 zav$LS*^;sRzU5!6W$XR$?*rC9x9M!7wmWUtY`?K*?8|oeg^cmIOW zQ}8>YTmPCbU2no_`pa-vAxQy0{-4rsiU>F_j_U*p!(PL;2qpXirGxke{DS2{;x_m! zA`9Une@-N!thUQZ^h-j7PXs5WLJmIH8@J>Vh_K z*0EhWsUD(4zKgJt4>f;4^$~8Fh2Y4qLfZktL9P&Lp!XuOz^@^G4!r%G7$D*7A@DPT zenx1~n~5PbM0n7@!Wc?o0$B+ivNwMP&uz#?tdUKEA@zh2{R2^fcQsIU!81L29x}B_ z=wD7K08CkmhG_C2@clF3`QhfTu^d5$3HZd(Pl!?UQ$m3D9yAJ{UlCcT+tC!^M!x_( zfX>L5uQ!PmnFF%$AIZFuCb4FA{#FSRJ%gTvHA{lL45#@C;*G5mW+fd6qxr_)y#(5I?;x+#oM4WFB3(K`S&yRnK(9MiD=(&~UM$Xv?*H^dr%L~g5 zGPw3>1&C^WT{z(M`5HvMK~#moE6`_kwUTI{c!OWvN;Js0;1hg_1{LQwu2N=>s8k!K zD!;l~*(S}^%65>dHpuGyMZTdCpi*7iXvn57ULi>mx@q_}T|RvGijG4S7Y|jTas__D z2G4{BF}=K5zXF+$G@vZrpkfWKx{SwbSgO@_11G=1H(r=-$U-Yu!bn@Kt=AfKZQ0kL zg7w+m%h1?)d6{oaPs6SLx|45|aII9Y^V_Y~Kv5WOwXgU_8b43tmM=^%^B|4OYkWgB zy}Sx{c>GL-YXw{@tU6cg^|}+J)zDPe8^r8#gBZt+eQ@m@Z+LLcGrsmImRQFvJ|!m( z)ax5-^#+R7>unC|{08tNRO*R_JkHnnhAg-SJTcYjEBv>uiyazoA`iy&;eK;9-@&%wLAFw$t(;NN8qxb=tW$TVEFHzB=FNpIe4! zPAr!;DTxLXZz!v=E8wamsVm@8s0aWTp|aK>4{SBiItWFHs67}5xjyirTkTk7cPz*?@0_&@Aid$I2N|l67II%(+yc3Ar zp%PRptPQq?(7w*=jR3p_FW+G8=9hFB|3c-eRzpxVP?1yc)uRAneSDiFYmJSy!9;_N z0}DLg&{xMWXHWqRHCTK#3s0#)`!_%#Ye4J?LW3S66 zFm z^5tP+7+laY1U~S(5RpmDdNxDJIFDLnK2%Zabj2&cH#kW-uYcTpHf_Wy!nEN|?`x`mR{cN1QG^){Wu;DF1q9W{)= zRaeZ1b%y2A=H`Y7MnMEz%j_XL0Sh-J8wIfPvDdjj4&5QMsZoSB6Y)kT6q8trH4r!a zzzJ~MreZ3N0o|AcG4G0Bf&bG4RHmVVaAhWb1xa^ip(5Rx!)=D)(L8R0D+{;{t}Nm< zxUv+#3f`~^wPmP5Y=>GseiagYTw8%!>)vkM4&i%ya675C7q^pY`*1s{wjYmKgJ!FE zOk7#RW8%sIJSMKJ<2EBu*}!dZWfQl-l`Y%`R}M;a4MOdZL>I0dmgvH@BNAP>c2uGZ z*N#ba;o5PDE?hey(S>U#LB`!T6nILyYV^Z{+gjBDsGi0`$ITiQxH7ttxJQ2lUg^>hjK36*su6RmBbNhPJ&o`nyNE zlKQ*Us^aGNwyL=Keeh;)tG_q2s<^@ZttxKt0JQD9(cgp8mDJxuttxK*aI1=&KLT&| zwfcLsRmBZ1x2m|oWAQ6$DYI?R&MPvKs==fQVp+WsYbZ7wRABnzPC!o(FaiA2Sx6_* zn;_P;rhKQi38r$zj)*9(T-7L$s#UYlQcY3$4Al=HRKs0m~1sUFwEH6Luq9*4+0 zcvZeZ6N7_ND)2jB)5J8sNB&XsW90kLH=BuO0`^c^*V}L%XvC9==xx{Oo9=7LBk11teI1dbegwa3J4u`( zZii7169-{de->u#VPYM2nRr-}NyEQRSgXLb4*2kJ9&nR5BegvNS98$vFx)u-pDwn-cZ%EqBS5A|jEMadA*xkelX zD$hY}7VaK|+A+9y8lIhmx6exDX}G@$J!N2h7E@i8`hUHC60hp%^+$Yl%S9OFv?LEa zHV-mN!lw&rXW`!#&~*;Vlfc-Zyq@gV_yKtV7hoo2WKRCo`>%Z zxU-{Co|povk4qYTecfQpsQ@Wh)@N>cdk(nWf>AC&FQ=tmS}l%2ON`qS(7rX|IjCdY zord=@RTx8afawV+cY&SYwl~u?aZ3+aJFkrhOxtfMyLDV1s5%dy!xD}Uz&9TCw{lsN zMjRk!pu{>XLtofV&jLMV*bPhp_3J?KVYogE^(1_7Uptac0p&x$!T-xUBzPeBgL9Ob zR_#^at8k5A35J3dK{@y?75qPHG;kh7N9bW~&;V=ZCRi=xV5QIstLk>}Voo@3=7zIP zJggc9V9zE5Cp*G`!YJ&H#lasWfgkK^GGHA!*kvvdML37w37mETntK4T{oo%4i5l=U z413U{-~q>hyGg*vF7UE5fTKB(^#W*O34BH!R;+gudx*WT7WxU|lZb*7#BxL<2Eq9U rq+-sUIGj!oq;XlxrgzGY_I0LRX4_@1UFO?mpjZJpY-ZTHl+ZMUcHsd;MKwr$(CjobIT-yioTYtQ7_*-x^PS!*V< z^2AMEObh@7_({yE0QmpzGS2_k{;&N1CwXOhCIEmE_J>vefxhULOq!96f&CAs|6}X@ zz`LYFuf@pKnGgVA{7*;v10J{{pc+$qGn*e>4*&q(4gkQz8q&RcnHf0!_%g@-XdwR= zh-TIvrT_qt$d9YZPaQ`XEgG1)iGeWyK>nYO?LQci35}ZnkN^P1#g9$!gI^G$Ajal4 z&h9_Dksp7OANY3+%5z7X>#C>I)41f?D?GPn4YzH)Pwl16$M20zo#Gcg zVAXl%`&9`nqU$ZEY2M>53`A5)LdZMTL~({-k=VRW^WPD!tv3_1LO_Rl-;u!XP`dTA zujB_>C*xsINQnDZQE4KxLUl@Is4&3dBk>WU<0hBvStPY^qm&^+dGjZ|+EtMF=*;nn zab1vA2MkPmlN7C&p}TmpJE8~DC)32HpMTlL{Cl|Tq#CpXpAS6hTJA~2z9(X;re zb|TWiXxwjG)hR65QhXop>t-$3z-;sc^dDZQ_;b6XzkroQLt?Q8KI-=?O|#d7(c+PE z)fGgs6G%k^dM(+jO4d@YE};TZ2c%jHL`=d}8m&f4DmoEWA+v(IjnH1GyyN`41Np6t zlLL7u#UK)AfxIoBGS)D4-0T{XOp~>oqqfoEm`?>zEBRbkV+Q5ZvO2uneZB`KX2pn4 zAHc(Ku%CD1OuIMCPJZK13r8lIeh-u?S^qkvNZb1SdzNLK+M9rxOp;$!D4y-9w;lKN zxIch` zLoJxy7RSBeH3e)3-OrXhu{Gx11!vwH5%PA8aJ0N6y)z6cf8`{!SUtW3x#52P-HB_e zwz%r-Sed)3pTh#jeQSs8b|Pq^S>aq0NT#+dghiUjq3$-!*{D@>T%xTtZ3^~X&9|;j zMz7LYOCZhIxTw9BdM21+Utino*l`-!&Z#Emb7%jT6|Suar4-Pps3J&1DH>Q&lBb5J z4!yg{NHPNYVy-*tp66>6#Uk=qr6L8_%FBrAO}7jiYNB?>)oDO9J={PzSH8b zDXn*{wB3k}|8$n0fsgNfotvlcK^w|W^+3BRg5T5F+|m8i1ns5PR{Jp-UO)T``U@lS z48sBw&>Gy1-{#-Ak-8;rY!2*J<3d2ZDa_6=d5K45{KYkDQI|r)6VcvCjwSv zlaqS#uX%q4@8{H*=G~tB-PusUjrh(o61{e)80&xtQ$fil{;wqVHZ`p_VBh|WwJvzx zHyPbK`qUVCQgB}^c0=%^N48nRCw?A+v18nGklVv)q=H^Rl$gyQb2DUb@G8V0>JdM(&%3aHdnlupFjCAd@| z73xa*+Rc05)(T8jdG+Xy@81D4c3(git@s~gPjQEnvZ&+QaUVsuR-!kjmqy<_?_tTm zo0x%o@x4KAtwv7Kh=q}-BYE?5ld`iC@w``BKif7JtS7V7+Z%N%w4_c~D|f{zcL3X| z^&MgF2oqBoQf=BBOU_1;g*~tnL~t69$`2{}E_nZUqHzWhlP7Rn1xRE?UV^V*T5@V_SUzVG{Z@qEa z?}`E2zN{_4UA@-Zj|fXCJ)GWy6|Eu__tQJ;Cm4v>L)k%eacai+;tVBx19IHPunNAe z>jeR4y1AAG^HBnBf3_!3%@(BDwEDLAJyuG29G#C++v6iQS{NVKoPa!7Sb>%@{uRFM zlE0=(H;GXjRT*!;{fSPK$Vc2WdulxTSX%%4aEo$l80k>iOjLzGGD;ATEx?{gR7F(1 z86|Wi+#TWSq8SqwoUx!OgOHCw&mmU3uXxIJ?<>z~d&+L~o$5ZLycT5n65Kt|oXSQ4BI8X3@hiYn$};_}a#=p^WIp%{t-;6- zZGQDleh2dnJBlhlSE|#+mZ;I+Q>Utt=ygb4!06^#xihgoEqI+VBN2i)K*)Z@%b|pA zw;3+cDC^4peqGQ_6P61i!AQ!R3LUoHuu8?pwF8~D?LC2%uY~#c$p_LyPPX`yz){Hm1 zZ)y~0cgygyIP&BT{DMtpf5!r)9`mi}okw1ZNu1MbpP8z7kPyL{ie8uE>6*V0z0DG5 zNSjCf@{)>SwMWy8c=GkZr|BRv1U;+rA>v`NYJC(WX;qa@S+c9;GzvF%I8^Y~<#1&g zRc;s`j~s$LFI+lCfE-5HFtn)CaEp3QAC<6IWfPxT?xsz7t4@;$ftptNYd1YDBb(XD znADKzB>SYi)F6>0=DoT%W`Bk%Pus+h?>{T{ueOyftE!5vR~9_Z*n-?9lcJzXmgXjV zBUOt|{=!T%J;mhPnyEeqkuD66 zo+X^Amj*>}3pEV(4SHWNo-s6)$!pZAJ|OOJW8SHJi3Y<8bJbAJ7sM@_Z&^*y!=NaL22MgrN2dyouiE_1>TbNj1rs>Kum3n zn;f#6t%C^d{0=dT*ESpFliFOSH)}%r>KTL+ykDFVwGf#B~U`*7?$MnR|D^^ ziPhj5i(@1YU)W&XBd;=hwF;Ik(-MyGyB=a=D?uUNJ|Sh!w2 z(h6+FPE?0tc7*wXBQG+uptjspOd|f3p!DyT-0sg#rELxtw}YSM`GS>FYW0e- zQ2&aMRm@;I!A)yn>oJ=wHF|Db7~T8h^}(@Je2wUc+R{#<3ydXvyz;xtIxAqL*hPIn zoUV>qSWoYuUsb>I#osJ{88F6|a0gGL>DaDeK*P$6*b)q3U6R2BR6lR?G$0wvh%Xxs zBY75P z<2IYPf|2hMu-VY2V?T8v-_Ns>LOydUzb8NWy^Bv65+&$Ug=Q?3P3A0Sky&-vu8gHh zkhmkyAgL-3Ly^>sUQZ4a8+r1s>wK4gde(*EcsGM)LfOcL#$!g;9yzH}kd0aU`y;QW zGgNWRmxld7Q=7j*35%Ec#94gqCl>@J8dv2{vg{V?ZM5f>6M&MR-7YbI0DsF@&H=WH*pqMgU z?}_LAxotGz=>tuJG;CQ(ic~gKJ4MfSZ)*k#nUpKaThBqq@`Yxjns8Ux;ObrB98c5Z z;TKY$b%Ua9{o|Uzu6ox3pOfoGLI<*J7Jk&oYFb_2=gW*ar)83yQXyuhwc5t$i`!Tz z!O1Yg*Z`J|nbfP;Mf$1O>&}K3Le_G}5)7+j8jOIpJPrli*(KDdlo>HFrTHT-N$}(1JAp%v_Hq)Hf#_N=Nrqo?hGgT?c+##$xA`Qx4#k39rSltYMR~4dvR(HnCfbuE2xGrX*|EbD zT#u4sDu`57v>YaihV)7c6Q%_!NKwCk$8K_eIdNRD%YgLgY+d)yv{ifTmylcpa;J$_+mqUya6Dx*B96E}gezusmQ9 zWv1m2wH&ku-3{(${||iiH3uJpHzwY-7s+3@`NN2 z0S^vV^ciUs(c z$av=2nWb$X9WGz9LS;*$uD$eNG;858ev!SZU~B)xV<@Zo2;tLvh5DGbCr~T8VeyIq z0=U)3dT+K+3$8zfMz@YXf9fCHzWBv8Hv`74Pug1hHuEseDg*yvV+4A-$Rua;x3Gr1 zyWdMuKIY?Yku)v7viCd zV^y#9j11_--xVX)9#AK>_N1fC1X0hMBD?bbe(# zN%8@cnv+8D?#0op|8HFCpnJ3Y^~41Kvp&StCWtmv1sPR8b9 zOsTukqLjS(z*Sp0j(qDT^OOT#QI&gMy<>zLaN`jm8!omJOgF4m`QNvs0cr+uc~mwn<*@*7cC z;Fn%=Dx6Pn*$xx$&o4VC_ZCZ zy;K{rCb=w0a~O^UT54u;u>SsMuAmK4ZMO{$w-PmYIMa`ueGi$u>dulj^!|+g9w|1& zdG)BHa6~|gtTk?&VCl2|H%$VEMGt5{C_HfdX_H7=@S1$E#N!hAw7! z9+t4As9PP+5+o?YA6BxC40Q2PF!~G;F&*5Q969UQ6?_X=rk;GHFmv7~kKOf=BX3?P z8}17yuVbZpi*BwU?xqd-lW0SiX9Kg)K1G0g^xx7sW&Z3wnY0^%As^>4UIPZma-@kJ zkHqX#>_wRB+9>9BqSE0bJ7ZxD>=U?*GKDNU%R-5;)q3NtL!32?+gTJIj7B0 zE<2cSL)+7~QF4S0&50(w)^%=>dvnaj!7E|zC$cN9iWPV{u z4he-CKDMXLBY9WEl&S$4(6{Gp;~UivSOA~QwQWqh_2|H8~mCmOAA?FjB=k_ zoA@4P2*TKTl|wV_$<+kcRQOHcslAz1fZqINCW>aU5bD@z3aZz+g)-8?PX#{VRHb5k z?mpSkVZ9zt;1a@4)A90^Q=%!r^;8_0TMNH)50p~J1vRhT4x!*1n)E`7z)R}toc(3Y_WM1^Bc=cD zjUPiyZGGJ6(Xn$Vfo#=^vXVvFvF$Qx>IIi3ZhA$g>G=HinIeHQu@C&8557rk6}-{m zX^U__eS!yy|EtN3_~h)O+QCylO4e+!onn_f_SRRiyR~t})9Y%ewkUxF;?^K{uYV&O z>Q+<%6Dv-YCz-!k?5XUM34z`HR^`O$1sy+aNdZ_MgLrxpqoW72FYgmv~=4i#)h}P2MML*O`xTFTBd$xa|~k%e!xgZS{iV%`bO2PQs*vc}_6Y80z@j5= z=+UXd6%g)4zZyV)1b*P@P!jCmhOg;3U$CjWvF{RM9o#zypI2V4*6eIOq1lk5+#AN6 z(tg^bWH~nfwPVL?oVxned_66Wt@fFNHdEM;{qJ6c=X^?2qWY>hw$esFFH<(DlQ@Z9L?i{lN>TgJbf zRMllC$`7>Z(^ba|A1_7k0L=3h34wxHn_D{9+67qIHswVO8d1K3x7Ya9uU5;PVVj4eKJw~u%+Ml40>YZpwcXn$~(;vv3 z9F%wgj24rZPH}xX(b(b?BrQCY+}?QsLfsl!FZ*A@&FY^q0d$w3dacL3PS)}yrAi8g z)Y%VX;?-`Z?d{@%fFVA=VIZ-Y7-Hm!v_aOVxO7o!&v+&kMcQxRVAbFBNW==ix{VME zfX|zPT(s8f8!L<_du8J2cS6o-cY569Hn+OPY!`eV4jQaG0y1%8F2V9O*j#%~!UUd; zxioH6Uoz$*MIMfeN6lxB7x+v-5>5>^^XqbGmsMSu^0Z3iDv>8N=)sh=GZ;PEiA6A$9^nYAgn?QCS;4ZMYQxcpLnWMm|EB50>DqKoGZ`5m!_9`7CW=ErdY zw{z5ijNL;GLnW%7aSZoV2AXJvoKR5gdv>gHHE|Sn(Z!zeeLAslbj){uK;-NhO?63| z{WvW$n7`j$)7k;R5^(zhR-Zu-a)lrS`Je+o&l0!9-Dw)remc`u+6>*Hf#TR4>8c@6;4Q(7b{o>Mw|8>0x!+VF~ui zx*;yn$NUc89%!Vc<4t19`?Z0B6BhrOpii~atoeb|Qo%JiGH;Th5(C`sRy}P_fo}Fh z_M#60DLLbWs(QBXBcSYS)>r-_*u*^$qr6s*Tx|4n%H|fzZtQrtjL&PFTm2|I)rL2M zvk%f4xhf5HKj~{HD(=8KEgyeoS^~>kZqR$~2(dm}aekvpJkQ~`a(E=S6?u97C+6(7 zEe4otG1o85Px2d_k(?v%9QN6pPQ$b23k%bbSSTfGyX)r?p|iy+RZWoW@0BD|8@^^@ z9MFF$joNJJl(3js$ZvvUAB& zg^`bTwnqbYL@$Fy|3F;~z@S-@dx|<)3wqzy3eB4X$oh=?6peZuMOpX4yNE!rw9t4G zdnvVIa@oMNy~G@=CUnKHF4N+AGPK6%i zZ3|a~K{$%%K#A;IsgYKJ@z2}K+YQ=P2cRh%N z+oIcYFr1qel6Z;3-sY}L?K-rC6ejq~?Sy>Ln73#ADlV^TAL%^#K`%CC zO(Y3|oy825k-^Aa7+%x7=_Y>fJmd`W^0KXZ*F21I!2_0meh%6T(Q{3ViyS=b;Vu>l zznn)h!fsWfw7Mt_&r>gfB`!~Au;)^!ZiDPghwf0eHRbKfydN2ur6P`mU zp7pw!y(RU?@363g)lnS9$qK)cL&Xcpe~%i73t7Vj@sJr=HI3~sh(|Vl^N$XV-zj=8 zmnSC%IZ!maw(~C^k{zO${$5^kWezA^_22c1GR|qOZsf{eD=59aT~>C$V(E<6FrK@( zkD-~{5YvI%f>QQ_VNg{iPySn+fdLmNto%#a;c?hN3!5?g&hoT;ZjsDkjKx%5cT&B^ zu`3EANO8wNM|7MQ!|nm@wp&8&%mZ5}oKvRFA4ZEOzw_pOR%c|!j1_QgBNc#(;nUBr zUNjHYLvEPsMM5qS;LP1yi16QM)*rEgPi1Y^q5vjk7@$!QR2r`c76{>*Q!DHO{Y0j< z?+5{KMbTSw?ULgwCa(yKIrhf4PN4_#yMy`hp;6WAm}QbQ$+{3H?TbNT8hKRbVoIyeXZURIO-0R%|H*F@Kc){Q(| zCHAUI0dE(9xu52Q+6A2VnhRp2rO#L6k8t!8mbxmzolo@?F)gti#+o!a*_CCag{Ygm z{M-NhB`RO2B*WfXMXDj-vG<%<5jK}WAVFdHt43PN|9nO#i}TRf z4h~1O*HH7&ZSJ=Qr?RZAm{+@LM!Pn?0}{gmE(s!rg}Z|xt|{gn&)nJv9-9g6Ie{5w zu}eR&_=Mj#HOmuWcp}thFdE=A-0yo>gXuP08n|mt+~Q|IqgTM2`nYRf%BSi8XKM-$ zymTPv*sCc6UmLtQ;6IuZAJ*WvorG$0DD(yZKZ2VY-%R#jf#dwcze>c>p z2A1!}`7*HKxjIkl3Uz1>J=V*#RGwvccA_6twZHaQh1>88dYMPWXX!~?!xB`p^Q+%F zM4wl#3}d0Rf|Ul&i|;8?-2PQ`^&>gZAQz_mQfwE8<_Ysg{L~0uPvcSN%`E4qmB~+l zjTlrcmkFiSj@vid5rpn9Hu+aimQMM-8ykzDra#>9*f~+0BTlwk>4mq(916Quo=rfC zwkP|JeIq$BapslgN>~y6r2f$ef)m${#y#4m#YUnC;KxbJ;7z@{G!+v~kMuw%n{;H_ zAiqy&HSDCK5C0qG@iav|ArXT8h3p9oMFP2g-k!zpDm`yBZENheHH+Wesg1UK?0XW&YoyV9{Cns}Px!PM~2YO{b=85ube#SLKp-V-Uo?&s&yh zI|%x&@*UyFA9Am0zg!09f}=Rsk}(|~(cGNCK?l7N6nq{#-Ybs1k?Y1wM!7S zN*p%h54^aIHnzuwZ`ZmAW4e**p z2VVaLY}e8ran+pB#j)b`?dxA9Y^PIja{re^Kb8zUS&ok4n}}et5LTM};Mzg;^yg>j zZSV36JNoPS%TijvPj&(`)AqY!d~~w4%5j+lrv<3({7+n($As)&In$=>q}*ApaQv;2&TDqJOTq@UZ_8KMDDNGdI8(unf2bLIdIf zas-M2ss`!-S^&BLMg^7t_5f}KJ_Nx4`3>R*(hu?lN&>11Y75!`Mh;d54h3!uJ`BMJ zQ3eSEsSnu%#RL@xEet&dBLFi8s|b4pCk$5r_YCijK!y;Bh>U257>1aG*noJ8#EE2r zRE)HZjDc*9T!OrZf{kL15`%J!%7JQ$+KPIQMuX;sR)}_m&V-(YevQF}5%iM_F~%|B zF(om*FdH#Hu$Zvau`+%}@Lw$64|s_dQ}hsc9svj-C;tuX|4rWqU*Dhvz=uB^nEwACY8=5A;)5P{GX&C55yc{&{VRvB%toq>8hVB;WDfqXou;h>U%*j~CH-;%Rs z^^{$&+t)-95cw6kJ`3XN#YXS}QJx>ob63Z3RNQbaa&imI=8g}Md|}vp_9WJ<>J(}M zqgmU&aU96r*5+@QENlAf*2NR`$ig#!8W2fevrm%lpSp` zEVZ@by0kjQQ1$`8-ph_a^ZaOC=ZatI7X4szxTK|MUe|naS6E@+f=jy}wO7t^UttpL zK<2MG6~VkTEse8NbN0L{%{XSV%6*CFWs{0lpTV!-_%laF`o{YDo^RLu!l;o8-{jwV zwId*+3WC6Z_G5^u|EV|37~}{DND2rjjkG`j0TD(BHudh&9~l|&2gSz3+=5}~@POHe zC}=HW;9#KOF*Q?rvFk+~d`OH_3<${O|BF@f&N(legA4{P20$c0eE(?^cO(ETP!Iq< z^E(9?QWA)~K_vc20%-1A0R049^Pl!B)RsNhW#IA3T7M^@7Wt=* zoU?{T%x}UBH?VC!zK>KEkRJO!Q%(2yU@4rsy_>_t#(TZ~Q)LKZ>f!8}5y}M&c3p!3 z?0my!FWJ@CKFedKWisIVVi2$2Q_IEq-$lF48xI03G$?>kHEo@PiJVWk%qfCz@`E@@ zX)QQYf6shnRIB_cudN`0-Td`?)>diSYT~q0-oHN{oy*e5;9QwJWqg*=9B->ueI2V3 z`wB0o(3#sLUxqE*aGW2Oi#3QBkA`AmU44=7xIcYK2Lffy|9ic!Z$XcHekklo6F-?} zyU&|<<@KNZl<5VCtxcR|bce&=-%f%6$s<`b*@UuokPMS|8jrbBK13V`P>z)jgL+?89!4g<5urz4z>;c_p#Jc9kaL45v*JwnJeMgI^yP#sX9 z2B;Wk5Qs?Vl0YF|Vi_OL@nODG!*1tN5L9F?b*WP_vYgBZyp|rZ5G&Ked-hikTAC?! z;{`-vnb!DK!%WPzr+!-IH7IW^b)cQKDtWd9_tT_3{p>y<8#fU;D<^)NLTaEt&Lk6f z-Xi&;P&IZ#y+B~vmlVBJVIVsw_O!4oq#F|Dcq*9zin+XQLtNMyL@u7OA@$0zTJc#q zp*w?2fvzdm29CmrGTPk4QJU2G(KLf2q`NP%d7z>?s4Qhl0@>mrqFebiMGb*i*n5mg z2afnn`EU@!Xsy6IslJmCGl5*e`yK1Ko9=7XP@?6DsD$vEiCE;$kPeU>f(@J;rCS%T zlDVBoJOgpUucN(np7odAtCNXEqHm66)g>Y_XFmLC83pKKbaE>|!efh@#!=lvr!dj! zph9(r@n9d7u0jl8R`u+eXK%K=coZG|3m|+v*=eSQWNG#TxvU zLU`{T+3n@Q<*y=AmYElb zZFGo5D5J}fm+Og>3i`pV@YrHU68VKpj{(MD1!0O;24w4 zo7xOwZ<=qB7j-!lzGOc#ZyGa5g7J{RLT7yfN+~a9&`DBrTS`gmn~5nZZ{vNEwwM?+ z0TjB^qNt-^{43QD3|OBDx{(R9@xv&gF=p|3ijNxyn)DE=oCQ6u=Fa{u4=t~Ly{5`_;F2!a~#?5G-LWA2Re)h18D_P71 zl0}WT8!zXu9V?3J;V0yqiM2KRc}1cbx(h05xCd=OyLcAcj@H;aNUVoC2m{j$Iv?#> zu$vnn8%VbC+V#X{Q(CQm9Rs8GerTssZNY2*28Oo`Gr=Ze7p6I_UuFf(BY&?}nK95Z zR1~*i!f-a8<2oSUTuuG?V#<%op4Aq>{tHeJNhb}CjF*@q9z~8HFyzgf)*$DKi!5d6Iz%P zH-U||-utM$gy(dgxY)_?R0dgT-`hpC8`3ArU9{#t1i4UHwJ-xdr4&3IJO7$7mKtNP z-iGCjuK*=I6YI2j&#ua(UebJ%NzK2#oy|77o$abCwFyqCn9BHR+nf9fWGuG?QK;BZ zok;%|l>{Ik8pw!6C&B@nK@fz@qDMsqmZ+h$NYzkERP@$@nTm084k|sLd2&7t{X{0R zqF%VR0I_C*t2aWZhf22DFdDqTqK6A^Mc*e^r?C`y9{rrzrhK45nA|*NszKart(Y0_ zgt1CqZYMX|adM2rEb=Zj$TnXMFH^)L{Gam4WEv|n`!Sc3aNPoo7@s)!8*a+XJ++P; zuC_3OZ4N~98XMVoyV1cb@52X>=U0i-P%p~E4wmOlo{e%{$8WK$Zo%p8++zYRGhA;W zgsvQjZN=QVE^8-J)jxiIU#=(e34Gwnm8`9G&R2Gi_D9bqI`1GN2|pqJ?rW^0jPQX1 zh<|q313AiaSs0thu;m0toYk;lN_GMGy+grb(|s+Ib>uf{XU6*~+wTzKG0&}Pd1lNr zBl-=$2P-^nApi7MrlKpJPk>elDFxPic<6$O#7F>U@g9pkDc;vy$vtZ>u^0u?E3at5 zx&r3v?C8HkGsn~J`sR=M3J@{{HX6nW@4zbksowuvLmBme1N$RFrapb^jW?v;uK8_# zx5?xwe2Ee2q4Yrj0C;d(|FhOI)YsoJrZChu)i>S+t-}Cf44xbz1UnF1k%9Gw^&+$; zJRP)$9y2wVF+>fh)4W5=^Ax4DJ?Cn zwSCGc#NP4Ucb{n=l!p7wBnG##wDPY~o0_VcXaKGYbv6E8Nl2?Hi@tgA@N8SeUGzFJ zcaTQm95MQ$yvguQ4wD{bKKoY*kE{)X+>**~eG^rI+R<0u8_pL^_O(QDHF0XtOeNYN z>;;~#Mov8ShZ2m+=^R(81q;&cvSnOo#25cDhADGc#)y> zBP``B-u_vi zJtX{IpWKdbA)sge7ZPwinWsE@4>ctD#jjFaJIiVBQO#krOiXx|NObPKGyl*Q?}ZgS z4*>pw;Q8z+5uStZH@lfFP}ype{Lizr?o}27C;|XI8b4d9uK#S-hjiMMH|c!YNuG|+ zWsmr)!v>H`3H1VmL?ec7_XMG{%f*cueF-)0tx+#%k6MB(F&7NrQPmuKGg{kla;s99zzj6 zMA))8;;A&?XTgw>?+~w4ijH#pv#Ou(S+JuTfhf>O^sW6;Fx#b2@rkj)P z-d}ewUs&r@x;?8bxf$`O*x4$w9`>Zp>GY6YYWOpppm0Tacj>9iMat?P7M zeq?N4er^2~ix2%ro%X&YLuBF*x1rn;Z`+whNU)8Qx?Rs|;h>c+(BThy{Z&%F@&w1yt=VV>r?H~L?6BF>5 zfJa7O#Hzbje%F80X)XY&@YP=+`+y2QQsM%pInqCr8y^i@=8oQ`C%0^%Ub%S)hpm7f zP~X1guWio2E3?dm>`7kJJ;Y@9;7<=tN!J0-=kELQvE7zHBF{AQTJXu*2qOWdrif8+I3s)9ni^D z#kH^$TnqQgMRvcEbW|EmSS4OD{6f0G(M!k6sOlQ}% z*;c`2gC|~H&<{<>%StNx;=zm+u-fT(FzM8F}SU;Atw&ec}8x^On? zguk%zd*;cMfG;)?qQg7bdxubOzFO?ABY$##DF5;Z=IOnjbPqK?S6Tx10xv3_0h&v_Si)5*QLc|Uv&m&^8kq`Vx6HZ+D9Z7L(kv*uQ>6qJ#+Jatmu{(X}0MRx#^&#bGc zv?`WG3*qv{5>wAp~q zyeu*@;mYg1NfecNl!;l@@q>)gcrr~@76o^UA>2`t_o{DomkZSVqAFeMxO7_*+TAVXR&@vmp0(C^bf-eNCzWa`UGR~+ zK|`J@b=TCTJCPppUWG?T`K=1ohPbYe!;jXBud>X;YPhbWAbVyHKOEyqmr!uV5FUQ% zli~9sP&M#E40D+q@0`Fb04*_r`_8-*{Sa>QzdC!$9cdnJ?J$)PVj9ygIf297MMbSw z#%I-d@_-%)xC|n2UXalFIg1c@Z1baqZ-x@sW?&hp7;?AiN&~!LC@{v*fWo5&RUb}H z@GsWqBt#64Xe~q{FrgGPlwpplSfCnKP#vqNfi={`I%?rc=L8&tK&a*Lqh*RfZ%am9 z)|`%MjKklToiz@_KMz|Q0j9#*ET~=|NmXJcbf67gQ0Rd|9~1_lFa(7WDCD591qx%( z%p4TQEn4^-(n2LoSjn>_71^A*xdK?k%NXq^E@^p;F+KmU7RkDHP`SEaWfW{N|hXm~Zm zF@PA!5*Pl`N7wgex`x5E-}&5#;{5RM3QlHHr1U1JW@IGcwy+dlUfD~bEp5f!+)@=& zZs$o--jjQfyyKuUX_+f|EuW^H2)c}+FwIuA7Ecv1SMJJ6S}D_vC-Y9ap^B8;`D`U5 zp|c{XU-><;wdXTRzhT5uv5;X<#Yu=L(aBSLMZiSDY;5=ykTfOOF#-4J3!_p zp=>)B&`oNgTh%Y{*+vwzR@07M1jQp3RM*zp|AA@oWkt?ML&hxf*Sx^fMz1mVom1BE zR!_T^V2Y?zS^b2zqN-vkmdFc1dd}~?+Q4HyuA^o?O=ZR zg6c{!LNSNd3B)WlGyU^Zm}VS6;?&^5xfJmRi2nv&b_S+e)sg*;*yS>@j1;rm$Go95 zYi4Odi=K7jc#RtRTvNAMnzzKJ5=X!bGfI9@V3`|3-KPD~Re70v1rMslaX_ipz|jwS zvnRv}Q$#y?uTm!7BCg|jQ^|XW0=P-=9&-`W6aXEE8G`T(o1{XP0$}6hJGdl38Nm$^ z@`eHUp|C(06Am#1M;L-*3}Fc{tZ@oY{wvoRuP2O5g^KD4xy@H z8>X-eQ*++}3LRn?hmH}TQv~QdhcKmZ2{X8c8Qj7Q?$HW8B0zlv^a+g|USSUJFo#c= z!#7%?Uj*nML1r!g@NfLyK7Od{g=q1$Wv#S`S%cny?^NpV?0_(6K;0a*avL;l?BXZ5 z7eMqTs4rmxTL}tf@rF5ClQn>KajYU;CBm&krE+9l9zYjvRa;J8Usn=eH&7w^`5lF{ z4D+bNG=tHZZm(I_Oxd1Z8ES1!ciK+cne<30gJvNIl{bUEXRpoYm6`I$+|c5F&-&u_ zZnE-yz#6kT^>%#tG;yU)sU|(m-gITGy*J%qwF0 zvF`ClrurB3;(S+ce7#FC#Mdq^zw*scomvf62>j&$E<<@L()7Z|25_iJl%Xv-68Lx0 z&bYmAYH6MDOcC!h?c$hxMs3&GK`vy(AzfX?xuli;o@#wfbv7-KIRXX~h)#XEm5mh& z80$lPtOqAOZ$BE~Q)C#-z~LrG;ww}AKFh~g|H@Rn#!g|Ao45?Ikr~5B1`k%+kCY#m z&UvctPz&wbSN6CI-i_0)+_~YvcbmTRl~Z5+PV0BSdRBFqI11Bn%2XW@zx-b7_svk< z=zwsi{3nOO@1NSS`SR+npjpdej`dRFS&vrQz}42p@HIPijo z7!d*ZP8g-vup0vHdyVha83yh8iQ}uC`=k{4fB<+2i)?e|*0522Vgb~N{vvYxzIH*$$}#0@zd`9@sYKU>UAa$WoyJekvUWOG0hGRWEUQU01{_ElaicFLJ;OvYmA=bwpdi=}e3vRvoQs z2ZBc$;gA4j@q8XurOT`{j(OTniTVZ3&21xpgtWN0;Vz?a%rY*`KSVCCBkKLF%L}_UKE6Zs ze6B2-IycOjkDdD*9SUBke0qJHTAwsWaTy|jj!0ud+9h02CQa(qeCyHSJJk3s^A?$? z)Hb40OeHS(kFo&m%hW=O01m`W>U`l(mEOI&MVGS`yFNRr$Gk?9%fcV@$?Tj*KI_}4(2 zVhaNb85A?tV7q*nH?wjwG%{dmDih>>SdGNBe_k2 z>&pU>UF}W?e~FW?TWAzX%sF2@g}SwcRH~fein4lnagS=Z(G%MhZGzFJJqC)FDz1n< zslQHgX6^%bjlfsvyq=s-Qc>vHQJ^uxp;!p!Mxi z0eKE7Qa@NsSZ40#fn=}vw@v=*B=2|%I-|309^PCB0yJw<>byqjK0Lfxx%hAk3r8I$Udb>}Z zM`Y7?{p}1daY5iwJZt|K!X>oP8{{-q9ZqNCj28_sZwAU{kt_+2=gHd%-%wHb#y98b zgyG29Z@eKT|5)`haQLBitp|tm;>~Oy)O<1Rl!0LuW;}>%KJq^1_OPpBDH=v?-q-K; z&nm%avn1tIe}asG_0dtB7L6tRu=zK1>m&nv229t)4Osv;@U%&f`n;4A;@u~p z0>idTi)zy0wm?(nRX^4TpR)D5>J})5-I4RwZ99w>wk7zJ+@*Nkk{kiHEzgG}5{w)S zRB|aidoc)oA3f2oJsFLDh%xa-MxL_bdps zWg+OApY~XRQ9dXi-?)p+%lhddlq08|R?wb-YPXS!0p#IA!STb;b15h?#~x&}*hPI^ zufliGG(w;^ftI_qcw`FQ?j=5b(f$BqgZ=pZ>9|X>G}nsX zuq8we`gm$TPtubp;aNsPL6uvf^lTJ|v^2*lg=afBPrCb&ed56nZ!TWXmlp?RhZ_5- zFD4v<+>y{h-rC>uG8mUK$T0O|*%g%ps&%67w1cd`LY%Zx9FPM_UU(YfiL%m?5iXZj z%9RuoXJE$RRrt6)$atahoxzI;)htC_?p4G$?xuZE1Js_G9QryU8%d{-89fL_r$UK5${CZ4`TM1(mLOc|%n{j3ObqnD_sYQnRJxfq}C+=~4I@TP6qv(y4P@=7uu8&Gpm2486pIb8DV5*L#=F zgdsRIgy+EKrw}$;2Kg%g@(ku>oZ_SZ9dr;0^p0VKWh&cK$k%-ifqJ(XDsQC0uCCyQAyCmZoA>&ARm>Abd|!(TeFE%I;bW z7CvNKXFJ6s!WC-61>dmz2(_e4NxW&y&ZQ(Frp#e@}HIs+rhh{dFTlS%+v5WH*v>Qih zZXn+U2Q=xu`N|3b)w&-HvIMkSxXiS8&>Gix%&;?6K$$s`xS5pU*um&80w-im_8&hn zeF8ZECFvS6lL65{7)<0#>~Sp&DP6;oYUDw2KT3F>y2B}yiEwU=G3&Vu?FB1}DaR<$ z0s`el)SdnrO_V=j%gm{HNp63u(o-DhYn_Q(Y~h4ye~ByE;g(-l*zW1V2Bu^0f<@KA z9K)=dA7%G%9REnWvU3G1x_SNbE!L@ox!GMe*X3{Ca&@;Z`zVuhJ zB2P#tVm%4w9%4EW;bp`)xpmD_YO~_qaa#6-a7#I~hPaR&Hd?^gE7{M=P8wk$%p6uk z9Q`M6g--(5A&Hg_u6Hi}YxvIASQ76m2t z(VR{wVHAvar$P0vjaYl+{nl>Vb6Xo>m_G0e*EXhQ1HZX$+uD#25H&;EO|1#9>K$e5 zndj}pVgm$4`WFfQ^`Xq)7V|c4U)1DuDjr!xx?r-+V~bU`BPtN05BJaG@s;r$e%7Oq z->J73>YBm%Us_>DV>Qs!ZXn2xk5Gv!3)SWgU)v>I(`}Q!V5OZJSVUySBG&L;U!b zs1CX?Bg_3(shRm^mzpufu$G?^+2zU-kCe|4NFG?_Pvn}1{gxu9qe%AA-M2jhG{Iri zhO&!?b5G5_@I}PVgEx*hJW_Z4wX-$^Z>B4R2@3vB!-ifMH~rSO(zdAT_M_ftW{T&v zo^Z@N-r-4ix>Yull6Y176;)xg|NZEXT->>}-*;qFrTOH^{z8+xHSKB!S?r=0Jravw zdu6_BbrsSFdc1Qo14ZiM9AcuE<(XG}Z@~fvc8jW#s};p!X=RnQrllj3V>^WpGc6oz z8@=Bzf9`mqEL30ZR9Cmg>&xbiUcM#!e&2}y8MHI)6;zAn>4oq>0HmPI4~uhqFaUDODpXLE8Sf5ZN><&1=AZ9!?FJ~->g|ie5ybHRXS@e-DYbk#Xp0#N>2_Vvv{=To%C7S*U)?ce<6=t23Ryi@j;h1 z7H8EYi;l~;MIw>#g?eQ?Wpndq?e=^w^u zH}_SyN||}r)bz@#r)}Wo{(C33?09cZ7hm6E0LpShx69jAI>%vTH&jij8pa1@IUsuf zdAF@f_1Cs97JQ1UH*UnJ`u%N|+#VyJsyaLx{J3Ygh-aO7N5TJi?5r@4yorOOIfIqT z$12PP8p3K(->FQdPt}03{c<_(fBBb}uUm#%%aBPdpmbzS$x9D4b9?%qaY zex$G{|5F2&T;LB`9*Wp%t@3+jY+`lT@yo81aj=FeL5YDQxrSSieRbk3*vEI zDZV#%_^Ja>&$+1$2FDtB5nG`J^R9w^@ufVv$^43tQX@+rUYOxm;Hx=m#Gke{hs&7` zSV~J5E)UZ=GtUd9*sb9e7Os26(OP6%cb2oF`xI*Ml}DtSyt;Y1^b^5yjyNy!9Q0Yw z+Y7F~ji+zo-<@UiY7c9(#Y*@3s_23N0?dl!S5ii}xM#@lUZ&xarl87F$l6!x*e0Pj zWw29~4OO;xz$1mXtMwWOH(c9c*Ktt?pI~N95`X>q|CL=+k(*@7Aaz4`;X>fFiRk(D z;S2azulblBeF*QA?JM6tZ`&7)tlr<>b+z&7D@Ir?u&9mBSh2YVw?<*rwwaR$tu`N<6%S>2%GjM_H#oOLeZKH2!FJBHEYm6$kVc@2Z)uR-!j~9le<~Lv#GsnB zNOq9=GBEJ@i^tGLfBjsKU9T22>=kiT#?Q#r@er5qB8c(>I%S;NWDW|tZhPtAu78(7 zRBqN?r4=W-BNnFDifFT6#Jo^H^Qgn3Dv``zS!0#yv#o6WNbp+7!Qpy_ef?1?HsNY@3hUbVmroKybpi#Tof2c% zZ_N;#Ek5F;bU+!Ts0x!sOk>L)pnEho;V@r8o*7|B*+?U4 zd8T|24y`0--Vx<-ekYCV{deYOnr$5A!}Fgakz$G>>C&mTjVzoOxFgE-$UPmN53g%WUr8L<6lZllHU2B}rWo$N$u<+$`6|c(#ge{R@)Z;+u3^aw^BMZ(3a` zp*qg`*{pMen8sX%8GLPI?!qH{&4F?m=vya#7~8O3^yBcq&?Ikwnkya(~YB ziq{u0CCSjGp#3fMhVkUXQ*3X67Wo!FfOSF`+?%uwo#5CvwXTEAP;HT(GgNk&!DC~_ zZHL@ZeuqtnhwR+BV|WkpC1h`#NfmuwN|+|SSCBBsS$h~tQRLOZD2@k~RvSCZwf2Vd zWsVBP=7*5#=rU)5kd$J6{YK*X&&CgLHr#R9Lh$yX2X|SjF|6l;mxfnj`A6a4GUAOzkO? z5;jY7*ZsV6(5&27Dt8N?g&u%a+&YpifAmd3h1CEvd9{iNxwZgO9bN9s*m+-EWurW1 z)&n6$D;iLB!4mEk&mv8;TeweHYxH)`W@}dvwI$`8yR0OrcAop&YO1BdY^5bXAeNhiI)(eY$x$yQ-+6pFE$TXTc6w zng?pKIt;v=sSS{#c;O`F^+z8gB@V?!g(g^ZP7?PTf1C7xSB&RgZfY;f{+gRT7mc#3 zYz?G^7}75nnHWEuVt8FKbh_R07o%To`^!8Y9PUX?7@v|UUtp4z&-u$s_&9^~9ih&n zmxn3UnrOAxsoM(DUmwO1hH=a;V^d}n9D1ta8O<~qyO`-uGr&h*|M8&n{ZGIBsta_b z&W-PVom)CgO`YgC!?p^C2$|Lze91^%_q?85mmB!YlwgY}UU9BmVY1+}P%GmjaUA5$ zxvUlk9*RpRJlYCLfi`c9TE8^Xm=p2r#=8#BfNNkRpC0@$P{m=wf2!uW3ZHjz|3J0Y zoE~Kt+u@$#C?V>!t1hx&e&z9L#*~)URFXEX4cRw)}S> zLV;TrOxS{XK{v}&68Beyic_!s2!XOu@7BZK?W8Tv)>X?`Nz^A>0B`bpH;Ua)t;#rJ zZJL^me4ECgr8;%>PF?>MkhoM7b~+QVN^uLJ$*Qg|IO8BX<*}a0EFem!+Bpkr`W?0r zTup04Wd60m+7t~2ZK6SG_F8jqXgR83h`5`Rta9dKu0Q_wWnLFNWfQZ}D`9fs3-GHZ zU&xc6!aRR&3!?EN!#h|F#|#K-Oh8Xhw{M%94mLZVVyB9t9U+k2_YSjJvIJ@CQ{`N1 zrKp;kD-9;EBwh~-I49TNU9%DqdwkCZ)bSi^sLuOa;#~u^2i6iD*;kwZ5u%sA>Zotr z@;hP|AHHDEmwj&>Le=%W$6b-?tgq!xJC>IH1A1WQl|D$)KK!sr>~vI)g`do2x5iQp zA5C2WpaYjbIQ(0Vvs5X#eS~SrN5RkjYboS3E>1!&U%Z+X+PJ7w??rBS>{1zaLX83;V|!etuGWVPWUE7UNr`R3XM5ygG7dJH&eF3j*mu%=OmVuhyAe z+XGo|zKYJi5(wM#f^FsPu*k0CPtU0(L&5WNHgu71BVz&BLdb^1niUA>;LYd9d-EgX z5g$Ch?MOuq>^*AxP}~zgd#<$*mL3+r-I9d<(hVNTt}MEFfIQ*PO*?%C2R@)5pw*B0 z@!;k{p@F-->?37Y)yVX3@Ql+Kci)dXD|$5 z%K5S@8}2GzI%h@aI>i8R;x}!NY2y+lBJ}H@PocJ53g@0gzT9goXtzY_R5|nL4Sl6W z<&$>pFs19;Yggu*tBN`4P%h{jT+(kc@GV|O+hDd?6W zcOntn(Nd+JCa`B3YW!`8|MVroAIUiI`r?_Bt=U-ncsDc!T>nuRzep#W8pAIDpQL_w zp8=12+=6ReiJVa22kPyGd2<_H``A~|lop;j(DJgS+a098S|=p2y~ zQ>Dyb@I~i`sDr)hT0j1;wTV%vJYgooo@%aCTKLGiu%p7Q&qA*=>+!%^iSe$-^Vf-~ z8cnGNHxK5WAqW*tG`R!;3WzBAEJ%X51#)Fp$fYj(O7`r3sOLwz6Xj5=8Mz98{p}R; zEO37Z%|QB2xV8Nc(;FIvOAbfh?_-xUHMgE?jOM#U-=g6{=o@iMp`*+SCjN)GLEIQs z1o)R|U57hoJ*KX9Gq-)i(CF@}um2|s$KXjH+KS11MWb8wbOt_8`-aE!_i>CB6gEu` zOb&-ZtuUT;xm@}dgO2udRou;rUk$nvtNs~G9cA%cdKrh) zZ7D?!Q-6Jk#+TsehP0F+v0wRgCNCmlfbP|gC=!L2LVR6u6@x9sW$DvGdR}k{JoT8w z6F@iQ=E~zAxoo#en~~Y!fcwdhawMzkMae9Qd%3m=T_^@4vP~8>5tY>Wml=S&&tthY zg^T!(f)iHXOB!`g-!diVUVm35<-a}g0#)uIS(mL~#OumWaEcnS4JRUIAiR_02)`uE zE@PX@+lO9iTSjhrik`P^by4kiL1a>s@99u;yA3E2@ctNXf;gvLs&F?o6ruQ@gjDm* zklW_E-~43u5{|sI;)6VEtJNbvBQ~wm4_*S!85gWZXj@$lS^a^jWWGuJl}<_@ys|jl zfaAhRgCuXW?FE8`V3!ZFDrRI^E2!iT!ad#$a#0Eu;G`Q$>!yL@^>;61;842=T-8t$ zLyR0PhiabyGk?S6F9R)&t(P8IXmq-Gqv&*N&jn1%pgI7P@IW7?<5ICL=@%F!SkN`yGJQ(k6cq)$jj z++{)ygb@ZOl!9laAV*ZB@6qd6w;I9gm8j@GO3caBNK3$Xyw3gr+F+AOy1_QsT5_@3M!0J4uE1v zf(M~qA%K}_T}~F@xNI6p;Zuba{j87xA)rW2Rq*LZ+nS$4kD}ut1`$XI=?WA)LI+I8 zAOHe*dR#9JO#DA3mi*I+usZ+%3l{n}jf2kK_}?SHZUTS;1<0wY+Uu4Y*`B7pN4iUE zx6vcpRWoD@J?a-^S;{q_Qr}zp1XyK-xmVwK=s5MKxrkIc{`_qOumy8Cfgwm(zzhbE zpIGx5uuY2(UcLQvQrCOpVUVs`6b}`$YlnC>!wzKD`k)__3a1qPbL~Z{-2@|Bw%g(k z#m@E;U_pBkYbeJZ>1g$Sw?7u_O2LM1H1wX$pTJ(dtAYUWtl-KYtZd?l z11}G_g$8_KAcWQTvjQ_r>6(QsB0$Mq*B_i{=B|_e5%YB4h#$KU0IC4MFn~ZV7Gv^< zStj}+nNxskz)Xew-@M50dQ%oJZf4vEO{v9705^ZpK|(QhDOfWAwV2jHmNSV1Y74F3 zV?jnVPB;WO6@u;1sZa#ZoC@Rd)~Rr+WSxp&P1%~@;HmiP%;Kj?U>xo#_3AUGUxzmB z1_>xMQwmEj@3D)huT+{@`>OG=wy~(>6)Ff%ZFS?-y*ap&_&pFs{K)&8$jg>rn4kl{k%S zyq}a%ucf15v{=%?owhpZ5L&(3_t+d7_^>D~WVfY(G6((b#|8BA0aEEO@5&H_^^5`mX+714k}%K4h!Vc` zfC?Is&`L*k=#L4+Xt&_a1i}DhV2EdsZ~->nqQY|Xp$zJiC{@3D_cc`n7@_e3A*M z`bKAadTovWQ{#074gn1V3kQ#Yh=h!SDhmxA0}~5dHV!Tx0TBr)894D;C+WT!U<21_4^m--^~Ip zJdkUT83C&E{3jCy!EA@cYG2ga2VMaJn-MyU{k{hbV0-A(hr{hS%l8&*1FteMk2kyY`uxci{L*heH_Kch$)h{buBZ z!|}<-aedpx#||FdTRL-t!|{Rd;UUh0drlm~d9TCqmX zt}PA+Eg#);%`x&-Ye&Xc4AKU&7hvT#R9S$XO z?D&CW2VS7JI~PY_sH2R(U#2Ezt2i7LU&U9f__E~(_m|7mJo9g5@?qSw)j^0z zKkEoM5)Sp*c*sp@xhGJqSIQwPWCp1sD{?kdEKqhXgfnucuyrt2$?-Ek&JWQ3Tz&u(qmBZZB|oMgb;KMEj8;q-Y&1U~ z%?z@kFjB4Bs5k2MY?TdM{{z!8ua7y zop%zi->DLr@{iO>?aS<05Fg<0%cMnr>R9F2;@IoZpWCs0)9RU|0Nw(Ug0hlPG9hr7 z6{?hLwPJx`l%cFrtC$sj9ybBc{B)y^>&2|ezQEbU%+|7nEWa3#%^)6Q)vEq#p=egh z!2IpWV%$=|otk83J5=J^KA2fHoC^z0smp&TC>BzFt0NlHNKi`k%WDp*r2{kDcrtX8P=z?yWCTos%Ry8B&Z=gyX}W<>i3)i5Exj;Z-CgTH?2=yyyw zRy%e%T$B3NwX;*hgWVyq+(Vem6|G>%znSi@22Nn0Ot(Mzaq>)Bdv5?#@iMFCG#%3!D(_zCwhG!z*!IHTeIdZWrw!jaaf z3qkf}#)bvl_SFJ)Z)sA$9QCEU&CF&|>OE}eBP&u%H1FX}PI*_VD?OO@ChL{Npe8q| zvaPvyx2131x8|sqMxE2uucu-ztzgiociVS+dS`0JmT^&`Qi817x+UgnuG0w7yfdYI zsSF1bWD1SRKi5XW-pRtXv_?vS4`D7jFtGB&XFYNJ+Vh*-|mq&4f2CEcx0 zg^0kl=YpQxKI+umZnb}d?3N@bN<9DIyh2WcV`F%JK)~|@^?HMGB-32LqnCZkLMj=r z9`Rkb)8iGKGIjRHSG`+y3SQ67>wFT~c={hEsBDPNYUQ49wZ8mr+|hjLbg^2&2u+Nz z86%`If{%{?8kQ?CJ8ij_70&G-pU=yPRV>U>D#`+Xv=qIur|5~g6M;ilg$*aA^e2Qp zx>7Cv&F#HWx8zC1A0UMI9*R3%qJi;d$sl3E3mn%=TrdVP*unfm~wxqmjUCU-88mwI}Cq5XR}Xjtrv)VXy-v0Ar>(u9Pfed!{yO zwzX=cp%tD`gQiN!a@dEbo}yZ(N}qbt@=Iiv?l*(dlkc+i{JWl%g6xQBK~oXl^(01H zKHntN@jgciqd6IGH5e`ysB)IMV6&JW0`ivk7rG;`KQqPs&PeOu|#?3P$368V!UQ<|gK4G7qYI@eF+db6{Qg zD-7~R-9bL5!R!(8-Y@$#KR!@$ihe5?bZV^wt$4}rce{kAn2*pm|4ZtlcRNf+AAE$2 zr86IaaBkt+iQ%PIWuAdmV0e)gW~)NnMpdDuiv^;)3+jhWDLee&M@s%cY5kaVGBQ!@ z2x>%?2XpnPml7(_yGiVCdm48yx$4Q0L$k-W*JW~esKcDOvHVa^s;3k^sxFUQo*Ba2 z)?k7^rEhgaFgG8=Ub>J{pc-q{EJU-0k-5bBd=-;?Kh*kY&~=&)E%W*Am^0iVk=_O! z^q>FfYYwS~*!phkyG@3#VN6xRESq>{r-5e%Y=&p@!I@xz4HTt4vpSS6n=Dw4`$fzm zaRitU+cU6*y|CuQ>J3+V>8+kM`LrCk z{o*U8ilwMDJ;mNiZ#vUMel@dUY*_anD~skp&p^mp zwrZ-_$PEnS2P{ccjbUqesNquyl>&YR{+M%lt+yBs)^c4vjN4LpOVE29Nko%Wdv6VF>Ym(I+bw4ft+*!0$TN`oRZ2AjqQVk|Uxd(5+jye(V0( z%RurS&42ty=zofffB*OFh?pPSj!+4-2L>hjHpdEJa8WmtH;yNnSyzyju`rY{=WWjH zHCW<0zle8kpc#HMrrCh40JF65$Hbz3I^A6nq~dTj;e@%Osxy>c)2(Q33%-O194y_i zdX-mJw3Sx}I${=tP^SIO1E(H1vFKvI*7Gmj>AH`I$%Lyr-MH`@I z??APB)&Bzwb1DxS`*ow#;v=-%6jS2~hZ z^Qn$*V&)<-w^vh%8g5K_6$S5GQ6-W?XisLQppe`S4fDwDWqB|7r zvV9`kZX@b&q>98i>RKi2dz-BInk17k;ntLQuWckMNMmU>_P821j zzM=0#&(K_uM17%{UoN(e_m=WevOUy0HUd3J+uG!AM=$&Z_1Uq(R0tf?;B*JvHNa*Y zAnrHtIWhs@jDk6{c?JNy#R3$2Iz|4KkHpfwnSdUVh-5}1#i^c)_cm7csBbNL-a5H@ z>Gnb@(V6zd2K@4{SCExrM=|7;jZq`)@#L-zC{dR)Hgen5<2e$3Y;4W9HWp?klHJ8r zw~rj}AFop4-skUG<&UJOM|WFn7Tki8Pr}Y7F^ic0Tm;SpmQO+9k(kZrZJRonE!!5g zvvi?(C5vY&ZR`4}S6Nz&HQ#jnnvYe&SW#$0V2nrmXUCFlKf)fG3t0`W1(&`?9X2bo z{Jf$2^KLDftMs~b-AyD#DEOQbp_Vgu9u(hOHYn(eD-$QX4b80(0a2hT6#AlBL54ot zJ^wzTgU%t>AwL7t3R!_I%jR=7^W}1tHl<`q3W=f>5;}Y?we^YC#|2Fj$zn21WXb8% z#MZZ3-}aLn0!VGh>3hc`g64E-;v)|Wrs34YH@{iG>$Ic++mnu?!Z>-O!|4bE1Adpp zbhaJGq-{q{;%v_jg34wqD3OEYAl$Pv0~oyhnXJ?UaND?Z_C3vnZy=}z=D*srS;0Mi zZtZz~g7H_rP~>w$q~x#_u_WE>@&{@67s&c+?{9rZQ2cI<-XUt5(E51mlN)_5uagFL zJ~6WN?V{>*`AF+4qUJ&n@(2=Q6dX^;cjzY_6-2Ax{d!nol(h8>7ie48GZAP@K>?(}_sbWaZnWye|MRqM^r%nqAk{cZ9TeNr38e|mhWI0ayaYxBf z12)S27kCpuil0%BP0DW~p=Bc7!u^bLtxzmxfgpC0DeJ6kl1|sv2i#h<`fEv$C96Y~ zeqF5^{szi4bN#;KN#H<3VOem|_Jvm=olakOC@X;rIY{s|rAU z>{Idk|Eg^~>88ZIowz3knnur`i1WWWLLTqRDLc2XTd(boZNB7^z5BF_=&>e|<|fsU zPu`s()JP94>c}4U5z?gP%ln5V`k#abzi~1|T0bYqtFkEU722YI=@^GTK|1t2`-U7~ z*#dYbz~g~faX}CeCv!g;Mu6SJ;fFLZ6*L|A#?z~(U12x_qF*Euk%?Fm6(Wyy7Kh%v zq+Vb0mbkiOAfX7|f-t8U27%!q_a-ADFJYPqNtE+Y+D0lc%JB$PGKa7DgCC1O zYdDv=JCL&4Td!J#7kRg-hoFNKxh zs&yFM#Uj)^3?a~Bdq|K$3AQ$W-i(*(zz)d{xNADcE`LTn? zEn00}vwWrC7S~TkHSv75lLc*}x7c^fl1xWOX31@x6EeBS)A4@iV7$u|j5SmeBxBlB z8d|>Y?Lq6%hW*7DDR?w`0Urv%;q6vnS@z(Q2eZo(F`-s&!j&Y=0~^B7+8tV(7liHL zMCQM~8rKUsJ#c_M50>CV@VcOmd}$WR-V=QLBLN`X8F=LFLFW;YJ>pzAWB+Zve1st# zgA2_c|Cqg>d66p~we@Qr<3<3;+qpEz&mh-zHf{#F7eHVGy(Q3kKIl4r+!cKMG4}WD zL-9D!O@%h_;3HK#KDS!8{&2`21kPhzDl^B6*7^_Fm_J%MB#! zYl+zN>C*#ddAfW&pP&?G&FQ7Cu{^QJIHeidHDC!bhs_;1%z{wPwchfiLr6Dd|1xV6-;`>%f>>dIxw z3nUooK8NepKhd|o#fEqPc3mwjp8g2oc&9}11#&NN+%sKp8jwc;Ig(S*1wvck&!L_> z&B$HQ)5$ZR1EI}FK4iM@7^umcyAlS(yrcC4u}xp78g067KlAqRWHF8>m+|B_Rk;yk zLTo{o1Rx+lNxIEaJX7L>pU9nFWU_dgWW@bbw|3+R(Iqvu^;l(mYfP1i3K)E?Z~DM& zr1e`#HACue47xCJY2?M${K>bxI3k^8G>e$z%u|x8(siw$w|>UBg=t{M_l#R!1sx>Z zg5$=ykLR>~UPW%}06}1!*oNxX+f;bCmyshHhms09{3pRD{OCJvSda;6Eg|F%hV|Ch zT7N4dS|dS`#EJ9FZ=1|Ro&TkfpdUlVs2_enG4AGepnkrUZ$h^b-nohRDH^}Q1tJBpEx2eRR-!xTE%J4|?2<_Zp z7N(yI#o~Y+F}2Zkp7RJ86@XiTZ&kOQMDBB17EUyv6PPOJfEVG^0?7(bvIqe~q4|-{ z#aZMbp*lU8Qo%-V?oW@0Y@{a!jvAqmCqHZaaA3t?&pX+??~YE;$f@_eMDI(>TIjaf-{ zdBcebH*x999vtjF)e6L7meXl6I-y>(4Ro47txtV+@l;8NCvgFt&XS2aZuYBf-jayJg@5rlkG;NgduhX344>04&9BzQBDL5n=1q{{w*V1(77d*M>n zilX^szphBKx8$A~IdW-cePL{7mAPKlY%+`P6+N|pytNN;VRq6rFyX5vOq7FV*;O1; z$fPIWn{4_Az0$m+NwQS8Ky^;Q28$gnR*Paz zU1%X4jmr=i7WlKtj;%M`@P$FP%;2MwdvW zUkXRy84A&lL|}S>iA{s0WS>DZ#J_9W9qjBsVv;^-5O+kj9u*LGP|-KH3N!D5e*PtW z7jiiZSyYyiN2P&#VxZUs2APFMc$wKQlfKJr>SnO)8|r=78-D&XVeiAeL%wp*gp>B( zU&!*$kw&^WlXgku%s(>yM2kdnr85`H+$#WAt!!&Y#JaEwA+8A-`nW=3mh+r-X3?ds zj&PFN+L37YAOFnSqD;;@21J`%@u3JIN9YGJ-dF!t-GAb6WnB5%U$f!A{jxqa{8sJj ze`k9H^S=>RV0<=fr#(IlIqakWepOgyx+t6*p3%L|j4NGZUcS$%?z`;>N}d&2O&qyx zpAop@5x;B8uH8;&+1#~-kKOv~-%K--PXC6~*x)aJD;7UF_-$qv!t=io-;9yhFnlkJ zykM{eH${s95CB1eqM$&vn`XH7sa^Od9v!8$M(5w zAA5opis!)%+@dYw>@=V?nH(X9x!?q1mMHkbyCqAlTTXiPsmXo&N<#;Z8vZvw?sv_O zj9%N48RTRp5i{r6;}{5 zxV7+Z4)nfbmmCJrfI0xE*8=L^1-@9&bO=k%0m&h3TmUy@qGHk=frlQ3B0GBhrAFY* z?+m(D7)B|$Wy_X)LHD27?@}*4a^q0|@r@@w!N&FamLzVy^;QnglOO+khP6pZ<82tf zg7MRK#MwxvxLOH1OlyQ96H&JZEl_pdP2o zyJjvE_7;;#2TL&~(AV`FFv*$$SWyh!6&#>GW8l$!vQYnAclq-9}F?du}}e2BL9)fb_NBbzJ2+j!JgG`@DJ28 zLCKR(C-ZdQ_BV`~szltmpk@fITYH+rZmJ492Rj8l9MG$aN3x^-v>Y6+305ds%ykU+ zH?5dEyZdT4(L%^BT$}8RnPPw(RgwwJpaV15!aE0;rcE{3-c4aS4hlRblj zQH9hIOLJZ%KP8`c6dVJ9yT3Deo;S}>hTPcM)Br~tQwZ(klLVUL2x{u;iEZ8L`mMV7 z@I%eTvXLKkO1dveyw$PUBX@Wx*=1~x^&4K{YvjQaaUS00lc~09g-i-5L-N86OJ**) z$Q!tF`ld)QT6HmsBHKtlkNh#yn%t%>XiX-pHPj4wX)VO)+9o6qGN3V;@*q{$^+(;> z;zf&4g}Q7N4a+0pQ0GXeTj;7vk24rIfMTI_BdnH_MJ8Uc4M9tuR^ z%OW2oMOa=`f%`?fhfYkFlu$t4yhq)zy)e`IA2S7_O&al=or`rUBvV#D zBJ%X$ie23SE8^+xFJ*P5I6P9Uh2^Xq=rTKkK0gxTM4^IPaw#sSM;*`C;JpVEaPx@1 zbY*X9Xein1mdu<&ZYN}Rc;lVSI^KGxl1eoDwaboj8|@};2nCY@#%%@qoI{6?p+1WW z&O%QsuRLT53X|hk!!ERuq-S>d#lo3DA z|K6}gDv3tRNfAt%hC~@zk1Jhpt+KhrWaZVdsi?`e3 z7Q9G+6FT34f)!-m$pX>ZiK*fQ05(P6*l@eB=H=3>=# z>0!6pCK1pxyP?O<_zY+ROYh;7S&9ym%Pyditr7YFX$X)iyw{6s*WUx8hv`i)#?d37 zhRp|}c!txTEKr>Dr0_xV0?(LQ+`coG9)_GHWZN7Z{vmjIFhY@s6Tz)WV z=#9fmmY>I-=keWwgXR4{ zm{)rSq_FRgkv0I^(>)PIxtqQ+Ihm3FjB)lWuYgv|V?D}$ zDAk$XMfFCC_l7Invi9c1Nt{=p`3lsZ-~mmhL?BaR$*x)_%~)4(y#< zyu%4k9F;T&`8c3qK2_Qa9&*^#Tf1+;{C(6^5bRoZeTv-Q%qxPbPw8Z{?z(}QVkU{g z2PBfaKj|g;VuueNk{G;6-M*QP&DlfE<(75_W4v1t{uFr>9^Dd*KIp;d4P?Do1j}Bw z3ui$o10!b>CpCr!W=EOiLWsEoinl^xp*;bY{&j!JRbLce>Lj7g>nrG>({yG#?M#VK z?K@DB4oC;0^kZ}RSV(8rkSYqAqA0t^O3i{-M%_N!l#K37(}xgP@NUCAkQ_;7YSAF{ zdU%^2yg%-7QNe%AF9^7y59tu%Fz0_uZlc#Chbuo5ZO0u9g>dE<41EoHU*Wj|z|2z> zjO(9h-gOteId{CMqNpfW3a-fYVQIOTP9+QUsQWX`w?3c|G1icBsZ3tU*9>8!|Gqa? zENct1yzojd2MxzCYPYT3K_nYRJnTcDQLW*{eNZ^c+zr7y_-VmeE%a0Sa_7!na0(RN zo%7`CSPFpR`=HBuH=;WDsDXz9#28&Ox88+3kb>@YF#Ly~ReVlS?nzPSq##ATN5Sz# zdG0yppvuXlQR%80x1LhnEJ}^epP@78{9yhbkL^jw&Ym!guz!q>?B4}3a|M)Tp+0$= zYwc21Ug8%=gOz|Pl|(I2366^XC8~4ZF_$(_s|W{4I7~hXUh7nE>pPKWM9-h-yG`w6 z{CCv}@-Nhm*CX@46Y_wB)zU(*&ZYnox0I1HNT3vo2-r~8kl}waz|M>1A)}28&ScC` zsDhJ7_Z)L=lq1YGN|WJz5!MhzMF9;6V$da1Uo~!3!bEm;8Y-?%DbC%nVgtRssC{6; z#Dt=4+3Qy$5weqnVgtjN4$G)Cf7N8qVO3m%_TI91_~tQUNRp28Y;H%7b`EZp<1+h9 z#UItCujQ5>iwfv+%yV)9;}xdbFbnX+1!*8V9yvEX?hBmf3?OkXqcN*u{!iDA4Vtn$ z-jU5sFIlfT_Z;$T@oa|BTsE(|x8vHb>bNkuv8$_nZ4C*Adjb%XW+vU;y><(Ou&2AX zi~Sv6Cak^KuKnyIp?H~RfUNl;&Ls`T&rWCsEO-E3Uj=Z6S-SK4`@ufUn_`NC8$dI= zAr@-n)Sz$pBsgUMly;`|_t+9Etx@ zojA!p{OgZ}MIF8=x0%SMA}Y8T9hc-q;FRTB60F-8{i9e=&<;P*?h07(uf}@o&}L`a zFtKxucB&!9e_k{QJ$<@oD3s4B62dv(m%bzzRJdhoy1V8bbFx!1eXpQGg*vJD z{tuw^FgOs$>J#!6ilEVS3DO5PZ6uOsu@&ZdmLuWdOMA7Y!L{pwS4uS@6XlHnI%v52T z)`ITvd6`+aKCO3a6hXfJeaO(a$+tx_f^RI~hUHIt+TIedU|De?6lCcZjtb_JGe$Cl zK{-xM^k|&rDPV&2`{Ip_Qe%C<#RBpkOfS^xtAxlKCc4l#{_2@iXMW-h9U?lb_A;c& zxr~jqDG*n4W3bWmQhQrJ_S~cYkpiuQA z4T=6Q$5)Ui*@`IVtY3(EhFHFVP10&liMcoo`Xc7@EvGw>>asFfXF${i+Eg;BXyN?h z4y?dHy&;@+`UFj&OO&K_?sJqyR~OI!TJX`oa_ne{QY3 zb~xn~h3+9yf#u4jNKvqESl3etWra@DiX`(<84b1GMlzb2GD#5toeB|ko!L&%kDv!vxUNZe=1WNQ{Abf{nMrXT(Xb8ai-Ll9SKspDpM+D za=o;V(SOo0PCrdfpoa$)WSi5|X)pka#atED(s`hJgG4$>(Feaq37HCQ{afqbEOG^P zDN^fqY@x@oV^{>p%!lJ~8YYj@Pa`Xv0*oCY{ap5FAqR-(S*(|zk%D;_@M+#1*?b_T zRPsiAIFoxmoRhsY9C8`!3>Uql(QtW_Ju)?|g4Y{&5x*7HWSOldnw)sS7fdr*F6 zmn}RRwRqpzsneb z^A<{mxtr$)$!F$&#n&?Nh{{5JA;f|z=4yfsvr3KC^SG1xoruz}cM@a6+q)|x9+4*B zZuo0s6|9>T1Z#4Y2aS6b((f?>0&ocTQ1}nz=U2evP@i2n=Q_Vjzft$YkX_Knlxa7q zL2P)F6Z48u%LZQg3tnWq0jid@iyQ$T|3JE2*Bo@J)k^WJb5KzXxSs4#3#Y&0=)Qil2X6RDO`E- z5+Cdnpzn6PG7isyMF+iOapIgO9FT=0njnMwazVdruCSE`OXp z@+j@VqK4KNNvvn);j&xJtR~jr^pZ`NY*@27PDsG&PKa~rns-D}Z`f(ZR%1m(cQ^eD zpL1h=`?^iL^RN7Zcw67!dN|vPQo$9vHoJ_`q64vb75%NNK#P zFiDG-KR_hRpUs##GrVg8!p&*Oj+l=2`IrLE6dp#8=iJ{ z!0L!dDiyJUV%4gz+T39pZaQuaI!L42BnLP)3{LrFIJe_gNZHFV)7Z}zL=n+cZq$GeZ@G7aw{^TCr+2j7+$R=J49_L(9a<&Qjv8j8Iwr0Ta#pa|JJ}&!h@8 zc&YkgEZpkq!7}Bd=%(6(VM_My8>CX{=mF$^T&q_u#=1B`^Csu&Vviy2a=Oduik#_m zkMfF5arKRcIMS7FeLs~CSt(5|L=YP26R3E-#JXu&8_%p=oigveyY(seWPFi)jOCywS-ps7S8h8jlrMp1A zc4a;QKV%Kuz4)RsrpNK5b$F5oBiXfmrhed9RYL4x#lrFKm>C!zA|x1?o7JQA zx_Ga5W-*C`JM)T8TXcsrWe(XYA_`*%2xrkSl^mLtDn?-U zsOcNqT!BC=q0{3fO~OLZrK0=d#gazRn@~Wd9;=6`%kc~N;2g4cJkR))D=hY4tQ{7# znE)L?c}$~w)4d9rlHJ(5#OI)-Lc?_M)!y;KMhl!}n9#r4J0>IlH{4^ux|??Lc;Wxm z*p5E?-^6yek$LhH`W0|l2lSfhk?r+LMHa=`c!GK_TyXgDU^+*AFmuDc>OJRuCi8lT z+$eQYt2^o|_nd#gXkmB#z6W;X_q)Cq9Awtf#9zE6@LXU0IP-RqdoVJ|T4cI*enY)T z6sNc~n^eRzXqSOMUWd`T6YE?8d`7V_k7+=)3S1y8jZ#>543>O1>H!vHVzq3gL0%A} zQM5CWhZgCd?es<6H(S)dPzT5EOTKJVO1 ze+hSm+2~)w^ZXdT#ZHL#_^)+Gp~HMUY@}wjBzb z2=iFqd#)%Or`{dWxlh@e-;tut#yt`5u60_+&CzTodUJ=?x~chvX7dZww{jbC-*uvE z;FgQvJiY+8a^ndx^x&zPzI#)OlDfBV=E|48n#tfF=m4uo&j3H2paZJA=Q=kLst;K@JeRePH|-(OnpFWVk<(&xWye3v5ZCQBARQI`Y9RCc-*) zo?%0v#=66Sm9!}oiqHehW4A&n1})H5!^SLijh<2{l4_DO*s2Hp$>iZCnQk^)pMDBi zcOn=qeV<(YyT~@YHK@?*$E!7pzbaYG@q4U`;}Avk6WGPG~RZSQgbgXbTbK1fC7Q5!w&^ z@Tp>EkncdzXq34~Fc&@D7L-gokq56Dm_S1ymTY0oI`GjzYLd2+t&g>yL9cJ_ihIf0 zsr#TL1?&~F3?2kD*z00fJgrxdn-euTv;UUeb046B z4|y%_GZ0zXv|bVKI1T}GW)Ko8FUOYH9?Ka=5JRvnrnWLfrlK=v`H zWT7aT{f7Y9m8bS51w|(Ctm=b1CZ%mtb5}(L#TeWjOE20Y8YN>*P#T_*$Q|xb>ru;n z2a#rmrQjM|puH2Tj_*@wJaS_~Uq9ki70n{@iB;;u_cPqy|FF91giI_=QMm`*#&8#8 za|+TqHqz4_Wd6%SR|?;d2ncR8YUdK==yqa@G{O94#mw38+npeJ1cVvnu^RO{-4p!a z2e353eaBp_Hitj%R~@&0K%L=UB*+swQR?GxvJ%~CfOwb~<9)~b#tm|qL45wIFEww zg7#ov$Y!^o^^YwXld0?)EJmb7&Y4R(d#5*Sy0WpufZC{c_C|_>DD239vx&~>BS!>O ze)4feZQZLX@w`L~0q4kzR1k=_VqiTayy~pB!+l`&vBgotj3vhoNbZnldR2Kk3ol#7 z8mfwyAieS;s)AzBtxcWU(OJrW;uHB&=Z;fTnmZ^`P}|}74a?x1^WJK_1MxSk1Cd`9 zZ+!Jt@y7Pm5i;v|1ro`070P+-tYe!$&Sqv1awtJ&oWD2F|F?S&QO9N2qNa*D*!#wHC0s0fO6&|qoAg{Z!Mw7?^bK3r z%{@gX#q|rXk*;#q^mk-7m>$jJ^mX*I?G2(KtS&ZQ@4}<`0Y3Q+rY3p~r`ufCX*h|i zl6{@?P%w`FzwC7fT{7QCJ`K;7RZNCWa7ci+D%mbyr4CkM@&&Zok_9BQT?~L_8_8K2 z@oih?dawzYeRs7fV(BfE{Ha7H>{mR|?u0}XqS0Wwqt8QwRKt;!=#F({G99t*4w?9Z z$fbL937tinq{vunBK?~u&Dvpv{hz_&tXalE+$49V8J<5=123UQofAFmt$FUM`)-%Q!4jXQprrW;!Rb0vHKBqnjl0L6-a)m$q<}uUkPSg zBO`1dCRX)I4ma7ilEX<}@pGB!k<8gk2~L>A*=x++V$TWj3w+n6ELNNA&kc4aLs)zS zU4AaEV2A{Y^MAydSMBgbe)y^_DPDDa;SNw;7wl4T;StlNSx1_zpcQ!T?NxaJI}WA{ zKF-P9-?kxtL-cmk@eHhTA?0WzEEsMS}=69k38 z{7yI4bfcd;=;s}_ee=Jjw;*QT;c#FTcLT5%GN{t90UONDLwJ$nHL+YDEV&@b41xt4 ziIC`=d@q>Eb_!Two*J?YwQ8WT<`65`x^yHVkaiS9Q?qWr;Ct@N8Et4TAJ|8Yl2;(E zP%z<<6t9d1Y=2;J-l^piHP2WuQt!zI;p=L}-qg|xat~M_PSBOwAxMHCdgSRvcVcsk z9?{(D_l{iEDwpnGV$s9;DFV`k#S&RoutrK?1lMptg~(yCe6H{$S`0r1;#blxzt@9O?F(SnQvgzp51TX ze$L5Qcv6wohJjhjVlCf@;&>Pb$B@5j)&C+cN%RP_t9mChsvejKndtUqi~F5&bgh)r zubZ@D14bfUUZPW~@1OA?taNU_%T3e$JH^k{5BKZ)nbp&SNK6oCY?)umc>U#)r>oLY zF7DlI4(_UTBs)A<_b1G)aCTJCJ`~Ct#Fs0HF0ZS1C=jKeB1A341|kxIWXVAF7Y;{6 zii@P%8y`@u*|O8)a@LpPsxKf4duP?yXnEF4T3@ciFq$FML8;{QIAhc|683t60X^E+ zEQZ~hfY?z9@*2ma9{B z&E*@nPHsbiIQ*7F{Uh(OlEP9dD60HeHW$AggLs^TBB+Kc@QedKc{%67v z{gUI&j>jDi=z6AuLU>~{;)S+G9Vmfs!QOa5nbY3n(gsR1eS|X%acE&;stjMoQF|M% z1tcn99*7+7=UNqeL~@Q{O?M2Jz$VACg42wDFj|cinItn9crKp7Q5a34z=-BMgxlDN zMF>=Uii+85o{mUT4|HHJmdzbGbOUsYG6iFy(&y|btr*!f6fVx*AtmIHDAl(p@(Deq zpmQS?i@9^|;$R}F4NmLCb%-dKH!LdEV5wZf9%DUB{ISlibaz#FwR+R z)oJU%-1*9r)5T_f#^UX#a{931F{oX{7|SIK7M2J(k(7uLl#040o0`M~J1Ys{q6&Xf z4rypdLhvMqskYjU4aq{fg!+zIS5^= z3Ue-j-sw&oo~fkxBU-r#3f5PM^~Zf3z>u64sqXRWneGl>++$)Ozj>>sj5mx#Iqpp= zf_Ew@{Y$d5KkW3!vvD~p_M?qS2m~eS5;U_jX#_%UtG*ID{>Z{e-PwUnxfyoMTd&o}WM_`(s$~@8F(3 z8>!x4{yHNh{xQk2g{CO@*ayMKz(^Y^3cG7=G{G~1D9D;DMXp=x!_pPQUEJH$iPIlq zOPjEd`J0^{lU0FFt_FfJxG0L=HOB+!jWMy_FgxpPJ<)ms>HD2zr*k&TJ(wxrWE?mF zR8aP4U17*znBZ2JLltymYbOB0nq(Nz>@I9w`={j5K)Mmavc()WAPQW$(a-!;wm}Kq zcx6CROpc&f1PI(0`mG;wrR03No>0qPZ7?`%E65MrY*aC}WjcdkB(8`*vqjB6N%mU8>qW(_ONbYrmq zt$3DtzmF%N@Aue?jGbkj_mT}y2h!u-Hgml`3eRl)eGWuUaDlmi+1WKV^SwS^UxPiF zOt@RWpo4+~_5Jg?k|~*2^Q7Wiu#B&P_;#QQ>YT^2*N0VIQ^gCp^+KZ9H(b9OxNeh< zGx9giQo_<*7jW>0T91F|0#d#D2Kqc_ZAP~yr2QLMm4iebcQchNcN4)wXC=*n#s#*8 zFoU|tlt5e6Vm|ODp&`i!w77fwRpHB`w|`;j+!Nhh*!W$R#eX_;C&Vl3gfxmFN|kg) z4;V`q?OWxg--xN2zF625I{EbY^jmUS)#=8z%Acbt2yY<2X*Pnt*il~8-4k=WXZ@0< z$?0L9-)0bx)0f!ZuLQMO^@z4V>+^@bFk+63RGI_@YeCOuPea zq%I_6N&j|I?YKTNGZ`NfX-IZ?RvlbCEz5qrl2#}UiI{*hOa8fJoq6nbBKTa$Boc8o z(ISUq&YX%i*a*^cBWWlk&x)OM6K?Dmi)Fx~5COvw?5Car#BAl0gGcm`1xKZbc$@*v z6dSk*xMdJRw=s8vO^IW*Ffpi{xwcT^|;TYL07jz|HS17 zPS1Rg;k2-6*=yl+L~|Sd3kbm=o@_%59Alp#a!!*F>_DSfkY<3)_<@0GgUjZ^%rE}% zIa#6SWctN>by0QsRHgNI+go2fi(w=a6l2}~-$$`8G(h*?q)@*T7;gP;b?aA=ONfnP z&2Ve4g<;-bw4k5S2Es!l^N&^0N(L2;H<|9EYEAG~b|22>?aheB`rW7Rgf zCxlLat}S1HwyXl#c5sJO&3|iX)669W^VX_j@5E-=wWcOx*XRGv?mpU8uXkn0Z^XG~ z*xxn!hb^$snaA!XXlS$f_TRGS9t;r!EXaaQrpxcgCWx}CMjNwLl~ILU$lY+CgsC;eqAXX!#!TRM1DJ%`ZphQ*efmT%#&QaN zHrBHHkZ2Q$i?)I-llvWNb+!@3uB5X6-j%SL0`ue0Fv$E2Zrkly1?u*O4swvKM^WJI zFb%+w$s8Wu(fe=YM_5!KQcbvTnW|#tE=OU{q~6-t+GG*LgknI#7RVT7<-LBH<8N6V zyA7KmI}^%0i5D@iX{Imn*w>$##7TtW`8?$G`L z3Qf%a56mRXPd9>&+=yC z)&s2v-CZ>-%Epfj4EK7-VR9+!miuVyIkhK^Fe4 z5bNS-P82WeMqL`y@5efYQYt&TvnuJNvqiNIQEMIXj&-rnTr`hW)U)x-b zcif2G@>%n65sW@*fef>HR}%XMGl>MMYkzSmnn^LOH(yfDX{t*K;pZ#TJ!L}yO-W_iYiyCk)XD=yFVEv!&8ynR4uiy|p z8$%I}5O*{Qs&RTWIXzZG6*RHAy%q9#7Yd3T;d~x$F;fya>cLAO3m24fJ4OIuOdrlL zP1qnG#`BTqM9jwMfu9vAcROu*+_%oeZhC?wqjwhiNjKNsXA{QRT^|HtEEnQnxI$-Rw$4`4_PkhX1+FT4aq;3Y*g2hKU%{e2AOPxD!fzfR zmV~d!=m;F)dK%(&M95&zF>lo%-!(!$Q^i3>Q{CJC9H|U++w6X@OVQXJQWV=Ax6-N^ zh)Vn(rR%}nD3v12U_rD-|9o4Bo*3;l&iuL5y~vrLqH9NbX&Ox8DlhVQ;>mQxrGV7& zCnjKWB)E|zbK5o#x-(tg{!~oYW2t^GyTh~f_6$-U0+P?71Xoxf6HoNDUd|LWu~1aZ zdO5;$Wuo;8xL}_59rL`Uo#1WzW|(lX9gna8%tjATVIz(iq6+*tI~ZBWKr!5)i;4*W zzS?FEAK4-b_>~x$?0O#SQ}G)q=H4g@F0MpwEP#E3v2p(kdlbL2=Y_LZ-R^VOp5G;J z%x6R~o;8ek4`eHB&@<5fI{ENY7@Cj|`%6>;+MTVR-Km-WBvmC8@ddiYlNa3aw^v!8 zr3$m7c03^Pb`1tB{Av6`0Z4%txvVy35hu}vrIQm~PW%Ltr<}A>qJRHNPnUY|q_1=B z`crc7@{yVm*|KKlqRIZSC#*=5B(kXBQ@ufxyx7@Is(PurIoaiOx~+77M@Vxn-mDPM zO-IW!@49Hafz0>Pbn%kuvDV{@`>oFLe6VASMGHP}a{YSlOJN^m;5Eyz3NgaQr#8&2 zV-1!d%_hK>$zUpLAr2rgdH5UOKr8nTe}K@{*Xn2MW1jw-zY+c9B1r`!N$Bb0z1*7j z%ng3oULWJ2yc4E0{~Yzw7CNtHS>>o5oq{b{Nd#!*b_Ze&yWbkAh5B(hDs`>meNVM#~Xp;+2*DxS~PbaaCv8&3!VwwA{wClwExn8p5wuD$c! zSqn`WhD!|M$Ax@OEJ%h2H1NjD_FYx&tGU>J-kXB;V*O3Kb~jGkMI2{7ZuO*MoBTiY z_FBjk5qkVB;H<{{4~5&&d*#D!q>ezLkq*K1GAAqx)kcergitK|8^cr=Ms>P<$EUD} zp$?7xsqOc91}xQlrfFPT^|9=0J|cg)`@tzgz8lKy(1I=M%S)+;HqNxFW}|Qo_dE5%vpiY{^pK;L;8!wU4Q@qq!$+2uQJVS4H&P zx`(fC-`$3CA=W!j^@AliLpE$n$R%ju%tA8`$j?h^kxZ|{T`C;(p z@hg?Ea|MI=7dZOG0>me=74a+;J!>|e^aexjD>rOIB?p_`BX`DtKC}ct+sEgCw%4tp zSJv?|x&R{BW#3^hHAvgu-_>k^!&0&oxOn;8Y6eDy$@w_C)FSB4L@e9B8=G6%U$cKZ z2?ADZ%ihAOG_0hvcjtfVsk6VKgfbXuFGj;3YPB)jUTa3!Zz)+%KGmK{b^+pZzd^(; z3e+X67eZv#iu%X>`q24%sDV?t>+ARbpY5JD>xh$A$V)t*s9;}WuDOA7$TC}o$<%0; z**E0&nQccRh#7uc4WJ`?p(eu(9IBs8?~`@dMRL@oDP~8AOeB-n$f39?W5v&~NfU(x zech|1!wjUzpP$a48z&p=Ff7CP-_?D2d>qAY1m*yTxW63=;mPW_uK1Qb{&FJ!p zd`n<#jV0L@$Op27Ic+evF?S%4gOG$fA!*qhhJ-*!LKYH|4Zmy-2(mYu1Sh{uNU{(X zVvY9us%K=$$YA#K`{(CztE#K2tKNI{>ecn?Rgnaf$RV6NF52OBWM(>ymz^Qfp5;T^ zZ3Q+-_9ogcx@}gAU8b}E<1*h_osZL_-b!YYe1jJcY_NN_G`H@_e|!DCYuDY&el3cZ z4Q|?&e`F8xNTfkm#AbalhLFa`p! z{F5dn=#EYcKWHK2V9fJ22b+3ZGB|Ks+6BWbFJB847X5v86OLlE53<^uJUF>qG<9 zkl2;cN)NVd_$)I_Vu(+pF>)b>fZ3K1bi-7uVX6KypE(}iwCwyqLC9gifzC}Gj@rdb ztZoOa3c4~f#(NjKbPcOZ%a`wR;yRi0+co;l6|JVqcw?o}>oZYmKl|Pd1KB2By(HQ< z`Lw!@bv8)~hegfuoLs|7*|}v&b}T2>XJ(g%4XYYkdNXic0#BC*Z4%&w`TzH!vAh_z zc-6Hi>V|j|P)A_EfJBgr3w)db)XM>QPtU0h#PJcSUUQ+#34s7g{#Ll?k?nT~Y z?$#v^CT3i9-qzKnMQYH}#Rw`bl6J4GwVR5u8| z!@YeSMJ;8|STA)MhBEb~(ai>5u5sNCY{RDl`t`n^=DHUbZ#0S-xoZsKV%rLvR8!!6 zP>hx7J&97UW@gPzjlwqj)#S_oP#O#R+0;lMJ+6X?xY&;3i2$C%Mf zV}#i!@P$t}doK!iOdHrYaN^Pet2anZ)sUJ9RV~)i(2ORh2z|{&a+4XnPV<9M^1|&` z8W(1HCMVAF`*5h|P4))%MZK8zVPD2=N){)JOfKAC!`Df~7sZXxW)xDloe=hDJ&YEB zP#&{s^t#PxLq3*)&0DM9$QELu#b+{UlOIF}YYOe6!H$)4u>?018AZKu>c@JE8`cz) z7reA}RgQ{tD@M0e3M2_mdt$It>0`Cd6p!(-ElO%*j%*_{*WA*nF`0Z=Z1E-kCK?tP zjA9KeH`pA;spMAXyg_4dTl6JUe-{k~V;Y0+i09Fck~fG=PEs4;sv|T*#t6#i&Jk(; zfPpE51m{;&>u3SlXvyB&-sQYP$%NNbfPG5cIU}u?b;ESA=*W5{xBMDhad*!Uxel zFUbait~x3n;^ljv_|LEVP&n?2r5UX8GlQ2brP9TXYVp!JeZ4*D!Zo;45T$o?m8S}) z+A9$+fkpsU>A4=AhnIjN=!gG&kw6{3(`J7S8Yf_*c1(Y0eu=uMs{C<&j@D?a&ILu? z)lf<3Di3586&R%O!rX${QMN3(Zb?ZIk0@#=WX^6^)y5Z&*Xn9k+s(D*86LTy@KkWT zRj$Jg1vZ3oI^ph~CUyhlj1Z;04-Vdp)RHeP2G7r1Mxoc_TjnORoz`G?fEp(QB}|AvqhyI^}# zomWw#<|I&sFj$=%LsB8)^Ot-Sp5N+sbS`Jw@`Wao?9~}O7ER>5LYr4E(K3%Q%b1ZZ zRsgt_c5T(UO>*wS!e!9dv1l~jjp4|mcvEkg)>0F8zQ zSEtG~aJe~yzuM};rBJ)j>D@L>b+oEMs)Zd|$RG$QP(*JV>cR<;`fhEpCfDS*W?{~2 zsp-LN&|=%edu>)=C<`R zU8$5Sd2~*l75Y4lMFqHg%xY>G@VRRco~d^sT+>h_`7#{FcZ&?nZgX1DYqU=P9wWYe zsLdMa{Hr^RXH%nk&^ekOBAz-`>(+mARhwz}sSX(DT<0|Su`KYVc`tk7;~N+uFc@4S5wm*PLQUc9?hm7-5h4SFECl<&K6ZFW}lycK!*fvQy)yfeKO zw+3E#PHuMX`OWc=-r89fFq=Il$L9Egtm=)+3i5-erK{@a=}LMW2CHZ(IcHF3sVTNv zN`o4|CR1b1u&weAt;)Q@=lHt1xCM&Ej*$aFbJ+!_tyh%@PqF!5*TGc);oge5&)wcUS!^N|a5V)M z2*$%Yk?t-##rRntX~*n&liLdg9qh>%v`+K!Q!}$)rkgA3x_`PJH?=*7T^@{j@=$A` z^et_v(GEsBTG~=V&reK0N9xSFw#{h~_h6d^m$r%V;VZ7(CI@hjd5cy*b*|5f1$=i- zUQuOrV-D-`dZQL6zsb#M(!p2;zsgMvR5do0+cU1dS7%7RZ}b?ke{ONQxRg{Od=|9^ zV=TOfz-Tg0z#1^dBRE<}VjHU%9|3MZ*ohXj*wj(Ian3Dl_K$#+Wyc+C+WRkO9=$Pp z_N8pN2W~bjt<#6F3vvNQMd(?v1On~|=Px2@Ff%#?G*(gL``Acv(qT2~K6`KSHJuSA zbGBeX(&}_rl7CPBiDk2FNHdDR_p`I&Ev{MdOEaC)nzdik&~11+wi>3pF|yL#^SLj4 zUTZjW6mQwH;7^U~N<@wTIv##flgNpwQ$STim_Kr})ro-|AWi-$`FD#0qdXX<-(WTx z%~OwIDQ3gRMvpnH7K8TlU-;ZTI-|>i>n)Q{8|ex>WAbU-x$-e_7?t)x$s&95FV z&c!b1Qm4hVV0#BF^)uJ9Cl+AoG|*i;MmDAl1RvDR{3}{Z8UnN6z-%*h&!VblLd4T! zT&&LBNhGRDL*agh)sO4hix0ng$n6UMU^MxDrq*w9s$kh0)-`YNigKni&`{F4!jCOt zdoGi*8=ebbdr1XJbmo+HYzNviw-HinKznQu>FRFY3{)`i_n2 z%oB>#`M-g6n!`^TJkHJwy;hy`rat47hY^(g!}^7*uMNs`*ReFtEwTKPg$vf~#Tq$Z zz0x@bmUM799+wtig$?6t=qaE$UJ0qLf;WlTOII9()N0j{!x(}hbJo-46 zrzYltGeK)qOtjvZC@js@jjvnjfPE9tmeeM-1W;+N3Xrnq}u|VxQft9<)@-! z`g%(efMeRTpeZaEXjvVr^LWH(&YHR>Z{q!i1zSa2ex&C#-JfPw1KlQW8;7_AM;-}c zEdFunNlSm9FzHD~eYcBx9}G0z?(uYYTOH6->F)NO)m$j~7kfrmr`9bxwOyTNm&Zs- zE8X1;Genj4P5i_jPDi7mI$U$RH*LVd2iK=}!~1cMFmwTQ-kfl8b!~GlTkZ8GUr4?v zUgh;nHJ~H*APV1BY zg9E#=r`R&JAHfZGVT4T7i}}R;$rqC^da*Bi3JThnnCkOlM?u5Zqik;!y>gflzhO_} z4yVp=!r%o2e5j5V+=;@EVulK%WKpUN3FiK23{C}-E^6Q!s}suyq83-j1X;kTvE<__ z3mDS$F)RaUV4@4z{sM0}y-bp+Q(!zlT;xPMn|v3AXNs=H5fCqj89@N}EjxC`$(kT6 zE5@_3rhWmn2|LfwlQs1rw&XEBx&oGWE)jfK-6+5asYaD_)Ip_WOln|;b4-p9rmV0X z1=}us6BSTXDh47}Eoy!K0Z*0rj>pKV-xGJ*bGEK~6qgwFi&x%*HTv-kY?H{)7;pX> zR$)wcUC9Pm@;G)*K78~QSZ00fc5{B7`L-wQV&R(Cy$wt@-*ttK<%me5yK_a^)GaKa zzx)mx%ho541=LYp8tMSe`AIg<3o*?isn-e!GP(yqJ1>;t^Oi?%{@VI#oX*>ytYz-U z&1~vwW}XkW)@wgI+A*k0K5*Xwz5ePs^b10+GzuMOh6YBr01V$Z)P~ibqc)1QI>6_n z!-u2=Cxug1^`rAc+I7yQ7p}}IYZ!h#dEW&NTPW6bh?Q$udHwM4us$;sGCwx_v+Q%W zU(#cm4|*mymfOYhhV8H4J?!&$o_kqe=b<0zk=yp+iun1P;@;$w!#~s5%Nq53%{44NE%@cVnJ3mk&a!j`bP%fUJJef-gYhV;L;{)A)LR_+I$NU3Y)& ziM#IkTJpK-*2P;EM+@fzY{4Dhc;fEczxj3Cuu@gg+*Vq+nD2$5PZY1jUME)Bs-W+} zM|vJl0JD1xSLmt=y>64sq?-8q6SLufxaPh0FohCtf>pme@4z;#S?@N8ciyRWqm@Gg z2qzYv#_UDNgO~`{1R$#dHMF=c?&A`|2Rk(}lMH zjW0>ws744$=!&%sQdN3eh`q(-4)%F6pe=T4bpn0tLl2Sksld*?SaE>7g3)<@*g=)< z!OE(i)>UULpgPhk69Er^#B$4wNmSfCs$L|$SbPcaO)WlUBQ<$M1@A$AjWp!EdHQX! z61H*Nw5p1o6Ov|pL4gmBqJY$gHi+RYlsGbV8QKqEFHrh#U4|Jxy&)8onY5v}NR+UOe2urcNXL*!WRL1LX%S1UDlq+P>4)M1+;|iga9L1Zbx5OkYbw>X z??qwi1c;?LbJKB|+C_X4uf^VOyG(z9l^nJ8ljyFbMb^{=E0lzQGuSke z)#=O3we3TT-!XDL%O^dTfeUf?-ac}1AQ!TS2_swDS#l2OVgSsVxo{g9!DxK{KBop> zvsc)wY1I)LN4HdzDIS6GpJlcefA(XHXYJV?bgE^*6Kp znc5-PjI+|wriXvoRQ|+)T-fel4r@ln*zdxzc=#eEnlWO}u-Lnct}x_`WR@&6Xp9+l z*L^uUo$dT(xQ_@uz&=egyHVBpfXF~G0hx*;0fQc!rmErmxa7*txDx`o{7zej#U<&o zk0#$*-S*1-l;eEXf9<=XoXe%1<>0Cn@{g&qVLv!kf{uHO7YzA7O)sG1bH|2-eKHbXJ3QYD}ZU zrWsq)d`~EZD|(V2;xcQpGz^IZ3yli|Csy&WN0#bWQwvg9L2=E9o)%TcXxI;M^h29$ zHHx?)k|a!+OBA}=jp! zkC)xiv!Hjus@u!P$9?|(eemz=_dk8v%{N`qaj4_6n-5;zafn($>-2t%AAU;fdfI#_ zq+m$Qd6IzPZGztxN1BDHceE1v@utGt3h!UV&+a!?N?yHFQ&6aJ>b+8>WS7@v8PA2P ztFfVEZAEt3LLKaym~%Snw-r`*H5(n8WrmDci(3!dmbg?@?{0}@1RVj1+4h!}I`qpr zYg)q#qn&nZcC0tDs=j;8+AEDrrQq9`CH)XsMvyV--0$#fyO|?UQWY2lRKmzd$0Qcd+@i4dywQFE{66yU3as#PqY#-7Av(<;|)zut#)0p9Dk*UDID zw#c=^H$XQQ+Ce(WD!z23#jr@ionK(z%N{ambdOx3HOo8i*6O}2z9#wVm)v@R(}csJ z&I@i`Qt$E9FS%t0-6m!*8T2@>{P|zFjiXxh5u}Cp{2`N8d&{@=%vSluE411hz-cl# z?R;<=R#0d~owE=a2m%mu0jdvfQbCo65c>17A{2#)6{-F63TLs^qIvhK)w|7XRTdO& zv%-=~+ddF3iu;0>8s;*jwyiPbUA%r-)b6e;V&e_{8J3Rz&7E3re*?pDnM{MYV|8my z)S;b+F%5-_a3p$rXU8_1Cd_N*9d;#psw|rEV)Y6;>%7%uka-%cCaBEl!o({Sge@A{ zD2vwaYl<|ju!s#UHyIs%sE|u0I~G~TaM^tmmi@8#xgIKLFK4&b8hw2|y-)@-X~f@Z z43b%MDEVQX4cDgMajWCPK^w}ipAN9=#NT753M)7+wK#hfblYoH6$q6za3Lp}fvO_G z@RA|ozM^Q07!+algRzUR)LKyUqB}!N@6zv_^oqTAR#vx-v2EMMpNknLP4Xm*Ho|&~ zCV4fk^VAz)r|UWC0s{irL+n9~m|T31*I#kZJrx+9inw`mA=@YZLKqgtsdp%qFrX%Z z7Uk!BRgn_q>Ii7J9vWpwVReD3AD~mnsdlVS&Df}i#61eB7F~lo5&1iDId9oDIu~6% zs(0|rR^xOHkPyWTt3e06w4%kTaoRD~77fOrtqnV8c9#)074-%fIHA}XkJfQ28O-}* zYXQ9c1D3O>m4A6NCL=bpTVE&Xa7B9rT2gh5TFeIS#%j7z+t#MhIP~(;Mp)D`qULm( zSewSEQIjNpKI4sN8&1U=e!6#Awq&(C z7QTMM{>RrBI-OP{22s>|yrX*!=a;Z1pZCc}-zs4)Euc3ZGJz_N?-+%>sNmK zkvCeRhXN`f>IX!B21GappVrkpwJ}0n1?EWjee?u#-d+AqO8&XP*XN}ccpFrueJKGLiadJv;!HJKh7@5y%)HolNW`e-!$ESD% zRvFIv43%idg6}q3f2f%6EETh}4e98!JX4k8q`9Z65NOE9K;{hRs&FO=YH=Z~1E1nK z2((j2jkr=hkmIM|NYtt4`#2}^&KeC+)sG}e8OYnUX zNKkg3bNq-afzYufC-geccx;Kw^Vbc8+d0C{)9dkUvH6(VJncx<9DbN{Tu!{}Qy~0t z=jX7@_irC1>*>rh`;^@$QfYp^NPb~1#piGo1UhB{s-(gyC5<3pDaKbx^6~6ieO@3) zOPDliXrp7#xOEx_=@xz}@ilc7jwH=G|BS;xXJ@z~bpjf@Hn39r4O(ZXGx1)`Q&KZp z7*tk|knm2%J3E~E9Q0-2cruOLEMjngd!YGrBW&~(?#aC%6V^aAWo4|etPBgV4)@lT zTit3QR5*)b?J8vtgC>cD1iuAj(eIjLRlo3XWC zklI+Ex{LQHy#ErPowdon>N^@kAid>nFj{icJM1T~I;E^K3&wm}^Pj!n&dG=Ec6FFX zu%-9g)0?AwI67$Aw*4_f zyL1_p1Js@Pli!~OBDnYgSfhFivoWkcr}Qdj^k-Mt(?;8GU%ro9#vYE~| zO_*)w73MFRe`8r=x!ZEo@(=48>s8jD+MKq{wudvSG9I>v?3?WO+uwAY<9OWhCuhBL zh4Uikbp<2&vU{>0$o{i`i~n-}Ul$bP_ws_j=49rq%(*4!x!j7}t8(98xOL(Gm5byX;KtyM!AF9Vp{&r#(1FnNi=2yAFM49pn|Td+hw}cCza{_or~Tdy zOW~UEQ22!ccfpN??S-E!{9fTdiuM+F6@M$zT9RAxTB)UUL+MvaPn2ya`+j*&`Nicw ztq51_uXw$(y7I!xFIWDe%33vA^{eWJ>IZ7PHD9eQtsSX-BkG9W7k#xZr*5q7mb%yK z-l@0O@2&qz{Ywq3;lhR!jiJW+#tRz1*!ZI+bJLQhFEzc{yrB8|=C>DbU;KYsGFvva ze6!`f)^)8&cj_oS5MbnUBB-(bQg5Tx;J;<-TmF}e=dnExnRlXmi%^U<5FdrZ`qa0o?mWS zt}Or63btbDiu+b(th{#R-_Q9{kI=KJM_DDVf_@6|6g@-Ee~E6+XnIe`kWLUI&Hgv_ z+vK|j8&}p2(4m^&6~krsjojkVik|L$0`xm(wZ@2?bK6 z5SFOyQ6Vh8i|6NfzY*`(3Ssu7kR{?SDCs(cKPiMY?TACT)Q@;)%H4#x{dkv!LTMaf zLqeA3At4iP0FO(2fx~_kU}*vDS#bB^5yUdUyI;s*)BO80Jo_BlIq=6LOH3%>8hYM}g)JVGZ5^C*V@?xCSoO!GGcz#j_RZ zmP$joae?x05w0V;0rpzTN6H6&(?U6?A<>+|PPtWBmlUM8Pw|KF2>67aHJ}%0rrC$M z7NLR40N?B+-T{uS^k_4{Gria?5n#3R3qlFy%ifqyioX-O;V+_k!1si&4Q^Y?O~3Ov z3a2#W!iYpGp7c8pOU04D1^MODd&(^%7j?kIF`)@An(d4qiXgNRxi*Rhl7Qr5*C)G@R@5veK}o%H?6R{gh|wJqCX# zJ@e#6__g6lm(wQwgu`a$bCYQ%TuOm?(*KwjH-VfGzb&9A6c54`ghQ&!jte-bPwAjL!~b0+2=Ca1|NL|6Rp{B; zF(|YO@^M*`r|X1srDvE$7KGb2N#MwrFisN$nU_boAPoDl5`T9K8mR#9FAG-*I?Q4= z3;O`;SA|D~uL~2xQH1|WI41l-_-|}YtP!K)55*seZ-{S6pONmBJ}=!bJs^EmdRTf) z*2yN>EoaF&GH$7oE9GAXGN97q3SbWa!zYVcij?E>^fbpdF@uM~@%Saj<9*<<8hE@c zz9Rlg{Ec+iEIb~P9+h!MU3STt@&Z|&2anr<$76wS2VMjo{|Y=r-~m&-L1z&5jZ=7p zKZ3_#@PgoF!2`kTfyW)euKj_`@_dmN8%5+2k4G5y==?@qrk z{jKSv(@#x*bNVaOcTOLgzJB`R>BZBz$;PQCroKM)z|@yc{^{h~Cx3tPKTiJk#>)P-F)oev73%vckIBi3y#^3X^x4Lf17+~^7oU! zojf}E%;eLPPfZ?~d}8wJlaEh6Hu=cp!;=q9-aUEef zJb&`M$#s)!CYMbvnJk?wnKVr5-}>8IZ@#(w&8|1w-)wo){l_ltk~ z#a8)!&Sj{O|KI;9LPS=Cb-f*Zvb^l5U|Y3J(XBbRSE=?Z1%3Tn<%8>b6)`XItO0Fw zU?8-`9|$NypCZIV?T0~wcz>)!VG%{{-&&%Gkx(EMC{d({Ja|OH1(~t9;)=`t{jmwr z9gj`qNpVGtuf0T8EFpN}i9tovbIDO1UZl(Iz8L=>r5@x*(nJjEN2rxN((L0NgRN73Y;d$@pE;~fJXimszKph$UrtIz92 zV*kNjS?TFPP-~xGR_e%C*ViXcsHp)_0fJI*vQkd*<&^Tpo?aQ$IGB(XQ%`R{LS%|F zk*}6~wf+A7zP>&`sHIrq1B$S^R}q#`;sD!~`Jj9dWlfZ8^FX0hz5PA@#Ol7@P+y==R$ABeBF;~ANr6(L z=p%|TUVIqCNKSPFUPG}E*d-K8DB_l_3L5|*ioU2sF-By9)&{gR!WJX}ysiCxl%&6% zLu-m0Hrj-EN319?!#L*1Tt>2}xv*k@5C`i0a>v0?f-030TkunbD6$_wrlCaDh7#>+ z5!N$&t}Mb=_;?1j*&o@6|3k4ORvdZiKo$8zfxaRzaYkf96g!l`M0<&1j{pT(Rx;vC z2{U+5LyDc=R^!di>&tiT6_%N1b zI6rtI=t{+owY`cn6q7p?s0%7qH0=JE-2V)&nupSaONhl{L;*MASYpC$C{}JR_6Nb< zUf}2{E>V1u2}W)v=uK``WI`f0J2Igm*B_bClDi->p(8gZGNC6oH!@)$cVT40NN#Zi z)KKZK==wqFkX)*;^QpCzD3Mu_-kHdY)X0)qk@+)`qiUoa5tNMLGvW!Po>EaIJZIw< z0Ddyy3IacJL%@&RMZk~TJm5!eKJX(q4E)F~0Dj~a0zYz#fFHS~5xI#sq_T+IuVnVi z5PGbicp?E;DJ7mQk0@ouN*UT?1)4$^ICkC!8A{ZJNU(ow3b12|Qkkye37f8iI8Lc3 zn!xGEj$Q~ws>P~VWEy!A+JGhYCatw6%&v?^FmAEg7-<@&$cfP)lF1058+x1 zdH{iWzv)L~Nz|1n(MYMUsYI#!q@-Z%0VJCJ1em4+uh?{fZ8?J-4}{WwBzlSJK4$2SbV$ohpQ# zCZ6!a-`@xMaQZh1fCl*=>P*!6LnxsWc*5bOAisGE0U#ujbr2$`3@sQAJ;-U0Ajbst zRs@8EzbQ$2sw^-|Q<@eSgeuzn6fHtcAXD>9lwyJ~k>$=%7ZpmixHuihkx?nF2y1&w znRX z@}rcf*s1v9y*+;Psd7_a=|nkmqusX6iCyjQnG+kE6Px~ac7CUS5sxSh#j_KnKS~$a z9#I;L4}$%O#}1;Up9wZpXsJ>T5IZ=^#K!q5fx*)Dt3U}awj_BG__Vnh@q7gAoDqq z!-CKWPY*ndJgXvyanu5y)$s6;HI$|cA!{iOdDc-H@~o#cVhsmu-}>!&iwlb|xmvxUke&j6+AhG&q{ zkY|X}kY_8UA9DUP^Ft|1&P=Z2sck2iDdTS6;-^!6;R%Ct``VmGeBgy6+ zui#Pr4C_o^N%=)gjGs>VCD?!XPRg$la)pyAzgCE`?37$kg$iR-HEp~NI8s>n zr09gZ6EKrI3iyZcbtOtCNE>*bAN{su=Ii-#J{7wjxs7sMsSFwTm*Q!JZw$Y!fMgu* zEaBBDp2s#(Uz!pw$!CMY7+MHUn!`RK>6E+3*cUYvQ=6v1_b}_YGH1P z7pCeeF{h?xmmERadqEk3OBPmxmU}ooFUH?NgrsXuh6ZW^7*Ng4S0BVlCe%MsdC#2h z)&S3~$bT=sALZYxDMpZzxN#>hk;)o}pSWoheu9U}S_4j94)+{zKc$@w(egPtP`%90 z3k2IK$mW(S1FDPh41-S-!WR6cQcqDN!Aop|^%hDwM)&FhGUBY=@R#AY2Ut+6+>Nk3 zs8wopBQv#I2FN>s!T;tPh#nF(kVDs?waoJm`^f0XkxGJ))nYwc51C^Ggl1U4u;N@$ zhG55J+llG68z(?vNda;%3;Ni8=(FcQ-Yf)G0U;=apnaYPyJ}(ZYaz6aiyX)TcEZD^81ta!7!cz`O@^Ta7wg zE38A^Y=CU&gTUkxrV%4mM)v_o~R@V#nvIf@3ns9btvG5LSVXdr<#aNuR3lFgl;ZD{GGl|_~ z^qMVW%Y`qn6>KFthxG`LuvIYQutxZda5r1a)|Ayp+sMwxwI!QbKTEJJ zIHNkqhS*lvyV=f$84NMA5w?TvWV_gIb`cw8d)OEoXBWfz|0V2Fb{V^zUBRwo``CVV z6}y@pVArr~*>&uCb_2VS-NX*Eo7o|D3%ixw#%|Y-?;I{KZ!70+WmQylIzFNC>`_NcIw>+_9%V0w69Tt0rwQGjAA;G%cdxl4L?UZ`94@*6JhSd++ zcy^WL<(2dfw<_gUr`(#9Tbpvz>DzQWhIfvS4XMHH9JlTSta2NyVjK)HpSt zx(?N?SF5YCUS;0O`V^M+)uw^r(E+g7$oQUA(psAuv}1f^YFQO6sccK- z)RxMrt=fu$cMt6x93B{-p+;Nkt9Z43aM#$WiioT1RvAylcckF#=u}JVRN<{ESL3V7 z)l#d`& Y{My=5Zj3WbM|mX<0#Lulu=APmKiR?A3IG5A literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Bold.woff b/docs/public/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..f38136ac1cc2dcdc9d9b10b8521487468b1f768c GIT binary patch literal 29912 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 bnfbLfgSm6Day;iB;wah|00962|Nj6Fv8wea literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Bold.woff2 b/docs/public/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ab2ad21da6fbe6c171bb869240954d0ead8f68fd GIT binary patch literal 25324 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 PaXk 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff b/docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..67807b0bd4f867853271f5917fb3adf377f93f53 GIT binary patch literal 19412 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.ttf b/docs/public/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0e9b0f354ad460202bba554359f5adcc8da666b7 GIT binary patch literal 33580 zcmdSC33waVeJ?ua%nl3&g8?wucM>46a03YLi%5}_MD06e$)YUDi{#yoW5;%4J6>Yh zN!%t)oHpCdp0wW$WGBtizTRv%ZQ7)5)|)hI^V%k@)1=Mb)FR*SoB=7ymXqeb_ucP% zqCfyMXJ*cSU(caH1VJ!``vg%~-nFlHVD3HVULgqAAI8z;lQ*2W`NUgJW5o3z76h{S z5*7d5bpU?oIi5)&DY#;RnLWc1mT8faTDX36Sv)rvKZWmqf$`ZJPuy_&`0MX61mWJOAV{~~eA8{W z|2!MmB?$LFj`6R*`PS1npZ)}W81vOI{waY919<-n8V0ngAk+i(K&c)m47~2tzyJ+j zcxHf{$C$IY_8$6KAtYo4?SrX^CeVQj8F0d3RZ*2fzF`kFhbC#gDK?vR91h`Fk!%a6 zwr>+@D7;nlBt%W2+SkOcR3z1t3Mc7jqmK8x-xU>`{FxdviAd>%Yf{|_C*G3)phAn> zN#pd7g_JOcC-xQsGJ9gaIN0D12#45%Ri%Ujcyx0RpX-d;}jArBF~!S!Gye zur`3^p`qs-8Y+~Eo&2Jq=55ydi^bDdi-sZIa`VnTimn-C#>z*C{w{peRFf=j+qu)^ zqxQsPMUj(BH|^4Gzu&8gln-!+zw^?AxN3)=eDj^fBL2U@xlYMT(V<37+3h6)xQvT z(H{yU!fxS&aJ%4}_S}5(@SZIbF(QEx82TbkeSp!P37%zvwLoSJMDAFk8fqXWUkHaByBod28t>%?c_2i6CQmE=9 zbmjcY2dS)R1{FzyIG+B#`k23~cTV+NO1_JzyIz&@`clzQ$ToGK$FJ!#HYH}cylEht z8%^qsQvFa_5kp0vVOox16+61QB-~E9&6=47Mj~0FU1y;x#<^`>h~Tday6G3 zna=eXisIkA6Wsc;)qfH5kn4Md$H1-k-`gxODTDL^TO2RVp&=l`mAVL%ITd(fOqnmX zMQ_N(Ynuozm*UcTeXv-}bNt~VcHkn0f!J`UO}s(SqsUMV`DJ4|2bzN%_2IDNgdKWo zMs7(Sxq!3s&1fQ&PCJBJq#DiB?n12? zE2f7^UgDUMT;A(FIVUd6CG5xFG1OZdPM2q!Mj;aQ9(vSEHw_f~!huj)rfQL}!$SkUUvgwl>os6_Ju5xz|BBzJLLr#u~y z$#2qgq}tY5_DDAE(G|nhWE*tWu7$3k;?qT@nc_Nh7Sy-!#HvDNNK{Htp4J6CCE|(% z1PFNNWOcb6f)x%G{=KJe4?Mhev!SV?^P+`aHce)w(64&laAfDShB+ZZU{xUx;~5z|BgmhTUw;VbS}c_sLqh}g`ugJv?%j6>*xhAWk`4aY z&0Bx9cK=UAbGW~zhy;(`vGmh-ALwUK`XrgATkxd4c+#j1XoB1@)SXBK%!dDvY8_k@mNkim&@1dl1vh&rtB7d7-a;g*X*PBDr%fk*%_ISrW%q=uk|Mg=`QEGCmdCi z2o1?QIyyt4ZX#M<$7@-ZpJvjM?DI#Yo!iD7)$n=9Yo)zn(ktn{c-9}tN-Cg!eD%-i zztJ9{45%ZNaZ0nvsHLc(`T#c@_MCnkCM#< z+SthD9(srwi*x7ldD(N{3s&#g`h-xux@ z(wK$Ds5~^_s#zspOk`Y4H}yA7d?Kj9q$fGRP-B>L`RHx?wYlYD;EMC zK~48%`o;}dl&F*JQs7<@VZZPJazOY`_)f~xfPJ9S$pK}AYpWizQ#B|}9J@u5K*s-6 zMX67ei71J3G{&$6uSNJC=IO;9WOj#(9zsZYV>nq&hf}pgBvnp0sS3v1kdW)ZQ|yUe z!m;bJjRM1xFAg;YIwyHyLCJ+L!LIozp;h`%8n<}QZc;RuLGgb;tKPW!3>~0vfVWhG zR_%!BuD9gkh~WiNz&NxyB(AAJU<}exEVvp|RmhuPo9y1)*cy$!LN*dz<>AKE|0-w9 zKqZrEbf=?oDAlmi^(<`d8{R*C{W}h93M%g$8hiNAky=H&@R`mY#ot@~;ybIEvPwE4 z-GBYk!3f~H5orAq{e7Vy@FjhKFPL||CpH(ReM6MlI=CQgsvsYxgAwc`Gqk~ms{Asf zkzg)1*VKq4nXgg3{g|=rwU6X;2lFbS@ex~9@6f8`8Lw%97T(lW54A3QKvW?~I<-uh zQZJ1$Q>K&86FJT(y>0bhXbJN=i+S~W`MipQYcp$8fT<=fy^PPQ`e~Z(<~uDVF9ADc(l!^_5Uxr>5kZ3z?vt z?D0ynHv&MS^=f~ln5#q#-KY7z5)E6L52G zhwRSBwMcH?NX`r%-xf`b4)spO%-n#77$(sMat7qhcc8D^3a4dJ^W_aVVAhsJj{CJJ&UO5~p6U{5yW>sE4#O-(W_CW%A| zi9Df&w|b+~$wt!l`Mh4eXy%7H(w4Gmu&=Kibt1XSHb?2+d&SFiGSsVt4&p(gR4A8o zyXx_N6L$a}dR8aNw}6K&z{7k9c!)HIFlh#Vi5VZp3Bfk_Va`LGg&=}BvBq7%(@?XG z5$1k#d|b%O(XpPl_7eYUp71Y}1Th{k8zzGP&#oVx4NCO1;(6k-3gc z*PKS7AMXTggV2u+VH@=0%urW?d7X`+fnsr8h#8P;49cNg(+6-?z?^LbrLIf&MUN7e z?(+jgl&L?~*E7`_&>E9li($na>7SSxEmWw-?zwegt2ZgV2#c60@8=acC?RTjqb zXJXl|SaSQ+D8hUqyaEuu1Uxwl>Ww)}Heo*)Y>fW^&LCH-fDx*eImeu&%r60@CMD(| zF#ttAmKlp+ll;h+b^La4lL;EI6u&5SHxw_NUfC;pdS;#q+K! zG@l(UQMvwZFEwO;C~Lptc0TJ`(nMP(@hl%pJ0!B`!At()3z#@4bKY?VC zh|^Zcgjqen%zgh-i97$~trOd?jT@w-6$$kpoyv6#?=V%Pc%#qPM`i2UDcM&)pvpbE zqsXFC&xN{HzTNB|y}}@xVi)_Q__nxCe}8)T%FRKEYG? zEFK+S_K@zay*}Gl(rj5KQo2!2m8vUprMbPXSdoC&&UV`ai#!8y7Bpm#4|6WvJlfaA zB6&B8VNT?lP{CUS?A)xc`?}2cdIfP`%o0V;aK~gW!y6v zc)@$R=mFkfoWLsJh9a0rS$~X^sHA(8(72YDbWI~xUm{4TsHz*E%Th7pPICViPl3t? zFyQYSF8T=j$KbnNcu3U9O@bjrF&D@0p@2^askyAnrn#Kd7|Lb2-<->dnt$b+E8mjf z3zGsVT)5lM-k7h9!`~!VJGz_i_re|PvTdJeomN29HM=2*VZoY8U}}42PD## z63!uEZe?7lXO`DB#>nTeu}m0T{Q%<&6TC5#_DmomSqs&^qGSzDDt1jjIH}rxhd~sE zq+8>KM7m5OC3`ZZC#W@&EJS+JvK*H>`qvX~!gCnZYfhNID`E`3v<8c9YR zUrJF#kDcl2&Wu-yoih8PW~tLM8kSw0flHE%7giqJkehpQ^=D$3eq2}L0U?;ZEhsF;j5sU+V_>({1i)rt+NFxVQE0e>TsF+mI*Tq;5!k^U-E<6> zJ%+O)y^ctl;mgHiGC8ot3iLNmJvld)Dy1^Vj(K8^hY(#pduOTV_)EYS_K8CHs0Bmt06F90m_1Qq_6J4R4^B~z<39C1?fS#J^)@S!7B(e)r*lpTd;@XK8Oj@z2lN4WOZ)m4&A;LjCrOMNy{FQ88DjUeGh{`hr z0x9m*FjQ6=vaY%gZ`n=guinfR_4&oxzPlLl?fs_0mHH82{6BuDGsm!V9uBN z2I1KvqcBisB4h*Z!D69MEXuAhYb2LR9fD zk9oa~dBwhNHq!O>tB*t3$Vf<-Y9S)i$A~gy1DH3DDckJM2!a1UPPgyy^dq{tS2}Wt z6bc7slh)wY5`EGK#0C#)p`_Kn6W*V`WiT8bKW+ih3K9JQsCh+~Xcb8ShNDy4n7-1a zpTPiA-_E-JF`)ESk0V;5a^UKz?qPTnuUmaatkO>ko8e6~Q{2<%T)~8i1#H}yaxvnV zVLoATgM=~p!XWs!VU`+T;n5%>1^V%^scVk)=gJ;Z8`!q{Wie6lhbi3K2lmDC31#PX zA)N-63(0G4v+~+Phe)@}{u#^}iA^eze_gy{slM&xHJWpzf8e2gNQcVNeGi2d;=O7| zS1}wtcYC*U&>-fpvIBNWTltj=v#lzI15O_T$yHFh0==nyaI$7Gz04?$iMGuqW9iF~ zcMv)fQ$dlTFza=|tw>pe2f; z9gqmzB#$W*%Muk?^JT}XbK8$(b{Eqn4;(=dbXk@}&`mJJ=1&KP82%EzEFU-*8b*2rV z54ost1|tW9SLCvL{3gQ`vW}cPIPywKNGY-vKXGxV!YQjX>1fEGbBIqAv)R5;D-!oY zFS1&RU!9`Bu>g8uH}4J0jK5xoTs_kQOW>~%!Y2VjJm#SLJ&=7JeNa7^1mJa-fu1My0Wuq9AK3}f(9fV?)M z+V+L95k}Dg=Q+dHByi1CFdMpgQ~!wO;rOtdhN4GROOhUVV8S&fmyVEA9T7=~VsLZV|Nshw39mmHZ>){y|vHBbfUmnEQz|Fh9gRK0fyi4$un-0fR$yrwtKU zOX_k+xI%Q51T;V-O~Wh$yuqntj{sr@8zLJOa`_($)*bR^kzL4yZ&0Jpk$_Q+YXtDO zBa7R~+wU2aC^DsRL#-{5ddQE;PDq(-qDZ`aTr5l`e3c+G9g30KVs8(!J0knGm3g*d={ zfcdEkCZxt?5@<9e@_sKAFX8$Jah_}2ZwKxt{|lOjG0~+G(B>DYrS|c{WweD^SdJYH z2jD!G#=IyIJwClTvUxMgJ~`zu^6IINu1V&lLQYiXe!~F==l>0rjCz$y)nE7OEjcb_QV8-%NtqC!W1Vc7=mfPgze6dy)cn(htwb?Gn%kCusxJfm6opG!P^pbND)Xcn=|y_s>mmt0b`E(~euN;S2^9yH zVRSZNo7b6!mM^@OK*kTQ3M;=LKr}zkaE8tsZf8!eQQM8ecvXR6Em$lSxI4mQT00V& zl$eLc!!K@p7z;pT+Ngl&;W3ogB}zTCB<8sv$K$e)N%IN`T3bTf!@4d@svr1zMC{FR zCO^CdHU6hiCPrD&7~Eum@4ekkPlx77`l-f-$W})Pxq`(l)Cs5!-3WWmkb6giKp&6- zOd;0SZ4-FXXqts;V09wXl>izu%y{2S{};R&k8Jo*U4@pHnWtxXEM?_uE8ixn`a~i- zmL!E0P0UEpwG;(5+?2(tzXx9=L_a2kg+6%j#i+q6Tuje%ZNil%i$H*^$a;#F`yj6N zbiEduG*af_>*9qsU)9@tY--CxSMK`ft+SRhd^+D}(b0xtJKFT{LRUs3^kdZb%4@f5 zyXL)FYii3q_kMGt@%ddRW%Ky_$@`qt;xZgEb9muJ$9AGKiNzQ6Yg}3nV|Lp&@ksij zH@+cG|9%*`5G4|~^S~Pn65_wZR6YI?98mhldY>oOJKO0tG_T4^N zDVJoDk0iain*Lpb97^?sM!Pmw%3gKm;az)*_TovM>{|ZgM)O2(Kr7_C<2fF4BAfd~ z@WirkH+bTg`!C`(Or;xCkZkusbQw+o2;tu$K z8K!y5d;C=UXP}C4Ju@4C^SCh z8w*hK^825|YCRn}7V;7;mE69wiRi^2sP`3^&SW**yXdEdqtKbNS!QP(K+Az;@do>0 zy#at7oW)X}%oHNH&AT~srac*s-CR#w8o_(4K@Q{cu5N`!WvAXNE=<{K_kxFZ%adD! z@k}6gX58}Z?>1vT>Wqk@r9t5m>4xDW@$e%3k{b<_(KR@k-ihP66NVWw{FL){kefiI1*w&0{|9e0U2(^pIZke zN9(2&s9^9iR$*Rp5LUVX0b>Kzr(`-StK|I<`cC+}SvZ`M9*o+9HN=keaZ#P`;_j1O zz9W4d6agVdb|_)Y&5KIys)Cb6KJtSIc>l^$k&=VH_$o`;iA2&vqvKJS6!`lWzJL}D z=96;2i1`opJt8B1Ea zRuc{qcQF{8%=dPG$V>KIBazeVKE!jwDqqEyFp1pkpPw8}kY(3Oj@I{jHW*0xI1N{_ z)?g#*+^{=}O7?5p>9;k1(Wj_l-+Kpc7#DM)##p1iUm`Ct)7&&N=b~*GJu8o>)6IfW zHqa_dgwFv3r+@*Lmn#HVEaceX5aV&?V{^}(1r--VB6LVFg<7O6AHfE&RK)-v(*`|H z?jz+#9~H$euP7lxG*X-EL7RmLqCQ<%d6OCrNwi65ml@(V9#$UI>}}j+xpAg3O|KDG z(h~XJGf)K)+#<-FTMXk7(!hmxA!|clLQL3m5p@if&Sg`fx=E^y0C6$o9N7j4-IfqlxHyQW8UU{iJ`buc!VijuLv|SCMuCuJYB$`o&Pb1v z=a5&|$-w-4osd|};7IUg7aBG?tVGXfN|ILoOkr+v&>y`bGmCt#r4jUmme6j+0x@5H zaWWm}QDmgYOY9eAngKwc_xk}T+^5p;jR81XXcD6L2A+9_kRuPg{7M#280)y=F+xp~ zF8q-K@%g$GslIpQ?nz{7G>P6pQC4e*Zfi&-Xyu5m9JanRdMcam5Pisd!J!g$%g?i1 zeb5NQ!0V&HYf@yI5s2e}gHbpt;1j}zxE>`l5%|xXM>qIXA|Z!a4Q6!Rs~VFO$p_9@ zE**e3=t$SIQ{y^>M{YxFSM&R^3?kE^YN7c0Vp&x=R{Y!R^tzLh*i#ero;Y_s zz2#AF*<%!f)B|iOUXNO!)AV6c4f(t%0swZPTl8;@4JLy+RK;k?s^2FK4@r7Y%8l8R zf$fQ%ejdOn2C$OeMXHsu z7BpOWP2k+es|d{V5mn~-$Gs!3m*4i^Bo8|m0*fP4Ct7|40|XJ?Ka%>ub)u?9sVl?a z?@xmcXFvz$)yFQ)&$1p7R&?HJj?BNTUkwt7qO4CY=obJ`B{3gEyj$s z)qiK6VP{0vOeNMBq*_lJAw9aLdWLTaAg3b-;~vjJ`WcCMvp#@@9yZ^!(;IawGvg)e z-n-(ePt}cXR33P;XbS11wng`nd~Ob zacj3mBX(MEdi^yqv?w7ybmJwKh1~;h`D4J#DDVJmTdY(o4Ra}Re zZ$-E1|3JT90y9U78J$0jwV6_3tuoxRWsJ@mB182*vy71uQTmB2;tl3n*^dd8zTgcQ zK$=JV8`d{rB7IGty@jxtfA!yS_iHxZop;Nvp@Kh#*{vZws!{myW$#Wu-M;;^{p+_E zUya)%{GvW;(GT-(+^EU0j;?FWyj0@C3<+NEpkPipwGy%h}bj;feJ%MmR}BVTV(&zyjM- z^jmk_z^p&j?9Y4?>9RONXd(tt>VcQ%MO1Zq^=C9kK8iZWE_l$JhkIl2pwR`w((H`) zxiWKkh4BR^L&43T0T^cFp~V>bB2Bjv$IkI4d^eopI*xqK2rr1#=QDyqR0?!C0Q(lj zvW-5h5g`ivM%(Tl@C5cXyONzz-4bJCRw-V_hoYS?2r!`1xv*=W$?l$_EP^q;fk##N3F`%s6Kl=^GdE+{WP`5`5QPFH3j%A|y@Fv-Ra&tcF zxx%Kocp#D|FAIu_vv2f>7Tg-3zEHmrLUm{=C{ypjnM8E)u9%5SQpI4P6N{l-ZW;n^ zrv(4Fb9jOT{HrTLjxi4zs_C}j_Zwl1rmS;WKSw*(>fZSU2JP)e!+Mx z`AuvVx_MTcU*j(%oqWE~php}a9|?u!&natkkQM7fO9^Jg7v{CS_n36|8k?p3X+>*< zR(Y_c?da1Gjc|%|WB_<(ek@vxrj^LfgolVsJO1-(gM0!#Agup>E9bJt5Jx_5GT?qZG%sev zezc*VL`=r2Rg4nVS`X7=kw|I?E=yl75pd{oI-*AOO^>mZAUux8K016= zf3HD{*+emHXB;X=tkO3B6`J=|4^j+4mQYq4{hqD{8=U@Ey?~=^B`c6+W>;^bKMq-ls%8 zTqjzlbasyElR4=9JS24yl+LiOakrI?dy_70OBWTNE3p(V{*|{a#NZ;o-fsz{5+7*+~3=YSoI2Sqp)0Yqf^Ma?Q!ts2~eW5Yy0 z5XzppF{_#ZA3bnUF71`?QKd4}pX?di(-SZx+e&US;3NfZjnZl{Tz+X&XS7{}1RkVM zpbu^iv>nU9|A3xfYk~tSs>p9~(t(v-j)ma|pW+z)ueEhO4?K|lUkZ^xq|*sFKGhqv z(eEb_8!2ol+JIBpQGwgKL=-FdJitVkqj~MO$eo)#bOk z>*}QJlO+-j>(AkAX4tKjv!dgx4hAB{OuiDdB3YTJ8YsB8l(v`!f+O87Mh% zB$=Sv0{xq8Ww@euYdvAOWheJ1F6DQ~>LGY6!@yJxn2K+})a5NG;{o7h-Q03;UrWvB zIbYp%BB#f5Ym&+5f1zdgo@4R`%6=tu*NT$hK?xyuomGUd&05m*cGE{o9c!)lU@U7sU?F3su3n2H(jda!oD9H;YW ztTLTMwASI#-6OluB;(Tq49VzAf%Y|04cVNrB=7JONupP`TAnkyVWp7}wFXmIAH@|= zv_FyS>;Y>_YdYv)Fnji8S|X*9IC?hXM%d?UvU1nChekBhn=`}vkgri>Pw5C&0t|YL z;Q?Uhf;)QvWY#ud^ea8BQdlX!7vT!ekJhExCW>*tVnZ3rR<}C8F1VvRn^$EFBx@iH3+eR)sIi ztb?*TiPnOT3R{IMF@uAPXm`R4*7PTWvkkUxErMfN7B?5blr5;jtp=!p_~kitLehXG z7dA)%#9)sCR7dj}bi)ia5iJZJ4##XQ?a**IuS#fjMcU3|ZLv28d6H8J8V6qu7LhIp#o+nNl^E4OJ8Z4q%%A)uZm-g+KG?bCipG0}86A_FaN{HyyQDP)|JG)J$7F7Jl+N!i8|Gsi^pbtNChB}5A=E!C!|+z zf4-;gJvtK$Z+lrP*r$7pfOX-o(GLztd0#8CMV72e2Y0JEa{Fa{b1rqr5`2{BMoKEP zJZp*w@NqC41|&2A2m(D9b9gO zKtL`@&Y|%YV@SehlVFI{dJt`k>WK~o^+TEX3@h3bK-nEW zCGw1!?o7I?-dP~E8q0#hAe4H87VI~@HDGAlVJVO;H`L#8`a049q6D)j&8wpo^p46_ zEY=?jG`f7Rc_quY!E=|%?wJG@bG5biIAU^E6`E&V80)=z7gct9!VK+PdATNyFZx0) zmU0?`ModwxrM8p;qZY_Ze4|r7D;)8MgBN|wV0Wfa?jeB=P3f=Y0^6ANTO^|GMXN+W z2{4FbeU?*-_(bBZcqWHCYJ;N_)!>?^IakV5x}DlpwNzxT8bMyRq{6tZd`0!!DWaOC zs)dA%6gid9#Hion?c#9$ocw_N3Gc5m`1<5Vb1g^GR@MOE`7l2RXa*!8BQG!XM1$!{ zES@P%%?2~hCE#UtsFs%RCIPI0AJdHTpraBvq7Q^RE2-k{7j5ncIh)3EbNi>t>k!=> zqrII@ZBKVGxt$s}A4tZE8N}eOb^S2r&8nA|n>Uk*!Wwh^#_10YaZeObfH8T{2N#qJ zmkxMy zx?yl@K#7=!JUBI3fB5-OpYFA-z0}+ESYkvDd{2S?*zrKW=@_ZbY~|h(M+Ff^VQ&d^ z$Z=p|j@Pu>;IhbvNfIkhL^x;{RUdNaOv$KRi?`$2HkWdJ!$@B$x%k87%qv$pK5!or zESK_eAA+)gCi`~|poMQfsd+lOItFqHE7GB8o`6?P*dqE#s~)YM_9+1*^lUv-$z&$e zQmN5d&mkF*^XQ4Lh}cBZ_*8#)x~5ajZ0u9Wu*b+(3MnYhvWbF#X!ht|wEX^l>fe+_ z-xOjht>*7{tO2;z7#6nkSd=xZf7QSq3GiO))C0NQ0c;HX7IF*22GBr!QDIPT(6%nz zOo)N5-zc`3a;VtJEW??^y_>s+HNqe*i;;9CUkZCAsqpKiwvc`DwcbREt{mQZO(`eq z>8`Nd?W2*-?oDwY)L@A5eiPdE3!wNxz}UyK!_2#4)*|9?6W1K0Y#$o_!;4JZUtwfq zbi{FH&zXF14p6}+-0x(KhL- zJy9|L7SIIyHFRM`BQ-&Me#TtdIO9T zL4bs*aFIcKYdKYxyHla$cgu1%>XAZ;8eNK2s;P23UW<1qG#1Vjao1s*M(yOY@R^hF z&7$`DZcXdtV)otPg3YW&U~s}+d{>y3!+%cms|tutSI6g9jLqE_{4 z;Z1<-_g@>|xJHT>++pzXyrCd=M8aFnVLiJHlWh+ToQl#MI1`Mka+l}1%LQ;54J1op#Z0?Lf>g6mtbU~`J{94B-4;enW<(BSK=&`Dk&8bXWfRAj=3Bph4YDaz(# z&VKyKR8m77n*3ap(nPYs?g%a{ySLhb8V&;ge7T37h z<~?^^cShE*?TIAYtnNr}Ku<3Qt^AOXN6?M-;OfW4Zu+l6uP}q0zvn}Xvs3-00J_oG z4npfF9%9ZK^X9^N$RATMoPMQ}ii#U2ViQ#`1Q9sQet>#hF{Ds@!Ub(|F$xw-pPzX6 z$}Kyz#LlKpq-g~jM_$Bgyg}l5&y6F~J4cm{BI?;xoFkvDZj%hUXMVB+dcxfHx3h

    sao)W)RDhP<$lKtvB5J&Be8B^s^2^vpe>NHvGX3*^v$xZ0pI$f4f^8M>O~ z(9v=iayYxO#+brdZhRd%?Q{oP&{>-{H!a+aXRUf`!4qR&C@F4oSayefbyYKUF~-rz zRLY)mSPFa1#3p3UnNQqPqpBU~d-%m+A_lhP6fEya1^k9`cCs{>a1v4!{(M;XWE@$? z64_`l?nm}LR>;({0iW+GJ6TDj5YBY4%>4Cv6eOvUEj~zgp!=Tr%!JmKI!_&!jF2&N zsO(26rQk$L(XCkZ5zQu3@IkQ!f@JQq{UHa-=5n>pYRYdV!wdOrSIFq>zVNF}Cn`yu z7BcA)a-5=Y0GL*)uL zW3{%TWh}=#8eRV4xkKW5HOTNcI7gCC7>P(Spv(`bDrK1?Pj1uVcvX}^6l~T zNGe49n>`LPexXFOE}Lb)A==O%-3zwk*ZXTX?;%RmGN_?+^mNzqnV@)oG$lv&CD7Vy zbtG1P(kBKMm3wX{)Z6{i-RMdag^|@)(;CeoFF1-7mYxr7o*eG&@?DfYD7Od{r>o(Z z9J!pvv4qqn{&RK8B(E)W$iVW2x*J!*zqad^{kcRbtM5gj%{Wki!Z9Yh_YboM-Z1_t zo`52Dk!G|b8s449j()d3Dor$RGXqYcFc^1qlIYuZ<=gY#pm>wa9&@wgn=&;gs$IFG zr-{X>$z(DiDY~vS$=jm7%DGL&sQJd-MY3nx8)e-aFYTP3;JZ-qd_KIk5y(|73nQ2Y#n}a=H3hLziP%F;@%LrAiP9n* zE^J`3vp-+hbR<8DzEVTurbngHhu)blS2Ky|?yDZWa&Z?Lq_Dx0Y>E1K zsScUfPM3`?en!JdRal15t? zYt6iSVw_U7)Mu(U=2LQD;jRyu-OEFbbaKfi)1e{A#;MgGK#zP1YdiJ`S3x$8?cch| z%XYZ9n9YJkf_(?BnA&U$2lo#g*FRX-GHtyA1S7AthE_L_XKJR?J%p1u#&G`+qw^m7 z;BYKU{o67`R8mJvU8v5^HC~Jjb&4IPvAN#XFG{evsKFDR>VSE5hHpwHN}ZWRc)$)d zQ!#|B(4ii=I2klk+mCo@=*rnlZOiRRG$vQBL5AK$ zEU=-9v?1P!xEKOEt=l2yK^A)j z2fN8nA;TZRS`Fkj+SxR&-dQIuGlO93p(d3~L@nFx?kFl6Xjv2K?}|S9k&uZPX4K4L zvqat0>5~*uG0Bl1lMmvK0d~iBmWR2=%s*z90??9N#twMpnJ9c+=@h#59Up|ZwyEmDg;o2%H2ifZGh80LOTJIKw5tk~Xfs1Y;FG2z7w;s5+}eOC;6=;FQ> z8&<*p;0NuM+@c)I+S@0h=#s}e z?G(C3os;pa;_ZgY%dKxmrOxhkx;iy9m8ufj;#F*rh2B$&{y>WCv_O9dZV7^awGYN4 zFht;BFj<6kffp3E%M7**#Bwp9H7|s+bWje2W%`InS6VCQStl#`u1L2I)XB;l$zRgX zh>CP!4>nn3jkWY?NxJar)m5^BZb7z^XKlSzH{Ty)Q@wySSFllNbLDae0da+y`v8%P zrpJl2ZIp`bAQ4kQbMSo3q&$W43?nkjs>3*OF*9X91uieMFzW|fHXmQwku@6q!SLSg zN4v}iDZTDGgq{8fI;+`gNkr_}Xy^rwK7aYvSNEJfbJZJ1`WKE_%J!pAkH3a`yu>sW zU7Rr-Y%9m|JR<5-&p!y>83FDe0`B*KcO0fU>WuzemoXle9K?#d1QspUNCkQxx4rN>bbU%XH7K@c zKz;zNt|H6IKl6-8zVSH+8jS_@Xe0;qw*lH8V@*jHdXFC99!gKQpYM)>?Tb(ZXIc%> z;96yEaInyBSAmTHlwb)oEJR%XKzALOV9hHmF(eJ~b*bF{{x1tbIqCu=z(8z-i zVc{nYvdt%OfQVUyg+zYnL0MK;Of>_KO_U6z?2ztY{G^JW4}aPO5>0Hk%6f@w7$C0D zH=@k~pR|WXWG+yGC>SiqA~$T{UL}wIJr=~iNm0c->zc^J5K^)OVJL2g?Xo1Bgo5hI zHtcrydX|>KV>G+0vk)H+hfxl*?ql*KDvPWOm}x2T3TUa*ze!8wa$I8;m}~u;cM@Pd z!yp4x*z_CLh0Un*h2nPab%Hyy|jeUO?HcZ}GA6eRM`cl%KmBfJ~Ak z3T)B~pTRa`8wLPFJAfe*IXSl1-30Rr34&y>S-lCAY>YpUlVLgGuw!!vMvb_2Z^luK zp|}deUM4y02PTkvUxj1}cmqxSJW<912{{(uYut32z8Iu>;&*PiX-ld%S;`=349-AX zFxEebEC0FjpIG8lCH>?e!J2Q#8qaSbDkz2qV=-hU$jZ0SQ>Q-i7?{kLDjh=cjv^I! zn+Zo(g{zPOOkV~})5y%QdJyVbYx^)2+8G%p20@-C1U$?aV{sZ&CrsmToeH4XH~t;o z3slZU2e@swn3_?TLc;31>(V!%uEDZ+kxeF&cMI4es#LVKp`fHmfP&EIOulP=6qv`{ z1EH;_WpAw?=@LJ{nksMgIXwW+U6}zB#h3Mde&$45w&$aPJfk#@peh0VxPi3gzVE+X+FImEIZBbsllXgdLA z@fI(wR$dC83~nDDsg^xosFgh{e@&F|Jlpr_v*1Fua_FVt!tH)=VQ0f;WtA63x`^^z z8;Q`;V6ZjzL|4Lp0rTi!Xk(ovP;nzy)4O>A^76CbK4t9k2tNY@MsKOcI*o8g#>@64 z#5U(ajTQFGRpVe*tN~ z5_leFE8m7-EjhaC2wFKtm?SgVzR1lyhF@dZ`r6hGu7<$q^=KD7%cCuY1#H|qtN*UV z49`Tt$;jT1->G1Sv}1Q+BNKhA)jJuD+WCs6htb+%`PF$U?nez%iY)er%d_KtW2AbE zhKeN(&+fxkh&231s4XFTpz4YJCxX@Doljv6`M&M`xTWkq;f!qU?7)J4e+~QEW0#{p zz;DgJ{lP;$S8SWuO1+&&Kb3lUuHma=(G)f=f1I#AvzLTl(lSZGt8LeHg52JR*jf?P zK3FT>#>FCYxqI1S5ts*ewFq{dV5>!laGUT;$&dT^ai4bNij5XgLV&JhD!%zrDn1NT zg6faBGO;q@-h}x^*gK!P_xPXWZgQ4>6uURJcK~18uR7u`TwzLp>s#eN8rupP9RZ0p zRlqhjk`HNw9&-2Gfh)_7>hox7|F$Z$d<^?nVs8H@_S>hzPsrW$IQ@_iM~@VGa1$!u zBLQVFCZG{GWE>Y4VW_|GDN1DgK&(wDS;(n+o&-f1_Q3yt1w$_$*nf)-GcWP zYI7B1)v)96Z~`M(5`t~aUK;T9`ow-)o2{$)tnAAek=w|$Zrf3(OZR$gY(vUd^l0SO z*f5)%#WF<0E8cON1#h3KV+%twSY&Bql71U<45%Jew+V7a2iMm%Z z^~yqkca7rD4he6@UsGZK;LbvlUWwmn(_jbi&u;%L3hyS1WCii~PsO5mh4>YeBDYI7 zNDoQxm3}5~lE0xWD}SYqsPEJK+T+>e9AlH{k$<^yu&x)`;vJ8vEUv4 zFIm59{V4FL9k;Ku|2249s1SO0I2nGEBRQ?e?NK3mEc$r#Pon=G3&ma;`+j^Z{;@<@#-6^U#K0aeZJ?_ zz1iM#eSyBu_1{0B4patq4BR#FM|E1ivi?J81m@`rFHW3)M9;(%})UcW2@PEPdl);!-@k_U z0bv{N@rO9~3A{cheoy!;-uv+SG(9cs!LzrL`s%-vRcQECVF|C(!{cwN)}jQOqp zGrqIA&td!`zJCYb=YZNnz{et8?z>63W>TVa&^ z6F=9)*k5qm^5>Faj5#XaCX8a<57O8w%fB4Jm=X3o@oNIh-kl=b@mzO&5a<2@pLgSx z!^_6FpNdoDtL(n`u5z3VaGd@g{eUon=WhedP26V(p7CY8zXk7~<@W{L;)-w^?(skI z`Z8$!6Gm^E#4b1hlKya25sru};FVjXlbov>HqNaV= zX6euAU(vs#-xOafJ}Lfz_-65~;@ib{iSNyZvaxI`=U-jr&+EjUrtsGXPQ1XK_To;T zrk_FN@D1@b8}9T@@jcmK7WE2tr`7*^^}DNo4~%_#^;@f7U;XIn)2n~9`p(rSS07ou zfA#LwGphru_Db)C|90W67hZeeHP3$Q*{?tQwP*j=vtN1kOV57s*)M$Oy6;^5om1bw zjl+sb{lEX$5~|sjaNzLVQZ~EzVZq$9*i!Z#IoxU_T3t)aS7*;1INYM0CqAM9nI}&c zu1e%`En%r8%oa93g;~rl&(vC^+R83pU2D;5Ay>%NT4FVO>S-|)7G`E!!P)Hc^2~V} znw>e{DbBX&?EX8mEu(-BvnNiqq}_Kug+Ld#Y2{8QbL{9-W|+(*v-nt;c`8VPI9F&1 zyAPjUdJ1kGf1p%tiIrA(_Aq;1%bA^R4@hKBWm_NH-I9t&p6VjL*}0Q*EoJU-t|fLZ z?Y-hK1}DxP&bD^%#-Zt@M7A}|J`FD|WzV~#F{3UVYJbbN`q=qCHu7V;4`+dmb0@Mb z&+fy^IFe=OJnU1GeQGWzmY0^662Ml=m_6AN_8x8ti)?TX-xG_iH2aiZJn>;mILStQ zSQf5YS~_)NsYNPFOKk|2vZnw~VP>h;lB?OdY)k4q0hrX;-G^IhVWy=OWb?uY%kw*s@v*>lU; zRsd+Lwe0HR{=?^`Q=6AMTE5eTJ8P|Ab#c$(#eMF?pFXO{rU z0_MMfqn8rv1xR>a5P}6DdA21?K82u|^Fz2Q;7=va?LXYI3p3fdmI?OrL9mx+vdbTe zM)Ak7grG1pGs7?t!Z~u{d`PRb9;+nsU~dO7hAXvJqMx&{NqFuslp>>IeFJ)4XiTG; z9pp0~#NFKc%spRCK>J*Fw(Pjze1KcJ&69=U^9>Saur`4Y0C3rBmLV)BhHI^%YENXm z)*AjzL&4Z5F?<9h5}eL#Pj-Q+1fX{7xpNDJ1*o9IFnrLuut>v%ghRmaD0CMbd<>JI zPCNOq^M)|f^3GOHpX(`Pv*YJ*&#_B~WqaKFwUoll+URU+ndy}2J%^u`vT`=@v{aPi zOEXNPcUo6CL!W?Ta#XV7MNvx z4HsF=KrXg%Q5XlBCe}~2JWwXt?0jK?J(N*#a_t-k#>I3?*nhYuI}U@+W>4LNxam46 zT1qFrZN;f|-^C^3^Eq$1(54nNf2}pO_B4+DHo2CWgY#UF*GN1K{n5j)INyrQ9^RdR zP0fxk^_=e`A;|5fOU~|1?7rme%q3^nuHAUQ=Uy>eZH-no4p_Tr?SY%Ct+C2Eupi^G zbCC2Gni~k()9S+%=QzlWjf*bkPryN&aY1M7T!5tYK=NFG=BwvDur-YPIp_a&EWL0! z2K(RPVuo*~$Hoi8iQEQ$$t|_#xc~(`T3N%&7JM74ipw#%KQ#TLqL7q9{XU1-62J7pJG3(LA( zy;re{8XNr&w6DG_AXwWspM3D$7%z!`gnh-&cV?k%q^U9P$?o~iobUYRcYZTx&Yn5H znR)I3@jZy+wOZ~JoZfJ*m0h2#*onDAUEGAXt@V6Z6*||4nft?Q#&iJ&0G_~Lc+Imh z7XdaVE>1UxhQtvV7DwQcI0Bc$>$HaFK_ejU?V!={IuB$*FMwR!74ba9y(peVFNtT- z%i>w|it_A)_Nwv}@Rg^)Rplu#CeE{fgg638aRkQ25ty)g#Xyr*FQJsxOXxMLm(Vq< zm(Y~eOK95aC6u;$3C&>RvpWTtv7uZC2VQqD0?f+jqUEB5X1Uh_#hG(ZoO#R90dW>c z+_oci(S~e_B?pz_4F^Sk6FF^8U0a3NBDQ*5;oD`#MVQ!V&FV2l z-6^|n@LXRR8?sCe=(BOC>_AbV`owK->qf5Vb8gbH_2NW{iN)-{f(QN3^`?#9BExFm z_}(yMCwsi7hww%^8u(`GUSQL^vvrU0&N{xyafSb443v2Kl$)%27K-RxG`ILV?9tzF zD~|)LwzQeYK@&AU=os4v59(5<#EZb_^Lp{o6N^oo0i~Dyi=Yr8CLMj(!)E! z{10>Va~wBgcrS(Mduw28#iv=Qk#C5RuSwoKh?^!9hnXTK%|6NeIw8hz3)eB;=3$Z> znFV@V@@Z1`kh^cCMv&l}1QMswtOqRr^AY+~`oJkT7tqtkn>Pisi!(?Q);^0~Nn|yl zfwXom+}tobl& z6xvyq{I`}?d7WjQC~b9EOlx^hvPOz;mIynWw4=fQS0aTuUdxx8Ur=hha}JaDB9@U} zA?7nu4U#<<_)QSAU4kJ-@A{m9N^q|-QLU<=F38HW1?l3P=Q#2gNuRap9mCZS)lcQ9 zyyn5GSy{03QC@LsLofS&t^{#+Yt(D&*tP_f%ieWCy4}~TFy9bbE$~fIV|_fJr);kG zE#li8Blud0IY+InKr_{>47i?c7Tf9y%@8+Bsp<-x+9}<7H1FaJ{!1E~AvHV3Y%O!u z?DbhD(t{PG!7Vl=bjy{aUnQ+jm8s_K<9;5y5AxvsDE_aHG0N_7^8|0?Y8V-Ji1mv@ z=CFB^`Q45(j_nvV^=VdCK1oYai}v-lRcYe-XyFYWj(n_A)yf&4p+2|aE#6@wv~Mx| z0J}^#J**e-)9T?o`=}@VtXe-vU5aD%Vant(?ZYT@a9_crgdS6RdvEe)<`46Q`I31- zzcOE&pH0rJdO><(|D=bV@mS_p^PBnI{9>4i-790Y+zJM4J>pd{+vq-Tzjwf_nRQy) z@65Mm!#h|ypH4M2u%4UtP0gp={(NhGAIa~d#ohk&v~NSrtu4hvlgT;1q}QLmn(zZ7 qslY(0IG&n-Fr1l9P0gf(1Cy!Xz--DTh*)t=jSXG0xko?nzP|yh7T3N2 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.woff b/docs/public/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..6f43b594b6c1d863a0e3f93b001f8dd503316464 GIT binary patch literal 19676 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.woff2 b/docs/public/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b50920e138807f385d0b0359f4f0f09891f18406 GIT binary patch literal 16988 zcmV(>K-j-`Pew8T0RR91076^<4gdfE0E4su073x(0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Regular.ttf b/docs/public/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dd45e1ed2e18b32c516d9b481ebed3cb8bffa711 GIT binary patch literal 53580 zcmd442bd&Rc`n@NRIci-?&_|t>YUT0p3ptrljF|J##wFDMrl{lYJ<`$AR#0nAqkX0 zB*_AcWPEL|Ot6Fyw%{5tV8CQ!urb%h27>@|eYu1m8*T6Zo>M&=KoUHD{`)-t&g@Kg zRdv<(edo*JjF0$yKGS!HPw*Yux?^x;=`S{p`+QG+5JwMPdez~Rm4EvFoX_`^?ehsc zFTL@G9K9;u_W3?l!})!epFDciCG}Ic`g|WchMV}09=`r0j)#1{udKsw_2`v1U;ang zqqx`bO~kGc*cp6`!wRHLPmGDvmsI z*~kcup8C-U`BPl8>Lb3tqM!E#eQBTiv=h=P9qEfSTa6JXYEwln7OE8*aqz}_J=$!o z7UQvUjZiC0No_WsO9mo67A?{@M+#7xRgd8%o*f;Adap z7`erk{R?~jMllgDR&oQ=t)6u71r7nWvC}hx2H1A^4g$7)yG9gFg?0n5F_>%`Rl2Vk zS@6aqNKsMjF33eiW)uPv;nDW_Z*UBE0+PjwgdglPjrN%N)7~CY^oQv-@=?5!bvbYW zc`~TW7hP;eZ@5m@gX{wD@HrQlp^w#qxue_+?)KiMBp9)GK>h2_pSM9N-iiqZLd zfhqyNBy8S71ljPe(3JowQ+`SJr4k5AxI&T%er^Wa``V{JLq0-j#9Xz|4Rs5=j&G^x88+PKDM3+Xqqt5z`Sj zn{mbT9x>RH=o#8Lp45f9d{HGU5Gmc8nWti;Sa0+SGNqH6K>DW}&pJ7wIwBGhC6p3- zXK&xk0oPFLbrP8D8@Hs0lXaaeq3aCtpMnui9U5IZ5!DCl;feZOSc

    viU|OFj=e4 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

    Yqh7OdB% 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�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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Main-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..eb24a7ba282b03d830fa6c63ee897d92a5188736 GIT binary patch literal 26272 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�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 bkH82T%!~T~dOL3iZSfI!+IWoKhyte*`46Vs literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..728ce7a1e2cb689df32c3a6c26e1bd072dcf2acb GIT binary patch literal 31196 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 T)YS6}E-Q5R&CfXgJ?`xQe`ny2 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..0ae390d74c9f665cf8b1e5ea5483395da7513444 GIT binary patch literal 18668 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�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 J00IC101u*7EU^Fp literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..29657023adc09956249f6295746c8ce4469b50d3 GIT binary patch literal 16400 zcmV+rK<~eIPew8T0RR9106-7`4gdfE0D43K06(+<0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Math-Italic.ttf b/docs/public/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..70d559b4e937ca1b805eb39f544cbebe3c58ca6f GIT binary patch literal 31308 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 G#ECDig^RoZ literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Math-Italic.woff b/docs/public/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..eb5159d4c1ca83fb92b3190223698427df0e010c GIT binary patch literal 18748 zcmY(KV{~sl(CGiQZQHhOoZ7bCp4zr;+qP}@)a|L=Q@d}Ud*2WDPS$THGixT<$;#Rv zGCOYa;^F`xz>i4r0^t9vJ!Su|{$Kn57kOm{W&nV%`^T#MgMnCtOo_3rp#uQGkNBe} z{xA(n^1^29>Ou$rh<*I%fH;6L&3utxNs-sXnRKe1A*KR%HE z3!=G=hZz6>Bnkj<%>n@WuAwnb85X97CIA30>W>fme;8v3|FQTn{=7@}k52FdDFi-n zsfDeJ`;VXOPrSkp?GF<0G&c6eKYl#_jj{6|tRy&!wubIMs@uCFQ%mqlgW|L&R{miT3OGXxosjhEk7N2MOo3FTxj0^^rd!OlPSx3D& zi)_yKqvM{0hOWnoi)`hxN*@0JPeQ~O$PFN5!~j8(jc_%b1*Ol6xwQ)m{kJOak7OO? zo{zL!s24#&I2Dk|xg*&C4T4M7%^1(ER%tPdRmlnsDzuJxhRxQ$a@~q~*>iw8qN zo`isapt~`IAqWr=pf48ous4J1ZOdk!yC%F%r$Y*lti8MYsOz}YuBzB<`<8Y}RRkqj zoo=ZjS)s|ICa4f_V{l~*Su5%O&E$CElN%odXcJy+q;O*7qiCm(R{Ir& z_IJ!gfgPIXhF{l3f!F-qFLtqgL%}jwtV&dz+H~yQ4#RO1y<)wzpMd}6KNlVgb2`3`UJK|*zEshFwUNS5 zC6%-UB-j+9Nv*j1g*bCdw689CnRMq$o=Dt_>RN~ny=N{hY$b+L-VSgYoh}Oxdm1q7 zA(jN|8VDLqLu1Uvp-G?}4p2hx?XSFb5GBZRzvh}~+z=onD(%|XJ93W+@~^N&;;EM+ zoVGX3XU)hQnbFG+rR}o>H1s#CTo1eR#W0`C73tZpm06Z8IZ;(MYvtG(z)@_3^R%kO z*3mr+C^}ivsPZUc{qyoj4GkUzHHAE!h|(1Gu{?v5He&J(M;1l^0-w=KLPo;X=f#1$ zi+Y^s>dgr9Moj31gf(tBU2h^N9bcPMrX|kV45d~Oz6VbDCX1fE`4(4q{5`SiwKo(X zHnD0_HY_XZuez&U1H{mO>ieByK<|AESpF(|A z8|i?G#EEiGvsnf!?#j!998j!Ti+dJ*ymUe_CXVjTo^p!iv{*hXzwBv+!s6dFmA zMGW;4>e3l&@yhyJH(!_b-}P|jtRxbpu`EWXlbZw@&E_wT$=YW|3DJqW?TrmVsdB>)ugcV!5AlK6OhU zN&e^H;ERPm@B~}$h}Z`;82z3qfzuiow-|!u*qK(^Vd%0?P`OIgh@HW|5N$P#S?qX8 zxpQ&-iRi|0-7eQ1O9TCag3zUc2W-}EbTRRIUeK~z5>BzzC21p)Azdi>; z$LOq}6sNkv(#R1j)i_b}=bIeWzfCPxp_U5@_dziO-qLvVQG*Vww$v$fX}#u_&05P6 z%bdn$-zL1gtu%XQ)d>911j*Uek~uRi)?yEMvmv`2?P_U}=c)|WYX@)$piwY=fy2B5 z9{c)_BVona!r1CdAe*6;-VR>F=@lyn`>vgfFrj99PeVez%slMu9aSgFY83)W^8uoZ zGgh9%uyzycu}FUtIwHzKxZ~bl4htssZN}<>n$6{&*z8_w2kt~^)U7U#q#rdBlkTwC>v0R@8#85t!F?eq0cq#~ALE5(LZ zI5iJC+uns#YVyE36F7*I9Jz+gPRQhIu(vF=lAh_r6IWDomoLOiYyDX1JWwrz136>u zIkQ7BU|u7u64Se5p2bTp8g7&8yX^>ymykxQg~}mk6&Te;WB~uC=ksr|q^y z&i@aI7?V+sHJ2VUx*Nxi&U6IGni7?na`tk)=($eA)vI{gjTf?{JVS$%_?Uk0QxE_Y zpHLs+uT`>0iS~9JD5`r!J6B!lznm-$L?~LKq32MA2XMICrNlm(eA9=GVF7sCIwk=7 zx1Xwp_6_@uJ%gtfzegVpjEpJUr0MB5ZHpgDTkg<$MCc;0pR=6K7FD6jlfK+ddRxE6 zR>T5HJVz;*y8msK(i|Th#*vUI$8xsZx$XHUGTJI&`O1{KV~6cgVyXqNymL=|`e@mZ}+ z@;n|7F^_)U_5qDoFnlfcJ((4gP4<+Af@JcZ$=EE)$)s6(V|Pa#4)6G2ykBQ|T=0tB zH6mf0&=3Co>Sg?x4*-Pdy+IZL_B-y*?A>U@<*eTO{y~7aNzcyGd1b$fZ573AI#O-4 zcImH{KO>IeB`bRE9HjA8thlDBx0O%53O6{x0XM2wsdT;S-F{Z94Co)P?+gw>loK)@ zk*;(!K&lU*74JnW6Dm+5CK6{uO>J!-vdn%=R9vQZM2_MO+MAku%J(*25*H8a1mBug z!k*|5>~Rt*`Ipk~`D_$3t0;p3kPdH<3XcqO%k4h)3hzH)Bq1A=8>$Qcq$$F)&^5km zWD}!Zzy{dujn&6N2WDfDBPIJ_f$jER+mpJsNnX;I_E>HHdcu*Q&*|R2yS*1e7w*h| zw&EyjxK_1#NYxwAytTWEg`v;6Ph*y#&C%g_dJw-9w0`;p;ie2$5Pu_kC;W%K{}FN4 zg(=7hPJ%k|cvX&n?y;o!`N={6_@7xiu!@3ri!(+%JLY0@W!D!^0?cZk*6vlSq$=N*K1Cs5y=($$Jfb^Ge8UJ^Oht;(?e_R>TSb*&mRHDJKL>DJ|hrZmRM|rGEYLx3B4jgQWNI=8k)nprL8c3v#>>;>F0^pTe5!Fnj z;&oRGn3os4CRVtR1)@~~i~={DcHj;JfeRubAH9;}9N*Rt4B;+T4q*9O{nD zBsEoM-Zo@Q>}7-%O2gd!Vh~9$BthS`_>n*e0sR@#@Ti?fH^)2lX;l8`Zm!c>k+2Ut zWu!pvwkWuO=Vg&4<~s?~LyxvtG##P#kg_VKUCF4%Yqx^aT&rK3na6k>=W@^IL7Uz~ z8TPdFO(S6YPLNd=_RRp?z)@jOu1rE5fYy}a8!pg1cp^5ildqk6V!u;i9~=M9`Py%T ze)&A|7njTTFcMMq$@aM6VzB_X}_X z1F;K)Op2?Gz~=>2fDSI0-D^4>?4;UmwRF_QfTZ#O5yYuAHzD9-Z#rMtwlUa3+}n`* zalq2cVkz=4Z#&+#tT%{HW@NgTCyhM&{~Oh1;A?DS66kw#m-1Tkd7b`OXD3iKCIoM;`;SaA^6N1>_@S_j?GE_+-Be5dSy9|(e3ATVEbo8`xZxLO90*rf)pgA zWdY8foA7n;D@GsT*X1J61YdQ&5&h3Va)o>BhD}lq(>;o@h2FEtT(W z4MYaZXIR@)R7SDy$@@i~an{&+BBZ5&UMW9XFt$0YQyz@^k}FMYHjJyW{@`)a-+;qk zuk*K&iJSP*kZpFR*2l_|VhpzGgm;Q5$G&Z;g{w3VkDxpp@3ax2^jElTp@>vaO6>hc zu2r?$+r5_HN+T5cqJyUV&;Ow-EKK zgqps&Lf`~0?x{Wn)e`G{M3oNuLn&QhP2f~88XD~LdakupFmNWk&WGyj-Wb z^4l29OF_ThS+2~}D4gsX&R_aNb%z@0Yqu(0_2$nmYXYn9$*!o%`sVv(|{qzf+ zak2>*L|1Z_rMZiL&Ukc5`^2oVrP26Ue9fg;B-YsMulFY9Y^!S;rNr)2{i5E{VYGzh z({=bcvv5=zg$V;7##dv^f1r+?REYd$$kGaombM1<0FjyhjZ zYMmybnYFYhulQbk0-BgN5~^DM*lS(vTz{f>YjzqX-_^xL(+=Z}Io&U?lwzx8*}bqS z(dki5+eILOGYq;F=TY)0LwivSPZ#5<0@BqY!7-XTY@ZBxb1--%g}W*6kAZt{fd!!` zL)!(RMOTJaWP4LhZl%Z5sYBOY7zAl7(r3*qs ze$WUa0%1Z{<+ykfLj&(SoZT;HnGX{NGTvI97OM<&PWO`_rvXjX6r`T89>+`;2V`Au zlqu5pEbK4oe#R(sT=@`txH=cW)|D#XH!39lNt6neu$*hlTX$ARM8we^wR2Gkc7^zt zGP`VReVgc-V^s06>@_H{A~ z@u8c8Q;g$}BSIKm%cWkgg*9Aj_F-z5f6YAA{dZKavbh0Wmjy$1pr>1W)PpCE8nN>W z+`LqZQd5W@H`+5s$id)PNc)~!m8aHZg0s51JH&=l9CD1{UpNJHfnZ}fP+6L9FrtIv zK$vBGME!0&4s1r~1(Ew+Kwk;AbGnVj{@9Dq$4bzcji({mZvjhUmZ6VvM-{LUhR{T5R&w-hvD#rbmpCY$Zn>(XMZx8W6 zQublwiKZ>+Fx1~WCbhnjEfobTz_3K1h@_sGRd4Wwm)4K~gaL(hC;W$2&AZz^z8IJT zw>$q>o;Wc5^~a-Nweet)thD7_Rn(*63R#+U zpAC_}WJZ}e#>U%}3>O733cu9sv~eFjQJsnF|H>|j&SW9Vam$S+y|-)BbocLQd@!J^ zf)8xLM3$V|+p3LLA^Y))K>W>im48D%ZU)>BR)5gkG85As6K6k8ihXC(D2GOe#(I_* z3TVqBDME)7RQi33sYdT{$WKdeaWLp?aT1Q-uOK2HxHmYk*OrxAb**mS;)Z*~3yq`; zgLcvba#OyM`zfTOnc^g=#6i*YeC>YsYN*kMikcgZwUYsf5Ar<^rg@hT29&#ly2qFz z0>}&dzC1`L;lVN{u%Qy@Wr6UL*_l(g9pM9tJr9hOizVV@HhSGO&Nnk_Dyla^}<=8~1ftJZZq{1cdl4@#S!A$|@; zoN2`&_gaPpgdF^T_sDUKiMm&Ks>^Ar&=4iPaPwud(_<#AwLQAmYi6EXw` zp4Wmg{&*4YtYg++=i_1NlLfvV&A{(#`vm`v$4$uu4m*rEeMul;K*7pEqJ&U8)r9bLPsw1-pY&Hl$|ew{65 z$EyD3&D*=pn}nTXx&TFmxs*W7n4n-!=IBms@@;S38V+qnH@}kAUlF>B?s_Vpvue-F z9yX!Kt+k&t-fVBz6;I1*l>1t1V%eIAVv6+S7)*Ac$OY(w6M{wDSSDOBQkkZ9m)8;b zY5PO@_=PF0nTi;zeW$bD$D}z~5~)+5aY1qazV$?qX{QOJtHMjCRXP&swbr@*RSCrP;QuBCF zFnA9dDwxtO0fcgnV9Y~<9!gWF0`r@sv1*rmiowv)ZQF6Hz&0{ipS%*$7BzdDffEfU zTjAoGvL#O3yIn*1s$xaqEu?n13}WDsZ|b)%m?;|jSvxs&)GOG>zdu|2ULURtUTZl9 zdry_1<6W#?z3`HjZTcRhihtHkJN0VjN>SUgwRIiS@AfLhKM$u&%hN!&&BA=(5X+lJ zzD~WXoABJ724?Co7zq<6v6!q)@!1Bq=M&}!*)q0s7ufTXMyM_su+^-2?#pU#Hwuq$yVYBp)u&3t|REymN-{|D+Ju_;@xfQ)844 z?cP#S=x2oqK>lXp_)WQimUE>#G-#U=U?CSM~9~`?V$}TDSYM^necCKEEoL^Y{;-+OmNbKe3$o zE>~f`m2HzSj54)aD3FmmT27R)j9rw+Q7!D}%myW6Y=F0;v)r|{`zkuZY?E|^g&5n5 z`(H+4x8@?7$Jssj5)$BWbRa-|A2 z5^Gsftg7Is#N_RUCOC|~wuIKDn&ccM+T=SKa9~l;$|zEnG`d!F$Oq5i#S}a2B;3Mb zE?$di;`X3?86gtW_nKw-vcNlRM8QJGg1De`fb~MR>f@SzwVaCvu{qpgxjt zS*6AE4+0i7$fQ(chNUTs6N>+_@Jx2vCJ(2Vb>#4+KUTdf)o2xHQE{J1_p7upAF!H# z1aL8uky+zdVytr)l5WbCnTaP`wKRsRkg1rADg=={ayRNkgR;tv^LER0)gj7uHO`H< zPPXLQmsMd_pcSn*p`It(%5PG%Mn6y?L9ODEd9jkPiT?U^F)4c^r05K*8hR}ukV$HF z9T9^_#3gFMBudE#CY9`ljswFYY^o$VT+YNHJ)5*V_A3zN-o+ki2VSyYB|bb_8ThvK zVo2i?6IhoqB%7dw4M#ThVsg@3o($5E+5i-4R}?9wN+6#E?nDf9yn7EAF(798llkv` zhV^$OLm1O7+rIYksC|cl^ZAfo+(weK$jZO(A&R#)cnqo8Ue!OA>_r_TJ7MzY*HGE1 zM=DmAzAA3Y6(8bSK&Dp@KJ?*_>qcjx^};Ud<2LJO;_M}Es`v@;GmSqv-H_yPn!=Jx zk77)$bkk5R^JXXy|P0Dd$_72}i zKnDxo+?7d6K7*w8cfVwS!f0V;mpagL92fAnE%r(52D^);Krv75c~`P!sr{ytyn@Pe z-4>tgUNQ^=1aTP2MT;BztE6O2@56n@k;YiZpa<$i;?+imYx@MUOqcCb(QP*ylE4Ap zkt4^_y?C(V&2!C8M`#FFkb2J!Npg@pOq5FzaEIn;zwkdM+sZ2Z7tFpH$ zhI@om4C{vG#I^zEK6Z7q>>|UG%wh6s+(jYU%{B>K#Qfdqw12a;mseP|W}&7pX_nmr zRJFZ2TaTaU-JjoU;4a}K_B4dX z_Q3aYCEL?IbWRUn=&>4wv^pw_OWz@xHpJ!3QljvkHH>Ci<`E5_gPgCLS9(zN9A4xq z(~mp#BJ-?vZsS@TR*Q@^QiU%uH(Qs)+RtHU;vN@GS_=@Gdhlb0@;#~t+xrlEUx*-K zn9^t1&G(q>AH(ibN9^)>92CbyH4eY%Umx21eU#fv$2I`{GyWWh5!1-}i?@_1LQZ}z zyJt=;r1=b8v|qS#O^5aH46DbUxZZ5{Su}Q~Z@H}|Q4-)EK5DZ;lc53%3`{QU+rF&* zhuE{$D$7)a(6`O%B9WBEKD9IDZRjFY+s66KJ;oKahudi50heAk`>(wa8D1y?$_6xn zjU0Dqx@SBl{@ToYWAyZ|DdNIP8p@_K&n|X`0xPuRla4$fW^R$OAuBOwT%iGrSb@>Y z2rWE=D!4_%r6LVcC(FL1Dh$!FuYL$1#ew;N{xcRrf-#(eTP z&hAihMYwI*9beo690olHr5jIDT!GP~R`xT?{Vs%JsvK=h{A55wsXQsNJDIgoKkmiyHZ;Up3%!zhzdI zC{lMD{D#;e5MXUsVy@na6{nSd)oC}8s`*VZTK}FtlRvz)Q)T-Y)llArpA*|G(W3Tn zs}0K1kDNm}&>xAEee>70cCO#Za9KNF{(BNssFu{?mM*mRGoz&V8253qmy37~jdiRppmE{z z&)y6)C(0PGyqPe-V`NQB@1CjzMG(kC`6w6Z5W!$ zl$LOpK2@ua*C?=b0vE+sw;5)|)_!cXSp1s#ISwDlFKwX$JoaZr(&A$CK4uN-z3R+K z+h@_94-AG|XBxEd9K$P_|>j~*tF>%$unchjAgnf`5 zaU2y^7Ef^Ute7q`cv5rRS7>5oxgyl^8v%}kt>_Pt_vN3F8*v5cLpE~eA2tJT-*(6# z4^BDdrb1@u{n(q+N8CypYP5ny{Z?;DjP^Mg_{yss9=GsZNDEIf#iYSb+0wb`U3#4_ ztGbu77C|mQCq7t?r&goCnkd|OD!cfbDx(cQk^-P|y3BgwjSUn?>M;FmUGCt!=SA_1QZVZe1jz$*!p3kmN9%~plY12zx zKr-F;*>xT>FpWMcnGG!0xFHctU_s<kjqaq8EuAq&_S zEKI*Ba3onj6LC4aczWZmXs{bm2cw!d`BwWDQ^f&w44)5?vqS^s#~3BkSSym3W_IXP zIe&(y1R#3UrKi~QA_CQ1?Iv^XS_D$2V#fKXk|b?2`VYQKluXZ1jIq~joL-V2s{$q1 z#Ac%yd8p8ekSx?H4i0lFDk^~7?q)~jJLWeK%<@f7V>PkmYxSU@aAiErQ!9V(dl$2q zi?HM^DUc#5dX(FivsPX%ercMvSca_O?4jTdY>TG^=evh3rlH=`FrOQJ#LH+`m_l*Z z>qU}de5?lKn2ce=cm^v}5p^(XSW@sGAL2X*N}M$B+r1-|VJv1jJsloe{jxR`C?vu2 zGaB)??UQhHNnm%cJx|r^0zQX{%yl}x0us{g`{Q3zUc|Dh70N5(HS_PSAA-G2JYAuB z6(c6b$&9-#m6wW<#rIhugSXval7RhYPneHXB-Jwcio|MqolKO4qwOR>Q+9N#w*mi^ zqDK22t`dg2Je-;Ed!vX=AIO%+LOB zf2N7m`z`m=Cy6MLB27GFueYtY*lOAO6>brQ_n9MFlzZo5T_vc|;L`4XNxt75)W(N> zl#2sv)XfG+vf8$WT57jS#}K|(YnUT1;x1C(IDTUDI8|{b+bGbIm9ipA<2m+^VlF_t zgW?Q(%O@P>AYBapG|Gr;$u7q8+<8kPqVi!(*Xt~QduGlKI0mbk{bVhi_nl;8=?~K5FlS^M37QeT>29amZe$m|c4?J4R z!GCCYKzp$_;$`4gmA=RB+SJL+Ju)F7{bwd~@UF9K^mw*MOaNq3V@2>_P|r71LSpQi z*U^X|=jU8r2cxg~v6a>7r}fM=iwV$C7Bd$K);eB{)d~uAbMj~a|MA_^LoqFO@>P#~ z?VSh1*hxr`#TQdx$f!do>5_#FBm{jXsu{}%tL8X?A^<1-oNDkyM#a+nkD7nj!)e11 z#(~G z<5o&{PFDySNUB;R?p3416uZn3=dd0WpVf;l{yMoVNBJ%-AN2xQIHp;BO3xO@QhyA_ z&77ndsi@Mq^FTHM} zH?QxQ)$!g(W<-DWeOu&GQi*{z74ns@V_iV(tM7fw8>5>nXOg3snBi)lz>pZ+6%BnU(v(MXsk?+W8bBl{ zPvxFT@lI`_iQz{)iCx8(Y?mw0$AG&qT-o_772>!s#m=;xa#PcNpehRw&mq~Pl76nZ zo<03?9*gX}!p)m1A>dYf0FBDQMK<*$CAkIrcW(cX);(=JG-=gDp1gzX6GV#RtA2zt zRQGy`z}B=H5MhJT;Vw%}NUvLxVKaY1p&yjteSXkcyN9EkS-f&QJC{lqAw9yi31u?Z z*+p#Md$M9$eH!R@bG)usQ(R)obj$oqkG07H#B2Ma)Ov}ICnKx@QAyQHYgygoZ9*Uh zj?#7CGpSQ%?IA0TL6dRrj|%rCR^pKMb#WS2s5w%IsOojGVCZxRvh&v)SAztrZ~;Vu zU+T<@>gnKJG7ln!ly*!w276vuC54s{5>Xg-0oC~b=J6VK1WyS?q?{Mxqf?&P#L*z*Lcq8A-1tsJiiT`tK;Di@Nw~ zy3(wa)tYd@Nem4Kda_Fur>mFs{Z+Cy)LThuX`|$eUIEDn9V{z7G z=%sKoF2<$NNVINDOR8FHnK;Cw}%&_vxd{r)jv96hwrxjE6 z@iBKxc7Ox!1%;N>2NgQ8BzuML@_m!yD_vwVO*6(8Y0>)8~q{Jzi>+ zv#Oh`1Hr-r(5oV4DQefsRS^O3qOK38b?-?_7{T-7-^DEOp*+vc0XN>Qb@%O1V8K}2 z*WXb+9=0?^*SoQt@ZaEL`|GFghG4mKIXxs_|4?1%#h*vp;NeaoVAZYG(1@2-)|;aP zkQIw67Rxous(NYFxtWPA-B(vFA8GI@-%6SDXu^So3bpg5xcPROozr@2rA?yVFKp6@ zHV5yHY3}%IMa_V zYV=?sA^et_?FdtQb9#oSinyZuc=w-y(3k?}@pfm;QT6E|00hvxn8dj=(1N~uA>oXz9DQrIIFWqMeJ5qHB{)%f zG6ES56aBS0*j(sQXtB`=LokMW@jDn^>q$0b*(y*CGVRj=rn0cR9CUksy}DdGGuqVx z9`@HKhKN*7!7B0lZCJ5Q_gY6p7A4FbaaxI+Eyj8QEy!%>?$EL!ZEWI%G$B%4SX}x= z=5n?K*O{4_Ka$zY00W%`+zd&Lz^jYJ3i-SoM``P5+WakDq-5SZ5CC@O#&5lUQS5oU zPsLax|5UqI)m){1^b(UHdsqNN{C12p53vw3clf41E6zwAx#J9uN=m|U1cMKE4bs>- zw#LT^kIiv3-f6}!HbXN1n2u1e>8Ul)gO=gN%vcj$6tkp;utvC7D}BOZ(*w$K=_Tye zrDKauZ_iJ3DTNouhXA*pQS!=LVvvw=x&1RfaskJUHV{M}3G@5y zF;ueWkvb{GrSb4|q<1DPp!-PZM%TAAx6ATXy8*jXsF72rHf2SlYg=a>>oEwG2^|3{ ztkO{)`q2-}jTB~2$gCNWv;^vxbBFs$GIjMzIDss5F_i1-o^)=PfZb1A z(ehIQcpLq&B!zYKhi2DHMcsN-T_%4p42i&Q1;LYqO!_ujAYzEgikkPOpdk|XrVc<3r1{Y?U53L9U|rwpJjBp>+=%-qk$zyThUa!Y|6$Rq z{ubvxz}$H=omv&J14g%I(7-6gXgoRt0xsIUao0O(r$BcR3V*tIG_J~NLp!Ykqf_vD z-l<39Rd+Vm@}_xd&A1k9&gD&P;o(v>Nz{*H*ugpdS1uqh*j1qF482XMJaTY4x+L{g z+u$$tX8f=1Ht|f1(Xspx^=miviRj{GVd_<>G}yV;F2khz&Q6t=w7_PRCfc-WvWQLET#qA;=#0Ye zSh&PUaaAI#bAy7l?KHA={4cVwqzU!*Mmf?pxR#eJB@0b|PJz}_W4QQldZ<%tdR}Vq zE(x(2b102`gE*aS1TGEQ9=>M1`lh(!zw7BfLlY+1o%`#>EO|WHb!K28N1Vbxc^;jz z-$*djDB-ucZYOzMyj6&_>KZm__ovbt>f3nI9VXLwrRnGi0S%8AET&2r{G68`(IYM@&iL%a5 z2)Q@Wc~Y+S8&bC8=YT(GIc8l|`m5zyQ0m_51+=Ph);&r1ZNzy99vrq6*@=x{5n zL06TffsH7E>%tNBOQP!_iV}N8zDJg*y$1n9FEUsNM{OfzhS5F^HHafs#3?`(?S18V z&*S8F(H1WST?NJ61MN)7SJPHO6B0^}0}Z(OnDf1Bv6<)iogSnA{sZF+$nKodfN)M4~+vMYY#+=00%hsF3*Az=#+|5w4koFRU8D z;nTpEH8M%ghv>MOg`<_?g}1k9qb-%^=Y)qpw<%b`s=9*@>CEJcJ*Kz`p#~uebk+6S z!Dsx9Mbg`3VP+uZs2ASdjIg<>ZW{5SW^42t9<|1CQBL=ZH*d$8L0I+$zds*Wub#Q7 z3C5gHrr*!+aSnrH!n~It!~7oOI#U~C!8uPz@Sy`i{8I0IqiVR=RWNlrs z&Cda1%BB(L<;dXbC-Mi?rY^BH{HDdSd2Bl71vePr>M)=L?KOsFD2Gm}q0;NTyIH&- znFdwBoPwlisEW8=ofGm{8qD>tD80|>9A8HsQ6wTVrk*Xo$Ds=4=YaKvB40bIE|*>1 zY`GL%le@DJru-N=3#mYb>A@8{g7322-3F_gU{e#}e8f5s12iWy;mF8=Rogj>lK>@-R>g#T z6;$brYnft}{!JQzwnR;6fQ^bR{nFOW*Ua66+|DrT5G=@4c7?mg!D8<6F=9s`(NKZ&Uo(kexI`D(1ScV9`0nkQ|oXxPF5(J5BO$& z*}xPO+(fQP_AKQy(K*!dfv55`FF>$ZYq>Pgf95S~|45YyQfz~{12W`m)lNhodTqAb zXy^xRYKaF~xY@L&pVA{K*?C|rK|r)lGrR0br^=ixxgWm)J;e8~KesynyANvzCLn?0<$ILH^&O07wQr0oeo105bt+0bhccf-HcFgKmI{f;EFHfuBOS zLMlRbKtVyxLCZpaz<9w-!K%P+!)3uE!{;L4BP1ZoA^{;qB3&WtA&;Qopk$&vp&Fo0 zqOqc-p?#spq5s7Qz_`O?!JNk8#Y)2l$F{*fz!Ack!qvn*!87?O^Z1bX83X`=Izn;6 zIwB^bUE**OQj$VaL{eMQZ8AQxPI63g2l5sQS_)f=B}#nC7Ro0o4XSdgFKP+uXzB+V zQ<^`tI<$*)W_0`X2K2KGI1JVdT|cw?Z~i}kX7poYGi1`s1>|Kxx>v_yWs7v$xL;aM? z9romI6oVdaU-=OVrU8wm4TTJIPwAbW3k=VrHP|n@NV!zyyBYk`-(Rh%rR$ruv@P1 zb%$3r?B>T73B*Y1DtFj7-YqsZe`CAj{KGYmzbPpp zQ0z^5~0tKJ=S#M(lqpcy%fPj>MfQl$f1P~ArgkUr8euMGxVSi9;Ow1h^#%>Ro z1Bl{|QbtZjN?vAjwHNyV#1WU&{ZwEO5kFiOg=e|a6+tp+*k}Ol8&dsGpR$o9Sik_( zV1!svGXOIbG_q#UD0Xx}SJzTHz-?+A*urZ!Z1djj8AJh?5C8``;#@TknjiG!TXC}l zjDs7#^h-b_nt2wriMD=>t(s0aJ?<=vQ`+uF!)cU%1= zrL@T8VnUAzY4Js5q`LOQ)=2@=yHzJMK@21~fDR2m$$$H*T5Zj9Qx+bt^5;{5TI!!M ze!&(NxwH*4*37>B_!Om^b?Og-1{gQalh_HF?apXl|PrOFt@+|SiNFI)f^>Ae91 z*!zYrTybb@d{)KH$!5b3#v$Ikr&mb`yo>c&v>XOlYElBDYT3C26S2{1&cNPLj9sff6l~maUl5P4<>#Se2K3A;Cf62);n%UqZ+YMgLGdP+d@< zW~ew95Qr$~@<3reVp$*0sWJXDqdu1k5L9Gt4e2v-^8B0!y!L+aP;0ZJdyZq_x{wj9 zsAz1Xa4L0X?P?T}P2YA?ah?DM5E_8a=HrAJGDD9N?xiwk{#ER_sqJ-HjSE?Ryj^fd zP@F|`IpSrOqk|xjI*)Wc^k2XWs16K>D-_3~6@;p}fr`akPD3oXxnvH0@%|<1P--#7 zDUo|abpAG(cKQ|~D9TzaWYOxR1&IuklN2X^F{O|q23Snx{{)T*arYF^=aFHN_b7`g ztzd?RcuXa^oQLgb!@+Syt^hcuU-JR9pbp_U?{;W6p7v`((JCbch=Ueo#t9ul90E=d zZ4OSVH+z0kXm11$apX{baukZk!0(?@vSI0jBTK4VD=>#fbqP9gM3H31=MQvFTRo^IA9Elh+cOX5qT zSm_vsk#?)9L?UwDo{y8#1rJB1izAXo&V}&%&6|dp5M|-IE;CRen-L|IejER5n-7St z8ey#34&G3S!SW{Y&GME?@+@zwq`=ZtNs;9pm6TZCRY@Pqdn)N?d0!<1ENvxw{9`F3 zrX@7c_y^w>2h|B_+;dou(rX{))VB(cFWJFD=K zjgRO)K2`utxTKphnv?usztY2G^iO&%PDV=}PaHm;Ns30*^Jjw;<KY7k)4Mn>Gr$2pLAzqA_?R@B{!+Zk}_-(P7-OB5H3n0Ig2DqND_z==xRLc00)^8QglX%B0dPFyD z#xm-$^7EZ&+nn<576^Roih%epa;*;gBNX^lI6WJ^85{Y{ti9= z&^hDa6MFCkJ@}3amG)(uE2%2{`}4O$f130$m};%bm8ElktA{hcFYDSLV@v@@c-ms{ z-obDJP@^;)Rt$jQFSc&gsdl?TI6#eaGC((|-M(33?)DJ<{B&^_5ya#^Bq|;}{D%mf zlbo)R*l$s`!D~Dz_V|chW;-l6jQ|=TAuX8XG_V%kvI-R7MVrLe`CVvz-L*XMqTQC4 zJX)a*+^Q)2QZDZUC6t@Gb+xGtzkiQGa zHwN(m%-0`Oc-mrMVBlmZVqj)qWZ?v|7XdMZ&B!1E3_J|mAZ#G%#Bd18W?@ib zWP!3-8Jrl^plmiIabBhr#tbN%kHLib44_rAKyft)g7Ak!PBG~7`15slH*|@+5YO$m zsC8F*qzEPRcZYdev>7Y4LWwdx0-wq8MR$_8>MuWx654?U3UtkF64)mvToBIb{7zui zI7;MM=LG31=RXA2#mU%pmYh(Y0uAZcg%5;JIAv3~C*CSOp}L%NEGef+&v!>j1^Y++ z+JD*)>3`gEc%E@YLEidqX9W^Owf_tCR7EoMb+@Fe(7gE4fmwgFQ+#=4pTEDn)ApHQ z=!&Xiem_;+Bcc~Qnc~X_PULoC4YRawaBd}kCn9FW?+WbsyVOqxI`f392?n;vNL_ej zYEdGp19!Q5OSdmn6dIDDW4#%8dhVJMoz)l4J3ZL5VD%~+y0>YYd((O2mV^5K$bTVv z>t(ld0~rR|75$zet5d(-=t#ziv+Nr8_$Mz-N7WXNsk-DmwKhHBsJ6VWdK_b0`i-|} z&Hym&uH^s#c-mrMVgQ5x%?w5i*gzhDAh!O_Xt z#nsK-!_&*#=SvVg7%&U~003KN+gojX+-IAZnweWzT3OrJ+SxleIyt+zy19FJdU^Z! z`uR@=flwrtNM&+`Ql-{tb^6s<<22}45JS6l)N!$E{2I17PZ00bZfh;j#meGGvz8}?&GBPzE8 z1u0OUJSyttUiBVPluy!d#s9|yDnr%+PdDJI6W~D+hF7dn3876mx~G$_T&rr^uln5x z|BT}}4pu5P3e*HEr8*eDNTG<1F_;U3ZA=tqpJ7vDW=sX5YRKxDB`FY!LZL8@ z!bX`TSd8YAvLOreMkita9aZ$fQ$*@8r}n?8&fXI{KJWmoXc#0=X$40A*07 z&SI0gyJXs?ugX_CC|r4aZcQPu+bcrpYg<7f7bmfQRh4#o+@zM{cG#5I0dklZ z)z<8ItFoM}%JCB=SLYwy?cof?1GGfhVUk-3A3vRct*O30o6@Q!dZh;dM6m*cJeAl!*4z~IaFs+R8AEDeJOU?u3$8JXqZrnAU^RPh+F zU;a;L|F-we${!dyOb=Y9sM9p#JJMP+Bki*!?>>9v2ey3PS!?%!*)SOVy?*)743p>5skoe=iCPWL7}q;e-a9(G+RBfkb0t=i8_N*+ z7_N0U_z$PkZB<@dmg^}j2qDKj_ZiD2E{-^a@MxAp%Lt*{=gz|MvAU+<%dmy%)1*fC9?>djP?CJbUm!@N*vrK|8L#IrzmL7}7602l}4y?RTD= z#6!3r^5Ona!>#G)S?_S5-S-FtfgimK1aUrG4ns(0(V#gV^>8f@hf-*su5ukNasBL{ zgLBnfJJ-)mbL-qOFU-SP%s=z%Z}%T+!EL+v^$fiHW#`{Ax6jd+tNxX~{?eYf=hVw& z*ze|P61T)(fBbU{mHHA0(6Y^eWse?T|L=*6X=cUCf~xpmtLO*gUB^F|M`rr)E7$la zYxyr@6;nP4W&KEj4@Z#n<^!?2U!Fz#w7-M}Qudi}#A94=>6^>8v6fIfp`dgF1SA+- zMF4VjQ4xk%u@w=Z-$gdg7Oo{tgy1r~(YkCMCt-eDf?_AkHuglXmjgUD#^7k|E?Zl6 zkZ!J=UPd7!ZlHBtFii+0{EiNC9rFul2FYaUfe(V*>Gog^dhqy^X!7cW12aOln0e=^P-ZnLl#qLQ#7r3Oe7La2?Ib8(RC|iNyUMS;^To8AQ{T z4^tCo>P4-BzB>=fh~tcCt%`h5z;b}#Yy-Zdz@325a-~Rkv>^Ddl0S?_08q|KIX^0OZw63{Y=(8w7`DXu%dD_IbvOuaQ?^`5OLLx#r+`^All1Y!=LjPHjjUZ(Dp zgb7ocC>oFviPYQ>j!@}K=0=hMsT*Cg4dezXeE8-w`qSwRN;+9?E?sYJ`43;$fw6Ih zzAS?bQSEn^qFn^dk<1!d3Wv+G4HA10Yzc_OqH+@RM8l1DK31X;b2wyuXhR zQ$_;t*sEriPL;ZwM)xrDbaUh%C|B)G(mnu_BH$_g4aF$bJ1Kz;K_)cX+JxkLknZYU z%33bcO~&7q5}?6^MU_wxdH5NXqCVeLEbGxA;Jj24@f-8^&8W-CBQPQ@0WaYb~#;VhN_MJ#uc(}5AUf}sGTxH({yT2-N)^ckVs~?s*D4EA`<36A9?my(<&%KFXS=y6E6kPfC?XXLmg{T zFtS6Eaa=Re2s!@Rii8aHK?7z=loVctoP2p+MDnl=(KHqo5~0q=XC^{7EhQ&6te~HonR+x@XP0i2l2`P<@ytx$c>rN-x34+~ zR%E~3A+Rzh&YDX55K~!?3^CSpSsjj?s?6T9AAMSvV1{=l-79 z{}z*4CT8?u_Qj2?8Cx~;R>?wiBUDjJBV#o_&s&*0oJxtnI*)zzhXeFBcTcm2l?-2< z_+mXW1WEx*q0s=AUqIt^LGqEH#yFXqWMLDgb->0#rWpeSjXfq9faDQCFvV1*fjD6q zQjk3Y2(~cIwqh58iq>J<41o3{RRMA{Q9PIdCa{>u!X%cG17nye)Pi~hpvIzfAjX(M z3d|z_Ef#H)!_bU_C+ON1@GNLwkS<3xH}pAvV^Q*jVaTi34`d0r~=9C_s+eq2XkOvlT8@xH<~90$?vd9{SMnw8qOC zZ)2VMApk67^bso@_8zpx zArSWtf~+r)b_qNT{^^)v76(T-|u$UBFvrSsBt2{0N{Ly7_xkhen+2Q4Ml ze^vrI#GK{-EgR@=LVZCfTfvJKQ^j_QDQ1I$3YLz!)GI~?ZVVUg$gF8qs)DLwt$0k4 z?(1mW_`hynk;0)a57G`Y?q%x4W#WpV(uo8^rcWpi9?|_k5CRA;b|%z6T|B*l@uL*Bc|%h3CCoWzZ^Q*TB0sB% zJOro3q>vb~wA>$umX)$Q$AWX`zCRO&GdTu&(SER{E%P_9$Th8MBq!40 z+~t)sk{fPo2}J1;@{@xoTh1q%JsN>(7A;r;qv0DPByIIGHs?#gtVqf9kR5V^C~Ud@ zOImuX_*~ekSJbb{6>_S!N95r!OQb$Rt3!5Lat_hl4iwUl74^$GmqFuTv1^egSAEy{ z%=j5~=PXV6;6VG$!;zun!Usn2iGweZxSnXggVhbjVS6_ z#0X?d+Bj(29rr)W(@e_{u#l)s;G)LrDpr<^3@QQ!8R|_AW;ma%)eXl|G%u-NC6NAd z8d*K-k)j&ZaOYd}tU)2xy8j+CNWDmlA1#;0?^Fb!=&2+ZkC0LI zDg}%AWtUFk%d~)=x$}^G|NYjM-pk!qllU5~)H)-I=Is<+XJ)2vJ|?L`J_1MX z<(e>u=3U>Hv)@LRZESS|`7 zfz@jFVsoQZewlL+ef(?kJue}or^cKYuW_JR1finE-WMo+G`v|JzmTr}C7b2q@o z5b5^)@?z4NErhiTZbbLD$LbWK+b@&_a)$}lyP_idId<$qkb|5s5cZ2luS?lVKW<%m z9_ANFkG>e4w+TtI&L+A+SGz@BihmBnBJVbST)Er|(BQ-2z<#>ockEw6B2lW31cf?+ za)W*x8D|uG`sQbw#nOs%n`YaYPTP(g@Vs!)=~VGU3vFbw;0*WXzdM^Zlx;V4LTVja z!KCd1jaucrxkKl6UDJkSZMFnsx7rkVy^hCKLQG%1OPwUyd#bE%o1aGYQOE?F{g6QUrme= zF|ud}g2WT%(49R94K5as&Q^K)h-;!*qOVM`X;2u?8!ZPH19sSScYSDth>q#MPd%upS3ky=sk`Mh z(XE5vXzB=QiF0$ebkV#h+T}984i+~<6kQ-TQNAn?5jT+0yQJ`7pzUDIf`6>U#Gs#; zdHgenRu`dES~}{Un~AV#*;zRV18GR++48X!{5$1<*HH0dg?fq5yUFN zEw8`qbr?jyrCH$h-FRw|;Fl&Pw)OH=GGaEP5aoQLF>e&2ILOKcT z(hy~gs5vhNCLwHE()|0#>C+)_De(H+unPP4xt*BsFuY`qx=Iut?s znr-m(WXL|Z1>6FXUMbW$Y&sCsi{a+{+Tjb4HoN2iBgv<%`G7t}Y)^wyF_v1@EQp&5 zOLKuZh#sVVEH6{mmJ=Xv`V|oKY8vWzJZD{W9ulS`vNhv_3XB<(vLuBtZ}h33I21`Q zCaEZt%tJx(A(A0fJW(xNs8GV;G!{Qk9<`Xu^%w0dPh}v@Ma!XXjY&{MJjf_rj%uaC zi{Fd=vSoe^@~CkwhD4Ye_Z-G|`K+`FPFMteMyt9bckuE?RuF3~wMTL#)C?FXcv~gA zF8i#Ue{YCirT520k0nxN7hb?HmN|D;b_)r|Czx&phZdH$FzD-Z8K*WDiUZMG!`faczN6~&{m7t8lrk%|--?}Qgh>V=szV>owavKfyPifC$A4d$ zx7)eisC7Sa1*rYy--;Qvol)Bd4yDfcw!I0J?efIcCSsy`7c_7WciGYGFk&V&`$C#N z7_QrU@H9+5q<+>gRtACNpx^lyU&}(m7Zij|(W=@P1%`{;Gp0}3!3Ry}nw*YloTs#= zTf$wR`m-w>Psg}P!qEsRRgx>tF(7Zb)yfVn3Q38i3Z>Fz9U%QzskIDyF`#0|20i_l zwCuIZXO+AJC%tN}T&1!U=DsaQPYZN>nm!E*3{Pj}0(Y_%uT#-s70BQybMU~VDKY(k zHUpd2CzOdL5vgs&Ytq-x8;|TS>PcM@j-M2%4NOwfdj1F*f2sRh%rKC1b#LARMUe|qO{0Ko0%pSdyaP+VLaRN$o4Rp%rxpD zV!2SihPX6ms*6cB?*^sR=_6ArTnKcCUE`6hF0KdKy5kgUDOYAU9>ybrC7PB9#pymL zLRZl25A~le+WwG)P_B$y5?Oz4d`!B#={?kK#tzON3 z`#U;z(qhxkzF52{VRlVZFPkHy@`9s*n6If)l877^(=RQ?ipF-5^4pe~iOX@LftspK zbryT`dvOY}?$yRyAp?+EsV!=MsC{9>51ymzdQ*Omh*ub2@|r=4bsGDrhCzrs*+>wX zcM17|Z|KvCWlUQ`{mfyri+1DXou6s>9j+cz~ zMa~0wKs#E%zON(HRv6zu+J1ax-We$*0~;m62R)lqoQIQzf(QRy+U-~U)a4tI9Ps>kz+<=}^&)1G!1oRR8< zn6ae@RStqfA!6G37}ru*@_EOcg-1cPQWhb4;S zw%2djKG#&Y&ZuRqOp95e*|ilq)s8s^XUHRy44>mPOP93G>yS=K#W}5uqRVifCQZAK zmER%#J)FOxmE5>Xj^pp~Q^&7-OC$%4+G*_B6J~fEE5~4U%vJrDu@EktD~S1-N+^FI`FG_?ou%=4qI#SNw?Z1{VVe1GkimR2V+hh zuiszKUo1T!nwg3a?T)|+t1bw~*_3mqTB2d8oX{%(Vc+p$yeom+9+DVaw^L`bK#m*< zXb!k=Qz=-Hv9s;iSw2Dw7FM;K#Pc2Q%qqjcq~{zKy#;xfiw&)d9nnlJqQ&#o8>7%+ zUNT7ILRhDQaN+GUw5@Z2<>|TZ^1&OeJAxC|KH8(EjMIFJJrCprKKdY)kqzSL35*Ao zVKh3lilu&5f2VKj3Y4;BGBG8Ck|LZ$LS8i0VIo}`{3QBslpK8a;bw&s&%lgBS)_9K zVj$3R=sn$j%%*#8<55~DPd6OQk(gc8@g3gcoLOnmn_Df*OH2(nrF^n!jfgylc7+vM z29y7DdzM5D&@C>85kqp=%xF2-T4E0}vqLDo#E~G@(R2|7G#6H0)SapI$P^0;l&MQo+Y*r>QQ=#QX2|-7F+A=@ zF7-U?7%>WYq+5Md!m($K#_R-z>EPT!_9P$;Zb4u)jA{^iCLG71TiNpY-X|aoB$qXC znhp(;Ezub^isg5v7^F#mto5Rt``6Mjk$zofjn*1v2E17d&1`fm~T2WN=cVm%p0W>tELR)N-Z_ZYMFtr>)NL7U5Kw^3VC{Er45QaR@SGJp>Dd%GTBy^>(?x-EAin4aRXH z9RTfn)aG!^yFAB*6eK_3dOI!H$w)>rkSa&izm5-=@CNOSD^M*ek76#FFbVn%O=v_X z2*~EFIc8#_->|KG_hIclq>~bir=S9Iy)(xX&JVIWiS^7B=|3f<4CL+n0!q)XU-_S7 zS~=XsF)e`1O@a0UX96@){B}`LM-h|rVsRhyp zGSzLSAmCMU0a}H8BKd~8W=UwXQ97!5z14mTjk+S#e z8=%Tw8Uz#}Hs=UiKQ3purP89cEV5hWv$;h0R2urWkB05;EXMM5{{s3tYipv1LD5_n zobT~Ix96w_vb{Few{B?F@XXXVue=)KTOCJ-=M3l`STEW*)+DHN1>}J_o56Vh=p$N( z7|-tWQpy2%)#WH}^2BknB#HWzlO$0hqPs!73(%qxf}B+P(A8FO&DA4yKs|_+G**mO z#WQ17@9`*>byXP$JFZIEj}fa!s^Q^rAQ-*0HY*YPZR+(T$R68%9)SQ!$Vm9MvA@1) zD0DTI_>12s{iAw%!F~uE!c?%5-NX2h8~0yUs9WdnFaPnnH1(ghOx>Z&V`w60(n6$Co3RbQ-yCf45{m4vKHYTh( z8Fu_oR)jsZABuyWQ^hA1gKkqftboT02uhC@mw)%rWc|C2VJZ5fC zv^UZVMA?C_T<&0HdifRjwGPE8KR;#H##dX6dg1tY=L1J$Ka~nJ!BF~8ag%<{tmJ&n-nfvdr9Q4Ow})U^;J}re;+F3wdjtkl^mBRK15KVB{$!9;TB}{ zMV~B_5kBwfkG9;uD{jnvB=mk=2#^0N_S;b7v%t&q@x+6uG}wFa60gx1Ssd%Jcv6BL z=9q;(kdt=+RU((C_q|w^{1%4nsVkts>cd4I5(|AF9_o*Wd%|z=D97Z+2OfHB)<|MG zV#0TEdAhl2S@J`L+;=JF*!0!)XT0}6>#X-UxY?Od{^|oR@tB5ET<&u@7FDGpuAGk^ zi#gx2PE7E67XA*)%Ck+vDVO3Lt9bv65Sza@FX-@%&hgvwf(^vW-@L79ty=VL%RLz@ zcuDvYTrX&y6E1G`4#%$lYh!s;Q$?}r{j*Qhm~$VQ75Sn$qP#!vD9X9(!eAeHJN`FW z2k599&!UA@lt&td|I03Ep<){-vJGegngA8AVr@viGa{l=K(*wA`0u}KndG&i%P*)Z z(NezZRa(fi7qtF|F!s=$e>t1muNZ`eaKmaqx!hxzuv?5O_cD~z?}pYRFNXvJlU_5| z+U<+)^W%xS(wM)dp>724K6BF8=Lc|ef)ipI_?4J>t9dwND*S&>24ap#Brg?HHGe0Q zM>oej-f*!z|Er=z;}is&b`oJSjE;q%_HG~6KOo$8J{?;UDt>EeLDjO7Zpj8d+uq)r z#=9l9?H-L{X;ZKN#%}LQ9@~LFQ|= zc3hrT7}NaWe?vyiTTuwH25W-efH2!~P(C_-!jMG^+^M`ll&5+F$SLsv_At=4L5$e4 zfr_S3Q5Y5Qs&uheVyj!4A=fwyaqA6prAHFH3;x$(1;TKCj3@5rAvG82A&`u`dMTsd z%mzvg>kMne$zxGf9*qH6ay{l}rw;AEH2xgQ)SeOha;Kgq7f80e+}W`P!%ErL?_W;)n)T!WP#UCdjFVyk||J^rnyNfX5?UYQ?nqS&yy&AzR<2 z%s{k+rJTM1k9VH$n{-<&72iVe-n}qV@tFiRC%eUSGM+`qwppZ97Wh(tkZxLZlz)7h zq%7O=5k5NpvLOO^`9C z_;Vrhasg71cnPci96B@^T?W@bLMHmqrFu5PGun>UyW z>UI46tB}E~-L_cZV&&Akn6?Up{GRZskT}mCY~a-!y+B2AFQ3)evN^Vas?<43}z@ogV#Wtv3erPGu!ixxV(CZR{gpP++9 zNkP6y-Wjme+F)XNNJO>(BbR~*N!HSRwBm3h4!AgRs!r+>%dYQ6&}$8^4%tG`Lwzq* zUXc0B`!;Sw38Mb1?3AnFe|@C^v7`;PuPRuVYbA{T0aC?aB54R{V$hf|$%lsl%R~{R zc!OAsA^_~$quR$Hs&u-qdCrVP^I$Mx_Z6ke7bT#gwB2|AeNYfec6S>+7%zhq8zbe@ zvdw|;{h~b$I70%GRVf|Sh83W7+sGZymM!RQmWVsKS;I>Ngc(J3t=oki089uXWH_9Q zAbB8z3xcpWHm@Q4x}zxKRw2>V*v(j9{ML#TzgF~$RQ(Gpr}AM1N|PjtNMo=@9RL!k zKsm@T5t!NED5s^yi|v1{dI8^wu1HP|$w%0!r%2nL9?9hH61&+jbj`Q@G3hdW|recTm_>RYB7OO9%n;Lyn!uGQqJ zC!iDOn`-XkF)GEwo=|WZ+1&$m>85n6rO9T7)9?l=Z1-*HjzOeL?w1#9+G(7J;A9#a z3kZtuB*O>sUCkmBAN}MV+o-uhGeVcnBb#sea?H!;0S1FNKVh(auzN9Ipu`64Ghx#< zm9xTYw0zQhvY}|nW727XaWd#$UgT1?JEmWft{3WuGZQ?#AX1AhI3EyDd$c_5l-eZJ z_q-ER$45V^++Fsi}7_S;Y=t*v%J- z4T@RSmxSlG&)vtvhV|S=m=6*p?k;7Pnq2hZhzP?$ajkd{4UR`)KMI3zBXqe>Soj+o z*Bfvd@{|K;7IuwEF}rS`j{H= zwba%NU;aAYxKE+*l_WNrjE@(^i#%ncYaLOci!U0!?%u4JU-oHM!U!;g$6?oL)&lc- zqYT{d7}}};Gy#FYKGQZLcxRZxcsfHce0%#nhR%Uj5hBULn68}-eVH13Z4*Es7+|J1 zA;e8eux_FV;+yAHiYLAwI{JfiLm1kgkMd8vdfaq^feT;^W+0M7u`9Nho+(SM9Z|-6 zHVbnbQ&xuvVp`}`JtzN2;ZrrbwrjTbB$syz>v*JsRC><1p2PX;;lDaS@wt-ov<@q{ zlZ*o@O!Bj6A*_IDUII(~LvDqv-j$hDfS`8Xj zd>-Fe1GO`>9C6G*%3sbaV;qfmUxo09NaAzB*XkC>EuS%b?se=cx@jwu+naW29mVTGWUv5apKR$e3L{9Nm38p<& zS#hej^*-FXoD&T&e}SNk-t3Z=E>Lr=|0eH2&WwxtEfQHhWY8yTyBKORM~D(Wy!dPI z=s7Sgq@M$OfLO@S&Cg)AGEs=!z#q7pX~>s^Jj$85d%n)18dMJ2Cz4+*m^sb{7q|n2 z_^0YiOu|SNMVW-xr-e-3pRQiCW_0by4gv8KDTFo7h)5cSmEOJ34cO&g5$Gs-W?{pj zxdW;p^(eMP#fs1*FJQdz9qDnx7!8vd@&;jTJ2X}=$R-taFv}nSSO_xLuymHc6Ico3 z7hi-BxK)+{ruHS!SPahuHL;aDXGR3r@vV}$jmp!`-4>+l(=Gx>X&iO1>5GHL+PMY* z8ABzNL1^?DIi86=` zZ@Uxh5(2RR4>JJCY7QM$AFZrT`^K)mZ;|fmM$;-?CvczkoYr9sA7xFMK(*2I=Rl$w zo&y!{k!CY6?NBXIxu!2FjfTzo01+Xh_?^9m79E|T$=cs05cJkOQ|XyQhNvuXSR4Cz z6)F31v7|Dz6+sssvs4^-bBQELF3oMV6gUgD@eRXu{Dj2(&NQ~%xFE;*`84f%B%b6l<7UJ9`cnq+3gy1~;Bn&l@e-&rA@JZW(NceL zk;1v5;8H>^nH6cpujHjAjI``gSL6pf_E4)LtD?40@@XYCEj+0tVP(q?-vS0Ac_=2G zZc=5*n+^8r9ElI)&*aa9g(^~d%LB@^Bd8_QK6@nXvPo?u3p##+n{j(u-J&M@2~CNH znh?C8Q;Y7uJy!sif+UYGonEAi{;IZsmw0i63h+q6^}Of*Ie#?-zMWU*{Akops^|gQ z@{>tHdWd(-`c`zbb? z-+5sW{%80E}x1sKoUb)&XGH(1I5xNup z8wP8#Q}58CRE|<%x%p5Uu%tALpg!H?`>O<%SHB2+*k}R4!TiZ!Rg)%H^qhivXeOBc zVJSEEb+kQN`L!jw(6%GnEb#FNb)mF<_pW$}<6|4e#uVmkR+8YUdQ!E2@|k)%hHKd@ zfoXj)g_eDH<8Fst-ZzCxSQ-_yG{t1f;k1m)fZVA#m{cw?9lRYj0OM~je%0V-l# zN(_u4;?{|mb*La$C7ueh%;OIAXi5be>S)X17SSZtNJdR?Cyn!-;>S}_J3tiPnr2(* z1O)mVv%s5Zxp|>aAr=zb-3U(bQ5D_tnB*fd4~gi5&C^`%9jiq)aY?=X4$0Y&=wXSW z*q;f;`nHA3)6w&kd)*=_n=AY9y1m-f#_h3F*yMHe07Vx5{w&}K$nwRx!iMu-vYc#w zi!apuOz)=jj^eT%ucmtFAS2bjq9WXc@q^U>DVi+E=`>T{9b9<(jZc4I5fkbf*s}DA z6^x+{+Z@c(@O?^q1L|oWX)WcFYc?Q47;tp7n6jF=5H{ny7xKfHY=LsH=A=b7ShiDv|z18 z<2&WiG{0rPYz>v)ds-$h#*QDB)<`84pAl-MXP-t9&7EDk3Ke>)|DokU1?+;atj)LX zEp)F*$`X=-p#I%OXDz`*ZLLPxY8!U!nY?DbC4Oy^%>B>8=pBCY%bUyLxLA3WqQDYlB=KSWYrv==tqdyU#;3Mlfo&yrU8uLMr6?+7+4uE&7K6EE=k3$IQa zArn4eFt5v{0QRYU#p>t2s@M|w8Cdq`9I~FmK7HsYPj=O*_rH@1{QSE|5l$q@V!LaP zJloyU9C`7v^KyGWZU1~{Sz62pf#Q>&Bbj^szY4{`^B&3Szn-i@60NWGq}T$5>RG=u{l;i?@+wcu-v7`r@{m+9NA5 z^V{=bEO{)VB1QP7nZevX9AuX-^TG&tBhGh%n`rBc3F4(xSpvGv@ z=vDcIj|di=VuXJrEhBi&R@L7-Y#TMEmJ5VgVDJCPs%n z`qFF~VhE-SK$d?b{jma@)f>RYlZ?jIpU8*ec1E!GuYw2fm_-4E2sB#|IVB#%GGleaSK>}^v1O0?6Kq@V1dcV2#*52%6jP( zOr>=c2gm=$2J103Yg8MOuibpk&8rdqyZEq=pBGl(O%JyBKeHX$P$#*uVF0k6e=dvW z<(S$_LC1s1POP%b+L3G#BCH5xKZ9uv^qD<~hsuQ{dUc#ZG=7g!t2Gt#)o+0!nRo)r zm*WW&kGZ;{Yq9sXCugiQLR;t8)~-x*A~U@gKbRVg5Uc%O>2h%GUT zb+v8?QixI*+lH)XL+q-db?f9EiX~LDZaBC2_Td`a7uV))5@CHSCGARy=)0^Dv{py= zs!@yDut62#u}7Qn*^E#B-KLG1G~qkZH-{ojvv@xmR%!cN!L=uUJofjfUDBix2sIm* zw61ag4w$ylqoCde05#P_TiXKOve%wF;?>R;KDxJ4bWGUnIxGC>iQ?CbUgu*U_nPe@ z+YB-_vAv>=b^p1%yNX@~_kTCAO+7feTHB!Z<#FPeBR7mG>qfs+bk1Db#^wkSlFcHR zoxdC8S>!gwl{we9P=&8T!Q8Ap&$Xpmq`LfGJDgc_4c6*0i%?Ln()l^o6>#tv zTlvpOVU`Jh(2BG!EmA5MH{#9kh6kf+3q0PDQvS~Wi;kJO*Una}(|_+>^4v6h9<6PP zSGh|UT|85j7}~kBTe?@%ZVeUJ{=-rwW46jnMB1%XQs^r+>?hT&D^#gwKMzNVvI?K4 zV_+9LgjJZXaWotFws&#m;Vc5!#I;2S6IyX4 zKb0^kWpLET`g+>05Ni^DRcG1OcU35eue2=j3`8J8iamWfeV7%wU-OHKT)6(zOGNp- zGY&(vv^Otpi(h+I!_OmA&U&DYQT-k9bee-h=GO{k{iDBP~5=PB6%IYM0?<`^1AtPkyZ4v zj9=Q>kcB^3f#qzFk*S9TB*}wgEKi3(FhO(^$uT~i z+<#7_+d_;P1|FNA?BB!ID~lG_88@xX{pkk>q5gi)f2$}>Yd3?R#(AlAU#nlhrjIDXM z?_=ubu#`9Ai>Jy+Ue^(D8vzU*c%6UKizh7wc2$Xn-b|s2{pT76Mo;o!_XY_Q%vA>$ zGx8f{#J>wv)RC6ZxQ1y8-DzJB8hHy@XG4Tx2bBq6jD??w3uqyl*W#Oc2B0CmB{-7W9u@zMY{z2?lVbSKho@J7kO#e$sU1H(B zC%I?|e ze>;DP>x|}bMdJsGULrXDFlY0om?-{XglwVYI$~=haf2v?NLBf=_@zS$Nl@v6I;5fx z#ND_4W{i!u96*Fc_mEd)+>Z?#?S=LplKoDCpXOuZt=L1taJoHIyl_P}?VWuE+P@vr06>)LcYN_v@W z6(UhM)|$J>F(qZ%dy_HuU;F*tmLA*rO~4v6Di0lKv-#?)*7=krNe9G(4LxoA62)r18!E{aGE zsI!C4(azV`-Q>7vcW0Y5k(VX$9WP^R(&-Bi%kkh6Mu@I@)YqUod~RO7xE&xL{F+K4 z6v?NU*-bMWcXMlOO~!y+dPOpK70a#83$i)C%S5RQXYC7f#qa+RSdH+n;-eO1OSLVt zZZ${dgcBIQxBV!FUH`CMW@hyHv$py$rI3I`EEP8yB@AD9<7Nb4Ec4TfDLODh79=o&!F8}&uRiUawFnO<+>>-+oo!ZQLP7VZ`{@?_qt?Bc}lmD4nK=&HMW z1qO@IaaBE>17P00^X?p{hHV;T3ndqEm?tm7?(c~Ob&n6OeL$I(x7~m8t$V}4=8NcH-KEVd~pqfAH3H}#sRqUJ8n-^KDB%9rvBt>J_8RysxIi2B_D?P&c_NKhgS{Cij!5E?Cc`X&M#gD zNWr6pkHN0}_pEfQcEp8e1&d~!uQ5?~u#L5kavSO!b3}9oQ!TnhNr5h{ew}ekYgBM( z6UG;EEn<{ikkj`N>FC1J$rpm8!Lc-;FJm`D{k1Gz-H3!H`oq%bEhEvGOMT z%sr7{ZdrljjUS<*RF}-(+a*n~Nn2eRP^s#%R=H;D<8PMFnD1o88b?|x$@1_Cp^%EA z&!2*f2(A#yd=`5TXH9dTj`Oy@wI?_B?MkEU>0d_rfnc++I32Ccq0;^38~}+U zoz)k^*P!McIYc)_z>E&3l_WsHK_RTo$MUoyD3GONPO@l8Hu&8%h4-c7rPLHTqxhe>K2AIXkvsKIWm;_ZYC0 zIUYnWF!y&{PxDL_V?So-MuwrPtJgB*Vd^@RPmWyAE$uX1@w#@xf6qfEsiV_uPyua)L~!uq(!9R zqEXsjMcIDTpirW7Of8`(28r@GOJ1SLgYxrZz`f1s<*JW+c<;h?QsjaHksz081*$ye z>08RsN`@RmREzE|o{m#>JGv{#+Kg?6W2&5PE|>%C37|8#KA?mr+z2@wf@?}UO-s8g zhICC}T+#*`0tgcOkl|v0apT1>u?H_k1U!8)$`tfsomR;p;u2wG{( ztZ^fT44c5Q>yw++JX|R*SFo3E?Bs+DSnVKJcuaGH1G10G{JO4dK0PNP{;6(7SSIU* zx(6HmwI2Q0UT#)>1vBTj>Cz}C#IlaIdn_}u)*@Dp>WQn`xFJnJw3G5DufUOarQGSYi>>=D|0!q$U(83G+ZEuW&R4jdJ6jeS;omLSM2vx{*us4mFeeV&0o$! zj%ISEY76rpQX{u4!@~MYp>Nl-7z{7-F`hO;F6N}zk*IQtZtBOC@$#G|J(iCyov5u? zC?oaTuXdK{90%p}g5w?sb4p0k`KtrUNv-=SXbzd$c3PbVW15XQ4C23i0}kYmQxTq% z-ss?MPLC-qM_5jwmn{9V=$^2~FKH;+xPq`m9Oammg(+UGuXJ+EbE};c)-4nI`@c}L zhz7?9rr+enjXc(^xI5z0Nn^0&6qHodG_)+NY;xG;%Hxo)fKy=|{qObgDpIUOsWRm% zRH{-fBrGB-rcPYF2926DOGrvd%gAccs!h8NofcUf7$5)zJb(c{z<~e=fe46!1W17l z5FtZ_4ih%=D58ui>S&^MRdmtE5H7};VvZ%&*pd@_a+4QF^0z0)h|A@7@uIPOd5`Hq zc*~1;nH-qt!5U(DZ+{QmR&b(t=^ASL<=M4*WZB9UNFqm&#Af%4{pGv|c?4+hXviDF z)4YeQRQLnE0`!t|g>;b<*U!a=kIc@cF*eqNEem9$O$h|y6&s!@{>lfY@HHLJmDuXw zk(+n18JUR54re4dCi_US=<@oKfuSDEN8m=!BR6LD+~{+WD^`4F*zI-Svd3Er)qjUh zruv&?)=hdHw#v3!DrL0I>SFo#m+_oB!nywmO`PF zLZD2c>y(yZ-p+KLPUVEK7CLR;GL&{c`t|KXX*)xiepA{~rqcmBWfJ-QKj%tL0->|~ z-uL(WqR98$d(S=RInVw)=ed%YBuQ@R-I6TLuHV$&HU1Cxep!-MHR0;)j(u|nZuolQ zcAVcKNzA$9n!~2-sC{0NW;Wygg}V=2wr_j>^o^3V`a>ARdD+~d1Gw&$q)SUU8kb#p z-R{1BefjrjzamLvKiRWuZs(5d$d4px{6$(@p)iNYaXzasS`;%^f|!^6ro0{282^`{(xU+A(?4`v4E-Q|>u%)uF>b zmESxiNtZ0g^H&`>xa+{KuW`UX{UG`um$=l0<1;*j)#{Q|@D+U7f-lwek)2&#Jaqck zU2GnG_TyQJKP>sAv}ByD4`>qaY7K-VT-UT@CW}u`cW<#E7rP?iNI0l#x|YJ#EH3^* zy>10-p2V$jAyC9+s7C zM&@-5GWQ2O9_=^hyU4$!F-3k)Zy)0tmwCR8GwrswUn1BB7l!1mfNhU-2(TTvJV_Xe zBn4iIy#x?7dkf2WPqo=w1c+VX5YVORdazJ<+l2_-)KgelsBosOrOq0bZfdM2mBb*y zLT~TS{546#uPW=;Ct}*Ri-Ms82heykotEuUe{E6^DC(+JW{c_xqN5%_$0;>tUUX3~ z$bN>#yWW+k+%x>>xsuLU*UD9lWml~Xel6+LcdUnyIyTW(b&xOt>z z*zMs5Kd1*5Ph@+2oeLeAY_%#ktzqbdbD7C^b2bhR>|A(;z06;g#-)wYR>}Uz)=g6@ zJDf78oDrA=!U{b=S|~((76EdA3@}}eZge`?pf;nAH>*2}iI!TdqH zH|J24%eZE1_j2~hA(zjL2i)aP2YcJ=B}oMzJtIF24A`YQsY4o;)=Qq{&efyKdNTD9 zkHOTgRu)Vp!Ae~~gB}Wov65a|NhX!lv{1le4QY|HBwb5eods@4Fq45y1qtFw_URK3 zf0BFElP@WukWEh}bz3N;wEJs-fd=+r!>^ z=IluLmJj<99sbS^P`-WPS2E+@2IZ%vU7-Bjw)GRu5-86s34wrsgppz|tt=8I+G8z{ zd$ImVNGyz04la{MB7M|5#Cxd)28bjD)k9&Dv7T;pkTY3avYzi{+g4rfZn(~$YHYLZ zZqvBIIIZj-0+{(ZWwj_g3k7X17nhQ!p$+N8q`UdX9%N~P9*_@7PyQrD5Y;j#m|3zwOn|`#OJntIlk)>OS)I!P)XRKJLc&g9{qFs4~8bSx`f} z3A5qhRoeNyM7dG9F;yKtRqv3w>xLU#{1tA9!C$>iXIxRZ>iZb$XMOkkWF6y=vNU@M zy zu9+Vu!!_AxuqN$u)TL|KL3X$%UFYznbJ2|9%K9{ZzI%-8vWq_zsILpE>@W+2lP;F2 zYj8EPw5y>m!(7Q`T-F*~Jnpi+LkHccclDDQ9$dIfj`F=y66>qgvA*8!-UP8b$werX zuykOmx}YAiH-ib*$c=`$gR@3x`TOqUj{3Nr-*;c)&8YVS_iFLDcJBu){aig`PRup6 z@Db@H={{K83Wrq~;O*A-yc~Ad`D`VVoYLd0llkCHXeV66w^#v@$kI?yP}z(#svN#J zuKRp?{l$mX=szWO&J<@f=2U=7!on217J|%+F*J$BfD2Gz9|7c#Wkr#PyL~ce#QgUu z@@=vV7egK%*5Ke-d`Pw?fDvpoLd9C2qdRx|BT)5QIT=r;mcO7l-;DY+S(87gz}~5{ z_te#jpX`6@!mrqy{9973)C2q99CMQWXI*ib*siLax-Df?j6hin2?FDRvxEvO66ZmU zGh=AFr{2z#RPUX4^rjS6lZZ?o4yKxe4md;H9Sqdg1cDGuI8NV65ANK((%Y$CH+K2u zW7nyj-YeeM)tEb2myb-CyCY-91;fEWAUJ%1F&5dC+(N5fBQf?P=-Cuj9V6*T2lWJu zYfrJa(9@j)@?kMa(1oyrqkO(XnEfbLe$;Ez1KW7rP}t8SYIsMN$EN5xjc<;%HaK*5 z*zYrb_dAC_oB)q0oo>czwet7N-}hq9943AhbM|A-c0cB1-4z4~;|-~@m{+($0xt!! zZln_|O+)G@3kdOHn~JS=ZMasot6@VixneB4rz1bSuA_FiMY-y>x)H5GtGJh6c`{%y zz380R`2|5EcIhg>(^4$nV!Lnx@jV`hDWwT&TdY0}}0MVVvmf!+JI zI}hJ<_{z;;=3$Dec*duT*_upyi>4^hWA$ksYciR$#g$2Gs(tN+7w#BTn{K%JNS{ZM zw0;su%HG@&>{7L`wE>&JGd_mxP%(0I7uL~g>NVeKX3^o zcXe54hTgzxvOQT%*CSjDHAcA_P_j+rsUJC_5<*{aXm&+*dIR=RL(>%&Z45on2G+PI zzm^IVd*RIsm%X=0=uBr+_Gt%1R+Vjf$ETkQ1U~cNCq58mz-k&;eHD=Q0jmufuo}o@ zeL$vp7PSF%LEx8gOCVRZ8w91|>VQl3g%!gGgbC>IXXg&Cg|*sCd-_jrAI+L!&8B%r z^8HEOk?3i#d0Es5vYkO#4Arm3>hOoJ7*k}{(|_c(;j~*WCOzr=;JVG>h9y2|7+#_O z-$@y8fN`?3$xafjCi9%2fk)9rP6vR4-=&AnVPH)b>}~m(=qkiIGInWKP&0q7ga%`} zqS_i#OU86Pxq5BBG3K$?B-Urukkb*38t#769aOY%@1CRU$D9A%$9e1`jj8_CdmXmE zw#>}>$y~C&ImP~hsjl^%BaO?MH?n7WN1Mg7uY+eFky?S>TA|YxV})Wb0JZ2Z;0L{{ zA_ny&gI9jwY>F{`_l%z%i;wB15F>Cwhkbj?(;zCBZC^1$X@@uAbKLQVok1ofXNV{d zD;!W`wQl=Am;c|aAKsiLJKvJxQeIjPZ?4$hoD6dEm@l4R{nAS}H*wB9D<_*9xT>Y|{Vk@uP~MVXwlWk5 zH-}cnVx|l9Uep0?ScP%2uieJL1Bf`g0zxxc=&Wi=g1EOA;L~L&H8`Hdo}y|2Pu{C= zw{h#xz^-Q^%2i_*k9BzbnwoORimEr}1{;D{jnX{PmP&Tp4aV$D_C=OBb(bp@a&|NB zIIVnkqBaW_*fwZEFerzriTJXSiM3Q zODXp#5xe|-zueuUh8>F6TmF5L+x=Qw#-rK3r#K#81t)V{VA%GAd+ig9}_ z8%WVCc@rWsA+S<_Fa^sD$Kx-c*H>FXw$65%)dp-)uD^qRp*mu%j)rlaUq_&Ua(l=be`Ok+9D zZGpyEafzL==V7IZL*54t$-|DQWJlBrR{+9D(8IwcfC9{*5i^KDySFHy2hr())!q;Qoe6tC0rrB3e2kN|5rbsf!d%spQG7&Vfi)j_5X6-kfhpj$ zF71CZ$l`b3<9*;}V{&|AW8G1|vWOfWD?jok$dHv_zB3n zcA~}$T%^f44R;Z>&bX)N`Y=f?2|3CnQ-XXXA(ft~5DTfV`3;B4z$%mk{fEB~7@#Ek zE8)jzex^EY+S0YFYoq#Y@2&ba@4fAMnQ4B_too_^Mi7)dnff?PGsC}6(OGQ``86ji zP&-zYicBIYNMT7c4+OaRyL6Ab;u1w71?`aiZS> zT!o)L2wm9;Xxb_2D0)eufR{9_!cA3X>g|G?+Rn)#C;-JiAqUC9#~!+R*3H06P8dtY zo1R#*Z~KmY9WkCxBZn;4ZoN`gWUgLu&56&koe$*=m3fmsFqEg!yz$i=jqU=|^6j#U zbZ+^#Nac1`Df<*SinzSa%AZ(%9LN3*7omf}jR+{a zMPj?!DF3XAHGaQEEbT`8t9r_(@2Iwp-FfG+3g!qZglWg3X{u3NDm(nW5hONrrfP_VEs1#&v-V=v+DeQm6b4V~ zNLdPsR=CcxGoc8j>Hq*Jj{9y|*IAf9>0i>P8IJGqc4T9*ThK!M$6H&-7iIS**EBJQ zM;YixC|q1SSr=mtIpWnhx3Nrn{-SMFUL?)ORj+aToqv*Cm1Ty^+%~51;^gXBtbDgx zg*Oa%DdXj{2?>WYbRIZ;KH%q9L5~g8R=@fc0guH1wYObs_fixIylEk!ZXp<2`PK42 zGhUfPz6NuQVUEPPR3%@s%L*#0?01IYkO4uuVUhoUwrn!A$Oqs+d18&rr`vX};uDv8 z4X`L zP}Vr5RV<&@!fxBoRD*131#~QAa;V1UG4yK>Fx)sBa4rX3Wz!XeORrT0sRFm6J8h@` zl?ThG&j1ShF|_b2{$s@R0eB3?Nizfk2p`x>+8pZK($EP4FHNe*+9jySg-Fc|u^g|_ zv=9EJN3nI4U%Bnikra5-cmL>Sr`;3EHTN`+`?CsT7qGb?`{-Q_JrnugAKcehdTMf6 z>qXnUC+cF!`X&3+w6j~-GKt>;tVOK-wAz5RlLhiuO+__u2YOhhl`lF0gsYEyGI`>$ z+DkT9WuIN#u%vZh=>^foctB8_y{a1<$xy1 zV@mtZV8Zkf+glEZ5ZP|ZkLnaTRxo2B24EHnnI4MFdyzyabalm*NF+=K*TNIqxF%Sq zPs;wWQB`*sPA#J7SwkT0mGn(>xwz^a9>hk{64__7)w?pf%_bXA?qMw$vT#_w;|tqr z1L|%?gH*#=um_Ds#(~mPS8pA-bt1iT$|27%Mf2!PW`^QX>v>1tkt-_Ly$9IskOr{6 zzG7S@N}rSP5Yny3WsB^B3$f0#kS!np-Ni(TLMQS~cQv+aYgSII(eswp_g<0C9%?r~qSxa_|w4J`(RhDev5-G8MwKBW5Ks*P2I^AJ$r_f!|KF^Hy&w9ZCx9%ZmEWSU^2D) z0-w_CSKSVezyDIzy}Ns9uon8+GOzB&_+%l(>UjA2l~*0oTsb&4)*aiD0J5qQcFkck zO2QARv9kS%#as`V3b3ZmXad*G)mOBE2s;RcC2V5FG{F@h zH3gLRfDg#tllfuB(xHQXSVYi0S1?qSe6U3MjjUEN_Fm(c|DyDF%tU_svf))Z>F_{k z?F}#6zxU<(D}k37yxFe;4$8yURdzwhA)-&D2xi5HAP5CH1d=u~k$1`|Jw+wrl-F&s zD|~J}b4JvBo9usyJ8C~1b?}#jbq=dP{#~0h!fJlZLll_=_0z|Az%a1UdW{|=TZBpi znLLcum|JAN85}WA^HeaO<=G6a`pgxP^s+D#K~RO*X%RvI?2m-17vz@$Y;vpa2x^0) z4yU1XP3X)u(xEv+^3r}S=-{6T%7vsHaw;8bWn;2QLC>Yj98Q~3n9w3KUez8^GW=n? zS1dlc2}3)wwM2huU`UeOFsN!OMy^DFXYJKp5XH$Lt*)_Ed+CwSCm zYx1tvRmbfflWkys@kMA7t$Ve)FAnK53i>CoC>0f}=2*V-v z{wm%Uq|Bnr5NG$7Plw#Fu`qbQc||o)bHLdbFWAZgHHJ%8f{31=7vA{2b%+1;U-6Z4 zZ8ApQ9`hJ-z|`c|Zn$1yU>1szAPICin9`Iteg_!WV;6D=yFc}S5vfcot7pNLO8G3w ztBM1Bn7zu(B{rYW$TT!$44=<-$+YEVVJ}jpZ7KEC)7FvvC;9W1A6$bubj(qQImA9! z0E$Hjx#jwhPQewFC6Icli7LmfK?CZ{#g)ktN|b*srDLsr?bHS2=vdRp{n!R$(q3N6 zz6?x@{W*m&4dqGJOfUhh0=NeCv8@zTje@%^!SetaQsI^IlU5SO) z+4Jnju*1t>hX;Ey0m{r+dp{|S7GLZpzrTuY!Z*_EJt9*kw(WZhdT~%FCaY$H4ac&Z zmpNoR1P0L_U%&mS0O&Ee0IpejZJnLIb$p_ zbGz-M9}ym-5%l}a+_vG?rS7oyV6Z-t;I^fPy~8iVhbS(*!5zSC3>FNvM)fW$`=5mZ z0D48lY^g)UE?7V)m=24KH7qrf)ogfK5yds_Z6ZWyYZW%bHn{1t<*znm2SZ+0V8G1T zTcc-33tr>e>$Rre{L7Js=7x1yQMmRF)1bD4NkdyPlcQcZ>4r8hp%SJ$W? zJwj&mtms6KHDz9p)Sw1oEIK>{*y0Osuou}2h;>^*v6jX-<+y>bDtFOd7^LAXID)rt z0TwF6f9Pv9J`+`s9jo=%wQiiyRNx1W&eVnPdJh{_Gx_?OsQvgae(qtBr!v?MX&iP3 zdysUn%bR3XPhWSkt1S>7K-nIHR*~4dknf;ft`3LLE@FR`)N--1@j@z(?7Bb;{QIi% zsi;CQSr+?s_1qhDX!Un9L-QytDOB6222#*1ZP;dwr|dqTJyB0iNLvohr>%+odC1Rm z{k8j1je)w0&Muf4qrO2K8npDr=RaR@jK1(!Z~`RXLKhFS?@LQX-HrW`EvttIa!l;g z03a|n5C*t3(jZx(w4tf2eJxz4TO#2m6j@P}O5jge?0>?I3kBt~>XR@67$EhX>7uiH zDK-=|joV~a z)|`F%){SZn%YDw&qS)APOlUe%^0v(KnbuUqsWiLDH*4?kM}|jr9#5{$F2$x=eJWw( zYFmp-vTcQ8`P=b?t=1QHI-~F)tZITD(CZZVn(|XE)jC#vW z)o{&9TKKg)!Pj}@gT8}3y{Oa%zHW}Y#a>2S4TggP5aJ;+t#D;ffN5#dNO&>0KFRGI z5fX>V+!w?ix5Hx?G1nwqS*RrdQ)M3h2zVXLqQYydw>j;0r;4CLX61jYB(KVcE6_=N z;jx8+^fF)yi2dfgDRS-s%eD#R2#i4!$U@!_6;^FOg2Yhpj7v?mS+j3RoN@JZZ%Gw3I&b+zx_So6OK05Rs<8bzHYnS)OC57 zBYzG1BeCCtzLb%AOZEl&y9yi7se@sKAfgTqJ_`vUwCovzF9Y7vje@*ON1QHwNv~#? zA6P$aa8!KNIucPgUp}No0E1s`OjeRClz#fm7y5?`P(gL+%Khw$qYhc~sm#H)ZdSwE zz|tye0c#QT{w84kWBI@0+sRkWF`kqE17FMSknahs+b4G0!Pk+8U>koXq zvh)Z3Ol?R;<7b56Z5P;|dL6XUTuT~ONG$uF@G+wO0CW_IWIL zYTTV8?Zr?7q!r%8I|wj4SpgtY?`Uxb>X-a68HVJV*hSG`ksPScpnXu)@*&8xvDAIG zJ1-O77Y$R9`G0r$RlYXc(;wybP&&5EV|RK(sFU_O9j{z_y}@c;eC4&qY%b*Pj887@ z^@Kv6UO3zER))BP{XjB>j>sfx4A?$3nLWd}Rnif!qjW*&ayhA^j@EKpGHi53SCwvR zIM=3zG~3cON?=vC1M62u`?RUIC9&!SGCj@phJsm8SLlu^}pwDv4{Gen%C86 zQ+n-+wFFgqVTk=ZxGw`L87Fhu8p<J|1B!@So8{5RtA1Uo~P0$xI-E3 zwEK)sOJ{*b@D!kAjpA6odH1h32ZQbTjLTCWdgX^c)^2mcBPU;>{J+ZIt7_Sum+84c z2V3TR-$b^#^*esAi}(oA#&!b6Mo5TByE_PMD?A?RrD8!67;>lZ{|q*ZYPeZAb$VcV zhB;-;ZnGEHKx1JtVTmi8QeS6pXhUXvx5nfp&Fa1@&XRNTSMCOPkdM$p9E_b0c#jZ8 zD=HxSbGDNw5E7vTPlcmNcM_=K7lt$PX0>xP)4X-*aI1lM4Bno*p|>?2OXzEQS044hYQV_5n z;cEq~ox(mMoGT)7A;Tkp07sqU!vL%TZjlh8SdAdY!g_i}qCxJj^&_a`Elp&8I{Oe# z8GX?5PERIoR}ACRqeG$Eh`+nLVu8B4EGK5qyX(D98MTi*-Jq#l;px7f zhId~LIJ@C5pF-sU#l~LJca+d2juK(zS+D{u;`?Q^&s1H2Wir{vq9JA!cPtx6y$Ha} zw+Vfv7%d^a8@VKqn0SvYC&eB9T90jjx3mYp_&{Z&;V-{rb8>gT{q8%f9xE&-EE92C z6n}mM_-I!yN&Yh~;`{`l9oZ&C5}zrlhk<$O+6w94#giC2F(R>(cmO zLxUrt3@uY44wthrUCU1BF4{W{PE4#^nYw+C6KNo-Dz<%VZo9|`g_@cVU9*+op0Sow|QuWhlIQGSKJ|Cka&YDd7&eg^oL1AdnUKZysl8VC%s6U>=xmUfhA z739Xk6&d2$YW@c-+!cv)xVl&Xd(@}g+tjp?+gx^6rrof4(m5n<>@GcH=yv$h9>zAT zW2+}Q>aRN*VlM7zj;><5y_Y@faH{%atg~yk>~?9g99%Lc%Pw!oG33xubt;4Y%ATE! zU3iHiYaR`T-%~Vq!U-lS)GrhSS5UshUR?z#9Q>yhz+hD37R$x1xaFk8LzJ!*p8|V2 zuy!*GuIundSE_c89?xV$Hizxvi+yrSiyCrxTaoQiiY^&A&j9CsWSWGrcyj8%X;t9Xxxz!HlZ z%JTY{^HZ*f=8MUwsL_%CWmpKIz0gTu$qKgE*EF`Q%k6GR*SRAQW~v}p z6m4l+O*m3#U1HOQR$M0=b-@-pJQ>9Zwv8ILaInQ@kOkYuH?eQQ&kc!~G8@HvA0jqD zT!hkH#6Fe88nj4cQIf^_K|D$v9#XqH!wPeFJDa^aUWee?x3Ov2(XOFVTviO-*WBTC z!liY2m{*Mis5()zDIJO@7Y+j+IF5m^X6T3+)F9w_j7Qm*gl||6iy8}6;ju!>s%7Zu z4pWka+=@cim;KYSOX-R=Z7`DE4NZ^Mn+@^0M2g?o&)k9BkOzO;9H|bsCsN}9o_~Oh z(zBRBR7F!>3_HdJh>~DM=mTLAQKdRIiUQP6$}Cw2oH{q4$Qr3am%{IW7pUs~qg*Dc z-L{oK<1S6=^&{VCy z0Xa2LiaqnT*dq~hFvTAVq)?LP4V^8pV;b~&0Ut|K|xtv8h@FKE;NVgXI zIcir5c$G=y10ngl81E@^zDL$wT-I%NyWIxa;}feGY7B1%J^8KJKVhVA*YFNhkALV) z)jjM5s_rWxDCT3|rAoo4_H9MF6~%jB;U7}u3s85Da-NnJtL}b^H?bdp!)Ui%)D|&h z&#H=!q?h(#M3x3p#lFzGAv?J?y&)ThV)6#oOa{CR_VwZPM8x5UtjOAIsF%Y#AgHLd z5y!3Mo26fgXc@F6JrRf_rW4#IptS7$b6iKgG@O0BT;snI+X-CrsyzsS$(v9W4GC?( z&8z7iEgVuk8f-V0{uQ$K%m13}z42d@y$g9GDhesPrk(gdsN?vLYJC=Z(%AsgTQ1 zw2>7+Hpi=VZ@EA;qYA4qYL((xceJ`Ex420NB@bnG_AVjqfwP;eTsdAB&DU&d$&lww z6-xYLmc&zGlpAS@@^8z(tvcNt`@xbtjkP9_RWVLxlU}P_dVF~VbDw)(;G*oV3 zm!~N86eDn6gM}_i{$$y^)Rp~VhX=K5VeWT2nu}vAH?7;Wa;(_waH3W-;@PIH-KIWt zg7t5SioH19r=I?Z3%&}20p?fnn)kX(-$o%0yX{G&BxI^dkZZBmtHTp(M@3*d>Otia z<=?ys(}ypr6Hvl-COQvSDn~8#NzQ?#sfO4U>_GX0<@?zFLzhlnVR*N8H~1nKDatDr znoz`bjn!hC+0pWyq8FjF@u5Qjj(h9T)qebG$xbo(K^y2F`_C&R4PE%KI;^@OsH*OE@O?VHql|1A|7+|g z$6*mR17oXubEa3kCz#A&@1ueda*57tGb5LysTIediZ}wA(q=N5PTV`Yo-dJx&nOfH zKNR}T^5?=XuM-<|v=hbZSWMti6zY|0%is0{mzKdRnMEOtn>6H1yunkqjh){_! z%Repuy?E6b{0UL9*$gd{saU4QH0t^oHeV2Cq#6nRsJYf`ZE1h`W!l;HYv^IU2c6DP zeNk0no`S@fpvq#6n2;DNmKH?u`4VS#)=6e~rUI*#a679&ts*p9`5Wb@s~o_BEKvSU z`IV~lSo?ZZfk_c-ir$DxWB=|gh!gHLVs?StvphqhK`KoaR@2!CTT$ykd{#xz-<6+> z$^6>G?wc+`u96_#UPZFzbCy5wWg|F#qg4Qz5a8%_Hcfs1o!oopZrRpYcShuaO8GgP z#}V5Ey)pz5tHnE66dknDn{w5+h%Fy6BK&5-7X%fV2Phii;tG?1MM%03kK>lOGwpF? zJ7?Ur-W4golgs|5P+Q}!fvm$b7sZRBp;{l@m8vF!lrvkOY%jgk7EK?j{3vGUURq8iqYyz6EjF}(jc#@!?`$X3 z<2?kOf47eJ4_=3tDd60JD>^$6hbc%Wf47b;!F4+fD2S=}n^S=>_KC`_HF_=&ul1y0 zX1o{8YD?bGrNhhdHdqF{E8eimHsSKTQMY}FE;lv#%gE;I-jTs&sWkRmzP>rY%inXg z=WXMlAa;`RuH(aae?dDjB&t{|;RR7ie9l>^P(`2>sD|ZKs0>v_{>0gt3K8yEVH5wK zkyKq2?|d_+)!lE$zD{+eo^K$4Wtwb6nbXtR?@Zx+5~jLyJ{*u20G=qxuMK#h-F0WX z!Vh}t6E^0KtX`J9 z3%Tx++R4r4m_x)`C{N`t!!B&Vx-)KYF7|b42b4ZUWZHtXG!*cGLM*XlXsiU>C(GH< zP|+?}+j_uyL?o7I-C$~V_snLSy*1-O%H-kk4fO%OIh4dT5amKo~^ZJi1RzTXkQ zd~|TIW!0*LV2bLCc5cnzz04fnU$iH-Op->Eq~G#1n>e%E?89=fI17AXX3pJhW_9Oo zH(O(%pnC$p-GMlo{0JHYT9Gi8FteGcqPW#)R6YHN({HL#F#y+-w7X7w=^NM+61`0w z#?#`B(m-~RXD|Z&Km(jzP2Z})+%5ia1gee|_Jnp@Z!ZMj`i%&@55vVS;Qx*Hv$=E( ze!d~#r2U|JyaYl1+WBEEod5C%-nN9jZ@Y57MV)7v$nyUG_E$NGt8S1E<5v~v9}FkF ztoP%u>2}fu{PR~nTcl61arU=-l>Zb}h<)-N`FX{yEK#;8H!7b}ey?__cdIXHz1rQ{ zKj|&{J^JsAX5(_>6UHBGv$m56m^Rx#VE?tF%keJ9GmclC&CXk#CtMA#!>-3&e{k=0 zKjUflTfx>2LGj<^O*I;lR$o=L6;7t-H5!a=ir$0I4`O;OAKMhWE_O2Zk9Fa?zPiim zK2-OOdZ~W6{+jxy;-2`{_zMl8hJ6j+G1r;TCPovx61OG3n0P*ECie?T0d78f=ktk6 zJp->x9+`ei=A3_sku_x!wJZ3|8i6^w`=Oadk2ZcyM%vHwQd<77G{`ejr-EOv zke5mAtP8(P@K@4$eChhAJS`21Ygb7~9ZOTVM%P>MU4w59-#oqz_@*muIu~E@9G;;u zAfFd08f!BJgk_;TO+s z!+ZXZ;rIj0c^8c-#<$?P4A%*NQ^3(m!2GXhUx@F1vE~m;1Hjo3*3pc6NFR%J57ITl z1K|_LPV|?QHK1h|^dHeCFCC+LIpPui>VhU+sH_1m{4Zrva1C)m_22aphbHsbHZElL0Em0tNxnT`%1vJt%!vDoGDXkFrkQ%m0>t zlfM9I{*e4J`F{BU`9b+p@~7p`nL)GGtY28b7$%-wCS5Gez3thj@$B>bC-Mi+diF2n z&zb?V#;jXdSop_5CVO6=353&Oa2;nk8w=^okkNoP1PrZ2Ib= zO6J1jP0TgAV#kV-wqiO_lG8IAw@ssS?AWwfnwr9;J5mRaH(=; zmOAKu2lf1$sc93~I5uaN>{HXTxMI>hJGF|`D$d4cXJ%$%z*fmQx}zj*oGwX|)H#9k z*kmbAt@z~Jqh4tT^>|d3w$IG$oSP}J)|r{g3TDimSWjwXrmdvr%oS!yNzY+T`smbj zNl%TGjMNAyfJbKAN}517Fk$YT*SC+Dbd#1Fv%sgnB|f`iM@el-;O3}#%shs<<~!6h zFtlNMb}BZvab`L-lbA6}%QsEqUX1Wk0i~^^=SsHGR{AL~fpr6?sgV@eB{ecv;@fwZ z*bV?v(p%a}wwy`Oy0I)p+Kw)OclqoLb(tL#(AsmyZEk6F#YjtHk#QWka~a8Ljlx<1 z!YGzLYpyt!nj@kLWJ@t3NXd)=$SRZ|ZE9}Jn!@!CkCz(p6dqn&+Sw1eiT_h0CtOZR zUI7xtQi+)sFtH~$&-sed&bhI+k~fDXm}bc{x|&vo1}IeW(%D9wc?G?E7|1J-Vgd&{ z0C>qaI%^)AHA_CAt*zwGO>Ul^S9XrgG?rYuQb*fLf!ySV>B&vj#aIH@1LArxH!t}| zw@lCb{i7u|H&XJolE{IzM&>>A$BRED76vWk^wjh`$sy1+atsv4wBD9P3XfIW;0L-- zk3f>??hIBk0r)3y^;}}T0}1CPDUbq^M@!PsafF|OA3`|^KjF4w^K{9d8ZlRt++aT! z1bcSGoPDIGhQZ|yNFyU7gn=OLvAOx6(OSBzHI@W>hq1;`Yg;Ljn`d;a0lw*2o12&E z7|qQqbd2TZRXWz?<~2Ij=jL@f#&h!q9UF4!V`|>!V{M);z_I5Q$kbe4iWK`F?E!XdD|J;#Jnz<45XY4|Tjo_3S}_f!NK`DGg`Rin z)15PW1mry!%^GLL+tmcL&v~Jx>r(h3VcW)rQhoE?EJSN90v}kwd7qhuu*~(fm3nje z$Us}E??37a#@>PMOF$wioHq031gQj|cGal zTZLPTzKcb~w{zZXszNPj{TCl06>`mzgY(uUS4q4a`Xf(R94|#ir>A1Dsph~; ze!hbRA-BWl+}#+PI_K`lId`kio;}`MpBT-R`diQLP<^O6;aIM;wDlO+k9h1DB>kOW z13~kp4uH5qEScCiV_|*{4%&#dbYkZeBrOlgvlcX-o43Q(5cdnt|F5z1#Q7NPzr)3Z zZ_;A}slHg^EPhGMRN$O|0`70EVr3=HmbNB{W`vi@Y8Fwj3MdF!Vh`^G5+2BxijeZv z?{Iw*!=bRf)QdiAa-}6WtR*b20J_a_7~v|m*5!zyOKXAV^||AcG>*m;8jKnna>tpt zvJnk&WfS$8z^%>HhZc~JKGfKnI{|GtiqC~+>g0n-gwP;eG!&Z~}91(r!2KBiH4-YPmdaXDUPaL(H^u%>mle%AzaR#j+Z?Kxw z;YO=T9o~h$LyP0xB+kTmH(O2W{%)&D-EYB@L)Lh=T21Qk9;-xSlHL1fft4SU1${lwI&$gt+jw@VVfuIStY-XgjWb7)*jZ;Uf z2E9!}0Qk&CxRdN2*g7lZJ1{TlBPW^=1GG@0(Ai@YWsl7_vO6{)Ah=_i&UcQ@H_`c{hGbok#%5ykS-SMN@otGJ%kS8+S@gsW z`ggJ(zsJShEswH=_m-6R!$^;vP7)2u zh};0O0sLW9Ye=YZrTbsS{jahY7T#DWh<-G#O*%*!0tF=i(*MBMYBTH-{*OwVBQXA( zN?XQG$}^R=A~i8@rL9UMtgq76&bsd6``PuC>u#wV*|JgTD(Qf99cJAtU54NMJ&bHZ zle9x>#<2_UJ9XeU!`eiv6Kzu(!*7}%5`FjMY!iC!#g+Xy?!wNhDXkLiJbv}{KN=Z1 zqs5W?@Z=p;aq@5UXA0V4Vdo$Y8$c}6hJr3cxOF+C^8Ug%QqVG74`vE;2 z4`L;|FisctSP5pzvHbB-+7`$8&-S}OKtPzFc}=`;k;iu_T8Hu34LFbBcoo*PSHMMB zy+-uvL(c;6`yb)wT+9=0|FgKKxdx?rVV=g3H8SAn_DY^cwu#i7QoVn$kKzy$@IaBMK77*}*4-??dN|un8;P zjhU{+NC(A8R*x&ulel)jn44xjf;Ms8L9_`nnspO6dJT^2AtluJY}nSEGXhcQ{9Hk> zoq_D!c}+ld4ZeH9#dFej{H0mX;AT$DIE?)>>UkKvYzJh-V+YV~$LA1MLDG8w*A9Wc z#FJMp(zzXwk7EV@ooAq;NF_mEy$7;%zJE91B7ROC8bv|&R73TL0S#uydjd}ULYrIi zpuWl{`4N@}QF(~66zIoVWIJPcle8W>%|wMz3Ki>V)M94Awas{&y%l<-4e+-^b~`a| z0eYebH4?p2A9PVaWNZNW&LQagVMy&5-i02=TOlh!r`3@1HPTw}%zEszZUA3x0^YZP zDqEpFW}t(&p+X0FQsi{+k=}zHl)smL$Ykkx>1Rxlek}b&`l<9I=^q%qrK970Li|z# z%3Gbx#oWw;Uzk53JuE$fyzEK+$o{<@9m5^s*j4DYj-yM|iMf6I=EPZHNw>Or&#uFB x+M2n2+jq|K>AievuexdPW$3Wwz@fcYUbSDI+Ot=lI<(h%V0a1Pk|Cq(`QM)rcFX_( literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..8d47c02d9408d34b2a9d566c0fe0d42bf82fb735 GIT binary patch literal 14408 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..cfaa3bda59246b49e94298478d6de3b3208066c8 GIT binary patch literal 12216 zcmV;pFGtXKPew8T0RR91057-z4gdfE0AMHp054wv0RR9100000000000000000000 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 G>;nKVNojrn literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf b/docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d5850df98ec19de2eee9ff922ef59586efe471d0 GIT binary patch literal 22364 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..7e02df963621a5e26d53d510f0b4992eebde1c60 GIT binary patch literal 14112 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 ZM6wWJ659DkbG}7@mjJD1@jO-Eqc8pH1xbNXy>V zuj4@|WLKW95E7|5CLkNL;`-Y+wfA&?GtJ-Z&L(!k4v|`??3CPcqTcL|tNjQ{K536( z{p-EnmtzN&6c7(-?6J;0;$I;9*Or=#CSe6e`Kj!u4Ul0&Ix>QOQ1Y#>s9n_Rs?i!K z`N8}1e;oFIb6U<-O6FuJcnRoEPTZX=aW9wuuhQ&I(s%2$94HMXDG%c+*1)?j&HvPt z{x5f&l`#j}k2io7&=!!w?=Rc&|6fkeUw4gUWm(R$oMkzA?`+>1cE=cO4|J9@oUwe@ zJq9WYEP(~E3>U5e2q**H@Lxant9$O-_qA1~YfFUmMWi9#7(z1*h0+O0B{7{3D{D^4 z+y+H#pL-pvasQi8$-7u`oy}^Vd1cS&h7d}o=09l#K=2N@4Uhmp8_<0KfKAV*4nF{9 zh``OnQviI=2H$)OZk$-3w+A?YOeVo(|CfPQ^gZ}X2Ef)13;=i^x&{D{0emUK0O21D zE;`}h2dxaq;I_*Km7p55ff-;SSPBk+6W{{40nMlsJ&B%0@1SXH7j`GM8{3B+zz$=_ zu#+;rEJr5!|Nnl_4|b>)w1dn}KY^Y`Z=qY*&M}W-CltGC;W3{5am+sQp%1+8mU~@s z)-i_vmS?{EEpPUg*S+dxFL}Z9o@?xb?}G~<-N^lQjQk`ZI}rTy)pLNZGKgSfq7o;5 z3C!o|;180KTmF@N!@SWef~L?@VC@<(_tr=p{0g*xco(8POvL-AAYBu2CpE-(Pg^7< zM^Ab3%zlk+nVs?3GjK8DTb^inatT2!oMR+)?S3PUowMxCg0eG3A)(Z;sCeEYpJ1XU2Jp}l7$I*6 zI6xy&p)wjudn4F^U5%uGuuCZ1$Q&p=y(q&{2;f zKrbeREM6T+Ko7)CYCtk?2a>fX1#8CI)v)hK=p9wy%t8)58sTxvW*qoQCGuy8Bx_BV zoRMWu7lbROj3Msrgt%?et_D%7pyMD^V*VfRke2622B|#P0%UJMS(2)~fZ!M_5rred z2-%CRYaEa|mdV3woIUz3r@ zsRDSjcf#7lhn~97stOI11A?yl>nS&NRT8SHmDI zY-?rR`%X4=0J*Sqny+N>V4&<$Yq47FB)0sp0MOE1LMEvBfI=MqO@OfiE$s(#wMUOk z?a9zYzDK;u?vGQ0?veN25XS#CVNm#a$Bl0EN*#qLK;RrjRM4`8EJv8-3OBJxmM6j_ zBAZkc%NKQ72XVu_B>c7gAgBnhq9!*k>Ki46emlE3S>ShfCc_v%r|u?UaIr6tLuw*N zh605Wg$jilMFEOJ6h$aBD6}ZHumPw&7Z_tBvwd`g$Iu{&avGpp#snH2jkXUm0~plp zR729dB>4JMQey;Qaqo=6%q{^h7tOYiM5h0`~o*gi{E6v*hEL=GsOXV?O4_ZQRHx~t)UzRQP-ftfIt~F zwkvtViXKQpI5z0J8QQmHLUiuWI#z%{_$C?w+&rb``3s$9%;LF|Y|ucR%RZB+EI}o9 zE(z_Kf?y}Mly&TdGh9t8Lriaas2*{nG)7i3s?v|Js~om8qMo}rHG^|(gd|Q4xY$54 zl}5y?l~qfEkew&}G;f47?iVhF#=Y%l#EJ?b;vkWRNHPi6+Bitu8;oEGMm&gGtDuc6d+M@+8kNlV zWA&lX(#E%KY~TJ$48V+4!+3V=TIP*~O{rCRfqw?5aK<445$&Z`)@uc&4(WnmOA!8p z7DRgOo}RMX#e{b2Pyl56EUjx{u>5V2=YViYP@$idfzbw0cy^x=ZeKlG0G2y3L5pV~ zk&tLK(6XY&0LstbI>0fB^pgKMdSt7K79u;F0qHaMuDL>IXM7*Z^Rq0D&f2 zFC7CUfB|?BJ%esz0Ff5<{WucQVj!sUR1|h#dr|>60~BRR%d$nxcqWPcIm#^3I~d^k ze`biDMdK`oorMCP6J9Dd2v9O(wl^_lNhvKraG!($7{>qy=uj5cXga0YK&dTM^Qh7l zSQ$4=l^j@KZEQ&qXaX&88_hM=0_s1eAcR3!GSG*fiyN4UT2tvVvssEdh!QXiN(7Do z5C;>m4nf2b;doeuAcnQehCsdoD3jqChUcL@v@@DG{66BQJOC>amPVIw90N#zx%s(j zBn(s4_wfLHHOb;kSu8ETmw7=0Fea>mq*Kcxl|o3id1T5QgUGqePw~jXg-HeyO;b1C zAwx4&WPYcdN>e0NX>eYt+Ao+$YDy`ea=ElAX^qA_TR_yZO=XbF@lhT?gMo2oRUlcG zqtO-#lSD2X%xlvs;SZ?{^MMGYc|=m|q;ovDVt*U?z1sjMA{xoYlZ^?_YjH<=J5)xl z00=7-5v@lNtDTKRG=*6+K3@DJT6y(E?4(B1(7v--&BfcB}z}?cna>21Ttx zG~{fct&y~3qhX86BPb*f&~C-U`iwDXaWcnO`gFhMPj#e8lhaYSwD=@SW zTN!vOG{`rox6-geZ1K9)KDP{*fB>4VwXMu23TNc;&EsJOutC#}z6~B?)}m|nA|Ck6 z7KH_{17;Ru$th1I(FwVsCyaq63hJ!fZT1;=uJhy(fSTu1qA#ukro`)24RD;WbhgzT zHNz}?zn>9t6j5%zv!AK0!AZUafHhpB($H6~P^poQ$$ifX=JXnf$_aoXR3>~@F17~Q z1tmn1!tsLm{qM7x>X%sBEtNqWvvf*Rgn>OnkYWEY<1W?zxi?Uwc}K)rR#>sS9+cHb zM~HTFnFw)Q>5=DJmV%GFTp2{~yueiM5#smppj=CRZh!}%?)j7p=FmLn@>l$fhDdkhC!{|~muRIgFFLiA@ZBCMhH;GW~$}|-tku#mPtZ7U& z12(KT`vE+$i|;L=)ToWMJe9hh5Vx49K!;NE4P8yrl_U@RBJ(&TK4BtZ^VMmY(+vM{ z#`Ue}K;1>k0i2u4L^jKO;yWNy`j3M+veO(zjJ5Q+U_d25r|V}BTMc39hF(9jh4oRp zJeR19=nD|XV6GFf)QSuol@qjiqtc}2s#?70La*m(Rg+a+rm2(%LG zKIPOvA~2$ver&qB1MNOCjale1AUD8KTe$EchztPKN;`x^s2T-ugGwzf;S4#gUPsq; zJs$XEf+b@0N-S8iCbk`ul*33dE!etT2vk{aJ8pK{;F*XVC_m+H)Xa+YshB6YIxf}0 zWd+y6iOMKhYO{G))eNaVR}UO}pr`p` zaw}&R?1iOU3PXbp+*WeEe>#C#BlB@X1T&yD1IQ=w?nqqqTDud(93{8TcMbBD_js(r z6tLXi>3{s?@zQDWbd_T^i$(Gbm|E0OOV0}>1l~8JWu50E1A78vY-+|~B3od-2k%QB zTR}7rk1NH1I(|-f<%q4@apMTjQE3O-5T7-#6479#qIS&kt)wx_!{-$d=7>_YTyg6> zZw$5=W>WX_lZLPa&%<#SAt#+|*3LrG*BqltowbJgTpvUNnP?)wviPB&tfUt5?iEIS z0?o`Uu(I%dPjND|afnKZ+GYcJyUOCVno+Xs>bCp3%1u&WF4k%-)XAgH!TL7B3t-U@4YUt9@q0 z?xqw0>QHe_PUbH9B2cO@Z)U1+X5of2Ml&)1+QUmgBzQ}b6;ag)UAzVTLoY@snlHu>dF0aw=BDIwb_q2PUnqecP|fMs`9oSPSJdwbDx_I z!7=N-(}gjxB)(vwOgE*`yHr0h#xUg+4zJiW%Y;oNO7d4`$jfgh%@-y@YlW0Qb4u!(pRC8xz?WI#78o36Aw;f24~j*LrRqyme=S**_HiC~UvPT>tatLHX;-oseQw{! z10Rw&K`%&BMCOZ<)nizFo}I5*;N2zikNceD?=a$Wllqd3=Iy4P1mFS-RZ($0)v)N+ z%Tog6xTDhOXPG7HqZ!B;z|cij>VaVG7cG&fB@fpMF^!1CRz~Kyx z&6yPT%d-G?mShL}+Vo8#8aDg6#1gNMTy+h75ozAl8;QzD)6iFv*@}v8RdavNP-iEh z;Y3oX$K*6(XhyHtpt41yF+;r6v{8nQSr`h{GJTUZ*R&#~6yI{zYKZb9)qzhZt+Yf$ z*9#TO*enc?iRL8YSk^0PSX|}S2}8twwiwQgiM-jdih(4;aeLjFND#=9nO#uAt#wNk z&9(N@kkqt9K`7!el?wdNdT!{U%qQGWM0e$2LoFVr*+T4kF0-E3wGe$>Rue1VPMxUs zjOg>W^RYpR3b#>NXNxZJmOjx+~6&M#22cj67p^kthE~1rjmP06z&;-7j=^zMxI0_ z%@-JQ(0XpLfJr_hyYe{>udNv6`kdyi1e=6=o#{FZMYuPz@R^(}6q4=gu~^EPQ1gf! z@mfLf@b%_|frr-7PS;aLRg#l=Q7)Z)j{Cn@(<9y}VhC5jD{4}HsLNrkD7dMQ|CA;y z=oLCT>SQ7?9}_hU_i5T}*@|dR^j4LD#_fhh^lC}#@=#i$5H|>PGVhfYo`&5tjj|JVZATZJIe1N_l4TxRuWSxHr<`{B4enmQiU z3i2~V?h9dQ7Cb|UC-Hy_%SE4eT_(d(Xx6Y9-o?u}Z`2K}ykC!-?8j_jvU0HFSpN`9 zXR~Ip!$mn3w7euGQvE|yyYdjo2|CEvPShjHUc`3;pnR=x;hD!;KZ^@96h*_y17oC- zW;=MUWtnaa7kJ5?3cyU;(1yk-qm-W3!h@zuTDmUcIVbv)7g=oX)L4t6SQO|_V4)^= zb~o$?;DO~alt`L4u0FokYc_I_L?W>@vy!2Cg-YhrIyCs>sjzVyVag%3)(&M`z_NO7~{vjt<08-7Vy#y<3DCI%o&qy zEdQsl5DLcpT3#BUF2rv~U6fUC-n{=O$YLVw>=yfTCnN=O_g%3xJeHIFFgSO#He6|r zV%~P@k1Xn6zlHXor>F4IDECoBQ}m}`d;5o50{89m?@A`YQ#8hB52+%fp)ew zvTlnnSOn^JhxTwtR?A~j;YI~O?P=iK(bP@`^)Ie)p=XNZ+?!+waZRpWt%8#nym;c{eJ#}M%~bSKYP0!*JB8(RS2wuh}1#vOZy@x^S!i162VTxKboB5 zg-*n2e_irG(l8BoU6bQ#H%<6TN+#b*#4?t!t=>tyNXT#A9+u1z%|2J@lV{iDzPB%1 z`YfM$YrZ_a=Rp_2;gZzc)<3yPDk};(kbL>$NG9Jjb^QKXv+>zG%A|Mk8rLcojj=^< z{G$q*vfH^GHTz5DSl0BUtj%0rvFg$v`o*jp&p4>Ia$l(iQv}wg^~g6%o1R|OQh#7O zswjt~4UW03O{40CXB3tPx-g4(zK>}O2TRL34e0@8ODtFH`C{6#>V8RXkx-mwL=*E8 zzuDH-Xz=Z;w=6qR#-m_V4B_P-GJ$R8Y~?WYw7dk z9fgbPYkwMind3h7U4IpShGd()QRjM4laRW!E^Xdw(Qrl43D8t=)THsKuF$<&52em{ zFoYn=CiM6?fwo~nK{V@J79HVB8&GvMGjRG85I-nhV)==9^lNLgNmj7T{Xb;?hmnp& zX3h^Zhp0}Rm(8KM3WRCbuQ#r5pFmQg9;o*~R-F)SHJ7Y$mW-x5D~|RhnF$GTzeGB! z&^GEG8vx+@_tu4@J(Nyn%|^)!ON$U0k>i2ti67;=l0~fyF{^R=RL`v1*Z>s!p~BXc z(wS}1*gg_7`q0=1M#S zQH0~xY?i9aALH?2Pye?RQdV(ei{R-~7}Q!t-T!lE$zENq*>%e1j%9)_an?xGLHm)D zoIIt&;lPKVPe>-*8Ey+ajE+nf~_ zN!-Fev=yOn^$(i=wAeP-?@#;m&+B|!exl7g!rb$Oi`%5wH_(?#c0|7;Rrdd5R{Hhr zx@<2JAn0<3t6MZpiQI^x=oGij>8cCvJ2f0q|8{;bCsbbW(KYxI$!m(VQ_gPOZ#F}3 z=xJ}!5wETvg*P7TDVt}@YpTtc^DdjKYfzlecrd)S#KmvqzCpQJo!_jj3mE1?ZzH1a z-g%?6XlgNYa7NgE-s@5Oo@g&Dgp60%-o(81Khv?!zvJ(8G(8<}R18}ur*a**Ptvri zeNk|hA+WY5%v-2WCVJXZIcZ^P-J;Np!p;ktuDSceq9(EY+lQEO5pT4YUEl1Bal1QY z9Ru@n>vU;l&W@m|w@erDDcnvwOucW2!8VWBC=JWD1N$)p5bfyLnw5s;%8dnXx=1oN*iEs)HNLz3g(;#UAGT9ixN2 zH|i>{69?OZsoQP?qaEzw&BMz>!^MHS2AavEbIuL)R&45tC8FhAhC{NcYYuE`1Q!?Z zgChnnvzL?WT3i&RG(pbR(*S+)G2)C{l^4zdgam`a{zC_0eE~(|2f!g{`V69L;v`_k zSYZKrjc7}5)Tf@(dg3_1M5DqX1b6Pz9}*Yk-yypT*=$5s!%XGk(GS7^sp%KZZ-UO1Jc5aQhjA28aV~6w*sqq-fLbhXOJGcsZj7 zBTdM$e^YS>?PY=Yjwn7pPUk`ufIqrs^II@hP`ZhD=`d=2&N$OBSlSsm8$AbhEQM^{ zJ8WdJ^nD$fEf57$C>Bx`%wzO zineUMz#dv_izis>d9=;`S7SG5$B<;5cnTt?d@>LHZvM2XGaMAJm8?hgQSfj-yDJ zu^z_0TU+WqGyjPRgt0No4~|KP%@llI)w@%6m+Wq5RA}zrR1WF&0 zwLTv1=RTYO3DJa~;jA{Gx|Z&4mLhnZa$vgc(2m({0qt!-*$Loty-m(^)U4g}=J~3G zN*^+(Ir1#;z_?$uST{FSvj(VUz;*uMxP3F{S)A^;D^d018;4CH;>ZjJ2bxT1a{QlK zL#+WIn+>65Nr*22#Pz2v-}Gas=N8Q8WTGN_wk}!R`T3K4^H-)%)7Xp$+Xas5S9Uae z`;#M`v@n7skwj0t+g6b(wZn!Xi!LieZ<1zVacN}hi*1cY15EE8ec<_&-42HqNiGno z>wyZ0$iM4Hjz-GnWJqNCHO{|{6^8QsmWNkY%x#8eQfFHGaL9U<6d@nVx0H!+$RAYH zRj*l2So<>=GVftweUj`LF=J%eF)Kh-)kSer=hK0fU55i>f{%V%2Rp9}TH3EY2^aXb z`*&10eX-@+=QQ=5yb*37ZoiDGt43BxmU7_dm}*0b4EFBo?|~na$+UC#+NMn%O&ua3 ztrq=HOC}LUbbf<+-WdEjc!u^rYLaZ8v`IE;59A%xC6k10r95O#m=ZAj!K-(|`e1LE zbLTChBGmKOpNQ!L==~UmeB4TuJnM{ChkR8y11o$ydkD3nagDQ~QkZ$uT9D)3a84V@ z9mM&80NdP|;WayoT@X+saFhL~;dss-S)sG=dHx+Z%DRwY&wP-wt1Xz)7o*Bt2zTzP zD`*g8g1V-17MZp@o^*Tb{D1Yqb^$UPlEH(}PBn>)RqJ}0e#z!Qn>n0WNC_RDecS0C zI=gJIzwx)vARD;Y9g0^4tc#VwG|ipQ3bTs#d@-Ly?OJ@cDZajmVE$qxj2y>XrTxMI!2l$_Tcf5quGPmG z-d4(~VMz7>Y~sx4TtR)NH_=v=aHWO>CNgc?9m+|mQ3egqmn|1Y;)a}?!Uqa-Hh-#n zo6-(pWEdcY98F{tKtpgFFd`dKj;fPm; zMl#s}yru|8?Pys!pSaHndEF2VpvMIMYSfC-m++bur%X>Avf7}(ZHMi1lk)b$R)~iG zp*_te)g<*vz;lgy#8#=i}8){UGxT`xD68S~c1 z^F^8Ma%-zGV00K96m-vAXm%xv+ZfyZx>$8u^o8k`r^rYSj32-Z#^gAp2TWn*aKk>;ENI`;{QCSF#r3@xt<9r%;4 zJAEs!woSf=7O62@h}U$L)a&fi_cGm-@8?f9YY(FXh@wZMY1}bXFH(!fg(DnPT#VFz z?CG@QxSq&HM1N?y*Bz}=o`#YLgf3UqtN5Lx;Onm)&on;5PQR&fC_EjSM#0#)ATNNe zxhql|YGvl!ziMr>Q&D(SKqr22>z}u}@Ym+?EP~3UD4b*b1fjwLG?6J99UTj|YqjWw zX}3E((7PZM(7bA7T8N`mjjV`C600vMkHd2Pfi#7EkJ98T-j3C35HuP*?q3+=(2UQ_ zAufFIyh%^f3#Zz7`+$F14&!$h-y zBd>1tE40B&&VfHnbOD$2Q!ECl5oj|1EoTqzvP8*(Vc}5myTsHT-Ip&z z-37T(S4; zxonEbd;KrsBR{_#b)kLxAnJMqgWMEAT?py}IeUPaGMlO1C6`X7YQ>JnyYhseWdDsX zmbT_f%{T`wRLd!y55m`PK5C1Hxo=KBZio`cZ^rr|iAV1V@7Igw@BIYkIk1f@FH+~M z*_wl*Lxu2No3QeZ_vF_wSnecnwoV3*+?iBVPy${S~VU>+pYn_PU9eoCmijrvpNKpy&as zXffm~BF`)e84Pe@x+D<}pjYbOrc#m+ZavLLdwvlfb9dhbmd)Ux0fL?Ureo;LWi)Rt z_@PFH31^xfu75x(Byrd{LSLQ3>`t<<$Xg@Qv=vj#Ep&0EY0?S%4f!}FySO*A4pZ)HCec%4V zMn>vvV0kzCzYrD^*m&pdN5Fke8=E#k5^l?$XE8%_$-M7~ue3Q-$s^+2R)<8j@|g8U z^%Z~y(78|#vsu<~3#8c9Afo@;_&V{8CKpF zxXsV%YN5Gsj`I4Fv1Te%9F!lJUSj(`7s(vZ;{l6==1xAX0Rnz61kTPqlFQm-lVZu& z%CQ$T$Y#r&vZ+{MW~g8|B$b&>Kr|-VSn^K>gY0n8L#EFmvHOg3jMK(zD_o-f_3^9a zHpB`*;!sERd-84Ju-n(e>f}IvFF;+y9Y4A|LIJ@QXI4)_bHi-S9nS8rVCJRJKZuin z@i@RBBB7w9QRJOikiYb~Q!8krypEM|p=YDCDKh$q#i@Vid3=gRj?v?gRVPIMpp^w> zSGe3jim2c|;Ng)rzx<5eQmEMMmxcFHAt{x!?@n_=PG@212krNMz#=|R?w)nN`{Q9a z-2@-RcMUArU*)mL5Lt9rixmQz+p9BOK`nE=HPuj8&c`6TgPuL>4%rhQ-w^LT`zfgK-IJdsi5# zz{!FM*PUe+EgxXHSBZuKCT{@~xOmt>>8&pkGkZJB`IKH_5eBT+y`@ER9$mkpgrc1V z45$?1+67#ca@ugH0%SC2Zz6nJWRObexFya+Qo33u(9osEmal6RYza|@Lp-j55hHqEo(hM$x zhLd{>8Dv<>1TjY7kTNzF%Eyi^C?XPjXC($^@=4H;D4~i}Ao7r?!yO!lSY$#@pr*Hw zNkO`RLvV^DkWK)0n^m%aQ{BEygaRNm-OJ?_DB;pgF&2d|tax9KW;dy`slbVWD%Ukq zK9h=J5@H^cE12ekcSFz|~*?6QoD>U^FnSk=i)1Qqr0Uk^L>J&;rZ+HAAoi zZl#eB`(cg%MoY18fwO2gm|s91(nmtez+&{uSf~jkQ8`FPmY~N#GLzXMK`4n+k)>w2xk3%Kzs?pLt!iz1nI~Jy+o0<08DygmjNXl1Q|K8 z6+RD!(P=PD8C=yagS;4f5;H1QKSls@;C&z?;nqan&fp#=w1dxVz*|rVUPd3m6&x1X_#+CQ&ywszu~Vq*NnkDO?OsQ@zD7_64x)KfD_K1#-da<6y{QFc*+UMF4c*;p@B%oDeH|p^$A8Yh7E$|Guy=`VwCiLy@Jf3|AnzU;>JHL0Q5Z?y^ghsYV3tfm5@2Yu3@K3yhZ4`U_s$jlzHy*si@RK~1^ z?NNLb>NJhmGsl@og8=);OY~WW6j}P?+lVMty1sWQLib zz8*)1Y*1LYd_*Q=ULu1!BCrcjRYSxw!n#v@2o=2oZGRykqlFleKCT-DlF39NhJ-o2 z(9ixx^?bs<3bM4L|F2{*W%19SynliE&V_=CCJP+{6AK#$7Z0C+kVv*1xy15FNXaND zsi+kwR768dN3WQHk%ZAde56-iarc)ZBuf~w70z(`#%0{cmOagFS~9(5Qb;3&WKzh& zQW8QEN`_D#$QjZ|D9KW?OJK9`*wC^hz%H<`Vc#aO`@xL-e&t zXrJ4Cc+Y{w`t#QjlKdDZG45G7b{O}qgbe)*rEbsut9O5ay7r*{YeE`-y?58b^5Wlj zf1i-(8@QL;iyPv93SF4L6xUUI4;(-Bhhp#h35kWV-fR00EiKf2t>PphP5*`V-yc{w zb(l7o@4@x=aIG9%IIwH!yEktGJYOb6^U&c#$ByqjJp6S+2In#Uro%^f9p3dEyOofh zEc!o67>S~Mp1FW6u!`AYwqVTWkG^j?8fC8Yzlzco^f`z=FS5spfmn#{F_Tf&uxKb1 zXNh>!aU*4GCFX2iZ5Q;Ia|hXnIhS@e>-e1UR4kgX zr;@R#+v8-CbN$NY6eV27+)hdK`z2g>q8_))Dfug147Vx+iFh&vP%gXl<9;dzAXENe zK$}V?Q~ANo=4-B*6f{Q3NXO`oos)tni>4ZWUS{jl zqRwnNe%wq~^g6fZ3w*>5y2B(~J0N)KlnU7_ z$2Mwv=H_|^W_t}5xot>qNNqM~9+2CDNA*-Ht5oRup2Nnb2D8Z}vCUMf(f`nLY;|4n1UsSUQcH z`!>WwevefoTA&i;`~)ijbUc;x1pJjMxUneM2VjGNYAzR&NDBN;C5bvlRIlH1)Za9Z zH&=%@g^J?U8+C%)Y%X;Rx)Os{YoPDc81+WVa%rtr)EOD2PdQq~TI;R0nqHgfP2JgR zC${X~7?_E6EwqJ4SZPIfPb-sK9D!;_%c$O{*PY7=8k3HRjQu`$&B@74SK7pmc%W&1 zu_5)CQMSDuBWfW7V5E?5@vsm z=uQNa9iz;8jjgz?S>reMRZ@^;nBueXkRj5zDa>-8C@ZbA>jj&}Tx)mgsCm4RdWu=O zzf|w+NJ|zbSAonzsYc&iQ|=##nY|UZu1yCvhL_WJ-R4DebaRj2vgMRU)VdfGg^wRJ zl-nm*L$ImAUA3`AHu{T;yxQF8mN}=BmNr$U^g;!pWR|`}o>6s>cveg4rTS;?&8h~< zk_@hjbTeemK*Y0p0b|_OR4OKkR*%OY96VzimhZn`9=3I|CTI71DF~;*eI4Cz#|y>ycEQ zw$3@Ox;USM9(AumeFanNQk_a+uLc7hB{ossCJG*_rHF~!B)zS~ph?6%WeJTzZK6yl zvRU8M#`ZdjHC@-69S-yLT|$w=YS5OJnk=PSgOxXwmTnLn?l-k@dNr?phJBm$6Blr> ziNGNlPx%rYa*xdi&Fiy?l|h@Y*-S%J)lyIyZUzW3|Um^uk!3-JF(8Qb)$e02J(68q5}4Zc$N}CkV^Pm1}cAkU;wRiuws0^ z^;SOL+#+lghh3y!0R1hT*IYhmGUj$m&NXF0==-%Moss4q)`~L9ZR}?oZy|Qf3 z$-)<4lY*=NN?%}Sh>Zkblgb==)y{GBFVRe?f@b0>mn$b#H=Sr1*bq6exp`!Fb6ha} zK(uw1mN*@CR+rNjD=YD^11%N(|MlJR=GmE#bXLBrjQC=$H}`|n}ES2 zSnwIF?f?c7msSThJ?y#5mxv|eesy~%cD$`s@?4wyWSN1lI=84Z$Fk!5T797W|ds)8};r-PzyTu+gR|Db_}=GLOV} zFw=m(E-(-?+<$-WNN+f?!P`WiZ<}oEwE8Md*O`5t*IUfpz4|Jpx6weSM|&dCMCAr9 zN6>BbZ-GfWAZQ72F1kS|Zf}A?eZd`?h7^6MXSrbE;sX;61~i<5jvJ^VzsTYR;n>Mv3dSn_1 zP{wrTjkPtQ5=TU-V5~~6)6uTD!`&Jys&ooX!;*RW)RoxAtIMNDt4)d`f|IJ$LC zEK=%c{GNd$MdnRz4Xw0VwN*_7IOnfz9+f&+7til(@btidFS zA~(~j&y|b`l`8xIpF@1XT+>K0L1{y*ea6I%h)9zIqSy zW07kU70!UpWH5$`?NDhCJF2UkOIw)6M71=EeW*(g?OpDztF8+^xO~G?m8RTJac`=5 zuBpn%m>jJd?Dt1i$@?uN?;dpzsan7R{UM2h=mPihVwaNY=!5b{ebSOfSM#9Oz|OGN z=~2`3xj(c<44#38-<%aqj6%nRAjQu^iv6UXY=DJMHP%+SSl;KlAgB_wOhHmrw*`v? zK^fR)RlYePx7Kui?^z6FHiR+lYE6TJ&wDqr+Tbtvt)~70> zvDBpAage?-u&=+R#A9?1R%sjq^|EX3`0+WHTtDCdL0y~MlTGoKmUz=gDh68jdDuHT zFXCpHbgSGnT+m_pt)==`V5iC`K$}d#D^$739Sq!1;gv)H%(=;XaNq0h#?;18iM?}g z*JNK(PwkGTu-zEiXrdY>cTCxgjr}@SRPO#_aamIfd|+)=v9+kk?5mLs>}G$ty<~g# zslDkME%W)R1;a$UrpTnxZ)Aq!UCy$WzF=vcCmqwz>jTZQNF~c?T=DmC*;F+?eFof+ zfDPY7g~&rFXnqRypF5*QDXO(m`|=n^uf3%2TBO3QMIk;Z3@wBve6?nBGy66@N@T+0 z92Z=93z(V(N+rz~2k z6(o&OhoFp+6gK}u?8}g)AZD(va)|28fgn6PzNzv`?_wz}s7D@UO?qjtt*yq;H{LvB zpd(Z+9$+%FHN^&7Cl*;J9i$pZ8P$*WZfYEw7k%Zy=Gui$rl)RS*k6DCDG-O_w)$JP z3{^S<-bi!IT(jI*Q595+PGAZh&aQ{2XeA0Tt?)38Y0LrZ;;?(5(}F(kD_7SG!5{)y zAS^kfrRQioe*N26GTEK`1#Q#PPD7oiR8RF=w6ef{#vY@&kLNzl*b_`RV_fxJ-8bi# zw29Y^rIN%5q!V(=7O`dtsa17FW4NLWIt1(5V%SCbohKDEx=LhGa_~?sZwoo~9DzWH zsn?)9zcF|FyFG`a#fGXw+Ti|Dt<5#t;;y{;N@-+pVA4BWVeBpoRz@2`{nJ}LjXgS6 zX=jg9jcYI%C@Sjr8-iP$R)1xv-2lgn9ia3TD#4X-Mioo$D>nT(s+HrFvQ%4Xht}Kx z*%)Ha0(MxXV(u~Ina+8hSLxt77!C1IwFeJJV6B0Ui#3Ec#jVoxhBjZYuQuA;TMu0? zggd4_x!8Mf?1Chb(#w=U(1v~#es@>3-p4;|Lg=0UBb?ew!*!+Ue8RIrM=D(6{f1I5iqc08rnobu+nK4R!^C;Uiee#h_JQ&q>m9?nKWM|Iif7(-eCI%|uh^s6K?O}amG3{i^zI_L0Plf9{G@u; zJX7Su8y<&kdN1wYyEpd~dp!4j8azM9(Z!e<_}gE?m<#?k`p@iTkDnhzE4Pogpp{1p z(D=XztyVw{8R4F0Dy}*Mv|<+(cMJ`T*aeM7Bh?OVvERfJxnJh~S?V3}>D?Y+D8-=d zsVV_?6lPq5(dD7gH`t_ZhsWQ*M9Gy|rgZGc+m&vct>`uL!7Gl-W3}vY@M!1lzFxb% zCig-2Ls`pI-K%*F=RYXl>f|j z(ayLZ?zag}vw#>d$b!L2n{C@|T57QA?ln^Tdv!Jg)!x3HnyV{^y{?(khYb+4$IU`n zy)(DFMZcN8%UNG0m_gVk8Zkw$nEl$O)Byc_n<4jN?(f$yzY^=)FJ9k`fY>%w% z@_t}yB^7|rb;&O0;W3BKZ{xbrc0o60?tYhP`jFOqa7dn;d03hl9i5Q&J84lR-`=K^ zLv~O1c0J3z#uZ)e*Oc1lM0bM{;p?SV->%Z5n)GA6u9TZ+KC8i6e;}COdId5R3~@nK z1B_rikU-cES6o%dDv@w|ErkLF$ckuFi~eeV*ysx!-j*j&%R1#OU5*O*mf0&5g^Hp@ z)4p$7G&OB0Ni2`cF1MCxsGs(Y%1u2QIkQHw%5_p68ZRo*6|R84Z@ zWS7xkj5&A2<1{n#*N>VeCnmNPPk~(y(3a|*C0iOd>?{(U&Mp22k(KG_)vxIf`WsFQ>n=f41aNmxpfH! z!uAb2%gT&4YoIAK>){ULTsq~G@rNx;sDLTKw zp%slAYdZW$O<0UYTiXv3)rhb%3D~L z=mEQ!&nt25kL@m1vH9z--+Miq9~-0RA7l$^1UG~Il>ycL=wG^)hf)zhgqz~tG^{N5 zD_nV3O2vIVE7hU#=j`ENmFq#45omjI7YdY06)1n_cbHrFFy`hFsef&5uK8RZ@J^kc zYe7_iTZ$hS2!cPz6_O+hl3!rvXpFhb#Cb|}#mnx6va1lS>8}z!iNVl^ohsc{cbwigM%PSG@$qUL6b79hqxY@m=s^g znc|KQR*so9k^~9ilC5dm*z{opCWhdFh<+cnczt2_>0NhJ4BCM1!0To$QV6cLhr7(w z6Kv}CeJl4X>i+xsLnVA2Ln;$hd8!GyS=OII)1ThLJ~Di+Xjm9SzfoqP4+BOuD|LYuZmAO4 zfgos&6PDz=yN9|v1#HfWKxc&*i3F+zwmdO0hKUCQVggwJczD=8t9R4aSATH9pKt+R z`ufpfK*UI3^>_6B^abQ0TA|Mp_2x@07XtW8T%{C}Vqk#kCrL;m1riP?LJ=@1k?>>x ziCeq+E5+onp3WKCx43n+QEEzTI_aR=P}xwYATfxW&=9SxN*c6=j(Alm{bVIIY;M-y z_ko~P#|)cdR!wb5rM9?K>kHR1xY6(}G`W|(KBdG|=43{_gF`*E`dj)F(5D#QGa|cE zj|o~B!3LaTHK+q5YCIJTs$6j7!=+@w=1ONqw-!6YEk;Xct-H9l1y+G=pA+mgicL&3 z#~O|1Shb$MH!8bNZEp5Q2hF+=1ySMF-jf?EDWQhZ8z*E|t>e_K1pOWW{Td)mRVt?d z1vC>*g}C~?;7~#@!<&a;$ZIIHJGzWT{1k{Wx1E_L+7csHeL&}OIh_m%0UtH(9~Dcyx(QApAK-##Nt~*k zsw~Rq)VO0)U}!K<2sSa5rx-EtG=VaS{k@+tNRXnlE}3UZ#_yD-N(_wGIaW%^96 zhp^SJuExlh)!rr08ODn;Rp`w(B?zo;iZ}?4eURBZH;4SGsUuR;SZQT~P+k?asWV=| z?79DXHEOSk+f2G{oXcy9E4ePl))WceFw<85@mv@R{N8k&j{KOJc&oxk5|`%CZ+B zX?0i^r(#^5-S8c_HoTm=myz0)q>W9j4rxQ?GKycI{Y(e_y1!c2c`5xbaDqP9+Ofu6 zz~JRDXjJaz&lcVcgDv(@s)wH+9CBU4Xk(Z!jZE9|*)Co-x4UxR# z3en;DQx(_3`787YS7Y?0>vwu}=_RvtY}QyIPMFi}P1QARr8ORFhPFKOPG;KP?X8%- zL#F1J`ltLgW6O08t&+Dc?ewR>#Ra{^b6K{FY$EsYRYAeY1nj#*U5ckfumhzto0eSq zc;}Y1=-AYvgWL*Ai%r|m*_Vt3^z^S|g7uxF(>Ggao%joOy)*Z%I5kYQwQs9}CE*&o zoj#?mT7^}WBBKl}Q){?+;3RO>jkqEZsJ>uWfN9FNz1L7Cw${n2*7n-sy|mp@8!RrW z4iCgzs>L5|zeP_CRl1h*SN%#138MAp4^`I~9h)1v=Ayd1bkTmS%un%<`BQf$R3P6I zc%A`ReyV#?lAEVwM(4KBcXUr^dJ_6mSJCJAmR5EAUT`Od(H<^+jwn)^5+_I@la<$C zD%JRd5u7=Bt;IE$n*EM_abiG{hSO1#SSB|$dQuME%*gP7-6Hq)cUXiHQ)ArOkYCyTwL1HE2*)A9X4n)+d#?z zpN&gqHP5(0*{iGbY!HG6pzBgKZ7fM!9ZKs4quChLX*Q2d-Fhp|JUm)cXtAG}T~bMp z`}C=S8*Ugld6gloXR3!afEAub4!jsEI0{~!3#ynS3cu)Ln>(N%*` z1F%fSY&PpMwis)!y*Jkr)I{`-4%N3nlt90Td2N_iP(5%Kj3e&gDT<_>hXul;AEosT z%s#KD+bZTh2Kj-{5YOd0d{iE0EY}DA@Hpmv%))bEB`SY-6oW@m;8LrcQ5|e(DGO7x zEE1^0s(t1yM6`mlM6eUrqf&eCenlvk%?F<}~hS#_OJXlO{&XXM;#(|WmgHPZ1P zEwVt3Rhz!jx_r&cRHmf^vJ^OdPtZVL1|0aKF8~hi-`hErQV1kGDim0c=Y0@Jz$*&! z)ss&@wyUkptF$&X33n>fuKF@6@9HvF>GWm(j^(HS`K6(u%Gx0+ej>QLI9bVz8Ap?B zsAEf%qYzWgIfeXC?l*3VGMNpHS6_l7R*wZZ8|z&=7X zMnP9<|``K0ADu1cYXp+kORi%>2XsWHP0fwhn zJ88x0FD_6B!DSRAf<#v0>^J$@sz5-iu}Ml@omT6(VuBeAA;&nJOhXu>Roe*qUS=Cr zt55S*AFVuJim*Q#;t%Vj#uc4R-`BOri>r^wd;iK(`IJF^EYy@6_- z&WA7(C!G=7IOQb9=t+zYUp(5ulK^f+Gu)}!!nU`Yd^%lqpw|+xBkwU`4;u`0+!k?R z>;OGSKZ&tUF8_Qt+ChJaSKg3v3xEsvi&H6KI1#K3r6ydCVS$aNf_iOy%HwX0)C9Ep zActaxbs{s){k?*J#n0)G8Hbk#3H>o(2#Y(hqM6*wb9M)CB6L8G3wBK^%XOrjK9uk8}7Zc9VG(8K1|Ys@0or^8hGfV5U} zI)PZPz@v z@mRXc-MtxOS-J7V0~Sj6TZ+HvH58?%<*vvkGC*4&q%;Z!}%`almisHQ$Q<>0h%!Vm^{;*IM# zq~0pycOBVt_(&?Lp`JVS%v*N_i-gw*!Kke5r=J}+Xo?o^%Y9L&o>GF&>@aejJW4Tu z4tgCwQRh!I@H|Z6-N4#%8v4xnRe+GmWO6^5naO=EgTuM}N!bB#b3M1jPmt8}Bj(|! zM`zD(W_!-xi=I5Q#n1A1W=m521@0vTgIL2K#EB2zuj<1`De)EI_zAZ3+G~27End8P zZo>G(AIh{tV0Yd%Iz|mnS4a7^H=VH2ErnS*A9-|9EOX6~_deBVP4(k=*o-J{%`8EC zafh789_$3GDfc+qWX)dDKBHK@!glSpwAI{GZK*jnGl8dfmL~grP}?n^H|+xx1`+)WYQqik>|TK6e9R5BD<)I<9a& z1a@=F$-&M))5FP#-HQF2&)fi9G;z%MvsL_+i1(I#XzzQr^-xV^I4ql)fkj;7=QLGT zLxaJ1cy{W5jv7(5R%yRNMvMK}i__+=*{Y&F;kwY+ z(rlk-4%LPC6jjZ3nWurRzj*Xim)9BKINN!9pbX{(Ak_JlCnV3O~QRRrq$EegPaa0)IpPNkE7(Lvj02k zO8j}ZBCA2j`%)KHOCjsDzVv7GioUS)bGphmL$R<94z&9J{Ks1`O0yM+_N+mY$`nMS7>(45iyqgK)0 zs{J(N=Ad|s_^|kG$sye)J*V^OmUR#5p4NRw@6bo|ZTemMyY(N@|3sGL8TnoEIYXD> zLBkV<|7WZ)9x;Bx__9edc})$bEv9ADm&_XTnE5^Cf3nyt_gbE_eBUZtQ`SD~ZPv%F zui0vCyKV2Veb+A9qxLQKd+pzHxEu+`5?-eqXB=O3{9ng8XQgwKGvmC<`CjMeoqy~6 zPgk{T#I@l1E7vdGE_cE`=sw|o(qr}P^L)ee1J5suG)3h_!$tTui7Hc|PtOfc8+KaS zeoHLEFI0+L^Z^f46n>7JKfcGJQjfR&Uj6{ zdIuTAJB9llf{b>4Z!i;VdZ2-xRPwc{S12r<8LUGx1tP_F#80l zf|Z-WShJ8NW?tg0VM~DBM|R-t1{|Y!6Z$F%FfAE^UtWpQhq9DLi5G39xE>(CA!%w@ z{VM$>a%#UJgF*=z;P(sdL+Y4m(B%e<+ehqb+c&Y^r-&KZW`ehwo<$qz0$LN4d(d|r z>zwBEsdMLH89`ew-e2c^@gCqf1MVLeu6L<;cab_yH{inQRmW)qdZlnLbx|3{7{Vn$ z@}SI%n84MJiH|QT$LO&tp8n07|vnt;k%5TX3yaMo%xc!LYgSw zb?bjO67m}>`Sri8-5A@AZ&7s;MJW@M)n;(>HS&9fkaz9i$qD}SJ^>7XK$Sk+gC~w` zf?8_GzoTqMy9T>@1J07SlAYulay@y7JVLVMN!r9x?Cb0s><8>+;je`c2p<$45FQdf zDx48Mp*WRdrEGN-Gbk9@fh_mJWh1}F{+4}@{YZGvMI#>;9#I@hky5(4y86@ApRB&R z`pW8$SAVqn^y=qU|Ig}~)%slR`467I@BH28?>hIrbKgDpopb+i?!|N8I`_?UFTAq! z%KR%kRM@fTU;dXRVI@npWO`>6W#~y_9v{kzlXIDD+?%bLo!_mT-jd0(>V>Ct*s4oQ z{zb3PmnE}VlJ@sJidEC|-H|K}XO;Qgkt_@QeSTjgD}DJ5(4qmo`&&T7U^J&ODcrpfwtmHPPIN6jwUU8)A6I(Or z>^+@PvSVYo)j8``vdz5KJUgqbY z$-I{2wdA~aes*@&3u7^{0$YjY7@9e|1cPLxVYvn@=Pg=K(bO@B&!cA99lEb(vU@T0lb~_v%JfE zj|#0EepGKJ>E7---@4!!!j}q?F+U3p0faPApI3TM`xiJS!)<5C`#6n z9^{yz0uE)Z{AvPMR+V2iOk`DwqJRcV06c3;&nu_rm8=b9i)8KLp{dM@X1Qm!Dr?&1 zKNZP3!b9Vkp~?JBuMhVf>V0Q;h1kjYn{)JVQY2B18?U;u#!g)4+O{2+2VOWGer zXsgPDD@^c}&fcj^*6#0Cdb4JTp9vd#zFV1pqNs=>N$Vip-QAo5PPEa56{jwgy(8qU zgm}Awqbn52dcrG|mqnmAFN?z~0xwI#D;i#U!z)@|mWEeEUY3PdBwm(>S9H9r2(RdQ z8480MdHQF?c~IJ~)Mx2-zFQ*M@I{U8^~NLl#>hpDf%V3t`9>v7vX;-f|6~t{V=TL=jna3nt=BCqtNpE#Qizdvh}q4 zn^)r0#c@r79zfuaj+w`1S!j-AQ{j3~TO`~3=ek0$m(aZhEF$h|rC#ahDgmS&IDNX` z-wzd(f#HMJg+*$n)a3+)TcNw$Sr58tpiZmRZYxI8oi(IGyH3~p6{YPo=G<^;H>Ey5 zUsm*Yuk}{4^IWHNj%Utl6s_Vts|jdJX1lqjm7%n;J|OV-&1Xe$`_k=-okc@=tE5TK zFZ;7v7*!}cO?ttL`ur^P!{uWZ02=hazi*-0>&FUxz!QbK3g-JGivSR=l0_&HFhdK0 zg9W(^63n>3trZ7Cz-K{|URVpl(zZqm1rTTh1zPyqK&FlBO<5VrL{a+u{d`f*#rCx} z6`4Gxvt%k$ue8CSbLd(ACMI2HMOLiF)c~5-eV05F-z<6a{sOn4`6JnmwbfMW7uYq= z9h}QiUSn}5^hZ6XVqeyi&Ww3sQ4Ono zqt-~63v_lf$UGW;l#o7D#!#WWG9G@Es&^((QSVIhKK*E#;(d5!3-7}#)4UI_%!JQE z8>Ugqpa$EH+H4q)SE#i))bjVX@_v-JZsYyb+IHSgt?l6b)Y?wIW-q$U^EG*8fv?Fc zi+oL9S>k;*p|Z^T@X9XUhgWv93Ky>( zP~qaWgDPCSb_g_XTW8>5^(xzmh9miE7pg}&(RsIQH?EGs)}qS$9M4yIpA%{y-oX2u z#NdtVvtFfMsUuG1t9-=O`6};z4d&UHpYqy#m3O!O&HmppYP^;m3Mf1zREk?g1#N=^Swj8Qs=uhU*+B3nXmHhw_#*Qe!koDRo>xr zzREk?5q{L5dbU~7`>2Kqy$G6M%VxVnS>3LzP&IaH&7emJ0>I}d;7-!JVe9fC-{BP^ zb)T(43{b~wk9l<#e9FCHHn`4aOWV(UC3T5$Q$u`J-!|E=VorgiPYN6Jo_<()fX^YAzheZ0ly8g ziyQ!CL#R)oo&%0kCvmP57-<84!k^y`@1k(6wq+UTh%rG z)LfCvX8Y4CU*3CKg^AOK!=R8RtlNZqjskd&lih&t1j<9ea-Rw#r}Ig*S2KFXK=D6E zu}gWusr}#O24AaG-B{@=%yd+pDc@s1 zdU82Fi2nIiPoU1_@F>P}$oQ(0knv%Zqu4jR@5QhUUor#d&>xoy4%-FDE?rjvR44J? zr^@sqKKZH_XtSWM*hR)saz3_VF1~M%1D;kq1Kj}VmjLlTTpvfh9&bL^8nqh$c^@$N zpNwI7C52zNh~{gTeO`xad>aQEMuRLWey;{eJU!qu;6%p+y=B3-pKLg(a3KHb!YQu@ z`mz{Lvv~1@P8oEZf^R_j@y(QK{DwmiGFyui&k*!V1kg8N7dK(u81zPhByqae4Bga< z9oB}-XFK$N7tYOkNH4JKC!4^fK}g6jH17y79s|85z`H4e{5nqOGh`OuUEPZBzae9a z-0t1v?c|@xOH?4=Bd_9XD)^!X`62lcd6|44d1#61s2)#K8Sn(SiJI~22UcpsZ%~~j zkCP|J=g4EyiG%wZ8@n3S5?^A^m+6*5*;OdJwfzeR4lJlwv6i@YYVWS&3*zv?fyLzo rmf6R~_Gu^g?LmhvhmY;sf9Rkvws)T}c5GjMKo@>bh|`xM-)s5*)si;6 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..31b84829b42edae20d0148eeec0d922dad2108c4 GIT binary patch literal 12316 zcmY*ZYjcwbulTEV8$@`t}$2ry4J=0ZF)l+l# zpT26!T|rzN00Q_HCOiPbe|MS7|EvEu|NlinnUMtmARGL)Du2U3tT8;o*w)Yi03gTu z)*Ar;5HJBcJxF6W7a{x9Ft`2on*;zLx&QzKI3tFCKIVqb-?2<+ z-#$?P3nX(JPqXiJL;(Pzx$kF}-5}`Z7N&+K001f5w-3jEFq#owv-mcC=Th{o6MlmX z;syA_!q&y(+t21Zp6eUe@7TDhHulEfek9*I;O#%q3=_K98hU)cm*l^kiT(o!BSM^= zp{?n6&N|<5#Q*?Up7GLe9S3`77XW|}?A!Lu3`l^!gY1Zdlj(OXUD$VA+BX_Z`$0oI z)|jfCMS4MbqPtJrX>HU7Kz77vT9+W%9Q%sHF^?#yVi6AVJVXl z-;%?+3k~e0qQknqT*k=JMcfHe^lphUw?@FYwL#43yHlh!H!V2hU)iIt7C3VG{ZM`n zuC>lH-?X>^TlRrjyH>v;5$Q1%xJd3XRT#)|k8bM=`S1y!-rnpESowWYY^{_7Q1O< zh29LgOFxY10>PiqG;&Xh^CLVB)$~hna!3=JSRZTf)LRoVHa1a*D-x!qi>%b+%T1GfWKU`8 zk-aOT=Z5BoG~{a~JU)CG5IsLWY93UTSt+x}IH-pTx$|{@d_`nEq%42E*x3H^efB#Z zgciSwlHjF|7<&7pqc?z7p@}lZ%2%U4@n_**&bEv>XNWPXrxKkIb*Grql;3kkXoPC5gq)=Ar!V*t(IKMtUraZmN^l3_p;+~W`5YMvl}oPcyFIjCs2c-zhF&sq za6P!$V7b0PWgq=z?u8esctZT=yPj1rEY*=Mxu#FSAdW=B{$TCG2RC&vLnTwjd z5RMA`eIyoE+0VP2H0jmZ_#|_q(+9m$9G)6Dxvlgjm7uhmM7eDDx)~m`{iqoZiL^u{wTK z?_#^-OM~IuT5gn%FgLj^{Vo>Si!4>`6vO@6PnzgN1c#<;CkP~Wf6Qi@^f9x?3_8+{ zSil^})Ki4{X&dDz+;)i<-??p|OYcF#+RxEFxcY`jKB(Xh%h)gU8793|iCiIliGw7> zi9AP*5S?KdbLf)}jNy3BDo12xSogA7xP;T){IN5-4_N&n%+J3ssvo>NXT9#iLR24- z6~d@xtv+z*ystY*FhVjKg_9!5ex=SeWf09x!m2*oLg2F9IRKM4`R4R0(n^46?Taw1Ua4 zonFj2OX)(mtVAomg6xy9*Ap>{N;Kog0>-0DDrZ~sp3b9)vzYWqUY4c<-YgEJihHjN z9f8`En)3NM^laCIujiQu{ENyP+_0{8=qJ~$_u(FfS|XM1=ML}A1dZQfaJ{H$9gs4; z3qn-J)=Tp}4jkE2qP8#71YOOMEA|XNr)mI+f{B2ZcD&YyPoK}=lK@2!C}}y5Y=uGz zYGAE$B@&q=TW_Kq>VqCe$)jofQ6w`cLbQAHla;J$oNc>a_86XMOxLQ(;le!-5ludZ zqG4-E>eXh(XvUuw&vCOL1k%pALZr~B%CAW`BzY}9MTKKNIy`X|B6lF+(GYK{-MUpS zVKDxhViAkWmtu6J^;Ptw0JfbzFEi!+OZu3v?iw;Q91sa*aeFxAm_|Xy7hjmUT*|*M zYGfxFLA1-oDMDS{E-i6?6;wFwpMAkQH6;2V#;%H|5r}~`al`|4z=-Lq!*WUfV zcSH;r&h0#4*b572LF%k;S>3Pmz0lI0x8{E0wvZ#WoRe%iAXxhCwf)|L$3M3ySy|H2 zqB_PjF`_ytu|h2@<@=KGg=8WsY&`^RU<`)fC6>@Y7mkAjpN%mo9i~tOd1G~;o?kv? zPMgIfqMnq=M`L?>-v&_9g&l^i7r*hHvrWkN!b)W(7q0C615Q+jfg`1eN@aezP=%E} z%JkZ%x-@K(I@`e*7hyRxxuHrYm@=o)vwvGipoo;?3q6*KT+d?66l8tgw-P}JfOmMG zb*_|INKMO^ajDQ;5>p-Q3O*L4Y&E&;3ExLdJN1JT!7|ospZR9abdbwGI0;H}RE}VW zz&3(29npU0Q+81CmHN}B+?W(w87V=jKK#yNyrm0s&lyW!fg8rd;bWIOeQJ6? zbJy_fpW!DJDI4G9_$k}DR=TTC%WbYMeM64@`+;&6Fg~La``}*FW=OFj`Ft3A-O4`d z@6Y<<3M`u3=Z(~(-Ds&aEbLzu7CT@`^Mp}w1P)6^UyiZ89x0xZ@DZmeL&4f{Txr5| z+2>vpZt4;gTTimOG`92+IkbDhALIwwsvY~eVaz!`m4_Q`#~JXsiy1Ef&>a_jhV-+` zNwOXF)SC`biCX;C!YMFz6Kmy~!8(3LxXMPXj!}0vh5P`)y1z%5V2OPEZPK`kk#4p9}*#oyTrkPn6ix5kP1`6hg9ea7rS)b;RZ8C?#5Y5N7 zA!J0d%9Be~=W` zV&R`_t_y}R0L4;(4{I!ZU#CQL-qUISdUc7L>2uqr#fRQ*^jTZ|#2L{>Xt2ir7}qZ)L~ieMGlDx!dee z598RDMXT=5nrnaYz7s+%m|qyzZSy|7u*H|)gPH-GM_&kpqaZx)4$ zBBg4EiwlbUf(;&li6wqy7R^<28{mww74_tJ??T!4wBcr}S8fWnR8x$0tFlm7Tmpz0 zcWABaKlAmV@Q<~I+APhtJ2gFGiL*A`$Pn6e-BrJ-mgnK|_GP4oYD~3mpT%yvVhggy z>sRGeD2G^0N>+4x`k4ON79hzB!_5X6<}}0!==D(HNbRn%C~8+Q1DQn!2!aw>T>d zYrcBR`Cw~MqsG4uhh>6R;BE|)y|EqRn->$6V?{{UqHzyxHnu`Yqfd}5E_X2=?5lTp z_aAE*R~R=ffrQCFGWuFrKaRI2Hl^lfSBr1uTOpa7$um67gmiyu%^g^xeYm<4wx8us zoR~mKv(?YCe_Wsq|12cYu=hj!Sr(;_Ep&gx?2sT^Ixb*@V}0WhdN8;pACxs=42gf! zC6$w#uDR=cL2TT$)0;*#bFkw1ly^~+j7-_Dk(X@`vau!5<+%IwB>ILf+X~Gu#yzc? zOa__R!}KYw-GlyG8Y=)j5FDG!9hj35XfOW{K~1_*g-^!oh|U%~$M3_D33i79)sI8< z)d>1P_3{_IM_1}4;yyJk?oM{WxU=O?4kG3dwJ7%U>Rq?vw+H&9(JPS*Y4k! zxilX}F?R|o18{_)cLyV|GkL7R_JQrJKL&@K)f^xHk>!ZoWH)-@Wv`{@^-jmu_9^(j zQX`6zd@K$*4`oEV=wBKE&KW?jcTN0;~`K}p$O*=EFfOMD$~ zH1(7M;doG=bQE9b`7Nx?NnqT2;k)Oj1IZS4d-@MfVYy&hj2W#EcxnIsLGcM2+N(9X z4W0BnHtSqg2o?Xm-B&ruF#Oa)t4mOOaqGdBro<0>J01AYTrgOL$J<2q>f8T;@#Y_1 zv=$)384|eSt06MVO(0j5JL(#xulzbRRJzF~8LQ)U@5m{6zYH zCT>)y79MT=(!Eyi^jozyD~Usm@Ceh)9P@Re8z~Iw#Z8CvY&n!eOyv~_?Gn5L(#Fa4 zOWPOL^x)14HcrA{YOFY5u4lfGiofY0sEw`_dYQuC>5z^c(yZ+WKLx{QTU$-cx95< zX^A=zL#~%YT+p*EdyMK3otynU5?affK3RxmwVltEn4#ccU>|uE1L81-sQr?Y_e(zD z2H)a>H*E5tmFq3FGvp0Shd~@P_XxTdc!%!2f(AnE~V>yCK9aINf zZqhdWAb|(v`dWmYJ>r-pftx+)dSziC;cI=%GBo{Q#wd_$|Xt9XN?>|4CQYP27 zG-_id)m+%LpO+2*N>!F+-in3*jsOtX@OU)`hyh5ApI- zoVdtN%1rmH{sx^<2F>vufh?<#Q>YwkqWp!OEQ-i^-%w_(2pJQ$WiX4R=vnQg+^EqH=eTOqe$mTnc5DRK?Nut=q%4fiya0g(7~Y^rT_vND6Hb z(*!6T18c!!mEb?<%tlxopCL{93*H?|2+Hm~c2S2B6vh5fB}8vSAOiQ<9qRQnWH!EV zqb&l3vh`o^NCTaN(FJ@Rw{w?+hgu5eF0+1T6_HTeI1fDP?HTol;ohuR9ms|EVJ&4R z4=>O9zgabt1fp_GSS5xla$A1Zz$-m`JUpDP@|Icxy9`b6vjNJ09-ak6d!K`7Ou~s~ zJN(sOyS?61LliDY(W7@L1v|X;5QMxB%dP#FquS6Ea3wDcvb7Kk3%0U!!lTxPd{9SC zqBIE~WMeYH=5d2I${|cV!%XNPoqUB%h9F@%^ z4bPGDE*HFxe8tDo6~4%Iv_P4$h4gbp#vIkZ`o#uNFxZ0kX}? zW;6dBX>P)D#Ia?ho16onLZnWC&IVC5dlT~gdC!*S-y68^e^6I2j6pKJ>;b#^&A2Zh ziWy_RruOtP8Qdyq z!0gl_tf+Habx9)g2VF>QI=(^=Q%bTYWa~=0tF&z=+QKh1HSgYGqS{cO+?SfaKz4`A z4{^_)BF4CpK+GOPT-lYawAn~>=qfHaB5%hhd~nLTiz=g5%)+q&7_4s?CskDg_`FAc z2knFY;QW2(4Rx?0Ug6P=44`s&$wMJ36@vP^HCjKLnC%!IvisoK4TXgUF>=(XquN|2gal*U zlhX&~dBukgjpl8IQ{UnQ%3#a!q=rUs9&AK7_FDuuQ)wqk0WW&xk*rdLbs*~;!Fxy} zb;394p$)t-BhX#sYFhNSy-3bljk`Xk1Dkwh1*slxa=#8AoIc4G-efRx z<3+)%-rdAMdi_@&(usbWBKQq(X!YCc@L(&yeG*9Fakm_Ix|UX^;M$2N<){X>QO80n zZ&><*7@YPVXgqb<&MtzLNmY_ZH~beSRrUu2i~JD{ggkP1r`A-HT&t?Ke;y~Qp{~dI zd8_UNDL<0L7LQ1KaLN5N_mSF$gYasQGk_#UbHyVZA)x`eH%4=%N8sXfrfTd5E06mZk`+fm{-C5=$HYEO|DQqnk| zoa9^Be>0b}eT}D?j{e+tcNv#|GAl+u)xY)TW@uyIUK`|r46RSxpPZZIvOtV{0ULl$ z6w|rtDeg7OCTzFMPVXEF_OU2!pR=%H!8uy2kg;~ZX#|s#xUW)VMMW2vPVnmQ*WBD_^6Z%!pbBM2d0lX=Zu)n6Gt3jd_XZ-?>uz`0eX_gn zyCPj@DJ_Q19ehO#ptn5i9Y}D@_TC-v=KgLBMuxfi9I(rHOXBZakue(A^ zFTk$B-&qCh;{BtCze2_=I9u0{ZdC6=Ylr=MK1k{$F60g(#y~=iiqjAh{@{#67ct!l z6roV3gDxa<&qzzKw|Y9AM2CIA`$t8OcjYebBdMZg(uJ7C*V5EP!7{@-4)Uua#*OM~ zeCs(KC*=`{c@0g;A?+<3MfXP2(nRs0!m!?`-}8mA#uwH!hZyz+FGXc3r;E+hXyy=q?+Fy#8 z`iw1Y7*G5n5lPRNX9ZiHL3$cPxE{}qd@IA(vhhDwy5$ELi+epLUHO!Yd7aC750@A5 z#?ECOcK__47wuyh#c+>XGWl$LnL8i*6zb^&Xsliunxy5c@Zd#d(u-B>F(1Zz3I&*1 z>-Z);pIu@6ouz$Chg;yIj^;z4>=hPjR%U88kAf(!)lWI>_a?C8QoY^~27`jWjJp=8Fc-)lWm2!D+(%b?c*xBB@g~Y`t19^7U2JG*w5&@cV{6X%TXON2cI|~@=4xH zdAb+8%ap`#Wja4(_AZH;RchMceT*hQ*#!cB=J?!8<<6J0ZGPnRhmAFb<@n_{$@nYm zy0R7jJ`AyJU z8AqUzTus=}db>v6T#Zd@tnVz3*6fajh2K!iy!7ue0dSerak)K0ij<{$-Ms$lz#~^% z2e_jMwzI|!X;j)nq%C0U*qHxHl@Es?Z@IbYY_We6kVG1n>AEXiZJ%M&#M!^ z&#AF7$pbP6LN-Q(V-iWt2Qu<@;`V1$+}5qAXl>RKGy@yy5Y5f5v$g%@=o2J;Y81zr ze4n6{_sak|3u||s=>P{=3rneDM#BnYKT;}3GASxoMaUBuC)eA5Hy}ao<=j#_;M=h7 zTdE#Euxge87JxJm@%-R87KIOBn-L!i!4dxwt&8*9;4~L0&WoV`E^-tz0MY zXX|?e?(c%Wn{2aKX z^ZZmuyOChpLHN)C)Xl7TGMX>+A^|sA!#6{m7sFtMu~@(V4HZlQ1JYKBaH;hXn zZ5fmn=?bR=Bs7rrhszcm4thp@^Ab-m)i%FMx&)=}iI`9dH_3F(WjDODCv%S8Mt@bx zVDKli<7QTa=bA@|H>OZGq?2#$EX^C#6ELMkrMW+N$LCbN+$3QV>to7oUviVQ;5`OTlyFcj$enQPPX z|K^z1B`#g$$pURYr`Xc&z9cf1F2U(@c8tx|jK#X=|5I?7~ zITd>8gIQJ_xwfBMnZsl@yHbI;`K2V)IIQjC-7x=5@8(O(Yt&XpX-DX2qZc?QAbB?{ZM6Laqn6me%Mo8QFYjDh!c-1C~k-QT|KghW5xu%u|$&Sl)ap$_* zi@L&<3(4tgi5?}Y(BN@9kdkmVuJZY_Fm?Kp(Z|WU6039$Yj{B4&whNkKN2UW1j6jp^xoz2eoC+)VhXOp%GpG>sAOh@ z0-=36-N&C)|C;i1K!N7&Zp^UO*4DwfRW%r&j<(S>xx|LH_ufsKe1gI}-27fv<~aBp zo(koSt`$uK`&aQr(oAxltreL6l1VK`_WeZlo#}brLIuMzQlRy^>hpYFI#C`MPIJ7? zPlTS|-mL9=9<<<7WGYek6Sl;D^4w(2V>VxKIR!FKFywFe7NC{C&o!6jtGzr*PC8C^ zYu!|oaIOId7+lGY)j`DUj3E*0GpTepNP@1TKCd5gzh(w;u~P*ZB!QKq%yVqeHLM@! z{-SdyCY8hZgs_FH>+>3@aZC|+`>@Pv5kbhCA&l6nNw+CeXxQ{>`2@iC-u4Cfx|r^h zPg42Sf zg;Aca9or+ZIg*lS3(pG#2NzdEOu3BxJh`7=ateV!Sn`OwH8qscZCClh=d?(Sa4MUE zFa`slb!!oT{L(aFH*fpn_?%M*qfGSZik`!{dp{9>kunfteN^Nxc!(Qym7fu#S?ZhP z&+UhH;Tg7gmyD$jm)+7KbxdY+P*4nZ06qf!iX1;Vo+R@=mjN03=c*TqDPB}qDLzWe z=Yf%xIdzkQR=t{0m)QR|qb~FDk*7YaQ<;*HhMA(n+rEhL1wxOhuNeoHDTvx)-;>6! zMnSpf_30Z{DF-Kc47kxn;5iHc7k+x1N#ly0s&n`QpAQi~87{urJNr*&1`U7lFV8*Y zx76ZN+*`Tx0}W#sKbi%xzgHBksiR%QA;Dyx0YmMkW>?*w!c~|uMS`TFdSgTJ&X*rwulm3*^iIACjPJ$2N2S*6!2v-ib1rG_23(p9z3U31c2LTM>Cqg2^HX<@&I$}TK8WIc= zCzAMgeX0fN8kri|3^^Ei2?YX$1w|Dl9c3C79hDu`_}fG42W-!`cKVefn5u`c%$Xz`?o$N%yvxWQ4%w9#Vg zz2;#!Jv@=sT|7iRX=xdzop$A%Teh+d5YT!#@jemsYyc1WxL=t;P*FNo+9iBNR?~suFN(vb_wr#!+$f2gV9#z`@ zLLmcB4^$a~nV>dp6IEUkM(90szU(@={_tgGA4 z$fEWVCN3r_s!)Bd?KLnSg+N!5Hi^Z^Q+TJQQ#UaR96a(&zV@Ix-@{As|S; zU$T^=b}87IQQn6!$O>_`8^=5w&)_`0K60x;cYNO+L~y+i&K*6ixZ40SVF5<{A|iOr zQ4!?v*=R#q<27^%=q9O77m*j8nW@d;?9C}(zERSBYCjYc2%)$TxWl~NT<5@+vxw`q z>r`j|&>;~Y^4UqftD&5$F@me;FrE(XVN9ma-mDndqL>K*+9D$S% zqP-t@vsWgd0RIa4`0t#n)K_7YEprsY1z315xbo7SWpGs76x*Y(_3<je3ZIP+Z z*(uFfPo8xv_zxst@K_leUMN$hPRub|;BVJ!Y+zU8T;t~zyYQM8%5sDoO$fsAum|$v z(@{-sXe@aFHoFAc*~VK%cR9wW zJO2Pk9m}E1C029-vrOOVJm<>=kZ>KrxY~|Fi$Gf7@6W+&^@7Z>zyhRf_Ui2NSML@@M zv;durr!g}W#%?9NOJ%OStC&$!+w0P57xKI~yP)>KSc|4Iq{~c42O$u3UgEGMk`i?-FewrHJyB*rPrwZ;MaCzK< zREF6}ic6q~>W3mGcytBY>`A;~{0mhib+tiAh=(kBdsgU`#Xz5&DH3Gw0b_c#eh~JS-5ybQl_67!On)$reGrg45ei$-*8C(ed!7pHp4cw#~b}8*8y; zd{5RnEe&#_*Ny@OB|A=hB&u6)oRcdj_Cc-Vn{XjTK%C8A=miOnEiMRoUIAk%n2YME zNqOQ&DRvNIOQnBu^Er0Q={!-6HbH%#hPZ{)@PCU(0z%%YRIDsr2L}rp)-df zoCx_{>|#JjE$z(;MsHc!UQAZs$I4rI8y_8eDj=W+kZUW-WXVYUF!(b+VDhNoMK3Qd zL!f{skRuf#zVu)oh<3CPl|$>BL+z2H_NfzI6YDNOiNmqvRIj(#1NFI~5$`<4S~#wu zk3=}zRpf`pli_?@Y_+N3IAX%g;8G8svf$fqy?^XyYmhJtCa!?VtJGX80?z`Df)P)Y5qb0^}| zu#%&kaHi5{xwXTh&7tHRdhkT%XrmeX-h?LE`Nt%eQ$^Z3mC~)s#6P+X6nbn|TXs?e zf0s~`PxU&5KLeaGoN9-xrG*1EHwSUocUas(2~&QHvskN~Zr9{CT&HQ5R$T|ztBY9# z!#=A*bD}Y%81WKEx_4EqEP%unS#_)Ba24#~R6`BR?IC%jc0 zx5F|&C1@3att@()LdIVqKN*Sca$!>;O1H|d_9@&cwvnK#cerT@qlXN>bh+*hwsY$Q z)SspQ(Cu1-k zRR_Ac)$C}!+3ff-)MOjSqe|TPbNgc00x9q@dqfDDil`XnNrk(KQs=L z6tJYg2r6HWy&6TCh9*KGQ!(5!MSd19+cIamNyuEwBpW}1JlNlK8CneuRL!yj-I|R^ z4!CUD3vmH^RUwz0)}oPXsZCyj&-0_xrG%enK_L4~DAv)}2^7&b$y$woTRUk4&jq*n z{FH25W;09Je!42Yje8{>H=$UM>7JWq_M|N+NB_)ee;3Eg0m$FB)WWQ}jZZprlYfFZ z`yi3cijb2BIWrrGX`7jF)Xj4L0q^yR!2dPNeXxt_bqmh_8UvI3Y??`1PV@2p&?@pP zVds(LKB*!fpwDC-}_i*-U{Sr7@2b)(zuJ_pdBg=~0SNFj5a%Q&e+mg#KB|G)>i zX3*jgj0#hjyiea6~%=9REJLT7zZ8h^O$=sy}TL(EhyU1}Tc$f*z10u7J4 zbEVU;+5A{+VMCUDQ0;*He%iS2vqdjF8Bv@iD-f7Sg_IjG3+E_wI><7S4l#z_GUn%G%b-FY?~WR7|ze8U7(nX!FAe=+k^8#L^g!VK%C zJtMl4)6>)2TjjBSK~dW8*yGV1&}ld}HAs9m7YgNPs7%pRN6|RpsOX3cTFNz~u$fsz z95huHjSoNlbp^7@3{z6DOCOKkwvp&l7jkZ>>XEsFQd(7L*A+j43*6>$T8Kvh!e)&vCQIGOZ)^Qt2mG(pDhwvUm66lhx9aS?nILUN+jH)Vn z7L%BHHu=?4ynHw&4ERg%{TVDc#ciKD^JhV0s%v&Zg=53B?oivx}%G%#2(Lm>v&^$-t3kiHwU&N=S)MPE`M?qNJv%s_Z^)X`bae?TM-5GG?l- z<2nW3y6HBe`?C4cD-z51Jg7Xw_tGx|U)%LOtbNn<(kGGY^E{-!^Y3=S{@2IT%rAPa zX3Ld)1|dJ2KEH`H$<4@BVRA|i>>-L?PD6x6Nd{%j z2gNy22_>C`B^{JSGmv#507e)#g4Ox{Aq~jFk`9buCC0&{2hqI~sQo4c1OW2&1wi~i DqysK0 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a90eea85f6f7bded69ff5d40114447a6d8b48cfe GIT binary patch literal 10344 zcmV-uD3{lFPew8T0RR9104Qhx4gdfE08C&204NXu0RR9100000000000000000000 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 GG{*pT{>~Tx literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Script-Regular.ttf b/docs/public/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fd679bf374af72f2a183b97b40c9c7e9e51fbe5e GIT binary patch literal 16648 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Script-Regular.woff b/docs/public/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..0e7da821eee0dd05a0a6f0b16c2c1345dc573a84 GIT binary patch literal 10588 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size1-Regular.ttf b/docs/public/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..871fd7d19d8658f64d8696ed9cdfc82c821ed76d GIT binary patch literal 12228 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c5a8462fbfe2c39a7c1857b9e296e62500a8a8a5 GIT binary patch literal 5468 zcmV-i6{G5RPew8T0RR9102N#S4gdfE059|a02KrP0RR9100000000000000000000 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 a^|k5z`r34UeQg~YeP3G~_EX$#+W!Ytlnjvo literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size2-Regular.woff b/docs/public/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..d241d9be2d317f7b39b401d96c8b18836acea0fa GIT binary patch literal 6188 zcmY*-Wmr^E*Y+6(7?70iZijA=W+(wk0YMlTS~>(q>268sE(N4Zy1PrdK^jF-K;Rvp z=lSt{_rC7ytaa}d`}UB~OWk`e#{P@sSU`2U{Jpa1p$+5bPD>+%W!0A3qP)kF~v zGf(-2a5Q%T0DN4OACF>RPDHl~;*AFb0Fch1{6{GMr>eD!jU&p;0su@@K0dAm&o$D< z+#Qum!Gemx`X32x9DJ++0Hg>2IAW+8_@PV_{kB%-mH>czfr=6NM~ffwi?%2cbrw`T zfF4B_>~|nPTSpIXl*WPb-B8SVa|#-Fa7LiwaR0^W{G$;}kJ!=N8`T&09m=OgkpXDM zA9XT!v_kdUMD@-C0Q3N}S-)BrXLk<(AP)clARnc(xRhi$xVTxNa!CzQ8WP1UzedSM z@8vxMjCU(Tbqgnt9F`KfjW_$^_)}<|prbsODe39-$!}w=Z^G^6KH7JQ`UxinfWyt4l!nK!=qM~h7r zCW1QJjz6U?x32rkgr6RZo8Ur@3sZuzs`i%rG@qWnI|~y}(!#h!WMWWS*@!oKzD6yB z+a}~X!E*Ka`F1|-(xi-ggYR#VWiXTFG*Hd(D#^pri#bh(p%#NFGp|?;2I20nDb%l* z8A!B0jp9!)y!ookAFp?RNwYuvvc%1$EJ!f7VGE!Zz z7;RS+D~RsBntPrb5pMUzM+M3`zkUg_iJ2vgZ70E4=~QI%!X{;nHJUF(bk=;6Y zbripTbq(eu)8~9Vcuwccr?<%9vNiEa+$cX!I7U6{UUS9aA-=j&IEc()M4xcFi>bmA1+YIQCMWjLzWfr*g(x9Gi`5Jly?pcDOh3|*{^ZYZeZ6n2 zIqSI_dCN`DxyY1}htDc?D`!_XFlw54wV;|s61HQB176>{bdEA5I#+)^k-DIp24A>_ zlT9zHl4|>L`5HmmSz8I}lE0m5YHwL^7568kx?-Ov&Twe#$%-W6Z|n+S-Ky7S{iTIy zFQEm3m*jb4N(v99LM(xU<_xB;1@>5hKk0e;BEQ&%R;=9kAr|bO+j5tVYnP| zkX=(;m=$R7`I8DMmnXvv{1#D3vRUZ4!-N;jG#r{iSavB`GHSO9Uy+P`s(yWG>=^Q@ z&Sgvnuf*El6!;RgQ_~m7&>L-2TyyEs>(u6GwY4;U@En)xGN)~ngf`^F@LCS&_+mX1 zI6(jS(wc?jEclsX&5@E6BU|}-guWZ&YEE-4hRrf1TS0G1kZoGcm%~i`%4wA%A|-m7 zczac11RX>kSFJ>+#k+sCLABwTuR>>7#}H*hfhW^|0M-Ecv5W$v9>43~5?6amS$Al5 z%v_|<6$4$HV9AEh5dT6_YPYgzkL*1N$>myI%;;a>sdLIS`c54IMyxbgv6NIY|R=&m; z+2sT#AQ1=)@pOrf{O&&^;dGw`V$zOo2JZb*Qe>>Y-0MoC9*+~ zLZ3Es@y1RUS1ws(!I4fa=2S{8rYg6)y4#Y_>_y^`fH|yd{F|{`ip2+`+>d-I zKE;HKkNJKVh|{xB+LE+gQW8!KGlofeiK);$XOjC6#A31BBfC6pgb&@-#<>qRz|UnD z00Iz)9C%%w9!J&PqYsN;)NbxbBmW&a9;*hi1Q^`Ee>Ubaed+kH~()pz0czvxYA zseIzo+9?&0su%ln{ZZ4k)2e$ybcOTM{bx#?MICJv4)S&m- z4Y8S=oXi-E=E;-x zCkh*e&SLDa!nVJc$iho|8zHMks;kR|r4xnSvV#g!yVFQ?0aH0`RzVsrWsFjIX&+uV zX~P(Xsn7QsZD(1mywp`1eMdXcH2DQA{!S$X2i}yu3rsE{_B-{U%Y`R3S-cGA=&jDZKFaMGHeXwLMTZc9W2 z5A)@U)$m8bgPiIIztRY-?|2%eyrwnBlnk*n7LKEo9J%9rb^1^kKW#+?W6F0z`xycw zs#Jj@hdlZf&W&C`!q;1_?1BPl=hZQM?C0QE4jE`{I>4(j-Tv2R>dHQk-+rV zp9pcYd&o$mD4AMWwBW!Zao7!hq?dJ3RSFs71~>#s}^{l$3<4j4)U4H!5s}A^I?< zT$_w^kLyV&p;4GQnVul{0vK*JK_V+4dw8> z^t6%u0$Q9Jc3^OS5@LNs&Dr6H#b!tdNx$Oj!MkaXudY7tbxyN5_=^T?U!;R1oWsa*FzPa+X$>Uz#WTr1z#V3J2Bak4fRFtv9$>A7QdnC0iF=H7zfC+Z_Ja*h z#otCi*~NO4>)qLZJ$OlpXnQXs;FfUs6#VOG*9d^74zDFwy!alV0?;vlQc%M+3Pk@~ z(traH0i**>zz|3pRE1j8XtZcDXwhhWU;u0eP6Gcx|Af(siNvhJ+=lQ%{2+0V97rXk z9de9CffbESf?f4U=21ARBIv)=Q^D*rBY64?AOL^+*XaMnU*f+7kTwi0l!gVM{dWg- z)<6C5J^($Y0~c3T1gy)^OUCfRdcnFH-qw8qsAPidKqX7KdknZby??hKocGBYUipUv z8V2pr2V-E>@tE^Lq7DQP`O@mXqG-gI7QD1omZlo81tP@hIu3O z54R7$?Dksg`^}Pedt&?JZg3gXRuym?bq#4WfALv-*2wTE?-KmL$6y~ocD=uuQT=ef(5$7 zyQbvxf&Pwj48YkhV)|6naQUu0eo{RPzbBsX{5GvzS>_hjY1^4V;kg;x;b<$#Bko}M`~ z$=QL3tCw`CPd9qrNqxP}d_G})0(Nptu#atXjWckU1621lNHvl^wSu#(ZlOLiAEgPY zUD3sw_ri-njd(wfFse*LtSQg~RUNjfo$|ka*KRYniN4yWZW}Cr>s&y;Q_xQ*6Sd8N zwX7WwMvMLm9aN7U?*WEHKPn57mts=)MUD}@ZHTBxub%3cbjKX3hWsK~&Z>o{rDScXVbF}Lbu=vKeHofmz6$#{)1mCum+07{P z*6ztGY>pyo^RrE6DsC?HTWcB`t*-evqKY6fKpM2z6Y#1hwtiV|o|1xe+1;k1u$xk+ z6k;bP*gTDg)-ZE4U@5nqIdT-F!z)-2rLij#F!Ap5pb$$&B5dfxiEhESQ_q1 zjaaBXNy}%X(^cg;Fqd3*aWP4F0>m9Iz5}?+6vQT4X_sS5?=rON)l@;-d9ZX>`EbJU z0Aj_=;H0DRoLrJ+>TU%Z@#I_@Xu0Uhede0F-OD20(wiu?zM}QtNyDnKO1s-3w0uP- zYZ?Q8UT1Yom8mkY82k17d~7Nj7dRU?X_(l9d@Wd~i{-1MA*+(1=buzxn(3*EL(Djm z_-BUWg+!Qn(b^}jgov!BgPkIe?q2P~?FhxkUkLp=eP#)X3!o;8R+wCtf(1o0&O82& zm!N5V<{15zZfY)m!*!MpqjeqCoIS@B62lBG&f2!ZM557Fu0w>+bJjcPdAVgkaiwLv zKQy$jJ_M8MVRL0WPr|%{mhvH+GMjkdBlC{G05eA*;;L8-du|bzYv*a?B-1-tPbr3X zP}VKP_4|vO3S#M0-H`abTrB!gyPm-xlPDW^3$dhCos56N46}0%%VTvEZc1hm@wT=h zm9G8%cx`a-Q6BaO4_zhqMEVm0WLnI#^sQ|V|!%choG@@3zN}KeA^tLKZf;JTMkNDg2%Ajp>PN5R*x=ogb&0V1#|L*%6x@$Tozxlf`3VRj+$RwGK9e!^=h871 z+H}&L0oS)`?wYbfk#rmh0Xy0sNoNk~EP-vMyKKJg39H8*>8rc|tBqfR$(IFI96JV%a9DcJC1Y4my4GG%Hx0a^_A*mn!ThL8Dsb!E zLHrxEr=^FLughOS$VWuV5}+L#z@Nd>FNT+v2TBrxb8&?cF6+&5@fQ~q{Hdo*NwYpg zAD>R&KUBx@D1j|3r@Qe^V8`Gh>W9sv=UZh?0uk=QJi{*Uc z`e!!Fg@UKE>G(e>7TMV^rj%N&_Y&%0K4WrC+U0SY1#NxfoIm%+s3J4nvs)OAjxd;W znZdqs&%Rx!@UY{5&WDIj1sgk3C+)5A|M*LXya%NG=frn5v5^zoJQ+Um?t;# z4$h}839<$8rSlGDN%?=g>2ahU| z4#agu;NjCgX7Gy|Rl+0mhd{tuKm~&ivQR?BmRuPOW{y@+cEeIfLl+UausenS-S`q% z?8QtRJZil_B7#Xy4kXiXLH=`(%c8~{{C~5K_i|+-hP{IviQ;54!M&^ZkQWNk`R1!@ zHsW?)*Ewwko)=$+R>pect4L8A#QoWpD!SJ zca_VUeWxI47VG?2M(3J`KqMvC_Po_zpyVbsi-Wg6Y{H*>GV+6As#)mAKXea5A1Jig znZuv|u%BsaD8CExS*@j(nf+?Ev#*(gc)_hTRe?J;yTj8YloNep51YrWZ{#R1IP5^$ z>OU7cbN>~Rz9Hs!RB{=V&|s{_t6+AcUx{#PaWHlLMPp`DiWt|oYFs>V>5wx?A#MF& zGkgV|%-?T&v-&K`FJbzyC$Os2U)^!S?d(+S+Dwlm_N2XNlk4cEd#dqd3tpek}xRYYUJNBwvb8Tj3Zp#|_ zo921N0XCAoWVH$m)XMD{G25d wY{_LX=H;XpKCoO0;vIG=&MNPm!DONaTgB3E>)@~e@w0#9F9-lVJOBj$2Tjs3JOBUy literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e1bccfe2403a4ed770c1697ae7c15b9e1cd9bc4e GIT binary patch literal 5208 zcmV-e6sPNVPew8T0RR9102EjN4gdfE04)>%02BcL0RR9100000000000000000000 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 CPy?p` literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size3-Regular.woff b/docs/public/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..e6e9b658dcf1cd031ac82b6b8f312444c55d4fc0 GIT binary patch literal 4420 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size4-Regular.ttf b/docs/public/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..74f08921f00f71f413ca42c9d1c90202e672ef38 GIT binary patch literal 10364 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Size4-Regular.woff b/docs/public/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..e1ec5457664f438ce5a1cc6dd8409bf60ca7804b GIT binary patch literal 5980 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 literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf b/docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c83252c5714c71a3e0ec62195884167339a0129b GIT binary patch literal 27556 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 MzaRX}iWL5T03x1QQ2+n{ literal 0 HcmV?d00001 diff --git a/docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff b/docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..2432419f28936aff53ddfa2a732d027e6a6648fd GIT binary patch literal 16028 zcmY*W81cE+qS*2ooqJA$@`t}$2ry4J>7Rrb@xp5kLj8& z4+U{?01)6u__G1<|J63d|Cj&Q{{KZmg@G9WV3GaNs{FuEOeSW)#Lmd^N0uC zTO6m;#NCw;0N{!L;oLva1~$d;Gk3JG0{~cg0RZrB0017=nEunp!pP;PFMsln4dnj< z(Zbft8~^|k1ppX^001Q)?SV2@OEV)=0DzhC$ATK*`1=B54N1V11JqXfdT zv~%_Rv9tW)gFj=yqUs|6Y#mH~?3gHjIQW0yxF8&p{$vhmv&I<$h#_ASemq4~1pc;yo9=Rw9hsSZ^ucI`aM(n4PH;fzKo zE3$_WRb~Ux3~iu?mRtYjsOC9pug1EO_=y{H>xU88h9A`HuaQ2Iq` zCLCr6`B$SW(k0qf276D6_OuESlvBMFQ^W-heJ8jze=}SSvw3oh8)cKm<}%l^A5RgO z;J#6FFm4d>&FB30YjISr-mga^*K0X+YRrpt&3?7$JpZbi`Kl93Pyp`pR<8@mS<)UB zD>@Ds#&Ai7(WZwWFWhEa5$|$(#!@j%=NS2X4+=#@bJGN|Feb)IIJc5gPGByOR4GIGwO$%SR? zv!YZRx__@ryQt(sk&5=7T#wQG&&GjJ|^QuDjsxl5c zp1#64eS(nGn`18v;W}ULUer-zU=nC*akV6$+q-ec>ZCKE~~=2+}rty}YRSL|+WG7X;Z)->M8 zdORJGJHNd^ATm1kKi5YO>=o$_Q78`NCixC-(9CrB&@h+AT$oS=sepK^hQ3xTfMB@l zo-qWDKRLBSEqsJCIVKjhBHvLQ?*b?xDv>l0EGtWo0T8OXhup3Dh~*zYtO$K8<>S1L zsWK205-49p?|%RTeWII3i&tty)ff5e)dYhL9%Er?EG6ZA$Y}#+jb3p7(R#BwN7?q2 z_ozjw zx$nlX4&g`O!{;$#Eda+4~fpP8KDn$&}5hsCFJp| zriyzcHP&g4x!`ZLYXQ5!hc}IQ;c&o=O>Zkuy=v z9WqI_I)LyQ@UD)~hEpS+Gy_#KOS{~{b~^>XVfXfGQ!P@oXsMoAQ-?+j3a~U*SB}W3 zFK%M2qM)lM)=7BYXdGt{PsP(;k>MrL--DUR&6t^tEr=i{&FD?Qu`Gw8GN$gl6-S;3 zC5+5G7~iNqeqVEkSFf$)UB5m~@|Kr#hT)K|u&3>%>V7x|J>L5*nHWRNam7*he7>bh@ zqq}GuNEtJTqc#L<8(bX}7>qbLd+ZR-nzV=->UsNZMmlP;f(YmxR`gHc^AC5=-SgtL zP}$*()5n7}u zDw*eM?a2|*#`dF3v%PkSd0w$~>PWGX%^Aq=s1=?WL}Z6#*TYH5bJsa~fA}{`b=4jL zo8<9(M!9e1Pfy@PmRje-X#POi`4{dA-_;Di-rRoB8eW&OTN8LU(Wp}G$Wl?Y>k@T> z(qSML!TIARX2uE-7Q*gZ@CRBlT+nZ3*QEv`voThDIunHf^M-Q<&Wsdy^z=%vw-Mn= zCJK;!-;m!o_IdFro~E(wP+nvA*Dl-1dnN92wBSr-OJ)W3h^{dQCgdCTn$TUA2ouU3?g&YGEShc`P3&A*$lJ zAG$as`F(U)+|VmXQS#CE=We#f#e=m`2MB0+I=m1K?`X8S0ONgA>7XV}5No?`>13To zPvK$PZ05;5k*fO$Zbt!QrzbLYgxV%2t?4_?+GpAs*s19q6QF0X<;s=L;%ucSZSQ`1 z$!Lcj#+QsYgRCwucg?mniSnCH%_Km02pP}#pU`X#ATi7czyV7x{KcDa%d#%WvlWFt zW6kLxAp;3cTAO`d-fm@h6ScT%iv9=o#4rF;ig=)LxcL_iJni=(d(u^xD>YBjRB$ah zkq&hFGeuXfI)*#bB?H^2iRoDoibmPx2d}W@{6Y}~j@}6dh(v@UI4%>%MW?|rpN{@!_M z)BbY9C`nKo2yGF~M2Q4$<-LAO1nlyC zK{qI)8=PWzPgjc(%xzx&`R&Xjf%HDV;m5~DB`>~^-s4cY&SkL0!&5WhUU`TI-3Pqc zfGStX$^G9~*tA^Gu#E5&WTgXZrc|3$tK#1}`p7zA!DiVhGI0B1ZVa7SL-3;Q=-Vz- zCaN~b&qJLVQe{%~r$?vcUYNGalQG#tT2eKmiqd1mVHaT#a4{1-^0aaUiE%E@)xhHK z`*8>u5zDtO!;_?aU7_8pbGCZEf}hJ~Z^t$_pZ)=rz!GdZqc@vGp={9sg5$f~g4+|i zkJcOToQI7~v&M!{lpI<(m&?_}ty^LUw%AK}hFEw?g&i;+Gb?J>WFfcG*QOQ7;7-^O zj}S5Z>sj;l2s+SnH;FweG^28-?v6ozwq4tAx}~Ke#9hyW2OXc|T%3GqRQQ$VjY`BK z%?H|6aXK`ys>&azX3H>(CR=n^@$iSX%z9h$NljB5J1`KtD8X}@dCgc`cyWy#iY?8u zkMaS9T3qP}|CF>UPNw^nTkkrUaZ1Z$4oZE@U@TV#fY9 zaUkOxRUd`E<(j$AjrZQmR$0xksx_S{THO`DTEo0wEItLg zuQV%DyG52lGLax{-f^*Fx!}P#@vlG~6r{_;J!gQ768X@xhRd?=5?f`0O4QS46~wal zf|~qgn!*@ikk*z*>7$hHHM=-F^;bI8RtrWLBp8Z=Y20V2kqsHvcGFTIyC|i7Bcayv z6ryi&GN8_qlO%X|q=uN2WTG#o6euW8gx2&^-XV4PJy8XPD<`8ne{euw2Umi5OeP(R z6Bue}dIXbcF`3*imsl%<<3QAWeacFnYrcVxp*?rDh#{6R(K!hF0QE#_By0JgWwv-7 z*WXWPm1g{^j-3OQsAn!T-W8fNl)~fC-o~b_))Ryeyb&v`GO!?$`diV{%0jeBWy1nZ zh4ylJe87O-E`xS<7S+toM{44fHY2m6(cf8(y*?(4WC`-2BSvOII6L|yrFa4x)APPr|~E6Cqd704kWi<_3$VRzlfO%_d{eznx1<~e?3}{ zvRN^^{FxYYpAxdsR0vD7V13a{h{$_WZg0vSt)wb@IBrgkXIAunQ;HdRN`Xifhi8o< zfgn)!z4BX|z{ztcNQ^9ZID^vzy|$CE*H=j}y~4z^_$H3ANkIa9h2Hm=8Rb~D*vJGC zp2X;RFnHY8%+yzFmy!}bYxhL?`xYD8j$QxhT?gZc_DQH2F){npPCADokm9a&y%P)% zKha9|<0v5{o>_u~hR09Vr8pPz)*q(N80saRZ9Av|oCmwMB}>+A8EK2NT1a6Z3u=s? z!axG8kkZhQaN%u2;)6)FdO{B-a^QQzBL2e#%k-KUk`;MAz;LnkNRRCsYws_vC%iIQ z@3m`T$Admp+a5WeVf{xNZQjW^htwy-U7>kETe?!Pg&+1WedP{)RsH%dgD?`f(6|`$ zZZYk$nbm@;g{h`jqNP>ATB_4zYZ97HP8EGY7U_1QL#9C+Jbc4BZ?9iMtXjHt$}2ED zc|x~=we!UI`NW-_t+$-;Pmu?(^2NyZ@@QNPt>GJHeeMOUL<&;qvwwem??7Sl1La5w z|KKC7)E-Zh_z+?e_%vwZtvL?;V1m%t54M)8Px57Y!{<9W)n;X#($eZ^tNs)f?9?)lRD+z|Jy z{nmbC{?|YJTwt)t+xN3>1s}rCK%#cSO2lpA;o^eX3FI8EP9icK=vg~Gc-VE(nbv?? z0tiVoTzZi?DYT`XJ0=6;bm(e=Eq5>9iQcjvR5S;o(Sq+wxo5<<=4iIDY0L+z zG%lAcz+Jwk8gE6B9NJmg$&@UpKwadW3_4g7TclK>x4}%7PBspSCu2rD(khmkrS2P) z(Mz|t)cgVWP-|r!c@2m7D&n}Vur}v!qcZl1l81Qh@GesfBwQyF6E+tv2j7KgeJ?}3 z*;-gp8)vD^s=L#{2H;kgCJxV$?<#nX8Fh$;&P>}1zIlLLc4jiaY<;5VBWypntKpob z$eoSnm#f?N6d*ozoYJ-$L`JvM#l6PW{~ukcK_b?tLg&jY;K^AlC$I-ynySgGdxZrO zRGx+6E-80h1^D=&?tyI^an)r0-?ARe5vYn%u{2QzEv2d`YK~ap_Mr$rySyhyH41zJ zK(f$Ts1%i7dIM-R!}f{+Io+0nX=7B9VGK9vR{l=3Maa4f$5eir?E|KSU8Mk9Wf}e< zp0K?&NCn1@pe@yxSWO)0L^ztwu0%?gr@4CGy~J*d%n!DiQ}&502Nr|Mwl{#-6ih49 zHHZJvtQS=IuZ8<1HQ96p2#g);#!7RvqR)$WUV(`RpNoxWJ=#R^5O^#wIy-=9H`;*wp1vw=4Z2|b@`5Www2wDljs%R)Lw0PtD1*U~3 zgceyvcCw=7Tl_480RJ%Is>$A{O)1;k{xf0_?kW<+C!M3a`j+O!5DfCky7rgL89cg< zNwf{>kUo5ie%G(_Sel^gTp{ja?G9F-h3ys^Hnx=Y=WM+Qs`5*dqDvG|E7lx2QfxM{ zAcJm#G=(Zsk8hFam6?#mx5L`Sc^L-h{1sQtLxavStKK zUQ7@ey*xPn@WJ9Hx0YnPvSO#b&;CN5 z(JbzTnTPFszlSO!G$XM(MvW{?uSAAGfM3Cgs`Lh%f(-bIeIMqP7)D*{ zMk{jf=+nV3YyMV(zJBU>XhJhN%?WpRNg&J$4&InNvpsalI)BK)bN{y$ss7RIJggZ&la_J1DLdJMuMhyFQ?PR_Zhv7jLDGj`9}mmp6}nE5`KERe>@(HyGg&1It87xk(TJi+!p3J2rYM9w#GD42Gx}z4Zj6JbOiqO*Nm_{MwGL%XPNHRF zg-&T4z61nf5EtgxoXbw5sICfAXVSrt2hL$ln|nVCzV(ToT&wa->u{sVc*APjE;Zj1 z>%J-S0`8uvfTr0u9;jgJZMtZ92kNk2w@3b`A=Id9J2|?H5U;>;`|lX%5|lu`*72%T zb~&QkGp33=N}GIlNQf7jWK`6MD{-67Lu^`TgPJOMGY&p%{jvOA*2ga`_8yO;2GYRF zPffze0~!@wKm4#|SIzX{YF)MgxxS!QNX|`M*Y`XmJ3n8@aib0UqZV^5J_QS^~BZUDEpzj z>=QE~&sx1u`jvqp8cAQ=F3K9^xUPF@u$wLYV*X)m7v6gsyV!ca$Ii-DgUdt#jypSky0n7B<6Gm{eEqJiI+8Ps%8>FlI0{u7m|Q$d)EDAESqan*-4KX> z`Fj`q-vM2DNZ{zdAWmH7D3dxyZqOfm17fGw=)Q=<=IN9ag!81XrPsNpJ!Tg8h-XZx zl&_|W=-URc-q<{8aQcAz3_M!U#JQHI_+8+~`jb_?xss;}Wj(gk5LCsKAfEb*@=0|*^SKPEJ7pVheSC- z_ehOD=)&JZHT3)?TC(UBimB^2l;JY6IvbU!8=l$OA~_+0Q%dp&_p>m& zi)O_5Wgzx{LlE%y_}1U;9Qh76oN(emr}zpM9rwT$gj zMzcqw)w!U~)t?0j6jJYLjy9D^4usulRJA|RlNz2tf<|0?atRwYTAGMSW(jstkGSUf z2Zpo6WE6Y8oc#nk%+j@@&l)N3)vwjz_gUmQE|ql)HAb6y2{g2YV~iWiZ9ar0R^K=d zqF{Aft1uTLo8faZzB&88_?v2D$s{Jol(?9g*a-@AURNC)-?dDkDNNx?L4$cQwc%pf zfqs`cyA(lzHO?__eU$VIwp$_HoTTREasHlg%;r*`&#_7S!s6m0>(Nt@|7GxGn+{p* zW*c2#zw4B`IAy%rfvc_L2ASrLR3V3Wj?=~Rk{wR)^|x*M92h3R3IbgnfrA!I$>33e z@#8o{VSL&zW!>+2p)jITjnDSijxBfD?%tZE`@3Ejjb_(|4E4!vuUSdy6KvUJl~H>m zb%(T#P0RYG`_b&*SRy5G3oQ>;-lk_6i98KLhKr1u4MB0{B0?_Zv-F&9-`7F9t_TYL zmXkHU|P%)*KWkcJS z(CdVJN9n~o@!j!rFE3D`wIl3qxh zzQn-OB-$v!s_*XQY&zeq>P;N7c)-t@Ox#O?w(~RdvUnS!|LKyUqM2-YX_=)QhwtBU znk*t!8~?k33Kl=5vNgM|nUcdw2$0%qXl|^P+M-#~xlGK)laIDaX-LS>F5zZ*YP*<**W@4_wD>V%N#hcT=fnQlXlR!y7_P- zXF4ZeRw?sjIc^wq8P5~M0HxbisuW$j-j2#~(`^%G3LOo^`T9kLlq#dt_=Y>;dEQ!M z1ZknbL#(YInRD|@lo{*%PB?waao8RnKtG~`S?8@cHe-ofgXKw`Bp8!mW*+VgMVOjT z0!Sha=U&*fc5f){i@geQ(B)aQ1d1htPAVaYYjkE3D}#geehn_5v@SiRc%opwulF|h zw;L#pk2uDm`NPo1N`Ne=K4ks5JSI5n&aVA+b{k~pt(4w6Z5kNYN(Ar;i+Mp}-}HXy zNs-P=Q<>!-qP)mS)msz00AcA` ze5FYa#+gH4QtOM05$yIZS;q-iIgci`;PN$>r(v1We}@241l~of3sB~q%?kF#Y1Huu zSGT3Kuk}+xhshA)eb$5+i}(LG_(;OzsbxxmJ2oQE$}J45%P>nearWSdsRRhq`}Pk_ zEC{ERZ=lxOtB;+I*GZ%ZBFSx1upxGOQ1N8NS}8u|XX%|buBF}ea9XZEkr091tsRL)Gu|1Kx8v?NR3!*2|AgMS zLurtn&Ft&jf63U}LI)9}R(%%RI~!ZmmLhs^U+ekA`#;(U((yXZ3jSOr*|{`0jSESJ z*>!Er?AW+$q-KObXaxNQY3*WkTNNo8CG#HF@8k4;8-01GFlJpia5Q^^@oZxxqOG@R zE0dwd)}%Fbc{fLDkNIr_7hGrTgy%wajgjNbWun8KH+w*3))eArh!PStBjzhRIo9fq zxg|$ENg%MmF~1hz_e~BS7QC3kOwH^yc3AD^%^b*+U7>e5Paf+ObU5pWmu0w8_m*P0N zeM+VWI8*qQCz{i;AKO#~l?c_H40?GzMa5L4*V)T9I&2LPf)u0-@0Yp-B& zzKGC#bXQ2Mp@EI?^ek}=5BMJP;Lce43F{-0RG<;>TKk>!enCfBL|clMU%9h09;*wO%d$IB5jXxTds81&@Am7p z)(T5hDbLWiJQ3DZxTs}he1T1m{t9a@uD)v8L=|Dpyg?qTCzVa+6>g-oHBl!8PwTnt z!YW#7|KPZEDw=3x>)oDU=_PF;y?$O~=zzcHf`Y=Ncb)7*x54kYhQKWc+>g>KZ?Bh8 zmzp<9fr=gV=ZU!sXMCw7{pZQ;>Qug8ICq++#w@W$j&Z#Y znEybM8YWoaoJKjKuTjeottwP&-CIp-XI@9KT7^Pi+Xfj^tefKxt12rhdw*-ks4_p? zCy+SZtig~|1Pz<+k45Nt1_uFm-#jNq0oBv=e7Ol?RS51h-^dtrHhz}`$=1%8`b1B7 zrcSg+3HsOUoWcs(mZ^6=e&-WrtmUwplx`oR?NFBR6M>MLzZR12(*@g1;ZWDi!x!T? z5Hh(-av~6hGA9zxm2}c3fbz`EV;YWM9`UWpq9f_O2)mPzfd&N22DuKBrKS`(?m~HH zvXCQJ49DoGF>L%Bz`#!%rLXSbf|WzhF_lU;bP~q8!h_atIWaf+ENCWZ)wj^>Y4Cymsm@{ zyHt)|IoXfFBThvJ+0FXd?L>-8cNOTEFj)BF46qyIWB{3hF>x`{MqF)xbQIWqUbNWj zr|6Klk)e1q?^*0^YT4Xfow=#eCy!_`fbE_&PUp5@Vi&fne3#@0U@=B}YbnQk-`IIvU z2opbBNNZ+&yX|k4T$pzedLNnlFj1}1D6!*(r}LReX`N!HfdB6UvHg$MJ3SZ@~2vLnjR9BMO zw20X6OPu3tEF90^p%dH;r;W3Ogza@Mfh6@V`*n{zOGEg(+<0w(ng>9pK(Eg&FQg=n zO6Gshn;~tOn4UbRN6Coy6=0?zkpU0A6!>DJfXnay1>{d8r%dkpbfJ3jzXd!#D;olV#|H5 zh}$rZqMG{;WO;$Z&Z_SjGRYcmwUAm`Iy$8w>Ch71HD97u*JX7SCDaLHdAJ5vF0w<# ziTjTmqsKFd4PUw5En-*d)yg2Lr|4SXszA>iVN1yG0J$^s(X z+F`td2pWoBZ|xSfwd8tp3MdPX2IttY(ooz6*zS64cZs!B+Q^CP1bV37Xk9AbUJHIO zKH$4Cv)>XX4BQ`Y>mUA}=$C4Vvy459dOfvuqvuO;V>Kk7Pi5?BhdyrY(`is?_VP=Y zm6CN8!x0+-gKIxWmwi-YeF!c;N9NRzSE1~cm0OG19X8IwBVxNlUTy@%)|=jJwVmCKbr@SZeL>7JZL zn=0a@&%^EtaW`hFsDF1m>yN%-LXp{!uo;;`!Z+EPYihF8L5JOn1exiQc>84D4veUV zwCwZ^Nvvp)Shx(>=Vt-2igM(){zZb9`~N>m<7u_N}jfz)f^ zS@}Fite$oeM}ynllwFuxtQeA(M)0~i?t=tTsF_c$8rHz9WE!uDs!&~Oq>zAs7$Wc_ zX`H={bpWb{Dm9iu3XsrI{bLR_5Oendu00^q!&faZMkB%M{`5ZfM*n~qrw-*KGbxnt zA(MUq!ME=<)4xgU&uHJ5nOTEM99G*MSEk;jm~e&!5S*6H{RPIKE)^Uf?PM`p;>oIO z_P-9Zk;{afk_Z~5MS4mj35bc=(oczUVXqSK$$uT@@;D+Ohs95kgfxjWOB>J9%tlhp zx|${pWgJz4V>~=FtB+7L)7TJ>W+()p%=7OtuDpVcUOaP>LrF!@*?R~YJ`Mi*4IlME z9N60TmBK!@`CslmE)G3AaMsfYvDXekE*&7G!%xYEX?H{1$6+9i-pN||s;JkoSl_2R z&EW|Fk^7bE=0FQHVh!~wQQAs?3LMoT;Z=XI-#{V#9Uu_0WTP|CQ(3p%rpNl5Ce4*J zdf5|}evl$Kdd5WS8&qT)BK0Y8HmiA2xtg=ZMfl_oSprdeFV0dRWPv)lBP!N3*f#l2 z7R#AZB2~gw0~~6p;5##*zbHKZf~G$XO4mE{Amfu(67h%V@K6x6%Y4XSrgnlSl`KzJ z(}5J#R5Ya95|2UPAt~$C!0!R+ykZ*uudOL2Z>f03cHdmJuOcVe_N?*6UNCY)XW%$!d#O`u=9r4pBWlxw-Z$; zJwyM5u6<<+znJ1S5_f1peS9Ta9ell1Ao=IlQQV{l8yS;EJE|g?f7t&Pgq2rZ)#NG; zdkzPU7dh6MUZ;(6X)Ic~Cq_Lj`p42^>IlG%s?l7=gnZmsnsSICa~pB~y{XnE-)lph z^{Y|njs3kPphhm09!wz2ffnI(iA3<`hAYf+L?RyfNo9uB@4Uu1P~;q3@w!;97IP%QbvXzybB;vdYox%pAcND2Zclxdw>@4f0D2tTr-{S zsQ+CIRYv*GKZ_Zj^(VdmC!7B_zy|>KQv(3NKfnaU{9Fm)VgFP72=f0H5kL?SB~S;j zAn+ClB!~cr3n(}!C#V^yH)t|w7w88V4_Fd76u1HSI0OrX2gDJi6r>AeE#xi~I20>X zIMgGw8T1AW1&lS!HmopgEgU_Z4O|mE3A_{hC4wG85yA(eHR3ChE7BM;9dZH+GD-r< zUsO%hDAY#OO*9lVN;GY>VRSrnQ}j*@7>u9XUQ9*I1k4jGeXJyG1Z+#}QtU4r4V)re zY+QTXemrEnTzoS8T>NhWBLXjiV?umFg`W~YSWS3OL_}mpluI;8bVdwE%tUNV>_J>a zyiFoWl0>pXDot8L#!r?{_Cc;eeof&-@kmKVsZ8lj+56*#|NQiW%#NoA0|ee@00PL_ zf6n=T<@@Oy2bc)B^+yN!Kc4()cy8iNu?VyMwDxa}J`(J-`mXAzE!TQ!%s0W-*Y?a%tYog{DLy7pT7RFifphEt{YV@v>9- z4>+Nm)bPJ|FflYWG~9eK$Rvu4c>PZMc1TAJBrXpC17wSUi~P@h<3qFT{{G4S{^gP8 zu)x3q2w@g}Lq=0mV?kgzSlC-I%-!ygdyqw46--=ARMq4Rv@ab-Q6@VR&&vM(d4e(6 z<(^zBta8!7KqSDzB*Nm)n5xoj#=n(dXY*Wdl=rM{c4F6fmUr}=@*K6C(ro@9;lnS? z0RYd5yH>t2vv~pKUzhde3#7P%AU*+5x})g$hM*|vW5_x4V0ueI(r;;ksK=ddR#HO#hN-+Oj<)5dU&qDu6R-aK1{4rirOm^z` zNAeL5IQWGxTytn{epbcJ$!5b3#v$H* zq*qA@e2Dc~w)_dS(xL=L)wXvHCUQOFwxkTcD+=NwqqE{l*O>pxu2T)EYN#fH-67Rj zuveb5nLh7P2pCF4=e9O6x>TV^n_6J9#M^Dq+`_8CzQM~capf^9l4XxDo)Uol$#CJr zqothQ(p=#`9m-tQgFx8~_}&^ETsGiY8V!HZ#!uzl8}#8@f6r2wHNOI}w@a{&>2`|M za1jDXoyeidB~^BTWSf1^dM#G)BjPxLa<(6b6$7=xJzRj*=?9x*f(A<29@N_xtlukj z8(BoXoZxhiRe3uU5*!td;0r_^5<+e&1%%>(>VX0^L&dp*Ktw^8{}$#Wmi7HLHO7B# z+~-;Wf{M(oDSb{(o}crC*WNE4YGZ!<$Z;ZE7czns6^(5iPNl)DQ;j0B<=1W|&J)N0 zLIcpcW7yLvbuxL#SC8s#?zFG{k~iNao-dA6%ghr50115qUO5=kJi|q;DgFqO8S27OhTN zlE^SQOL6iSQwk|zfW=gz&Yvb2CA?BbQPmiRhI-19b!3NKTMi94iPZu)OAQ`@n)Bfg zIB(r8IdWfYgcqpEz`}#j%|@Z{gmHo85$)jRD>=OVlr0@V5uE-g`Z?EE@7jJixU-a4 zCG=)r&`={K{n}F?r(nZQh(dAik9T(Cz&fgP`YT*S9vE-?4z(oVxx)!A&%1y08Jgf;RVhmByqg=Bv2108`=KarvinNrBb^Z-v4;^9!%H(?d?RNSsn^7JQ>pKZc z2nx4}VMHpw*IW_nRLTea0HpE~=)i;uieM@%IL<8Rt|6P)hxS|aO;a9)Kh>Yyht>j; zU@G)?iK`(2m9#etD4kVRM+s@e01HpmT|!LU89%=|K(4(wi#aptpJCtPkm-}cFFJW~ z8T_BvJ69@FeC5$12=#a=I+w;bm&!9&{Yy8ZHqL{e0-Jrsxj}!q7xHUMGr?torD#&q z0Fhw6yVwtvJJaQ^#CluP+3|*3gVi-^`?Nx=P(2KsRY|g!uI{j%DvKHTJK#-Fq%((W zs9Zh#08Gs60M40a`8=nSY-n(V$c|tX4yqn?DI=D9kQG46kKEcRoStGCt4M!h{&=4<8vv z#aJSNqu^ax$EI zaYi~Rvz;yMFk79_&b5|-lUSn9_`tuA_aFUw2@9Z?VuRFJ@UZ71aMe9@|9x zGoP5!t!pMyN?iP_!dUtkE;k8GWPv0+H;wOh2ONPFi&$|v5knU^RHyf?m_AMD5hlvkZuPAWq_jsW{>CT0 zg|blYDpwbHW_}}-~*wAp_l+xJH+|cv@v=IY{DR^c)AMi(L zT^7~{HjL1g5Ubx2Xwuw>(NHy@Q41>@6C~f3ozzLc6nIohk)0q23I-)#tx+)nGa&G6 zzurLUX?tg92Z3)@@6z8tuHL;in01LUCs?Ybs1rLfLt9lJ%u5zqRa<1)N)A~Dn}t=3 zds9ul*2$)Or=NDQLa7P6#KqK8H=-_iA?uo&VUZ^=iFJieQ_4)S`r#Am4gFs^g>^MJ zC##x*)&<*Kw~t!#AG^E?HZOIZrzUp0ZFd9mK4l#5idU1b9yh1)7f03-CugufNL-x! zEw#YW+FMEeno)nEL;XAx76`UM@oK1>F~_!wd7osKC6Da-R@t87+Pt|Mw#~^txERRe zsDYX+y}3@RZT!G_SzI^Qz;cQdOFo{(-Z3I{T(*4+oIoZ6g}ZRI?ZiVOJ?gh#bPd?3 ztqt8-Zs2-zl^JY}uR|WrVZiL~2K<@6jGNM2@W{~O#Xg#pdC#9alA0rQI+?Gmu;}Q; zSo=|eqpfd|i{U2vo?p?d&|63#5fh8kS04kv0%jVK{%Uj)c%a-gT z@4;9-ku@F*YQM1LoLUDGN{Y$~ON+}3OpMG7O^wYBZcW!?NUm+$eN69l`?X&rj`w9) zWsdiCP^PZ?WmM<3`*lDf&*w#KNn_9Fbx5J_-^-Z6_rJALy)b#b&gZk0vb_Kyk8CN9CW*AUKZRb(vF-L12^-sRp4kkW?yS(-j4&mT7M`-Mm+~H|D|J~(s zx%geq;*D1(>ArFW~rrE6envo%`l% zO&%1KVbFMCgu$9D>Vhor_p7zu_xgZnQd6^Hr;Yl38vs1CA)z7xl?8(x!jsR-@WGX-^qjEyCu_uh7 z*I^gY?D-X??S9Ph4`*u;DbmS24lMp0i)^I~rpgtodMf)%0pM!zD=q+k>MsCRbH@(- z*djQscm())^5fs_Q}OsZfs<}Ca@=XAhI-RiE3ozs0|0$%4*;FwG9?G4Rt|A9A}!%eLthL~ z5hhYIlz9=7#fhLTpzK79Hts?j8WWCQfh6zi7&fdo>H*Dy^`wGqe+Zaua-BoP^#*kY z3z_^znGb}NHKj3Pq9&3}l9gHI(a{W=QeL@bkbp*+=_Htdm(o$X9YqGJ01gn@2p|*y z0zI{2&_qe=)m}fd*%BKaA=oLEO*l8gqOn_# zPoOow3G4Z`O&=u8PbWhJ6^9~s9Uvh}A{)1{B_X$fDlVHsH-j^5HaNj%bZ6Q!;-^Gl z@?y|!gCyYAg>S@lK9Oa$%UVw{mh~uOoA__b- z6Qm;q`)u5Tut+)VDp`kkf-+s%4T>DP@&Mu^AIgYq-U=%_>xi*s5^~9uDv;S;Q1m`XrT zUKx2RO&Bu;GwG|9CQf0Q^!16R(*mvNZ8Mo$umL-4#15OV!)ENT1v?y# z9ge{c$6|-$uuCQ>RcVWovm@ji>M+YXk%gtmk}~&QV^t(aB&QBGB^nT=E~i<3zZWmZ z3(a6 zn$mj_ystCK!Iic{wgNEU*eQa98yRh@2y8{6%}jEVC#rHLtU^u=m7s%xdaoh~;lfhY zc_TE4yXZ`VBp0XR%WbQ`C>zym?nl~OTeK{eJoRH!1;pZ*!L>9dg^MJEES9^1it)tc z=`G=Ynl%i8^*?UOFQRJ)BQ=Z}WGnSRRR=aIBx7ZC(wAzvO zD6-?cnO;Rs%(?|KZAa$J30Xj`gw=<9QNU!Wk>GD9h-Nhau@L^+B=dhxp&yyn@<-O}{5 zE5*kHssQR=MuxChqR4tt=>lLfj@8u9Y0O-irgcmcXAYHX4Zzuq3Wg{s5D;SKDqIf#!G+&Gn$%yuHMM`PzX6+JO=6 zz(T`lkq6OY56Ufpl6)-H`2b#~^RZm#W7IHO;X$<0gO*n%>=%B1`{CoLYCi&Ve04^> zN?%{^jvvRm#yO^n;SbrjB!&SXP*3XQFH#LP+;ad>%>ZaGr#2M8Il(O4_Md}`1B${N z-~vY}DarsO*_nHD?kZ#;jShxR0XaWF2-x}U&vQCcwd4Frw7gBEB9iQtl!^qTgpx@E zxJ0Fo>eDGP5k<>lazl2sG?hw75J(dlkw_$0@Wi*OsOd) z<;h}WbWmEG?f29*1e`jG)nnRhNxZ}wEsGW8dW4iuq!A`n85;6gNung4NDbv=rnk4( z_?&`5lb8?_5@CWSNw1Jnqz01+O@%gvlvJ3!@j8{);i!;GTAH*fCRxZ8B0EJGxDkCR zuH(ssrD<->mdv;jZU)8?Cn2tv#FRr{Rtw9-MP#yS#O8yXIv>O_R0#w+uR|0Rj(&T> zeJ4$=5U6IbCfYkh10Xvefi$Mz)$xvVQTs$8DI-oYVT!v3=Gv@&v?9tdulZMlFHSQ% zwUGgRMEXf!_YI8z%St;C1VAvHmZ`6r?x{Jj3xxh?bMI zLt79$Y|&_S#X<4jUp2)QmJ{)8sD0tpBi$=WsXa}-&L|?js#Zgs6pAON4`IY#lIlrW zmTQ54S=XP#5FBzsvZW3@T<4R+rDtHpb5k)Pa;N;%uV=KuS?|6 z^i1#RRV-+FB%2;#K00n^4BMito@X{Rebt~&fY_3z+qWQYv$qZd?3Aq9m0#{w&7X?G zbfeW|jzTxXH_*Tq>C|;8UB{viS47ym=GyGh$`~TiAB31FaGf3}5b;Kd?rh1RPz8k> z)8{InUV2()n@t9K1WM#eaV96(b{V6H=2Ymed9yuzJz~nCo~JuWnxypK>3-ioHKk(2 z9x}kj0sLRdCWSLDdIo#L?c^$bIdf{eFhq=Jg$hQ9n^j4sLHjn18LwQf3z2C>>DltQ91-pXfi zjPe)p*t7t|uVXEE8d)1Ns$GA?wLE&Ylwd`;!xpRe>;{i!yxx7g%Bil&OS%owo|yMJf)CgRgbF%6aG@`kjCX{ZWw~H4 zxT$E=PdMKt#G_ZE)?mtr4Tp~;+x}3B!>-*s8hmyLL{75bc{ej0BcVSX{q+svv#xha z-t*lF)}DwMt{K~~auT|#?7n4*dGHoucJiC7+{^`7NwaDe>{u}eOB)1vgW|v=*t5Iu zGVpC!q4@QF1^wu9qTk4kTz&hpwH!L^6*D|m*WbU8jB%5bq4wyJVrOwM!o*ik1a^lGY}TY*E7$)Hpj6c(POo|?!PdkhQa zKYD)m z)$q&rA#NQQzPC_FMZ+jQcKfg$Lr=pyXrO+@)2}GFqb%vZbBN1J0lLc*6I%mt!bQFi z8=zx_#){UwFOzpPQY;t#(115RPD-M%WTeYHphHbu8Cwj27^zVQwFW%Y_f}JVuj$#$^@%6vJ3V@FAy(l}<#PD+lW71S{lKw+lLaE6h4N5dsYTLP?krv*Bd4hl9`=Vp;B z71E1lm4q~52G|=#UwPX`1J#7Zyi`>J9!los7cl71fg~|NH@=jRG^X!KgKCtVNS#x( zO-U|#`_%|Ev{9dhFn}|Y(;HjdysA^6U)omF?&^9jNc)6tuPUs)oE!EmfXGW8p)prT zpB^pPmn2i6?m!UOW(ijn1=Q0cfI1Lnavm-ORV%;)CV*AI{4vB(ut6;(WjiB{xXlGY z+oDFzKv11HX;1&Sl{V@`g?GnZ&s67rGK*=*D*fd%sB9KoJ|5b!58`n3(n9-2)gW3c z6A{n*ynO_sZCI`Oq!~7g@`rr*i+&d%qoMXrE1m6%c(+h)4AQFa4_gFDCg;vYasE+X zH4}tZk?$I7U~uuAvxaC9^?bg)lj*d>RdO66bL?EcZg;rhD3Jc}Y%aiddGVCH7`0Y_ zp79O>JdaMKD>FX?W-;G4mX)@O*Txbavf)&rt0CeG*^B$j$8I+(h<9d$)qPzol}yI$ z5tL%j{RoY~LZnL4Lpl>9z5thU%b)Y~h(3+LQG%B{C8)CNLy3%pY6F5S(TmlH@CM4; zo;&h+&~MP---F~o-IPc=vAKrIT$y=}j@AbJln&iZ&KuuvS0m=$lv2D@g$mw>Q95d+ zP(ei}KRM2k?Jnx7Ky3dDSD&>bKLACf*v>L%rs0IOt{IuAV9Wl82qX0Ft&9zo%WmO#X9X)@LOyJ z0uv67m&>@XujfPv7M{eJK>QJ>;<+^I_ru}=i$*|by3GPj6#}cKQu9m#D5DqdxgUA6 zE<>I)ck>-dr3u(r8qqz|_`iY;k})m1uu>!wY47Jl0E`!vzc8tn{^mu{Y2|d(TI=4` z;QnBlvYFhv)eTW)WU5aysv^W+tt%G<&!vbtMQTCLsD&-SQOIw?S=L=zybq(99>_&k zR3i?(1TG^lP#I0%Pm)EKt6X-gY8-%|GAZj2h1+Yu%WA0Qu)VXal%&x?d3H7B5fEst zc=@(18SOa{nj&-r0YkZ$YSMA>G?GvE6Bc)VHVjPBNw;Li?}M}l$CY?W3D^`|pdG=jFB|2Gx5GDDse``9o{6}tPd4*Zb6so!Z$ z{>q(|MU~gfn&$3l=tbQW-wNf894!R*$zJ^om+tN(Ik3&Jo*vJJ zRlhh6Gl9!KqoLAE>*1Ipj@$SplvO$g)T_{_74YLqEpry2q?N?|h{P`Q9{lbtsOx&T znWvIXc!Ye~U%Z?>>Xul|B#)CwWr%u(Fj==58#MQ!*3RuB0p%aKk z%NGW`Im2PO!J}ZhVc4E0qgGwR z=tcUJPy=7;KL#tRW5jp@3F8>m#Bd_R%6K(EX#6ubv{)9<{%p&dJR7diKe6jeEhbkv z3J~mKs>g+~yqEOcOa7UJ&W+=nVIU7-rXi+J7Ll|)9WkAHT zD3V33(M;v@ktQ*yD>K#Vz^g?Y)PPHy2yA4*7`98L!Jbie&E}UKv7TV%&>qB|X4%Me?xUUl=>zE`0cQT_Qw-(bOpL*!;i`%=Y>-PR*(^R+sQe{U-xQvaeY? zlNy|FW320hn66!Nx<6?j8K5)51PHASPYy+`sJv}{3u)*qfM~1Ejc3WGq}W$Bv<^vo zohsqlaxbJB(+Qw~&d18nnhn|SxHlX2g@$r_! zjHggV#BdlCaA15Cf)mD9G0I3VIoXlQ_fd-y7Uf7K)3|VIim-J9Ew-!LVO8qjkb>Hx zGfb`=p8z_DDt#KoMHEAS3`v3k>LhMflGFZnLn*1^oXlWEdmc_ntu^jRgIzhPdQZu` z%Tkxqfgson8aLEaafQ_h{?HMpNT)Ka7^1aZLiG+Jx;?LYFopS)!S6;ax+^=Dy!%&L zX<}tnn(j3I=&nX(UZ~a$ts@?rQ0Q52^Zqf$EgjJbpQ7mLLW0P ze0hn@Qk1E~)ZUrJNk;#JHjz4IW~3wqEe%G-Sx?FX)TxX?VHe zmjl+qXqp21Pa3}dN5UEk=jl!4&^nyKkfPY;fmjPjoG9Y4MJxL zRyH&5l8Q>TKW?BS|2uTr>@zC`+GweM*Fg_z{IU9Epx^5ETjOz>U{;=4*r3|k8s8CD z7h8q?!PB*CG$M=;2{{}Hf{%!88&UiT8U4L2oC^4d)_e>7K*=IFfBGSjnFB!_j!;Bk zB8|3PidRlw8=3EPt*QD8p+RG&Cp`)0uT-o`R938fzp;7etloV=X+>Pcluzkjr#9cy%dsi$r4^mV z!q{Lo-?_^9Ons?iapDy*Hu|FMc9Vqu%ytF&)Lb@p!baFO_4CuyLX2A3kT@xm38keU zI|}LTtIqcc%WH-=8Gk>OO@ z#n;*nHAswE^#=;6&Nm`i6j^2>qLamz3RoMt9XaGGC3>q z3^!EOO?NL>q3i{Qe#i3l_2#U(VwSVBwcEE09y zQ@^Ei7F~eb0QQG7v)Y}NY;_jy$4mMrAC$>ld$KrNw{V*8auJ*!*P4juK_}snnGqhM zY?ue;y#{R>%Z}E1e4TCymtQ=mt7%zM^Sjnh82SfBHk*Y1GZT8q?TjnT31p?q-;s-~ zxfX5BR{0;ydjYD$}$t< z<{c6(Bn`ocDJ=@E_LgH4{5X3;lj4Kv&kqcJEtHK8DJa`mfJ#UtJB`Y{rNU@NC@p&Y zU-a{DbALfaJg5)NnsCkxmznzgg4X(+1c&>5TxZhF0b7d?m^31G%X=c61!?H5& zvu>9G2UdLG%|)MjbS7U)yWeJs3E1iawxQOn5?7MQIp#}F&MNgJF^dcZg5~hK_W0qq z385QR*yf&h`a46jN=o0PX?$K;;Kv0=^c9odiD%EV^7j})%PVHPsxX!4u>lZc*-~sS zk6N;LG`dg~=eGPb50T10z>ZEz_ig)-)GsjnAWbivk{wl`iJqEVwk)C&e)6gE*_#0L zaIDz1dTFH?9Sl|7OnF87iam7GJsp!&N+s_Q(eK2*_YP{Fr#!ptw*8qk&!~5tRVs$9 zr%!FA6t}U4bg{=p#(H0o;sy!U{v_ue^*brAdo0wB=KYx4lOG&x8nIc!Psf$T#mgny z`G2#_%{5x1hiRJS_+~YQQ&kaPq(@9&OuDe(S%p;j(eELd`WY5)o3ngxL{K4Seaj60 zJ@L+vEv2aR`ns6%>RI_}#kJ0b>dMJaHdoaz@k<8ibk|!d#%7_!6Dftl|FaTjM6mMp zo=}a!_p(bMnf`*-6B{o)2yAlO+t{gqLdvLETX|WHR!TPP(R~iVeZA{?`(TIz3w3)M zNU6qOUT$Mmj8s9wApJomC%TLYX1dZH(I_968_26~^8mzCD_5|yv*3O>i=C|;#lp+! zKO&l)VCm4NA`+LaISE#+2KzyqeC|)c5Nq?TAB!!l&d@yjy*vBt4msK8bsunCZj2AE$7ju%d!SMHE9Nk7E+|}oTfz)d4UJUJUzB2a znNVf^F(d7KVZq#iT;D(WiP^3sSuP{jGMvElDQHEFR(`*oq$ViY;C;Ea1}vBd7P=+( ze2ptt6jVQOiq}tzuMaF;QITSuNOitfI17{IYHLuGR#(JW*-Ih|HB1G@Y?NXsqK-0r zc5o)n5^`B+EI_Ru>@v#YGbjFR#|JB9+Fq(rs_DkzS`FT`JH*N-eMn)h7}96vx)?Mn)+@(-miKjsr%2eVYR=H$!II+k{d zK7aiD_LD_hz^N^SiVfxEPvqx?Se3TG`r;m9souv`pw&GtTXh;er_HTFI3nE1sKnEk zcC`rQf5o}{o;b#Fq)@u&q8&#^B3ij1*4LVB7sxf; zpd=7b%I^=#sKHVbsOzukLq4HYY^cBwd<(Qww71SzmlRu4x(e611afuV$jQ|tebJ!G z=^0P+?U<1>IT}A2A9hXd{s`b0%@ZHR<0d03oW3BeXwIv}d;?EySwm$3f|Y)Z9+R+T0%7 z{mTEpicZ$`nnvml=N_(m$;|#vMz8*VY~uvFJ>Vn`gtUQ%U6oJEmBq8$--tUwlY@lK zI_KsKWJ1-){hLBct#!s|N9(Ncc-%=@EmGgcu7I;k;x7X%rV#s%V`0BU!2I0?<( znratT;d4JHXWNm!qh8+?H+4nD(cG_ck5;Uhik+G%JnL+W5O1BcJHd>%i_VFfpaSnt z9~V<}Bg?lI-3i~h^UgSADdkDO#C2Lb@Nd`!n?4X0YjR6ed9o>Q&xm{?4n#T16b^0= zKT5>h`5Q8Ic=HdwygME0q>y;$6A@?x-C<_fup8DJ{vB zzwG(qR1j5kPz?eZQ6k|!M9#zPPm!l&x%c|49iC#mLI#R4(zC3aNH56qu6|pw?^;lBdJCQOr z{p=+AZ@UMb_p5u+mV&m*A9O_nJ!lBs`>M(6L1Vo~TvAp(u8ac%4tU`5nV>Fs=JG&3 z08fqY{-Yxu5^lr$pp$_|UBAjKjm zN!BDOE;(3mutZWUYf6GdEjmTh>_t%AQqP59vu3CEO@mXr)4EyOGNPrWj9(1naSR^2 zef!0am-2rz602{Omf)$PRk5~iYd7MUl|LuU#DGu6R#sM{HC`P7<}!B8fNJBVq=w+%K73Me&<734gPI32j(!oXWxSO#3f3)6<&CA3n3S@ z(@fa8?beq)^5rW4H&&B4g~Yz++xMvpoEMi%DsW>weT3K}s}*2-8-GqnC_oWkK^i~$ zWAOKmsnf`^6Ry5K_<5z(OsFC_5UdEX>Gf#V28ju$$9jtPQ7j@(ldzlSGo29@%@0n> z+hV@w3Z~VJ67Hq}^YezQS+zsZ>2fcaF?wgxN)(Y^=`V|Fe zW_A1V;pT5qCds8^uRM-#_ITcT&W4TOyCCS;9)Ys%1#|pJ2#DNV`E?05JGGZ`V(KO4QcNdwk5qL={p{=zf zx(usm%*6HNn59$ zvJ9Ky&C3IhW?4>u7kGo*(-7RrP=vy zL1zlt@-0o;ER=9#Vk4@(Ro}O`))BRI6!*hsQ~%@qCWX4rk#A#J{<3;kw6xAOwbGyM ztx543{pLY<7&^9}5IX;MmScavxlVvqLE&z+1{D!o-h3838+)%lH#aAvSiko;OA5w{ z8myUtSrrQRl~{*s+8o`hFRd&stdQFx&+fqDR)UphdbQEP@0&9m$7^Aho}gu?q7Z@i zHb<-RxSH{eTpl(jyV(8@=(@35reZ_cIc!FHh(&VN^Vz zkZ?wOlDn-n5L><^3nP@$unUrYPWi#c2W6gIM|Yq=uvovq>-HtP7I`v6W_fHw7ZMwj z9Ao~~5-ly0f}i{Q4Nu*RXxM8Nf%I0>Dw@mw>KCM`rZ^^abP3v8VTsFpWudy0sdIy% zhMcXw(EByzfE3d|1BpKzl~Ho6TLGF|_S{-mBIvm!RwHMUXhzE_Bny8h)|_6&x}BgV zw+6JeiY(Ob-FdluH#gK^$dP+7E{aiTx6fcNGHAbE*>>+l8F%b_aUrPHXlpnep+rZ? zMcpC`_4V&v!qr+-N^HL0D^`4f$=c&rw0m;;I1h~<=y9JLT})r ztGX#A@qTKe$-!4kMjAXiO^jR~D{Ch0TRRE_4D>mqF&uxJ5+ z4*m4I&A6X8y-VKoB%z;_!ELVJekV}QsA`HMH^kBi^j7{fL#!#XXcN`??=v>)^9VY9 z*zG8@&FHktW=6@f*I2`oWxq;tY~?9qFzUvs9W;^qW~y&s0+ zE^Qxet|y!x`eJjcI#jn^pYox`CS3T>?cKC7Y%iPsX5+NsG7P?q_zGtVWrUpmt|dwN z=AGr?+1dine9l`wZJMZ*7g9LNLut~1cRwD{uu^TfhF?=uid}pI@4~$@GY>;$9#32T z>}C=D9!+kx!(+wmHh&4%<#6VQSe3?~8PO`IwzD?y$IXIrd~R-enU#Hv8-41K;vwy7uk&Pk4b9wvX}07Ls{t#|wAtZl|4_L1?Am4< zA1+*iT2MEo2SJ_LIf621*$~PzC!q13axUS!r!oFAX3B`~ferTdJa~4VBQR2|uAll4 zGy+$9ckj+`LO*#!{u5rOOc_htO)gAbCy)r%r7k2nnIB#`647YWU6qxUhC|W`D=)j0 zEh)7$RXOyR*3SGwYYVJZ!H^+tB`B+0`xeawf@HdUmMo)(l(iq2lU~JEnlK24xtw^_ z%iSDEe^zJ@ME*AY!h8;?#?&v84TlCvCRk80O1H^*D2#~MuDLyaRlmGJQYEQYjX`1b za+}?g?16Y!jVd-2tSo!yq0=Wjtxg!awLaaC>jpS?+$*&j>XKdv#k;Oe{`qGoPyZ>c z@xO9%jZEB9x!Ijom|6(+?6SEGx;D0^G6Wj>-p@mS0FZsDd+&YKI++fts)X4SmEjOg zFU#^C33B6Ja-W0pVeZS-^)E4XzsQwP`HGjR=uW@f&lrERu;&^24$YBK7J`?$DpMXn z`>)TVc|3$en25;3AFD6Z>S@ibV3qb?L%F09m=frBi6sUfE#L|GaE%N+`stM~Rr(d9 zt)!Kj1_T~vucIn0tFgFr{U@eKNv{HQMojmLF>46lP(;ZHs%QfqvKC|a%w3?1YfU>xvx9zpXvWN;*VuN@aS8qM`4QwZ>PFh4gd?c;fK4Ah@yy4|q24ARrvB)S*Egx1-``*;q&b~G@(`Fxfo$lx| zem_k;yquy(tI^Bwdam)vaYTCmKXG30$pwiZ;&kqed*i1NZOV;`d3smx)Pauyq? za||!z!$e}zZ?F>rqW)Vi9P0Hf-Ou zO`R=bYI)>}_43z#0(Y-pxATccy%A3O!$nF5|K$pH4HPd>5G?KO6&}b!{pO6bx1t>l zS!PUBS(yXr&+>V<-aLON^Tgfu3j*fu;zbFvWr^;)4F5f}_4k8YfIiK&XZNzIKB2lE z{qnBVh?8G09gTrTI7BTjJhaGAMEeI*~KyLu}cMi<2&)c1=2lsp39XZyC`fsF0Pb{7juPEzLKfHr`N@6JM@?|_2hIz||Pg0XBx<^PDIzR-isrRE%0HNm8 zM^++u0D{R8_T(N438v3^g46T@$|8yRZdGXTTn_) zvG8)JCMt(#nL=_`a{t+O`p&SJ78>UCpjHK5!7bMt%?1;v>2E>5z0*GXbU?J~iQ^N! zPZ#Y_`nf2j)v5rSh{?OkHh-@z>HG&HgGICP!DS6bUBtXKg^>j)DDfb`C6ih7>p6 zL{M_aBo4w#ftpyrN1!L4RIMu)Ga%ez^3Zlw_|+heVgarZDB+;k6doF-WS8zbIEiUd zo-%R~7Y;l3=wX<6#0On?xE2e>*tR&D#i*Wor6Jn`t-QA*SD-gVTu%* zOvDdh64-yNqN3}KBoQSo5UW()rxt57@{6&3;xxZwTLPh7{FKV8zAyFQ#DuTwpRI_6 zTC6adgcJ#*>$bdZ?Jq&U^1H}S@qRO}<}l}(sD~M15x14w5M2-%&<#WiqPY#+O7ydt z{U=s@-3(r?l__YUfJ;JpFe(;~ra%Ur>1*fLGC3u{Ob|hg%0~&0kkEtEorfr?0EX@H zhqSbitAC=eO8L5nTbjyB-D-|K-YE(eyR+i-YDU84wp(;H*OX<#iw8uRKH(}jBm^QE zKxB}J3xbNmd_E2xQqdyHB1(yvc%tD4DRu_99JMIOO^t_q792U8m!6WO&^>f0tMbJX zP?EBgvG~*hsi;m%D#coam`+KQNiKQ&R-|6?Pg7ABkGLoHWCnO*dD7D+J+9w+Y_d7m zBBqc)5u)S?4nz$}9O^R2s;FnY+d7nCxnY3~2BH1`hxVD7%^KLEhMfLct9^%gah*g`)h#3xT%i2LlU6gqr(_&>O4Hj`{dYJ2Tb%gf?5S&qpT zr$ed)8mST`NR;H5y|P$jaY&#>h=C(9EO3Rg$S8Z{vWu$>9WF?l;|A0t^Fpw*xfRMv!C>hw@Wm9Vs046!)dDTxH)~?8LGnC76NG%%$ zqfAbxi^Y0E^7U1pq+u9=SCD(2aG}8+?N}o8Kz5(+CIRP*+veQ`(`^T4)QFXr=;H zGI}Th)0BMDqRe;IUMow%&r#FFU3xHbgvPTtq9`Tv9R&PLef>N|ssVSQskO?P-g7p~ zCP68+rc(M)Q)A_{PG0t4uk``s=9Ky|tHj?!fYT&uyr%rH2Oug$86&l;xQbg%1sU$h z((YsLY{=2FbrpL6OANW^RGADzoFi2Ao-%5GAY(ZK3+XjQ*)r_%_0uA87vTg4I&Pv$ zoo6EjC|)u+L-Od-3K^M5dE#Df0?|i}8RpUlfSMeYDo)~Pn%b!ioPy+FA=Igdonyr> zddn5~@*@l?7Ly%D*}m?zrvP$*^Z7LsK`I4|IOrYw z%mma?KlxW&tQ{4jgu_m2`QKu8p+*0;IPm|AA2Tp~0zx8U5>hyV42eQxu;dh!RMa%I zqUh)u7@3$^M2itCPW;COo}7PvyA-L?q<`J@XH1rCIdbK3$mitZ=Hca2z^_n|VgV&e zl_^&tD5O%AYBg%rsn?)UlV&Yig|!7{4o_O_Q@4`G|9p`Gi!9+IAN#~@pQX$StE{ok z2AgcL%?`VG)8X{kFCnoNzFO_9xoKwAS?i6?bc^0(v$pf-24xvVl^VTf^vTf{#*Uqy z2?|4BK6K@y51!RkerYBzsY>|D@!>0@POF>sV*j)k?p}&|v)%}_ZsiD^4F!exS-wI4 z&a1bt3V0_?49+3t+y79NTY0JW^O%c+a~}T5DG&LNQM9%p;XJ@uIIA854zN}e-)`N9 z^KD&^4pNLb!qCDvSBysY87J7A0?M0fJ8nOQ(}aI$%AE_+Opl<`rO1C$>3SRP;Zm{g G0ssIW.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} \ No newline at end of file diff --git a/docs/public/katex/katex.min.js b/docs/public/katex/katex.min.js new file mode 100644 index 0000000..f59062a --- /dev/null +++ b/docs/public/katex/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return Wn}});class r{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;let n,o,s="KaTeX parse error: "+e;const i=t&&t.loc;if(i&&i.start<=i.end){const e=i.lexer.input;n=i.start,o=i.end,n===e.length?s+=" at end of input: ":s+=" at position "+(n+1)+": ";const t=e.slice(n,o).replace(/[^]/g,"$&\u0332");let r,a;r=n>15?"\u2026"+e.slice(n-15,n):e.slice(0,n),a=o+15":">","<":"<",'"':""","'":"'"},i=/[&><"']/g;const a=function(e){return"ordgroup"===e.type||"color"===e.type?1===e.body.length?a(e.body[0]):e:"font"===e.type?a(e.body):e};var l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(i,(e=>s[e]))},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:a,isCharacterBox:function(e){const t=a(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){const t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}};const h={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function c(e){if(e.default)return e.default;const t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class m{constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(const t in h)if(h.hasOwnProperty(t)){const r=h[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:c(r)}}reportNonstrict(e,t,r){let o=this.strict;if("function"==typeof o&&(o=o(e,t,r)),o&&"ignore"!==o){if(!0===o||"error"===o)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===o?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+o+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){let n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){const t=l.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}const t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)}}class p{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return u[d[this.id]]}sub(){return u[g[this.id]]}fracNum(){return u[f[this.id]]}fracDen(){return u[b[this.id]]}cramp(){return u[y[this.id]]}text(){return u[x[this.id]]}isTight(){return this.size>=2}}const u=[new p(0,0,!1),new p(1,0,!0),new p(2,1,!1),new p(3,1,!0),new p(4,2,!1),new p(5,2,!0),new p(6,3,!1),new p(7,3,!0)],d=[4,5,4,5,6,7,6,7],g=[5,5,5,5,7,7,7,7],f=[2,3,4,5,6,7,6,7],b=[3,3,5,5,7,7,7,7],y=[1,1,3,3,5,5,7,7],x=[0,1,2,3,2,3,2,3];var w={DISPLAY:u[0],TEXT:u[2],SCRIPT:u[4],SCRIPTSCRIPT:u[6]};const v=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];const k=[];function S(e){for(let t=0;t=k[t]&&e<=k[t+1])return!0;return!1}v.forEach((e=>e.blocks.forEach((e=>k.push(...e)))));const M=80,z={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class A{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createDocumentFragment();for(let t=0;te.toText())).join("")}}var T={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}};const B={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},C={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function N(e,t,r){if(!T[t])throw new Error("Font metrics not found for font: "+t+".");let n=e.charCodeAt(0),o=T[t][n];if(!o&&e[0]in C&&(n=C[e[0]].charCodeAt(0),o=T[t][n]),o||"text"!==r||S(n)&&(o=T[t][77]),o)return{depth:o[0],height:o[1],italic:o[2],skew:o[3],width:o[4]}}const q={};const I=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],R=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],H=function(e,t){return t.size<2?e:I[e-1][t.size-1]};class O{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||O.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=R[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){const t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(const r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new O(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:H(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:R[e-1]})}havingBaseStyle(e){e=e||this.style.text();const t=H(O.BASESIZE,e);return this.size===t&&this.textSize===O.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){let e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==O.BASESIZE?["sizing","reset-size"+this.size,"size"+O.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){let t;if(t=e>=5?0:e>=3?1:2,!q[t]){const e=q[t]={cssEmPerMu:B.quad[t]/18};for(const r in B)B.hasOwnProperty(r)&&(e[r]=B[r][t])}return q[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}O.BASESIZE=6;var E=O;const L={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},D={ex:!0,em:!0,mu:!0},V=function(e){return"string"!=typeof e&&(e=e.unit),e in L||e in D||"ex"===e},P=function(e,t){let r;if(e.unit in L)r=L[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{let o;if(o=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=o.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=o.fontMetrics().quad}o!==t&&(r*=o.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},F=function(e){return+e.toFixed(4)+"em"},G=function(e){return e.filter((e=>e)).join(" ")},U=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");const e=t.getColor();e&&(this.style.color=e)}},Y=function(e){const t=document.createElement(e);t.className=G(this.classes);for(const e in this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);for(const e in this.attributes)this.attributes.hasOwnProperty(e)&&t.setAttribute(e,this.attributes[e]);for(let e=0;e/=\x00-\x1f]/,W=function(e){let t="<"+e;this.classes.length&&(t+=' class="'+l.escape(G(this.classes))+'"');let r="";for(const e in this.style)this.style.hasOwnProperty(e)&&(r+=l.hyphenate(e)+":"+this.style[e]+";");r&&(t+=' style="'+l.escape(r)+'"');for(const e in this.attributes)if(this.attributes.hasOwnProperty(e)){if(X.test(e))throw new n("Invalid attribute name '"+e+"'");t+=" "+e+'="'+l.escape(this.attributes[e])+'"'}t+=">";for(let e=0;e",t};class _{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,e,r,n),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return l.contains(this.classes,e)}toNode(){return Y.call(this,"span")}toMarkup(){return W.call(this,"span")}}class j{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return l.contains(this.classes,e)}toNode(){return Y.call(this,"a")}toMarkup(){return W.call(this,"a")}}class ${constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(const t in this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){let e=''+l.escape(this.alt)+'=n[0]&&e<=n[1])return r.name}}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Z[this.text])}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createTextNode(this.text);let t=null;this.italic>0&&(t=document.createElement("span"),t.style.marginRight=F(this.italic)),this.classes.length>0&&(t=t||document.createElement("span"),t.className=G(this.classes));for(const e in this.style)this.style.hasOwnProperty(e)&&(t=t||document.createElement("span"),t.style[e]=this.style[e]);return t?(t.appendChild(e),t):e}toMarkup(){let e=!1,t="0&&(r+="margin-right:"+this.italic+"em;");for(const e in this.style)this.style.hasOwnProperty(e)&&(r+=l.hyphenate(e)+":"+this.style[e]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');const n=l.escape(this.text);return e?(t+=">",t+=n,t+="",t):n}}class J{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(let t=0;t':''}}class ee{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){const e=document.createElementNS("http://www.w3.org/2000/svg","line");for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){let e="","\\gt",!0),ie(ae,he,xe,"\u2208","\\in",!0),ie(ae,he,xe,"\ue020","\\@not"),ie(ae,he,xe,"\u2282","\\subset",!0),ie(ae,he,xe,"\u2283","\\supset",!0),ie(ae,he,xe,"\u2286","\\subseteq",!0),ie(ae,he,xe,"\u2287","\\supseteq",!0),ie(ae,ce,xe,"\u2288","\\nsubseteq",!0),ie(ae,ce,xe,"\u2289","\\nsupseteq",!0),ie(ae,he,xe,"\u22a8","\\models"),ie(ae,he,xe,"\u2190","\\leftarrow",!0),ie(ae,he,xe,"\u2264","\\le"),ie(ae,he,xe,"\u2264","\\leq",!0),ie(ae,he,xe,"<","\\lt",!0),ie(ae,he,xe,"\u2192","\\rightarrow",!0),ie(ae,he,xe,"\u2192","\\to"),ie(ae,ce,xe,"\u2271","\\ngeq",!0),ie(ae,ce,xe,"\u2270","\\nleq",!0),ie(ae,he,we,"\xa0","\\ "),ie(ae,he,we,"\xa0","\\space"),ie(ae,he,we,"\xa0","\\nobreakspace"),ie(le,he,we,"\xa0","\\ "),ie(le,he,we,"\xa0"," "),ie(le,he,we,"\xa0","\\space"),ie(le,he,we,"\xa0","\\nobreakspace"),ie(ae,he,we,null,"\\nobreak"),ie(ae,he,we,null,"\\allowbreak"),ie(ae,he,ye,",",","),ie(ae,he,ye,";",";"),ie(ae,ce,pe,"\u22bc","\\barwedge",!0),ie(ae,ce,pe,"\u22bb","\\veebar",!0),ie(ae,he,pe,"\u2299","\\odot",!0),ie(ae,he,pe,"\u2295","\\oplus",!0),ie(ae,he,pe,"\u2297","\\otimes",!0),ie(ae,he,ve,"\u2202","\\partial",!0),ie(ae,he,pe,"\u2298","\\oslash",!0),ie(ae,ce,pe,"\u229a","\\circledcirc",!0),ie(ae,ce,pe,"\u22a1","\\boxdot",!0),ie(ae,he,pe,"\u25b3","\\bigtriangleup"),ie(ae,he,pe,"\u25bd","\\bigtriangledown"),ie(ae,he,pe,"\u2020","\\dagger"),ie(ae,he,pe,"\u22c4","\\diamond"),ie(ae,he,pe,"\u22c6","\\star"),ie(ae,he,pe,"\u25c3","\\triangleleft"),ie(ae,he,pe,"\u25b9","\\triangleright"),ie(ae,he,be,"{","\\{"),ie(le,he,ve,"{","\\{"),ie(le,he,ve,"{","\\textbraceleft"),ie(ae,he,ue,"}","\\}"),ie(le,he,ve,"}","\\}"),ie(le,he,ve,"}","\\textbraceright"),ie(ae,he,be,"{","\\lbrace"),ie(ae,he,ue,"}","\\rbrace"),ie(ae,he,be,"[","\\lbrack",!0),ie(le,he,ve,"[","\\lbrack",!0),ie(ae,he,ue,"]","\\rbrack",!0),ie(le,he,ve,"]","\\rbrack",!0),ie(ae,he,be,"(","\\lparen",!0),ie(ae,he,ue,")","\\rparen",!0),ie(le,he,ve,"<","\\textless",!0),ie(le,he,ve,">","\\textgreater",!0),ie(ae,he,be,"\u230a","\\lfloor",!0),ie(ae,he,ue,"\u230b","\\rfloor",!0),ie(ae,he,be,"\u2308","\\lceil",!0),ie(ae,he,ue,"\u2309","\\rceil",!0),ie(ae,he,ve,"\\","\\backslash"),ie(ae,he,ve,"\u2223","|"),ie(ae,he,ve,"\u2223","\\vert"),ie(le,he,ve,"|","\\textbar",!0),ie(ae,he,ve,"\u2225","\\|"),ie(ae,he,ve,"\u2225","\\Vert"),ie(le,he,ve,"\u2225","\\textbardbl"),ie(le,he,ve,"~","\\textasciitilde"),ie(le,he,ve,"\\","\\textbackslash"),ie(le,he,ve,"^","\\textasciicircum"),ie(ae,he,xe,"\u2191","\\uparrow",!0),ie(ae,he,xe,"\u21d1","\\Uparrow",!0),ie(ae,he,xe,"\u2193","\\downarrow",!0),ie(ae,he,xe,"\u21d3","\\Downarrow",!0),ie(ae,he,xe,"\u2195","\\updownarrow",!0),ie(ae,he,xe,"\u21d5","\\Updownarrow",!0),ie(ae,he,fe,"\u2210","\\coprod"),ie(ae,he,fe,"\u22c1","\\bigvee"),ie(ae,he,fe,"\u22c0","\\bigwedge"),ie(ae,he,fe,"\u2a04","\\biguplus"),ie(ae,he,fe,"\u22c2","\\bigcap"),ie(ae,he,fe,"\u22c3","\\bigcup"),ie(ae,he,fe,"\u222b","\\int"),ie(ae,he,fe,"\u222b","\\intop"),ie(ae,he,fe,"\u222c","\\iint"),ie(ae,he,fe,"\u222d","\\iiint"),ie(ae,he,fe,"\u220f","\\prod"),ie(ae,he,fe,"\u2211","\\sum"),ie(ae,he,fe,"\u2a02","\\bigotimes"),ie(ae,he,fe,"\u2a01","\\bigoplus"),ie(ae,he,fe,"\u2a00","\\bigodot"),ie(ae,he,fe,"\u222e","\\oint"),ie(ae,he,fe,"\u222f","\\oiint"),ie(ae,he,fe,"\u2230","\\oiiint"),ie(ae,he,fe,"\u2a06","\\bigsqcup"),ie(ae,he,fe,"\u222b","\\smallint"),ie(le,he,de,"\u2026","\\textellipsis"),ie(ae,he,de,"\u2026","\\mathellipsis"),ie(le,he,de,"\u2026","\\ldots",!0),ie(ae,he,de,"\u2026","\\ldots",!0),ie(ae,he,de,"\u22ef","\\@cdots",!0),ie(ae,he,de,"\u22f1","\\ddots",!0),ie(ae,he,ve,"\u22ee","\\varvdots"),ie(le,he,ve,"\u22ee","\\varvdots"),ie(ae,he,me,"\u02ca","\\acute"),ie(ae,he,me,"\u02cb","\\grave"),ie(ae,he,me,"\xa8","\\ddot"),ie(ae,he,me,"~","\\tilde"),ie(ae,he,me,"\u02c9","\\bar"),ie(ae,he,me,"\u02d8","\\breve"),ie(ae,he,me,"\u02c7","\\check"),ie(ae,he,me,"^","\\hat"),ie(ae,he,me,"\u20d7","\\vec"),ie(ae,he,me,"\u02d9","\\dot"),ie(ae,he,me,"\u02da","\\mathring"),ie(ae,he,ge,"\ue131","\\@imath"),ie(ae,he,ge,"\ue237","\\@jmath"),ie(ae,he,ve,"\u0131","\u0131"),ie(ae,he,ve,"\u0237","\u0237"),ie(le,he,ve,"\u0131","\\i",!0),ie(le,he,ve,"\u0237","\\j",!0),ie(le,he,ve,"\xdf","\\ss",!0),ie(le,he,ve,"\xe6","\\ae",!0),ie(le,he,ve,"\u0153","\\oe",!0),ie(le,he,ve,"\xf8","\\o",!0),ie(le,he,ve,"\xc6","\\AE",!0),ie(le,he,ve,"\u0152","\\OE",!0),ie(le,he,ve,"\xd8","\\O",!0),ie(le,he,me,"\u02ca","\\'"),ie(le,he,me,"\u02cb","\\`"),ie(le,he,me,"\u02c6","\\^"),ie(le,he,me,"\u02dc","\\~"),ie(le,he,me,"\u02c9","\\="),ie(le,he,me,"\u02d8","\\u"),ie(le,he,me,"\u02d9","\\."),ie(le,he,me,"\xb8","\\c"),ie(le,he,me,"\u02da","\\r"),ie(le,he,me,"\u02c7","\\v"),ie(le,he,me,"\xa8",'\\"'),ie(le,he,me,"\u02dd","\\H"),ie(le,he,me,"\u25ef","\\textcircled");const ke={"--":!0,"---":!0,"``":!0,"''":!0};ie(le,he,ve,"\u2013","--",!0),ie(le,he,ve,"\u2013","\\textendash"),ie(le,he,ve,"\u2014","---",!0),ie(le,he,ve,"\u2014","\\textemdash"),ie(le,he,ve,"\u2018","`",!0),ie(le,he,ve,"\u2018","\\textquoteleft"),ie(le,he,ve,"\u2019","'",!0),ie(le,he,ve,"\u2019","\\textquoteright"),ie(le,he,ve,"\u201c","``",!0),ie(le,he,ve,"\u201c","\\textquotedblleft"),ie(le,he,ve,"\u201d","''",!0),ie(le,he,ve,"\u201d","\\textquotedblright"),ie(ae,he,ve,"\xb0","\\degree",!0),ie(le,he,ve,"\xb0","\\degree"),ie(le,he,ve,"\xb0","\\textdegree",!0),ie(ae,he,ve,"\xa3","\\pounds"),ie(ae,he,ve,"\xa3","\\mathsterling",!0),ie(le,he,ve,"\xa3","\\pounds"),ie(le,he,ve,"\xa3","\\textsterling",!0),ie(ae,ce,ve,"\u2720","\\maltese"),ie(le,ce,ve,"\u2720","\\maltese");const Se='0123456789/@."';for(let e=0;e<14;e++){const t=Se.charAt(e);ie(ae,he,ve,t,t)}const Me='0123456789!@*()-=+";:?/.,';for(let e=0;e<25;e++){const t=Me.charAt(e);ie(le,he,ve,t,t)}const ze="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";for(let e=0;e<52;e++){const t=ze.charAt(e);ie(ae,he,ge,t,t),ie(le,he,ve,t,t)}ie(ae,ce,ve,"C","\u2102"),ie(le,ce,ve,"C","\u2102"),ie(ae,ce,ve,"H","\u210d"),ie(le,ce,ve,"H","\u210d"),ie(ae,ce,ve,"N","\u2115"),ie(le,ce,ve,"N","\u2115"),ie(ae,ce,ve,"P","\u2119"),ie(le,ce,ve,"P","\u2119"),ie(ae,ce,ve,"Q","\u211a"),ie(le,ce,ve,"Q","\u211a"),ie(ae,ce,ve,"R","\u211d"),ie(le,ce,ve,"R","\u211d"),ie(ae,ce,ve,"Z","\u2124"),ie(le,ce,ve,"Z","\u2124"),ie(ae,he,ge,"h","\u210e"),ie(le,he,ge,"h","\u210e");let Ae="";for(let e=0;e<52;e++){const t=ze.charAt(e);Ae=String.fromCharCode(55349,56320+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56372+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56424+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56580+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56684+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56736+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56788+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56840+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56944+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),e<26&&(Ae=String.fromCharCode(55349,56632+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56476+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae))}Ae=String.fromCharCode(55349,56668),ie(ae,he,ge,"k",Ae),ie(le,he,ve,"k",Ae);for(let e=0;e<10;e++){const t=e.toString();Ae=String.fromCharCode(55349,57294+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57314+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57324+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57334+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae)}const Te="\xd0\xde\xfe";for(let e=0;e<3;e++){const t=Te.charAt(e);ie(ae,he,ge,t,t),ie(le,he,ve,t,t)}const Be=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Ce=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Ne=function(e,t,r){return se[r][e]&&se[r][e].replace&&(e=se[r][e].replace),{value:e,metrics:N(e,t,r)}},qe=function(e,t,r,n,o){const s=Ne(e,t,r),i=s.metrics;let a;if(e=s.value,i){let t=i.italic;("text"===r||n&&"mathit"===n.font)&&(t=0),a=new K(e,i.height,i.depth,t,i.skew,i.width,o)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),a=new K(e,0,0,0,0,0,o);if(n){a.maxFontSize=n.sizeMultiplier,n.style.isTight()&&a.classes.push("mtight");const e=n.getColor();e&&(a.style.color=e)}return a},Ie=(e,t)=>{if(G(e.classes)!==G(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){const t=e.classes[0];if("mbin"===t||"mord"===t)return!1}for(const r in e.style)if(e.style.hasOwnProperty(r)&&e.style[r]!==t.style[r])return!1;for(const r in t.style)if(t.style.hasOwnProperty(r)&&e.style[r]!==t.style[r])return!1;return!0},Re=function(e){let t=0,r=0,n=0;for(let o=0;ot&&(t=s.height),s.depth>r&&(r=s.depth),s.maxFontSize>n&&(n=s.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},He=function(e,t,r,n){const o=new _(e,t,r,n);return Re(o),o},Oe=(e,t,r,n)=>new _(e,t,r,n),Ee=function(e){const t=new A(e);return Re(t),t},Le=function(e,t,r){let n,o="";switch(e){case"amsrm":o="AMS";break;case"textrm":o="Main";break;case"textsf":o="SansSerif";break;case"texttt":o="Typewriter";break;default:o=e}return n="textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular",o+"-"+n},De={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ve={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]};var Pe={fontMap:De,makeSymbol:qe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Ne(e,"Main-Bold",t).metrics?qe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===se[t][e].font?qe(e,"Main-Regular",t,r,n):qe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:He,makeSvgSpan:Oe,makeLineSpan:function(e,t,r){const n=He([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=F(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){const o=new j(e,t,r,n);return Re(o),o},makeFragment:Ee,wrapFragment:function(e,t){return e instanceof A?He([],[e],t):e},makeVList:function(e,t){const{children:r,depth:n}=function(e){if("individualShift"===e.positionType){const t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth;let o=n;for(let e=1;e0)return qe(s,h,o,t,i.concat(c));if(l){let e,n;if("boldsymbol"===l){const t=function(e,t,r,n,o){return"textord"!==o&&Ne(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(s,o,0,0,r);e=t.fontName,n=[t.fontClass]}else a?(e=De[l].fontName,n=[l]):(e=Le(l,t.fontWeight,t.fontShape),n=[l,t.fontWeight,t.fontShape]);if(Ne(s,e,o).metrics)return qe(s,e,o,t,i.concat(n));if(ke.hasOwnProperty(s)&&"Typewriter"===e.slice(0,10)){const r=[];for(let a=0;a{const r=He(["mspace"],[],t),n=P(e,t);return r.style.marginRight=F(n),r},staticSvg:function(e,t){const[r,n,o]=Ve[e],s=new Q(r),i=new J([s],{width:F(n),height:F(o),style:"width:"+F(n),viewBox:"0 0 "+1e3*n+" "+1e3*o,preserveAspectRatio:"xMinYMin"}),a=Oe(["overlay"],[i],t);return a.height=o,a.style.height=F(o),a.style.width=F(n),a},svgData:Ve,tryCombineChars:e=>{for(let t=0;t{const r=t.classes[0],n=e.classes[0];"mbin"===r&&l.contains(tt,n)?t.classes[0]="mord":"mbin"===n&&l.contains(et,r)&&(e.classes[0]="mord")}),{node:i},a,h),st(o,((e,t)=>{const r=lt(t),n=lt(e),o=r&&n?e.hasClass("mtight")?Xe[r][n]:Ye[r][n]:null;if(o)return Pe.makeGlue(o,s)}),{node:i},a,h),o},st=function(e,t,r,n,o){n&&e.push(n);let s=0;for(;sr=>{e.splice(t+1,0,r),s++})(s)}n&&e.pop()},it=function(e){return e instanceof A||e instanceof j||e instanceof _&&e.hasClass("enclosing")?e:null},at=function(e,t){const r=it(e);if(r){const e=r.children;if(e.length){if("right"===t)return at(e[e.length-1],"right");if("left"===t)return at(e[0],"left")}}return e},lt=function(e,t){return e?(t&&(e=at(e,t)),nt[e.classes[0]]||null):null},ht=function(e,t){const r=["nulldelimiter"].concat(e.baseSizingClasses());return Qe(t.concat(r))},ct=function(e,t,r){if(!e)return Qe();if(_e[e.type]){let n=_e[e.type](e,t);if(r&&t.size!==r.size){n=Qe(t.sizingClasses(r),[n],t);const e=t.sizeMultiplier/r.sizeMultiplier;n.height*=e,n.depth*=e}return n}throw new n("Got group of unknown type: '"+e.type+"'")};function mt(e,t){const r=Qe(["base"],e,t),n=Qe(["strut"]);return n.style.height=F(r.height+r.depth),r.depth&&(n.style.verticalAlign=F(-r.depth)),r.children.unshift(n),r}function pt(e,t){let r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);const n=ot(e,t,"root");let o;2===n.length&&n[1].hasClass("tag")&&(o=n.pop());const s=[];let i,a=[];for(let e=0;e0&&(s.push(mt(a,t)),a=[]),s.push(n[e]));a.length>0&&s.push(mt(a,t)),r?(i=mt(ot(r,t,!0)),i.classes=["tag"],s.push(i)):o&&s.push(o);const l=Qe(["katex-html"],s);if(l.setAttribute("aria-hidden","true"),i){const e=i.children[0];e.style.height=F(l.height+l.depth),l.depth&&(e.style.verticalAlign=F(-l.depth))}return l}function ut(e){return new A(e)}class dt{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){const e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=G(this.classes));for(let t=0;t0&&(e+=' class ="'+l.escape(G(this.classes))+'"'),e+=">";for(let t=0;t",e}toText(){return this.children.map((e=>e.toText())).join("")}}class gt{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return l.escape(this.toText())}toText(){return this.text}}var ft={MathNode:dt,TextNode:gt,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);{const e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",F(this.width)),e}}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},newDocumentFragment:ut};const bt=function(e,t,r){return!se[t][e]||!se[t][e].replace||55349===e.charCodeAt(0)||ke.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=se[t][e].replace),new ft.TextNode(e)},yt=function(e){return 1===e.length?e[0]:new ft.MathNode("mrow",e)},xt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";const r=t.font;if(!r||"mathnormal"===r)return null;const n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathsfit"===r)return"sans-serif-italic";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";let o=e.text;if(l.contains(["\\imath","\\jmath"],o))return null;se[n][o]&&se[n][o].replace&&(o=se[n][o].replace);return N(o,Pe.fontMap[r].fontName,n)?Pe.fontMap[r].variant:null};function wt(e){if(!e)return!1;if("mi"===e.type&&1===e.children.length){const t=e.children[0];return t instanceof gt&&"."===t.text}if("mo"===e.type&&1===e.children.length&&"true"===e.getAttribute("separator")&&"0em"===e.getAttribute("lspace")&&"0em"===e.getAttribute("rspace")){const t=e.children[0];return t instanceof gt&&","===t.text}return!1}const vt=function(e,t,r){if(1===e.length){const n=St(e[0],t);return r&&n instanceof dt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}const n=[];let o;for(let r=0;r=1&&("mn"===o.type||wt(o))){const e=s.children[0];e instanceof dt&&"mn"===e.type&&(e.children=[...o.children,...e.children],n.pop())}else if("mi"===o.type&&1===o.children.length){const e=o.children[0];if(e instanceof gt&&"\u0338"===e.text&&("mo"===s.type||"mi"===s.type||"mn"===s.type)){const e=s.children[0];e instanceof gt&&e.text.length>0&&(e.text=e.text.slice(0,1)+"\u0338"+e.text.slice(1),n.pop())}}}n.push(s),o=s}return n},kt=function(e,t,r){return yt(vt(e,t,r))},St=function(e,t){if(!e)return new ft.MathNode("mrow");if(je[e.type]){return je[e.type](e,t)}throw new n("Got group of unknown type: '"+e.type+"'")};function Mt(e,t,r,n,o){const s=vt(e,r);let i;i=1===s.length&&s[0]instanceof dt&&l.contains(["mrow","mtable"],s[0].type)?s[0]:new ft.MathNode("mrow",s);const a=new ft.MathNode("annotation",[new ft.TextNode(t)]);a.setAttribute("encoding","application/x-tex");const h=new ft.MathNode("semantics",[i,a]),c=new ft.MathNode("math",[h]);c.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&c.setAttribute("display","block");const m=o?"katex":"katex-mathml";return Pe.makeSpan([m],[c])}const zt=function(e){return new E({style:e.displayMode?w.DISPLAY:w.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},At=function(e,t){if(t.displayMode){const r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Pe.makeSpan(r,[e])}return e},Tt=function(e,t,r){const n=zt(r);let o;if("mathml"===r.output)return Mt(e,t,n,r.displayMode,!0);if("html"===r.output){const t=pt(e,n);o=Pe.makeSpan(["katex"],[t])}else{const s=Mt(e,t,n,r.displayMode,!1),i=pt(e,n);o=Pe.makeSpan(["katex"],[s,i])}return At(o,r)};const Bt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Ct={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]};var Nt=function(e,t,r,n,o){let s;const i=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(s=Pe.makeSpan(["stretchy",t],[],o),"fbox"===t){const e=o.color&&o.getColor();e&&(s.style.borderColor=e)}}else{const e=[];/^[bx]cancel$/.test(t)&&e.push(new ee({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&e.push(new ee({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));const r=new J(e,{width:"100%",height:F(i)});s=Pe.makeSvgSpan([],[r],o)}return s.height=i,s.style.height=F(i),s},qt=function(e){const t=new ft.MathNode("mo",[new ft.TextNode(Bt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},It=function(e,t){const{span:r,minWidth:n,height:o}=function(){let r=4e5;const n=e.label.slice(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){const s="ordgroup"===(o=e.base).type?o.body.length:1;let i,a,l;if(s>5)"widehat"===n||"widecheck"===n?(i=420,r=2364,l=.42,a=n+"4"):(i=312,r=2340,l=.34,a="tilde4");else{const e=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][e],i=[0,239,300,360,420][e],l=[0,.24,.3,.3,.36,.42][e],a=n+e):(r=[0,600,1033,2339,2340][e],i=[0,260,286,306,312][e],l=[0,.26,.286,.3,.306,.34][e],a="tilde"+e)}const h=new Q(a),c=new J([h],{width:"100%",height:F(l),viewBox:"0 0 "+r+" "+i,preserveAspectRatio:"none"});return{span:Pe.makeSvgSpan([],[c],t),minWidth:0,height:l}}{const e=[],o=Ct[n],[s,i,a]=o,l=a/1e3,h=s.length;let c,m;if(1===h){c=["hide-tail"],m=[o[3]]}else if(2===h)c=["halfarrow-left","halfarrow-right"],m=["xMinYMin","xMaxYMin"];else{if(3!==h)throw new Error("Correct katexImagesData or update code here to support\n "+h+" children.");c=["brace-left","brace-center","brace-right"],m=["xMinYMin","xMidYMin","xMaxYMin"]}for(let n=0;n0&&(r.style.minWidth=F(n)),r};function Rt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Ht(e){const t=Ot(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ot(e){return e&&("atom"===e.type||ne.hasOwnProperty(e.type))?e:null}const Et=(e,t)=>{let r,n,o;e&&"supsub"===e.type?(n=Rt(e.base,"accent"),r=n.base,e.base=r,o=function(e){if(e instanceof _)return e;throw new Error("Expected span but got "+String(e)+".")}(ct(e,t)),e.base=n):(n=Rt(e,"accent"),r=n.base);const s=ct(r,t.havingCrampedStyle());let i=0;if(n.isShifty&&l.isCharacterBox(r)){const e=l.getBaseElem(r);i=te(ct(e,t.havingCrampedStyle())).skew}const a="\\c"===n.label;let h,c=a?s.height+s.depth:Math.min(s.height,t.fontMetrics().xHeight);if(n.isStretchy)h=It(n,t),h=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:i>0?{width:"calc(100% - "+F(2*i)+")",marginLeft:F(2*i)}:void 0}]},t);else{let e,r;"\\vec"===n.label?(e=Pe.staticSvg("vec",t),r=Pe.svgData.vec[1]):(e=Pe.makeOrd({mode:n.mode,text:n.label},t,"textord"),e=te(e),e.italic=0,r=e.width,a&&(c+=e.depth)),h=Pe.makeSpan(["accent-body"],[e]);const o="\\textcircled"===n.label;o&&(h.classes.push("accent-full"),c=s.height);let l=i;o||(l-=r/2),h.style.left=F(l),"\\textcircled"===n.label&&(h.style.top=".2em"),h=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}const m=Pe.makeSpan(["mord","accent"],[h],t);return o?(o.children[0]=m,o.height=Math.max(m.height,o.height),o.classes[0]="mord",o):m},Lt=(e,t)=>{const r=e.isStretchy?qt(e.label):new ft.MathNode("mo",[bt(e.label,e.mode)]),n=new ft.MathNode("mover",[St(e.base,t),r]);return n.setAttribute("accent","true"),n},Dt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((e=>"\\"+e)).join("|"));$e({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{const r=Ke(t[0]),n=!Dt.test(e.funcName),o=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:o,base:r}},htmlBuilder:Et,mathmlBuilder:Lt}),$e({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{const r=t[0];let n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Et,mathmlBuilder:Lt}),$e({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:o}},htmlBuilder:(e,t)=>{const r=ct(e.base,t),n=It(e,t),o="\\utilde"===e.label?.12:0,s=Pe.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:o},{type:"elem",elem:r}]},t);return Pe.makeSpan(["mord","accentunder"],[s],t)},mathmlBuilder:(e,t)=>{const r=qt(e.label),n=new ft.MathNode("munder",[St(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});const Vt=e=>{const t=new ft.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};$e({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){let{parser:n,funcName:o}=e;return{type:"xArrow",mode:n.mode,label:o,body:t[0],below:r[0]}},htmlBuilder(e,t){const r=t.style;let n=t.havingStyle(r.sup());const o=Pe.wrapFragment(ct(e.body,n,t),t),s="\\x"===e.label.slice(0,2)?"x":"cd";let i;o.classes.push(s+"-arrow-pad"),e.below&&(n=t.havingStyle(r.sub()),i=Pe.wrapFragment(ct(e.below,n,t),t),i.classes.push(s+"-arrow-pad"));const a=It(e,t),l=-t.fontMetrics().axisHeight+.5*a.height;let h,c=-t.fontMetrics().axisHeight-.5*a.height-.111;if((o.depth>.25||"\\xleftequilibrium"===e.label)&&(c-=o.depth),i){const e=-t.fontMetrics().axisHeight+i.height+.5*a.height+.111;h=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:c},{type:"elem",elem:a,shift:l},{type:"elem",elem:i,shift:e}]},t)}else h=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:c},{type:"elem",elem:a,shift:l}]},t);return h.children[0].children[0].children[1].classes.push("svg-align"),Pe.makeSpan(["mrel","x-arrow"],[h],t)},mathmlBuilder(e,t){const r=qt(e.label);let n;if(r.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){const o=Vt(St(e.body,t));if(e.below){const s=Vt(St(e.below,t));n=new ft.MathNode("munderover",[r,s,o])}else n=new ft.MathNode("mover",[r,o])}else if(e.below){const o=Vt(St(e.below,t));n=new ft.MathNode("munder",[r,o])}else n=Vt(),n=new ft.MathNode("mover",[r,n]);return n}});const Pt=Pe.makeSpan;function Ft(e,t){const r=ot(e.body,t,!0);return Pt([e.mclass],r,t)}function Gt(e,t){let r;const n=vt(e.body,t);return"minner"===e.mclass?r=new ft.MathNode("mpadded",n):"mord"===e.mclass?e.isCharacterBox?(r=n[0],r.type="mi"):r=new ft.MathNode("mi",n):(e.isCharacterBox?(r=n[0],r.type="mo"):r=new ft.MathNode("mo",n),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}$e({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:Je(o),isCharacterBox:l.isCharacterBox(o)}},htmlBuilder:Ft,mathmlBuilder:Gt});const Ut=e=>{const t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};$e({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){let{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:Ut(t[0]),body:Je(t[1]),isCharacterBox:l.isCharacterBox(t[1])}}}),$e({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){let{parser:r,funcName:n}=e;const o=t[1],s=t[0];let i;i="\\stackrel"!==n?Ut(o):"mrel";const a={type:"op",mode:o.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:Je(o)},h={type:"supsub",mode:s.mode,base:a,sup:"\\underset"===n?null:s,sub:"\\underset"===n?s:null};return{type:"mclass",mode:r.mode,mclass:i,body:[h],isCharacterBox:l.isCharacterBox(h)}},htmlBuilder:Ft,mathmlBuilder:Gt}),$e({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:Ut(t[0]),body:Je(t[0])}},htmlBuilder(e,t){const r=ot(e.body,t,!0),n=Pe.makeSpan([e.mclass],r,t);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(e,t){const r=vt(e.body,t),n=new ft.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});const Yt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},Xt=e=>"textord"===e.type&&"@"===e.text;function Wt(e,t,r){const n=Yt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":{const e={type:"atom",text:n,mode:"math",family:"rel"},o={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[e],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[o],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{const e={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[e],[])}default:return{type:"textord",text:" ",mode:"math"}}}$e({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder(e,t){const r=t.havingStyle(t.style.sup()),n=Pe.wrapFragment(ct(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=F(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(e,t){let r=new ft.MathNode("mrow",[St(e.label,t)]);return r=new ft.MathNode("mpadded",[r]),r.setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new ft.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),$e({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){let{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){const r=Pe.wrapFragment(ct(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(e,t){return new ft.MathNode("mrow",[St(e.fragment,t)])}}),$e({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;const o=Rt(t[0],"ordgroup").body;let s="";for(let e=0;e=1114111)throw new n("\\@char with invalid code point "+s);return a<=65535?i=String.fromCharCode(a):(a-=65536,i=String.fromCharCode(55296+(a>>10),56320+(1023&a))),{type:"textord",mode:r.mode,text:i}}});const _t=(e,t)=>{const r=ot(e.body,t.withColor(e.color),!1);return Pe.makeFragment(r)},jt=(e,t)=>{const r=vt(e.body,t.withColor(e.color)),n=new ft.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};$e({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){let{parser:r}=e;const n=Rt(t[0],"color-token").color,o=t[1];return{type:"color",mode:r.mode,color:n,body:Je(o)}},htmlBuilder:_t,mathmlBuilder:jt}),$e({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){let{parser:r,breakOnTokenText:n}=e;const o=Rt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",o);const s=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:o,body:s}},htmlBuilder:_t,mathmlBuilder:jt}),$e({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){let{parser:n}=e;const o="["===n.gullet.future().text?n.parseSizeGroup(!0):null,s=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:s,size:o&&Rt(o,"size").value}},htmlBuilder(e,t){const r=Pe.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=F(P(e.size,t)))),r},mathmlBuilder(e,t){const r=new ft.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",F(P(e.size,t)))),r}});const $t={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},Zt=e=>{const t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},Kt=(e,t,r,n)=>{let o=e.gullet.macros.get(r.text);null==o&&(r.noexpand=!0,o={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,o,n)};$e({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){let{parser:t,funcName:r}=e;t.consumeSpaces();const o=t.fetch();if($t[o.text])return"\\global"!==r&&"\\\\globallong"!==r||(o.text=$t[o.text]),Rt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",o)}}),$e({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e,o=t.gullet.popToken();const s=o.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(s))throw new n("Expected a control sequence",o);let i,a=0;const l=[[]];for(;"{"!==t.gullet.future().text;)if(o=t.gullet.popToken(),"#"===o.text){if("{"===t.gullet.future().text){i=t.gullet.future(),l[a].push("{");break}if(o=t.gullet.popToken(),!/^[1-9]$/.test(o.text))throw new n('Invalid argument number "'+o.text+'"');if(parseInt(o.text)!==a+1)throw new n('Argument number "'+o.text+'" out of order');a++,l.push([])}else{if("EOF"===o.text)throw new n("Expected a macro definition");l[a].push(o.text)}let{tokens:h}=t.gullet.consumeArg();return i&&h.unshift(i),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h),h.reverse()),t.gullet.macros.set(s,{tokens:h,numArgs:a,delimiters:l},r===$t[r]),{type:"internal",mode:t.mode}}}),$e({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e;const n=Zt(t.gullet.popToken());t.gullet.consumeSpaces();const o=(e=>{let t=e.gullet.popToken();return"="===t.text&&(t=e.gullet.popToken()," "===t.text&&(t=e.gullet.popToken())),t})(t);return Kt(t,n,o,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),$e({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e;const n=Zt(t.gullet.popToken()),o=t.gullet.popToken(),s=t.gullet.popToken();return Kt(t,n,s,"\\\\globalfuture"===r),t.gullet.pushToken(s),t.gullet.pushToken(o),{type:"internal",mode:t.mode}}});const Jt=function(e,t,r){const n=N(se.math[e]&&se.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},Qt=function(e,t,r,n){const o=r.havingBaseStyle(t),s=Pe.makeSpan(n.concat(o.sizingClasses(r)),[e],r),i=o.sizeMultiplier/r.sizeMultiplier;return s.height*=i,s.depth*=i,s.maxFontSize=o.sizeMultiplier,s},er=function(e,t,r){const n=t.havingBaseStyle(r),o=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=F(o),e.height-=o,e.depth+=o},tr=function(e,t,r,n,o,s){const i=function(e,t,r,n){return Pe.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,o,n),a=Qt(Pe.makeSpan(["delimsizing","size"+t],[i],n),w.TEXT,n,s);return r&&er(a,n,w.TEXT),a},rr=function(e,t,r){let n;n="Size1-Regular"===t?"delim-size1":"delim-size4";return{type:"elem",elem:Pe.makeSpan(["delimsizinginner",n],[Pe.makeSpan([],[Pe.makeSymbol(e,t,r)])])}},nr=function(e,t,r){const n=T["Size4-Regular"][e.charCodeAt(0)]?T["Size4-Regular"][e.charCodeAt(0)][4]:T["Size1-Regular"][e.charCodeAt(0)][4],o=new Q("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),s=new J([o],{width:F(n),height:F(t),style:"width:"+F(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),i=Pe.makeSvgSpan([],[s],r);return i.height=t,i.style.height=F(t),i.style.width=F(n),{type:"elem",elem:i}},or={type:"kern",size:-.008},sr=["|","\\lvert","\\rvert","\\vert"],ir=["\\|","\\lVert","\\rVert","\\Vert"],ar=function(e,t,r,n,o,s){let i,a,h,c,m="",p=0;i=h=c=e,a=null;let u="Size1-Regular";"\\uparrow"===e?h=c="\u23d0":"\\Uparrow"===e?h=c="\u2016":"\\downarrow"===e?i=h="\u23d0":"\\Downarrow"===e?i=h="\u2016":"\\updownarrow"===e?(i="\\uparrow",h="\u23d0",c="\\downarrow"):"\\Updownarrow"===e?(i="\\Uparrow",h="\u2016",c="\\Downarrow"):l.contains(sr,e)?(h="\u2223",m="vert",p=333):l.contains(ir,e)?(h="\u2225",m="doublevert",p=556):"["===e||"\\lbrack"===e?(i="\u23a1",h="\u23a2",c="\u23a3",u="Size4-Regular",m="lbrack",p=667):"]"===e||"\\rbrack"===e?(i="\u23a4",h="\u23a5",c="\u23a6",u="Size4-Regular",m="rbrack",p=667):"\\lfloor"===e||"\u230a"===e?(h=i="\u23a2",c="\u23a3",u="Size4-Regular",m="lfloor",p=667):"\\lceil"===e||"\u2308"===e?(i="\u23a1",h=c="\u23a2",u="Size4-Regular",m="lceil",p=667):"\\rfloor"===e||"\u230b"===e?(h=i="\u23a5",c="\u23a6",u="Size4-Regular",m="rfloor",p=667):"\\rceil"===e||"\u2309"===e?(i="\u23a4",h=c="\u23a5",u="Size4-Regular",m="rceil",p=667):"("===e||"\\lparen"===e?(i="\u239b",h="\u239c",c="\u239d",u="Size4-Regular",m="lparen",p=875):")"===e||"\\rparen"===e?(i="\u239e",h="\u239f",c="\u23a0",u="Size4-Regular",m="rparen",p=875):"\\{"===e||"\\lbrace"===e?(i="\u23a7",a="\u23a8",c="\u23a9",h="\u23aa",u="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(i="\u23ab",a="\u23ac",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(i="\u23a7",c="\u23a9",h="\u23aa",u="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(i="\u23ab",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(i="\u23a7",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(i="\u23ab",c="\u23a9",h="\u23aa",u="Size4-Regular");const d=Jt(i,u,o),g=d.height+d.depth,f=Jt(h,u,o),b=f.height+f.depth,y=Jt(c,u,o),x=y.height+y.depth;let v=0,k=1;if(null!==a){const e=Jt(a,u,o);v=e.height+e.depth,k=2}const S=g+x+v,M=S+Math.max(0,Math.ceil((t-S)/(k*b)))*k*b;let z=n.fontMetrics().axisHeight;r&&(z*=n.sizeMultiplier);const A=M/2-z,T=[];if(m.length>0){const e=M-g-x,t=Math.round(1e3*M),r=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(m,Math.round(1e3*e)),o=new Q(m,r),s=(p/1e3).toFixed(3)+"em",i=(t/1e3).toFixed(3)+"em",a=new J([o],{width:s,height:i,viewBox:"0 0 "+p+" "+t}),l=Pe.makeSvgSpan([],[a],n);l.height=t/1e3,l.style.width=s,l.style.height=i,T.push({type:"elem",elem:l})}else{if(T.push(rr(c,u,o)),T.push(or),null===a){const e=M-g-x+.016;T.push(nr(h,e,n))}else{const e=(M-g-x-v)/2+.016;T.push(nr(h,e,n)),T.push(or),T.push(rr(a,u,o)),T.push(or),T.push(nr(h,e,n))}T.push(or),T.push(rr(i,u,o))}const B=n.havingBaseStyle(w.TEXT),C=Pe.makeVList({positionType:"bottom",positionData:A,children:T},B);return Qt(Pe.makeSpan(["delimsizing","mult"],[C],B),w.TEXT,n,s)},lr=.08,hr=function(e,t,r,n,o){const s=function(e,t,r){t*=1e3;let n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,M);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,M,r)}return n}(e,n,r),i=new Q(e,s),a=new J([i],{width:"400em",height:F(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Pe.makeSvgSpan(["hide-tail"],[a],o)},cr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],mr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],pr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],ur=[0,1.2,1.8,2.4,3],dr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],gr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"stack"}],fr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],br=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},yr=function(e,t,r,n){for(let o=Math.min(2,3-n.style.size);ot)return r[o]}return r[r.length-1]},xr=function(e,t,r,n,o,s){let i;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),i=l.contains(pr,e)?dr:l.contains(cr,e)?fr:gr;const a=yr(e,t,i,n);return"small"===a.type?function(e,t,r,n,o,s){const i=Pe.makeSymbol(e,"Main-Regular",o,n),a=Qt(i,t,n,s);return r&&er(a,n,t),a}(e,a.style,r,n,o,s):"large"===a.type?tr(e,a.size,r,n,o,s):ar(e,t,r,n,o,s)};var wr={sqrtImage:function(e,t){const r=t.havingBaseSizing(),n=yr("\\surd",e*r.sizeMultiplier,fr,r);let o=r.sizeMultiplier;const s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness);let i,a,l=0,h=0,c=0;return"small"===n.type?(c=1e3+1e3*s+80,e<1?o=1:e<1.4&&(o=.7),l=(1+s+lr)/o,h=(1+s)/o,i=hr("sqrtMain",l,c,s,t),i.style.minWidth="0.853em",a=.833/o):"large"===n.type?(c=1080*ur[n.size],h=(ur[n.size]+s)/o,l=(ur[n.size]+s+lr)/o,i=hr("sqrtSize"+n.size,l,c,s,t),i.style.minWidth="1.02em",a=1/o):(l=e+s+lr,h=e+s,c=Math.floor(1e3*e+s)+80,i=hr("sqrtTall",l,c,s,t),i.style.minWidth="0.742em",a=1.056),i.height=h,i.style.height=F(l),{span:i,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,o,s){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(cr,e)||l.contains(pr,e))return tr(e,t,!1,r,o,s);if(l.contains(mr,e))return ar(e,ur[t],!1,r,o,s);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:ur,customSizedDelim:xr,leftRightDelim:function(e,t,r,n,o,s){const i=n.fontMetrics().axisHeight*n.sizeMultiplier,a=5/n.fontMetrics().ptPerEm,l=Math.max(t-i,r+i),h=Math.max(l/500*901,2*l-a);return xr(e,h,!0,n,o,s)}};const vr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},kr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Sr(e,t){const r=Ot(e);if(r&&l.contains(kr,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Mr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}$e({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{const r=Sr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:vr[e.funcName].size,mclass:vr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Pe.makeSpan([e.mclass]):wr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{const t=[];"."!==e.delim&&t.push(bt(e.delim,e.mode));const r=new ft.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");const n=F(wr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),$e({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Sr(t[0],e).text,color:r}}}),$e({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=Sr(t[0],e),n=e.parser;++n.leftrightDepth;const o=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);const s=Rt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:o,left:r.text,right:s.delim,rightColor:s.color}},htmlBuilder:(e,t)=>{Mr(e);const r=ot(e.body,t,!0,["mopen","mclose"]);let n,o,s=0,i=0,a=!1;for(let e=0;e{Mr(e);const r=vt(e.body,t);if("."!==e.left){const t=new ft.MathNode("mo",[bt(e.left,e.mode)]);t.setAttribute("fence","true"),r.unshift(t)}if("."!==e.right){const t=new ft.MathNode("mo",[bt(e.right,e.mode)]);t.setAttribute("fence","true"),e.rightColor&&t.setAttribute("mathcolor",e.rightColor),r.push(t)}return yt(r)}}),$e({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=Sr(t[0],e);if(!e.parser.leftrightDepth)throw new n("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{let r;if("."===e.delim)r=ht(t,[]);else{r=wr.sizedDelim(e.delim,1,t,e.mode,[]);const n={delim:e.delim,options:t};r.isMiddle=n}return r},mathmlBuilder:(e,t)=>{const r="\\vert"===e.delim||"|"===e.delim?bt("|","text"):bt(e.delim,e.mode),n=new ft.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n}});const zr=(e,t)=>{const r=Pe.wrapFragment(ct(e.body,t),t),n=e.label.slice(1);let o,s=t.sizeMultiplier,i=0;const a=l.isCharacterBox(e.body);if("sout"===n)o=Pe.makeSpan(["stretchy","sout"]),o.height=t.fontMetrics().defaultRuleThickness/s,i=-.5*t.fontMetrics().xHeight;else if("phase"===n){const e=P({number:.6,unit:"pt"},t),n=P({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;const a=r.height+r.depth+e+n;r.style.paddingLeft=F(a/2+e);const l=Math.floor(1e3*a*s),c="M400000 "+(h=l)+" H0 L"+h/2+" 0 l65 45 L145 "+(h-80)+" H400000z",m=new J([new Q("phase",c)],{width:"400em",height:F(l/1e3),viewBox:"0 0 400000 "+l,preserveAspectRatio:"xMinYMin slice"});o=Pe.makeSvgSpan(["hide-tail"],[m],t),o.style.height=F(a),i=r.depth+e+n}else{/cancel/.test(n)?a||r.classes.push("cancel-pad"):"angl"===n?r.classes.push("anglpad"):r.classes.push("boxpad");let s=0,l=0,h=0;/box/.test(n)?(h=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),s=t.fontMetrics().fboxsep+("colorbox"===n?0:h),l=s):"angl"===n?(h=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness),s=4*h,l=Math.max(0,.25-r.depth)):(s=a?.2:0,l=s),o=Nt(r,n,s,l,t),/fbox|boxed|fcolorbox/.test(n)?(o.style.borderStyle="solid",o.style.borderWidth=F(h)):"angl"===n&&.049!==h&&(o.style.borderTopWidth=F(h),o.style.borderRightWidth=F(h)),i=r.depth+l,e.backgroundColor&&(o.style.backgroundColor=e.backgroundColor,e.borderColor&&(o.style.borderColor=e.borderColor))}var h;let c;if(e.backgroundColor)c=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:i},{type:"elem",elem:r,shift:0}]},t);else{const e=/cancel|phase/.test(n)?["svg-align"]:[];c=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:o,shift:i,wrapperClasses:e}]},t)}return/cancel/.test(n)&&(c.height=r.height,c.depth=r.depth),/cancel/.test(n)&&!a?Pe.makeSpan(["mord","cancel-lap"],[c],t):Pe.makeSpan(["mord"],[c],t)},Ar=(e,t)=>{let r=0;const n=new ft.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[St(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){const r=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+r+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};$e({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){let{parser:n,funcName:o}=e;const s=Rt(t[0],"color-token").color,i=t[1];return{type:"enclose",mode:n.mode,label:o,backgroundColor:s,body:i}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){let{parser:n,funcName:o}=e;const s=Rt(t[0],"color-token").color,i=Rt(t[1],"color-token").color,a=t[2];return{type:"enclose",mode:n.mode,label:o,backgroundColor:i,borderColor:s,body:a}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),$e({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"enclose",mode:r.mode,label:n,body:o}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){let{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});const Tr={};function Br(e){let{type:t,names:r,props:n,handler:o,htmlBuilder:s,mathmlBuilder:i}=e;const a={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:o};for(let e=0;e{if(!e.parser.settings.displayMode)throw new n("{"+e.envName+"} can be used only in display mode.")};function Or(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function Er(e,t,r){let{hskipBeforeAndAfter:o,addJot:s,cols:i,arraystretch:a,colSeparationType:l,autoTag:h,singleRow:c,emptySingleRow:m,maxNumCols:p,leqno:u}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!a){const t=e.gullet.expandMacroAsText("\\arraystretch");if(null==t)a=1;else if(a=parseFloat(t),!a||a<0)throw new n("Invalid \\arraystretch: "+t)}e.gullet.beginGroup();let d=[];const g=[d],f=[],b=[],y=null!=h?[]:void 0;function x(){h&&e.gullet.macros.set("\\@eqnsw","1",!0)}function w(){y&&(e.gullet.macros.get("\\df@tag")?(y.push(e.subparse([new Ir("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):y.push(Boolean(h)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(x(),b.push(Rr(e));;){let t=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),t={type:"ordgroup",mode:e.mode,body:t},r&&(t={type:"styling",mode:e.mode,style:r,body:[t]}),d.push(t);const o=e.fetch().text;if("&"===o){if(p&&d.length===p){if(c||l)throw new n("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===o){w(),1===d.length&&"styling"===t.type&&0===t.body[0].body.length&&(g.length>1||!m)&&g.pop(),b.length0&&(x+=.25),c.push({pos:x,isDashed:e[t]})}for(v(i[0]),r=0;r0&&(p+=y,le)))for(r=0;r=a)continue;(o>0||e.hskipBeforeAndAfter)&&(i=l.deflt(c.pregap,u),0!==i&&(z=Pe.makeSpan(["arraycolsep"],[]),z.style.width=F(i),M.push(z)));let d=[];for(r=0;r0){const e=Pe.makeLineSpan("hline",t,m),r=Pe.makeLineSpan("hdashline",t,m),n=[{type:"elem",elem:h,shift:0}];for(;c.length>0;){const t=c.pop(),o=t.pos-k;t.isDashed?n.push({type:"elem",elem:r,shift:o}):n.push({type:"elem",elem:e,shift:o})}h=Pe.makeVList({positionType:"individualShift",children:n},t)}if(0===T.length)return Pe.makeSpan(["mord"],[h],t);{let e=Pe.makeVList({positionType:"individualShift",children:T},t);return e=Pe.makeSpan(["tag"],[e],t),Pe.makeFragment([h,e])}},Vr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){const r=[],n=new ft.MathNode("mtd",[],["mtr-glue"]),o=new ft.MathNode("mtd",[],["mml-eqn-num"]);for(let s=0;s0){const t=e.cols;let r="",n=!1,o=0,i=t.length;"separator"===t[0].type&&(a+="top ",o=1),"separator"===t[t.length-1].type&&(a+="bottom ",i-=1);for(let e=o;e0?"left ":"",a+=c[c.length-1].length>0?"right ":"";for(let e=1;e-1?"alignat":"align",s="split"===e.envName,i=Er(e.parser,{cols:r,addJot:!0,autoTag:s?void 0:Or(e.envName),emptySingleRow:!0,colSeparationType:o,maxNumCols:s?2:void 0,leqno:e.parser.settings.leqno},"display");let a,l=0;const h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){let e="";for(let r=0;r0&&c&&(n=1),r[e]={type:"align",align:t,pregap:n,postgap:0}}return i.colSeparationType=c?"align":"alignat",i};Br({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){const r=(Ot(t[0])?[t[0]]:Rt(t[0],"ordgroup").body).map((function(e){const t=Ht(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),o={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,o,Lr(e.envName))},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){const t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")];let r="c";const o={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){const t=e.parser;if(t.consumeSpaces(),"["===t.fetch().text){if(t.consume(),t.consumeSpaces(),r=t.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",t.nextToken);t.consume(),t.consumeSpaces(),t.expect("]"),t.consume(),o.cols=[{type:"align",align:r}]}}const s=Er(e.parser,o,Lr(e.envName)),i=Math.max(0,...s.body.map((e=>e.length)));return s.cols=new Array(i).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[s],left:t[0],right:t[1],rightColor:void 0}:s},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){const t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){const r=(Ot(t[0])?[t[0]]:Rt(t[0],"ordgroup").body).map((function(e){const t=Ht(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");let o={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if(o=Er(e.parser,o,"script"),o.body.length>0&&o.body[0].length>1)throw new n("{subarray} can contain only one column");return o},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){const t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Lr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){l.contains(["gather","gather*"],e.envName)&&Hr(e);const t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Or(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Hr(e);const t={autoTag:Or(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["CD"],props:{numArgs:0},handler(e){return Hr(e),function(e){const t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();const r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}let r=[];const o=[r];for(let a=0;a-1);else{if(!("<>AV".indexOf(o)>-1))throw new n('Expected one of "<>AV=|." after @',l[t]);for(let e=0;e<2;e++){let r=!0;for(let h=t+1;h{const r=e.font,n=t.withFont(r);return ct(e.body,n)},Yr=(e,t)=>{const r=e.font,n=t.withFont(r);return St(e.body,n)},Xr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};$e({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=Ke(t[0]);let s=n;return s in Xr&&(s=Xr[s]),{type:"font",mode:r.mode,font:s.slice(1),body:o}},htmlBuilder:Ur,mathmlBuilder:Yr}),$e({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{let{parser:r}=e;const n=t[0],o=l.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:Ut(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:o}}}),$e({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{let{parser:r,funcName:n,breakOnTokenText:o}=e;const{mode:s}=r,i=r.parseExpression(!0,o);return{type:"font",mode:s,font:"math"+n.slice(1),body:{type:"ordgroup",mode:r.mode,body:i}}},htmlBuilder:Ur,mathmlBuilder:Yr});const Wr=(e,t)=>{let r=t;return"display"===e?r=r.id>=w.SCRIPT.id?r.text():w.DISPLAY:"text"===e&&r.size===w.DISPLAY.size?r=w.TEXT:"script"===e?r=w.SCRIPT:"scriptscript"===e&&(r=w.SCRIPTSCRIPT),r},_r=(e,t)=>{const r=Wr(e.size,t.style),n=r.fracNum(),o=r.fracDen();let s;s=t.havingStyle(n);const i=ct(e.numer,s,t);if(e.continued){const e=8.5/t.fontMetrics().ptPerEm,r=3.5/t.fontMetrics().ptPerEm;i.height=i.height0?3*c:7*c,u=t.fontMetrics().denom1):(h>0?(m=t.fontMetrics().num2,p=c):(m=t.fontMetrics().num3,p=3*c),u=t.fontMetrics().denom2),l){const e=t.fontMetrics().axisHeight;m-i.depth-(e+.5*h){let r=new ft.MathNode("mfrac",[St(e.numer,t),St(e.denom,t)]);if(e.hasBarLine){if(e.barSize){const n=P(e.barSize,t);r.setAttribute("linethickness",F(n))}}else r.setAttribute("linethickness","0px");const n=Wr(e.size,t.style);if(n.size!==t.style.size){r=new ft.MathNode("mstyle",[r]);const e=n.size===w.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",e),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){const t=[];if(null!=e.leftDelim){const r=new ft.MathNode("mo",[new ft.TextNode(e.leftDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}if(t.push(r),null!=e.rightDelim){const r=new ft.MathNode("mo",[new ft.TextNode(e.rightDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}return yt(t)}return r};$e({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];let i,a=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":i=!0;break;case"\\\\atopfrac":i=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":i=!1,a="(",l=")";break;case"\\\\bracefrac":i=!1,a="\\{",l="\\}";break;case"\\\\brackfrac":i=!1,a="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:r.mode,continued:!1,numer:o,denom:s,hasBarLine:i,leftDelim:a,rightDelim:l,size:h,barSize:null}},htmlBuilder:_r,mathmlBuilder:jr}),$e({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:o,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),$e({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){let t,{parser:r,funcName:n,token:o}=e;switch(n){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:o}}});const $r=["display","text","script","scriptscript"],Zr=function(e){let t=null;return e.length>0&&(t=e,t="."===t?null:t),t};$e({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){let{parser:r}=e;const n=t[4],o=t[5],s=Ke(t[0]),i="atom"===s.type&&"open"===s.family?Zr(s.text):null,a=Ke(t[1]),l="atom"===a.type&&"close"===a.family?Zr(a.text):null,h=Rt(t[2],"size");let c,m=null;h.isBlank?c=!0:(m=h.value,c=m.number>0);let p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){const e=Rt(u.body[0],"textord");p=$r[Number(e.text)]}}else u=Rt(u,"textord"),p=$r[Number(u.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:c,barSize:m,leftDelim:i,rightDelim:l,size:p}},htmlBuilder:_r,mathmlBuilder:jr}),$e({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){let{parser:r,funcName:n,token:o}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Rt(t[0],"size").value,token:o}}}),$e({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Rt(t[1],"infix").size),i=t[2],a=s.number>0;return{type:"genfrac",mode:r.mode,numer:o,denom:i,continued:!1,hasBarLine:a,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:_r,mathmlBuilder:jr});const Kr=(e,t)=>{const r=t.style;let n,o;"supsub"===e.type?(n=e.sup?ct(e.sup,t.havingStyle(r.sup()),t):ct(e.sub,t.havingStyle(r.sub()),t),o=Rt(e.base,"horizBrace")):o=Rt(e,"horizBrace");const s=ct(o.base,t.havingBaseStyle(w.DISPLAY)),i=It(o,t);let a;if(o.isOver?(a=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:i}]},t),a.children[0].children[0].children[1].classes.push("svg-align")):(a=Pe.makeVList({positionType:"bottom",positionData:s.depth+.1+i.height,children:[{type:"elem",elem:i},{type:"kern",size:.1},{type:"elem",elem:s}]},t),a.children[0].children[0].children[0].classes.push("svg-align")),n){const e=Pe.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t);a=o.isOver?Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"kern",size:.2},{type:"elem",elem:n}]},t):Pe.makeVList({positionType:"bottom",positionData:e.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:e}]},t)}return Pe.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t)};$e({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:Kr,mathmlBuilder:(e,t)=>{const r=qt(e.label);return new ft.MathNode(e.isOver?"mover":"munder",[St(e.base,t),r])}}),$e({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[1],o=Rt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:o})?{type:"href",mode:r.mode,href:o,body:Je(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{const r=ot(e.body,t,!1);return Pe.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{let r=kt(e.body,t);return r instanceof dt||(r=new dt("mrow",[r])),r.setAttribute("href",e.href),r}}),$e({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=Rt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");const o=[];for(let e=0;e{let{parser:r,funcName:o,token:s}=e;const i=Rt(t[0],"raw").string,a=t[1];let l;r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");const h={};switch(o){case"\\htmlClass":h.class=i,l={command:"\\htmlClass",class:i};break;case"\\htmlId":h.id=i,l={command:"\\htmlId",id:i};break;case"\\htmlStyle":h.style=i,l={command:"\\htmlStyle",style:i};break;case"\\htmlData":{const e=i.split(",");for(let t=0;t{const r=ot(e.body,t,!1),n=["enclosing"];e.attributes.class&&n.push(...e.attributes.class.trim().split(/\s+/));const o=Pe.makeSpan(n,r,t);for(const t in e.attributes)"class"!==t&&e.attributes.hasOwnProperty(t)&&o.setAttribute(t,e.attributes[t]);return o},mathmlBuilder:(e,t)=>kt(e.body,t)}),$e({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:Je(t[0]),mathml:Je(t[1])}},htmlBuilder:(e,t)=>{const r=ot(e.html,t,!1);return Pe.makeFragment(r)},mathmlBuilder:(e,t)=>kt(e.mathml,t)});const Jr=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};{const t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new n("Invalid size: '"+e+"' in \\includegraphics");const r={number:+(t[1]+t[2]),unit:t[3]};if(!V(r))throw new n("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r}};$e({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{let{parser:o}=e,s={number:0,unit:"em"},i={number:.9,unit:"em"},a={number:0,unit:"em"},l="";if(r[0]){const e=Rt(r[0],"raw").string.split(",");for(let t=0;t{const r=P(e.height,t);let n=0;e.totalheight.number>0&&(n=P(e.totalheight,t)-r);let o=0;e.width.number>0&&(o=P(e.width,t));const s={height:F(r+n)};o>0&&(s.width=F(o)),n>0&&(s.verticalAlign=F(-n));const i=new $(e.src,e.alt,s);return i.height=r,i.depth=n,i},mathmlBuilder:(e,t)=>{const r=new ft.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);const n=P(e.height,t);let o=0;if(e.totalheight.number>0&&(o=P(e.totalheight,t)-n,r.setAttribute("valign",F(-o))),r.setAttribute("height",F(n+o)),e.width.number>0){const n=P(e.width,t);r.setAttribute("width",F(n))}return r.setAttribute("src",e.src),r}}),$e({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=Rt(t[0],"size");if(r.settings.strict){const e="m"===n[1],t="mu"===o.value.unit;e?(t||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+o.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):t&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:o.value}},htmlBuilder(e,t){return Pe.makeGlue(e.dimension,t)},mathmlBuilder(e,t){const r=P(e.dimension,t);return new ft.SpaceNode(r)}}),$e({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:o}},htmlBuilder:(e,t)=>{let r;"clap"===e.alignment?(r=Pe.makeSpan([],[ct(e.body,t)]),r=Pe.makeSpan(["inner"],[r],t)):r=Pe.makeSpan(["inner"],[ct(e.body,t)]);const n=Pe.makeSpan(["fix"],[]);let o=Pe.makeSpan([e.alignment],[r,n],t);const s=Pe.makeSpan(["strut"]);return s.style.height=F(o.height+o.depth),o.depth&&(s.style.verticalAlign=F(-o.depth)),o.children.unshift(s),o=Pe.makeSpan(["thinbox"],[o],t),Pe.makeSpan(["mord","vbox"],[o],t)},mathmlBuilder:(e,t)=>{const r=new ft.MathNode("mpadded",[St(e.body,t)]);if("rlap"!==e.alignment){const t="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",t+"width")}return r.setAttribute("width","0px"),r}}),$e({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){let{funcName:r,parser:n}=e;const o=n.mode;n.switchMode("math");const s="\\("===r?"\\)":"$",i=n.parseExpression(!1,s);return n.expect(s),n.switchMode(o),{type:"styling",mode:n.mode,style:"text",body:i}}}),$e({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new n("Mismatched "+e.funcName)}});const Qr=(e,t)=>{switch(t.style.size){case w.DISPLAY.size:return e.display;case w.TEXT.size:return e.text;case w.SCRIPT.size:return e.script;case w.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};$e({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{let{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:Je(t[0]),text:Je(t[1]),script:Je(t[2]),scriptscript:Je(t[3])}},htmlBuilder:(e,t)=>{const r=Qr(e,t),n=ot(r,t,!1);return Pe.makeFragment(n)},mathmlBuilder:(e,t)=>{const r=Qr(e,t);return kt(r,t)}});const en=(e,t,r,n,o,s,i)=>{e=Pe.makeSpan([],[e]);const a=r&&l.isCharacterBox(r);let h,c,m;if(t){const e=ct(t,n.havingStyle(o.sup()),n);c={elem:e,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-e.depth)}}if(r){const e=ct(r,n.havingStyle(o.sub()),n);h={elem:e,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-e.height)}}if(c&&h){const t=n.fontMetrics().bigOpSpacing5+h.elem.height+h.elem.depth+h.kern+e.depth+i;m=Pe.makeVList({positionType:"bottom",positionData:t,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:h.elem,marginLeft:F(-s)},{type:"kern",size:h.kern},{type:"elem",elem:e},{type:"kern",size:c.kern},{type:"elem",elem:c.elem,marginLeft:F(s)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(h){const t=e.height-i;m=Pe.makeVList({positionType:"top",positionData:t,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:h.elem,marginLeft:F(-s)},{type:"kern",size:h.kern},{type:"elem",elem:e}]},n)}else{if(!c)return e;{const t=e.depth+i;m=Pe.makeVList({positionType:"bottom",positionData:t,children:[{type:"elem",elem:e},{type:"kern",size:c.kern},{type:"elem",elem:c.elem,marginLeft:F(s)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}}const p=[m];if(h&&0!==s&&!a){const e=Pe.makeSpan(["mspace"],[],n);e.style.marginRight=F(s),p.unshift(e)}return Pe.makeSpan(["mop","op-limits"],p,n)},tn=["\\smallint"],rn=(e,t)=>{let r,n,o,s=!1;"supsub"===e.type?(r=e.sup,n=e.sub,o=Rt(e.base,"op"),s=!0):o=Rt(e,"op");const i=t.style;let a,h=!1;if(i.size===w.DISPLAY.size&&o.symbol&&!l.contains(tn,o.name)&&(h=!0),o.symbol){const e=h?"Size2-Regular":"Size1-Regular";let r="";if("\\oiint"!==o.name&&"\\oiiint"!==o.name||(r=o.name.slice(1),o.name="oiint"===r?"\\iint":"\\iiint"),a=Pe.makeSymbol(o.name,e,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),r.length>0){const e=a.italic,n=Pe.staticSvg(r+"Size"+(h?"2":"1"),t);a=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:0},{type:"elem",elem:n,shift:h?.08:0}]},t),o.name="\\"+r,a.classes.unshift("mop"),a.italic=e}}else if(o.body){const e=ot(o.body,t,!0);1===e.length&&e[0]instanceof K?(a=e[0],a.classes[0]="mop"):a=Pe.makeSpan(["mop"],e,t)}else{const e=[];for(let r=1;r{let r;if(e.symbol)r=new dt("mo",[bt(e.name,e.mode)]),l.contains(tn,e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new dt("mo",vt(e.body,t));else{r=new dt("mi",[new gt(e.name.slice(1))]);const t=new dt("mo",[bt("\u2061","text")]);r=e.parentIsSupSub?new dt("mrow",[r,t]):ut([r,t])}return r},on={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};$e({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{let{parser:r,funcName:n}=e,o=n;return 1===o.length&&(o=on[o]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:o}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:Je(n)}},htmlBuilder:rn,mathmlBuilder:nn});const sn={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};$e({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e,n=r;return 1===n.length&&(n=sn[n]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:rn,mathmlBuilder:nn});const an=(e,t)=>{let r,n,o,s,i=!1;if("supsub"===e.type?(r=e.sup,n=e.sub,o=Rt(e.base,"operatorname"),i=!0):o=Rt(e,"operatorname"),o.body.length>0){const e=o.body.map((e=>{const t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),r=ot(e,t.withFont("mathrm"),!0);for(let e=0;e{let{parser:r,funcName:n}=e;const o=t[0];return{type:"operatorname",mode:r.mode,body:Je(o),alwaysHandleSupSub:"\\operatornamewithlimits"===n,limits:!1,parentIsSupSub:!1}},htmlBuilder:an,mathmlBuilder:(e,t)=>{let r=vt(e.body,t.withFont("mathrm")),n=!0;for(let e=0;ee.toText())).join("");r=[new ft.TextNode(e)]}const o=new ft.MathNode("mi",r);o.setAttribute("mathvariant","normal");const s=new ft.MathNode("mo",[bt("\u2061","text")]);return e.parentIsSupSub?new ft.MathNode("mrow",[o,s]):ft.newDocumentFragment([o,s])}}),Nr("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),Ze({type:"ordgroup",htmlBuilder(e,t){return e.semisimple?Pe.makeFragment(ot(e.body,t,!1)):Pe.makeSpan(["mord"],ot(e.body,t,!0),t)},mathmlBuilder(e,t){return kt(e.body,t,!0)}}),$e({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){let{parser:r}=e;const n=t[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(e,t){const r=ct(e.body,t.havingCrampedStyle()),n=Pe.makeLineSpan("overline-line",t),o=t.fontMetrics().defaultRuleThickness,s=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*o},{type:"elem",elem:n},{type:"kern",size:o}]},t);return Pe.makeSpan(["mord","overline"],[s],t)},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[new ft.TextNode("\u203e")]);r.setAttribute("stretchy","true");const n=new ft.MathNode("mover",[St(e.body,t),r]);return n.setAttribute("accent","true"),n}}),$e({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"phantom",mode:r.mode,body:Je(n)}},htmlBuilder:(e,t)=>{const r=ot(e.body,t.withPhantom(),!1);return Pe.makeFragment(r)},mathmlBuilder:(e,t)=>{const r=vt(e.body,t);return new ft.MathNode("mphantom",r)}}),$e({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"hphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{let r=Pe.makeSpan([],[ct(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(let e=0;e{const r=vt(Je(e.body),t),n=new ft.MathNode("mphantom",r),o=new ft.MathNode("mpadded",[n]);return o.setAttribute("height","0px"),o.setAttribute("depth","0px"),o}}),$e({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"vphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{const r=Pe.makeSpan(["inner"],[ct(e.body,t.withPhantom())]),n=Pe.makeSpan(["fix"],[]);return Pe.makeSpan(["mord","rlap"],[r,n],t)},mathmlBuilder:(e,t)=>{const r=vt(Je(e.body),t),n=new ft.MathNode("mphantom",r),o=new ft.MathNode("mpadded",[n]);return o.setAttribute("width","0px"),o}}),$e({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){let{parser:r}=e;const n=Rt(t[0],"size").value,o=t[1];return{type:"raisebox",mode:r.mode,dy:n,body:o}},htmlBuilder(e,t){const r=ct(e.body,t),n=P(e.dy,t);return Pe.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){const r=new ft.MathNode("mpadded",[St(e.body,t)]),n=e.dy.number+e.dy.unit;return r.setAttribute("voffset",n),r}}),$e({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(e){let{parser:t}=e;return{type:"internal",mode:t.mode}}}),$e({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(e,t,r){let{parser:n}=e;const o=r[0],s=Rt(t[0],"size"),i=Rt(t[1],"size");return{type:"rule",mode:n.mode,shift:o&&Rt(o,"size").value,width:s.value,height:i.value}},htmlBuilder(e,t){const r=Pe.makeSpan(["mord","rule"],[],t),n=P(e.width,t),o=P(e.height,t),s=e.shift?P(e.shift,t):0;return r.style.borderRightWidth=F(n),r.style.borderTopWidth=F(o),r.style.bottom=F(s),r.width=n,r.height=o+s,r.depth=-s,r.maxFontSize=1.125*o*t.sizeMultiplier,r},mathmlBuilder(e,t){const r=P(e.width,t),n=P(e.height,t),o=e.shift?P(e.shift,t):0,s=t.color&&t.getColor()||"black",i=new ft.MathNode("mspace");i.setAttribute("mathbackground",s),i.setAttribute("width",F(r)),i.setAttribute("height",F(n));const a=new ft.MathNode("mpadded",[i]);return o>=0?a.setAttribute("height",F(o)):(a.setAttribute("height",F(o)),a.setAttribute("depth",F(-o))),a.setAttribute("voffset",F(o)),a}});const hn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];$e({type:"sizing",names:hn,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{let{breakOnTokenText:r,funcName:n,parser:o}=e;const s=o.parseExpression(!1,r);return{type:"sizing",mode:o.mode,size:hn.indexOf(n)+1,body:s}},htmlBuilder:(e,t)=>{const r=t.havingSize(e.size);return ln(e.body,r,t)},mathmlBuilder:(e,t)=>{const r=t.havingSize(e.size),n=vt(e.body,r),o=new ft.MathNode("mstyle",n);return o.setAttribute("mathsize",F(r.sizeMultiplier)),o}}),$e({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{let{parser:n}=e,o=!1,s=!1;const i=r[0]&&Rt(r[0],"ordgroup");if(i){let e="";for(let t=0;t{const r=Pe.makeSpan([],[ct(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(let e=0;e{const r=new ft.MathNode("mpadded",[St(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),$e({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){let{parser:n}=e;const o=r[0],s=t[0];return{type:"sqrt",mode:n.mode,body:s,index:o}},htmlBuilder(e,t){let r=ct(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Pe.wrapFragment(r,t);const n=t.fontMetrics().defaultRuleThickness;let o=n;t.style.idr.height+r.depth+s&&(s=(s+c-r.height-r.depth)/2);const m=a.height-r.height-s-l;r.style.paddingLeft=F(h);const p=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+m)},{type:"elem",elem:a},{type:"kern",size:l}]},t);if(e.index){const r=t.havingStyle(w.SCRIPTSCRIPT),n=ct(e.index,r,t),o=.6*(p.height-p.depth),s=Pe.makeVList({positionType:"shift",positionData:-o,children:[{type:"elem",elem:n}]},t),i=Pe.makeSpan(["root"],[s]);return Pe.makeSpan(["mord","sqrt"],[i,p],t)}return Pe.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){const{body:r,index:n}=e;return n?new ft.MathNode("mroot",[St(r,t),St(n,t)]):new ft.MathNode("msqrt",[St(r,t)])}});const cn={display:w.DISPLAY,text:w.TEXT,script:w.SCRIPT,scriptscript:w.SCRIPTSCRIPT};$e({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){let{breakOnTokenText:r,funcName:n,parser:o}=e;const s=o.parseExpression(!0,r),i=n.slice(1,n.length-5);return{type:"styling",mode:o.mode,style:i,body:s}},htmlBuilder(e,t){const r=cn[e.style],n=t.havingStyle(r).withFont("");return ln(e.body,n,t)},mathmlBuilder(e,t){const r=cn[e.style],n=t.havingStyle(r),o=vt(e.body,n),s=new ft.MathNode("mstyle",o),i={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return s.setAttribute("scriptlevel",i[0]),s.setAttribute("displaystyle",i[1]),s}});Ze({type:"supsub",htmlBuilder(e,t){const r=function(e,t){const r=e.base;if(r)return"op"===r.type?r.limits&&(t.style.size===w.DISPLAY.size||r.alwaysHandleSupSub)?rn:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===w.DISPLAY.size||r.limits)?an:null:"accent"===r.type?l.isCharacterBox(r.base)?Et:null:"horizBrace"===r.type&&!e.sub===r.isOver?Kr:null;return null}(e,t);if(r)return r(e,t);const{base:n,sup:o,sub:s}=e,i=ct(n,t);let a,h;const c=t.fontMetrics();let m=0,p=0;const u=n&&l.isCharacterBox(n);if(o){const e=t.havingStyle(t.style.sup());a=ct(o,e,t),u||(m=i.height-e.fontMetrics().supDrop*e.sizeMultiplier/t.sizeMultiplier)}if(s){const e=t.havingStyle(t.style.sub());h=ct(s,e,t),u||(p=i.depth+e.fontMetrics().subDrop*e.sizeMultiplier/t.sizeMultiplier)}let d;d=t.style===w.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;const g=t.sizeMultiplier,f=F(.5/c.ptPerEm/g);let b,y=null;if(h){const t=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(i instanceof K||t)&&(y=F(-i.italic))}if(a&&h){m=Math.max(m,d,a.depth+.25*c.xHeight),p=Math.max(p,c.sub2);const e=4*c.defaultRuleThickness;if(m-a.depth-(h.height-p)0&&(m+=t,p-=t)}const r=[{type:"elem",elem:h,shift:p,marginRight:f,marginLeft:y},{type:"elem",elem:a,shift:-m,marginRight:f}];b=Pe.makeVList({positionType:"individualShift",children:r},t)}else if(h){p=Math.max(p,c.sub1,h.height-.8*c.xHeight);const e=[{type:"elem",elem:h,marginLeft:y,marginRight:f}];b=Pe.makeVList({positionType:"shift",positionData:p,children:e},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");m=Math.max(m,d,a.depth+.25*c.xHeight),b=Pe.makeVList({positionType:"shift",positionData:-m,children:[{type:"elem",elem:a,marginRight:f}]},t)}const x=lt(i,"right")||"mord";return Pe.makeSpan([x],[i,Pe.makeSpan(["msupsub"],[b])],t)},mathmlBuilder(e,t){let r,n,o=!1;e.base&&"horizBrace"===e.base.type&&(n=!!e.sup,n===e.base.isOver&&(o=!0,r=e.base.isOver)),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);const s=[St(e.base,t)];let i;if(e.sub&&s.push(St(e.sub,t)),e.sup&&s.push(St(e.sup,t)),o)i=r?"mover":"munder";else if(e.sub)if(e.sup){const r=e.base;i=r&&"op"===r.type&&r.limits&&t.style===w.DISPLAY||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(t.style===w.DISPLAY||r.limits)?"munderover":"msubsup"}else{const r=e.base;i=r&&"op"===r.type&&r.limits&&(t.style===w.DISPLAY||r.alwaysHandleSupSub)||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(r.limits||t.style===w.DISPLAY)?"munder":"msub"}else{const r=e.base;i=r&&"op"===r.type&&r.limits&&(t.style===w.DISPLAY||r.alwaysHandleSupSub)||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(r.limits||t.style===w.DISPLAY)?"mover":"msup"}return new ft.MathNode(i,s)}}),Ze({type:"atom",htmlBuilder(e,t){return Pe.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[bt(e.text,e.mode)]);if("bin"===e.family){const n=xt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});const mn={mi:"italic",mn:"normal",mtext:"normal"};Ze({type:"mathord",htmlBuilder(e,t){return Pe.makeOrd(e,t,"mathord")},mathmlBuilder(e,t){const r=new ft.MathNode("mi",[bt(e.text,e.mode,t)]),n=xt(e,t)||"italic";return n!==mn[r.type]&&r.setAttribute("mathvariant",n),r}}),Ze({type:"textord",htmlBuilder(e,t){return Pe.makeOrd(e,t,"textord")},mathmlBuilder(e,t){const r=bt(e.text,e.mode,t),n=xt(e,t)||"normal";let o;return o="text"===e.mode?new ft.MathNode("mtext",[r]):/[0-9]/.test(e.text)?new ft.MathNode("mn",[r]):"\\prime"===e.text?new ft.MathNode("mo",[r]):new ft.MathNode("mi",[r]),n!==mn[o.type]&&o.setAttribute("mathvariant",n),o}});const pn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},un={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};Ze({type:"spacing",htmlBuilder(e,t){if(un.hasOwnProperty(e.text)){const r=un[e.text].className||"";if("text"===e.mode){const n=Pe.makeOrd(e,t,"textord");return n.classes.push(r),n}return Pe.makeSpan(["mspace",r],[Pe.mathsym(e.text,e.mode,t)],t)}if(pn.hasOwnProperty(e.text))return Pe.makeSpan(["mspace",pn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){let r;if(!un.hasOwnProperty(e.text)){if(pn.hasOwnProperty(e.text))return new ft.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return r=new ft.MathNode("mtext",[new ft.TextNode("\xa0")]),r}});const dn=()=>{const e=new ft.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};Ze({type:"tag",mathmlBuilder(e,t){const r=new ft.MathNode("mtable",[new ft.MathNode("mtr",[dn(),new ft.MathNode("mtd",[kt(e.body,t)]),dn(),new ft.MathNode("mtd",[kt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});const gn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},fn={"\\textbf":"textbf","\\textmd":"textmd"},bn={"\\textit":"textit","\\textup":"textup"},yn=(e,t)=>{const r=e.font;return r?gn[r]?t.withTextFontFamily(gn[r]):fn[r]?t.withTextFontWeight(fn[r]):"\\emph"===r?"textit"===t.fontShape?t.withTextFontShape("textup"):t.withTextFontShape("textit"):t.withTextFontShape(bn[r]):t};$e({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"text",mode:r.mode,body:Je(o),font:n}},htmlBuilder(e,t){const r=yn(e,t),n=ot(e.body,r,!0);return Pe.makeSpan(["mord","text"],n,r)},mathmlBuilder(e,t){const r=yn(e,t);return kt(e.body,r)}}),$e({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){const r=ct(e.body,t),n=Pe.makeLineSpan("underline-line",t),o=t.fontMetrics().defaultRuleThickness,s=Pe.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:o},{type:"elem",elem:n},{type:"kern",size:3*o},{type:"elem",elem:r}]},t);return Pe.makeSpan(["mord","underline"],[s],t)},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[new ft.TextNode("\u203e")]);r.setAttribute("stretchy","true");const n=new ft.MathNode("munder",[St(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),$e({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){let{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){const r=ct(e.body,t),n=t.fontMetrics().axisHeight,o=.5*(r.height-n-(r.depth+n));return Pe.makeVList({positionType:"shift",positionData:o,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){return new ft.MathNode("mpadded",[St(e.body,t)],["vcenter"])}}),$e({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){const r=xn(e),n=[],o=t.havingStyle(t.style.text());for(let t=0;te.body.replace(/ /g,e.star?"\u2423":"\xa0");var wn=We;const vn="[ \r\n\t]",kn="(\\\\[a-zA-Z@]+)"+vn+"*",Sn="[\u0300-\u036f]",Mn=new RegExp(Sn+"+$"),zn="("+vn+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Sn+"*|[\ud800-\udbff][\udc00-\udfff]"+Sn+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+kn+"|\\\\[^\ud800-\udfff])";class An{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(zn,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){const e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new Ir("EOF",new qr(this,t,t));const r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new n("Unexpected character: '"+e[t]+"'",new Ir(e[t],new qr(this,t,t+1)));const o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){const t=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===t?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=t+1,this.lex()}return new Ir(o,new qr(this,t,this.tokenRegex.lastIndex))}}class Tn{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new n("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");const e=this.undefStack.pop();for(const t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(let t=0;t0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{const t=this.undefStack[this.undefStack.length-1];t&&!t.hasOwnProperty(e)&&(t[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Bn=Cr;Nr("\\noexpand",(function(e){const t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Nr("\\expandafter",(function(e){const t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Nr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Nr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Nr("\\@ifnextchar",(function(e){const t=e.consumeArgs(3);e.consumeSpaces();const r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Nr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Nr("\\TextOrMath",(function(e){const t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));const Cn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Nr("\\char",(function(e){let t,r=e.popToken(),o="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if(r=e.popToken(),"\\"===r.text[0])o=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");o=r.text.charCodeAt(0)}else t=10;if(t){if(o=Cn[r.text],null==o||o>=t)throw new n("Invalid base-"+t+" digit "+r.text);let s;for(;null!=(s=Cn[e.future().text])&&s{let s=e.consumeArg().tokens;if(1!==s.length)throw new n("\\newcommand's first argument must be a macro name");const i=s[0].text,a=e.isDefined(i);if(a&&!t)throw new n("\\newcommand{"+i+"} attempting to redefine "+i+"; use \\renewcommand");if(!a&&!r)throw new n("\\renewcommand{"+i+"} when command "+i+" does not yet exist; use \\newcommand");let l=0;if(s=e.consumeArg().tokens,1===s.length&&"["===s[0].text){let t="",r=e.expandNextToken();for(;"]"!==r.text&&"EOF"!==r.text;)t+=r.text,r=e.expandNextToken();if(!t.match(/^\s*[0-9]+\s*$/))throw new n("Invalid number of arguments: "+t);l=parseInt(t),s=e.consumeArg().tokens}return a&&o||e.macros.set(i,{tokens:s,numArgs:l}),""};Nr("\\newcommand",(e=>Nn(e,!1,!0,!1))),Nr("\\renewcommand",(e=>Nn(e,!0,!1,!1))),Nr("\\providecommand",(e=>Nn(e,!0,!0,!0))),Nr("\\message",(e=>{const t=e.consumeArgs(1)[0];return console.log(t.reverse().map((e=>e.text)).join("")),""})),Nr("\\errmessage",(e=>{const t=e.consumeArgs(1)[0];return console.error(t.reverse().map((e=>e.text)).join("")),""})),Nr("\\show",(e=>{const t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),wn[r],se.math[r],se.text[r]),""})),Nr("\\bgroup","{"),Nr("\\egroup","}"),Nr("~","\\nobreakspace"),Nr("\\lq","`"),Nr("\\rq","'"),Nr("\\aa","\\r a"),Nr("\\AA","\\r A"),Nr("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Nr("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Nr("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Nr("\u212c","\\mathscr{B}"),Nr("\u2130","\\mathscr{E}"),Nr("\u2131","\\mathscr{F}"),Nr("\u210b","\\mathscr{H}"),Nr("\u2110","\\mathscr{I}"),Nr("\u2112","\\mathscr{L}"),Nr("\u2133","\\mathscr{M}"),Nr("\u211b","\\mathscr{R}"),Nr("\u212d","\\mathfrak{C}"),Nr("\u210c","\\mathfrak{H}"),Nr("\u2128","\\mathfrak{Z}"),Nr("\\Bbbk","\\Bbb{k}"),Nr("\xb7","\\cdotp"),Nr("\\llap","\\mathllap{\\textrm{#1}}"),Nr("\\rlap","\\mathrlap{\\textrm{#1}}"),Nr("\\clap","\\mathclap{\\textrm{#1}}"),Nr("\\mathstrut","\\vphantom{(}"),Nr("\\underbar","\\underline{\\text{#1}}"),Nr("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Nr("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Nr("\\ne","\\neq"),Nr("\u2260","\\neq"),Nr("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Nr("\u2209","\\notin"),Nr("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Nr("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Nr("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Nr("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Nr("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Nr("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Nr("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Nr("\u27c2","\\perp"),Nr("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Nr("\u220c","\\notni"),Nr("\u231c","\\ulcorner"),Nr("\u231d","\\urcorner"),Nr("\u231e","\\llcorner"),Nr("\u231f","\\lrcorner"),Nr("\xa9","\\copyright"),Nr("\xae","\\textregistered"),Nr("\ufe0f","\\textregistered"),Nr("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Nr("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Nr("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Nr("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Nr("\\vdots","{\\varvdots\\rule{0pt}{15pt}}"),Nr("\u22ee","\\vdots"),Nr("\\varGamma","\\mathit{\\Gamma}"),Nr("\\varDelta","\\mathit{\\Delta}"),Nr("\\varTheta","\\mathit{\\Theta}"),Nr("\\varLambda","\\mathit{\\Lambda}"),Nr("\\varXi","\\mathit{\\Xi}"),Nr("\\varPi","\\mathit{\\Pi}"),Nr("\\varSigma","\\mathit{\\Sigma}"),Nr("\\varUpsilon","\\mathit{\\Upsilon}"),Nr("\\varPhi","\\mathit{\\Phi}"),Nr("\\varPsi","\\mathit{\\Psi}"),Nr("\\varOmega","\\mathit{\\Omega}"),Nr("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Nr("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Nr("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Nr("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Nr("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Nr("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;"),Nr("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}"),Nr("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");const qn={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Nr("\\dots",(function(e){let t="\\dotso";const r=e.expandAfterFuture().text;return r in qn?t=qn[r]:("\\not"===r.slice(0,4)||r in se.math&&l.contains(["bin","rel"],se.math[r].group))&&(t="\\dotsb"),t}));const In={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Nr("\\dotso",(function(e){return e.future().text in In?"\\ldots\\,":"\\ldots"})),Nr("\\dotsc",(function(e){const t=e.future().text;return t in In&&","!==t?"\\ldots\\,":"\\ldots"})),Nr("\\cdots",(function(e){return e.future().text in In?"\\@cdots\\,":"\\@cdots"})),Nr("\\dotsb","\\cdots"),Nr("\\dotsm","\\cdots"),Nr("\\dotsi","\\!\\cdots"),Nr("\\dotsx","\\ldots\\,"),Nr("\\DOTSI","\\relax"),Nr("\\DOTSB","\\relax"),Nr("\\DOTSX","\\relax"),Nr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Nr("\\,","\\tmspace+{3mu}{.1667em}"),Nr("\\thinspace","\\,"),Nr("\\>","\\mskip{4mu}"),Nr("\\:","\\tmspace+{4mu}{.2222em}"),Nr("\\medspace","\\:"),Nr("\\;","\\tmspace+{5mu}{.2777em}"),Nr("\\thickspace","\\;"),Nr("\\!","\\tmspace-{3mu}{.1667em}"),Nr("\\negthinspace","\\!"),Nr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Nr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Nr("\\enspace","\\kern.5em "),Nr("\\enskip","\\hskip.5em\\relax"),Nr("\\quad","\\hskip1em\\relax"),Nr("\\qquad","\\hskip2em\\relax"),Nr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Nr("\\tag@paren","\\tag@literal{({#1})}"),Nr("\\tag@literal",(e=>{if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Nr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Nr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Nr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Nr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Nr("\\newline","\\\\\\relax"),Nr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");const Rn=F(T["Main-Regular"]["T".charCodeAt(0)][1]-.7*T["Main-Regular"]["A".charCodeAt(0)][1]);Nr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Rn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Nr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Rn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Nr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Nr("\\@hspace","\\hskip #1\\relax"),Nr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Nr("\\ordinarycolon",":"),Nr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Nr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Nr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Nr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Nr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Nr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Nr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Nr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Nr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Nr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Nr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Nr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Nr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Nr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Nr("\u2237","\\dblcolon"),Nr("\u2239","\\eqcolon"),Nr("\u2254","\\coloneqq"),Nr("\u2255","\\eqqcolon"),Nr("\u2a74","\\Coloneqq"),Nr("\\ratio","\\vcentcolon"),Nr("\\coloncolon","\\dblcolon"),Nr("\\colonequals","\\coloneqq"),Nr("\\coloncolonequals","\\Coloneqq"),Nr("\\equalscolon","\\eqqcolon"),Nr("\\equalscoloncolon","\\Eqqcolon"),Nr("\\colonminus","\\coloneq"),Nr("\\coloncolonminus","\\Coloneq"),Nr("\\minuscolon","\\eqcolon"),Nr("\\minuscoloncolon","\\Eqcolon"),Nr("\\coloncolonapprox","\\Colonapprox"),Nr("\\coloncolonsim","\\Colonsim"),Nr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Nr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Nr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Nr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Nr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Nr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Nr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Nr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Nr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Nr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Nr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Nr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Nr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Nr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Nr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Nr("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Nr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Nr("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Nr("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Nr("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Nr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Nr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Nr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Nr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Nr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Nr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Nr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Nr("\\imath","\\html@mathml{\\@imath}{\u0131}"),Nr("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Nr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Nr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Nr("\u27e6","\\llbracket"),Nr("\u27e7","\\rrbracket"),Nr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Nr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Nr("\u2983","\\lBrace"),Nr("\u2984","\\rBrace"),Nr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Nr("\u29b5","\\minuso"),Nr("\\darr","\\downarrow"),Nr("\\dArr","\\Downarrow"),Nr("\\Darr","\\Downarrow"),Nr("\\lang","\\langle"),Nr("\\rang","\\rangle"),Nr("\\uarr","\\uparrow"),Nr("\\uArr","\\Uparrow"),Nr("\\Uarr","\\Uparrow"),Nr("\\N","\\mathbb{N}"),Nr("\\R","\\mathbb{R}"),Nr("\\Z","\\mathbb{Z}"),Nr("\\alef","\\aleph"),Nr("\\alefsym","\\aleph"),Nr("\\Alpha","\\mathrm{A}"),Nr("\\Beta","\\mathrm{B}"),Nr("\\bull","\\bullet"),Nr("\\Chi","\\mathrm{X}"),Nr("\\clubs","\\clubsuit"),Nr("\\cnums","\\mathbb{C}"),Nr("\\Complex","\\mathbb{C}"),Nr("\\Dagger","\\ddagger"),Nr("\\diamonds","\\diamondsuit"),Nr("\\empty","\\emptyset"),Nr("\\Epsilon","\\mathrm{E}"),Nr("\\Eta","\\mathrm{H}"),Nr("\\exist","\\exists"),Nr("\\harr","\\leftrightarrow"),Nr("\\hArr","\\Leftrightarrow"),Nr("\\Harr","\\Leftrightarrow"),Nr("\\hearts","\\heartsuit"),Nr("\\image","\\Im"),Nr("\\infin","\\infty"),Nr("\\Iota","\\mathrm{I}"),Nr("\\isin","\\in"),Nr("\\Kappa","\\mathrm{K}"),Nr("\\larr","\\leftarrow"),Nr("\\lArr","\\Leftarrow"),Nr("\\Larr","\\Leftarrow"),Nr("\\lrarr","\\leftrightarrow"),Nr("\\lrArr","\\Leftrightarrow"),Nr("\\Lrarr","\\Leftrightarrow"),Nr("\\Mu","\\mathrm{M}"),Nr("\\natnums","\\mathbb{N}"),Nr("\\Nu","\\mathrm{N}"),Nr("\\Omicron","\\mathrm{O}"),Nr("\\plusmn","\\pm"),Nr("\\rarr","\\rightarrow"),Nr("\\rArr","\\Rightarrow"),Nr("\\Rarr","\\Rightarrow"),Nr("\\real","\\Re"),Nr("\\reals","\\mathbb{R}"),Nr("\\Reals","\\mathbb{R}"),Nr("\\Rho","\\mathrm{P}"),Nr("\\sdot","\\cdot"),Nr("\\sect","\\S"),Nr("\\spades","\\spadesuit"),Nr("\\sub","\\subset"),Nr("\\sube","\\subseteq"),Nr("\\supe","\\supseteq"),Nr("\\Tau","\\mathrm{T}"),Nr("\\thetasym","\\vartheta"),Nr("\\weierp","\\wp"),Nr("\\Zeta","\\mathrm{Z}"),Nr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Nr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Nr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Nr("\\bra","\\mathinner{\\langle{#1}|}"),Nr("\\ket","\\mathinner{|{#1}\\rangle}"),Nr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Nr("\\Bra","\\left\\langle#1\\right|"),Nr("\\Ket","\\left|#1\\right\\rangle");const Hn=e=>t=>{const r=t.consumeArg().tokens,n=t.consumeArg().tokens,o=t.consumeArg().tokens,s=t.consumeArg().tokens,i=t.macros.get("|"),a=t.macros.get("\\|");t.macros.beginGroup();const l=t=>r=>{e&&(r.macros.set("|",i),o.length&&r.macros.set("\\|",a));let s=t;if(!t&&o.length){"|"===r.future().text&&(r.popToken(),s=!0)}return{tokens:s?o:n,numArgs:0}};t.macros.set("|",l(!1)),o.length&&t.macros.set("\\|",l(!0));const h=t.consumeArg().tokens,c=t.expandTokens([...s,...h,...r]);return t.macros.endGroup(),{tokens:c.reverse(),numArgs:0}};Nr("\\bra@ket",Hn(!1)),Nr("\\bra@set",Hn(!0)),Nr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Nr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Nr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Nr("\\angln","{\\angl n}"),Nr("\\blue","\\textcolor{##6495ed}{#1}"),Nr("\\orange","\\textcolor{##ffa500}{#1}"),Nr("\\pink","\\textcolor{##ff00af}{#1}"),Nr("\\red","\\textcolor{##df0030}{#1}"),Nr("\\green","\\textcolor{##28ae7b}{#1}"),Nr("\\gray","\\textcolor{gray}{#1}"),Nr("\\purple","\\textcolor{##9d38bd}{#1}"),Nr("\\blueA","\\textcolor{##ccfaff}{#1}"),Nr("\\blueB","\\textcolor{##80f6ff}{#1}"),Nr("\\blueC","\\textcolor{##63d9ea}{#1}"),Nr("\\blueD","\\textcolor{##11accd}{#1}"),Nr("\\blueE","\\textcolor{##0c7f99}{#1}"),Nr("\\tealA","\\textcolor{##94fff5}{#1}"),Nr("\\tealB","\\textcolor{##26edd5}{#1}"),Nr("\\tealC","\\textcolor{##01d1c1}{#1}"),Nr("\\tealD","\\textcolor{##01a995}{#1}"),Nr("\\tealE","\\textcolor{##208170}{#1}"),Nr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Nr("\\greenB","\\textcolor{##8af281}{#1}"),Nr("\\greenC","\\textcolor{##74cf70}{#1}"),Nr("\\greenD","\\textcolor{##1fab54}{#1}"),Nr("\\greenE","\\textcolor{##0d923f}{#1}"),Nr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Nr("\\goldB","\\textcolor{##ffbb71}{#1}"),Nr("\\goldC","\\textcolor{##ff9c39}{#1}"),Nr("\\goldD","\\textcolor{##e07d10}{#1}"),Nr("\\goldE","\\textcolor{##a75a05}{#1}"),Nr("\\redA","\\textcolor{##fca9a9}{#1}"),Nr("\\redB","\\textcolor{##ff8482}{#1}"),Nr("\\redC","\\textcolor{##f9685d}{#1}"),Nr("\\redD","\\textcolor{##e84d39}{#1}"),Nr("\\redE","\\textcolor{##bc2612}{#1}"),Nr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Nr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Nr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Nr("\\maroonD","\\textcolor{##ca337c}{#1}"),Nr("\\maroonE","\\textcolor{##9e034e}{#1}"),Nr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Nr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Nr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Nr("\\purpleD","\\textcolor{##7854ab}{#1}"),Nr("\\purpleE","\\textcolor{##543b78}{#1}"),Nr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Nr("\\mintB","\\textcolor{##edf2df}{#1}"),Nr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Nr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Nr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Nr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Nr("\\grayD","\\textcolor{##d6d8da}{#1}"),Nr("\\grayE","\\textcolor{##babec2}{#1}"),Nr("\\grayF","\\textcolor{##888d93}{#1}"),Nr("\\grayG","\\textcolor{##626569}{#1}"),Nr("\\grayH","\\textcolor{##3b3e40}{#1}"),Nr("\\grayI","\\textcolor{##21242c}{#1}"),Nr("\\kaBlue","\\textcolor{##314453}{#1}"),Nr("\\kaGreen","\\textcolor{##71B307}{#1}");const On={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class En{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Tn(Bn,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new An(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){let t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:n,end:r}=this.consumeArg(["]"]))}else({tokens:n,start:t,end:r}=this.consumeArg());return this.pushToken(new Ir("EOF",r.loc)),this.pushTokens(n),t.range(r,"")}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){const t=[],r=e&&e.length>0;r||this.consumeSpaces();const o=this.future();let s,i=0,a=0;do{if(s=this.popToken(),t.push(s),"{"===s.text)++i;else if("}"===s.text){if(--i,-1===i)throw new n("Extra }",s)}else if("EOF"===s.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[a]:"}")+"'",s);if(e&&r)if((0===i||1===i&&"{"===e[a])&&s.text===e[a]){if(++a,a===e.length){t.splice(-a,a);break}}else a=0}while(0!==i||r);return"{"===o.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:o,end:s}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");const r=t[0];for(let e=0;ethis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){const t=this.popToken(),r=t.text,o=t.noexpand?null:this._getExpansion(r);if(null==o||e&&o.unexpandable){if(e&&null==o&&"\\"===r[0]&&!this.isDefined(r))throw new n("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);let s=o.tokens;const i=this.consumeArgs(o.numArgs,o.delimiters);if(o.numArgs){s=s.slice();for(let e=s.length-1;e>=0;--e){let t=s[e];if("#"===t.text){if(0===e)throw new n("Incomplete placeholder at end of macro body",t);if(t=s[--e],"#"===t.text)s.splice(e+1,1);else{if(!/^[1-9]$/.test(t.text))throw new n("Not a valid argument number",t);s.splice(e,2,...i[+t.text-1])}}}}return this.pushTokens(s),s.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){const e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new Ir(e)]):void 0}expandTokens(e){const t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){const e=this.stack.pop();e.treatAsRelax&&(e.noexpand=!1,e.treatAsRelax=!1),t.push(e)}return this.countExpansion(t.length),t}expandMacroAsText(e){const t=this.expandMacro(e);return t?t.map((e=>e.text)).join(""):t}_getExpansion(e){const t=this.macros.get(e);if(null==t)return t;if(1===e.length){const t=this.lexer.catcodes[e];if(null!=t&&13!==t)return}const r="function"==typeof t?t(this):t;if("string"==typeof r){let e=0;if(-1!==r.indexOf("#")){const t=r.replace(/##/g,"");for(;-1!==t.indexOf("#"+(e+1));)++e}const t=new An(r,this.settings),n=[];let o=t.lex();for(;"EOF"!==o.text;)n.push(o),o=t.lex();n.reverse();return{tokens:n,numArgs:e}}return r}isDefined(e){return this.macros.has(e)||wn.hasOwnProperty(e)||se.math.hasOwnProperty(e)||se.text.hasOwnProperty(e)||On.hasOwnProperty(e)}isExpandable(e){const t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:wn.hasOwnProperty(e)&&!wn[e].primitive}}const Ln=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Dn=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Vn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Pn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class Fn{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new En(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{const e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){const t=this.nextToken;this.consume(),this.gullet.pushToken(new Ir("}")),this.gullet.pushTokens(e);const r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){const r=[];for(;;){"math"===this.mode&&this.consumeSpaces();const n=this.fetch();if(-1!==Fn.endOfExpression.indexOf(n.text))break;if(t&&n.text===t)break;if(e&&wn[n.text]&&wn[n.text].infix)break;const o=this.parseAtom(t);if(!o)break;"internal"!==o.type&&r.push(o)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){let t,r=-1;for(let o=0;o=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);const r=se[this.mode][t].group,n=qr.range(e);let s;if(re.hasOwnProperty(r)){const e=r;s={type:"atom",mode:this.mode,family:e,loc:n,text:t}}else s={type:r,mode:this.mode,loc:n,text:t};o=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(S(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:qr.range(e),text:t}}if(this.consume(),r)for(let t=0;t{var abe=Object.create;var _y=Object.defineProperty;var sbe=Object.getOwnPropertyDescriptor;var obe=Object.getOwnPropertyNames;var lbe=Object.getPrototypeOf,cbe=Object.prototype.hasOwnProperty;var o=(t,e)=>_y(t,"name",{value:e,configurable:!0});var N=(t,e)=>()=>(t&&(e=t(t=0)),e);var Pi=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),ur=(t,e)=>{for(var r in e)_y(t,r,{get:e[r],enumerable:!0})},V4=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of obe(e))!cbe.call(t,i)&&i!==r&&_y(t,i,{get:()=>e[i],enumerable:!(n=sbe(e,i))||n.enumerable});return t},Cr=(t,e,r)=>(V4(t,e,"default"),r&&V4(r,e,"default")),Aa=(t,e,r)=>(r=t!=null?abe(lbe(t)):{},V4(e||!t||!t.__esModule?_y(r,"default",{value:t,enumerable:!0}):r,t)),ube=t=>V4(_y({},"__esModule",{value:!0}),t);var U4=Pi((HC,WC)=>{"use strict";(function(t,e){typeof HC=="object"&&typeof WC<"u"?WC.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs=e()})(HC,function(){"use strict";var t=1e3,e=6e4,r=36e5,n="millisecond",i="second",a="minute",s="hour",l="day",u="week",h="month",f="quarter",d="year",p="date",m="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,v={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:o(function(k){var L=["th","st","nd","rd"],A=k%100;return"["+k+(L[(A-20)%10]||L[A]||L[0])+"]"},"ordinal")},x=o(function(k,L,A){var I=String(k);return!I||I.length>=L?k:""+Array(L+1-I.length).join(A)+k},"m"),b={s:x,z:o(function(k){var L=-k.utcOffset(),A=Math.abs(L),I=Math.floor(A/60),M=A%60;return(L<=0?"+":"-")+x(I,2,"0")+":"+x(M,2,"0")},"z"),m:o(function k(L,A){if(L.date()1)return k(B[0])}else{var F=L.name;S[F]=L,M=F}return!I&&M&&(T=M),M||!I&&T},"t"),C=o(function(k,L){if(E(k))return k.clone();var A=typeof L=="object"?L:{};return A.date=k,A.args=arguments,new O(A)},"O"),D=b;D.l=_,D.i=E,D.w=function(k,L){return C(k,{locale:L.$L,utc:L.$u,x:L.$x,$offset:L.$offset})};var O=function(){function k(A){this.$L=_(A.locale,null,!0),this.parse(A),this.$x=this.$x||A.x||{},this[w]=!0}o(k,"M");var L=k.prototype;return L.parse=function(A){this.$d=function(I){var M=I.date,P=I.utc;if(M===null)return new Date(NaN);if(D.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var B=M.match(g);if(B){var F=B[2]-1||0,z=(B[7]||"0").substring(0,3);return P?new Date(Date.UTC(B[1],F,B[3]||1,B[4]||0,B[5]||0,B[6]||0,z)):new Date(B[1],F,B[3]||1,B[4]||0,B[5]||0,B[6]||0,z)}}return new Date(M)}(A),this.init()},L.init=function(){var A=this.$d;this.$y=A.getFullYear(),this.$M=A.getMonth(),this.$D=A.getDate(),this.$W=A.getDay(),this.$H=A.getHours(),this.$m=A.getMinutes(),this.$s=A.getSeconds(),this.$ms=A.getMilliseconds()},L.$utils=function(){return D},L.isValid=function(){return this.$d.toString()!==m},L.isSame=function(A,I){var M=C(A);return this.startOf(I)<=M&&M<=this.endOf(I)},L.isAfter=function(A,I){return C(A){"use strict";f$=Aa(U4(),1),iu={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},X={trace:o((...t)=>{},"trace"),debug:o((...t)=>{},"debug"),info:o((...t)=>{},"info"),warn:o((...t)=>{},"warn"),error:o((...t)=>{},"error"),fatal:o((...t)=>{},"fatal")},Dy=o(function(t="fatal"){let e=iu.fatal;typeof t=="string"?t.toLowerCase()in iu&&(e=iu[t]):typeof t=="number"&&(e=t),X.trace=()=>{},X.debug=()=>{},X.info=()=>{},X.warn=()=>{},X.error=()=>{},X.fatal=()=>{},e<=iu.fatal&&(X.fatal=console.error?console.error.bind(console,ko("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",ko("FATAL"))),e<=iu.error&&(X.error=console.error?console.error.bind(console,ko("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",ko("ERROR"))),e<=iu.warn&&(X.warn=console.warn?console.warn.bind(console,ko("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",ko("WARN"))),e<=iu.info&&(X.info=console.info?console.info.bind(console,ko("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",ko("INFO"))),e<=iu.debug&&(X.debug=console.debug?console.debug.bind(console,ko("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",ko("DEBUG"))),e<=iu.trace&&(X.trace=console.debug?console.debug.bind(console,ko("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",ko("TRACE")))},"setLogLevel"),ko=o(t=>`%c${(0,f$.default)().format("ss.SSS")} : ${t} : `,"format")});var hbe,u0,qC,d$,H4=N(()=>{"use strict";hbe=Object.freeze({left:0,top:0,width:16,height:16}),u0=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),qC=Object.freeze({...hbe,...u0}),d$=Object.freeze({...qC,body:"",hidden:!1})});var fbe,p$,m$=N(()=>{"use strict";H4();fbe=Object.freeze({width:null,height:null}),p$=Object.freeze({...fbe,...u0})});var YC,W4,g$=N(()=>{"use strict";YC=o((t,e,r,n="")=>{let i=t.split(":");if(t.slice(0,1)==="@"){if(i.length<2||i.length>3)return null;n=i.shift().slice(1)}if(i.length>3||!i.length)return null;if(i.length>1){let l=i.pop(),u=i.pop(),h={provider:i.length>0?i[0]:n,prefix:u,name:l};return e&&!W4(h)?null:h}let a=i[0],s=a.split("-");if(s.length>1){let l={provider:n,prefix:s.shift(),name:s.join("-")};return e&&!W4(l)?null:l}if(r&&n===""){let l={provider:n,prefix:"",name:a};return e&&!W4(l,r)?null:l}return null},"stringToIcon"),W4=o((t,e)=>t?!!((e&&t.prefix===""||t.prefix)&&t.name):!1,"validateIconName")});function y$(t,e){let r={};!t.hFlip!=!e.hFlip&&(r.hFlip=!0),!t.vFlip!=!e.vFlip&&(r.vFlip=!0);let n=((t.rotate||0)+(e.rotate||0))%4;return n&&(r.rotate=n),r}var v$=N(()=>{"use strict";o(y$,"mergeIconTransformations")});function XC(t,e){let r=y$(t,e);for(let n in d$)n in u0?n in t&&!(n in r)&&(r[n]=u0[n]):n in e?r[n]=e[n]:n in t&&(r[n]=t[n]);return r}var x$=N(()=>{"use strict";H4();v$();o(XC,"mergeIconData")});function b$(t,e){let r=t.icons,n=t.aliases||Object.create(null),i=Object.create(null);function a(s){if(r[s])return i[s]=[];if(!(s in i)){i[s]=null;let l=n[s]&&n[s].parent,u=l&&a(l);u&&(i[s]=[l].concat(u))}return i[s]}return o(a,"resolve"),(e||Object.keys(r).concat(Object.keys(n))).forEach(a),i}var T$=N(()=>{"use strict";o(b$,"getIconsTree")});function w$(t,e,r){let n=t.icons,i=t.aliases||Object.create(null),a={};function s(l){a=XC(n[l]||i[l],a)}return o(s,"parse"),s(e),r.forEach(s),XC(t,a)}function jC(t,e){if(t.icons[e])return w$(t,e,[]);let r=b$(t,[e])[e];return r?w$(t,e,r):null}var k$=N(()=>{"use strict";x$();T$();o(w$,"internalGetIconData");o(jC,"getIconData")});function KC(t,e,r){if(e===1)return t;if(r=r||100,typeof t=="number")return Math.ceil(t*e*r)/r;if(typeof t!="string")return t;let n=t.split(dbe);if(n===null||!n.length)return t;let i=[],a=n.shift(),s=pbe.test(a);for(;;){if(s){let l=parseFloat(a);isNaN(l)?i.push(a):i.push(Math.ceil(l*e*r)/r)}else i.push(a);if(a=n.shift(),a===void 0)return i.join("");s=!s}}var dbe,pbe,E$=N(()=>{"use strict";dbe=/(-?[0-9.]*[0-9]+[0-9.]*)/g,pbe=/^-?[0-9.]*[0-9]+[0-9.]*$/g;o(KC,"calculateSize")});function mbe(t,e="defs"){let r="",n=t.indexOf("<"+e);for(;n>=0;){let i=t.indexOf(">",n),a=t.indexOf("",a);if(s===-1)break;r+=t.slice(i+1,a).trim(),t=t.slice(0,n).trim()+t.slice(s+1)}return{defs:r,content:t}}function gbe(t,e){return t?""+t+""+e:e}function S$(t,e,r){let n=mbe(t);return gbe(n.defs,e+n.content+r)}var C$=N(()=>{"use strict";o(mbe,"splitSVGDefs");o(gbe,"mergeDefsAndContent");o(S$,"wrapSVGContent")});function QC(t,e){let r={...qC,...t},n={...p$,...e},i={left:r.left,top:r.top,width:r.width,height:r.height},a=r.body;[r,n].forEach(y=>{let v=[],x=y.hFlip,b=y.vFlip,T=y.rotate;x?b?T+=2:(v.push("translate("+(i.width+i.left).toString()+" "+(0-i.top).toString()+")"),v.push("scale(-1 1)"),i.top=i.left=0):b&&(v.push("translate("+(0-i.left).toString()+" "+(i.height+i.top).toString()+")"),v.push("scale(1 -1)"),i.top=i.left=0);let S;switch(T<0&&(T-=Math.floor(T/4)*4),T=T%4,T){case 1:S=i.height/2+i.top,v.unshift("rotate(90 "+S.toString()+" "+S.toString()+")");break;case 2:v.unshift("rotate(180 "+(i.width/2+i.left).toString()+" "+(i.height/2+i.top).toString()+")");break;case 3:S=i.width/2+i.left,v.unshift("rotate(-90 "+S.toString()+" "+S.toString()+")");break}T%2===1&&(i.left!==i.top&&(S=i.left,i.left=i.top,i.top=S),i.width!==i.height&&(S=i.width,i.width=i.height,i.height=S)),v.length&&(a=S$(a,'',""))});let s=n.width,l=n.height,u=i.width,h=i.height,f,d;s===null?(d=l===null?"1em":l==="auto"?h:l,f=KC(d,u/h)):(f=s==="auto"?u:s,d=l===null?KC(f,h/u):l==="auto"?h:l);let p={},m=o((y,v)=>{ybe(v)||(p[y]=v.toString())},"setAttr");m("width",f),m("height",d);let g=[i.left,i.top,u,h];return p.viewBox=g.join(" "),{attributes:p,viewBox:g,body:a}}var ybe,A$=N(()=>{"use strict";H4();m$();E$();C$();ybe=o(t=>t==="unset"||t==="undefined"||t==="none","isUnsetKeyword");o(QC,"iconToSVG")});function ZC(t,e=xbe){let r=[],n;for(;n=vbe.exec(t);)r.push(n[1]);if(!r.length)return t;let i="suffix"+(Math.random()*16777216|Date.now()).toString(16);return r.forEach(a=>{let s=typeof e=="function"?e(a):e+(bbe++).toString(),l=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");t=t.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+s+i+"$3")}),t=t.replace(new RegExp(i,"g"),""),t}var vbe,xbe,bbe,_$=N(()=>{"use strict";vbe=/\sid="(\S+)"/g,xbe="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16),bbe=0;o(ZC,"replaceIDs")});function JC(t,e){let r=t.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(let n in e)r+=" "+n+'="'+e[n]+'"';return'"+t+""}var D$=N(()=>{"use strict";o(JC,"iconToHTML")});var R$=Pi((Iat,L$)=>{"use strict";var h0=1e3,f0=h0*60,d0=f0*60,ed=d0*24,Tbe=ed*7,wbe=ed*365.25;L$.exports=function(t,e){e=e||{};var r=typeof t;if(r==="string"&&t.length>0)return kbe(t);if(r==="number"&&isFinite(t))return e.long?Sbe(t):Ebe(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))};function kbe(t){if(t=String(t),!(t.length>100)){var e=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(t);if(e){var r=parseFloat(e[1]),n=(e[2]||"ms").toLowerCase();switch(n){case"years":case"year":case"yrs":case"yr":case"y":return r*wbe;case"weeks":case"week":case"w":return r*Tbe;case"days":case"day":case"d":return r*ed;case"hours":case"hour":case"hrs":case"hr":case"h":return r*d0;case"minutes":case"minute":case"mins":case"min":case"m":return r*f0;case"seconds":case"second":case"secs":case"sec":case"s":return r*h0;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}o(kbe,"parse");function Ebe(t){var e=Math.abs(t);return e>=ed?Math.round(t/ed)+"d":e>=d0?Math.round(t/d0)+"h":e>=f0?Math.round(t/f0)+"m":e>=h0?Math.round(t/h0)+"s":t+"ms"}o(Ebe,"fmtShort");function Sbe(t){var e=Math.abs(t);return e>=ed?q4(t,e,ed,"day"):e>=d0?q4(t,e,d0,"hour"):e>=f0?q4(t,e,f0,"minute"):e>=h0?q4(t,e,h0,"second"):t+" ms"}o(Sbe,"fmtLong");function q4(t,e,r,n){var i=e>=r*1.5;return Math.round(t/r)+" "+n+(i?"s":"")}o(q4,"plural")});var M$=Pi((Pat,N$)=>{"use strict";function Cbe(t){r.debug=r,r.default=r,r.coerce=u,r.disable=s,r.enable=i,r.enabled=l,r.humanize=R$(),r.destroy=h,Object.keys(t).forEach(f=>{r[f]=t[f]}),r.names=[],r.skips=[],r.formatters={};function e(f){let d=0;for(let p=0;p{if(E==="%%")return"%";S++;let C=r.formatters[_];if(typeof C=="function"){let D=v[S];E=C.call(x,D),v.splice(S,1),S--}return E}),r.formatArgs.call(x,v),(x.log||r.log).apply(x,v)}return o(y,"debug"),y.namespace=f,y.useColors=r.useColors(),y.color=r.selectColor(f),y.extend=n,y.destroy=r.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:o(()=>p!==null?p:(m!==r.namespaces&&(m=r.namespaces,g=r.enabled(f)),g),"get"),set:o(v=>{p=v},"set")}),typeof r.init=="function"&&r.init(y),y}o(r,"createDebug");function n(f,d){let p=r(this.namespace+(typeof d>"u"?":":d)+f);return p.log=this.log,p}o(n,"extend");function i(f){r.save(f),r.namespaces=f,r.names=[],r.skips=[];let d=(typeof f=="string"?f:"").trim().replace(" ",",").split(",").filter(Boolean);for(let p of d)p[0]==="-"?r.skips.push(p.slice(1)):r.names.push(p)}o(i,"enable");function a(f,d){let p=0,m=0,g=-1,y=0;for(;p"-"+d)].join(",");return r.enable(""),f}o(s,"disable");function l(f){for(let d of r.skips)if(a(f,d))return!1;for(let d of r.names)if(a(f,d))return!0;return!1}o(l,"enabled");function u(f){return f instanceof Error?f.stack||f.message:f}o(u,"coerce");function h(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return o(h,"destroy"),r.enable(r.load()),r}o(Cbe,"setup");N$.exports=Cbe});var I$=Pi((js,Y4)=>{"use strict";js.formatArgs=_be;js.save=Dbe;js.load=Lbe;js.useColors=Abe;js.storage=Rbe();js.destroy=(()=>{let t=!1;return()=>{t||(t=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})();js.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function Abe(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let t;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(t=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(t[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}o(Abe,"useColors");function _be(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+Y4.exports.humanize(this.diff),!this.useColors)return;let e="color: "+this.color;t.splice(1,0,e,"color: inherit");let r=0,n=0;t[0].replace(/%[a-zA-Z%]/g,i=>{i!=="%%"&&(r++,i==="%c"&&(n=r))}),t.splice(n,0,e)}o(_be,"formatArgs");js.log=console.debug||console.log||(()=>{});function Dbe(t){try{t?js.storage.setItem("debug",t):js.storage.removeItem("debug")}catch{}}o(Dbe,"save");function Lbe(){let t;try{t=js.storage.getItem("debug")}catch{}return!t&&typeof process<"u"&&"env"in process&&(t=process.env.DEBUG),t}o(Lbe,"load");function Rbe(){try{return localStorage}catch{}}o(Rbe,"localstorage");Y4.exports=M$()(js);var{formatters:Nbe}=Y4.exports;Nbe.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}});var zat,O$=N(()=>{"use strict";g$();k$();A$();_$();D$();zat=Aa(I$(),1)});var t7,e7,P$,X4,B$,F$,Es,jl=N(()=>{"use strict";yt();O$();t7={body:'?',height:80,width:80},e7=new Map,P$=new Map,X4=o(t=>{for(let e of t){if(!e.name)throw new Error('Invalid icon loader. Must have a "name" property with non-empty string value.');if(X.debug("Registering icon pack:",e.name),"loader"in e)P$.set(e.name,e.loader);else if("icons"in e)e7.set(e.name,e.icons);else throw X.error("Invalid icon loader:",e),new Error('Invalid icon loader. Must have either "icons" or "loader" property.')}},"registerIconPacks"),B$=o(async(t,e)=>{let r=YC(t,!0,e!==void 0);if(!r)throw new Error(`Invalid icon name: ${t}`);let n=r.prefix||e;if(!n)throw new Error(`Icon name must contain a prefix: ${t}`);let i=e7.get(n);if(!i){let s=P$.get(n);if(!s)throw new Error(`Icon set not found: ${r.prefix}`);try{i={...await s(),prefix:n},e7.set(n,i)}catch(l){throw X.error(l),new Error(`Failed to load icon set: ${r.prefix}`)}}let a=jC(i,r.name);if(!a)throw new Error(`Icon not found: ${t}`);return a},"getRegisteredIconData"),F$=o(async t=>{try{return await B$(t),!0}catch{return!1}},"isIconAvailable"),Es=o(async(t,e,r)=>{let n;try{n=await B$(t,e?.fallbackPrefix)}catch(s){X.error(s),n=t7}let i=QC(n,e);return JC(ZC(i.body),{...i.attributes,...r})},"getIconSVG")});function j4(t){for(var e=[],r=1;r{"use strict";o(j4,"dedent")});var K4,td,$$,Q4=N(()=>{"use strict";K4=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,td=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,$$=/\s*%%.*\n/gm});var p0,n7=N(()=>{"use strict";p0=class extends Error{static{o(this,"UnknownDiagramError")}constructor(e){super(e),this.name="UnknownDiagramError"}}});var au,m0,Ly,i7,z$,rd=N(()=>{"use strict";yt();Q4();n7();au={},m0=o(function(t,e){t=t.replace(K4,"").replace(td,"").replace($$,` +`);for(let[r,{detector:n}]of Object.entries(au))if(n(t,e))return r;throw new p0(`No diagram type detected matching given configuration for text: ${t}`)},"detectType"),Ly=o((...t)=>{for(let{id:e,detector:r,loader:n}of t)i7(e,r,n)},"registerLazyLoadedDiagrams"),i7=o((t,e,r)=>{au[t]&&X.warn(`Detector with key ${t} already exists. Overwriting.`),au[t]={detector:e,loader:r},X.debug(`Detector with key ${t} added${r?" with loader":""}`)},"addDetector"),z$=o(t=>au[t].loader,"getDiagramLoader")});var Ry,G$,a7=N(()=>{"use strict";Ry=function(){var t=o(function(ze,Le,Ie,xe){for(Ie=Ie||{},xe=ze.length;xe--;Ie[ze[xe]]=Le);return Ie},"o"),e=[1,24],r=[1,25],n=[1,26],i=[1,27],a=[1,28],s=[1,63],l=[1,64],u=[1,65],h=[1,66],f=[1,67],d=[1,68],p=[1,69],m=[1,29],g=[1,30],y=[1,31],v=[1,32],x=[1,33],b=[1,34],T=[1,35],S=[1,36],w=[1,37],E=[1,38],_=[1,39],C=[1,40],D=[1,41],O=[1,42],R=[1,43],k=[1,44],L=[1,45],A=[1,46],I=[1,47],M=[1,48],P=[1,50],B=[1,51],F=[1,52],z=[1,53],$=[1,54],U=[1,55],K=[1,56],ee=[1,57],Y=[1,58],ce=[1,59],Z=[1,60],ue=[14,42],Q=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],j=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],ne=[1,82],te=[1,83],he=[1,84],le=[1,85],J=[12,14,42],Se=[12,14,33,42],se=[12,14,33,42,76,77,79,80],ae=[12,33],Oe=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],ye={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:o(function(Le,Ie,xe,q,de,ie,oe){var V=ie.length-1;switch(de){case 3:q.setDirection("TB");break;case 4:q.setDirection("BT");break;case 5:q.setDirection("RL");break;case 6:q.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:q.setC4Type(ie[V-3]);break;case 19:q.setTitle(ie[V].substring(6)),this.$=ie[V].substring(6);break;case 20:q.setAccDescription(ie[V].substring(15)),this.$=ie[V].substring(15);break;case 21:this.$=ie[V].trim(),q.setTitle(this.$);break;case 22:case 23:this.$=ie[V].trim(),q.setAccDescription(this.$);break;case 28:ie[V].splice(2,0,"ENTERPRISE"),q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 29:ie[V].splice(2,0,"SYSTEM"),q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 30:q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 31:ie[V].splice(2,0,"CONTAINER"),q.addContainerBoundary(...ie[V]),this.$=ie[V];break;case 32:q.addDeploymentNode("node",...ie[V]),this.$=ie[V];break;case 33:q.addDeploymentNode("nodeL",...ie[V]),this.$=ie[V];break;case 34:q.addDeploymentNode("nodeR",...ie[V]),this.$=ie[V];break;case 35:q.popBoundaryParseStack();break;case 39:q.addPersonOrSystem("person",...ie[V]),this.$=ie[V];break;case 40:q.addPersonOrSystem("external_person",...ie[V]),this.$=ie[V];break;case 41:q.addPersonOrSystem("system",...ie[V]),this.$=ie[V];break;case 42:q.addPersonOrSystem("system_db",...ie[V]),this.$=ie[V];break;case 43:q.addPersonOrSystem("system_queue",...ie[V]),this.$=ie[V];break;case 44:q.addPersonOrSystem("external_system",...ie[V]),this.$=ie[V];break;case 45:q.addPersonOrSystem("external_system_db",...ie[V]),this.$=ie[V];break;case 46:q.addPersonOrSystem("external_system_queue",...ie[V]),this.$=ie[V];break;case 47:q.addContainer("container",...ie[V]),this.$=ie[V];break;case 48:q.addContainer("container_db",...ie[V]),this.$=ie[V];break;case 49:q.addContainer("container_queue",...ie[V]),this.$=ie[V];break;case 50:q.addContainer("external_container",...ie[V]),this.$=ie[V];break;case 51:q.addContainer("external_container_db",...ie[V]),this.$=ie[V];break;case 52:q.addContainer("external_container_queue",...ie[V]),this.$=ie[V];break;case 53:q.addComponent("component",...ie[V]),this.$=ie[V];break;case 54:q.addComponent("component_db",...ie[V]),this.$=ie[V];break;case 55:q.addComponent("component_queue",...ie[V]),this.$=ie[V];break;case 56:q.addComponent("external_component",...ie[V]),this.$=ie[V];break;case 57:q.addComponent("external_component_db",...ie[V]),this.$=ie[V];break;case 58:q.addComponent("external_component_queue",...ie[V]),this.$=ie[V];break;case 60:q.addRel("rel",...ie[V]),this.$=ie[V];break;case 61:q.addRel("birel",...ie[V]),this.$=ie[V];break;case 62:q.addRel("rel_u",...ie[V]),this.$=ie[V];break;case 63:q.addRel("rel_d",...ie[V]),this.$=ie[V];break;case 64:q.addRel("rel_l",...ie[V]),this.$=ie[V];break;case 65:q.addRel("rel_r",...ie[V]),this.$=ie[V];break;case 66:q.addRel("rel_b",...ie[V]),this.$=ie[V];break;case 67:ie[V].splice(0,1),q.addRel("rel",...ie[V]),this.$=ie[V];break;case 68:q.updateElStyle("update_el_style",...ie[V]),this.$=ie[V];break;case 69:q.updateRelStyle("update_rel_style",...ie[V]),this.$=ie[V];break;case 70:q.updateLayoutConfig("update_layout_config",...ie[V]),this.$=ie[V];break;case 71:this.$=[ie[V]];break;case 72:ie[V].unshift(ie[V-1]),this.$=ie[V];break;case 73:case 75:this.$=ie[V].trim();break;case 74:let Te={};Te[ie[V-1].trim()]=ie[V].trim(),this.$=Te;break;case 76:this.$="";break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:70,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:71,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:72,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:73,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{14:[1,74]},t(ue,[2,13],{43:23,29:49,30:61,32:62,20:75,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z}),t(ue,[2,14]),t(Q,[2,16],{12:[1,76]}),t(ue,[2,36],{12:[1,77]}),t(j,[2,19]),t(j,[2,20]),{25:[1,78]},{27:[1,79]},t(j,[2,23]),{35:80,75:81,76:ne,77:te,79:he,80:le},{35:86,75:81,76:ne,77:te,79:he,80:le},{35:87,75:81,76:ne,77:te,79:he,80:le},{35:88,75:81,76:ne,77:te,79:he,80:le},{35:89,75:81,76:ne,77:te,79:he,80:le},{35:90,75:81,76:ne,77:te,79:he,80:le},{35:91,75:81,76:ne,77:te,79:he,80:le},{35:92,75:81,76:ne,77:te,79:he,80:le},{35:93,75:81,76:ne,77:te,79:he,80:le},{35:94,75:81,76:ne,77:te,79:he,80:le},{35:95,75:81,76:ne,77:te,79:he,80:le},{35:96,75:81,76:ne,77:te,79:he,80:le},{35:97,75:81,76:ne,77:te,79:he,80:le},{35:98,75:81,76:ne,77:te,79:he,80:le},{35:99,75:81,76:ne,77:te,79:he,80:le},{35:100,75:81,76:ne,77:te,79:he,80:le},{35:101,75:81,76:ne,77:te,79:he,80:le},{35:102,75:81,76:ne,77:te,79:he,80:le},{35:103,75:81,76:ne,77:te,79:he,80:le},{35:104,75:81,76:ne,77:te,79:he,80:le},t(J,[2,59]),{35:105,75:81,76:ne,77:te,79:he,80:le},{35:106,75:81,76:ne,77:te,79:he,80:le},{35:107,75:81,76:ne,77:te,79:he,80:le},{35:108,75:81,76:ne,77:te,79:he,80:le},{35:109,75:81,76:ne,77:te,79:he,80:le},{35:110,75:81,76:ne,77:te,79:he,80:le},{35:111,75:81,76:ne,77:te,79:he,80:le},{35:112,75:81,76:ne,77:te,79:he,80:le},{35:113,75:81,76:ne,77:te,79:he,80:le},{35:114,75:81,76:ne,77:te,79:he,80:le},{35:115,75:81,76:ne,77:te,79:he,80:le},{20:116,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{12:[1,118],33:[1,117]},{35:119,75:81,76:ne,77:te,79:he,80:le},{35:120,75:81,76:ne,77:te,79:he,80:le},{35:121,75:81,76:ne,77:te,79:he,80:le},{35:122,75:81,76:ne,77:te,79:he,80:le},{35:123,75:81,76:ne,77:te,79:he,80:le},{35:124,75:81,76:ne,77:te,79:he,80:le},{35:125,75:81,76:ne,77:te,79:he,80:le},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(ue,[2,15]),t(Q,[2,17],{21:22,19:130,22:e,23:r,24:n,26:i,28:a}),t(ue,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:r,24:n,26:i,28:a,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z}),t(j,[2,21]),t(j,[2,22]),t(J,[2,39]),t(Se,[2,71],{75:81,35:132,76:ne,77:te,79:he,80:le}),t(se,[2,73]),{78:[1,133]},t(se,[2,75]),t(se,[2,76]),t(J,[2,40]),t(J,[2,41]),t(J,[2,42]),t(J,[2,43]),t(J,[2,44]),t(J,[2,45]),t(J,[2,46]),t(J,[2,47]),t(J,[2,48]),t(J,[2,49]),t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),t(J,[2,57]),t(J,[2,58]),t(J,[2,60]),t(J,[2,61]),t(J,[2,62]),t(J,[2,63]),t(J,[2,64]),t(J,[2,65]),t(J,[2,66]),t(J,[2,67]),t(J,[2,68]),t(J,[2,69]),t(J,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(ae,[2,28]),t(ae,[2,29]),t(ae,[2,30]),t(ae,[2,31]),t(ae,[2,32]),t(ae,[2,33]),t(ae,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t(Q,[2,18]),t(ue,[2,38]),t(Se,[2,72]),t(se,[2,74]),t(J,[2,24]),t(J,[2,35]),t(Oe,[2,25]),t(Oe,[2,26],{12:[1,138]}),t(Oe,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:o(function(Le,Ie){if(Ie.recoverable)this.trace(Le);else{var xe=new Error(Le);throw xe.hash=Ie,xe}},"parseError"),parse:o(function(Le){var Ie=this,xe=[0],q=[],de=[null],ie=[],oe=this.table,V="",Te=0,W=0,pe=0,ve=2,Pe=1,_e=ie.slice.call(arguments,1),be=Object.create(this.lexer),Ve={yy:{}};for(var De in this.yy)Object.prototype.hasOwnProperty.call(this.yy,De)&&(Ve.yy[De]=this.yy[De]);be.setInput(Le,Ve.yy),Ve.yy.lexer=be,Ve.yy.parser=this,typeof be.yylloc>"u"&&(be.yylloc={});var qe=be.yylloc;ie.push(qe);var at=be.options&&be.options.ranges;typeof Ve.yy.parseError=="function"?this.parseError=Ve.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Rt(nt){xe.length=xe.length-2*nt,de.length=de.length-nt,ie.length=ie.length-nt}o(Rt,"popStack");function st(){var nt;return nt=q.pop()||be.lex()||Pe,typeof nt!="number"&&(nt instanceof Array&&(q=nt,nt=q.pop()),nt=Ie.symbols_[nt]||nt),nt}o(st,"lex");for(var Ue,ct,We,ot,Yt,Tt,Mt={},bt,ut,St,ft;;){if(We=xe[xe.length-1],this.defaultActions[We]?ot=this.defaultActions[We]:((Ue===null||typeof Ue>"u")&&(Ue=st()),ot=oe[We]&&oe[We][Ue]),typeof ot>"u"||!ot.length||!ot[0]){var vt="";ft=[];for(bt in oe[We])this.terminals_[bt]&&bt>ve&&ft.push("'"+this.terminals_[bt]+"'");be.showPosition?vt="Parse error on line "+(Te+1)+`: +`+be.showPosition()+` +Expecting `+ft.join(", ")+", got '"+(this.terminals_[Ue]||Ue)+"'":vt="Parse error on line "+(Te+1)+": Unexpected "+(Ue==Pe?"end of input":"'"+(this.terminals_[Ue]||Ue)+"'"),this.parseError(vt,{text:be.match,token:this.terminals_[Ue]||Ue,line:be.yylineno,loc:qe,expected:ft})}if(ot[0]instanceof Array&&ot.length>1)throw new Error("Parse Error: multiple actions possible at state: "+We+", token: "+Ue);switch(ot[0]){case 1:xe.push(Ue),de.push(be.yytext),ie.push(be.yylloc),xe.push(ot[1]),Ue=null,ct?(Ue=ct,ct=null):(W=be.yyleng,V=be.yytext,Te=be.yylineno,qe=be.yylloc,pe>0&&pe--);break;case 2:if(ut=this.productions_[ot[1]][1],Mt.$=de[de.length-ut],Mt._$={first_line:ie[ie.length-(ut||1)].first_line,last_line:ie[ie.length-1].last_line,first_column:ie[ie.length-(ut||1)].first_column,last_column:ie[ie.length-1].last_column},at&&(Mt._$.range=[ie[ie.length-(ut||1)].range[0],ie[ie.length-1].range[1]]),Tt=this.performAction.apply(Mt,[V,W,Te,Ve.yy,ot[1],de,ie].concat(_e)),typeof Tt<"u")return Tt;ut&&(xe=xe.slice(0,-1*ut*2),de=de.slice(0,-1*ut),ie=ie.slice(0,-1*ut)),xe.push(this.productions_[ot[1]][0]),de.push(Mt.$),ie.push(Mt._$),St=oe[xe[xe.length-2]][xe[xe.length-1]],xe.push(St);break;case 3:return!0}}return!0},"parse")},Be=function(){var ze={EOF:1,parseError:o(function(Ie,xe){if(this.yy.parser)this.yy.parser.parseError(Ie,xe);else throw new Error(Ie)},"parseError"),setInput:o(function(Le,Ie){return this.yy=Ie||this.yy||{},this._input=Le,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var Le=this._input[0];this.yytext+=Le,this.yyleng++,this.offset++,this.match+=Le,this.matched+=Le;var Ie=Le.match(/(?:\r\n?|\n).*/g);return Ie?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Le},"input"),unput:o(function(Le){var Ie=Le.length,xe=Le.split(/(?:\r\n?|\n)/g);this._input=Le+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Ie),this.offset-=Ie;var q=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),xe.length-1&&(this.yylineno-=xe.length-1);var de=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:xe?(xe.length===q.length?this.yylloc.first_column:0)+q[q.length-xe.length].length-xe[0].length:this.yylloc.first_column-Ie},this.options.ranges&&(this.yylloc.range=[de[0],de[0]+this.yyleng-Ie]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(Le){this.unput(this.match.slice(Le))},"less"),pastInput:o(function(){var Le=this.matched.substr(0,this.matched.length-this.match.length);return(Le.length>20?"...":"")+Le.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var Le=this.match;return Le.length<20&&(Le+=this._input.substr(0,20-Le.length)),(Le.substr(0,20)+(Le.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var Le=this.pastInput(),Ie=new Array(Le.length+1).join("-");return Le+this.upcomingInput()+` +`+Ie+"^"},"showPosition"),test_match:o(function(Le,Ie){var xe,q,de;if(this.options.backtrack_lexer&&(de={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(de.yylloc.range=this.yylloc.range.slice(0))),q=Le[0].match(/(?:\r\n?|\n).*/g),q&&(this.yylineno+=q.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:q?q[q.length-1].length-q[q.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Le[0].length},this.yytext+=Le[0],this.match+=Le[0],this.matches=Le,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(Le[0].length),this.matched+=Le[0],xe=this.performAction.call(this,this.yy,this,Ie,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),xe)return xe;if(this._backtrack){for(var ie in de)this[ie]=de[ie];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Le,Ie,xe,q;this._more||(this.yytext="",this.match="");for(var de=this._currentRules(),ie=0;ieIe[0].length)){if(Ie=xe,q=ie,this.options.backtrack_lexer){if(Le=this.test_match(xe,de[ie]),Le!==!1)return Le;if(this._backtrack){Ie=!1;continue}else return!1}else if(!this.options.flex)break}return Ie?(Le=this.test_match(Ie,de[q]),Le!==!1?Le:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var Ie=this.next();return Ie||this.lex()},"lex"),begin:o(function(Ie){this.conditionStack.push(Ie)},"begin"),popState:o(function(){var Ie=this.conditionStack.length-1;return Ie>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(Ie){return Ie=this.conditionStack.length-1-Math.abs(Ie||0),Ie>=0?this.conditionStack[Ie]:"INITIAL"},"topState"),pushState:o(function(Ie){this.begin(Ie)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(Ie,xe,q,de){var ie=de;switch(q){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),26;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:break;case 14:c;break;case 15:return 12;case 16:break;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;break;case 23:return this.begin("person"),44;break;case 24:return this.begin("system_ext_queue"),51;break;case 25:return this.begin("system_ext_db"),50;break;case 26:return this.begin("system_ext"),49;break;case 27:return this.begin("system_queue"),48;break;case 28:return this.begin("system_db"),47;break;case 29:return this.begin("system"),46;break;case 30:return this.begin("boundary"),37;break;case 31:return this.begin("enterprise_boundary"),34;break;case 32:return this.begin("system_boundary"),36;break;case 33:return this.begin("container_ext_queue"),57;break;case 34:return this.begin("container_ext_db"),56;break;case 35:return this.begin("container_ext"),55;break;case 36:return this.begin("container_queue"),54;break;case 37:return this.begin("container_db"),53;break;case 38:return this.begin("container"),52;break;case 39:return this.begin("container_boundary"),38;break;case 40:return this.begin("component_ext_queue"),63;break;case 41:return this.begin("component_ext_db"),62;break;case 42:return this.begin("component_ext"),61;break;case 43:return this.begin("component_queue"),60;break;case 44:return this.begin("component_db"),59;break;case 45:return this.begin("component"),58;break;case 46:return this.begin("node"),39;break;case 47:return this.begin("node"),39;break;case 48:return this.begin("node_l"),40;break;case 49:return this.begin("node_r"),41;break;case 50:return this.begin("rel"),64;break;case 51:return this.begin("birel"),65;break;case 52:return this.begin("rel_u"),66;break;case 53:return this.begin("rel_u"),66;break;case 54:return this.begin("rel_d"),67;break;case 55:return this.begin("rel_d"),67;break;case 56:return this.begin("rel_l"),68;break;case 57:return this.begin("rel_l"),68;break;case 58:return this.begin("rel_r"),69;break;case 59:return this.begin("rel_r"),69;break;case 60:return this.begin("rel_b"),70;break;case 61:return this.begin("rel_index"),71;break;case 62:return this.begin("update_el_style"),72;break;case 63:return this.begin("update_rel_style"),73;break;case 64:return this.begin("update_layout_config"),74;break;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";break;case 67:this.begin("attribute");break;case 68:this.popState(),this.popState();break;case 69:return 80;case 70:break;case 71:return 80;case 72:this.begin("string");break;case 73:this.popState();break;case 74:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";break;case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 79:this.popState(),this.popState();break;case 80:return"STR";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};return ze}();ye.lexer=Be;function He(){this.yy={}}return o(He,"Parser"),He.prototype=ye,ye.Parser=He,new He}();Ry.parser=Ry;G$=Ry});var s7,Un,g0=N(()=>{"use strict";s7=o((t,e,{depth:r=2,clobber:n=!1}={})=>{let i={depth:r,clobber:n};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach(a=>s7(t,a,i)),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach(a=>{t.includes(a)||t.push(a)}),t):t===void 0||r<=0?t!=null&&typeof t=="object"&&typeof e=="object"?Object.assign(t,e):e:(e!==void 0&&typeof t=="object"&&typeof e=="object"&&Object.keys(e).forEach(a=>{typeof e[a]=="object"&&(t[a]===void 0||typeof t[a]=="object")?(t[a]===void 0&&(t[a]=Array.isArray(e[a])?[]:{}),t[a]=s7(t[a],e[a],{depth:r-1,clobber:n})):(n||typeof t[a]!="object"&&typeof e[a]!="object")&&(t[a]=e[a])}),t)},"assignWithDepth"),Un=s7});var Z4,V$,U$=N(()=>{"use strict";Z4={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:o(t=>t>=255?255:t<0?0:t,"r"),g:o(t=>t>=255?255:t<0?0:t,"g"),b:o(t=>t>=255?255:t<0?0:t,"b"),h:o(t=>t%360,"h"),s:o(t=>t>=100?100:t<0?0:t,"s"),l:o(t=>t>=100?100:t<0?0:t,"l"),a:o(t=>t>=1?1:t<0?0:t,"a")},toLinear:o(t=>{let e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},"toLinear"),hue2rgb:o((t,e,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<.16666666666666666?t+(e-t)*6*r:r<.5?e:r<.6666666666666666?t+(e-t)*(.6666666666666666-r)*6:t),"hue2rgb"),hsl2rgb:o(({h:t,s:e,l:r},n)=>{if(!e)return r*2.55;t/=360,e/=100,r/=100;let i=r<.5?r*(1+e):r+e-r*e,a=2*r-i;switch(n){case"r":return Z4.hue2rgb(a,i,t+.3333333333333333)*255;case"g":return Z4.hue2rgb(a,i,t)*255;case"b":return Z4.hue2rgb(a,i,t-.3333333333333333)*255}},"hsl2rgb"),rgb2hsl:o(({r:t,g:e,b:r},n)=>{t/=255,e/=255,r/=255;let i=Math.max(t,e,r),a=Math.min(t,e,r),s=(i+a)/2;if(n==="l")return s*100;if(i===a)return 0;let l=i-a,u=s>.5?l/(2-i-a):l/(i+a);if(n==="s")return u*100;switch(i){case t:return((e-r)/l+(e{"use strict";Mbe={clamp:o((t,e,r)=>e>r?Math.min(e,Math.max(r,t)):Math.min(r,Math.max(e,t)),"clamp"),round:o(t=>Math.round(t*1e10)/1e10,"round")},H$=Mbe});var Ibe,q$,Y$=N(()=>{"use strict";Ibe={dec2hex:o(t=>{let e=Math.round(t).toString(16);return e.length>1?e:`0${e}`},"dec2hex")},q$=Ibe});var Obe,jt,Kl=N(()=>{"use strict";U$();W$();Y$();Obe={channel:V$,lang:H$,unit:q$},jt=Obe});var su,Bi,Ny=N(()=>{"use strict";Kl();su={};for(let t=0;t<=255;t++)su[t]=jt.unit.dec2hex(t);Bi={ALL:0,RGB:1,HSL:2}});var o7,X$,j$=N(()=>{"use strict";Ny();o7=class{static{o(this,"Type")}constructor(){this.type=Bi.ALL}get(){return this.type}set(e){if(this.type&&this.type!==e)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=e}reset(){this.type=Bi.ALL}is(e){return this.type===e}},X$=o7});var l7,K$,Q$=N(()=>{"use strict";Kl();j$();Ny();l7=class{static{o(this,"Channels")}constructor(e,r){this.color=r,this.changed=!1,this.data=e,this.type=new X$}set(e,r){return this.color=r,this.changed=!1,this.data=e,this.type.type=Bi.ALL,this}_ensureHSL(){let e=this.data,{h:r,s:n,l:i}=e;r===void 0&&(e.h=jt.channel.rgb2hsl(e,"h")),n===void 0&&(e.s=jt.channel.rgb2hsl(e,"s")),i===void 0&&(e.l=jt.channel.rgb2hsl(e,"l"))}_ensureRGB(){let e=this.data,{r,g:n,b:i}=e;r===void 0&&(e.r=jt.channel.hsl2rgb(e,"r")),n===void 0&&(e.g=jt.channel.hsl2rgb(e,"g")),i===void 0&&(e.b=jt.channel.hsl2rgb(e,"b"))}get r(){let e=this.data,r=e.r;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"r"))}get g(){let e=this.data,r=e.g;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"g"))}get b(){let e=this.data,r=e.b;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"b"))}get h(){let e=this.data,r=e.h;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"h"))}get s(){let e=this.data,r=e.s;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"s"))}get l(){let e=this.data,r=e.l;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"l"))}get a(){return this.data.a}set r(e){this.type.set(Bi.RGB),this.changed=!0,this.data.r=e}set g(e){this.type.set(Bi.RGB),this.changed=!0,this.data.g=e}set b(e){this.type.set(Bi.RGB),this.changed=!0,this.data.b=e}set h(e){this.type.set(Bi.HSL),this.changed=!0,this.data.h=e}set s(e){this.type.set(Bi.HSL),this.changed=!0,this.data.s=e}set l(e){this.type.set(Bi.HSL),this.changed=!0,this.data.l=e}set a(e){this.changed=!0,this.data.a=e}},K$=l7});var Pbe,uh,My=N(()=>{"use strict";Q$();Pbe=new K$({r:0,g:0,b:0,a:0},"transparent"),uh=Pbe});var Z$,nd,c7=N(()=>{"use strict";My();Ny();Z$={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:o(t=>{if(t.charCodeAt(0)!==35)return;let e=t.match(Z$.re);if(!e)return;let r=e[1],n=parseInt(r,16),i=r.length,a=i%4===0,s=i>4,l=s?1:17,u=s?8:4,h=a?0:-1,f=s?255:15;return uh.set({r:(n>>u*(h+3)&f)*l,g:(n>>u*(h+2)&f)*l,b:(n>>u*(h+1)&f)*l,a:a?(n&f)*l/255:1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`#${su[Math.round(e)]}${su[Math.round(r)]}${su[Math.round(n)]}${su[Math.round(i*255)]}`:`#${su[Math.round(e)]}${su[Math.round(r)]}${su[Math.round(n)]}`},"stringify")},nd=Z$});var J4,Iy,J$=N(()=>{"use strict";Kl();My();J4={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:o(t=>{let e=t.match(J4.hueRe);if(e){let[,r,n]=e;switch(n){case"grad":return jt.channel.clamp.h(parseFloat(r)*.9);case"rad":return jt.channel.clamp.h(parseFloat(r)*180/Math.PI);case"turn":return jt.channel.clamp.h(parseFloat(r)*360)}}return jt.channel.clamp.h(parseFloat(t))},"_hue2deg"),parse:o(t=>{let e=t.charCodeAt(0);if(e!==104&&e!==72)return;let r=t.match(J4.re);if(!r)return;let[,n,i,a,s,l]=r;return uh.set({h:J4._hue2deg(n),s:jt.channel.clamp.s(parseFloat(i)),l:jt.channel.clamp.l(parseFloat(a)),a:s?jt.channel.clamp.a(l?parseFloat(s)/100:parseFloat(s)):1},t)},"parse"),stringify:o(t=>{let{h:e,s:r,l:n,a:i}=t;return i<1?`hsla(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%, ${i})`:`hsl(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%)`},"stringify")},Iy=J4});var e3,u7,ez=N(()=>{"use strict";c7();e3={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:o(t=>{t=t.toLowerCase();let e=e3.colors[t];if(e)return nd.parse(e)},"parse"),stringify:o(t=>{let e=nd.stringify(t);for(let r in e3.colors)if(e3.colors[r]===e)return r},"stringify")},u7=e3});var tz,Oy,rz=N(()=>{"use strict";Kl();My();tz={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:o(t=>{let e=t.charCodeAt(0);if(e!==114&&e!==82)return;let r=t.match(tz.re);if(!r)return;let[,n,i,a,s,l,u,h,f]=r;return uh.set({r:jt.channel.clamp.r(i?parseFloat(n)*2.55:parseFloat(n)),g:jt.channel.clamp.g(s?parseFloat(a)*2.55:parseFloat(a)),b:jt.channel.clamp.b(u?parseFloat(l)*2.55:parseFloat(l)),a:h?jt.channel.clamp.a(f?parseFloat(h)/100:parseFloat(h)):1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`rgba(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)}, ${jt.lang.round(i)})`:`rgb(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)})`},"stringify")},Oy=tz});var Bbe,Fi,ou=N(()=>{"use strict";c7();J$();ez();rz();Ny();Bbe={format:{keyword:u7,hex:nd,rgb:Oy,rgba:Oy,hsl:Iy,hsla:Iy},parse:o(t=>{if(typeof t!="string")return t;let e=nd.parse(t)||Oy.parse(t)||Iy.parse(t)||u7.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},"parse"),stringify:o(t=>!t.changed&&t.color?t.color:t.type.is(Bi.HSL)||t.data.r===void 0?Iy.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?Oy.stringify(t):nd.stringify(t),"stringify")},Fi=Bbe});var Fbe,t3,h7=N(()=>{"use strict";Kl();ou();Fbe=o((t,e)=>{let r=Fi.parse(t);for(let n in e)r[n]=jt.channel.clamp[n](e[n]);return Fi.stringify(r)},"change"),t3=Fbe});var $be,Qa,f7=N(()=>{"use strict";Kl();My();ou();h7();$be=o((t,e,r=0,n=1)=>{if(typeof t!="number")return t3(t,{a:e});let i=uh.set({r:jt.channel.clamp.r(t),g:jt.channel.clamp.g(e),b:jt.channel.clamp.b(r),a:jt.channel.clamp.a(n)});return Fi.stringify(i)},"rgba"),Qa=$be});var zbe,id,nz=N(()=>{"use strict";Kl();ou();zbe=o((t,e)=>jt.lang.round(Fi.parse(t)[e]),"channel"),id=zbe});var Gbe,iz,az=N(()=>{"use strict";Kl();ou();Gbe=o(t=>{let{r:e,g:r,b:n}=Fi.parse(t),i=.2126*jt.channel.toLinear(e)+.7152*jt.channel.toLinear(r)+.0722*jt.channel.toLinear(n);return jt.lang.round(i)},"luminance"),iz=Gbe});var Vbe,sz,oz=N(()=>{"use strict";az();Vbe=o(t=>iz(t)>=.5,"isLight"),sz=Vbe});var Ube,la,lz=N(()=>{"use strict";oz();Ube=o(t=>!sz(t),"isDark"),la=Ube});var Hbe,r3,d7=N(()=>{"use strict";Kl();ou();Hbe=o((t,e,r)=>{let n=Fi.parse(t),i=n[e],a=jt.channel.clamp[e](i+r);return i!==a&&(n[e]=a),Fi.stringify(n)},"adjustChannel"),r3=Hbe});var Wbe,Lt,cz=N(()=>{"use strict";d7();Wbe=o((t,e)=>r3(t,"l",e),"lighten"),Lt=Wbe});var qbe,Ot,uz=N(()=>{"use strict";d7();qbe=o((t,e)=>r3(t,"l",-e),"darken"),Ot=qbe});var Ybe,Me,hz=N(()=>{"use strict";ou();h7();Ybe=o((t,e)=>{let r=Fi.parse(t),n={};for(let i in e)e[i]&&(n[i]=r[i]+e[i]);return t3(t,n)},"adjust"),Me=Ybe});var Xbe,fz,dz=N(()=>{"use strict";ou();f7();Xbe=o((t,e,r=50)=>{let{r:n,g:i,b:a,a:s}=Fi.parse(t),{r:l,g:u,b:h,a:f}=Fi.parse(e),d=r/100,p=d*2-1,m=s-f,y=((p*m===-1?p:(p+m)/(1+p*m))+1)/2,v=1-y,x=n*y+l*v,b=i*y+u*v,T=a*y+h*v,S=s*d+f*(1-d);return Qa(x,b,T,S)},"mix"),fz=Xbe});var jbe,wt,pz=N(()=>{"use strict";ou();dz();jbe=o((t,e=100)=>{let r=Fi.parse(t);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,fz(r,t,e)},"invert"),wt=jbe});var mz=N(()=>{"use strict";f7();nz();lz();cz();uz();hz();pz()});var Ks=N(()=>{"use strict";mz()});var hh,fh,Py=N(()=>{"use strict";hh="#ffffff",fh="#f2f2f2"});var Si,y0=N(()=>{"use strict";Ks();Si=o((t,e)=>e?Me(t,{s:-40,l:10}):Me(t,{s:-40,l:-10}),"mkBorder")});var m7,gz,yz=N(()=>{"use strict";Ks();Py();y0();m7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||Me(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||Me(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Si(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Si(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||wt(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||wt(this.tertiaryColor),this.lineColor=this.lineColor||wt(this.background),this.arrowheadColor=this.arrowheadColor||wt(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?Ot(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||Ot(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||wt(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||Lt(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.vertLineColor=this.vertLineColor||"navy",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.darkMode?(this.rowOdd=this.rowOdd||Ot(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10)):(this.rowOdd=this.rowOdd||Lt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||Lt(this.mainBkg,5)),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.darkMode)for(let r=0;r{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},gz=o(t=>{let e=new m7;return e.calculate(t),e},"getThemeVariables")});var g7,vz,xz=N(()=>{"use strict";Ks();y0();g7=class{static{o(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=Lt(this.primaryColor,16),this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=wt(this.background),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=Lt(wt("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=Qa(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=Ot("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=Ot(this.sectionBkgColor,10),this.taskBorderColor=Qa(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=Qa(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Lt(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10),this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=Lt(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=Lt(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=Lt(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330});for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},vz=o(t=>{let e=new g7;return e.calculate(t),e},"getThemeVariables")});var y7,dh,By=N(()=>{"use strict";Ks();y0();Py();y7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=Me(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.sectionBkgColor=Qa(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="navy",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd="calculated",this.rowEven="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e{this[n]==="calculated"&&(this[n]=void 0)}),typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},dh=o(t=>{let e=new y7;return e.calculate(t),e},"getThemeVariables")});var v7,bz,Tz=N(()=>{"use strict";Ks();Py();y0();v7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=Lt("#cde498",10),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.primaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=Ot(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},bz=o(t=>{let e=new v7;return e.calculate(t),e},"getThemeVariables")});var x7,wz,kz=N(()=>{"use strict";Ks();y0();Py();x7=class{static{o(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=Lt(this.contrast,55),this.background="#ffffff",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Lt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||"#f4f4f4",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=Lt(this.contrast,55),this.border2=this.contrast,this.actorBorder=Lt(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},wz=o(t=>{let e=new x7;return e.calculate(t),e},"getThemeVariables")});var Eo,n3=N(()=>{"use strict";yz();xz();By();Tz();kz();Eo={base:{getThemeVariables:gz},dark:{getThemeVariables:vz},default:{getThemeVariables:dh},forest:{getThemeVariables:bz},neutral:{getThemeVariables:wz}}});var ul,Ez=N(()=>{"use strict";ul={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200,inheritDir:!1},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,maxLabelWidth:360,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],titleColor:"",titleFontFamily:'"trebuchet ms", verdana, arial, sans-serif',titleFontSize:"4ex"},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,nodeSpacing:140,rankSpacing:80,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showDataLabel:!1,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16},radar:{useMaxWidth:!0,width:600,height:600,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,axisScaleFactor:1,axisLabelFactor:1.05,curveTension:.17},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1}});var Sz,Cz,Az,or,_a=N(()=>{"use strict";n3();Ez();Sz={...ul,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF"},themeCSS:void 0,themeVariables:Eo.default.getThemeVariables(),sequence:{...ul.sequence,messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont"),noteFont:o(function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},"noteFont"),actorFont:o(function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}},"actorFont")},class:{hideEmptyMembersBox:!1},gantt:{...ul.gantt,tickInterval:void 0,useWidth:void 0},c4:{...ul.c4,useWidth:void 0,personFont:o(function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},"personFont"),flowchart:{...ul.flowchart,inheritDir:!1},external_personFont:o(function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},"external_personFont"),systemFont:o(function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},"systemFont"),external_systemFont:o(function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},"external_systemFont"),system_dbFont:o(function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},"system_dbFont"),external_system_dbFont:o(function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},"external_system_dbFont"),system_queueFont:o(function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},"system_queueFont"),external_system_queueFont:o(function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},"external_system_queueFont"),containerFont:o(function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},"containerFont"),external_containerFont:o(function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},"external_containerFont"),container_dbFont:o(function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},"container_dbFont"),external_container_dbFont:o(function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},"external_container_dbFont"),container_queueFont:o(function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},"container_queueFont"),external_container_queueFont:o(function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},"external_container_queueFont"),componentFont:o(function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},"componentFont"),external_componentFont:o(function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},"external_componentFont"),component_dbFont:o(function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},"component_dbFont"),external_component_dbFont:o(function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},"external_component_dbFont"),component_queueFont:o(function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},"component_queueFont"),external_component_queueFont:o(function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},"external_component_queueFont"),boundaryFont:o(function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},"boundaryFont"),messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont")},pie:{...ul.pie,useWidth:984},xyChart:{...ul.xyChart,useWidth:void 0},requirement:{...ul.requirement,useWidth:void 0},packet:{...ul.packet},radar:{...ul.radar},treemap:{useMaxWidth:!0,padding:10,diagramPadding:8,showValues:!0,nodeWidth:100,nodeHeight:40,borderWidth:1,valueFontSize:12,labelFontSize:14,valueFormat:","}},Cz=o((t,e="")=>Object.keys(t).reduce((r,n)=>Array.isArray(t[n])?r:typeof t[n]=="object"&&t[n]!==null?[...r,e+n,...Cz(t[n],"")]:[...r,e+n],[]),"keyify"),Az=new Set(Cz(Sz,"")),or=Sz});var v0,Kbe,b7=N(()=>{"use strict";_a();yt();v0=o(t=>{if(X.debug("sanitizeDirective called with",t),!(typeof t!="object"||t==null)){if(Array.isArray(t)){t.forEach(e=>v0(e));return}for(let e of Object.keys(t)){if(X.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!Az.has(e)||t[e]==null){X.debug("sanitize deleting key: ",e),delete t[e];continue}if(typeof t[e]=="object"){X.debug("sanitizing object",e),v0(t[e]);continue}let r=["themeCSS","fontFamily","altFontFamily"];for(let n of r)e.includes(n)&&(X.debug("sanitizing css option",e),t[e]=Kbe(t[e]))}if(t.themeVariables)for(let e of Object.keys(t.themeVariables)){let r=t.themeVariables[e];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}X.debug("After sanitization",t)}},"sanitizeDirective"),Kbe=o(t=>{let e=0,r=0;for(let n of t){if(e{"use strict";g0();yt();n3();_a();b7();ph=Object.freeze(or),Ss=Un({},ph),x0=[],Fy=Un({},ph),i3=o((t,e)=>{let r=Un({},t),n={};for(let i of e)Nz(i),n=Un(n,i);if(r=Un(r,n),n.theme&&n.theme in Eo){let i=Un({},Dz),a=Un(i.themeVariables||{},n.themeVariables);r.theme&&r.theme in Eo&&(r.themeVariables=Eo[r.theme].getThemeVariables(a))}return Fy=r,Iz(Fy),Fy},"updateCurrentConfig"),T7=o(t=>(Ss=Un({},ph),Ss=Un(Ss,t),t.theme&&Eo[t.theme]&&(Ss.themeVariables=Eo[t.theme].getThemeVariables(t.themeVariables)),i3(Ss,x0),Ss),"setSiteConfig"),Lz=o(t=>{Dz=Un({},t)},"saveConfigFromInitialize"),Rz=o(t=>(Ss=Un(Ss,t),i3(Ss,x0),Ss),"updateSiteConfig"),w7=o(()=>Un({},Ss),"getSiteConfig"),a3=o(t=>(Iz(t),Un(Fy,t),tr()),"setConfig"),tr=o(()=>Un({},Fy),"getConfig"),Nz=o(t=>{t&&(["secure",...Ss.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(X.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{typeof t[e]=="string"&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],typeof t[e]=="object"&&Nz(t[e])}))},"sanitize"),Mz=o(t=>{v0(t),t.fontFamily&&!t.themeVariables?.fontFamily&&(t.themeVariables={...t.themeVariables,fontFamily:t.fontFamily}),x0.push(t),i3(Ss,x0)},"addDirective"),$y=o((t=Ss)=>{x0=[],i3(t,x0)},"reset"),Qbe={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},_z={},Zbe=o(t=>{_z[t]||(X.warn(Qbe[t]),_z[t]=!0)},"issueWarning"),Iz=o(t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&Zbe("LAZY_LOAD_DEPRECATED")},"checkConfig")});function es(t){return function(e){e instanceof RegExp&&(e.lastIndex=0);for(var r=arguments.length,n=new Array(r>1?r-1:0),i=1;i2&&arguments[2]!==void 0?arguments[2]:l3;Oz&&Oz(t,null);let n=e.length;for(;n--;){let i=e[n];if(typeof i=="string"){let a=r(i);a!==i&&(Jbe(e)||(e[n]=a),i=a)}t[i]=!0}return t}function o4e(t){for(let e=0;e0&&arguments[0]!==void 0?arguments[0]:v4e(),e=o(Dt=>Xz(Dt),"DOMPurify");if(e.version="3.2.5",e.removed=[],!t||!t.document||t.document.nodeType!==Hy.document||!t.Element)return e.isSupported=!1,e;let{document:r}=t,n=r,i=n.currentScript,{DocumentFragment:a,HTMLTemplateElement:s,Node:l,Element:u,NodeFilter:h,NamedNodeMap:f=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:d,DOMParser:p,trustedTypes:m}=t,g=u.prototype,y=Uy(g,"cloneNode"),v=Uy(g,"remove"),x=Uy(g,"nextSibling"),b=Uy(g,"childNodes"),T=Uy(g,"parentNode");if(typeof s=="function"){let Dt=r.createElement("template");Dt.content&&Dt.content.ownerDocument&&(r=Dt.content.ownerDocument)}let S,w="",{implementation:E,createNodeIterator:_,createDocumentFragment:C,getElementsByTagName:D}=r,{importNode:O}=n,R=Uz();e.isSupported=typeof Hz=="function"&&typeof T=="function"&&E&&E.createHTMLDocument!==void 0;let{MUSTACHE_EXPR:k,ERB_EXPR:L,TMPLIT_EXPR:A,DATA_ATTR:I,ARIA_ATTR:M,IS_SCRIPT_OR_DATA:P,ATTR_WHITESPACE:B,CUSTOM_ELEMENT:F}=Vz,{IS_ALLOWED_URI:z}=Vz,$=null,U=_r({},[...Fz,...E7,...S7,...C7,...$z]),K=null,ee=_r({},[...zz,...A7,...Gz,...o3]),Y=Object.seal(Wz(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ce=null,Z=null,ue=!0,Q=!0,j=!1,ne=!0,te=!1,he=!0,le=!1,J=!1,Se=!1,se=!1,ae=!1,Oe=!1,ye=!0,Be=!1,He="user-content-",ze=!0,Le=!1,Ie={},xe=null,q=_r({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),de=null,ie=_r({},["audio","video","img","source","image","track"]),oe=null,V=_r({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Te="http://www.w3.org/1998/Math/MathML",W="http://www.w3.org/2000/svg",pe="http://www.w3.org/1999/xhtml",ve=pe,Pe=!1,_e=null,be=_r({},[Te,W,pe],k7),Ve=_r({},["mi","mo","mn","ms","mtext"]),De=_r({},["annotation-xml"]),qe=_r({},["title","style","font","a","script"]),at=null,Rt=["application/xhtml+xml","text/html"],st="text/html",Ue=null,ct=null,We=r.createElement("form"),ot=o(function(Ce){return Ce instanceof RegExp||Ce instanceof Function},"isRegexOrFunction"),Yt=o(function(){let Ce=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(ct&&ct===Ce)){if((!Ce||typeof Ce!="object")&&(Ce={}),Ce=ad(Ce),at=Rt.indexOf(Ce.PARSER_MEDIA_TYPE)===-1?st:Ce.PARSER_MEDIA_TYPE,Ue=at==="application/xhtml+xml"?k7:l3,$=hl(Ce,"ALLOWED_TAGS")?_r({},Ce.ALLOWED_TAGS,Ue):U,K=hl(Ce,"ALLOWED_ATTR")?_r({},Ce.ALLOWED_ATTR,Ue):ee,_e=hl(Ce,"ALLOWED_NAMESPACES")?_r({},Ce.ALLOWED_NAMESPACES,k7):be,oe=hl(Ce,"ADD_URI_SAFE_ATTR")?_r(ad(V),Ce.ADD_URI_SAFE_ATTR,Ue):V,de=hl(Ce,"ADD_DATA_URI_TAGS")?_r(ad(ie),Ce.ADD_DATA_URI_TAGS,Ue):ie,xe=hl(Ce,"FORBID_CONTENTS")?_r({},Ce.FORBID_CONTENTS,Ue):q,ce=hl(Ce,"FORBID_TAGS")?_r({},Ce.FORBID_TAGS,Ue):{},Z=hl(Ce,"FORBID_ATTR")?_r({},Ce.FORBID_ATTR,Ue):{},Ie=hl(Ce,"USE_PROFILES")?Ce.USE_PROFILES:!1,ue=Ce.ALLOW_ARIA_ATTR!==!1,Q=Ce.ALLOW_DATA_ATTR!==!1,j=Ce.ALLOW_UNKNOWN_PROTOCOLS||!1,ne=Ce.ALLOW_SELF_CLOSE_IN_ATTR!==!1,te=Ce.SAFE_FOR_TEMPLATES||!1,he=Ce.SAFE_FOR_XML!==!1,le=Ce.WHOLE_DOCUMENT||!1,se=Ce.RETURN_DOM||!1,ae=Ce.RETURN_DOM_FRAGMENT||!1,Oe=Ce.RETURN_TRUSTED_TYPE||!1,Se=Ce.FORCE_BODY||!1,ye=Ce.SANITIZE_DOM!==!1,Be=Ce.SANITIZE_NAMED_PROPS||!1,ze=Ce.KEEP_CONTENT!==!1,Le=Ce.IN_PLACE||!1,z=Ce.ALLOWED_URI_REGEXP||qz,ve=Ce.NAMESPACE||pe,Ve=Ce.MATHML_TEXT_INTEGRATION_POINTS||Ve,De=Ce.HTML_INTEGRATION_POINTS||De,Y=Ce.CUSTOM_ELEMENT_HANDLING||{},Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Y.tagNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Y.attributeNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&typeof Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(Y.allowCustomizedBuiltInElements=Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),te&&(Q=!1),ae&&(se=!0),Ie&&($=_r({},$z),K=[],Ie.html===!0&&(_r($,Fz),_r(K,zz)),Ie.svg===!0&&(_r($,E7),_r(K,A7),_r(K,o3)),Ie.svgFilters===!0&&(_r($,S7),_r(K,A7),_r(K,o3)),Ie.mathMl===!0&&(_r($,C7),_r(K,Gz),_r(K,o3))),Ce.ADD_TAGS&&($===U&&($=ad($)),_r($,Ce.ADD_TAGS,Ue)),Ce.ADD_ATTR&&(K===ee&&(K=ad(K)),_r(K,Ce.ADD_ATTR,Ue)),Ce.ADD_URI_SAFE_ATTR&&_r(oe,Ce.ADD_URI_SAFE_ATTR,Ue),Ce.FORBID_CONTENTS&&(xe===q&&(xe=ad(xe)),_r(xe,Ce.FORBID_CONTENTS,Ue)),ze&&($["#text"]=!0),le&&_r($,["html","head","body"]),$.table&&(_r($,["tbody"]),delete ce.tbody),Ce.TRUSTED_TYPES_POLICY){if(typeof Ce.TRUSTED_TYPES_POLICY.createHTML!="function")throw Vy('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof Ce.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Vy('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');S=Ce.TRUSTED_TYPES_POLICY,w=S.createHTML("")}else S===void 0&&(S=x4e(m,i)),S!==null&&typeof w=="string"&&(w=S.createHTML(""));Ja&&Ja(Ce),ct=Ce}},"_parseConfig"),Tt=_r({},[...E7,...S7,...l4e]),Mt=_r({},[...C7,...c4e]),bt=o(function(Ce){let tt=T(Ce);(!tt||!tt.tagName)&&(tt={namespaceURI:ve,tagName:"template"});let Ct=l3(Ce.tagName),gr=l3(tt.tagName);return _e[Ce.namespaceURI]?Ce.namespaceURI===W?tt.namespaceURI===pe?Ct==="svg":tt.namespaceURI===Te?Ct==="svg"&&(gr==="annotation-xml"||Ve[gr]):!!Tt[Ct]:Ce.namespaceURI===Te?tt.namespaceURI===pe?Ct==="math":tt.namespaceURI===W?Ct==="math"&&De[gr]:!!Mt[Ct]:Ce.namespaceURI===pe?tt.namespaceURI===W&&!De[gr]||tt.namespaceURI===Te&&!Ve[gr]?!1:!Mt[Ct]&&(qe[Ct]||!Tt[Ct]):!!(at==="application/xhtml+xml"&&_e[Ce.namespaceURI]):!1},"_checkValidNamespace"),ut=o(function(Ce){zy(e.removed,{element:Ce});try{T(Ce).removeChild(Ce)}catch{v(Ce)}},"_forceRemove"),St=o(function(Ce,tt){try{zy(e.removed,{attribute:tt.getAttributeNode(Ce),from:tt})}catch{zy(e.removed,{attribute:null,from:tt})}if(tt.removeAttribute(Ce),Ce==="is")if(se||ae)try{ut(tt)}catch{}else try{tt.setAttribute(Ce,"")}catch{}},"_removeAttribute"),ft=o(function(Ce){let tt=null,Ct=null;if(Se)Ce=""+Ce;else{let yn=Bz(Ce,/^[\r\n\t ]+/);Ct=yn&&yn[0]}at==="application/xhtml+xml"&&ve===pe&&(Ce=''+Ce+"");let gr=S?S.createHTML(Ce):Ce;if(ve===pe)try{tt=new p().parseFromString(gr,at)}catch{}if(!tt||!tt.documentElement){tt=E.createDocument(ve,"template",null);try{tt.documentElement.innerHTML=Pe?w:gr}catch{}}let rn=tt.body||tt.documentElement;return Ce&&Ct&&rn.insertBefore(r.createTextNode(Ct),rn.childNodes[0]||null),ve===pe?D.call(tt,le?"html":"body")[0]:le?tt.documentElement:rn},"_initDocument"),vt=o(function(Ce){return _.call(Ce.ownerDocument||Ce,Ce,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT|h.SHOW_PROCESSING_INSTRUCTION|h.SHOW_CDATA_SECTION,null)},"_createNodeIterator"),nt=o(function(Ce){return Ce instanceof d&&(typeof Ce.nodeName!="string"||typeof Ce.textContent!="string"||typeof Ce.removeChild!="function"||!(Ce.attributes instanceof f)||typeof Ce.removeAttribute!="function"||typeof Ce.setAttribute!="function"||typeof Ce.namespaceURI!="string"||typeof Ce.insertBefore!="function"||typeof Ce.hasChildNodes!="function")},"_isClobbered"),pn=o(function(Ce){return typeof l=="function"&&Ce instanceof l},"_isNode");function kt(Dt,Ce,tt){s3(Dt,Ct=>{Ct.call(e,Ce,tt,ct)})}o(kt,"_executeHooks");let On=o(function(Ce){let tt=null;if(kt(R.beforeSanitizeElements,Ce,null),nt(Ce))return ut(Ce),!0;let Ct=Ue(Ce.nodeName);if(kt(R.uponSanitizeElement,Ce,{tagName:Ct,allowedTags:$}),Ce.hasChildNodes()&&!pn(Ce.firstElementChild)&&Za(/<[/\w!]/g,Ce.innerHTML)&&Za(/<[/\w!]/g,Ce.textContent)||Ce.nodeType===Hy.progressingInstruction||he&&Ce.nodeType===Hy.comment&&Za(/<[/\w]/g,Ce.data))return ut(Ce),!0;if(!$[Ct]||ce[Ct]){if(!ce[Ct]&&Mr(Ct)&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ct)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ct)))return!1;if(ze&&!xe[Ct]){let gr=T(Ce)||Ce.parentNode,rn=b(Ce)||Ce.childNodes;if(rn&&gr){let yn=rn.length;for(let Zr=yn-1;Zr>=0;--Zr){let Oi=y(rn[Zr],!0);Oi.__removalCount=(Ce.__removalCount||0)+1,gr.insertBefore(Oi,x(Ce))}}}return ut(Ce),!0}return Ce instanceof u&&!bt(Ce)||(Ct==="noscript"||Ct==="noembed"||Ct==="noframes")&&Za(/<\/no(script|embed|frames)/i,Ce.innerHTML)?(ut(Ce),!0):(te&&Ce.nodeType===Hy.text&&(tt=Ce.textContent,s3([k,L,A],gr=>{tt=Gy(tt,gr," ")}),Ce.textContent!==tt&&(zy(e.removed,{element:Ce.cloneNode()}),Ce.textContent=tt)),kt(R.afterSanitizeElements,Ce,null),!1)},"_sanitizeElements"),tn=o(function(Ce,tt,Ct){if(ye&&(tt==="id"||tt==="name")&&(Ct in r||Ct in We))return!1;if(!(Q&&!Z[tt]&&Za(I,tt))){if(!(ue&&Za(M,tt))){if(!K[tt]||Z[tt]){if(!(Mr(Ce)&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ce)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ce))&&(Y.attributeNameCheck instanceof RegExp&&Za(Y.attributeNameCheck,tt)||Y.attributeNameCheck instanceof Function&&Y.attributeNameCheck(tt))||tt==="is"&&Y.allowCustomizedBuiltInElements&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ct)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ct))))return!1}else if(!oe[tt]){if(!Za(z,Gy(Ct,B,""))){if(!((tt==="src"||tt==="xlink:href"||tt==="href")&&Ce!=="script"&&i4e(Ct,"data:")===0&&de[Ce])){if(!(j&&!Za(P,Gy(Ct,B,"")))){if(Ct)return!1}}}}}}return!0},"_isValidAttribute"),Mr=o(function(Ce){return Ce!=="annotation-xml"&&Bz(Ce,F)},"_isBasicCustomElement"),Ir=o(function(Ce){kt(R.beforeSanitizeAttributes,Ce,null);let{attributes:tt}=Ce;if(!tt||nt(Ce))return;let Ct={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:K,forceKeepAttr:void 0},gr=tt.length;for(;gr--;){let rn=tt[gr],{name:yn,namespaceURI:Zr,value:Oi}=rn,ei=Ue(yn),Sn=yn==="value"?Oi:a4e(Oi);if(Ct.attrName=ei,Ct.attrValue=Sn,Ct.keepAttr=!0,Ct.forceKeepAttr=void 0,kt(R.uponSanitizeAttribute,Ce,Ct),Sn=Ct.attrValue,Be&&(ei==="id"||ei==="name")&&(St(yn,Ce),Sn=He+Sn),he&&Za(/((--!?|])>)|<\/(style|title)/i,Sn)){St(yn,Ce);continue}if(Ct.forceKeepAttr||(St(yn,Ce),!Ct.keepAttr))continue;if(!ne&&Za(/\/>/i,Sn)){St(yn,Ce);continue}te&&s3([k,L,A],et=>{Sn=Gy(Sn,et," ")});let Hr=Ue(Ce.nodeName);if(tn(Hr,ei,Sn)){if(S&&typeof m=="object"&&typeof m.getAttributeType=="function"&&!Zr)switch(m.getAttributeType(Hr,ei)){case"TrustedHTML":{Sn=S.createHTML(Sn);break}case"TrustedScriptURL":{Sn=S.createScriptURL(Sn);break}}try{Zr?Ce.setAttributeNS(Zr,yn,Sn):Ce.setAttribute(yn,Sn),nt(Ce)?ut(Ce):Pz(e.removed)}catch{}}}kt(R.afterSanitizeAttributes,Ce,null)},"_sanitizeAttributes"),Pn=o(function Dt(Ce){let tt=null,Ct=vt(Ce);for(kt(R.beforeSanitizeShadowDOM,Ce,null);tt=Ct.nextNode();)kt(R.uponSanitizeShadowNode,tt,null),On(tt),Ir(tt),tt.content instanceof a&&Dt(tt.content);kt(R.afterSanitizeShadowDOM,Ce,null)},"_sanitizeShadowDOM");return e.sanitize=function(Dt){let Ce=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},tt=null,Ct=null,gr=null,rn=null;if(Pe=!Dt,Pe&&(Dt=""),typeof Dt!="string"&&!pn(Dt))if(typeof Dt.toString=="function"){if(Dt=Dt.toString(),typeof Dt!="string")throw Vy("dirty is not a string, aborting")}else throw Vy("toString is not a function");if(!e.isSupported)return Dt;if(J||Yt(Ce),e.removed=[],typeof Dt=="string"&&(Le=!1),Le){if(Dt.nodeName){let Oi=Ue(Dt.nodeName);if(!$[Oi]||ce[Oi])throw Vy("root node is forbidden and cannot be sanitized in-place")}}else if(Dt instanceof l)tt=ft(""),Ct=tt.ownerDocument.importNode(Dt,!0),Ct.nodeType===Hy.element&&Ct.nodeName==="BODY"||Ct.nodeName==="HTML"?tt=Ct:tt.appendChild(Ct);else{if(!se&&!te&&!le&&Dt.indexOf("<")===-1)return S&&Oe?S.createHTML(Dt):Dt;if(tt=ft(Dt),!tt)return se?null:Oe?w:""}tt&&Se&&ut(tt.firstChild);let yn=vt(Le?Dt:tt);for(;gr=yn.nextNode();)On(gr),Ir(gr),gr.content instanceof a&&Pn(gr.content);if(Le)return Dt;if(se){if(ae)for(rn=C.call(tt.ownerDocument);tt.firstChild;)rn.appendChild(tt.firstChild);else rn=tt;return(K.shadowroot||K.shadowrootmode)&&(rn=O.call(n,rn,!0)),rn}let Zr=le?tt.outerHTML:tt.innerHTML;return le&&$["!doctype"]&&tt.ownerDocument&&tt.ownerDocument.doctype&&tt.ownerDocument.doctype.name&&Za(Yz,tt.ownerDocument.doctype.name)&&(Zr=" +`+Zr),te&&s3([k,L,A],Oi=>{Zr=Gy(Zr,Oi," ")}),S&&Oe?S.createHTML(Zr):Zr},e.setConfig=function(){let Dt=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Yt(Dt),J=!0},e.clearConfig=function(){ct=null,J=!1},e.isValidAttribute=function(Dt,Ce,tt){ct||Yt({});let Ct=Ue(Dt),gr=Ue(Ce);return tn(Ct,gr,tt)},e.addHook=function(Dt,Ce){typeof Ce=="function"&&zy(R[Dt],Ce)},e.removeHook=function(Dt,Ce){if(Ce!==void 0){let tt=r4e(R[Dt],Ce);return tt===-1?void 0:n4e(R[Dt],tt,1)[0]}return Pz(R[Dt])},e.removeHooks=function(Dt){R[Dt]=[]},e.removeAllHooks=function(){R=Uz()},e}var Hz,Oz,Jbe,e4e,t4e,Ja,So,Wz,_7,D7,s3,r4e,Pz,zy,n4e,l3,k7,Bz,Gy,i4e,a4e,hl,Za,Vy,Fz,E7,S7,l4e,C7,c4e,$z,zz,A7,Gz,o3,u4e,h4e,f4e,d4e,p4e,qz,m4e,g4e,Yz,y4e,Vz,Hy,v4e,x4e,Uz,mh,L7=N(()=>{"use strict";({entries:Hz,setPrototypeOf:Oz,isFrozen:Jbe,getPrototypeOf:e4e,getOwnPropertyDescriptor:t4e}=Object),{freeze:Ja,seal:So,create:Wz}=Object,{apply:_7,construct:D7}=typeof Reflect<"u"&&Reflect;Ja||(Ja=o(function(e){return e},"freeze"));So||(So=o(function(e){return e},"seal"));_7||(_7=o(function(e,r,n){return e.apply(r,n)},"apply"));D7||(D7=o(function(e,r){return new e(...r)},"construct"));s3=es(Array.prototype.forEach),r4e=es(Array.prototype.lastIndexOf),Pz=es(Array.prototype.pop),zy=es(Array.prototype.push),n4e=es(Array.prototype.splice),l3=es(String.prototype.toLowerCase),k7=es(String.prototype.toString),Bz=es(String.prototype.match),Gy=es(String.prototype.replace),i4e=es(String.prototype.indexOf),a4e=es(String.prototype.trim),hl=es(Object.prototype.hasOwnProperty),Za=es(RegExp.prototype.test),Vy=s4e(TypeError);o(es,"unapply");o(s4e,"unconstruct");o(_r,"addToSet");o(o4e,"cleanArray");o(ad,"clone");o(Uy,"lookupGetter");Fz=Ja(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),E7=Ja(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),S7=Ja(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),l4e=Ja(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),C7=Ja(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),c4e=Ja(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),$z=Ja(["#text"]),zz=Ja(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),A7=Ja(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),Gz=Ja(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),o3=Ja(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),u4e=So(/\{\{[\w\W]*|[\w\W]*\}\}/gm),h4e=So(/<%[\w\W]*|[\w\W]*%>/gm),f4e=So(/\$\{[\w\W]*/gm),d4e=So(/^data-[\-\w.\u00B7-\uFFFF]+$/),p4e=So(/^aria-[\-\w]+$/),qz=So(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),m4e=So(/^(?:\w+script|data):/i),g4e=So(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Yz=So(/^html$/i),y4e=So(/^[a-z][.\w]*(-[.\w]+)+$/i),Vz=Object.freeze({__proto__:null,ARIA_ATTR:p4e,ATTR_WHITESPACE:g4e,CUSTOM_ELEMENT:y4e,DATA_ATTR:d4e,DOCTYPE_NAME:Yz,ERB_EXPR:h4e,IS_ALLOWED_URI:qz,IS_SCRIPT_OR_DATA:m4e,MUSTACHE_EXPR:u4e,TMPLIT_EXPR:f4e}),Hy={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},v4e=o(function(){return typeof window>"u"?null:window},"getGlobal"),x4e=o(function(e,r){if(typeof e!="object"||typeof e.createPolicy!="function")return null;let n=null,i="data-tt-policy-suffix";r&&r.hasAttribute(i)&&(n=r.getAttribute(i));let a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML(s){return s},createScriptURL(s){return s}})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}},"_createTrustedTypesPolicy"),Uz=o(function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},"_createHooksMap");o(Xz,"createDOMPurify");mh=Xz()});var CV={};ur(CV,{ParseError:()=>pt,SETTINGS_SCHEMA:()=>Xy,__defineFunction:()=>Nt,__defineMacro:()=>fe,__defineSymbol:()=>G,__domTree:()=>SV,__parse:()=>TV,__renderToDomTree:()=>O3,__renderToHTMLTree:()=>kV,__setFontMetrics:()=>_G,default:()=>u5e,render:()=>xA,renderToString:()=>bV,version:()=>EV});function C4e(t){return String(t).replace(S4e,e=>E4e[e])}function L4e(t){if(t.default)return t.default;var e=t.type,r=Array.isArray(e)?e[0]:e;if(typeof r!="string")return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}function B4e(t){for(var e=0;e=i[0]&&t<=i[1])return r.name}return null}function AG(t){for(var e=0;e=b3[e]&&t<=b3[e+1])return!0;return!1}function _G(t,e){Jl[t]=e}function nA(t,e,r){if(!Jl[e])throw new Error("Font metrics not found for font: "+e+".");var n=t.charCodeAt(0),i=Jl[e][n];if(!i&&t[0]in Kz&&(n=Kz[t[0]].charCodeAt(0),i=Jl[e][n]),!i&&r==="text"&&AG(n)&&(i=Jl[e][77]),i)return{depth:i[0],height:i[1],italic:i[2],skew:i[3],width:i[4]}}function X4e(t){var e;if(t>=5?e=0:t>=3?e=1:e=2,!R7[e]){var r=R7[e]={cssEmPerMu:c3.quad[e]/18};for(var n in c3)c3.hasOwnProperty(n)&&(r[n]=c3[n][e])}return R7[e]}function Jz(t){if(t instanceof As)return t;throw new Error("Expected symbolNode but got "+String(t)+".")}function J4e(t){if(t instanceof ld)return t;throw new Error("Expected span but got "+String(t)+".")}function G(t,e,r,n,i,a){An[t][i]={font:e,group:r,replace:n},a&&n&&(An[t][n]=An[t][i])}function Nt(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs,argTypes:n.argTypes,allowedInArgument:!!n.allowedInArgument,allowedInText:!!n.allowedInText,allowedInMath:n.allowedInMath===void 0?!0:n.allowedInMath,numOptionalArgs:n.numOptionalArgs||0,infix:!!n.infix,primitive:!!n.primitive,handler:i},u=0;u0&&(a.push(g3(s,e)),s=[]),a.push(n[l]));s.length>0&&a.push(g3(s,e));var h;r?(h=g3($i(r,e,!0)),h.classes=["tag"],a.push(h)):i&&a.push(i);var f=fu(["katex-html"],a);if(f.setAttribute("aria-hidden","true"),h){var d=h.children[0];d.style.height=Et(f.height+f.depth),f.depth&&(d.style.verticalAlign=Et(-f.depth))}return f}function zG(t){return new od(t)}function I7(t){if(!t)return!1;if(t.type==="mi"&&t.children.length===1){var e=t.children[0];return e instanceof Ao&&e.text==="."}else if(t.type==="mo"&&t.children.length===1&&t.getAttribute("separator")==="true"&&t.getAttribute("lspace")==="0em"&&t.getAttribute("rspace")==="0em"){var r=t.children[0];return r instanceof Ao&&r.text===","}else return!1}function iG(t,e,r,n,i){var a=_s(t,r),s;a.length===1&&a[0]instanceof ts&&Jt.contains(["mrow","mtable"],a[0].type)?s=a[0]:s=new dt.MathNode("mrow",a);var l=new dt.MathNode("annotation",[new dt.TextNode(e)]);l.setAttribute("encoding","application/x-tex");var u=new dt.MathNode("semantics",[s,l]),h=new dt.MathNode("math",[u]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&h.setAttribute("display","block");var f=i?"katex":"katex-mathml";return Fe.makeSpan([f],[h])}function xr(t,e){if(!t||t.type!==e)throw new Error("Expected node of type "+e+", but got "+(t?"node of type "+t.type:String(t)));return t}function oA(t){var e=R3(t);if(!e)throw new Error("Expected node of symbol group type, but got "+(t?"node of type "+t.type:String(t)));return e}function R3(t){return t&&(t.type==="atom"||t3e.hasOwnProperty(t.type))?t:null}function HG(t,e){var r=$i(t.body,e,!0);return R3e([t.mclass],r,e)}function WG(t,e){var r,n=_s(t.body,e);return t.mclass==="minner"?r=new dt.MathNode("mpadded",n):t.mclass==="mord"?t.isCharacterBox?(r=n[0],r.type="mi"):r=new dt.MathNode("mi",n):(t.isCharacterBox?(r=n[0],r.type="mo"):r=new dt.MathNode("mo",n),t.mclass==="mbin"?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):t.mclass==="mpunct"?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):t.mclass==="mopen"||t.mclass==="mclose"?(r.attributes.lspace="0em",r.attributes.rspace="0em"):t.mclass==="minner"&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}function I3e(t,e,r){var n=N3e[t];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var i=r.callFunction("\\\\cdleft",[e[0]],[]),a={type:"atom",text:n,mode:"math",family:"rel"},s=r.callFunction("\\Big",[a],[]),l=r.callFunction("\\\\cdright",[e[1]],[]),u={type:"ordgroup",mode:"math",body:[i,s,l]};return r.callFunction("\\\\cdparent",[u],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function O3e(t){var e=[];for(t.gullet.beginGroup(),t.gullet.macros.set("\\cr","\\\\\\relax"),t.gullet.beginGroup();;){e.push(t.parseExpression(!1,"\\\\")),t.gullet.endGroup(),t.gullet.beginGroup();var r=t.fetch().text;if(r==="&"||r==="\\\\")t.consume();else if(r==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new pt("Expected \\\\ or \\cr or \\end",t.nextToken)}for(var n=[],i=[n],a=0;a-1))if("<>AV".indexOf(h)>-1)for(var d=0;d<2;d++){for(var p=!0,m=u+1;mAV=|." after @',s[u]);var g=I3e(h,f,t),y={type:"styling",body:[g],mode:"math",style:"display"};n.push(y),l=aG()}a%2===0?n.push(l):n.shift(),n=[],i.push(n)}t.gullet.endGroup(),t.gullet.endGroup();var v=new Array(i[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:i,arraystretch:1,addJot:!0,rowGaps:[null],cols:v,colSeparationType:"CD",hLinesBeforeRow:new Array(i.length+1).fill([])}}function M3(t,e){var r=R3(t);if(r&&Jt.contains(X3e,r.text))return r;throw r?new pt("Invalid delimiter '"+r.text+"' after '"+e.funcName+"'",t):new pt("Invalid delimiter type '"+t.type+"'",t)}function lG(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}function tc(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:i},u=0;u1||!f)&&y.pop(),x.length{"use strict";Qs=class t{static{o(this,"SourceLocation")}constructor(e,r,n){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=r,this.end=n}static range(e,r){return r?!e||!e.loc||!r.loc||e.loc.lexer!==r.loc.lexer?null:new t(e.loc.lexer,e.loc.start,r.loc.end):e&&e.loc}},_o=class t{static{o(this,"Token")}constructor(e,r){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=r}range(e,r){return new t(r,Qs.range(this,e))}},pt=class t{static{o(this,"ParseError")}constructor(e,r){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var n="KaTeX parse error: "+e,i,a,s=r&&r.loc;if(s&&s.start<=s.end){var l=s.lexer.input;i=s.start,a=s.end,i===l.length?n+=" at end of input: ":n+=" at position "+(i+1)+": ";var u=l.slice(i,a).replace(/[^]/g,"$&\u0332"),h;i>15?h="\u2026"+l.slice(i-15,i):h=l.slice(0,i);var f;a+15":">","<":"<",'"':""","'":"'"},S4e=/[&><"']/g;o(C4e,"escape");CG=o(function t(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?t(e.body[0]):e:e.type==="font"?t(e.body):e},"getBaseElem"),A4e=o(function(e){var r=CG(e);return r.type==="mathord"||r.type==="textord"||r.type==="atom"},"isCharacterBox"),_4e=o(function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},"assert"),D4e=o(function(e){var r=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return r?r[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(r[1])?null:r[1].toLowerCase():"_relative"},"protocolFromUrl"),Jt={contains:b4e,deflt:T4e,escape:C4e,hyphenate:k4e,getBaseElem:CG,isCharacterBox:A4e,protocolFromUrl:D4e},Xy={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:o(t=>"#"+t,"cliProcessor")},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:o((t,e)=>(e.push(t),e),"cliProcessor")},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:o(t=>Math.max(0,t),"processor"),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:o(t=>Math.max(0,t),"processor"),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:o(t=>Math.max(0,t),"processor"),cli:"-e, --max-expand ",cliProcessor:o(t=>t==="Infinity"?1/0:parseInt(t),"cliProcessor")},globalGroup:{type:"boolean",cli:!1}};o(L4e,"getDefaultValue");Ky=class{static{o(this,"Settings")}constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var r in Xy)if(Xy.hasOwnProperty(r)){var n=Xy[r];this[r]=e[r]!==void 0?n.processor?n.processor(e[r]):e[r]:L4e(n)}}reportNonstrict(e,r,n){var i=this.strict;if(typeof i=="function"&&(i=i(e,r,n)),!(!i||i==="ignore")){if(i===!0||i==="error")throw new pt("LaTeX-incompatible input and strict mode is set to 'error': "+(r+" ["+e+"]"),n);i==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]"))}}useStrictBehavior(e,r,n){var i=this.strict;if(typeof i=="function")try{i=i(e,r,n)}catch{i="error"}return!i||i==="ignore"?!1:i===!0||i==="error"?!0:i==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var r=Jt.protocolFromUrl(e.url);if(r==null)return!1;e.protocol=r}var n=typeof this.trust=="function"?this.trust(e):this.trust;return!!n}},Ql=class{static{o(this,"Style")}constructor(e,r,n){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=r,this.cramped=n}sup(){return Zl[R4e[this.id]]}sub(){return Zl[N4e[this.id]]}fracNum(){return Zl[M4e[this.id]]}fracDen(){return Zl[I4e[this.id]]}cramp(){return Zl[O4e[this.id]]}text(){return Zl[P4e[this.id]]}isTight(){return this.size>=2}},rA=0,T3=1,w0=2,uu=3,Qy=4,Co=5,k0=6,rs=7,Zl=[new Ql(rA,0,!1),new Ql(T3,0,!0),new Ql(w0,1,!1),new Ql(uu,1,!0),new Ql(Qy,2,!1),new Ql(Co,2,!0),new Ql(k0,3,!1),new Ql(rs,3,!0)],R4e=[Qy,Co,Qy,Co,k0,rs,k0,rs],N4e=[Co,Co,Co,Co,rs,rs,rs,rs],M4e=[w0,uu,Qy,Co,k0,rs,k0,rs],I4e=[uu,uu,Co,Co,rs,rs,rs,rs],O4e=[T3,T3,uu,uu,Co,Co,rs,rs],P4e=[rA,T3,w0,uu,w0,uu,w0,uu],nr={DISPLAY:Zl[rA],TEXT:Zl[w0],SCRIPT:Zl[Qy],SCRIPTSCRIPT:Zl[k0]},H7=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];o(B4e,"scriptFromCodepoint");b3=[];H7.forEach(t=>t.blocks.forEach(e=>b3.push(...e)));o(AG,"supportedCodepoint");T0=80,F4e=o(function(e,r){return"M95,"+(622+e+r)+` +c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 +c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 +c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 +s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429 +c69,-144,104.5,-217.7,106.5,-221 +l`+e/2.075+" -"+e+` +c5.3,-9.3,12,-14,20,-14 +H400000v`+(40+e)+`H845.2724 +s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 +c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z +M`+(834+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtMain"),$4e=o(function(e,r){return"M263,"+(601+e+r)+`c0.7,0,18,39.7,52,119 +c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 +c340,-704.7,510.7,-1060.3,512,-1067 +l`+e/2.084+" -"+e+` +c4.7,-7.3,11,-11,19,-11 +H40000v`+(40+e)+`H1012.3 +s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232 +c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 +s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 +c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z +M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize1"),z4e=o(function(e,r){return"M983 "+(10+e+r)+` +l`+e/3.13+" -"+e+` +c4,-6.7,10,-10,18,-10 H400000v`+(40+e)+` +H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7 +s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744 +c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30 +c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722 +c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5 +c53.7,-170.3,84.5,-266.8,92.5,-289.5z +M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize2"),G4e=o(function(e,r){return"M424,"+(2398+e+r)+` +c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514 +c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20 +s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121 +s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081 +l`+e/4.223+" -"+e+`c4,-6.7,10,-10,18,-10 H400000 +v`+(40+e)+`H1014.6 +s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185 +c-2,6,-10,9,-24,9 +c-8,0,-12,-0.7,-12,-2z M`+(1001+e)+" "+r+` +h400000v`+(40+e)+"h-400000z"},"sqrtSize3"),V4e=o(function(e,r){return"M473,"+(2713+e+r)+` +c339.3,-1799.3,509.3,-2700,510,-2702 l`+e/5.298+" -"+e+` +c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+e)+`H1017.7 +s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9 +c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200 +c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26 +s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104, +606zM`+(1001+e)+" "+r+"h400000v"+(40+e)+"H1017.7z"},"sqrtSize4"),U4e=o(function(e){var r=e/2;return"M400000 "+e+" H0 L"+r+" 0 l65 45 L145 "+(e-80)+" H400000z"},"phasePath"),H4e=o(function(e,r,n){var i=n-54-r-e;return"M702 "+(e+r)+"H400000"+(40+e)+` +H742v`+i+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1 +h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170 +c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 +219 661 l218 661zM702 `+r+"H400000v"+(40+e)+"H742z"},"sqrtTall"),W4e=o(function(e,r,n){r=1e3*r;var i="";switch(e){case"sqrtMain":i=F4e(r,T0);break;case"sqrtSize1":i=$4e(r,T0);break;case"sqrtSize2":i=z4e(r,T0);break;case"sqrtSize3":i=G4e(r,T0);break;case"sqrtSize4":i=V4e(r,T0);break;case"sqrtTall":i=H4e(r,T0,n)}return i},"sqrtPath"),q4e=o(function(e,r){switch(e){case"\u239C":return"M291 0 H417 V"+r+" H291z M291 0 H417 V"+r+" H291z";case"\u2223":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z";case"\u2225":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z"+("M367 0 H410 V"+r+" H367z M367 0 H410 V"+r+" H367z");case"\u239F":return"M457 0 H583 V"+r+" H457z M457 0 H583 V"+r+" H457z";case"\u23A2":return"M319 0 H403 V"+r+" H319z M319 0 H403 V"+r+" H319z";case"\u23A5":return"M263 0 H347 V"+r+" H263z M263 0 H347 V"+r+" H263z";case"\u23AA":return"M384 0 H504 V"+r+" H384z M384 0 H504 V"+r+" H384z";case"\u23D0":return"M312 0 H355 V"+r+" H312z M312 0 H355 V"+r+" H312z";case"\u2016":return"M257 0 H300 V"+r+" H257z M257 0 H300 V"+r+" H257z"+("M478 0 H521 V"+r+" H478z M478 0 H521 V"+r+" H478z");default:return""}},"innerPath"),jz={doubleleftarrow:`M262 157 +l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 + 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28 + 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5 +c2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5 + 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87 +-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7 +-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z +m8 0v40h399730v-40zm0 194v40h399730v-40z`,doublerightarrow:`M399738 392l +-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5 + 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88 +-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68 +-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18 +-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782 +c-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3 +-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,leftarrow:`M400000 241H110l3-3c68.7-52.7 113.7-120 + 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8 +-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247 +c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208 + 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3 + 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202 + l-3-3h399890zM100 241v40h399900v-40z`,leftbrace:`M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117 +-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7 + 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,leftbraceunder:`M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13 + 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688 + 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7 +-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,leftgroup:`M400000 80 +H435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0 + 435 0h399565z`,leftgroupunder:`M400000 262 +H435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219 + 435 219h399565z`,leftharpoon:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3 +-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5 +-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7 +-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,leftharpoonplus:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5 + 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3 +-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7 +-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z +m0 0v40h400000v-40z`,leftharpoondown:`M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333 + 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5 + 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667 +-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,leftharpoondownplus:`M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12 + 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7 +-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0 +v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,lefthook:`M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5 +-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3 +-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21 + 71.5 23h399859zM103 281v-40h399897v40z`,leftlinesegment:`M40 281 V428 H0 V94 H40 V241 H400000 v40z +M40 281 V428 H0 V94 H40 V241 H400000 v40z`,leftmapsto:`M40 281 V448H0V74H40V241H400000v40z +M40 281 V448H0V74H40V241H400000v40z`,leftToFrom:`M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23 +-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8 +c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3 + 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,longequal:`M0 50 h400000 v40H0z m0 194h40000v40H0z +M0 50 h400000 v40H0z m0 194h40000v40H0z`,midbrace:`M200428 334 +c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14 +-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7 + 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11 + 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,midbraceunder:`M199572 214 +c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14 + 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3 + 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0 +-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,oiintSize1:`M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6 +-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z +m368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8 +60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,oiintSize2:`M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8 +-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z +m502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2 +c0 110 84 276 504 276s502.4-166 502.4-276z`,oiiintSize1:`M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6 +-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z +m525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0 +85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,oiiintSize2:`M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8 +-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z +m770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1 +c0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,rightarrow:`M0 241v40h399891c-47.3 35.3-84 78-110 128 +-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 + 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 + 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85 +-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 +-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 + 151.7 139 205zm0 0v40h399900v-40z`,rightbrace:`M400000 542l +-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5 +s-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1 +c124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,rightbraceunder:`M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3 + 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237 +-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,rightgroup:`M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0 + 3-1 3-3v-38c-76-158-257-219-435-219H0z`,rightgroupunder:`M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18 + 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,rightharpoon:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3 +-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2 +-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 + 69.2 92 94.5zm0 0v40h399900v-40z`,rightharpoonplus:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11 +-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7 + 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z +m0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,rightharpoondown:`M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8 + 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5 +-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95 +-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,rightharpoondownplus:`M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8 + 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 + 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3 +-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z +m0-194v40h400000v-40zm0 0v40h400000v-40z`,righthook:`M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3 + 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0 +-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21 + 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,rightlinesegment:`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z +M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,rightToFrom:`M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23 + 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32 +-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142 +-167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,twoheadleftarrow:`M0 167c68 40 + 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69 +-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3 +-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19 +-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101 + 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,twoheadrightarrow:`M400000 167 +c-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3 + 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42 + 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333 +-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70 + 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,tilde1:`M200 55.538c-77 0-168 73.953-177 73.953-3 0-7 +-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0 + 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0 + 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128 +-68.267.847-113-73.952-191-73.952z`,tilde2:`M344 55.266c-142 0-300.638 81.316-311.5 86.418 +-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9 + 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114 +c1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751 + 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,tilde3:`M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457 +-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0 + 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697 + 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696 + -338 0-409-156.573-744-156.573z`,tilde4:`M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345 +-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409 + 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9 + 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409 + -175.236-744-175.236z`,vec:`M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5 +3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11 +10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63 +-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1 +-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59 +H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359 +c-16-25.333-24-45-24-59z`,widehat1:`M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22 +c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,widehat2:`M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat3:`M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat4:`M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10 +-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widecheck1:`M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1, +-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,widecheck2:`M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck3:`M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck4:`M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,baraboveleftarrow:`M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202 +c4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5 +c-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130 +s-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47 +121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6 +s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11 +c0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z +M100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,rightarrowabovebar:`M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32 +-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0 +13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39 +-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5 +-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 +-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 +151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,baraboveshortleftharpoon:`M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 +c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17 +c2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21 +c-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40 +c-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z +M0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,rightharpoonaboveshortbar:`M0,241 l0,40c399126,0,399993,0,399993,0 +c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, +-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 +c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z +M0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,shortbaraboveleftharpoon:`M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 +c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9, +1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7, +-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z +M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,shortrightharpoonabovebar:`M53,241l0,40c398570,0,399437,0,399437,0 +c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, +-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 +c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z +M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},Y4e=o(function(e,r){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v1759 h347 v-84 +H403z M403 1759 V0 H319 V1759 v`+r+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v1759 H0 v84 H347z +M347 1759 V0 H263 V1759 v`+r+" v1759 h84z";case"vert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+" v585 h43z";case"doublevert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+` v585 h43z +M367 15 v585 v`+r+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+r+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+r+` v1715 h263 v84 H319z +MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+r+` v1799 H0 v-84 H319z +MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v602 h84z +M403 1759 V0 H319 V1759 v`+r+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v602 h84z +M347 1759 V0 h-84 V1759 v`+r+" v602 h84z";case"lparen":return`M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1 +c-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349, +-36,557 l0,`+(r+84)+`c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210, +949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9 +c0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5, +-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189 +l0,-`+(r+92)+`c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3, +-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z`;case"rparen":return`M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3, +63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5 +c11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,`+(r+9)+` +c-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664 +c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11 +c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17 +c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558 +l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7, +-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}},"tallDelim"),od=class{static{o(this,"DocumentFragment")}constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return Jt.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),r=0;rr.toText(),"toText");return this.children.map(e).join("")}},Jl={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},c3={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},Kz={\u00C5:"A",\u00D0:"D",\u00DE:"o",\u00E5:"a",\u00F0:"d",\u00FE:"o",\u0410:"A",\u0411:"B",\u0412:"B",\u0413:"F",\u0414:"A",\u0415:"E",\u0416:"K",\u0417:"3",\u0418:"N",\u0419:"N",\u041A:"K",\u041B:"N",\u041C:"M",\u041D:"H",\u041E:"O",\u041F:"N",\u0420:"P",\u0421:"C",\u0422:"T",\u0423:"y",\u0424:"O",\u0425:"X",\u0426:"U",\u0427:"h",\u0428:"W",\u0429:"W",\u042A:"B",\u042B:"X",\u042C:"B",\u042D:"3",\u042E:"X",\u042F:"R",\u0430:"a",\u0431:"b",\u0432:"a",\u0433:"r",\u0434:"y",\u0435:"e",\u0436:"m",\u0437:"e",\u0438:"n",\u0439:"n",\u043A:"n",\u043B:"n",\u043C:"m",\u043D:"n",\u043E:"o",\u043F:"n",\u0440:"p",\u0441:"c",\u0442:"o",\u0443:"y",\u0444:"b",\u0445:"x",\u0446:"n",\u0447:"n",\u0448:"w",\u0449:"w",\u044A:"a",\u044B:"m",\u044C:"a",\u044D:"e",\u044E:"m",\u044F:"r"};o(_G,"setFontMetrics");o(nA,"getCharacterMetrics");R7={};o(X4e,"getGlobalMetrics");j4e=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],Qz=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],Zz=o(function(e,r){return r.size<2?e:j4e[e-1][r.size-1]},"sizeAtStyle"),w3=class t{static{o(this,"Options")}constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||t.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=Qz[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);return new t(r)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:Zz(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:Qz[e-1]})}havingBaseStyle(e){e=e||this.style.text();var r=Zz(t.BASESIZE,e);return this.size===r&&this.textSize===t.BASESIZE&&this.style===e?this:this.extend({style:e,size:r})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==t.BASESIZE?["sizing","reset-size"+this.size,"size"+t.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=X4e(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}};w3.BASESIZE=6;W7={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},K4e={ex:!0,em:!0,mu:!0},DG=o(function(e){return typeof e!="string"&&(e=e.unit),e in W7||e in K4e||e==="ex"},"validUnit"),ni=o(function(e,r){var n;if(e.unit in W7)n=W7[e.unit]/r.fontMetrics().ptPerEm/r.sizeMultiplier;else if(e.unit==="mu")n=r.fontMetrics().cssEmPerMu;else{var i;if(r.style.isTight()?i=r.havingStyle(r.style.text()):i=r,e.unit==="ex")n=i.fontMetrics().xHeight;else if(e.unit==="em")n=i.fontMetrics().quad;else throw new pt("Invalid unit: '"+e.unit+"'");i!==r&&(n*=i.sizeMultiplier/r.sizeMultiplier)}return Math.min(e.number*n,r.maxSize)},"calculateSize"),Et=o(function(e){return+e.toFixed(4)+"em"},"makeEm"),vh=o(function(e){return e.filter(r=>r).join(" ")},"createClass"),LG=o(function(e,r,n){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=n||{},r){r.style.isTight()&&this.classes.push("mtight");var i=r.getColor();i&&(this.style.color=i)}},"initNode"),RG=o(function(e){var r=document.createElement(e);r.className=vh(this.classes);for(var n in this.style)this.style.hasOwnProperty(n)&&(r.style[n]=this.style[n]);for(var i in this.attributes)this.attributes.hasOwnProperty(i)&&r.setAttribute(i,this.attributes[i]);for(var a=0;a/=\x00-\x1f]/,NG=o(function(e){var r="<"+e;this.classes.length&&(r+=' class="'+Jt.escape(vh(this.classes))+'"');var n="";for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(r+=' style="'+Jt.escape(n)+'"');for(var a in this.attributes)if(this.attributes.hasOwnProperty(a)){if(Q4e.test(a))throw new pt("Invalid attribute name '"+a+"'");r+=" "+a+'="'+Jt.escape(this.attributes[a])+'"'}r+=">";for(var s=0;s",r},"toMarkup"),ld=class{static{o(this,"Span")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,LG.call(this,e,n,i),this.children=r||[]}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return RG.call(this,"span")}toMarkup(){return NG.call(this,"span")}},Zy=class{static{o(this,"Anchor")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,LG.call(this,r,i),this.children=n||[],this.setAttribute("href",e)}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return RG.call(this,"a")}toMarkup(){return NG.call(this,"a")}},q7=class{static{o(this,"Img")}constructor(e,r,n){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=r,this.src=e,this.classes=["mord"],this.style=n}hasClass(e){return Jt.contains(this.classes,e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var r in this.style)this.style.hasOwnProperty(r)&&(e.style[r]=this.style[r]);return e}toMarkup(){var e=''+Jt.escape(this.alt)+'0&&(r=document.createElement("span"),r.style.marginRight=Et(this.italic)),this.classes.length>0&&(r=r||document.createElement("span"),r.className=vh(this.classes));for(var n in this.style)this.style.hasOwnProperty(n)&&(r=r||document.createElement("span"),r.style[n]=this.style[n]);return r?(r.appendChild(e),r):e}toMarkup(){var e=!1,r="0&&(n+="margin-right:"+this.italic+"em;");for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(e=!0,r+=' style="'+Jt.escape(n)+'"');var a=Jt.escape(this.text);return e?(r+=">",r+=a,r+="",r):a}},dl=class{static{o(this,"SvgNode")}constructor(e,r){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=r||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"svg");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);for(var i=0;i':''}},Jy=class{static{o(this,"LineNode")}constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"line");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);return r}toMarkup(){var e="","\\gt",!0);G(H,re,Ee,"\u2208","\\in",!0);G(H,re,Ee,"\uE020","\\@not");G(H,re,Ee,"\u2282","\\subset",!0);G(H,re,Ee,"\u2283","\\supset",!0);G(H,re,Ee,"\u2286","\\subseteq",!0);G(H,re,Ee,"\u2287","\\supseteq",!0);G(H,ke,Ee,"\u2288","\\nsubseteq",!0);G(H,ke,Ee,"\u2289","\\nsupseteq",!0);G(H,re,Ee,"\u22A8","\\models");G(H,re,Ee,"\u2190","\\leftarrow",!0);G(H,re,Ee,"\u2264","\\le");G(H,re,Ee,"\u2264","\\leq",!0);G(H,re,Ee,"<","\\lt",!0);G(H,re,Ee,"\u2192","\\rightarrow",!0);G(H,re,Ee,"\u2192","\\to");G(H,ke,Ee,"\u2271","\\ngeq",!0);G(H,ke,Ee,"\u2270","\\nleq",!0);G(H,re,pu,"\xA0","\\ ");G(H,re,pu,"\xA0","\\space");G(H,re,pu,"\xA0","\\nobreakspace");G(it,re,pu,"\xA0","\\ ");G(it,re,pu,"\xA0"," ");G(it,re,pu,"\xA0","\\space");G(it,re,pu,"\xA0","\\nobreakspace");G(H,re,pu,null,"\\nobreak");G(H,re,pu,null,"\\allowbreak");G(H,re,D3,",",",");G(H,re,D3,";",";");G(H,ke,It,"\u22BC","\\barwedge",!0);G(H,ke,It,"\u22BB","\\veebar",!0);G(H,re,It,"\u2299","\\odot",!0);G(H,re,It,"\u2295","\\oplus",!0);G(H,re,It,"\u2297","\\otimes",!0);G(H,re,Re,"\u2202","\\partial",!0);G(H,re,It,"\u2298","\\oslash",!0);G(H,ke,It,"\u229A","\\circledcirc",!0);G(H,ke,It,"\u22A1","\\boxdot",!0);G(H,re,It,"\u25B3","\\bigtriangleup");G(H,re,It,"\u25BD","\\bigtriangledown");G(H,re,It,"\u2020","\\dagger");G(H,re,It,"\u22C4","\\diamond");G(H,re,It,"\u22C6","\\star");G(H,re,It,"\u25C3","\\triangleleft");G(H,re,It,"\u25B9","\\triangleright");G(H,re,Zs,"{","\\{");G(it,re,Re,"{","\\{");G(it,re,Re,"{","\\textbraceleft");G(H,re,ns,"}","\\}");G(it,re,Re,"}","\\}");G(it,re,Re,"}","\\textbraceright");G(H,re,Zs,"{","\\lbrace");G(H,re,ns,"}","\\rbrace");G(H,re,Zs,"[","\\lbrack",!0);G(it,re,Re,"[","\\lbrack",!0);G(H,re,ns,"]","\\rbrack",!0);G(it,re,Re,"]","\\rbrack",!0);G(H,re,Zs,"(","\\lparen",!0);G(H,re,ns,")","\\rparen",!0);G(it,re,Re,"<","\\textless",!0);G(it,re,Re,">","\\textgreater",!0);G(H,re,Zs,"\u230A","\\lfloor",!0);G(H,re,ns,"\u230B","\\rfloor",!0);G(H,re,Zs,"\u2308","\\lceil",!0);G(H,re,ns,"\u2309","\\rceil",!0);G(H,re,Re,"\\","\\backslash");G(H,re,Re,"\u2223","|");G(H,re,Re,"\u2223","\\vert");G(it,re,Re,"|","\\textbar",!0);G(H,re,Re,"\u2225","\\|");G(H,re,Re,"\u2225","\\Vert");G(it,re,Re,"\u2225","\\textbardbl");G(it,re,Re,"~","\\textasciitilde");G(it,re,Re,"\\","\\textbackslash");G(it,re,Re,"^","\\textasciicircum");G(H,re,Ee,"\u2191","\\uparrow",!0);G(H,re,Ee,"\u21D1","\\Uparrow",!0);G(H,re,Ee,"\u2193","\\downarrow",!0);G(H,re,Ee,"\u21D3","\\Downarrow",!0);G(H,re,Ee,"\u2195","\\updownarrow",!0);G(H,re,Ee,"\u21D5","\\Updownarrow",!0);G(H,re,Ci,"\u2210","\\coprod");G(H,re,Ci,"\u22C1","\\bigvee");G(H,re,Ci,"\u22C0","\\bigwedge");G(H,re,Ci,"\u2A04","\\biguplus");G(H,re,Ci,"\u22C2","\\bigcap");G(H,re,Ci,"\u22C3","\\bigcup");G(H,re,Ci,"\u222B","\\int");G(H,re,Ci,"\u222B","\\intop");G(H,re,Ci,"\u222C","\\iint");G(H,re,Ci,"\u222D","\\iiint");G(H,re,Ci,"\u220F","\\prod");G(H,re,Ci,"\u2211","\\sum");G(H,re,Ci,"\u2A02","\\bigotimes");G(H,re,Ci,"\u2A01","\\bigoplus");G(H,re,Ci,"\u2A00","\\bigodot");G(H,re,Ci,"\u222E","\\oint");G(H,re,Ci,"\u222F","\\oiint");G(H,re,Ci,"\u2230","\\oiiint");G(H,re,Ci,"\u2A06","\\bigsqcup");G(H,re,Ci,"\u222B","\\smallint");G(it,re,E0,"\u2026","\\textellipsis");G(H,re,E0,"\u2026","\\mathellipsis");G(it,re,E0,"\u2026","\\ldots",!0);G(H,re,E0,"\u2026","\\ldots",!0);G(H,re,E0,"\u22EF","\\@cdots",!0);G(H,re,E0,"\u22F1","\\ddots",!0);G(H,re,Re,"\u22EE","\\varvdots");G(it,re,Re,"\u22EE","\\varvdots");G(H,re,Hn,"\u02CA","\\acute");G(H,re,Hn,"\u02CB","\\grave");G(H,re,Hn,"\xA8","\\ddot");G(H,re,Hn,"~","\\tilde");G(H,re,Hn,"\u02C9","\\bar");G(H,re,Hn,"\u02D8","\\breve");G(H,re,Hn,"\u02C7","\\check");G(H,re,Hn,"^","\\hat");G(H,re,Hn,"\u20D7","\\vec");G(H,re,Hn,"\u02D9","\\dot");G(H,re,Hn,"\u02DA","\\mathring");G(H,re,rr,"\uE131","\\@imath");G(H,re,rr,"\uE237","\\@jmath");G(H,re,Re,"\u0131","\u0131");G(H,re,Re,"\u0237","\u0237");G(it,re,Re,"\u0131","\\i",!0);G(it,re,Re,"\u0237","\\j",!0);G(it,re,Re,"\xDF","\\ss",!0);G(it,re,Re,"\xE6","\\ae",!0);G(it,re,Re,"\u0153","\\oe",!0);G(it,re,Re,"\xF8","\\o",!0);G(it,re,Re,"\xC6","\\AE",!0);G(it,re,Re,"\u0152","\\OE",!0);G(it,re,Re,"\xD8","\\O",!0);G(it,re,Hn,"\u02CA","\\'");G(it,re,Hn,"\u02CB","\\`");G(it,re,Hn,"\u02C6","\\^");G(it,re,Hn,"\u02DC","\\~");G(it,re,Hn,"\u02C9","\\=");G(it,re,Hn,"\u02D8","\\u");G(it,re,Hn,"\u02D9","\\.");G(it,re,Hn,"\xB8","\\c");G(it,re,Hn,"\u02DA","\\r");G(it,re,Hn,"\u02C7","\\v");G(it,re,Hn,"\xA8",'\\"');G(it,re,Hn,"\u02DD","\\H");G(it,re,Hn,"\u25EF","\\textcircled");MG={"--":!0,"---":!0,"``":!0,"''":!0};G(it,re,Re,"\u2013","--",!0);G(it,re,Re,"\u2013","\\textendash");G(it,re,Re,"\u2014","---",!0);G(it,re,Re,"\u2014","\\textemdash");G(it,re,Re,"\u2018","`",!0);G(it,re,Re,"\u2018","\\textquoteleft");G(it,re,Re,"\u2019","'",!0);G(it,re,Re,"\u2019","\\textquoteright");G(it,re,Re,"\u201C","``",!0);G(it,re,Re,"\u201C","\\textquotedblleft");G(it,re,Re,"\u201D","''",!0);G(it,re,Re,"\u201D","\\textquotedblright");G(H,re,Re,"\xB0","\\degree",!0);G(it,re,Re,"\xB0","\\degree");G(it,re,Re,"\xB0","\\textdegree",!0);G(H,re,Re,"\xA3","\\pounds");G(H,re,Re,"\xA3","\\mathsterling",!0);G(it,re,Re,"\xA3","\\pounds");G(it,re,Re,"\xA3","\\textsterling",!0);G(H,ke,Re,"\u2720","\\maltese");G(it,ke,Re,"\u2720","\\maltese");eG='0123456789/@."';for(u3=0;u30)return fl(a,h,i,r,s.concat(f));if(u){var d,p;if(u==="boldsymbol"){var m=i3e(a,i,r,s,n);d=m.fontName,p=[m.fontClass]}else l?(d=PG[u].fontName,p=[u]):(d=m3(u,r.fontWeight,r.fontShape),p=[u,r.fontWeight,r.fontShape]);if(L3(a,d,i).metrics)return fl(a,d,i,r,s.concat(p));if(MG.hasOwnProperty(a)&&d.slice(0,10)==="Typewriter"){for(var g=[],y=0;y{if(vh(t.classes)!==vh(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;if(t.classes.length===1){var r=t.classes[0];if(r==="mbin"||r==="mord")return!1}for(var n in t.style)if(t.style.hasOwnProperty(n)&&t.style[n]!==e.style[n])return!1;for(var i in e.style)if(e.style.hasOwnProperty(i)&&t.style[i]!==e.style[i])return!1;return!0},"canCombine"),o3e=o(t=>{for(var e=0;er&&(r=s.height),s.depth>n&&(n=s.depth),s.maxFontSize>i&&(i=s.maxFontSize)}e.height=r,e.depth=n,e.maxFontSize=i},"sizeElementFromChildren"),Cs=o(function(e,r,n,i){var a=new ld(e,r,n,i);return iA(a),a},"makeSpan"),IG=o((t,e,r,n)=>new ld(t,e,r,n),"makeSvgSpan"),l3e=o(function(e,r,n){var i=Cs([e],[],r);return i.height=Math.max(n||r.fontMetrics().defaultRuleThickness,r.minRuleThickness),i.style.borderBottomWidth=Et(i.height),i.maxFontSize=1,i},"makeLineSpan"),c3e=o(function(e,r,n,i){var a=new Zy(e,r,n,i);return iA(a),a},"makeAnchor"),OG=o(function(e){var r=new od(e);return iA(r),r},"makeFragment"),u3e=o(function(e,r){return e instanceof od?Cs([],[e],r):e},"wrapFragment"),h3e=o(function(e){if(e.positionType==="individualShift"){for(var r=e.children,n=[r[0]],i=-r[0].shift-r[0].elem.depth,a=i,s=1;s{var r=Cs(["mspace"],[],e),n=ni(t,e);return r.style.marginRight=Et(n),r},"makeGlue"),m3=o(function(e,r,n){var i="";switch(e){case"amsrm":i="AMS";break;case"textrm":i="Main";break;case"textsf":i="SansSerif";break;case"texttt":i="Typewriter";break;default:i=e}var a;return r==="textbf"&&n==="textit"?a="BoldItalic":r==="textbf"?a="Bold":r==="textit"?a="Italic":a="Regular",i+"-"+a},"retrieveTextFontName"),PG={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},BG={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},p3e=o(function(e,r){var[n,i,a]=BG[e],s=new ec(n),l=new dl([s],{width:Et(i),height:Et(a),style:"width:"+Et(i),viewBox:"0 0 "+1e3*i+" "+1e3*a,preserveAspectRatio:"xMinYMin"}),u=IG(["overlay"],[l],r);return u.height=a,u.style.height=Et(a),u.style.width=Et(i),u},"staticSvg"),Fe={fontMap:PG,makeSymbol:fl,mathsym:n3e,makeSpan:Cs,makeSvgSpan:IG,makeLineSpan:l3e,makeAnchor:c3e,makeFragment:OG,wrapFragment:u3e,makeVList:f3e,makeOrd:a3e,makeGlue:d3e,staticSvg:p3e,svgData:BG,tryCombineChars:o3e},ri={number:3,unit:"mu"},sd={number:4,unit:"mu"},cu={number:5,unit:"mu"},m3e={mord:{mop:ri,mbin:sd,mrel:cu,minner:ri},mop:{mord:ri,mop:ri,mrel:cu,minner:ri},mbin:{mord:sd,mop:sd,mopen:sd,minner:sd},mrel:{mord:cu,mop:cu,mopen:cu,minner:cu},mopen:{},mclose:{mop:ri,mbin:sd,mrel:cu,minner:ri},mpunct:{mord:ri,mop:ri,mrel:cu,mopen:ri,mclose:ri,mpunct:ri,minner:ri},minner:{mord:ri,mop:ri,mbin:sd,mrel:cu,mopen:ri,mpunct:ri,minner:ri}},g3e={mord:{mop:ri},mop:{mord:ri,mop:ri},mbin:{},mrel:{},mopen:{},mclose:{mop:ri},mpunct:{},minner:{mop:ri}},FG={},E3={},S3={};o(Nt,"defineFunction");o(cd,"defineFunctionBuilders");C3=o(function(e){return e.type==="ordgroup"&&e.body.length===1?e.body[0]:e},"normalizeArgument"),gi=o(function(e){return e.type==="ordgroup"?e.body:[e]},"ordargument"),fu=Fe.makeSpan,y3e=["leftmost","mbin","mopen","mrel","mop","mpunct"],v3e=["rightmost","mrel","mclose","mpunct"],x3e={display:nr.DISPLAY,text:nr.TEXT,script:nr.SCRIPT,scriptscript:nr.SCRIPTSCRIPT},b3e={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},$i=o(function(e,r,n,i){i===void 0&&(i=[null,null]);for(var a=[],s=0;s{var v=y.classes[0],x=g.classes[0];v==="mbin"&&Jt.contains(v3e,x)?y.classes[0]="mord":x==="mbin"&&Jt.contains(y3e,v)&&(g.classes[0]="mord")},{node:d},p,m),nG(a,(g,y)=>{var v=X7(y),x=X7(g),b=v&&x?g.hasClass("mtight")?g3e[v][x]:m3e[v][x]:null;if(b)return Fe.makeGlue(b,h)},{node:d},p,m),a},"buildExpression"),nG=o(function t(e,r,n,i,a){i&&e.push(i);for(var s=0;sp=>{e.splice(d+1,0,p),s++})(s)}i&&e.pop()},"traverseNonSpaceNodes"),$G=o(function(e){return e instanceof od||e instanceof Zy||e instanceof ld&&e.hasClass("enclosing")?e:null},"checkPartialGroup"),T3e=o(function t(e,r){var n=$G(e);if(n){var i=n.children;if(i.length){if(r==="right")return t(i[i.length-1],"right");if(r==="left")return t(i[0],"left")}}return e},"getOutermostNode"),X7=o(function(e,r){return e?(r&&(e=T3e(e,r)),b3e[e.classes[0]]||null):null},"getTypeOfDomTree"),ev=o(function(e,r){var n=["nulldelimiter"].concat(e.baseSizingClasses());return fu(r.concat(n))},"makeNullDelimiter"),$r=o(function(e,r,n){if(!e)return fu();if(E3[e.type]){var i=E3[e.type](e,r);if(n&&r.size!==n.size){i=fu(r.sizingClasses(n),[i],r);var a=r.sizeMultiplier/n.sizeMultiplier;i.height*=a,i.depth*=a}return i}else throw new pt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(g3,"buildHTMLUnbreakable");o(j7,"buildHTML");o(zG,"newDocumentFragment");ts=class{static{o(this,"MathNode")}constructor(e,r,n){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=r||[],this.classes=n||[]}setAttribute(e,r){this.attributes[e]=r}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&e.setAttribute(r,this.attributes[r]);this.classes.length>0&&(e.className=vh(this.classes));for(var n=0;n0&&(e+=' class ="'+Jt.escape(vh(this.classes))+'"'),e+=">";for(var n=0;n",e}toText(){return this.children.map(e=>e.toText()).join("")}},Ao=class{static{o(this,"TextNode")}constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return Jt.escape(this.toText())}toText(){return this.text}},K7=class{static{o(this,"SpaceNode")}constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character="\u200A":e>=.1666&&e<=.1667?this.character="\u2009":e>=.2222&&e<=.2223?this.character="\u2005":e>=.2777&&e<=.2778?this.character="\u2005\u200A":e>=-.05556&&e<=-.05555?this.character="\u200A\u2063":e>=-.1667&&e<=-.1666?this.character="\u2009\u2063":e>=-.2223&&e<=-.2222?this.character="\u205F\u2063":e>=-.2778&&e<=-.2777?this.character="\u2005\u2063":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",Et(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},dt={MathNode:ts,TextNode:Ao,SpaceNode:K7,newDocumentFragment:zG},Do=o(function(e,r,n){return An[r][e]&&An[r][e].replace&&e.charCodeAt(0)!==55349&&!(MG.hasOwnProperty(e)&&n&&(n.fontFamily&&n.fontFamily.slice(4,6)==="tt"||n.font&&n.font.slice(4,6)==="tt"))&&(e=An[r][e].replace),new dt.TextNode(e)},"makeText"),aA=o(function(e){return e.length===1?e[0]:new dt.MathNode("mrow",e)},"makeRow"),sA=o(function(e,r){if(r.fontFamily==="texttt")return"monospace";if(r.fontFamily==="textsf")return r.fontShape==="textit"&&r.fontWeight==="textbf"?"sans-serif-bold-italic":r.fontShape==="textit"?"sans-serif-italic":r.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(r.fontShape==="textit"&&r.fontWeight==="textbf")return"bold-italic";if(r.fontShape==="textit")return"italic";if(r.fontWeight==="textbf")return"bold";var n=r.font;if(!n||n==="mathnormal")return null;var i=e.mode;if(n==="mathit")return"italic";if(n==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(n==="mathbf")return"bold";if(n==="mathbb")return"double-struck";if(n==="mathsfit")return"sans-serif-italic";if(n==="mathfrak")return"fraktur";if(n==="mathscr"||n==="mathcal")return"script";if(n==="mathsf")return"sans-serif";if(n==="mathtt")return"monospace";var a=e.text;if(Jt.contains(["\\imath","\\jmath"],a))return null;An[i][a]&&An[i][a].replace&&(a=An[i][a].replace);var s=Fe.fontMap[n].fontName;return nA(a,s,i)?Fe.fontMap[n].variant:null},"getVariant");o(I7,"isNumberPunctuation");_s=o(function(e,r,n){if(e.length===1){var i=vn(e[0],r);return n&&i instanceof ts&&i.type==="mo"&&(i.setAttribute("lspace","0em"),i.setAttribute("rspace","0em")),[i]}for(var a=[],s,l=0;l=1&&(s.type==="mn"||I7(s))){var h=u.children[0];h instanceof ts&&h.type==="mn"&&(h.children=[...s.children,...h.children],a.pop())}else if(s.type==="mi"&&s.children.length===1){var f=s.children[0];if(f instanceof Ao&&f.text==="\u0338"&&(u.type==="mo"||u.type==="mi"||u.type==="mn")){var d=u.children[0];d instanceof Ao&&d.text.length>0&&(d.text=d.text.slice(0,1)+"\u0338"+d.text.slice(1),a.pop())}}}a.push(u),s=u}return a},"buildExpression"),xh=o(function(e,r,n){return aA(_s(e,r,n))},"buildExpressionRow"),vn=o(function(e,r){if(!e)return new dt.MathNode("mrow");if(S3[e.type]){var n=S3[e.type](e,r);return n}else throw new pt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(iG,"buildMathML");GG=o(function(e){return new w3({style:e.displayMode?nr.DISPLAY:nr.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},"optionsFromSettings"),VG=o(function(e,r){if(r.displayMode){var n=["katex-display"];r.leqno&&n.push("leqno"),r.fleqn&&n.push("fleqn"),e=Fe.makeSpan(n,[e])}return e},"displayWrap"),w3e=o(function(e,r,n){var i=GG(n),a;if(n.output==="mathml")return iG(e,r,i,n.displayMode,!0);if(n.output==="html"){var s=j7(e,i);a=Fe.makeSpan(["katex"],[s])}else{var l=iG(e,r,i,n.displayMode,!1),u=j7(e,i);a=Fe.makeSpan(["katex"],[l,u])}return VG(a,n)},"buildTree"),k3e=o(function(e,r,n){var i=GG(n),a=j7(e,i),s=Fe.makeSpan(["katex"],[a]);return VG(s,n)},"buildHTMLTree"),E3e={widehat:"^",widecheck:"\u02C7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23DF",overbrace:"\u23DE",overgroup:"\u23E0",undergroup:"\u23E1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21D2",xRightarrow:"\u21D2",overleftharpoon:"\u21BC",xleftharpoonup:"\u21BC",overrightharpoon:"\u21C0",xrightharpoonup:"\u21C0",xLeftarrow:"\u21D0",xLeftrightarrow:"\u21D4",xhookleftarrow:"\u21A9",xhookrightarrow:"\u21AA",xmapsto:"\u21A6",xrightharpoondown:"\u21C1",xleftharpoondown:"\u21BD",xrightleftharpoons:"\u21CC",xleftrightharpoons:"\u21CB",xtwoheadleftarrow:"\u219E",xtwoheadrightarrow:"\u21A0",xlongequal:"=",xtofrom:"\u21C4",xrightleftarrows:"\u21C4",xrightequilibrium:"\u21CC",xleftequilibrium:"\u21CB","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},S3e=o(function(e){var r=new dt.MathNode("mo",[new dt.TextNode(E3e[e.replace(/^\\/,"")])]);return r.setAttribute("stretchy","true"),r},"mathMLnode"),C3e={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},A3e=o(function(e){return e.type==="ordgroup"?e.body.length:1},"groupLength"),_3e=o(function(e,r){function n(){var l=4e5,u=e.label.slice(1);if(Jt.contains(["widehat","widecheck","widetilde","utilde"],u)){var h=e,f=A3e(h.base),d,p,m;if(f>5)u==="widehat"||u==="widecheck"?(d=420,l=2364,m=.42,p=u+"4"):(d=312,l=2340,m=.34,p="tilde4");else{var g=[1,1,2,2,3,3][f];u==="widehat"||u==="widecheck"?(l=[0,1062,2364,2364,2364][g],d=[0,239,300,360,420][g],m=[0,.24,.3,.3,.36,.42][g],p=u+g):(l=[0,600,1033,2339,2340][g],d=[0,260,286,306,312][g],m=[0,.26,.286,.3,.306,.34][g],p="tilde"+g)}var y=new ec(p),v=new dl([y],{width:"100%",height:Et(m),viewBox:"0 0 "+l+" "+d,preserveAspectRatio:"none"});return{span:Fe.makeSvgSpan([],[v],r),minWidth:0,height:m}}else{var x=[],b=C3e[u],[T,S,w]=b,E=w/1e3,_=T.length,C,D;if(_===1){var O=b[3];C=["hide-tail"],D=[O]}else if(_===2)C=["halfarrow-left","halfarrow-right"],D=["xMinYMin","xMaxYMin"];else if(_===3)C=["brace-left","brace-center","brace-right"],D=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support + `+_+" children.");for(var R=0;R<_;R++){var k=new ec(T[R]),L=new dl([k],{width:"400em",height:Et(E),viewBox:"0 0 "+l+" "+w,preserveAspectRatio:D[R]+" slice"}),A=Fe.makeSvgSpan([C[R]],[L],r);if(_===1)return{span:A,minWidth:S,height:E};A.style.height=Et(E),x.push(A)}return{span:Fe.makeSpan(["stretchy"],x,r),minWidth:S,height:E}}}o(n,"buildSvgSpan_");var{span:i,minWidth:a,height:s}=n();return i.height=s,i.style.height=Et(s),a>0&&(i.style.minWidth=Et(a)),i},"svgSpan"),D3e=o(function(e,r,n,i,a){var s,l=e.height+e.depth+n+i;if(/fbox|color|angl/.test(r)){if(s=Fe.makeSpan(["stretchy",r],[],a),r==="fbox"){var u=a.color&&a.getColor();u&&(s.style.borderColor=u)}}else{var h=[];/^[bx]cancel$/.test(r)&&h.push(new Jy({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(r)&&h.push(new Jy({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var f=new dl(h,{width:"100%",height:Et(l)});s=Fe.makeSvgSpan([],[f],a)}return s.height=l,s.style.height=Et(l),s},"encloseSpan"),du={encloseSpan:D3e,mathMLnode:S3e,svgSpan:_3e};o(xr,"assertNodeType");o(oA,"assertSymbolNodeType");o(R3,"checkSymbolNodeType");lA=o((t,e)=>{var r,n,i;t&&t.type==="supsub"?(n=xr(t.base,"accent"),r=n.base,t.base=r,i=J4e($r(t,e)),t.base=n):(n=xr(t,"accent"),r=n.base);var a=$r(r,e.havingCrampedStyle()),s=n.isShifty&&Jt.isCharacterBox(r),l=0;if(s){var u=Jt.getBaseElem(r),h=$r(u,e.havingCrampedStyle());l=Jz(h).skew}var f=n.label==="\\c",d=f?a.height+a.depth:Math.min(a.height,e.fontMetrics().xHeight),p;if(n.isStretchy)p=du.svgSpan(n,e),p=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"elem",elem:p,wrapperClasses:["svg-align"],wrapperStyle:l>0?{width:"calc(100% - "+Et(2*l)+")",marginLeft:Et(2*l)}:void 0}]},e);else{var m,g;n.label==="\\vec"?(m=Fe.staticSvg("vec",e),g=Fe.svgData.vec[1]):(m=Fe.makeOrd({mode:n.mode,text:n.label},e,"textord"),m=Jz(m),m.italic=0,g=m.width,f&&(d+=m.depth)),p=Fe.makeSpan(["accent-body"],[m]);var y=n.label==="\\textcircled";y&&(p.classes.push("accent-full"),d=a.height);var v=l;y||(v-=g/2),p.style.left=Et(v),n.label==="\\textcircled"&&(p.style.top=".2em"),p=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:-d},{type:"elem",elem:p}]},e)}var x=Fe.makeSpan(["mord","accent"],[p],e);return i?(i.children[0]=x,i.height=Math.max(x.height,i.height),i.classes[0]="mord",i):x},"htmlBuilder$a"),UG=o((t,e)=>{var r=t.isStretchy?du.mathMLnode(t.label):new dt.MathNode("mo",[Do(t.label,t.mode)]),n=new dt.MathNode("mover",[vn(t.base,e),r]);return n.setAttribute("accent","true"),n},"mathmlBuilder$9"),L3e=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(t=>"\\"+t).join("|"));Nt({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:o((t,e)=>{var r=C3(e[0]),n=!L3e.test(t.funcName),i=!n||t.funcName==="\\widehat"||t.funcName==="\\widetilde"||t.funcName==="\\widecheck";return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:n,isShifty:i,base:r}},"handler"),htmlBuilder:lA,mathmlBuilder:UG});Nt({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:o((t,e)=>{var r=e[0],n=t.parser.mode;return n==="math"&&(t.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+t.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:t.funcName,isStretchy:!1,isShifty:!0,base:r}},"handler"),htmlBuilder:lA,mathmlBuilder:UG});Nt({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"accentUnder",mode:r.mode,label:n,base:i}},"handler"),htmlBuilder:o((t,e)=>{var r=$r(t.base,e),n=du.svgSpan(t,e),i=t.label==="\\utilde"?.12:0,a=Fe.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:i},{type:"elem",elem:r}]},e);return Fe.makeSpan(["mord","accentunder"],[a],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=du.mathMLnode(t.label),n=new dt.MathNode("munder",[vn(t.base,e),r]);return n.setAttribute("accentunder","true"),n},"mathmlBuilder")});y3=o(t=>{var e=new dt.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e},"paddedNode");Nt({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n,funcName:i}=t;return{type:"xArrow",mode:n.mode,label:i,body:e[0],below:r[0]}},htmlBuilder(t,e){var r=e.style,n=e.havingStyle(r.sup()),i=Fe.wrapFragment($r(t.body,n,e),e),a=t.label.slice(0,2)==="\\x"?"x":"cd";i.classes.push(a+"-arrow-pad");var s;t.below&&(n=e.havingStyle(r.sub()),s=Fe.wrapFragment($r(t.below,n,e),e),s.classes.push(a+"-arrow-pad"));var l=du.svgSpan(t,e),u=-e.fontMetrics().axisHeight+.5*l.height,h=-e.fontMetrics().axisHeight-.5*l.height-.111;(i.depth>.25||t.label==="\\xleftequilibrium")&&(h-=i.depth);var f;if(s){var d=-e.fontMetrics().axisHeight+s.height+.5*l.height+.111;f=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u},{type:"elem",elem:s,shift:d}]},e)}else f=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u}]},e);return f.children[0].children[0].children[1].classes.push("svg-align"),Fe.makeSpan(["mrel","x-arrow"],[f],e)},mathmlBuilder(t,e){var r=du.mathMLnode(t.label);r.setAttribute("minsize",t.label.charAt(0)==="x"?"1.75em":"3.0em");var n;if(t.body){var i=y3(vn(t.body,e));if(t.below){var a=y3(vn(t.below,e));n=new dt.MathNode("munderover",[r,a,i])}else n=new dt.MathNode("mover",[r,i])}else if(t.below){var s=y3(vn(t.below,e));n=new dt.MathNode("munder",[r,s])}else n=y3(),n=new dt.MathNode("mover",[r,n]);return n}});R3e=Fe.makeSpan;o(HG,"htmlBuilder$9");o(WG,"mathmlBuilder$8");Nt({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:gi(i),isCharacterBox:Jt.isCharacterBox(i)}},htmlBuilder:HG,mathmlBuilder:WG});N3=o(t=>{var e=t.type==="ordgroup"&&t.body.length?t.body[0]:t;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"},"binrelClass");Nt({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(t,e){var{parser:r}=t;return{type:"mclass",mode:r.mode,mclass:N3(e[0]),body:gi(e[1]),isCharacterBox:Jt.isCharacterBox(e[1])}}});Nt({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(t,e){var{parser:r,funcName:n}=t,i=e[1],a=e[0],s;n!=="\\stackrel"?s=N3(i):s="mrel";var l={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:n!=="\\stackrel",body:gi(i)},u={type:"supsub",mode:a.mode,base:l,sup:n==="\\underset"?null:a,sub:n==="\\underset"?a:null};return{type:"mclass",mode:r.mode,mclass:s,body:[u],isCharacterBox:Jt.isCharacterBox(u)}},htmlBuilder:HG,mathmlBuilder:WG});Nt({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"pmb",mode:r.mode,mclass:N3(e[0]),body:gi(e[0])}},htmlBuilder(t,e){var r=$i(t.body,e,!0),n=Fe.makeSpan([t.mclass],r,e);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(t,e){var r=_s(t.body,e),n=new dt.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});N3e={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},aG=o(()=>({type:"styling",body:[],mode:"math",style:"display"}),"newCell"),sG=o(t=>t.type==="textord"&&t.text==="@","isStartOfArrow"),M3e=o((t,e)=>(t.type==="mathord"||t.type==="atom")&&t.text===e,"isLabelEnd");o(I3e,"cdArrow");o(O3e,"parseCD");Nt({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:e[0]}},htmlBuilder(t,e){var r=e.havingStyle(e.style.sup()),n=Fe.wrapFragment($r(t.label,r,e),e);return n.classes.push("cd-label-"+t.side),n.style.bottom=Et(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(t,e){var r=new dt.MathNode("mrow",[vn(t.label,e)]);return r=new dt.MathNode("mpadded",[r]),r.setAttribute("width","0"),t.side==="left"&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new dt.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}});Nt({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(t,e){var{parser:r}=t;return{type:"cdlabelparent",mode:r.mode,fragment:e[0]}},htmlBuilder(t,e){var r=Fe.wrapFragment($r(t.fragment,e),e);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(t,e){return new dt.MathNode("mrow",[vn(t.fragment,e)])}});Nt({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(t,e){for(var{parser:r}=t,n=xr(e[0],"ordgroup"),i=n.body,a="",s=0;s=1114111)throw new pt("\\@char with invalid code point "+a);return u<=65535?h=String.fromCharCode(u):(u-=65536,h=String.fromCharCode((u>>10)+55296,(u&1023)+56320)),{type:"textord",mode:r.mode,text:h}}});qG=o((t,e)=>{var r=$i(t.body,e.withColor(t.color),!1);return Fe.makeFragment(r)},"htmlBuilder$8"),YG=o((t,e)=>{var r=_s(t.body,e.withColor(t.color)),n=new dt.MathNode("mstyle",r);return n.setAttribute("mathcolor",t.color),n},"mathmlBuilder$7");Nt({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(t,e){var{parser:r}=t,n=xr(e[0],"color-token").color,i=e[1];return{type:"color",mode:r.mode,color:n,body:gi(i)}},htmlBuilder:qG,mathmlBuilder:YG});Nt({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(t,e){var{parser:r,breakOnTokenText:n}=t,i=xr(e[0],"color-token").color;r.gullet.macros.set("\\current@color",i);var a=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:i,body:a}},htmlBuilder:qG,mathmlBuilder:YG});Nt({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(t,e,r){var{parser:n}=t,i=n.gullet.future().text==="["?n.parseSizeGroup(!0):null,a=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:a,size:i&&xr(i,"size").value}},htmlBuilder(t,e){var r=Fe.makeSpan(["mspace"],[],e);return t.newLine&&(r.classes.push("newline"),t.size&&(r.style.marginTop=Et(ni(t.size,e)))),r},mathmlBuilder(t,e){var r=new dt.MathNode("mspace");return t.newLine&&(r.setAttribute("linebreak","newline"),t.size&&r.setAttribute("height",Et(ni(t.size,e)))),r}});Q7={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},XG=o(t=>{var e=t.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new pt("Expected a control sequence",t);return e},"checkControlSequence"),P3e=o(t=>{var e=t.gullet.popToken();return e.text==="="&&(e=t.gullet.popToken(),e.text===" "&&(e=t.gullet.popToken())),e},"getRHS"),jG=o((t,e,r,n)=>{var i=t.gullet.macros.get(r.text);i==null&&(r.noexpand=!0,i={tokens:[r],numArgs:0,unexpandable:!t.gullet.isExpandable(r.text)}),t.gullet.macros.set(e,i,n)},"letCommand");Nt({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(t){var{parser:e,funcName:r}=t;e.consumeSpaces();var n=e.fetch();if(Q7[n.text])return(r==="\\global"||r==="\\\\globallong")&&(n.text=Q7[n.text]),xr(e.parseFunction(),"internal");throw new pt("Invalid token after macro prefix",n)}});Nt({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=e.gullet.popToken(),i=n.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new pt("Expected a control sequence",n);for(var a=0,s,l=[[]];e.gullet.future().text!=="{";)if(n=e.gullet.popToken(),n.text==="#"){if(e.gullet.future().text==="{"){s=e.gullet.future(),l[a].push("{");break}if(n=e.gullet.popToken(),!/^[1-9]$/.test(n.text))throw new pt('Invalid argument number "'+n.text+'"');if(parseInt(n.text)!==a+1)throw new pt('Argument number "'+n.text+'" out of order');a++,l.push([])}else{if(n.text==="EOF")throw new pt("Expected a macro definition");l[a].push(n.text)}var{tokens:u}=e.gullet.consumeArg();return s&&u.unshift(s),(r==="\\edef"||r==="\\xdef")&&(u=e.gullet.expandTokens(u),u.reverse()),e.gullet.macros.set(i,{tokens:u,numArgs:a,delimiters:l},r===Q7[r]),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=XG(e.gullet.popToken());e.gullet.consumeSpaces();var i=P3e(e);return jG(e,n,i,r==="\\\\globallet"),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=XG(e.gullet.popToken()),i=e.gullet.popToken(),a=e.gullet.popToken();return jG(e,n,a,r==="\\\\globalfuture"),e.gullet.pushToken(a),e.gullet.pushToken(i),{type:"internal",mode:e.mode}}});Yy=o(function(e,r,n){var i=An.math[e]&&An.math[e].replace,a=nA(i||e,r,n);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+r+".");return a},"getMetrics"),cA=o(function(e,r,n,i){var a=n.havingBaseStyle(r),s=Fe.makeSpan(i.concat(a.sizingClasses(n)),[e],n),l=a.sizeMultiplier/n.sizeMultiplier;return s.height*=l,s.depth*=l,s.maxFontSize=a.sizeMultiplier,s},"styleWrap"),KG=o(function(e,r,n){var i=r.havingBaseStyle(n),a=(1-r.sizeMultiplier/i.sizeMultiplier)*r.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=Et(a),e.height-=a,e.depth+=a},"centerSpan"),B3e=o(function(e,r,n,i,a,s){var l=Fe.makeSymbol(e,"Main-Regular",a,i),u=cA(l,r,i,s);return n&&KG(u,i,r),u},"makeSmallDelim"),F3e=o(function(e,r,n,i){return Fe.makeSymbol(e,"Size"+r+"-Regular",n,i)},"mathrmSize"),QG=o(function(e,r,n,i,a,s){var l=F3e(e,r,a,i),u=cA(Fe.makeSpan(["delimsizing","size"+r],[l],i),nr.TEXT,i,s);return n&&KG(u,i,nr.TEXT),u},"makeLargeDelim"),O7=o(function(e,r,n){var i;r==="Size1-Regular"?i="delim-size1":i="delim-size4";var a=Fe.makeSpan(["delimsizinginner",i],[Fe.makeSpan([],[Fe.makeSymbol(e,r,n)])]);return{type:"elem",elem:a}},"makeGlyphSpan"),P7=o(function(e,r,n){var i=Jl["Size4-Regular"][e.charCodeAt(0)]?Jl["Size4-Regular"][e.charCodeAt(0)][4]:Jl["Size1-Regular"][e.charCodeAt(0)][4],a=new ec("inner",q4e(e,Math.round(1e3*r))),s=new dl([a],{width:Et(i),height:Et(r),style:"width:"+Et(i),viewBox:"0 0 "+1e3*i+" "+Math.round(1e3*r),preserveAspectRatio:"xMinYMin"}),l=Fe.makeSvgSpan([],[s],n);return l.height=r,l.style.height=Et(r),l.style.width=Et(i),{type:"elem",elem:l}},"makeInner"),Z7=.008,v3={type:"kern",size:-1*Z7},$3e=["|","\\lvert","\\rvert","\\vert"],z3e=["\\|","\\lVert","\\rVert","\\Vert"],ZG=o(function(e,r,n,i,a,s){var l,u,h,f,d="",p=0;l=h=f=e,u=null;var m="Size1-Regular";e==="\\uparrow"?h=f="\u23D0":e==="\\Uparrow"?h=f="\u2016":e==="\\downarrow"?l=h="\u23D0":e==="\\Downarrow"?l=h="\u2016":e==="\\updownarrow"?(l="\\uparrow",h="\u23D0",f="\\downarrow"):e==="\\Updownarrow"?(l="\\Uparrow",h="\u2016",f="\\Downarrow"):Jt.contains($3e,e)?(h="\u2223",d="vert",p=333):Jt.contains(z3e,e)?(h="\u2225",d="doublevert",p=556):e==="["||e==="\\lbrack"?(l="\u23A1",h="\u23A2",f="\u23A3",m="Size4-Regular",d="lbrack",p=667):e==="]"||e==="\\rbrack"?(l="\u23A4",h="\u23A5",f="\u23A6",m="Size4-Regular",d="rbrack",p=667):e==="\\lfloor"||e==="\u230A"?(h=l="\u23A2",f="\u23A3",m="Size4-Regular",d="lfloor",p=667):e==="\\lceil"||e==="\u2308"?(l="\u23A1",h=f="\u23A2",m="Size4-Regular",d="lceil",p=667):e==="\\rfloor"||e==="\u230B"?(h=l="\u23A5",f="\u23A6",m="Size4-Regular",d="rfloor",p=667):e==="\\rceil"||e==="\u2309"?(l="\u23A4",h=f="\u23A5",m="Size4-Regular",d="rceil",p=667):e==="("||e==="\\lparen"?(l="\u239B",h="\u239C",f="\u239D",m="Size4-Regular",d="lparen",p=875):e===")"||e==="\\rparen"?(l="\u239E",h="\u239F",f="\u23A0",m="Size4-Regular",d="rparen",p=875):e==="\\{"||e==="\\lbrace"?(l="\u23A7",u="\u23A8",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(l="\u23AB",u="\u23AC",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lgroup"||e==="\u27EE"?(l="\u23A7",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\rgroup"||e==="\u27EF"?(l="\u23AB",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lmoustache"||e==="\u23B0"?(l="\u23A7",f="\u23AD",h="\u23AA",m="Size4-Regular"):(e==="\\rmoustache"||e==="\u23B1")&&(l="\u23AB",f="\u23A9",h="\u23AA",m="Size4-Regular");var g=Yy(l,m,a),y=g.height+g.depth,v=Yy(h,m,a),x=v.height+v.depth,b=Yy(f,m,a),T=b.height+b.depth,S=0,w=1;if(u!==null){var E=Yy(u,m,a);S=E.height+E.depth,w=2}var _=y+T+S,C=Math.max(0,Math.ceil((r-_)/(w*x))),D=_+C*w*x,O=i.fontMetrics().axisHeight;n&&(O*=i.sizeMultiplier);var R=D/2-O,k=[];if(d.length>0){var L=D-y-T,A=Math.round(D*1e3),I=Y4e(d,Math.round(L*1e3)),M=new ec(d,I),P=(p/1e3).toFixed(3)+"em",B=(A/1e3).toFixed(3)+"em",F=new dl([M],{width:P,height:B,viewBox:"0 0 "+p+" "+A}),z=Fe.makeSvgSpan([],[F],i);z.height=A/1e3,z.style.width=P,z.style.height=B,k.push({type:"elem",elem:z})}else{if(k.push(O7(f,m,a)),k.push(v3),u===null){var $=D-y-T+2*Z7;k.push(P7(h,$,i))}else{var U=(D-y-T-S)/2+2*Z7;k.push(P7(h,U,i)),k.push(v3),k.push(O7(u,m,a)),k.push(v3),k.push(P7(h,U,i))}k.push(v3),k.push(O7(l,m,a))}var K=i.havingBaseStyle(nr.TEXT),ee=Fe.makeVList({positionType:"bottom",positionData:R,children:k},K);return cA(Fe.makeSpan(["delimsizing","mult"],[ee],K),nr.TEXT,i,s)},"makeStackedDelim"),B7=80,F7=.08,$7=o(function(e,r,n,i,a){var s=W4e(e,i,n),l=new ec(e,s),u=new dl([l],{width:"400em",height:Et(r),viewBox:"0 0 400000 "+n,preserveAspectRatio:"xMinYMin slice"});return Fe.makeSvgSpan(["hide-tail"],[u],a)},"sqrtSvg"),G3e=o(function(e,r){var n=r.havingBaseSizing(),i=rV("\\surd",e*n.sizeMultiplier,tV,n),a=n.sizeMultiplier,s=Math.max(0,r.minRuleThickness-r.fontMetrics().sqrtRuleThickness),l,u=0,h=0,f=0,d;return i.type==="small"?(f=1e3+1e3*s+B7,e<1?a=1:e<1.4&&(a=.7),u=(1+s+F7)/a,h=(1+s)/a,l=$7("sqrtMain",u,f,s,r),l.style.minWidth="0.853em",d=.833/a):i.type==="large"?(f=(1e3+B7)*jy[i.size],h=(jy[i.size]+s)/a,u=(jy[i.size]+s+F7)/a,l=$7("sqrtSize"+i.size,u,f,s,r),l.style.minWidth="1.02em",d=1/a):(u=e+s+F7,h=e+s,f=Math.floor(1e3*e+s)+B7,l=$7("sqrtTall",u,f,s,r),l.style.minWidth="0.742em",d=1.056),l.height=h,l.style.height=Et(u),{span:l,advanceWidth:d,ruleWidth:(r.fontMetrics().sqrtRuleThickness+s)*a}},"makeSqrtImage"),JG=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","\\surd"],V3e=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1"],eV=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],jy=[0,1.2,1.8,2.4,3],U3e=o(function(e,r,n,i,a){if(e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle"),Jt.contains(JG,e)||Jt.contains(eV,e))return QG(e,r,!1,n,i,a);if(Jt.contains(V3e,e))return ZG(e,jy[r],!1,n,i,a);throw new pt("Illegal delimiter: '"+e+"'")},"makeSizedDelim"),H3e=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],W3e=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"stack"}],tV=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],q3e=o(function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},"delimTypeToFont"),rV=o(function(e,r,n,i){for(var a=Math.min(2,3-i.style.size),s=a;sr)return n[s]}return n[n.length-1]},"traverseSequence"),nV=o(function(e,r,n,i,a,s){e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle");var l;Jt.contains(eV,e)?l=H3e:Jt.contains(JG,e)?l=tV:l=W3e;var u=rV(e,r,l,i);return u.type==="small"?B3e(e,u.style,n,i,a,s):u.type==="large"?QG(e,u.size,n,i,a,s):ZG(e,r,n,i,a,s)},"makeCustomSizedDelim"),Y3e=o(function(e,r,n,i,a,s){var l=i.fontMetrics().axisHeight*i.sizeMultiplier,u=901,h=5/i.fontMetrics().ptPerEm,f=Math.max(r-l,n+l),d=Math.max(f/500*u,2*f-h);return nV(e,d,!0,i,a,s)},"makeLeftRightDelim"),hu={sqrtImage:G3e,sizedDelim:U3e,sizeToMaxHeight:jy,customSizedDelim:nV,leftRightDelim:Y3e},oG={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},X3e=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27E8","\\rangle","\u27E9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];o(M3,"checkDelimiter");Nt({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:o((t,e)=>{var r=M3(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:oG[t.funcName].size,mclass:oG[t.funcName].mclass,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>t.delim==="."?Fe.makeSpan([t.mclass]):hu.sizedDelim(t.delim,t.size,e,t.mode,[t.mclass]),"htmlBuilder"),mathmlBuilder:o(t=>{var e=[];t.delim!=="."&&e.push(Do(t.delim,t.mode));var r=new dt.MathNode("mo",e);t.mclass==="mopen"||t.mclass==="mclose"?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=Et(hu.sizeToMaxHeight[t.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r},"mathmlBuilder")});o(lG,"assertParsed");Nt({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=t.parser.gullet.macros.get("\\current@color");if(r&&typeof r!="string")throw new pt("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:M3(e[0],t).text,color:r}},"handler")});Nt({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=M3(e[0],t),n=t.parser;++n.leftrightDepth;var i=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var a=xr(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:i,left:r.text,right:a.delim,rightColor:a.color}},"handler"),htmlBuilder:o((t,e)=>{lG(t);for(var r=$i(t.body,e,!0,["mopen","mclose"]),n=0,i=0,a=!1,s=0;s{lG(t);var r=_s(t.body,e);if(t.left!=="."){var n=new dt.MathNode("mo",[Do(t.left,t.mode)]);n.setAttribute("fence","true"),r.unshift(n)}if(t.right!=="."){var i=new dt.MathNode("mo",[Do(t.right,t.mode)]);i.setAttribute("fence","true"),t.rightColor&&i.setAttribute("mathcolor",t.rightColor),r.push(i)}return aA(r)},"mathmlBuilder")});Nt({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=M3(e[0],t);if(!t.parser.leftrightDepth)throw new pt("\\middle without preceding \\left",r);return{type:"middle",mode:t.parser.mode,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>{var r;if(t.delim===".")r=ev(e,[]);else{r=hu.sizedDelim(t.delim,1,e,t.mode,[]);var n={delim:t.delim,options:e};r.isMiddle=n}return r},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=t.delim==="\\vert"||t.delim==="|"?Do("|","text"):Do(t.delim,t.mode),n=new dt.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n},"mathmlBuilder")});uA=o((t,e)=>{var r=Fe.wrapFragment($r(t.body,e),e),n=t.label.slice(1),i=e.sizeMultiplier,a,s=0,l=Jt.isCharacterBox(t.body);if(n==="sout")a=Fe.makeSpan(["stretchy","sout"]),a.height=e.fontMetrics().defaultRuleThickness/i,s=-.5*e.fontMetrics().xHeight;else if(n==="phase"){var u=ni({number:.6,unit:"pt"},e),h=ni({number:.35,unit:"ex"},e),f=e.havingBaseSizing();i=i/f.sizeMultiplier;var d=r.height+r.depth+u+h;r.style.paddingLeft=Et(d/2+u);var p=Math.floor(1e3*d*i),m=U4e(p),g=new dl([new ec("phase",m)],{width:"400em",height:Et(p/1e3),viewBox:"0 0 400000 "+p,preserveAspectRatio:"xMinYMin slice"});a=Fe.makeSvgSpan(["hide-tail"],[g],e),a.style.height=Et(d),s=r.depth+u+h}else{/cancel/.test(n)?l||r.classes.push("cancel-pad"):n==="angl"?r.classes.push("anglpad"):r.classes.push("boxpad");var y=0,v=0,x=0;/box/.test(n)?(x=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),y=e.fontMetrics().fboxsep+(n==="colorbox"?0:x),v=y):n==="angl"?(x=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),y=4*x,v=Math.max(0,.25-r.depth)):(y=l?.2:0,v=y),a=du.encloseSpan(r,n,y,v,e),/fbox|boxed|fcolorbox/.test(n)?(a.style.borderStyle="solid",a.style.borderWidth=Et(x)):n==="angl"&&x!==.049&&(a.style.borderTopWidth=Et(x),a.style.borderRightWidth=Et(x)),s=r.depth+v,t.backgroundColor&&(a.style.backgroundColor=t.backgroundColor,t.borderColor&&(a.style.borderColor=t.borderColor))}var b;if(t.backgroundColor)b=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:s},{type:"elem",elem:r,shift:0}]},e);else{var T=/cancel|phase/.test(n)?["svg-align"]:[];b=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:a,shift:s,wrapperClasses:T}]},e)}return/cancel/.test(n)&&(b.height=r.height,b.depth=r.depth),/cancel/.test(n)&&!l?Fe.makeSpan(["mord","cancel-lap"],[b],e):Fe.makeSpan(["mord"],[b],e)},"htmlBuilder$7"),hA=o((t,e)=>{var r=0,n=new dt.MathNode(t.label.indexOf("colorbox")>-1?"mpadded":"menclose",[vn(t.body,e)]);switch(t.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),t.label==="\\fcolorbox"){var i=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);n.setAttribute("style","border: "+i+"em solid "+String(t.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return t.backgroundColor&&n.setAttribute("mathbackground",t.backgroundColor),n},"mathmlBuilder$6");Nt({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=e[1];return{type:"enclose",mode:n.mode,label:i,backgroundColor:a,body:s}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=xr(e[1],"color-token").color,l=e[2];return{type:"enclose",mode:n.mode,label:i,backgroundColor:s,borderColor:a,body:l}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\fbox",body:e[0]}}});Nt({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"enclose",mode:r.mode,label:n,body:i}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\angl",body:e[0]}}});iV={};o(tc,"defineEnvironment");aV={};o(fe,"defineMacro");o(cG,"getHLines");I3=o(t=>{var e=t.parser.settings;if(!e.displayMode)throw new pt("{"+t.envName+"} can be used only in display mode.")},"validateAmsEnvironmentContext");o(fA,"getAutoTag");o(bh,"parseArray");o(dA,"dCellStyle");rc=o(function(e,r){var n,i,a=e.body.length,s=e.hLinesBeforeRow,l=0,u=new Array(a),h=[],f=Math.max(r.fontMetrics().arrayRuleWidth,r.minRuleThickness),d=1/r.fontMetrics().ptPerEm,p=5*d;if(e.colSeparationType&&e.colSeparationType==="small"){var m=r.havingStyle(nr.SCRIPT).sizeMultiplier;p=.2778*(m/r.sizeMultiplier)}var g=e.colSeparationType==="CD"?ni({number:3,unit:"ex"},r):12*d,y=3*d,v=e.arraystretch*g,x=.7*v,b=.3*v,T=0;function S(ae){for(var Oe=0;Oe0&&(T+=.25),h.push({pos:T,isDashed:ae[Oe]})}for(o(S,"setHLinePos"),S(s[0]),n=0;n0&&(R+=b,_ae))for(n=0;n=l)){var Z=void 0;(i>0||e.hskipBeforeAndAfter)&&(Z=Jt.deflt(U.pregap,p),Z!==0&&(I=Fe.makeSpan(["arraycolsep"],[]),I.style.width=Et(Z),A.push(I)));var ue=[];for(n=0;n0){for(var te=Fe.makeLineSpan("hline",r,f),he=Fe.makeLineSpan("hdashline",r,f),le=[{type:"elem",elem:u,shift:0}];h.length>0;){var J=h.pop(),Se=J.pos-k;J.isDashed?le.push({type:"elem",elem:he,shift:Se}):le.push({type:"elem",elem:te,shift:Se})}u=Fe.makeVList({positionType:"individualShift",children:le},r)}if(P.length===0)return Fe.makeSpan(["mord"],[u],r);var se=Fe.makeVList({positionType:"individualShift",children:P},r);return se=Fe.makeSpan(["tag"],[se],r),Fe.makeFragment([u,se])},"htmlBuilder"),j3e={c:"center ",l:"left ",r:"right "},nc=o(function(e,r){for(var n=[],i=new dt.MathNode("mtd",[],["mtr-glue"]),a=new dt.MathNode("mtd",[],["mml-eqn-num"]),s=0;s0){var g=e.cols,y="",v=!1,x=0,b=g.length;g[0].type==="separator"&&(p+="top ",x=1),g[g.length-1].type==="separator"&&(p+="bottom ",b-=1);for(var T=x;T0?"left ":"",p+=C[C.length-1].length>0?"right ":"";for(var D=1;D-1?"alignat":"align",a=e.envName==="split",s=bh(e.parser,{cols:n,addJot:!0,autoTag:a?void 0:fA(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:a?2:void 0,leqno:e.parser.settings.leqno},"display"),l,u=0,h={type:"ordgroup",mode:e.mode,body:[]};if(r[0]&&r[0].type==="ordgroup"){for(var f="",d=0;d0&&m&&(v=1),n[g]={type:"align",align:y,pregap:v,postgap:0}}return s.colSeparationType=m?"align":"alignat",s},"alignedHandler");tc({type:"array",names:["array","darray"],props:{numArgs:1},handler(t,e){var r=R3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=oA(s),u=l.text;if("lcr".indexOf(u)!==-1)return{type:"align",align:u};if(u==="|")return{type:"separator",separator:"|"};if(u===":")return{type:"separator",separator:":"};throw new pt("Unknown column alignment: "+u,s)}),a={cols:i,hskipBeforeAndAfter:!0,maxNumCols:i.length};return bh(t.parser,a,dA(t.envName))},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName.replace("*","")],r="c",n={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if(t.envName.charAt(t.envName.length-1)==="*"){var i=t.parser;if(i.consumeSpaces(),i.fetch().text==="["){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,"lcr".indexOf(r)===-1)throw new pt("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),n.cols=[{type:"align",align:r}]}}var a=bh(t.parser,n,dA(t.envName)),s=Math.max(0,...a.body.map(l=>l.length));return a.cols=new Array(s).fill({type:"align",align:r}),e?{type:"leftright",mode:t.mode,body:[a],left:e[0],right:e[1],rightColor:void 0}:a},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(t){var e={arraystretch:.5},r=bh(t.parser,e,"script");return r.colSeparationType="small",r},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["subarray"],props:{numArgs:1},handler(t,e){var r=R3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=oA(s),u=l.text;if("lc".indexOf(u)!==-1)return{type:"align",align:u};throw new pt("Unknown column alignment: "+u,s)});if(i.length>1)throw new pt("{subarray} can contain only one column");var a={cols:i,hskipBeforeAndAfter:!1,arraystretch:.5};if(a=bh(t.parser,a,"script"),a.body.length>0&&a.body[0].length>1)throw new pt("{subarray} can contain only one column");return a},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(t){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},r=bh(t.parser,e,dA(t.envName));return{type:"leftright",mode:t.mode,body:[r],left:t.envName.indexOf("r")>-1?".":"\\{",right:t.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:sV,htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(t){Jt.contains(["gather","gather*"],t.envName)&&I3(t);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:fA(t.envName),emptySingleRow:!0,leqno:t.parser.settings.leqno};return bh(t.parser,e,"display")},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:sV,htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(t){I3(t);var e={autoTag:fA(t.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:t.parser.settings.leqno};return bh(t.parser,e,"display")},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["CD"],props:{numArgs:0},handler(t){return I3(t),O3e(t.parser)},htmlBuilder:rc,mathmlBuilder:nc});fe("\\nonumber","\\gdef\\@eqnsw{0}");fe("\\notag","\\nonumber");Nt({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(t,e){throw new pt(t.funcName+" valid only within array environment")}});uG=iV;Nt({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];if(i.type!=="ordgroup")throw new pt("Invalid environment name",i);for(var a="",s=0;s{var r=t.font,n=e.withFont(r);return $r(t.body,n)},"htmlBuilder$5"),lV=o((t,e)=>{var r=t.font,n=e.withFont(r);return vn(t.body,n)},"mathmlBuilder$4"),hG={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Nt({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=C3(e[0]),a=n;return a in hG&&(a=hG[a]),{type:"font",mode:r.mode,font:a.slice(1),body:i}},"handler"),htmlBuilder:oV,mathmlBuilder:lV});Nt({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r}=t,n=e[0],i=Jt.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:N3(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:i}},"handler")});Nt({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n,breakOnTokenText:i}=t,{mode:a}=r,s=r.parseExpression(!0,i),l="math"+n.slice(1);return{type:"font",mode:a,font:l,body:{type:"ordgroup",mode:r.mode,body:s}}},"handler"),htmlBuilder:oV,mathmlBuilder:lV});cV=o((t,e)=>{var r=e;return t==="display"?r=r.id>=nr.SCRIPT.id?r.text():nr.DISPLAY:t==="text"&&r.size===nr.DISPLAY.size?r=nr.TEXT:t==="script"?r=nr.SCRIPT:t==="scriptscript"&&(r=nr.SCRIPTSCRIPT),r},"adjustStyle"),pA=o((t,e)=>{var r=cV(t.size,e.style),n=r.fracNum(),i=r.fracDen(),a;a=e.havingStyle(n);var s=$r(t.numer,a,e);if(t.continued){var l=8.5/e.fontMetrics().ptPerEm,u=3.5/e.fontMetrics().ptPerEm;s.height=s.height0?g=3*p:g=7*p,y=e.fontMetrics().denom1):(d>0?(m=e.fontMetrics().num2,g=p):(m=e.fontMetrics().num3,g=3*p),y=e.fontMetrics().denom2);var v;if(f){var b=e.fontMetrics().axisHeight;m-s.depth-(b+.5*d){var r=new dt.MathNode("mfrac",[vn(t.numer,e),vn(t.denom,e)]);if(!t.hasBarLine)r.setAttribute("linethickness","0px");else if(t.barSize){var n=ni(t.barSize,e);r.setAttribute("linethickness",Et(n))}var i=cV(t.size,e.style);if(i.size!==e.style.size){r=new dt.MathNode("mstyle",[r]);var a=i.size===nr.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",a),r.setAttribute("scriptlevel","0")}if(t.leftDelim!=null||t.rightDelim!=null){var s=[];if(t.leftDelim!=null){var l=new dt.MathNode("mo",[new dt.TextNode(t.leftDelim.replace("\\",""))]);l.setAttribute("fence","true"),s.push(l)}if(s.push(r),t.rightDelim!=null){var u=new dt.MathNode("mo",[new dt.TextNode(t.rightDelim.replace("\\",""))]);u.setAttribute("fence","true"),s.push(u)}return aA(s)}return r},"mathmlBuilder$3");Nt({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1],s,l=null,u=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":s=!0;break;case"\\\\atopfrac":s=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":s=!1,l="(",u=")";break;case"\\\\bracefrac":s=!1,l="\\{",u="\\}";break;case"\\\\brackfrac":s=!1,l="[",u="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:r.mode,continued:!1,numer:i,denom:a,hasBarLine:s,leftDelim:l,rightDelim:u,size:h,barSize:null}},"handler"),htmlBuilder:pA,mathmlBuilder:mA});Nt({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:i,denom:a,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}},"handler")});Nt({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(t){var{parser:e,funcName:r,token:n}=t,i;switch(r){case"\\over":i="\\frac";break;case"\\choose":i="\\binom";break;case"\\atop":i="\\\\atopfrac";break;case"\\brace":i="\\\\bracefrac";break;case"\\brack":i="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:i,token:n}}});fG=["display","text","script","scriptscript"],dG=o(function(e){var r=null;return e.length>0&&(r=e,r=r==="."?null:r),r},"delimFromValue");Nt({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(t,e){var{parser:r}=t,n=e[4],i=e[5],a=C3(e[0]),s=a.type==="atom"&&a.family==="open"?dG(a.text):null,l=C3(e[1]),u=l.type==="atom"&&l.family==="close"?dG(l.text):null,h=xr(e[2],"size"),f,d=null;h.isBlank?f=!0:(d=h.value,f=d.number>0);var p="auto",m=e[3];if(m.type==="ordgroup"){if(m.body.length>0){var g=xr(m.body[0],"textord");p=fG[Number(g.text)]}}else m=xr(m,"textord"),p=fG[Number(m.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:f,barSize:d,leftDelim:s,rightDelim:u,size:p}},htmlBuilder:pA,mathmlBuilder:mA});Nt({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(t,e){var{parser:r,funcName:n,token:i}=t;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:xr(e[0],"size").value,token:i}}});Nt({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=_4e(xr(e[1],"infix").size),s=e[2],l=a.number>0;return{type:"genfrac",mode:r.mode,numer:i,denom:s,continued:!1,hasBarLine:l,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},"handler"),htmlBuilder:pA,mathmlBuilder:mA});uV=o((t,e)=>{var r=e.style,n,i;t.type==="supsub"?(n=t.sup?$r(t.sup,e.havingStyle(r.sup()),e):$r(t.sub,e.havingStyle(r.sub()),e),i=xr(t.base,"horizBrace")):i=xr(t,"horizBrace");var a=$r(i.base,e.havingBaseStyle(nr.DISPLAY)),s=du.svgSpan(i,e),l;if(i.isOver?(l=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:s}]},e),l.children[0].children[0].children[1].classes.push("svg-align")):(l=Fe.makeVList({positionType:"bottom",positionData:a.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:a}]},e),l.children[0].children[0].children[0].classes.push("svg-align")),n){var u=Fe.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e);i.isOver?l=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:u},{type:"kern",size:.2},{type:"elem",elem:n}]},e):l=Fe.makeVList({positionType:"bottom",positionData:u.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:u}]},e)}return Fe.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e)},"htmlBuilder$3"),K3e=o((t,e)=>{var r=du.mathMLnode(t.label);return new dt.MathNode(t.isOver?"mover":"munder",[vn(t.base,e),r])},"mathmlBuilder$2");Nt({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:e[0]}},htmlBuilder:uV,mathmlBuilder:K3e});Nt({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[1],i=xr(e[0],"url").url;return r.settings.isTrusted({command:"\\href",url:i})?{type:"href",mode:r.mode,href:i,body:gi(n)}:r.formatUnsupportedCmd("\\href")},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.body,e,!1);return Fe.makeAnchor(t.href,[],r,e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=xh(t.body,e);return r instanceof ts||(r=new ts("mrow",[r])),r.setAttribute("href",t.href),r},"mathmlBuilder")});Nt({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=xr(e[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var i=[],a=0;a{var{parser:r,funcName:n,token:i}=t,a=xr(e[0],"raw").string,s=e[1];r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var l,u={};switch(n){case"\\htmlClass":u.class=a,l={command:"\\htmlClass",class:a};break;case"\\htmlId":u.id=a,l={command:"\\htmlId",id:a};break;case"\\htmlStyle":u.style=a,l={command:"\\htmlStyle",style:a};break;case"\\htmlData":{for(var h=a.split(","),f=0;f{var r=$i(t.body,e,!1),n=["enclosing"];t.attributes.class&&n.push(...t.attributes.class.trim().split(/\s+/));var i=Fe.makeSpan(n,r,e);for(var a in t.attributes)a!=="class"&&t.attributes.hasOwnProperty(a)&&i.setAttribute(a,t.attributes[a]);return i},"htmlBuilder"),mathmlBuilder:o((t,e)=>xh(t.body,e),"mathmlBuilder")});Nt({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"htmlmathml",mode:r.mode,html:gi(e[0]),mathml:gi(e[1])}},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.html,e,!1);return Fe.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>xh(t.mathml,e),"mathmlBuilder")});z7=o(function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var r=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!r)throw new pt("Invalid size: '"+e+"' in \\includegraphics");var n={number:+(r[1]+r[2]),unit:r[3]};if(!DG(n))throw new pt("Invalid unit: '"+n.unit+"' in \\includegraphics.");return n},"sizeData");Nt({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:o((t,e,r)=>{var{parser:n}=t,i={number:0,unit:"em"},a={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var u=xr(r[0],"raw").string,h=u.split(","),f=0;f{var r=ni(t.height,e),n=0;t.totalheight.number>0&&(n=ni(t.totalheight,e)-r);var i=0;t.width.number>0&&(i=ni(t.width,e));var a={height:Et(r+n)};i>0&&(a.width=Et(i)),n>0&&(a.verticalAlign=Et(-n));var s=new q7(t.src,t.alt,a);return s.height=r,s.depth=n,s},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mglyph",[]);r.setAttribute("alt",t.alt);var n=ni(t.height,e),i=0;if(t.totalheight.number>0&&(i=ni(t.totalheight,e)-n,r.setAttribute("valign",Et(-i))),r.setAttribute("height",Et(n+i)),t.width.number>0){var a=ni(t.width,e);r.setAttribute("width",Et(a))}return r.setAttribute("src",t.src),r},"mathmlBuilder")});Nt({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=xr(e[0],"size");if(r.settings.strict){var a=n[1]==="m",s=i.value.unit==="mu";a?(s||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, "+("not "+i.value.unit+" units")),r.mode!=="math"&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):s&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:i.value}},htmlBuilder(t,e){return Fe.makeGlue(t.dimension,e)},mathmlBuilder(t,e){var r=ni(t.dimension,e);return new dt.SpaceNode(r)}});Nt({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:i}},"handler"),htmlBuilder:o((t,e)=>{var r;t.alignment==="clap"?(r=Fe.makeSpan([],[$r(t.body,e)]),r=Fe.makeSpan(["inner"],[r],e)):r=Fe.makeSpan(["inner"],[$r(t.body,e)]);var n=Fe.makeSpan(["fix"],[]),i=Fe.makeSpan([t.alignment],[r,n],e),a=Fe.makeSpan(["strut"]);return a.style.height=Et(i.height+i.depth),i.depth&&(a.style.verticalAlign=Et(-i.depth)),i.children.unshift(a),i=Fe.makeSpan(["thinbox"],[i],e),Fe.makeSpan(["mord","vbox"],[i],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mpadded",[vn(t.body,e)]);if(t.alignment!=="rlap"){var n=t.alignment==="llap"?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r},"mathmlBuilder")});Nt({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){var{funcName:r,parser:n}=t,i=n.mode;n.switchMode("math");var a=r==="\\("?"\\)":"$",s=n.parseExpression(!1,a);return n.expect(a),n.switchMode(i),{type:"styling",mode:n.mode,style:"text",body:s}}});Nt({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){throw new pt("Mismatched "+t.funcName)}});pG=o((t,e)=>{switch(e.style.size){case nr.DISPLAY.size:return t.display;case nr.TEXT.size:return t.text;case nr.SCRIPT.size:return t.script;case nr.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}},"chooseMathStyle");Nt({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"mathchoice",mode:r.mode,display:gi(e[0]),text:gi(e[1]),script:gi(e[2]),scriptscript:gi(e[3])}},"handler"),htmlBuilder:o((t,e)=>{var r=pG(t,e),n=$i(r,e,!1);return Fe.makeFragment(n)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=pG(t,e);return xh(r,e)},"mathmlBuilder")});hV=o((t,e,r,n,i,a,s)=>{t=Fe.makeSpan([],[t]);var l=r&&Jt.isCharacterBox(r),u,h;if(e){var f=$r(e,n.havingStyle(i.sup()),n);h={elem:f,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-f.depth)}}if(r){var d=$r(r,n.havingStyle(i.sub()),n);u={elem:d,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-d.height)}}var p;if(h&&u){var m=n.fontMetrics().bigOpSpacing5+u.elem.height+u.elem.depth+u.kern+t.depth+s;p=Fe.makeVList({positionType:"bottom",positionData:m,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:Et(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Et(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(u){var g=t.height-s;p=Fe.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:Et(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t}]},n)}else if(h){var y=t.depth+s;p=Fe.makeVList({positionType:"bottom",positionData:y,children:[{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Et(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else return t;var v=[p];if(u&&a!==0&&!l){var x=Fe.makeSpan(["mspace"],[],n);x.style.marginRight=Et(a),v.unshift(x)}return Fe.makeSpan(["mop","op-limits"],v,n)},"assembleSupSub"),fV=["\\smallint"],S0=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"op"),i=!0):a=xr(t,"op");var s=e.style,l=!1;s.size===nr.DISPLAY.size&&a.symbol&&!Jt.contains(fV,a.name)&&(l=!0);var u;if(a.symbol){var h=l?"Size2-Regular":"Size1-Regular",f="";if((a.name==="\\oiint"||a.name==="\\oiiint")&&(f=a.name.slice(1),a.name=f==="oiint"?"\\iint":"\\iiint"),u=Fe.makeSymbol(a.name,h,"math",e,["mop","op-symbol",l?"large-op":"small-op"]),f.length>0){var d=u.italic,p=Fe.staticSvg(f+"Size"+(l?"2":"1"),e);u=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:u,shift:0},{type:"elem",elem:p,shift:l?.08:0}]},e),a.name="\\"+f,u.classes.unshift("mop"),u.italic=d}}else if(a.body){var m=$i(a.body,e,!0);m.length===1&&m[0]instanceof As?(u=m[0],u.classes[0]="mop"):u=Fe.makeSpan(["mop"],m,e)}else{for(var g=[],y=1;y{var r;if(t.symbol)r=new ts("mo",[Do(t.name,t.mode)]),Jt.contains(fV,t.name)&&r.setAttribute("largeop","false");else if(t.body)r=new ts("mo",_s(t.body,e));else{r=new ts("mi",[new Ao(t.name.slice(1))]);var n=new ts("mo",[Do("\u2061","text")]);t.parentIsSupSub?r=new ts("mrow",[r,n]):r=zG([r,n])}return r},"mathmlBuilder$1"),Q3e={"\u220F":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22C0":"\\bigwedge","\u22C1":"\\bigvee","\u22C2":"\\bigcap","\u22C3":"\\bigcup","\u2A00":"\\bigodot","\u2A01":"\\bigoplus","\u2A02":"\\bigotimes","\u2A04":"\\biguplus","\u2A06":"\\bigsqcup"};Nt({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220F","\u2210","\u2211","\u22C0","\u22C1","\u22C2","\u22C3","\u2A00","\u2A01","\u2A02","\u2A04","\u2A06"],props:{numArgs:0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=n;return i.length===1&&(i=Q3e[i]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:i}},"handler"),htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:gi(n)}},"handler"),htmlBuilder:S0,mathmlBuilder:tv});Z3e={"\u222B":"\\int","\u222C":"\\iint","\u222D":"\\iiint","\u222E":"\\oint","\u222F":"\\oiint","\u2230":"\\oiiint"};Nt({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222B","\u222C","\u222D","\u222E","\u222F","\u2230"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t,n=r;return n.length===1&&(n=Z3e[n]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:S0,mathmlBuilder:tv});dV=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"operatorname"),i=!0):a=xr(t,"operatorname");var s;if(a.body.length>0){for(var l=a.body.map(d=>{var p=d.text;return typeof p=="string"?{type:"textord",mode:d.mode,text:p}:d}),u=$i(l,e.withFont("mathrm"),!0),h=0;h{for(var r=_s(t.body,e.withFont("mathrm")),n=!0,i=0;if.toText()).join("");r=[new dt.TextNode(l)]}var u=new dt.MathNode("mi",r);u.setAttribute("mathvariant","normal");var h=new dt.MathNode("mo",[Do("\u2061","text")]);return t.parentIsSupSub?new dt.MathNode("mrow",[u,h]):dt.newDocumentFragment([u,h])},"mathmlBuilder");Nt({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"operatorname",mode:r.mode,body:gi(i),alwaysHandleSupSub:n==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},"handler"),htmlBuilder:dV,mathmlBuilder:J3e});fe("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");cd({type:"ordgroup",htmlBuilder(t,e){return t.semisimple?Fe.makeFragment($i(t.body,e,!1)):Fe.makeSpan(["mord"],$i(t.body,e,!0),e)},mathmlBuilder(t,e){return xh(t.body,e,!0)}});Nt({type:"overline",names:["\\overline"],props:{numArgs:1},handler(t,e){var{parser:r}=t,n=e[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(t,e){var r=$r(t.body,e.havingCrampedStyle()),n=Fe.makeLineSpan("overline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*i},{type:"elem",elem:n},{type:"kern",size:i}]},e);return Fe.makeSpan(["mord","overline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("mover",[vn(t.body,e),r]);return n.setAttribute("accent","true"),n}});Nt({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"phantom",mode:r.mode,body:gi(n)}},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.body,e.withPhantom(),!1);return Fe.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=_s(t.body,e);return new dt.MathNode("mphantom",r)},"mathmlBuilder")});Nt({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"hphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Fe.makeSpan([],[$r(t.body,e.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var n=0;n{var r=_s(gi(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("height","0px"),i.setAttribute("depth","0px"),i},"mathmlBuilder")});Nt({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"vphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Fe.makeSpan(["inner"],[$r(t.body,e.withPhantom())]),n=Fe.makeSpan(["fix"],[]);return Fe.makeSpan(["mord","rlap"],[r,n],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=_s(gi(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("width","0px"),i},"mathmlBuilder")});Nt({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t,n=xr(e[0],"size").value,i=e[1];return{type:"raisebox",mode:r.mode,dy:n,body:i}},htmlBuilder(t,e){var r=$r(t.body,e),n=ni(t.dy,e);return Fe.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){var r=new dt.MathNode("mpadded",[vn(t.body,e)]),n=t.dy.number+t.dy.unit;return r.setAttribute("voffset",n),r}});Nt({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(t){var{parser:e}=t;return{type:"internal",mode:e.mode}}});Nt({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(t,e,r){var{parser:n}=t,i=r[0],a=xr(e[0],"size"),s=xr(e[1],"size");return{type:"rule",mode:n.mode,shift:i&&xr(i,"size").value,width:a.value,height:s.value}},htmlBuilder(t,e){var r=Fe.makeSpan(["mord","rule"],[],e),n=ni(t.width,e),i=ni(t.height,e),a=t.shift?ni(t.shift,e):0;return r.style.borderRightWidth=Et(n),r.style.borderTopWidth=Et(i),r.style.bottom=Et(a),r.width=n,r.height=i+a,r.depth=-a,r.maxFontSize=i*1.125*e.sizeMultiplier,r},mathmlBuilder(t,e){var r=ni(t.width,e),n=ni(t.height,e),i=t.shift?ni(t.shift,e):0,a=e.color&&e.getColor()||"black",s=new dt.MathNode("mspace");s.setAttribute("mathbackground",a),s.setAttribute("width",Et(r)),s.setAttribute("height",Et(n));var l=new dt.MathNode("mpadded",[s]);return i>=0?l.setAttribute("height",Et(i)):(l.setAttribute("height",Et(i)),l.setAttribute("depth",Et(-i))),l.setAttribute("voffset",Et(i)),l}});o(pV,"sizingGroup");mG=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],e5e=o((t,e)=>{var r=e.havingSize(t.size);return pV(t.body,r,e)},"htmlBuilder");Nt({type:"sizing",names:mG,props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!1,r);return{type:"sizing",mode:i.mode,size:mG.indexOf(n)+1,body:a}},"handler"),htmlBuilder:e5e,mathmlBuilder:o((t,e)=>{var r=e.havingSize(t.size),n=_s(t.body,r),i=new dt.MathNode("mstyle",n);return i.setAttribute("mathsize",Et(r.sizeMultiplier)),i},"mathmlBuilder")});Nt({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:o((t,e,r)=>{var{parser:n}=t,i=!1,a=!1,s=r[0]&&xr(r[0],"ordgroup");if(s)for(var l="",u=0;u{var r=Fe.makeSpan([],[$r(t.body,e)]);if(!t.smashHeight&&!t.smashDepth)return r;if(t.smashHeight&&(r.height=0,r.children))for(var n=0;n{var r=new dt.MathNode("mpadded",[vn(t.body,e)]);return t.smashHeight&&r.setAttribute("height","0px"),t.smashDepth&&r.setAttribute("depth","0px"),r},"mathmlBuilder")});Nt({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n}=t,i=r[0],a=e[0];return{type:"sqrt",mode:n.mode,body:a,index:i}},htmlBuilder(t,e){var r=$r(t.body,e.havingCrampedStyle());r.height===0&&(r.height=e.fontMetrics().xHeight),r=Fe.wrapFragment(r,e);var n=e.fontMetrics(),i=n.defaultRuleThickness,a=i;e.style.idr.height+r.depth+s&&(s=(s+d-r.height-r.depth)/2);var p=u.height-r.height-s-h;r.style.paddingLeft=Et(f);var m=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+p)},{type:"elem",elem:u},{type:"kern",size:h}]},e);if(t.index){var g=e.havingStyle(nr.SCRIPTSCRIPT),y=$r(t.index,g,e),v=.6*(m.height-m.depth),x=Fe.makeVList({positionType:"shift",positionData:-v,children:[{type:"elem",elem:y}]},e),b=Fe.makeSpan(["root"],[x]);return Fe.makeSpan(["mord","sqrt"],[b,m],e)}else return Fe.makeSpan(["mord","sqrt"],[m],e)},mathmlBuilder(t,e){var{body:r,index:n}=t;return n?new dt.MathNode("mroot",[vn(r,e),vn(n,e)]):new dt.MathNode("msqrt",[vn(r,e)])}});gG={display:nr.DISPLAY,text:nr.TEXT,script:nr.SCRIPT,scriptscript:nr.SCRIPTSCRIPT};Nt({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t,e){var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!0,r),s=n.slice(1,n.length-5);return{type:"styling",mode:i.mode,style:s,body:a}},htmlBuilder(t,e){var r=gG[t.style],n=e.havingStyle(r).withFont("");return pV(t.body,n,e)},mathmlBuilder(t,e){var r=gG[t.style],n=e.havingStyle(r),i=_s(t.body,n),a=new dt.MathNode("mstyle",i),s={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},l=s[t.style];return a.setAttribute("scriptlevel",l[0]),a.setAttribute("displaystyle",l[1]),a}});t5e=o(function(e,r){var n=e.base;if(n)if(n.type==="op"){var i=n.limits&&(r.style.size===nr.DISPLAY.size||n.alwaysHandleSupSub);return i?S0:null}else if(n.type==="operatorname"){var a=n.alwaysHandleSupSub&&(r.style.size===nr.DISPLAY.size||n.limits);return a?dV:null}else{if(n.type==="accent")return Jt.isCharacterBox(n.base)?lA:null;if(n.type==="horizBrace"){var s=!e.sub;return s===n.isOver?uV:null}else return null}else return null},"htmlBuilderDelegate");cd({type:"supsub",htmlBuilder(t,e){var r=t5e(t,e);if(r)return r(t,e);var{base:n,sup:i,sub:a}=t,s=$r(n,e),l,u,h=e.fontMetrics(),f=0,d=0,p=n&&Jt.isCharacterBox(n);if(i){var m=e.havingStyle(e.style.sup());l=$r(i,m,e),p||(f=s.height-m.fontMetrics().supDrop*m.sizeMultiplier/e.sizeMultiplier)}if(a){var g=e.havingStyle(e.style.sub());u=$r(a,g,e),p||(d=s.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}var y;e.style===nr.DISPLAY?y=h.sup1:e.style.cramped?y=h.sup3:y=h.sup2;var v=e.sizeMultiplier,x=Et(.5/h.ptPerEm/v),b=null;if(u){var T=t.base&&t.base.type==="op"&&t.base.name&&(t.base.name==="\\oiint"||t.base.name==="\\oiiint");(s instanceof As||T)&&(b=Et(-s.italic))}var S;if(l&&u){f=Math.max(f,y,l.depth+.25*h.xHeight),d=Math.max(d,h.sub2);var w=h.defaultRuleThickness,E=4*w;if(f-l.depth-(u.height-d)0&&(f+=_,d-=_)}var C=[{type:"elem",elem:u,shift:d,marginRight:x,marginLeft:b},{type:"elem",elem:l,shift:-f,marginRight:x}];S=Fe.makeVList({positionType:"individualShift",children:C},e)}else if(u){d=Math.max(d,h.sub1,u.height-.8*h.xHeight);var D=[{type:"elem",elem:u,marginLeft:b,marginRight:x}];S=Fe.makeVList({positionType:"shift",positionData:d,children:D},e)}else if(l)f=Math.max(f,y,l.depth+.25*h.xHeight),S=Fe.makeVList({positionType:"shift",positionData:-f,children:[{type:"elem",elem:l,marginRight:x}]},e);else throw new Error("supsub must have either sup or sub.");var O=X7(s,"right")||"mord";return Fe.makeSpan([O],[s,Fe.makeSpan(["msupsub"],[S])],e)},mathmlBuilder(t,e){var r=!1,n,i;t.base&&t.base.type==="horizBrace"&&(i=!!t.sup,i===t.base.isOver&&(r=!0,n=t.base.isOver)),t.base&&(t.base.type==="op"||t.base.type==="operatorname")&&(t.base.parentIsSupSub=!0);var a=[vn(t.base,e)];t.sub&&a.push(vn(t.sub,e)),t.sup&&a.push(vn(t.sup,e));var s;if(r)s=n?"mover":"munder";else if(t.sub)if(t.sup){var h=t.base;h&&h.type==="op"&&h.limits&&e.style===nr.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===nr.DISPLAY||h.limits)?s="munderover":s="msubsup"}else{var u=t.base;u&&u.type==="op"&&u.limits&&(e.style===nr.DISPLAY||u.alwaysHandleSupSub)||u&&u.type==="operatorname"&&u.alwaysHandleSupSub&&(u.limits||e.style===nr.DISPLAY)?s="munder":s="msub"}else{var l=t.base;l&&l.type==="op"&&l.limits&&(e.style===nr.DISPLAY||l.alwaysHandleSupSub)||l&&l.type==="operatorname"&&l.alwaysHandleSupSub&&(l.limits||e.style===nr.DISPLAY)?s="mover":s="msup"}return new dt.MathNode(s,a)}});cd({type:"atom",htmlBuilder(t,e){return Fe.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[Do(t.text,t.mode)]);if(t.family==="bin"){var n=sA(t,e);n==="bold-italic"&&r.setAttribute("mathvariant",n)}else t.family==="punct"?r.setAttribute("separator","true"):(t.family==="open"||t.family==="close")&&r.setAttribute("stretchy","false");return r}});mV={mi:"italic",mn:"normal",mtext:"normal"};cd({type:"mathord",htmlBuilder(t,e){return Fe.makeOrd(t,e,"mathord")},mathmlBuilder(t,e){var r=new dt.MathNode("mi",[Do(t.text,t.mode,e)]),n=sA(t,e)||"italic";return n!==mV[r.type]&&r.setAttribute("mathvariant",n),r}});cd({type:"textord",htmlBuilder(t,e){return Fe.makeOrd(t,e,"textord")},mathmlBuilder(t,e){var r=Do(t.text,t.mode,e),n=sA(t,e)||"normal",i;return t.mode==="text"?i=new dt.MathNode("mtext",[r]):/[0-9]/.test(t.text)?i=new dt.MathNode("mn",[r]):t.text==="\\prime"?i=new dt.MathNode("mo",[r]):i=new dt.MathNode("mi",[r]),n!==mV[i.type]&&i.setAttribute("mathvariant",n),i}});G7={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},V7={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};cd({type:"spacing",htmlBuilder(t,e){if(V7.hasOwnProperty(t.text)){var r=V7[t.text].className||"";if(t.mode==="text"){var n=Fe.makeOrd(t,e,"textord");return n.classes.push(r),n}else return Fe.makeSpan(["mspace",r],[Fe.mathsym(t.text,t.mode,e)],e)}else{if(G7.hasOwnProperty(t.text))return Fe.makeSpan(["mspace",G7[t.text]],[],e);throw new pt('Unknown type of space "'+t.text+'"')}},mathmlBuilder(t,e){var r;if(V7.hasOwnProperty(t.text))r=new dt.MathNode("mtext",[new dt.TextNode("\xA0")]);else{if(G7.hasOwnProperty(t.text))return new dt.MathNode("mspace");throw new pt('Unknown type of space "'+t.text+'"')}return r}});yG=o(()=>{var t=new dt.MathNode("mtd",[]);return t.setAttribute("width","50%"),t},"pad");cd({type:"tag",mathmlBuilder(t,e){var r=new dt.MathNode("mtable",[new dt.MathNode("mtr",[yG(),new dt.MathNode("mtd",[xh(t.body,e)]),yG(),new dt.MathNode("mtd",[xh(t.tag,e)])])]);return r.setAttribute("width","100%"),r}});vG={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},xG={"\\textbf":"textbf","\\textmd":"textmd"},r5e={"\\textit":"textit","\\textup":"textup"},bG=o((t,e)=>{var r=t.font;if(r){if(vG[r])return e.withTextFontFamily(vG[r]);if(xG[r])return e.withTextFontWeight(xG[r]);if(r==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(r5e[r])},"optionsWithFont");Nt({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"text",mode:r.mode,body:gi(i),font:n}},htmlBuilder(t,e){var r=bG(t,e),n=$i(t.body,r,!0);return Fe.makeSpan(["mord","text"],n,r)},mathmlBuilder(t,e){var r=bG(t,e);return xh(t.body,r)}});Nt({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"underline",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=$r(t.body,e),n=Fe.makeLineSpan("underline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Fe.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:i},{type:"elem",elem:n},{type:"kern",size:3*i},{type:"elem",elem:r}]},e);return Fe.makeSpan(["mord","underline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("munder",[vn(t.body,e),r]);return n.setAttribute("accentunder","true"),n}});Nt({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"vcenter",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=$r(t.body,e),n=e.fontMetrics().axisHeight,i=.5*(r.height-n-(r.depth+n));return Fe.makeVList({positionType:"shift",positionData:i,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){return new dt.MathNode("mpadded",[vn(t.body,e)],["vcenter"])}});Nt({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(t,e,r){throw new pt("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(t,e){for(var r=TG(t),n=[],i=e.havingStyle(e.style.text()),a=0;at.body.replace(/ /g,t.star?"\u2423":"\xA0"),"makeVerb"),yh=FG,gV=`[ \r + ]`,n5e="\\\\[a-zA-Z@]+",i5e="\\\\[^\uD800-\uDFFF]",a5e="("+n5e+")"+gV+"*",s5e=`\\\\( +|[ \r ]+ +?)[ \r ]*`,J7="[\u0300-\u036F]",o5e=new RegExp(J7+"+$"),l5e="("+gV+"+)|"+(s5e+"|")+"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]"+(J7+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(J7+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+a5e)+("|"+i5e+")"),A3=class{static{o(this,"Lexer")}constructor(e,r){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=r,this.tokenRegex=new RegExp(l5e,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,r){this.catcodes[e]=r}lex(){var e=this.input,r=this.tokenRegex.lastIndex;if(r===e.length)return new _o("EOF",new Qs(this,r,r));var n=this.tokenRegex.exec(e);if(n===null||n.index!==r)throw new pt("Unexpected character: '"+e[r]+"'",new _o(e[r],new Qs(this,r,r+1)));var i=n[6]||n[3]||(n[2]?"\\ ":" ");if(this.catcodes[i]===14){var a=e.indexOf(` +`,this.tokenRegex.lastIndex);return a===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=a+1,this.lex()}return new _o(i,new Qs(this,r,this.tokenRegex.lastIndex))}},eA=class{static{o(this,"Namespace")}constructor(e,r){e===void 0&&(e={}),r===void 0&&(r={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=r,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new pt("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var r in e)e.hasOwnProperty(r)&&(e[r]==null?delete this.current[r]:this.current[r]=e[r])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,r,n){if(n===void 0&&(n=!1),n){for(var i=0;i0&&(this.undefStack[this.undefStack.length-1][e]=r)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}r==null?delete this.current[e]:this.current[e]=r}},c5e=aV;fe("\\noexpand",function(t){var e=t.popToken();return t.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});fe("\\expandafter",function(t){var e=t.popToken();return t.expandOnce(!0),{tokens:[e],numArgs:0}});fe("\\@firstoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[0],numArgs:0}});fe("\\@secondoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[1],numArgs:0}});fe("\\@ifnextchar",function(t){var e=t.consumeArgs(3);t.consumeSpaces();var r=t.future();return e[0].length===1&&e[0][0].text===r.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});fe("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");fe("\\TextOrMath",function(t){var e=t.consumeArgs(2);return t.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});wG={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};fe("\\char",function(t){var e=t.popToken(),r,n="";if(e.text==="'")r=8,e=t.popToken();else if(e.text==='"')r=16,e=t.popToken();else if(e.text==="`")if(e=t.popToken(),e.text[0]==="\\")n=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new pt("\\char` missing argument");n=e.text.charCodeAt(0)}else r=10;if(r){if(n=wG[e.text],n==null||n>=r)throw new pt("Invalid base-"+r+" digit "+e.text);for(var i;(i=wG[t.future().text])!=null&&i{var i=t.consumeArg().tokens;if(i.length!==1)throw new pt("\\newcommand's first argument must be a macro name");var a=i[0].text,s=t.isDefined(a);if(s&&!e)throw new pt("\\newcommand{"+a+"} attempting to redefine "+(a+"; use \\renewcommand"));if(!s&&!r)throw new pt("\\renewcommand{"+a+"} when command "+a+" does not yet exist; use \\newcommand");var l=0;if(i=t.consumeArg().tokens,i.length===1&&i[0].text==="["){for(var u="",h=t.expandNextToken();h.text!=="]"&&h.text!=="EOF";)u+=h.text,h=t.expandNextToken();if(!u.match(/^\s*[0-9]+\s*$/))throw new pt("Invalid number of arguments: "+u);l=parseInt(u),i=t.consumeArg().tokens}return s&&n||t.macros.set(a,{tokens:i,numArgs:l}),""},"newcommand");fe("\\newcommand",t=>gA(t,!1,!0,!1));fe("\\renewcommand",t=>gA(t,!0,!1,!1));fe("\\providecommand",t=>gA(t,!0,!0,!0));fe("\\message",t=>{var e=t.consumeArgs(1)[0];return console.log(e.reverse().map(r=>r.text).join("")),""});fe("\\errmessage",t=>{var e=t.consumeArgs(1)[0];return console.error(e.reverse().map(r=>r.text).join("")),""});fe("\\show",t=>{var e=t.popToken(),r=e.text;return console.log(e,t.macros.get(r),yh[r],An.math[r],An.text[r]),""});fe("\\bgroup","{");fe("\\egroup","}");fe("~","\\nobreakspace");fe("\\lq","`");fe("\\rq","'");fe("\\aa","\\r a");fe("\\AA","\\r A");fe("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xA9}");fe("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");fe("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xAE}");fe("\u212C","\\mathscr{B}");fe("\u2130","\\mathscr{E}");fe("\u2131","\\mathscr{F}");fe("\u210B","\\mathscr{H}");fe("\u2110","\\mathscr{I}");fe("\u2112","\\mathscr{L}");fe("\u2133","\\mathscr{M}");fe("\u211B","\\mathscr{R}");fe("\u212D","\\mathfrak{C}");fe("\u210C","\\mathfrak{H}");fe("\u2128","\\mathfrak{Z}");fe("\\Bbbk","\\Bbb{k}");fe("\xB7","\\cdotp");fe("\\llap","\\mathllap{\\textrm{#1}}");fe("\\rlap","\\mathrlap{\\textrm{#1}}");fe("\\clap","\\mathclap{\\textrm{#1}}");fe("\\mathstrut","\\vphantom{(}");fe("\\underbar","\\underline{\\text{#1}}");fe("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');fe("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}");fe("\\ne","\\neq");fe("\u2260","\\neq");fe("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}");fe("\u2209","\\notin");fe("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}");fe("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");fe("\u225A","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");fe("\u225B","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225B}}");fe("\u225D","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225D}}");fe("\u225E","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225E}}");fe("\u225F","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}");fe("\u27C2","\\perp");fe("\u203C","\\mathclose{!\\mkern-0.8mu!}");fe("\u220C","\\notni");fe("\u231C","\\ulcorner");fe("\u231D","\\urcorner");fe("\u231E","\\llcorner");fe("\u231F","\\lrcorner");fe("\xA9","\\copyright");fe("\xAE","\\textregistered");fe("\uFE0F","\\textregistered");fe("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');fe("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');fe("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');fe("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');fe("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");fe("\u22EE","\\vdots");fe("\\varGamma","\\mathit{\\Gamma}");fe("\\varDelta","\\mathit{\\Delta}");fe("\\varTheta","\\mathit{\\Theta}");fe("\\varLambda","\\mathit{\\Lambda}");fe("\\varXi","\\mathit{\\Xi}");fe("\\varPi","\\mathit{\\Pi}");fe("\\varSigma","\\mathit{\\Sigma}");fe("\\varUpsilon","\\mathit{\\Upsilon}");fe("\\varPhi","\\mathit{\\Phi}");fe("\\varPsi","\\mathit{\\Psi}");fe("\\varOmega","\\mathit{\\Omega}");fe("\\substack","\\begin{subarray}{c}#1\\end{subarray}");fe("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");fe("\\boxed","\\fbox{$\\displaystyle{#1}$}");fe("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");fe("\\implies","\\DOTSB\\;\\Longrightarrow\\;");fe("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");fe("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");fe("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");kG={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};fe("\\dots",function(t){var e="\\dotso",r=t.expandAfterFuture().text;return r in kG?e=kG[r]:(r.slice(0,4)==="\\not"||r in An.math&&Jt.contains(["bin","rel"],An.math[r].group))&&(e="\\dotsb"),e});yA={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};fe("\\dotso",function(t){var e=t.future().text;return e in yA?"\\ldots\\,":"\\ldots"});fe("\\dotsc",function(t){var e=t.future().text;return e in yA&&e!==","?"\\ldots\\,":"\\ldots"});fe("\\cdots",function(t){var e=t.future().text;return e in yA?"\\@cdots\\,":"\\@cdots"});fe("\\dotsb","\\cdots");fe("\\dotsm","\\cdots");fe("\\dotsi","\\!\\cdots");fe("\\dotsx","\\ldots\\,");fe("\\DOTSI","\\relax");fe("\\DOTSB","\\relax");fe("\\DOTSX","\\relax");fe("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");fe("\\,","\\tmspace+{3mu}{.1667em}");fe("\\thinspace","\\,");fe("\\>","\\mskip{4mu}");fe("\\:","\\tmspace+{4mu}{.2222em}");fe("\\medspace","\\:");fe("\\;","\\tmspace+{5mu}{.2777em}");fe("\\thickspace","\\;");fe("\\!","\\tmspace-{3mu}{.1667em}");fe("\\negthinspace","\\!");fe("\\negmedspace","\\tmspace-{4mu}{.2222em}");fe("\\negthickspace","\\tmspace-{5mu}{.277em}");fe("\\enspace","\\kern.5em ");fe("\\enskip","\\hskip.5em\\relax");fe("\\quad","\\hskip1em\\relax");fe("\\qquad","\\hskip2em\\relax");fe("\\tag","\\@ifstar\\tag@literal\\tag@paren");fe("\\tag@paren","\\tag@literal{({#1})}");fe("\\tag@literal",t=>{if(t.macros.get("\\df@tag"))throw new pt("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});fe("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");fe("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");fe("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");fe("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");fe("\\newline","\\\\\\relax");fe("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");yV=Et(Jl["Main-Regular"][84][1]-.7*Jl["Main-Regular"][65][1]);fe("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+yV+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");fe("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+yV+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");fe("\\hspace","\\@ifstar\\@hspacer\\@hspace");fe("\\@hspace","\\hskip #1\\relax");fe("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");fe("\\ordinarycolon",":");fe("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");fe("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');fe("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');fe("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');fe("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');fe("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');fe("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');fe("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');fe("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');fe("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');fe("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');fe("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');fe("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');fe("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');fe("\u2237","\\dblcolon");fe("\u2239","\\eqcolon");fe("\u2254","\\coloneqq");fe("\u2255","\\eqqcolon");fe("\u2A74","\\Coloneqq");fe("\\ratio","\\vcentcolon");fe("\\coloncolon","\\dblcolon");fe("\\colonequals","\\coloneqq");fe("\\coloncolonequals","\\Coloneqq");fe("\\equalscolon","\\eqqcolon");fe("\\equalscoloncolon","\\Eqqcolon");fe("\\colonminus","\\coloneq");fe("\\coloncolonminus","\\Coloneq");fe("\\minuscolon","\\eqcolon");fe("\\minuscoloncolon","\\Eqcolon");fe("\\coloncolonapprox","\\Colonapprox");fe("\\coloncolonsim","\\Colonsim");fe("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");fe("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");fe("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");fe("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");fe("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");fe("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");fe("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");fe("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");fe("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");fe("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}");fe("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}");fe("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}");fe("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}");fe("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}");fe("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}");fe("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}");fe("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}");fe("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}");fe("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}");fe("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228A}");fe("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2ACB}");fe("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228B}");fe("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2ACC}");fe("\\imath","\\html@mathml{\\@imath}{\u0131}");fe("\\jmath","\\html@mathml{\\@jmath}{\u0237}");fe("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27E6}}");fe("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27E7}}");fe("\u27E6","\\llbracket");fe("\u27E7","\\rrbracket");fe("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}");fe("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}");fe("\u2983","\\lBrace");fe("\u2984","\\rBrace");fe("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29B5}}");fe("\u29B5","\\minuso");fe("\\darr","\\downarrow");fe("\\dArr","\\Downarrow");fe("\\Darr","\\Downarrow");fe("\\lang","\\langle");fe("\\rang","\\rangle");fe("\\uarr","\\uparrow");fe("\\uArr","\\Uparrow");fe("\\Uarr","\\Uparrow");fe("\\N","\\mathbb{N}");fe("\\R","\\mathbb{R}");fe("\\Z","\\mathbb{Z}");fe("\\alef","\\aleph");fe("\\alefsym","\\aleph");fe("\\Alpha","\\mathrm{A}");fe("\\Beta","\\mathrm{B}");fe("\\bull","\\bullet");fe("\\Chi","\\mathrm{X}");fe("\\clubs","\\clubsuit");fe("\\cnums","\\mathbb{C}");fe("\\Complex","\\mathbb{C}");fe("\\Dagger","\\ddagger");fe("\\diamonds","\\diamondsuit");fe("\\empty","\\emptyset");fe("\\Epsilon","\\mathrm{E}");fe("\\Eta","\\mathrm{H}");fe("\\exist","\\exists");fe("\\harr","\\leftrightarrow");fe("\\hArr","\\Leftrightarrow");fe("\\Harr","\\Leftrightarrow");fe("\\hearts","\\heartsuit");fe("\\image","\\Im");fe("\\infin","\\infty");fe("\\Iota","\\mathrm{I}");fe("\\isin","\\in");fe("\\Kappa","\\mathrm{K}");fe("\\larr","\\leftarrow");fe("\\lArr","\\Leftarrow");fe("\\Larr","\\Leftarrow");fe("\\lrarr","\\leftrightarrow");fe("\\lrArr","\\Leftrightarrow");fe("\\Lrarr","\\Leftrightarrow");fe("\\Mu","\\mathrm{M}");fe("\\natnums","\\mathbb{N}");fe("\\Nu","\\mathrm{N}");fe("\\Omicron","\\mathrm{O}");fe("\\plusmn","\\pm");fe("\\rarr","\\rightarrow");fe("\\rArr","\\Rightarrow");fe("\\Rarr","\\Rightarrow");fe("\\real","\\Re");fe("\\reals","\\mathbb{R}");fe("\\Reals","\\mathbb{R}");fe("\\Rho","\\mathrm{P}");fe("\\sdot","\\cdot");fe("\\sect","\\S");fe("\\spades","\\spadesuit");fe("\\sub","\\subset");fe("\\sube","\\subseteq");fe("\\supe","\\supseteq");fe("\\Tau","\\mathrm{T}");fe("\\thetasym","\\vartheta");fe("\\weierp","\\wp");fe("\\Zeta","\\mathrm{Z}");fe("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");fe("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");fe("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");fe("\\bra","\\mathinner{\\langle{#1}|}");fe("\\ket","\\mathinner{|{#1}\\rangle}");fe("\\braket","\\mathinner{\\langle{#1}\\rangle}");fe("\\Bra","\\left\\langle#1\\right|");fe("\\Ket","\\left|#1\\right\\rangle");vV=o(t=>e=>{var r=e.consumeArg().tokens,n=e.consumeArg().tokens,i=e.consumeArg().tokens,a=e.consumeArg().tokens,s=e.macros.get("|"),l=e.macros.get("\\|");e.macros.beginGroup();var u=o(d=>p=>{t&&(p.macros.set("|",s),i.length&&p.macros.set("\\|",l));var m=d;if(!d&&i.length){var g=p.future();g.text==="|"&&(p.popToken(),m=!0)}return{tokens:m?i:n,numArgs:0}},"midMacro");e.macros.set("|",u(!1)),i.length&&e.macros.set("\\|",u(!0));var h=e.consumeArg().tokens,f=e.expandTokens([...a,...h,...r]);return e.macros.endGroup(),{tokens:f.reverse(),numArgs:0}},"braketHelper");fe("\\bra@ket",vV(!1));fe("\\bra@set",vV(!0));fe("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");fe("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");fe("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");fe("\\angln","{\\angl n}");fe("\\blue","\\textcolor{##6495ed}{#1}");fe("\\orange","\\textcolor{##ffa500}{#1}");fe("\\pink","\\textcolor{##ff00af}{#1}");fe("\\red","\\textcolor{##df0030}{#1}");fe("\\green","\\textcolor{##28ae7b}{#1}");fe("\\gray","\\textcolor{gray}{#1}");fe("\\purple","\\textcolor{##9d38bd}{#1}");fe("\\blueA","\\textcolor{##ccfaff}{#1}");fe("\\blueB","\\textcolor{##80f6ff}{#1}");fe("\\blueC","\\textcolor{##63d9ea}{#1}");fe("\\blueD","\\textcolor{##11accd}{#1}");fe("\\blueE","\\textcolor{##0c7f99}{#1}");fe("\\tealA","\\textcolor{##94fff5}{#1}");fe("\\tealB","\\textcolor{##26edd5}{#1}");fe("\\tealC","\\textcolor{##01d1c1}{#1}");fe("\\tealD","\\textcolor{##01a995}{#1}");fe("\\tealE","\\textcolor{##208170}{#1}");fe("\\greenA","\\textcolor{##b6ffb0}{#1}");fe("\\greenB","\\textcolor{##8af281}{#1}");fe("\\greenC","\\textcolor{##74cf70}{#1}");fe("\\greenD","\\textcolor{##1fab54}{#1}");fe("\\greenE","\\textcolor{##0d923f}{#1}");fe("\\goldA","\\textcolor{##ffd0a9}{#1}");fe("\\goldB","\\textcolor{##ffbb71}{#1}");fe("\\goldC","\\textcolor{##ff9c39}{#1}");fe("\\goldD","\\textcolor{##e07d10}{#1}");fe("\\goldE","\\textcolor{##a75a05}{#1}");fe("\\redA","\\textcolor{##fca9a9}{#1}");fe("\\redB","\\textcolor{##ff8482}{#1}");fe("\\redC","\\textcolor{##f9685d}{#1}");fe("\\redD","\\textcolor{##e84d39}{#1}");fe("\\redE","\\textcolor{##bc2612}{#1}");fe("\\maroonA","\\textcolor{##ffbde0}{#1}");fe("\\maroonB","\\textcolor{##ff92c6}{#1}");fe("\\maroonC","\\textcolor{##ed5fa6}{#1}");fe("\\maroonD","\\textcolor{##ca337c}{#1}");fe("\\maroonE","\\textcolor{##9e034e}{#1}");fe("\\purpleA","\\textcolor{##ddd7ff}{#1}");fe("\\purpleB","\\textcolor{##c6b9fc}{#1}");fe("\\purpleC","\\textcolor{##aa87ff}{#1}");fe("\\purpleD","\\textcolor{##7854ab}{#1}");fe("\\purpleE","\\textcolor{##543b78}{#1}");fe("\\mintA","\\textcolor{##f5f9e8}{#1}");fe("\\mintB","\\textcolor{##edf2df}{#1}");fe("\\mintC","\\textcolor{##e0e5cc}{#1}");fe("\\grayA","\\textcolor{##f6f7f7}{#1}");fe("\\grayB","\\textcolor{##f0f1f2}{#1}");fe("\\grayC","\\textcolor{##e3e5e6}{#1}");fe("\\grayD","\\textcolor{##d6d8da}{#1}");fe("\\grayE","\\textcolor{##babec2}{#1}");fe("\\grayF","\\textcolor{##888d93}{#1}");fe("\\grayG","\\textcolor{##626569}{#1}");fe("\\grayH","\\textcolor{##3b3e40}{#1}");fe("\\grayI","\\textcolor{##21242c}{#1}");fe("\\kaBlue","\\textcolor{##314453}{#1}");fe("\\kaGreen","\\textcolor{##71B307}{#1}");xV={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},tA=class{static{o(this,"MacroExpander")}constructor(e,r,n){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=r,this.expansionCount=0,this.feed(e),this.macros=new eA(c5e,r.macros),this.mode=n,this.stack=[]}feed(e){this.lexer=new A3(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var r,n,i;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;r=this.popToken(),{tokens:i,end:n}=this.consumeArg(["]"])}else({tokens:i,start:r,end:n}=this.consumeArg());return this.pushToken(new _o("EOF",n.loc)),this.pushTokens(i),r.range(n,"")}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var r=[],n=e&&e.length>0;n||this.consumeSpaces();var i=this.future(),a,s=0,l=0;do{if(a=this.popToken(),r.push(a),a.text==="{")++s;else if(a.text==="}"){if(--s,s===-1)throw new pt("Extra }",a)}else if(a.text==="EOF")throw new pt("Unexpected end of input in a macro argument, expected '"+(e&&n?e[l]:"}")+"'",a);if(e&&n)if((s===0||s===1&&e[l]==="{")&&a.text===e[l]){if(++l,l===e.length){r.splice(-l,l);break}}else l=0}while(s!==0||n);return i.text==="{"&&r[r.length-1].text==="}"&&(r.pop(),r.shift()),r.reverse(),{tokens:r,start:i,end:a}}consumeArgs(e,r){if(r){if(r.length!==e+1)throw new pt("The length of delimiters doesn't match the number of args!");for(var n=r[0],i=0;ithis.settings.maxExpand)throw new pt("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var r=this.popToken(),n=r.text,i=r.noexpand?null:this._getExpansion(n);if(i==null||e&&i.unexpandable){if(e&&i==null&&n[0]==="\\"&&!this.isDefined(n))throw new pt("Undefined control sequence: "+n);return this.pushToken(r),!1}this.countExpansion(1);var a=i.tokens,s=this.consumeArgs(i.numArgs,i.delimiters);if(i.numArgs){a=a.slice();for(var l=a.length-1;l>=0;--l){var u=a[l];if(u.text==="#"){if(l===0)throw new pt("Incomplete placeholder at end of macro body",u);if(u=a[--l],u.text==="#")a.splice(l+1,1);else if(/^[1-9]$/.test(u.text))a.splice(l,2,...s[+u.text-1]);else throw new pt("Not a valid argument number",u)}}}return this.pushTokens(a),a.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new _o(e)]):void 0}expandTokens(e){var r=[],n=this.stack.length;for(this.pushTokens(e);this.stack.length>n;)if(this.expandOnce(!0)===!1){var i=this.stack.pop();i.treatAsRelax&&(i.noexpand=!1,i.treatAsRelax=!1),r.push(i)}return this.countExpansion(r.length),r}expandMacroAsText(e){var r=this.expandMacro(e);return r&&r.map(n=>n.text).join("")}_getExpansion(e){var r=this.macros.get(e);if(r==null)return r;if(e.length===1){var n=this.lexer.catcodes[e];if(n!=null&&n!==13)return}var i=typeof r=="function"?r(this):r;if(typeof i=="string"){var a=0;if(i.indexOf("#")!==-1)for(var s=i.replace(/##/g,"");s.indexOf("#"+(a+1))!==-1;)++a;for(var l=new A3(i,this.settings),u=[],h=l.lex();h.text!=="EOF";)u.push(h),h=l.lex();u.reverse();var f={tokens:u,numArgs:a};return f}return i}isDefined(e){return this.macros.has(e)||yh.hasOwnProperty(e)||An.math.hasOwnProperty(e)||An.text.hasOwnProperty(e)||xV.hasOwnProperty(e)}isExpandable(e){var r=this.macros.get(e);return r!=null?typeof r=="string"||typeof r=="function"||!r.unexpandable:yh.hasOwnProperty(e)&&!yh[e].primitive}},EG=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,x3=Object.freeze({"\u208A":"+","\u208B":"-","\u208C":"=","\u208D":"(","\u208E":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1D62":"i","\u2C7C":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209A":"p","\u1D63":"r","\u209B":"s","\u209C":"t","\u1D64":"u","\u1D65":"v","\u2093":"x","\u1D66":"\u03B2","\u1D67":"\u03B3","\u1D68":"\u03C1","\u1D69":"\u03D5","\u1D6A":"\u03C7","\u207A":"+","\u207B":"-","\u207C":"=","\u207D":"(","\u207E":")","\u2070":"0","\xB9":"1","\xB2":"2","\xB3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1D2C":"A","\u1D2E":"B","\u1D30":"D","\u1D31":"E","\u1D33":"G","\u1D34":"H","\u1D35":"I","\u1D36":"J","\u1D37":"K","\u1D38":"L","\u1D39":"M","\u1D3A":"N","\u1D3C":"O","\u1D3E":"P","\u1D3F":"R","\u1D40":"T","\u1D41":"U","\u2C7D":"V","\u1D42":"W","\u1D43":"a","\u1D47":"b","\u1D9C":"c","\u1D48":"d","\u1D49":"e","\u1DA0":"f","\u1D4D":"g",\u02B0:"h","\u2071":"i",\u02B2:"j","\u1D4F":"k",\u02E1:"l","\u1D50":"m",\u207F:"n","\u1D52":"o","\u1D56":"p",\u02B3:"r",\u02E2:"s","\u1D57":"t","\u1D58":"u","\u1D5B":"v",\u02B7:"w",\u02E3:"x",\u02B8:"y","\u1DBB":"z","\u1D5D":"\u03B2","\u1D5E":"\u03B3","\u1D5F":"\u03B4","\u1D60":"\u03D5","\u1D61":"\u03C7","\u1DBF":"\u03B8"}),U7={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030C":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030A":{text:"\\r",math:"\\mathring"},"\u030B":{text:"\\H"},"\u0327":{text:"\\c"}},SG={\u00E1:"a\u0301",\u00E0:"a\u0300",\u00E4:"a\u0308",\u01DF:"a\u0308\u0304",\u00E3:"a\u0303",\u0101:"a\u0304",\u0103:"a\u0306",\u1EAF:"a\u0306\u0301",\u1EB1:"a\u0306\u0300",\u1EB5:"a\u0306\u0303",\u01CE:"a\u030C",\u00E2:"a\u0302",\u1EA5:"a\u0302\u0301",\u1EA7:"a\u0302\u0300",\u1EAB:"a\u0302\u0303",\u0227:"a\u0307",\u01E1:"a\u0307\u0304",\u00E5:"a\u030A",\u01FB:"a\u030A\u0301",\u1E03:"b\u0307",\u0107:"c\u0301",\u1E09:"c\u0327\u0301",\u010D:"c\u030C",\u0109:"c\u0302",\u010B:"c\u0307",\u00E7:"c\u0327",\u010F:"d\u030C",\u1E0B:"d\u0307",\u1E11:"d\u0327",\u00E9:"e\u0301",\u00E8:"e\u0300",\u00EB:"e\u0308",\u1EBD:"e\u0303",\u0113:"e\u0304",\u1E17:"e\u0304\u0301",\u1E15:"e\u0304\u0300",\u0115:"e\u0306",\u1E1D:"e\u0327\u0306",\u011B:"e\u030C",\u00EA:"e\u0302",\u1EBF:"e\u0302\u0301",\u1EC1:"e\u0302\u0300",\u1EC5:"e\u0302\u0303",\u0117:"e\u0307",\u0229:"e\u0327",\u1E1F:"f\u0307",\u01F5:"g\u0301",\u1E21:"g\u0304",\u011F:"g\u0306",\u01E7:"g\u030C",\u011D:"g\u0302",\u0121:"g\u0307",\u0123:"g\u0327",\u1E27:"h\u0308",\u021F:"h\u030C",\u0125:"h\u0302",\u1E23:"h\u0307",\u1E29:"h\u0327",\u00ED:"i\u0301",\u00EC:"i\u0300",\u00EF:"i\u0308",\u1E2F:"i\u0308\u0301",\u0129:"i\u0303",\u012B:"i\u0304",\u012D:"i\u0306",\u01D0:"i\u030C",\u00EE:"i\u0302",\u01F0:"j\u030C",\u0135:"j\u0302",\u1E31:"k\u0301",\u01E9:"k\u030C",\u0137:"k\u0327",\u013A:"l\u0301",\u013E:"l\u030C",\u013C:"l\u0327",\u1E3F:"m\u0301",\u1E41:"m\u0307",\u0144:"n\u0301",\u01F9:"n\u0300",\u00F1:"n\u0303",\u0148:"n\u030C",\u1E45:"n\u0307",\u0146:"n\u0327",\u00F3:"o\u0301",\u00F2:"o\u0300",\u00F6:"o\u0308",\u022B:"o\u0308\u0304",\u00F5:"o\u0303",\u1E4D:"o\u0303\u0301",\u1E4F:"o\u0303\u0308",\u022D:"o\u0303\u0304",\u014D:"o\u0304",\u1E53:"o\u0304\u0301",\u1E51:"o\u0304\u0300",\u014F:"o\u0306",\u01D2:"o\u030C",\u00F4:"o\u0302",\u1ED1:"o\u0302\u0301",\u1ED3:"o\u0302\u0300",\u1ED7:"o\u0302\u0303",\u022F:"o\u0307",\u0231:"o\u0307\u0304",\u0151:"o\u030B",\u1E55:"p\u0301",\u1E57:"p\u0307",\u0155:"r\u0301",\u0159:"r\u030C",\u1E59:"r\u0307",\u0157:"r\u0327",\u015B:"s\u0301",\u1E65:"s\u0301\u0307",\u0161:"s\u030C",\u1E67:"s\u030C\u0307",\u015D:"s\u0302",\u1E61:"s\u0307",\u015F:"s\u0327",\u1E97:"t\u0308",\u0165:"t\u030C",\u1E6B:"t\u0307",\u0163:"t\u0327",\u00FA:"u\u0301",\u00F9:"u\u0300",\u00FC:"u\u0308",\u01D8:"u\u0308\u0301",\u01DC:"u\u0308\u0300",\u01D6:"u\u0308\u0304",\u01DA:"u\u0308\u030C",\u0169:"u\u0303",\u1E79:"u\u0303\u0301",\u016B:"u\u0304",\u1E7B:"u\u0304\u0308",\u016D:"u\u0306",\u01D4:"u\u030C",\u00FB:"u\u0302",\u016F:"u\u030A",\u0171:"u\u030B",\u1E7D:"v\u0303",\u1E83:"w\u0301",\u1E81:"w\u0300",\u1E85:"w\u0308",\u0175:"w\u0302",\u1E87:"w\u0307",\u1E98:"w\u030A",\u1E8D:"x\u0308",\u1E8B:"x\u0307",\u00FD:"y\u0301",\u1EF3:"y\u0300",\u00FF:"y\u0308",\u1EF9:"y\u0303",\u0233:"y\u0304",\u0177:"y\u0302",\u1E8F:"y\u0307",\u1E99:"y\u030A",\u017A:"z\u0301",\u017E:"z\u030C",\u1E91:"z\u0302",\u017C:"z\u0307",\u00C1:"A\u0301",\u00C0:"A\u0300",\u00C4:"A\u0308",\u01DE:"A\u0308\u0304",\u00C3:"A\u0303",\u0100:"A\u0304",\u0102:"A\u0306",\u1EAE:"A\u0306\u0301",\u1EB0:"A\u0306\u0300",\u1EB4:"A\u0306\u0303",\u01CD:"A\u030C",\u00C2:"A\u0302",\u1EA4:"A\u0302\u0301",\u1EA6:"A\u0302\u0300",\u1EAA:"A\u0302\u0303",\u0226:"A\u0307",\u01E0:"A\u0307\u0304",\u00C5:"A\u030A",\u01FA:"A\u030A\u0301",\u1E02:"B\u0307",\u0106:"C\u0301",\u1E08:"C\u0327\u0301",\u010C:"C\u030C",\u0108:"C\u0302",\u010A:"C\u0307",\u00C7:"C\u0327",\u010E:"D\u030C",\u1E0A:"D\u0307",\u1E10:"D\u0327",\u00C9:"E\u0301",\u00C8:"E\u0300",\u00CB:"E\u0308",\u1EBC:"E\u0303",\u0112:"E\u0304",\u1E16:"E\u0304\u0301",\u1E14:"E\u0304\u0300",\u0114:"E\u0306",\u1E1C:"E\u0327\u0306",\u011A:"E\u030C",\u00CA:"E\u0302",\u1EBE:"E\u0302\u0301",\u1EC0:"E\u0302\u0300",\u1EC4:"E\u0302\u0303",\u0116:"E\u0307",\u0228:"E\u0327",\u1E1E:"F\u0307",\u01F4:"G\u0301",\u1E20:"G\u0304",\u011E:"G\u0306",\u01E6:"G\u030C",\u011C:"G\u0302",\u0120:"G\u0307",\u0122:"G\u0327",\u1E26:"H\u0308",\u021E:"H\u030C",\u0124:"H\u0302",\u1E22:"H\u0307",\u1E28:"H\u0327",\u00CD:"I\u0301",\u00CC:"I\u0300",\u00CF:"I\u0308",\u1E2E:"I\u0308\u0301",\u0128:"I\u0303",\u012A:"I\u0304",\u012C:"I\u0306",\u01CF:"I\u030C",\u00CE:"I\u0302",\u0130:"I\u0307",\u0134:"J\u0302",\u1E30:"K\u0301",\u01E8:"K\u030C",\u0136:"K\u0327",\u0139:"L\u0301",\u013D:"L\u030C",\u013B:"L\u0327",\u1E3E:"M\u0301",\u1E40:"M\u0307",\u0143:"N\u0301",\u01F8:"N\u0300",\u00D1:"N\u0303",\u0147:"N\u030C",\u1E44:"N\u0307",\u0145:"N\u0327",\u00D3:"O\u0301",\u00D2:"O\u0300",\u00D6:"O\u0308",\u022A:"O\u0308\u0304",\u00D5:"O\u0303",\u1E4C:"O\u0303\u0301",\u1E4E:"O\u0303\u0308",\u022C:"O\u0303\u0304",\u014C:"O\u0304",\u1E52:"O\u0304\u0301",\u1E50:"O\u0304\u0300",\u014E:"O\u0306",\u01D1:"O\u030C",\u00D4:"O\u0302",\u1ED0:"O\u0302\u0301",\u1ED2:"O\u0302\u0300",\u1ED6:"O\u0302\u0303",\u022E:"O\u0307",\u0230:"O\u0307\u0304",\u0150:"O\u030B",\u1E54:"P\u0301",\u1E56:"P\u0307",\u0154:"R\u0301",\u0158:"R\u030C",\u1E58:"R\u0307",\u0156:"R\u0327",\u015A:"S\u0301",\u1E64:"S\u0301\u0307",\u0160:"S\u030C",\u1E66:"S\u030C\u0307",\u015C:"S\u0302",\u1E60:"S\u0307",\u015E:"S\u0327",\u0164:"T\u030C",\u1E6A:"T\u0307",\u0162:"T\u0327",\u00DA:"U\u0301",\u00D9:"U\u0300",\u00DC:"U\u0308",\u01D7:"U\u0308\u0301",\u01DB:"U\u0308\u0300",\u01D5:"U\u0308\u0304",\u01D9:"U\u0308\u030C",\u0168:"U\u0303",\u1E78:"U\u0303\u0301",\u016A:"U\u0304",\u1E7A:"U\u0304\u0308",\u016C:"U\u0306",\u01D3:"U\u030C",\u00DB:"U\u0302",\u016E:"U\u030A",\u0170:"U\u030B",\u1E7C:"V\u0303",\u1E82:"W\u0301",\u1E80:"W\u0300",\u1E84:"W\u0308",\u0174:"W\u0302",\u1E86:"W\u0307",\u1E8C:"X\u0308",\u1E8A:"X\u0307",\u00DD:"Y\u0301",\u1EF2:"Y\u0300",\u0178:"Y\u0308",\u1EF8:"Y\u0303",\u0232:"Y\u0304",\u0176:"Y\u0302",\u1E8E:"Y\u0307",\u0179:"Z\u0301",\u017D:"Z\u030C",\u1E90:"Z\u0302",\u017B:"Z\u0307",\u03AC:"\u03B1\u0301",\u1F70:"\u03B1\u0300",\u1FB1:"\u03B1\u0304",\u1FB0:"\u03B1\u0306",\u03AD:"\u03B5\u0301",\u1F72:"\u03B5\u0300",\u03AE:"\u03B7\u0301",\u1F74:"\u03B7\u0300",\u03AF:"\u03B9\u0301",\u1F76:"\u03B9\u0300",\u03CA:"\u03B9\u0308",\u0390:"\u03B9\u0308\u0301",\u1FD2:"\u03B9\u0308\u0300",\u1FD1:"\u03B9\u0304",\u1FD0:"\u03B9\u0306",\u03CC:"\u03BF\u0301",\u1F78:"\u03BF\u0300",\u03CD:"\u03C5\u0301",\u1F7A:"\u03C5\u0300",\u03CB:"\u03C5\u0308",\u03B0:"\u03C5\u0308\u0301",\u1FE2:"\u03C5\u0308\u0300",\u1FE1:"\u03C5\u0304",\u1FE0:"\u03C5\u0306",\u03CE:"\u03C9\u0301",\u1F7C:"\u03C9\u0300",\u038E:"\u03A5\u0301",\u1FEA:"\u03A5\u0300",\u03AB:"\u03A5\u0308",\u1FE9:"\u03A5\u0304",\u1FE8:"\u03A5\u0306",\u038F:"\u03A9\u0301",\u1FFA:"\u03A9\u0300"},_3=class t{static{o(this,"Parser")}constructor(e,r){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new tA(e,r,this.mode),this.settings=r,this.leftrightDepth=0}expect(e,r){if(r===void 0&&(r=!0),this.fetch().text!==e)throw new pt("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());r&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var r=this.nextToken;this.consume(),this.gullet.pushToken(new _o("}")),this.gullet.pushTokens(e);var n=this.parseExpression(!1);return this.expect("}"),this.nextToken=r,n}parseExpression(e,r){for(var n=[];;){this.mode==="math"&&this.consumeSpaces();var i=this.fetch();if(t.endOfExpression.indexOf(i.text)!==-1||r&&i.text===r||e&&yh[i.text]&&yh[i.text].infix)break;var a=this.parseAtom(r);if(a){if(a.type==="internal")continue}else break;n.push(a)}return this.mode==="text"&&this.formLigatures(n),this.handleInfixNodes(n)}handleInfixNodes(e){for(var r=-1,n,i=0;i=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+r[0]+'" used in math mode',e);var l=An[this.mode][r].group,u=Qs.range(e),h;if(e3e.hasOwnProperty(l)){var f=l;h={type:"atom",mode:this.mode,family:f,loc:u,text:r}}else h={type:l,mode:this.mode,loc:u,text:r};s=h}else if(r.charCodeAt(0)>=128)this.settings.strict&&(AG(r.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+r[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+r[0]+'"'+(" ("+r.charCodeAt(0)+")"),e)),s={type:"textord",mode:"text",loc:Qs.range(e),text:r};else return null;if(this.consume(),a)for(var d=0;d{e instanceof Element&&e.tagName==="A"&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")??"")}),mh.addHook("afterSanitizeAttributes",e=>{e instanceof Element&&e.tagName==="A"&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)??""),e.removeAttribute(t),e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener"))})}var ud,h5e,f5e,LV,_V,wr,p5e,m5e,g5e,y5e,RV,mu,dr,v5e,x5e,ic,bA,b5e,T5e,DV,P3,yi,hd,Th,Ze,pr=N(()=>{"use strict";L7();ud=//gi,h5e=o(t=>t?RV(t).replace(/\\n/g,"#br#").split("#br#"):[""],"getRows"),f5e=(()=>{let t=!1;return()=>{t||(d5e(),t=!0)}})();o(d5e,"setupDompurifyHooks");LV=o(t=>(f5e(),mh.sanitize(t)),"removeScript"),_V=o((t,e)=>{if(e.flowchart?.htmlLabels!==!1){let r=e.securityLevel;r==="antiscript"||r==="strict"?t=LV(t):r!=="loose"&&(t=RV(t),t=t.replace(//g,">"),t=t.replace(/=/g,"="),t=y5e(t))}return t},"sanitizeMore"),wr=o((t,e)=>t&&(e.dompurifyConfig?t=mh.sanitize(_V(t,e),e.dompurifyConfig).toString():t=mh.sanitize(_V(t,e),{FORBID_TAGS:["style"]}).toString(),t),"sanitizeText"),p5e=o((t,e)=>typeof t=="string"?wr(t,e):t.flat().map(r=>wr(r,e)),"sanitizeTextOrArray"),m5e=o(t=>ud.test(t),"hasBreaks"),g5e=o(t=>t.split(ud),"splitBreaks"),y5e=o(t=>t.replace(/#br#/g,"
    "),"placeholderToBreak"),RV=o(t=>t.replace(ud,"#br#"),"breakToPlaceholder"),mu=o(t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=CSS.escape(e)),e},"getUrl"),dr=o(t=>!(t===!1||["false","null","0"].includes(String(t).trim().toLowerCase())),"evaluate"),v5e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.max(...e)},"getMax"),x5e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.min(...e)},"getMin"),ic=o(function(t){let e=t.split(/(,)/),r=[];for(let n=0;n0&&n+1Math.max(0,t.split(e).length-1),"countOccurrence"),b5e=o((t,e)=>{let r=bA(t,"~"),n=bA(e,"~");return r===1&&n===1},"shouldCombineSets"),T5e=o(t=>{let e=bA(t,"~"),r=!1;if(e<=1)return t;e%2!==0&&t.startsWith("~")&&(t=t.substring(1),r=!0);let n=[...t],i=n.indexOf("~"),a=n.lastIndexOf("~");for(;i!==-1&&a!==-1&&i!==a;)n[i]="<",n[a]=">",i=n.indexOf("~"),a=n.lastIndexOf("~");return r&&n.unshift("~"),n.join("")},"processSet"),DV=o(()=>window.MathMLElement!==void 0,"isMathMLSupported"),P3=/\$\$(.*)\$\$/g,yi=o(t=>(t.match(P3)?.length??0)>0,"hasKatex"),hd=o(async(t,e)=>{t=await Th(t,e);let r=document.createElement("div");r.innerHTML=t,r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0",document.querySelector("body")?.insertAdjacentElement("beforeend",r);let i={width:r.clientWidth,height:r.clientHeight};return r.remove(),i},"calculateMathMLDimensions"),Th=o(async(t,e)=>{if(!yi(t))return t;if(!(DV()||e.legacyMathML||e.forceLegacyMathML))return t.replace(P3,"MathML is unsupported in this environment.");{let{default:r}=await Promise.resolve().then(()=>(AV(),CV)),n=e.forceLegacyMathML||!DV()&&e.legacyMathML?"htmlAndMathml":"mathml";return t.split(ud).map(i=>yi(i)?`

    ${i}
    `:`
    ${i}
    `).join("").replace(P3,(i,a)=>r.renderToString(a,{throwOnError:!0,displayMode:!0,output:n}).replace(/\n/g," ").replace(//g,""))}return t.replace(P3,"Katex is not supported in @mermaid-js/tiny. Please use the full mermaid library.")},"renderKatex"),Ze={getRows:h5e,sanitizeText:wr,sanitizeTextOrArray:p5e,hasBreaks:m5e,splitBreaks:g5e,lineBreakRegex:ud,removeScript:LV,getUrl:mu,evaluate:dr,getMax:v5e,getMin:x5e}});var w5e,k5e,fn,Lo,xi=N(()=>{"use strict";yt();w5e=o(function(t,e){for(let r of e)t.attr(r[0],r[1])},"d3Attrs"),k5e=o(function(t,e,r){let n=new Map;return r?(n.set("width","100%"),n.set("style",`max-width: ${e}px;`)):(n.set("height",t),n.set("width",e)),n},"calculateSvgSizeAttrs"),fn=o(function(t,e,r,n){let i=k5e(e,r,n);w5e(t,i)},"configureSvgSize"),Lo=o(function(t,e,r,n){let i=e.node().getBBox(),a=i.width,s=i.height;X.info(`SVG bounds: ${a}x${s}`,i);let l=0,u=0;X.info(`Graph bounds: ${l}x${u}`,t),l=a+r*2,u=s+r*2,X.info(`Calculated bounds: ${l}x${u}`),fn(e,u,l,n);let h=`${i.x-r} ${i.y-r} ${i.width+2*r} ${i.height+2*r}`;e.attr("viewBox",h)},"setupGraphViewbox")});var B3,E5e,NV,MV,TA=N(()=>{"use strict";yt();B3={},E5e=o((t,e,r)=>{let n="";return t in B3&&B3[t]?n=B3[t](r):X.warn(`No theme found for ${t}`),` & { + font-family: ${r.fontFamily}; + font-size: ${r.fontSize}; + fill: ${r.textColor} + } + @keyframes edge-animation-frame { + from { + stroke-dashoffset: 0; + } + } + @keyframes dash { + to { + stroke-dashoffset: 0; + } + } + & .edge-animation-slow { + stroke-dasharray: 9,5 !important; + stroke-dashoffset: 900; + animation: dash 50s linear infinite; + stroke-linecap: round; + } + & .edge-animation-fast { + stroke-dasharray: 9,5 !important; + stroke-dashoffset: 900; + animation: dash 20s linear infinite; + stroke-linecap: round; + } + /* Classes common for multiple diagrams */ + + & .error-icon { + fill: ${r.errorBkgColor}; + } + & .error-text { + fill: ${r.errorTextColor}; + stroke: ${r.errorTextColor}; + } + + & .edge-thickness-normal { + stroke-width: 1px; + } + & .edge-thickness-thick { + stroke-width: 3.5px + } + & .edge-pattern-solid { + stroke-dasharray: 0; + } + & .edge-thickness-invisible { + stroke-width: 0; + fill: none; + } + & .edge-pattern-dashed{ + stroke-dasharray: 3; + } + .edge-pattern-dotted { + stroke-dasharray: 2; + } + + & .marker { + fill: ${r.lineColor}; + stroke: ${r.lineColor}; + } + & .marker.cross { + stroke: ${r.lineColor}; + } + + & svg { + font-family: ${r.fontFamily}; + font-size: ${r.fontSize}; + } + & p { + margin: 0 + } + + ${n} + + ${e} +`},"getStyles"),NV=o((t,e)=>{e!==void 0&&(B3[t]=e)},"addStylesForDiagram"),MV=E5e});var rv={};ur(rv,{clear:()=>kr,getAccDescription:()=>Rr,getAccTitle:()=>Dr,getDiagramTitle:()=>Nr,setAccDescription:()=>Lr,setAccTitle:()=>Ar,setDiagramTitle:()=>Or});var wA,kA,EA,SA,kr,Ar,Dr,Lr,Rr,Or,Nr,ci=N(()=>{"use strict";pr();mi();wA="",kA="",EA="",SA=o(t=>wr(t,tr()),"sanitizeText"),kr=o(()=>{wA="",EA="",kA=""},"clear"),Ar=o(t=>{wA=SA(t).replace(/^\s+/g,"")},"setAccTitle"),Dr=o(()=>wA,"getAccTitle"),Lr=o(t=>{EA=SA(t).replace(/\n\s+/g,` +`)},"setAccDescription"),Rr=o(()=>EA,"getAccDescription"),Or=o(t=>{kA=SA(t)},"setDiagramTitle"),Nr=o(()=>kA,"getDiagramTitle")});var IV,S5e,me,nv,$3,fd,AA,C5e,F3,dd,iv,CA,Gt=N(()=>{"use strict";rd();yt();mi();pr();xi();TA();ci();IV=X,S5e=Dy,me=tr,nv=a3,$3=ph,fd=o(t=>wr(t,me()),"sanitizeText"),AA=Lo,C5e=o(()=>rv,"getCommonDb"),F3={},dd=o((t,e,r)=>{F3[t]&&IV.warn(`Diagram with id ${t} already registered. Overwriting.`),F3[t]=e,r&&i7(t,r),NV(t,e.styles),e.injectUtils?.(IV,S5e,me,fd,AA,C5e(),()=>{})},"registerDiagram"),iv=o(t=>{if(t in F3)return F3[t];throw new CA(t)},"getDiagram"),CA=class extends Error{static{o(this,"DiagramNotFoundError")}constructor(e){super(`Diagram ${e} not found.`)}}});var ml,wh,is,pl,ac,av,_A,DA,z3,G3,OV,A5e,_5e,D5e,L5e,R5e,N5e,M5e,I5e,O5e,P5e,B5e,F5e,$5e,z5e,G5e,V5e,U5e,PV,H5e,W5e,BV,q5e,Y5e,X5e,j5e,kh,K5e,Q5e,Z5e,J5e,eTe,sv,LA=N(()=>{"use strict";Gt();pr();ci();ml=[],wh=[""],is="global",pl="",ac=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],av=[],_A="",DA=!1,z3=4,G3=2,A5e=o(function(){return OV},"getC4Type"),_5e=o(function(t){OV=wr(t,me())},"setC4Type"),D5e=o(function(t,e,r,n,i,a,s,l,u){if(t==null||e===void 0||e===null||r===void 0||r===null||n===void 0||n===null)return;let h={},f=av.find(d=>d.from===e&&d.to===r);if(f?h=f:av.push(h),h.type=t,h.from=e,h.to=r,h.label={text:n},i==null)h.techn={text:""};else if(typeof i=="object"){let[d,p]=Object.entries(i)[0];h[d]={text:p}}else h.techn={text:i};if(a==null)h.descr={text:""};else if(typeof a=="object"){let[d,p]=Object.entries(a)[0];h[d]={text:p}}else h.descr={text:a};if(typeof s=="object"){let[d,p]=Object.entries(s)[0];h[d]=p}else h.sprite=s;if(typeof l=="object"){let[d,p]=Object.entries(l)[0];h[d]=p}else h.tags=l;if(typeof u=="object"){let[d,p]=Object.entries(u)[0];h[d]=p}else h.link=u;h.wrap=kh()},"addRel"),L5e=o(function(t,e,r,n,i,a,s){if(e===null||r===null)return;let l={},u=ml.find(h=>h.alias===e);if(u&&e===u.alias?l=u:(l.alias=e,ml.push(l)),r==null?l.label={text:""}:l.label={text:r},n==null)l.descr={text:""};else if(typeof n=="object"){let[h,f]=Object.entries(n)[0];l[h]={text:f}}else l.descr={text:n};if(typeof i=="object"){let[h,f]=Object.entries(i)[0];l[h]=f}else l.sprite=i;if(typeof a=="object"){let[h,f]=Object.entries(a)[0];l[h]=f}else l.tags=a;if(typeof s=="object"){let[h,f]=Object.entries(s)[0];l[h]=f}else l.link=s;l.typeC4Shape={text:t},l.parentBoundary=is,l.wrap=kh()},"addPersonOrSystem"),R5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ml.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ml.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=kh(),u.typeC4Shape={text:t},u.parentBoundary=is},"addContainer"),N5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ml.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ml.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=kh(),u.typeC4Shape={text:t},u.parentBoundary=is},"addComponent"),M5e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=ac.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,ac.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"system"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=is,a.wrap=kh(),pl=is,is=t,wh.push(pl)},"addPersonOrSystemBoundary"),I5e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=ac.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,ac.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"container"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=is,a.wrap=kh(),pl=is,is=t,wh.push(pl)},"addContainerBoundary"),O5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ac.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ac.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.type={text:"node"};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.type={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.nodeType=t,u.parentBoundary=is,u.wrap=kh(),pl=is,is=e,wh.push(pl)},"addDeploymentNode"),P5e=o(function(){is=pl,wh.pop(),pl=wh.pop(),wh.push(pl)},"popBoundaryParseStack"),B5e=o(function(t,e,r,n,i,a,s,l,u,h,f){let d=ml.find(p=>p.alias===e);if(!(d===void 0&&(d=ac.find(p=>p.alias===e),d===void 0))){if(r!=null)if(typeof r=="object"){let[p,m]=Object.entries(r)[0];d[p]=m}else d.bgColor=r;if(n!=null)if(typeof n=="object"){let[p,m]=Object.entries(n)[0];d[p]=m}else d.fontColor=n;if(i!=null)if(typeof i=="object"){let[p,m]=Object.entries(i)[0];d[p]=m}else d.borderColor=i;if(a!=null)if(typeof a=="object"){let[p,m]=Object.entries(a)[0];d[p]=m}else d.shadowing=a;if(s!=null)if(typeof s=="object"){let[p,m]=Object.entries(s)[0];d[p]=m}else d.shape=s;if(l!=null)if(typeof l=="object"){let[p,m]=Object.entries(l)[0];d[p]=m}else d.sprite=l;if(u!=null)if(typeof u=="object"){let[p,m]=Object.entries(u)[0];d[p]=m}else d.techn=u;if(h!=null)if(typeof h=="object"){let[p,m]=Object.entries(h)[0];d[p]=m}else d.legendText=h;if(f!=null)if(typeof f=="object"){let[p,m]=Object.entries(f)[0];d[p]=m}else d.legendSprite=f}},"updateElStyle"),F5e=o(function(t,e,r,n,i,a,s){let l=av.find(u=>u.from===e&&u.to===r);if(l!==void 0){if(n!=null)if(typeof n=="object"){let[u,h]=Object.entries(n)[0];l[u]=h}else l.textColor=n;if(i!=null)if(typeof i=="object"){let[u,h]=Object.entries(i)[0];l[u]=h}else l.lineColor=i;if(a!=null)if(typeof a=="object"){let[u,h]=Object.entries(a)[0];l[u]=parseInt(h)}else l.offsetX=parseInt(a);if(s!=null)if(typeof s=="object"){let[u,h]=Object.entries(s)[0];l[u]=parseInt(h)}else l.offsetY=parseInt(s)}},"updateRelStyle"),$5e=o(function(t,e,r){let n=z3,i=G3;if(typeof e=="object"){let a=Object.values(e)[0];n=parseInt(a)}else n=parseInt(e);if(typeof r=="object"){let a=Object.values(r)[0];i=parseInt(a)}else i=parseInt(r);n>=1&&(z3=n),i>=1&&(G3=i)},"updateLayoutConfig"),z5e=o(function(){return z3},"getC4ShapeInRow"),G5e=o(function(){return G3},"getC4BoundaryInRow"),V5e=o(function(){return is},"getCurrentBoundaryParse"),U5e=o(function(){return pl},"getParentBoundaryParse"),PV=o(function(t){return t==null?ml:ml.filter(e=>e.parentBoundary===t)},"getC4ShapeArray"),H5e=o(function(t){return ml.find(e=>e.alias===t)},"getC4Shape"),W5e=o(function(t){return Object.keys(PV(t))},"getC4ShapeKeys"),BV=o(function(t){return t==null?ac:ac.filter(e=>e.parentBoundary===t)},"getBoundaries"),q5e=BV,Y5e=o(function(){return av},"getRels"),X5e=o(function(){return _A},"getTitle"),j5e=o(function(t){DA=t},"setWrap"),kh=o(function(){return DA},"autoWrap"),K5e=o(function(){ml=[],ac=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],pl="",is="global",wh=[""],av=[],wh=[""],_A="",DA=!1,z3=4,G3=2},"clear"),Q5e={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},Z5e={FILLED:0,OPEN:1},J5e={LEFTOF:0,RIGHTOF:1,OVER:2},eTe=o(function(t){_A=wr(t,me())},"setTitle"),sv={addPersonOrSystem:L5e,addPersonOrSystemBoundary:M5e,addContainer:R5e,addContainerBoundary:I5e,addComponent:N5e,addDeploymentNode:O5e,popBoundaryParseStack:P5e,addRel:D5e,updateElStyle:B5e,updateRelStyle:F5e,updateLayoutConfig:$5e,autoWrap:kh,setWrap:j5e,getC4ShapeArray:PV,getC4Shape:H5e,getC4ShapeKeys:W5e,getBoundaries:BV,getBoundarys:q5e,getCurrentBoundaryParse:V5e,getParentBoundaryParse:U5e,getRels:Y5e,getTitle:X5e,getC4Type:A5e,getC4ShapeInRow:z5e,getC4BoundaryInRow:G5e,setAccTitle:Ar,getAccTitle:Dr,getAccDescription:Rr,setAccDescription:Lr,getConfig:o(()=>me().c4,"getConfig"),clear:K5e,LINETYPE:Q5e,ARROWTYPE:Z5e,PLACEMENT:J5e,setTitle:eTe,setC4Type:_5e}});function pd(t,e){return t==null||e==null?NaN:te?1:t>=e?0:NaN}var RA=N(()=>{"use strict";o(pd,"ascending")});function NA(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}var FV=N(()=>{"use strict";o(NA,"descending")});function md(t){let e,r,n;t.length!==2?(e=pd,r=o((l,u)=>pd(t(l),u),"compare2"),n=o((l,u)=>t(l)-u,"delta")):(e=t===pd||t===NA?t:tTe,r=t,n=t);function i(l,u,h=0,f=l.length){if(h>>1;r(l[d],u)<0?h=d+1:f=d}while(h>>1;r(l[d],u)<=0?h=d+1:f=d}while(hh&&n(l[d-1],u)>-n(l[d],u)?d-1:d}return o(s,"center"),{left:i,center:s,right:a}}function tTe(){return 0}var MA=N(()=>{"use strict";RA();FV();o(md,"bisector");o(tTe,"zero")});function IA(t){return t===null?NaN:+t}var $V=N(()=>{"use strict";o(IA,"number")});var zV,GV,rTe,nTe,OA,VV=N(()=>{"use strict";RA();MA();$V();zV=md(pd),GV=zV.right,rTe=zV.left,nTe=md(IA).center,OA=GV});function UV({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):r}function iTe({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function aTe({_intern:t,_key:e},r){let n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function sTe(t){return t!==null&&typeof t=="object"?t.valueOf():t}var C0,HV=N(()=>{"use strict";C0=class extends Map{static{o(this,"InternMap")}constructor(e,r=sTe){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(let[n,i]of e)this.set(n,i)}get(e){return super.get(UV(this,e))}has(e){return super.has(UV(this,e))}set(e,r){return super.set(iTe(this,e),r)}delete(e){return super.delete(aTe(this,e))}};o(UV,"intern_get");o(iTe,"intern_set");o(aTe,"intern_delete");o(sTe,"keyof")});function V3(t,e,r){let n=(e-t)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),s=a>=oTe?10:a>=lTe?5:a>=cTe?2:1,l,u,h;return i<0?(h=Math.pow(10,-i)/s,l=Math.round(t*h),u=Math.round(e*h),l/he&&--u,h=-h):(h=Math.pow(10,i)*s,l=Math.round(t/h),u=Math.round(e/h),l*he&&--u),u0))return[];if(t===e)return[t];let n=e=i))return[];let l=a-i+1,u=new Array(l);if(n)if(s<0)for(let h=0;h{"use strict";oTe=Math.sqrt(50),lTe=Math.sqrt(10),cTe=Math.sqrt(2);o(V3,"tickSpec");o(U3,"ticks");o(ov,"tickIncrement");o(A0,"tickStep")});function H3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}var qV=N(()=>{"use strict";o(H3,"max")});function W3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var YV=N(()=>{"use strict";o(W3,"min")});function q3(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((e-t)/r))|0,a=new Array(i);++n{"use strict";o(q3,"range")});var Eh=N(()=>{"use strict";VV();MA();qV();YV();XV();WV();HV()});function PA(t){return t}var jV=N(()=>{"use strict";o(PA,"default")});function uTe(t){return"translate("+t+",0)"}function hTe(t){return"translate(0,"+t+")"}function fTe(t){return e=>+t(e)}function dTe(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function pTe(){return!this.__axis}function QV(t,e){var r=[],n=null,i=null,a=6,s=6,l=3,u=typeof window<"u"&&window.devicePixelRatio>1?0:.5,h=t===X3||t===Y3?-1:1,f=t===Y3||t===BA?"x":"y",d=t===X3||t===FA?uTe:hTe;function p(m){var g=n??(e.ticks?e.ticks.apply(e,r):e.domain()),y=i??(e.tickFormat?e.tickFormat.apply(e,r):PA),v=Math.max(a,0)+l,x=e.range(),b=+x[0]+u,T=+x[x.length-1]+u,S=(e.bandwidth?dTe:fTe)(e.copy(),u),w=m.selection?m.selection():m,E=w.selectAll(".domain").data([null]),_=w.selectAll(".tick").data(g,e).order(),C=_.exit(),D=_.enter().append("g").attr("class","tick"),O=_.select("line"),R=_.select("text");E=E.merge(E.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),_=_.merge(D),O=O.merge(D.append("line").attr("stroke","currentColor").attr(f+"2",h*a)),R=R.merge(D.append("text").attr("fill","currentColor").attr(f,h*v).attr("dy",t===X3?"0em":t===FA?"0.71em":"0.32em")),m!==w&&(E=E.transition(m),_=_.transition(m),O=O.transition(m),R=R.transition(m),C=C.transition(m).attr("opacity",KV).attr("transform",function(k){return isFinite(k=S(k))?d(k+u):this.getAttribute("transform")}),D.attr("opacity",KV).attr("transform",function(k){var L=this.parentNode.__axis;return d((L&&isFinite(L=L(k))?L:S(k))+u)})),C.remove(),E.attr("d",t===Y3||t===BA?s?"M"+h*s+","+b+"H"+u+"V"+T+"H"+h*s:"M"+u+","+b+"V"+T:s?"M"+b+","+h*s+"V"+u+"H"+T+"V"+h*s:"M"+b+","+u+"H"+T),_.attr("opacity",1).attr("transform",function(k){return d(S(k)+u)}),O.attr(f+"2",h*a),R.attr(f,h*v).text(y),w.filter(pTe).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===BA?"start":t===Y3?"end":"middle"),w.each(function(){this.__axis=S})}return o(p,"axis"),p.scale=function(m){return arguments.length?(e=m,p):e},p.ticks=function(){return r=Array.from(arguments),p},p.tickArguments=function(m){return arguments.length?(r=m==null?[]:Array.from(m),p):r.slice()},p.tickValues=function(m){return arguments.length?(n=m==null?null:Array.from(m),p):n&&n.slice()},p.tickFormat=function(m){return arguments.length?(i=m,p):i},p.tickSize=function(m){return arguments.length?(a=s=+m,p):a},p.tickSizeInner=function(m){return arguments.length?(a=+m,p):a},p.tickSizeOuter=function(m){return arguments.length?(s=+m,p):s},p.tickPadding=function(m){return arguments.length?(l=+m,p):l},p.offset=function(m){return arguments.length?(u=+m,p):u},p}function $A(t){return QV(X3,t)}function zA(t){return QV(FA,t)}var X3,BA,FA,Y3,KV,ZV=N(()=>{"use strict";jV();X3=1,BA=2,FA=3,Y3=4,KV=1e-6;o(uTe,"translateX");o(hTe,"translateY");o(fTe,"number");o(dTe,"center");o(pTe,"entering");o(QV,"axis");o($A,"axisTop");o(zA,"axisBottom")});var JV=N(()=>{"use strict";ZV()});function tU(){for(var t=0,e=arguments.length,r={},n;t=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!e.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}function yTe(t,e){for(var r=0,n=t.length,i;r{"use strict";mTe={value:o(()=>{},"value")};o(tU,"dispatch");o(j3,"Dispatch");o(gTe,"parseTypenames");j3.prototype=tU.prototype={constructor:j3,on:o(function(t,e){var r=this._,n=gTe(t+"",r),i,a=-1,s=n.length;if(arguments.length<2){for(;++a0)for(var r=new Array(i),n=0,i,a;n{"use strict";rU()});var K3,UA,HA=N(()=>{"use strict";K3="http://www.w3.org/1999/xhtml",UA={svg:"http://www.w3.org/2000/svg",xhtml:K3,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"}});function sc(t){var e=t+="",r=e.indexOf(":");return r>=0&&(e=t.slice(0,r))!=="xmlns"&&(t=t.slice(r+1)),UA.hasOwnProperty(e)?{space:UA[e],local:t}:t}var Q3=N(()=>{"use strict";HA();o(sc,"default")});function vTe(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===K3&&e.documentElement.namespaceURI===K3?e.createElement(t):e.createElementNS(r,t)}}function xTe(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function lv(t){var e=sc(t);return(e.local?xTe:vTe)(e)}var WA=N(()=>{"use strict";Q3();HA();o(vTe,"creatorInherit");o(xTe,"creatorFixed");o(lv,"default")});function bTe(){}function Sh(t){return t==null?bTe:function(){return this.querySelector(t)}}var Z3=N(()=>{"use strict";o(bTe,"none");o(Sh,"default")});function qA(t){typeof t!="function"&&(t=Sh(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";gl();Z3();o(qA,"default")});function YA(t){return t==null?[]:Array.isArray(t)?t:Array.from(t)}var iU=N(()=>{"use strict";o(YA,"array")});function TTe(){return[]}function _0(t){return t==null?TTe:function(){return this.querySelectorAll(t)}}var XA=N(()=>{"use strict";o(TTe,"empty");o(_0,"default")});function wTe(t){return function(){return YA(t.apply(this,arguments))}}function jA(t){typeof t=="function"?t=wTe(t):t=_0(t);for(var e=this._groups,r=e.length,n=[],i=[],a=0;a{"use strict";gl();iU();XA();o(wTe,"arrayAll");o(jA,"default")});function D0(t){return function(){return this.matches(t)}}function J3(t){return function(e){return e.matches(t)}}var cv=N(()=>{"use strict";o(D0,"default");o(J3,"childMatcher")});function ETe(t){return function(){return kTe.call(this.children,t)}}function STe(){return this.firstElementChild}function KA(t){return this.select(t==null?STe:ETe(typeof t=="function"?t:J3(t)))}var kTe,sU=N(()=>{"use strict";cv();kTe=Array.prototype.find;o(ETe,"childFind");o(STe,"childFirst");o(KA,"default")});function ATe(){return Array.from(this.children)}function _Te(t){return function(){return CTe.call(this.children,t)}}function QA(t){return this.selectAll(t==null?ATe:_Te(typeof t=="function"?t:J3(t)))}var CTe,oU=N(()=>{"use strict";cv();CTe=Array.prototype.filter;o(ATe,"children");o(_Te,"childrenFilter");o(QA,"default")});function ZA(t){typeof t!="function"&&(t=D0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";gl();cv();o(ZA,"default")});function uv(t){return new Array(t.length)}var JA=N(()=>{"use strict";o(uv,"default")});function e8(){return new ui(this._enter||this._groups.map(uv),this._parents)}function hv(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}var t8=N(()=>{"use strict";JA();gl();o(e8,"default");o(hv,"EnterNode");hv.prototype={constructor:hv,appendChild:o(function(t){return this._parent.insertBefore(t,this._next)},"appendChild"),insertBefore:o(function(t,e){return this._parent.insertBefore(t,e)},"insertBefore"),querySelector:o(function(t){return this._parent.querySelector(t)},"querySelector"),querySelectorAll:o(function(t){return this._parent.querySelectorAll(t)},"querySelectorAll")}});function r8(t){return function(){return t}}var cU=N(()=>{"use strict";o(r8,"default")});function DTe(t,e,r,n,i,a){for(var s=0,l,u=e.length,h=a.length;s=T&&(T=b+1);!(w=v[T])&&++T{"use strict";gl();t8();cU();o(DTe,"bindIndex");o(LTe,"bindKey");o(RTe,"datum");o(n8,"default");o(NTe,"arraylike")});function i8(){return new ui(this._exit||this._groups.map(uv),this._parents)}var hU=N(()=>{"use strict";JA();gl();o(i8,"default")});function a8(t,e,r){var n=this.enter(),i=this,a=this.exit();return typeof t=="function"?(n=t(n),n&&(n=n.selection())):n=n.append(t+""),e!=null&&(i=e(i),i&&(i=i.selection())),r==null?a.remove():r(a),n&&i?n.merge(i).order():i}var fU=N(()=>{"use strict";o(a8,"default")});function s8(t){for(var e=t.selection?t.selection():t,r=this._groups,n=e._groups,i=r.length,a=n.length,s=Math.min(i,a),l=new Array(i),u=0;u{"use strict";gl();o(s8,"default")});function o8(){for(var t=this._groups,e=-1,r=t.length;++e=0;)(s=n[i])&&(a&&s.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(s,a),a=s);return this}var pU=N(()=>{"use strict";o(o8,"default")});function l8(t){t||(t=MTe);function e(d,p){return d&&p?t(d.__data__,p.__data__):!d-!p}o(e,"compareNode");for(var r=this._groups,n=r.length,i=new Array(n),a=0;ae?1:t>=e?0:NaN}var mU=N(()=>{"use strict";gl();o(l8,"default");o(MTe,"ascending")});function c8(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}var gU=N(()=>{"use strict";o(c8,"default")});function u8(){return Array.from(this)}var yU=N(()=>{"use strict";o(u8,"default")});function h8(){for(var t=this._groups,e=0,r=t.length;e{"use strict";o(h8,"default")});function f8(){let t=0;for(let e of this)++t;return t}var xU=N(()=>{"use strict";o(f8,"default")});function d8(){return!this.node()}var bU=N(()=>{"use strict";o(d8,"default")});function p8(t){for(var e=this._groups,r=0,n=e.length;r{"use strict";o(p8,"default")});function ITe(t){return function(){this.removeAttribute(t)}}function OTe(t){return function(){this.removeAttributeNS(t.space,t.local)}}function PTe(t,e){return function(){this.setAttribute(t,e)}}function BTe(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function FTe(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttribute(t):this.setAttribute(t,r)}}function $Te(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,r)}}function m8(t,e){var r=sc(t);if(arguments.length<2){var n=this.node();return r.local?n.getAttributeNS(r.space,r.local):n.getAttribute(r)}return this.each((e==null?r.local?OTe:ITe:typeof e=="function"?r.local?$Te:FTe:r.local?BTe:PTe)(r,e))}var wU=N(()=>{"use strict";Q3();o(ITe,"attrRemove");o(OTe,"attrRemoveNS");o(PTe,"attrConstant");o(BTe,"attrConstantNS");o(FTe,"attrFunction");o($Te,"attrFunctionNS");o(m8,"default")});function fv(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}var g8=N(()=>{"use strict";o(fv,"default")});function zTe(t){return function(){this.style.removeProperty(t)}}function GTe(t,e,r){return function(){this.style.setProperty(t,e,r)}}function VTe(t,e,r){return function(){var n=e.apply(this,arguments);n==null?this.style.removeProperty(t):this.style.setProperty(t,n,r)}}function y8(t,e,r){return arguments.length>1?this.each((e==null?zTe:typeof e=="function"?VTe:GTe)(t,e,r??"")):Ch(this.node(),t)}function Ch(t,e){return t.style.getPropertyValue(e)||fv(t).getComputedStyle(t,null).getPropertyValue(e)}var v8=N(()=>{"use strict";g8();o(zTe,"styleRemove");o(GTe,"styleConstant");o(VTe,"styleFunction");o(y8,"default");o(Ch,"styleValue")});function UTe(t){return function(){delete this[t]}}function HTe(t,e){return function(){this[t]=e}}function WTe(t,e){return function(){var r=e.apply(this,arguments);r==null?delete this[t]:this[t]=r}}function x8(t,e){return arguments.length>1?this.each((e==null?UTe:typeof e=="function"?WTe:HTe)(t,e)):this.node()[t]}var kU=N(()=>{"use strict";o(UTe,"propertyRemove");o(HTe,"propertyConstant");o(WTe,"propertyFunction");o(x8,"default")});function EU(t){return t.trim().split(/^|\s+/)}function b8(t){return t.classList||new SU(t)}function SU(t){this._node=t,this._names=EU(t.getAttribute("class")||"")}function CU(t,e){for(var r=b8(t),n=-1,i=e.length;++n{"use strict";o(EU,"classArray");o(b8,"classList");o(SU,"ClassList");SU.prototype={add:o(function(t){var e=this._names.indexOf(t);e<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},"add"),remove:o(function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},"remove"),contains:o(function(t){return this._names.indexOf(t)>=0},"contains")};o(CU,"classedAdd");o(AU,"classedRemove");o(qTe,"classedTrue");o(YTe,"classedFalse");o(XTe,"classedFunction");o(T8,"default")});function jTe(){this.textContent=""}function KTe(t){return function(){this.textContent=t}}function QTe(t){return function(){var e=t.apply(this,arguments);this.textContent=e??""}}function w8(t){return arguments.length?this.each(t==null?jTe:(typeof t=="function"?QTe:KTe)(t)):this.node().textContent}var DU=N(()=>{"use strict";o(jTe,"textRemove");o(KTe,"textConstant");o(QTe,"textFunction");o(w8,"default")});function ZTe(){this.innerHTML=""}function JTe(t){return function(){this.innerHTML=t}}function ewe(t){return function(){var e=t.apply(this,arguments);this.innerHTML=e??""}}function k8(t){return arguments.length?this.each(t==null?ZTe:(typeof t=="function"?ewe:JTe)(t)):this.node().innerHTML}var LU=N(()=>{"use strict";o(ZTe,"htmlRemove");o(JTe,"htmlConstant");o(ewe,"htmlFunction");o(k8,"default")});function twe(){this.nextSibling&&this.parentNode.appendChild(this)}function E8(){return this.each(twe)}var RU=N(()=>{"use strict";o(twe,"raise");o(E8,"default")});function rwe(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function S8(){return this.each(rwe)}var NU=N(()=>{"use strict";o(rwe,"lower");o(S8,"default")});function C8(t){var e=typeof t=="function"?t:lv(t);return this.select(function(){return this.appendChild(e.apply(this,arguments))})}var MU=N(()=>{"use strict";WA();o(C8,"default")});function nwe(){return null}function A8(t,e){var r=typeof t=="function"?t:lv(t),n=e==null?nwe:typeof e=="function"?e:Sh(e);return this.select(function(){return this.insertBefore(r.apply(this,arguments),n.apply(this,arguments)||null)})}var IU=N(()=>{"use strict";WA();Z3();o(nwe,"constantNull");o(A8,"default")});function iwe(){var t=this.parentNode;t&&t.removeChild(this)}function _8(){return this.each(iwe)}var OU=N(()=>{"use strict";o(iwe,"remove");o(_8,"default")});function awe(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function swe(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function D8(t){return this.select(t?swe:awe)}var PU=N(()=>{"use strict";o(awe,"selection_cloneShallow");o(swe,"selection_cloneDeep");o(D8,"default")});function L8(t){return arguments.length?this.property("__data__",t):this.node().__data__}var BU=N(()=>{"use strict";o(L8,"default")});function owe(t){return function(e){t.call(this,e,this.__data__)}}function lwe(t){return t.trim().split(/^|\s+/).map(function(e){var r="",n=e.indexOf(".");return n>=0&&(r=e.slice(n+1),e=e.slice(0,n)),{type:e,name:r}})}function cwe(t){return function(){var e=this.__on;if(e){for(var r=0,n=-1,i=e.length,a;r{"use strict";o(owe,"contextListener");o(lwe,"parseTypenames");o(cwe,"onRemove");o(uwe,"onAdd");o(R8,"default")});function $U(t,e,r){var n=fv(t),i=n.CustomEvent;typeof i=="function"?i=new i(e,r):(i=n.document.createEvent("Event"),r?(i.initEvent(e,r.bubbles,r.cancelable),i.detail=r.detail):i.initEvent(e,!1,!1)),t.dispatchEvent(i)}function hwe(t,e){return function(){return $U(this,t,e)}}function fwe(t,e){return function(){return $U(this,t,e.apply(this,arguments))}}function N8(t,e){return this.each((typeof e=="function"?fwe:hwe)(t,e))}var zU=N(()=>{"use strict";g8();o($U,"dispatchEvent");o(hwe,"dispatchConstant");o(fwe,"dispatchFunction");o(N8,"default")});function*M8(){for(var t=this._groups,e=0,r=t.length;e{"use strict";o(M8,"default")});function ui(t,e){this._groups=t,this._parents=e}function VU(){return new ui([[document.documentElement]],I8)}function dwe(){return this}var I8,gu,gl=N(()=>{"use strict";nU();aU();sU();oU();lU();uU();t8();hU();fU();dU();pU();mU();gU();yU();vU();xU();bU();TU();wU();v8();kU();_U();DU();LU();RU();NU();MU();IU();OU();PU();BU();FU();zU();GU();I8=[null];o(ui,"Selection");o(VU,"selection");o(dwe,"selection_selection");ui.prototype=VU.prototype={constructor:ui,select:qA,selectAll:jA,selectChild:KA,selectChildren:QA,filter:ZA,data:n8,enter:e8,exit:i8,join:a8,merge:s8,selection:dwe,order:o8,sort:l8,call:c8,nodes:u8,node:h8,size:f8,empty:d8,each:p8,attr:m8,style:y8,property:x8,classed:T8,text:w8,html:k8,raise:E8,lower:S8,append:C8,insert:A8,remove:_8,clone:D8,datum:L8,on:R8,dispatch:N8,[Symbol.iterator]:M8};gu=VU});function Ge(t){return typeof t=="string"?new ui([[document.querySelector(t)]],[document.documentElement]):new ui([[t]],I8)}var UU=N(()=>{"use strict";gl();o(Ge,"default")});var yl=N(()=>{"use strict";cv();Q3();UU();gl();Z3();XA();v8()});var HU=N(()=>{"use strict"});function Ah(t,e,r){t.prototype=e.prototype=r,r.constructor=t}function L0(t,e){var r=Object.create(t.prototype);for(var n in e)r[n]=e[n];return r}var O8=N(()=>{"use strict";o(Ah,"default");o(L0,"extend")});function _h(){}function qU(){return this.rgb().formatHex()}function Twe(){return this.rgb().formatHex8()}function wwe(){return JU(this).formatHsl()}function YU(){return this.rgb().formatRgb()}function xl(t){var e,r;return t=(t+"").trim().toLowerCase(),(e=pwe.exec(t))?(r=e[1].length,e=parseInt(e[1],16),r===6?XU(e):r===3?new ca(e>>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):r===8?e5(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):r===4?e5(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=mwe.exec(t))?new ca(e[1],e[2],e[3],1):(e=gwe.exec(t))?new ca(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=ywe.exec(t))?e5(e[1],e[2],e[3],e[4]):(e=vwe.exec(t))?e5(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=xwe.exec(t))?QU(e[1],e[2]/100,e[3]/100,1):(e=bwe.exec(t))?QU(e[1],e[2]/100,e[3]/100,e[4]):WU.hasOwnProperty(t)?XU(WU[t]):t==="transparent"?new ca(NaN,NaN,NaN,0):null}function XU(t){return new ca(t>>16&255,t>>8&255,t&255,1)}function e5(t,e,r,n){return n<=0&&(t=e=r=NaN),new ca(t,e,r,n)}function B8(t){return t instanceof _h||(t=xl(t)),t?(t=t.rgb(),new ca(t.r,t.g,t.b,t.opacity)):new ca}function N0(t,e,r,n){return arguments.length===1?B8(t):new ca(t,e,r,n??1)}function ca(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function jU(){return`#${gd(this.r)}${gd(this.g)}${gd(this.b)}`}function kwe(){return`#${gd(this.r)}${gd(this.g)}${gd(this.b)}${gd((isNaN(this.opacity)?1:this.opacity)*255)}`}function KU(){let t=n5(this.opacity);return`${t===1?"rgb(":"rgba("}${yd(this.r)}, ${yd(this.g)}, ${yd(this.b)}${t===1?")":`, ${t})`}`}function n5(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function yd(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function gd(t){return t=yd(t),(t<16?"0":"")+t.toString(16)}function QU(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new vl(t,e,r,n)}function JU(t){if(t instanceof vl)return new vl(t.h,t.s,t.l,t.opacity);if(t instanceof _h||(t=xl(t)),!t)return new vl;if(t instanceof vl)return t;t=t.rgb();var e=t.r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),s=NaN,l=a-i,u=(a+i)/2;return l?(e===a?s=(r-n)/l+(r0&&u<1?0:s,new vl(s,l,u,t.opacity)}function eH(t,e,r,n){return arguments.length===1?JU(t):new vl(t,e,r,n??1)}function vl(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function ZU(t){return t=(t||0)%360,t<0?t+360:t}function t5(t){return Math.max(0,Math.min(1,t||0))}function P8(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}var dv,r5,R0,pv,oc,pwe,mwe,gwe,ywe,vwe,xwe,bwe,WU,F8=N(()=>{"use strict";O8();o(_h,"Color");dv=.7,r5=1/dv,R0="\\s*([+-]?\\d+)\\s*",pv="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",oc="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",pwe=/^#([0-9a-f]{3,8})$/,mwe=new RegExp(`^rgb\\(${R0},${R0},${R0}\\)$`),gwe=new RegExp(`^rgb\\(${oc},${oc},${oc}\\)$`),ywe=new RegExp(`^rgba\\(${R0},${R0},${R0},${pv}\\)$`),vwe=new RegExp(`^rgba\\(${oc},${oc},${oc},${pv}\\)$`),xwe=new RegExp(`^hsl\\(${pv},${oc},${oc}\\)$`),bwe=new RegExp(`^hsla\\(${pv},${oc},${oc},${pv}\\)$`),WU={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Ah(_h,xl,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:qU,formatHex:qU,formatHex8:Twe,formatHsl:wwe,formatRgb:YU,toString:YU});o(qU,"color_formatHex");o(Twe,"color_formatHex8");o(wwe,"color_formatHsl");o(YU,"color_formatRgb");o(xl,"color");o(XU,"rgbn");o(e5,"rgba");o(B8,"rgbConvert");o(N0,"rgb");o(ca,"Rgb");Ah(ca,N0,L0(_h,{brighter(t){return t=t==null?r5:Math.pow(r5,t),new ca(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?dv:Math.pow(dv,t),new ca(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new ca(yd(this.r),yd(this.g),yd(this.b),n5(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:jU,formatHex:jU,formatHex8:kwe,formatRgb:KU,toString:KU}));o(jU,"rgb_formatHex");o(kwe,"rgb_formatHex8");o(KU,"rgb_formatRgb");o(n5,"clampa");o(yd,"clampi");o(gd,"hex");o(QU,"hsla");o(JU,"hslConvert");o(eH,"hsl");o(vl,"Hsl");Ah(vl,eH,L0(_h,{brighter(t){return t=t==null?r5:Math.pow(r5,t),new vl(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?dv:Math.pow(dv,t),new vl(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new ca(P8(t>=240?t-240:t+120,i,n),P8(t,i,n),P8(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new vl(ZU(this.h),t5(this.s),t5(this.l),n5(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let t=n5(this.opacity);return`${t===1?"hsl(":"hsla("}${ZU(this.h)}, ${t5(this.s)*100}%, ${t5(this.l)*100}%${t===1?")":`, ${t})`}`}}));o(ZU,"clamph");o(t5,"clampt");o(P8,"hsl2rgb")});var tH,rH,nH=N(()=>{"use strict";tH=Math.PI/180,rH=180/Math.PI});function cH(t){if(t instanceof lc)return new lc(t.l,t.a,t.b,t.opacity);if(t instanceof yu)return uH(t);t instanceof ca||(t=B8(t));var e=V8(t.r),r=V8(t.g),n=V8(t.b),i=$8((.2225045*e+.7168786*r+.0606169*n)/aH),a,s;return e===r&&r===n?a=s=i:(a=$8((.4360747*e+.3850649*r+.1430804*n)/iH),s=$8((.0139322*e+.0971045*r+.7141733*n)/sH)),new lc(116*i-16,500*(a-i),200*(i-s),t.opacity)}function U8(t,e,r,n){return arguments.length===1?cH(t):new lc(t,e,r,n??1)}function lc(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}function $8(t){return t>Ewe?Math.pow(t,1/3):t/lH+oH}function z8(t){return t>M0?t*t*t:lH*(t-oH)}function G8(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function V8(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Swe(t){if(t instanceof yu)return new yu(t.h,t.c,t.l,t.opacity);if(t instanceof lc||(t=cH(t)),t.a===0&&t.b===0)return new yu(NaN,0{"use strict";O8();F8();nH();i5=18,iH=.96422,aH=1,sH=.82521,oH=4/29,M0=6/29,lH=3*M0*M0,Ewe=M0*M0*M0;o(cH,"labConvert");o(U8,"lab");o(lc,"Lab");Ah(lc,U8,L0(_h,{brighter(t){return new lc(this.l+i5*(t??1),this.a,this.b,this.opacity)},darker(t){return new lc(this.l-i5*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return e=iH*z8(e),t=aH*z8(t),r=sH*z8(r),new ca(G8(3.1338561*e-1.6168667*t-.4906146*r),G8(-.9787684*e+1.9161415*t+.033454*r),G8(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}}));o($8,"xyz2lab");o(z8,"lab2xyz");o(G8,"lrgb2rgb");o(V8,"rgb2lrgb");o(Swe,"hclConvert");o(mv,"hcl");o(yu,"Hcl");o(uH,"hcl2lab");Ah(yu,mv,L0(_h,{brighter(t){return new yu(this.h,this.c,this.l+i5*(t??1),this.opacity)},darker(t){return new yu(this.h,this.c,this.l-i5*(t??1),this.opacity)},rgb(){return uH(this).rgb()}}))});var I0=N(()=>{"use strict";F8();hH()});function H8(t,e,r,n,i){var a=t*t,s=a*t;return((1-3*t+3*a-s)*e+(4-6*a+3*s)*r+(1+3*t+3*a-3*s)*n+s*i)/6}function W8(t){var e=t.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],s=n>0?t[n-1]:2*i-a,l=n{"use strict";o(H8,"basis");o(W8,"default")});function Y8(t){var e=t.length;return function(r){var n=Math.floor(((r%=1)<0?++r:r)*e),i=t[(n+e-1)%e],a=t[n%e],s=t[(n+1)%e],l=t[(n+2)%e];return H8((r-n/e)*e,i,a,s,l)}}var fH=N(()=>{"use strict";q8();o(Y8,"default")});var O0,X8=N(()=>{"use strict";O0=o(t=>()=>t,"default")});function dH(t,e){return function(r){return t+r*e}}function Cwe(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}function pH(t,e){var r=e-t;return r?dH(t,r>180||r<-180?r-360*Math.round(r/360):r):O0(isNaN(t)?e:t)}function mH(t){return(t=+t)==1?vu:function(e,r){return r-e?Cwe(e,r,t):O0(isNaN(e)?r:e)}}function vu(t,e){var r=e-t;return r?dH(t,r):O0(isNaN(t)?e:t)}var j8=N(()=>{"use strict";X8();o(dH,"linear");o(Cwe,"exponential");o(pH,"hue");o(mH,"gamma");o(vu,"nogamma")});function gH(t){return function(e){var r=e.length,n=new Array(r),i=new Array(r),a=new Array(r),s,l;for(s=0;s{"use strict";I0();q8();fH();j8();vd=o(function t(e){var r=mH(e);function n(i,a){var s=r((i=N0(i)).r,(a=N0(a)).r),l=r(i.g,a.g),u=r(i.b,a.b),h=vu(i.opacity,a.opacity);return function(f){return i.r=s(f),i.g=l(f),i.b=u(f),i.opacity=h(f),i+""}}return o(n,"rgb"),n.gamma=t,n},"rgbGamma")(1);o(gH,"rgbSpline");Awe=gH(W8),_we=gH(Y8)});function Q8(t,e){e||(e=[]);var r=t?Math.min(e.length,t.length):0,n=e.slice(),i;return function(a){for(i=0;i{"use strict";o(Q8,"default");o(yH,"isNumberArray")});function xH(t,e){var r=e?e.length:0,n=t?Math.min(r,t.length):0,i=new Array(n),a=new Array(r),s;for(s=0;s{"use strict";a5();o(xH,"genericArray")});function Z8(t,e){var r=new Date;return t=+t,e=+e,function(n){return r.setTime(t*(1-n)+e*n),r}}var TH=N(()=>{"use strict";o(Z8,"default")});function Ki(t,e){return t=+t,e=+e,function(r){return t*(1-r)+e*r}}var gv=N(()=>{"use strict";o(Ki,"default")});function J8(t,e){var r={},n={},i;(t===null||typeof t!="object")&&(t={}),(e===null||typeof e!="object")&&(e={});for(i in e)i in t?r[i]=Dh(t[i],e[i]):n[i]=e[i];return function(a){for(i in r)n[i]=r[i](a);return n}}var wH=N(()=>{"use strict";a5();o(J8,"default")});function Dwe(t){return function(){return t}}function Lwe(t){return function(e){return t(e)+""}}function P0(t,e){var r=t_.lastIndex=e_.lastIndex=0,n,i,a,s=-1,l=[],u=[];for(t=t+"",e=e+"";(n=t_.exec(t))&&(i=e_.exec(e));)(a=i.index)>r&&(a=e.slice(r,a),l[s]?l[s]+=a:l[++s]=a),(n=n[0])===(i=i[0])?l[s]?l[s]+=i:l[++s]=i:(l[++s]=null,u.push({i:s,x:Ki(n,i)})),r=e_.lastIndex;return r{"use strict";gv();t_=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,e_=new RegExp(t_.source,"g");o(Dwe,"zero");o(Lwe,"one");o(P0,"default")});function Dh(t,e){var r=typeof e,n;return e==null||r==="boolean"?O0(e):(r==="number"?Ki:r==="string"?(n=xl(e))?(e=n,vd):P0:e instanceof xl?vd:e instanceof Date?Z8:yH(e)?Q8:Array.isArray(e)?xH:typeof e.valueOf!="function"&&typeof e.toString!="function"||isNaN(e)?J8:Ki)(t,e)}var a5=N(()=>{"use strict";I0();K8();bH();TH();gv();wH();r_();X8();vH();o(Dh,"default")});function s5(t,e){return t=+t,e=+e,function(r){return Math.round(t*(1-r)+e*r)}}var kH=N(()=>{"use strict";o(s5,"default")});function l5(t,e,r,n,i,a){var s,l,u;return(s=Math.sqrt(t*t+e*e))&&(t/=s,e/=s),(u=t*r+e*n)&&(r-=t*u,n-=e*u),(l=Math.sqrt(r*r+n*n))&&(r/=l,n/=l,u/=l),t*n{"use strict";EH=180/Math.PI,o5={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};o(l5,"default")});function CH(t){let e=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?o5:l5(e.a,e.b,e.c,e.d,e.e,e.f)}function AH(t){return t==null?o5:(c5||(c5=document.createElementNS("http://www.w3.org/2000/svg","g")),c5.setAttribute("transform",t),(t=c5.transform.baseVal.consolidate())?(t=t.matrix,l5(t.a,t.b,t.c,t.d,t.e,t.f)):o5)}var c5,_H=N(()=>{"use strict";SH();o(CH,"parseCss");o(AH,"parseSvg")});function DH(t,e,r,n){function i(h){return h.length?h.pop()+" ":""}o(i,"pop");function a(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push("translate(",null,e,null,r);g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d||p)&&m.push("translate("+d+e+p+r)}o(a,"translate");function s(h,f,d,p){h!==f?(h-f>180?f+=360:f-h>180&&(h+=360),p.push({i:d.push(i(d)+"rotate(",null,n)-2,x:Ki(h,f)})):f&&d.push(i(d)+"rotate("+f+n)}o(s,"rotate");function l(h,f,d,p){h!==f?p.push({i:d.push(i(d)+"skewX(",null,n)-2,x:Ki(h,f)}):f&&d.push(i(d)+"skewX("+f+n)}o(l,"skewX");function u(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push(i(m)+"scale(",null,",",null,")");g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d!==1||p!==1)&&m.push(i(m)+"scale("+d+","+p+")")}return o(u,"scale"),function(h,f){var d=[],p=[];return h=t(h),f=t(f),a(h.translateX,h.translateY,f.translateX,f.translateY,d,p),s(h.rotate,f.rotate,d,p),l(h.skewX,f.skewX,d,p),u(h.scaleX,h.scaleY,f.scaleX,f.scaleY,d,p),h=f=null,function(m){for(var g=-1,y=p.length,v;++g{"use strict";gv();_H();o(DH,"interpolateTransform");n_=DH(CH,"px, ","px)","deg)"),i_=DH(AH,", ",")",")")});function RH(t){return function(e,r){var n=t((e=mv(e)).h,(r=mv(r)).h),i=vu(e.c,r.c),a=vu(e.l,r.l),s=vu(e.opacity,r.opacity);return function(l){return e.h=n(l),e.c=i(l),e.l=a(l),e.opacity=s(l),e+""}}}var a_,Rwe,NH=N(()=>{"use strict";I0();j8();o(RH,"hcl");a_=RH(pH),Rwe=RH(vu)});var B0=N(()=>{"use strict";a5();gv();kH();r_();LH();K8();NH()});function wv(){return xd||(OH(Nwe),xd=bv.now()+f5)}function Nwe(){xd=0}function Tv(){this._call=this._time=this._next=null}function d5(t,e,r){var n=new Tv;return n.restart(t,e,r),n}function PH(){wv(),++F0;for(var t=u5,e;t;)(e=xd-t._time)>=0&&t._call.call(void 0,e),t=t._next;--F0}function MH(){xd=(h5=bv.now())+f5,F0=vv=0;try{PH()}finally{F0=0,Iwe(),xd=0}}function Mwe(){var t=bv.now(),e=t-h5;e>IH&&(f5-=e,h5=t)}function Iwe(){for(var t,e=u5,r,n=1/0;e;)e._call?(n>e._time&&(n=e._time),t=e,e=e._next):(r=e._next,e._next=null,e=t?t._next=r:u5=r);xv=t,s_(n)}function s_(t){if(!F0){vv&&(vv=clearTimeout(vv));var e=t-xd;e>24?(t<1/0&&(vv=setTimeout(MH,t-bv.now()-f5)),yv&&(yv=clearInterval(yv))):(yv||(h5=bv.now(),yv=setInterval(Mwe,IH)),F0=1,OH(MH))}}var F0,vv,yv,IH,u5,xv,h5,xd,f5,bv,OH,o_=N(()=>{"use strict";F0=0,vv=0,yv=0,IH=1e3,h5=0,xd=0,f5=0,bv=typeof performance=="object"&&performance.now?performance:Date,OH=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};o(wv,"now");o(Nwe,"clearNow");o(Tv,"Timer");Tv.prototype=d5.prototype={constructor:Tv,restart:o(function(t,e,r){if(typeof t!="function")throw new TypeError("callback is not a function");r=(r==null?wv():+r)+(e==null?0:+e),!this._next&&xv!==this&&(xv?xv._next=this:u5=this,xv=this),this._call=t,this._time=r,s_()},"restart"),stop:o(function(){this._call&&(this._call=null,this._time=1/0,s_())},"stop")};o(d5,"timer");o(PH,"timerFlush");o(MH,"wake");o(Mwe,"poke");o(Iwe,"nap");o(s_,"sleep")});function kv(t,e,r){var n=new Tv;return e=e==null?0:+e,n.restart(i=>{n.stop(),t(i+e)},e,r),n}var BH=N(()=>{"use strict";o_();o(kv,"default")});var p5=N(()=>{"use strict";o_();BH()});function xu(t,e,r,n,i,a){var s=t.__transition;if(!s)t.__transition={};else if(r in s)return;Bwe(t,r,{name:e,index:n,group:i,on:Owe,tween:Pwe,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:zH})}function Sv(t,e){var r=zi(t,e);if(r.state>zH)throw new Error("too late; already scheduled");return r}function ua(t,e){var r=zi(t,e);if(r.state>m5)throw new Error("too late; already running");return r}function zi(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function Bwe(t,e,r){var n=t.__transition,i;n[e]=r,r.timer=d5(a,0,r.time);function a(h){r.state=FH,r.timer.restart(s,r.delay,r.time),r.delay<=h&&s(h-r.delay)}o(a,"schedule");function s(h){var f,d,p,m;if(r.state!==FH)return u();for(f in n)if(m=n[f],m.name===r.name){if(m.state===m5)return kv(s);m.state===$H?(m.state=Ev,m.timer.stop(),m.on.call("interrupt",t,t.__data__,m.index,m.group),delete n[f]):+f{"use strict";VA();p5();Owe=GA("start","end","cancel","interrupt"),Pwe=[],zH=0,FH=1,g5=2,m5=3,$H=4,y5=5,Ev=6;o(xu,"default");o(Sv,"init");o(ua,"set");o(zi,"get");o(Bwe,"create")});function Cv(t,e){var r=t.__transition,n,i,a=!0,s;if(r){e=e==null?null:e+"";for(s in r){if((n=r[s]).name!==e){a=!1;continue}i=n.state>g5&&n.state{"use strict";Ds();o(Cv,"default")});function l_(t){return this.each(function(){Cv(this,t)})}var VH=N(()=>{"use strict";GH();o(l_,"default")});function Fwe(t,e){var r,n;return function(){var i=ua(this,t),a=i.tween;if(a!==r){n=r=a;for(var s=0,l=n.length;s{"use strict";Ds();o(Fwe,"tweenRemove");o($we,"tweenFunction");o(c_,"default");o($0,"tweenValue")});function _v(t,e){var r;return(typeof e=="number"?Ki:e instanceof xl?vd:(r=xl(e))?(e=r,vd):P0)(t,e)}var u_=N(()=>{"use strict";I0();B0();o(_v,"default")});function zwe(t){return function(){this.removeAttribute(t)}}function Gwe(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Vwe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttribute(t);return s===i?null:s===n?a:a=e(n=s,r)}}function Uwe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttributeNS(t.space,t.local);return s===i?null:s===n?a:a=e(n=s,r)}}function Hwe(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttribute(t):(s=this.getAttribute(t),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function Wwe(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttributeNS(t.space,t.local):(s=this.getAttributeNS(t.space,t.local),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function h_(t,e){var r=sc(t),n=r==="transform"?i_:_v;return this.attrTween(t,typeof e=="function"?(r.local?Wwe:Hwe)(r,n,$0(this,"attr."+t,e)):e==null?(r.local?Gwe:zwe)(r):(r.local?Uwe:Vwe)(r,n,e))}var UH=N(()=>{"use strict";B0();yl();Av();u_();o(zwe,"attrRemove");o(Gwe,"attrRemoveNS");o(Vwe,"attrConstant");o(Uwe,"attrConstantNS");o(Hwe,"attrFunction");o(Wwe,"attrFunctionNS");o(h_,"default")});function qwe(t,e){return function(r){this.setAttribute(t,e.call(this,r))}}function Ywe(t,e){return function(r){this.setAttributeNS(t.space,t.local,e.call(this,r))}}function Xwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&Ywe(t,a)),r}return o(i,"tween"),i._value=e,i}function jwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&qwe(t,a)),r}return o(i,"tween"),i._value=e,i}function f_(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(e==null)return this.tween(r,null);if(typeof e!="function")throw new Error;var n=sc(t);return this.tween(r,(n.local?Xwe:jwe)(n,e))}var HH=N(()=>{"use strict";yl();o(qwe,"attrInterpolate");o(Ywe,"attrInterpolateNS");o(Xwe,"attrTweenNS");o(jwe,"attrTween");o(f_,"default")});function Kwe(t,e){return function(){Sv(this,t).delay=+e.apply(this,arguments)}}function Qwe(t,e){return e=+e,function(){Sv(this,t).delay=e}}function d_(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Kwe:Qwe)(e,t)):zi(this.node(),e).delay}var WH=N(()=>{"use strict";Ds();o(Kwe,"delayFunction");o(Qwe,"delayConstant");o(d_,"default")});function Zwe(t,e){return function(){ua(this,t).duration=+e.apply(this,arguments)}}function Jwe(t,e){return e=+e,function(){ua(this,t).duration=e}}function p_(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Zwe:Jwe)(e,t)):zi(this.node(),e).duration}var qH=N(()=>{"use strict";Ds();o(Zwe,"durationFunction");o(Jwe,"durationConstant");o(p_,"default")});function eke(t,e){if(typeof e!="function")throw new Error;return function(){ua(this,t).ease=e}}function m_(t){var e=this._id;return arguments.length?this.each(eke(e,t)):zi(this.node(),e).ease}var YH=N(()=>{"use strict";Ds();o(eke,"easeConstant");o(m_,"default")});function tke(t,e){return function(){var r=e.apply(this,arguments);if(typeof r!="function")throw new Error;ua(this,t).ease=r}}function g_(t){if(typeof t!="function")throw new Error;return this.each(tke(this._id,t))}var XH=N(()=>{"use strict";Ds();o(tke,"easeVarying");o(g_,"default")});function y_(t){typeof t!="function"&&(t=D0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";yl();bd();o(y_,"default")});function v_(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,r=t._groups,n=e.length,i=r.length,a=Math.min(n,i),s=new Array(n),l=0;l{"use strict";bd();o(v_,"default")});function rke(t){return(t+"").trim().split(/^|\s+/).every(function(e){var r=e.indexOf(".");return r>=0&&(e=e.slice(0,r)),!e||e==="start"})}function nke(t,e,r){var n,i,a=rke(e)?Sv:ua;return function(){var s=a(this,t),l=s.on;l!==n&&(i=(n=l).copy()).on(e,r),s.on=i}}function x_(t,e){var r=this._id;return arguments.length<2?zi(this.node(),r).on.on(t):this.each(nke(r,t,e))}var QH=N(()=>{"use strict";Ds();o(rke,"start");o(nke,"onFunction");o(x_,"default")});function ike(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}function b_(){return this.on("end.remove",ike(this._id))}var ZH=N(()=>{"use strict";o(ike,"removeFunction");o(b_,"default")});function T_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=Sh(t));for(var n=this._groups,i=n.length,a=new Array(i),s=0;s{"use strict";yl();bd();Ds();o(T_,"default")});function w_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=_0(t));for(var n=this._groups,i=n.length,a=[],s=[],l=0;l{"use strict";yl();bd();Ds();o(w_,"default")});function k_(){return new ake(this._groups,this._parents)}var ake,tW=N(()=>{"use strict";yl();ake=gu.prototype.constructor;o(k_,"default")});function ske(t,e){var r,n,i;return function(){var a=Ch(this,t),s=(this.style.removeProperty(t),Ch(this,t));return a===s?null:a===r&&s===n?i:i=e(r=a,n=s)}}function rW(t){return function(){this.style.removeProperty(t)}}function oke(t,e,r){var n,i=r+"",a;return function(){var s=Ch(this,t);return s===i?null:s===n?a:a=e(n=s,r)}}function lke(t,e,r){var n,i,a;return function(){var s=Ch(this,t),l=r(this),u=l+"";return l==null&&(u=l=(this.style.removeProperty(t),Ch(this,t))),s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l))}}function cke(t,e){var r,n,i,a="style."+e,s="end."+a,l;return function(){var u=ua(this,t),h=u.on,f=u.value[a]==null?l||(l=rW(e)):void 0;(h!==r||i!==f)&&(n=(r=h).copy()).on(s,i=f),u.on=n}}function E_(t,e,r){var n=(t+="")=="transform"?n_:_v;return e==null?this.styleTween(t,ske(t,n)).on("end.style."+t,rW(t)):typeof e=="function"?this.styleTween(t,lke(t,n,$0(this,"style."+t,e))).each(cke(this._id,t)):this.styleTween(t,oke(t,n,e),r).on("end.style."+t,null)}var nW=N(()=>{"use strict";B0();yl();Ds();Av();u_();o(ske,"styleNull");o(rW,"styleRemove");o(oke,"styleConstant");o(lke,"styleFunction");o(cke,"styleMaybeRemove");o(E_,"default")});function uke(t,e,r){return function(n){this.style.setProperty(t,e.call(this,n),r)}}function hke(t,e,r){var n,i;function a(){var s=e.apply(this,arguments);return s!==i&&(n=(i=s)&&uke(t,s,r)),n}return o(a,"tween"),a._value=e,a}function S_(t,e,r){var n="style."+(t+="");if(arguments.length<2)return(n=this.tween(n))&&n._value;if(e==null)return this.tween(n,null);if(typeof e!="function")throw new Error;return this.tween(n,hke(t,e,r??""))}var iW=N(()=>{"use strict";o(uke,"styleInterpolate");o(hke,"styleTween");o(S_,"default")});function fke(t){return function(){this.textContent=t}}function dke(t){return function(){var e=t(this);this.textContent=e??""}}function C_(t){return this.tween("text",typeof t=="function"?dke($0(this,"text",t)):fke(t==null?"":t+""))}var aW=N(()=>{"use strict";Av();o(fke,"textConstant");o(dke,"textFunction");o(C_,"default")});function pke(t){return function(e){this.textContent=t.call(this,e)}}function mke(t){var e,r;function n(){var i=t.apply(this,arguments);return i!==r&&(e=(r=i)&&pke(i)),e}return o(n,"tween"),n._value=t,n}function A_(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(t==null)return this.tween(e,null);if(typeof t!="function")throw new Error;return this.tween(e,mke(t))}var sW=N(()=>{"use strict";o(pke,"textInterpolate");o(mke,"textTween");o(A_,"default")});function __(){for(var t=this._name,e=this._id,r=v5(),n=this._groups,i=n.length,a=0;a{"use strict";bd();Ds();o(__,"default")});function D_(){var t,e,r=this,n=r._id,i=r.size();return new Promise(function(a,s){var l={value:s},u={value:o(function(){--i===0&&a()},"value")};r.each(function(){var h=ua(this,n),f=h.on;f!==t&&(e=(t=f).copy(),e._.cancel.push(l),e._.interrupt.push(l),e._.end.push(u)),h.on=e}),i===0&&a()})}var lW=N(()=>{"use strict";Ds();o(D_,"default")});function as(t,e,r,n){this._groups=t,this._parents=e,this._name=r,this._id=n}function cW(t){return gu().transition(t)}function v5(){return++gke}var gke,bu,bd=N(()=>{"use strict";yl();UH();HH();WH();qH();YH();XH();jH();KH();QH();ZH();JH();eW();tW();nW();iW();aW();sW();oW();Av();lW();gke=0;o(as,"Transition");o(cW,"transition");o(v5,"newId");bu=gu.prototype;as.prototype=cW.prototype={constructor:as,select:T_,selectAll:w_,selectChild:bu.selectChild,selectChildren:bu.selectChildren,filter:y_,merge:v_,selection:k_,transition:__,call:bu.call,nodes:bu.nodes,node:bu.node,size:bu.size,empty:bu.empty,each:bu.each,on:x_,attr:h_,attrTween:f_,style:E_,styleTween:S_,text:C_,textTween:A_,remove:b_,tween:c_,delay:d_,duration:p_,ease:m_,easeVarying:g_,end:D_,[Symbol.iterator]:bu[Symbol.iterator]}});function x5(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var uW=N(()=>{"use strict";o(x5,"cubicInOut")});var L_=N(()=>{"use strict";uW()});function vke(t,e){for(var r;!(r=t.__transition)||!(r=r[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return r}function R_(t){var e,r;t instanceof as?(e=t._id,t=t._name):(e=v5(),(r=yke).time=wv(),t=t==null?null:t+"");for(var n=this._groups,i=n.length,a=0;a{"use strict";bd();Ds();L_();p5();yke={time:null,delay:0,duration:250,ease:x5};o(vke,"inherit");o(R_,"default")});var fW=N(()=>{"use strict";yl();VH();hW();gu.prototype.interrupt=l_;gu.prototype.transition=R_});var b5=N(()=>{"use strict";fW()});var dW=N(()=>{"use strict"});var pW=N(()=>{"use strict"});var mW=N(()=>{"use strict"});function gW(t){return[+t[0],+t[1]]}function xke(t){return[gW(t[0]),gW(t[1])]}function N_(t){return{type:t}}var _gt,Dgt,Lgt,Rgt,Ngt,Mgt,yW=N(()=>{"use strict";b5();dW();pW();mW();({abs:_gt,max:Dgt,min:Lgt}=Math);o(gW,"number1");o(xke,"number2");Rgt={name:"x",handles:["w","e"].map(N_),input:o(function(t,e){return t==null?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},"input"),output:o(function(t){return t&&[t[0][0],t[1][0]]},"output")},Ngt={name:"y",handles:["n","s"].map(N_),input:o(function(t,e){return t==null?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},"input"),output:o(function(t){return t&&[t[0][1],t[1][1]]},"output")},Mgt={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(N_),input:o(function(t){return t==null?null:xke(t)},"input"),output:o(function(t){return t},"output")};o(N_,"type")});var vW=N(()=>{"use strict";yW()});function xW(t){this._+=t[0];for(let e=1,r=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return xW;let r=10**e;return function(n){this._+=n[0];for(let i=1,a=n.length;i{"use strict";M_=Math.PI,I_=2*M_,Td=1e-6,bke=I_-Td;o(xW,"append");o(Tke,"appendRound");wd=class{static{o(this,"Path")}constructor(e){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=e==null?xW:Tke(e)}moveTo(e,r){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(e,r){this._append`L${this._x1=+e},${this._y1=+r}`}quadraticCurveTo(e,r,n,i){this._append`Q${+e},${+r},${this._x1=+n},${this._y1=+i}`}bezierCurveTo(e,r,n,i,a,s){this._append`C${+e},${+r},${+n},${+i},${this._x1=+a},${this._y1=+s}`}arcTo(e,r,n,i,a){if(e=+e,r=+r,n=+n,i=+i,a=+a,a<0)throw new Error(`negative radius: ${a}`);let s=this._x1,l=this._y1,u=n-e,h=i-r,f=s-e,d=l-r,p=f*f+d*d;if(this._x1===null)this._append`M${this._x1=e},${this._y1=r}`;else if(p>Td)if(!(Math.abs(d*u-h*f)>Td)||!a)this._append`L${this._x1=e},${this._y1=r}`;else{let m=n-s,g=i-l,y=u*u+h*h,v=m*m+g*g,x=Math.sqrt(y),b=Math.sqrt(p),T=a*Math.tan((M_-Math.acos((y+p-v)/(2*x*b)))/2),S=T/b,w=T/x;Math.abs(S-1)>Td&&this._append`L${e+S*f},${r+S*d}`,this._append`A${a},${a},0,0,${+(d*m>f*g)},${this._x1=e+w*u},${this._y1=r+w*h}`}}arc(e,r,n,i,a,s){if(e=+e,r=+r,n=+n,s=!!s,n<0)throw new Error(`negative radius: ${n}`);let l=n*Math.cos(i),u=n*Math.sin(i),h=e+l,f=r+u,d=1^s,p=s?i-a:a-i;this._x1===null?this._append`M${h},${f}`:(Math.abs(this._x1-h)>Td||Math.abs(this._y1-f)>Td)&&this._append`L${h},${f}`,n&&(p<0&&(p=p%I_+I_),p>bke?this._append`A${n},${n},0,1,${d},${e-l},${r-u}A${n},${n},0,1,${d},${this._x1=h},${this._y1=f}`:p>Td&&this._append`A${n},${n},0,${+(p>=M_)},${d},${this._x1=e+n*Math.cos(a)},${this._y1=r+n*Math.sin(a)}`)}rect(e,r,n,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}};o(bW,"path");bW.prototype=wd.prototype});var O_=N(()=>{"use strict";TW()});var wW=N(()=>{"use strict"});var kW=N(()=>{"use strict"});var EW=N(()=>{"use strict"});var SW=N(()=>{"use strict"});var CW=N(()=>{"use strict"});var AW=N(()=>{"use strict"});var _W=N(()=>{"use strict"});function P_(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function kd(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}var Dv=N(()=>{"use strict";o(P_,"default");o(kd,"formatDecimalParts")});function bl(t){return t=kd(Math.abs(t)),t?t[1]:NaN}var Lv=N(()=>{"use strict";Dv();o(bl,"default")});function B_(t,e){return function(r,n){for(var i=r.length,a=[],s=0,l=t[0],u=0;i>0&&l>0&&(u+l+1>n&&(l=Math.max(1,n-u)),a.push(r.substring(i-=l,i+l)),!((u+=l+1)>n));)l=t[s=(s+1)%t.length];return a.reverse().join(e)}}var DW=N(()=>{"use strict";o(B_,"default")});function F_(t){return function(e){return e.replace(/[0-9]/g,function(r){return t[+r]})}}var LW=N(()=>{"use strict";o(F_,"default")});function Lh(t){if(!(e=wke.exec(t)))throw new Error("invalid format: "+t);var e;return new T5({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function T5(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}var wke,$_=N(()=>{"use strict";wke=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;o(Lh,"formatSpecifier");Lh.prototype=T5.prototype;o(T5,"FormatSpecifier");T5.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type}});function z_(t){e:for(var e=t.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?t.slice(0,n)+t.slice(i+1):t}var RW=N(()=>{"use strict";o(z_,"default")});function V_(t,e){var r=kd(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(G_=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=n.length;return a===s?n:a>s?n+new Array(a-s+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+kd(t,Math.max(0,e+a-1))[0]}var G_,U_=N(()=>{"use strict";Dv();o(V_,"default")});function w5(t,e){var r=kd(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}var NW=N(()=>{"use strict";Dv();o(w5,"default")});var H_,MW=N(()=>{"use strict";Dv();U_();NW();H_={"%":o((t,e)=>(t*100).toFixed(e),"%"),b:o(t=>Math.round(t).toString(2),"b"),c:o(t=>t+"","c"),d:P_,e:o((t,e)=>t.toExponential(e),"e"),f:o((t,e)=>t.toFixed(e),"f"),g:o((t,e)=>t.toPrecision(e),"g"),o:o(t=>Math.round(t).toString(8),"o"),p:o((t,e)=>w5(t*100,e),"p"),r:w5,s:V_,X:o(t=>Math.round(t).toString(16).toUpperCase(),"X"),x:o(t=>Math.round(t).toString(16),"x")}});function k5(t){return t}var IW=N(()=>{"use strict";o(k5,"default")});function W_(t){var e=t.grouping===void 0||t.thousands===void 0?k5:B_(OW.call(t.grouping,Number),t.thousands+""),r=t.currency===void 0?"":t.currency[0]+"",n=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?k5:F_(OW.call(t.numerals,String)),s=t.percent===void 0?"%":t.percent+"",l=t.minus===void 0?"\u2212":t.minus+"",u=t.nan===void 0?"NaN":t.nan+"";function h(d){d=Lh(d);var p=d.fill,m=d.align,g=d.sign,y=d.symbol,v=d.zero,x=d.width,b=d.comma,T=d.precision,S=d.trim,w=d.type;w==="n"?(b=!0,w="g"):H_[w]||(T===void 0&&(T=12),S=!0,w="g"),(v||p==="0"&&m==="=")&&(v=!0,p="0",m="=");var E=y==="$"?r:y==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",_=y==="$"?n:/[%p]/.test(w)?s:"",C=H_[w],D=/[defgprs%]/.test(w);T=T===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,T)):Math.max(0,Math.min(20,T));function O(R){var k=E,L=_,A,I,M;if(w==="c")L=C(R)+L,R="";else{R=+R;var P=R<0||1/R<0;if(R=isNaN(R)?u:C(Math.abs(R),T),S&&(R=z_(R)),P&&+R==0&&g!=="+"&&(P=!1),k=(P?g==="("?g:l:g==="-"||g==="("?"":g)+k,L=(w==="s"?PW[8+G_/3]:"")+L+(P&&g==="("?")":""),D){for(A=-1,I=R.length;++AM||M>57){L=(M===46?i+R.slice(A+1):R.slice(A))+L,R=R.slice(0,A);break}}}b&&!v&&(R=e(R,1/0));var B=k.length+R.length+L.length,F=B>1)+k+R+L+F.slice(B);break;default:R=F+k+R+L;break}return a(R)}return o(O,"format"),O.toString=function(){return d+""},O}o(h,"newFormat");function f(d,p){var m=h((d=Lh(d),d.type="f",d)),g=Math.max(-8,Math.min(8,Math.floor(bl(p)/3)))*3,y=Math.pow(10,-g),v=PW[8+g/3];return function(x){return m(y*x)+v}}return o(f,"formatPrefix"),{format:h,formatPrefix:f}}var OW,PW,BW=N(()=>{"use strict";Lv();DW();LW();$_();RW();MW();U_();IW();OW=Array.prototype.map,PW=["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"];o(W_,"default")});function q_(t){return E5=W_(t),cc=E5.format,S5=E5.formatPrefix,E5}var E5,cc,S5,FW=N(()=>{"use strict";BW();q_({thousands:",",grouping:[3],currency:["$",""]});o(q_,"defaultLocale")});function C5(t){return Math.max(0,-bl(Math.abs(t)))}var $W=N(()=>{"use strict";Lv();o(C5,"default")});function A5(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(bl(e)/3)))*3-bl(Math.abs(t)))}var zW=N(()=>{"use strict";Lv();o(A5,"default")});function _5(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,bl(e)-bl(t))+1}var GW=N(()=>{"use strict";Lv();o(_5,"default")});var Y_=N(()=>{"use strict";FW();$_();$W();zW();GW()});var VW=N(()=>{"use strict"});function kke(t){var e=0,r=t.children,n=r&&r.length;if(!n)e=1;else for(;--n>=0;)e+=r[n].value;t.value=e}function X_(){return this.eachAfter(kke)}var UW=N(()=>{"use strict";o(kke,"count");o(X_,"default")});function j_(t,e){let r=-1;for(let n of this)t.call(e,n,++r,this);return this}var HW=N(()=>{"use strict";o(j_,"default")});function K_(t,e){for(var r=this,n=[r],i,a,s=-1;r=n.pop();)if(t.call(e,r,++s,this),i=r.children)for(a=i.length-1;a>=0;--a)n.push(i[a]);return this}var WW=N(()=>{"use strict";o(K_,"default")});function Q_(t,e){for(var r=this,n=[r],i=[],a,s,l,u=-1;r=n.pop();)if(i.push(r),a=r.children)for(s=0,l=a.length;s{"use strict";o(Q_,"default")});function Z_(t,e){let r=-1;for(let n of this)if(t.call(e,n,++r,this))return n}var YW=N(()=>{"use strict";o(Z_,"default")});function J_(t){return this.eachAfter(function(e){for(var r=+t(e.data)||0,n=e.children,i=n&&n.length;--i>=0;)r+=n[i].value;e.value=r})}var XW=N(()=>{"use strict";o(J_,"default")});function eD(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}var jW=N(()=>{"use strict";o(eD,"default")});function tD(t){for(var e=this,r=Eke(e,t),n=[e];e!==r;)e=e.parent,n.push(e);for(var i=n.length;t!==r;)n.splice(i,0,t),t=t.parent;return n}function Eke(t,e){if(t===e)return t;var r=t.ancestors(),n=e.ancestors(),i=null;for(t=r.pop(),e=n.pop();t===e;)i=t,t=r.pop(),e=n.pop();return i}var KW=N(()=>{"use strict";o(tD,"default");o(Eke,"leastCommonAncestor")});function rD(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}var QW=N(()=>{"use strict";o(rD,"default")});function nD(){return Array.from(this)}var ZW=N(()=>{"use strict";o(nD,"default")});function iD(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}var JW=N(()=>{"use strict";o(iD,"default")});function aD(){var t=this,e=[];return t.each(function(r){r!==t&&e.push({source:r.parent,target:r})}),e}var eq=N(()=>{"use strict";o(aD,"default")});function*sD(){var t=this,e,r=[t],n,i,a;do for(e=r.reverse(),r=[];t=e.pop();)if(yield t,n=t.children)for(i=0,a=n.length;i{"use strict";o(sD,"default")});function z0(t,e){t instanceof Map?(t=[void 0,t],e===void 0&&(e=Ake)):e===void 0&&(e=Cke);for(var r=new Rv(t),n,i=[r],a,s,l,u;n=i.pop();)if((s=e(n.data))&&(u=(s=Array.from(s)).length))for(n.children=s,l=u-1;l>=0;--l)i.push(a=s[l]=new Rv(s[l])),a.parent=n,a.depth=n.depth+1;return r.eachBefore(Dke)}function Ske(){return z0(this).eachBefore(_ke)}function Cke(t){return t.children}function Ake(t){return Array.isArray(t)?t[1]:null}function _ke(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function Dke(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Rv(t){this.data=t,this.depth=this.height=0,this.parent=null}var rq=N(()=>{"use strict";UW();HW();WW();qW();YW();XW();jW();KW();QW();ZW();JW();eq();tq();o(z0,"hierarchy");o(Ske,"node_copy");o(Cke,"objectChildren");o(Ake,"mapChildren");o(_ke,"copyData");o(Dke,"computeHeight");o(Rv,"Node");Rv.prototype=z0.prototype={constructor:Rv,count:X_,each:j_,eachAfter:Q_,eachBefore:K_,find:Z_,sum:J_,sort:eD,path:tD,ancestors:rD,descendants:nD,leaves:iD,links:aD,copy:Ske,[Symbol.iterator]:sD}});function nq(t){if(typeof t!="function")throw new Error;return t}var iq=N(()=>{"use strict";o(nq,"required")});function G0(){return 0}function Ed(t){return function(){return t}}var aq=N(()=>{"use strict";o(G0,"constantZero");o(Ed,"default")});function oD(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)}var sq=N(()=>{"use strict";o(oD,"default")});function lD(t,e,r,n,i){for(var a=t.children,s,l=-1,u=a.length,h=t.value&&(n-e)/t.value;++l{"use strict";o(lD,"default")});function cD(t,e,r,n,i){for(var a=t.children,s,l=-1,u=a.length,h=t.value&&(i-r)/t.value;++l{"use strict";o(cD,"default")});function Rke(t,e,r,n,i,a){for(var s=[],l=e.children,u,h,f=0,d=0,p=l.length,m,g,y=e.value,v,x,b,T,S,w,E;fb&&(b=h),E=v*v*w,T=Math.max(b/E,E/x),T>S){v-=h;break}S=T}s.push(u={value:v,dice:m{"use strict";oq();lq();Lke=(1+Math.sqrt(5))/2;o(Rke,"squarifyRatio");cq=o(function t(e){function r(n,i,a,s,l){Rke(e,n,i,a,s,l)}return o(r,"squarify"),r.ratio=function(n){return t((n=+n)>1?n:1)},r},"custom")(Lke)});function D5(){var t=cq,e=!1,r=1,n=1,i=[0],a=G0,s=G0,l=G0,u=G0,h=G0;function f(p){return p.x0=p.y0=0,p.x1=r,p.y1=n,p.eachBefore(d),i=[0],e&&p.eachBefore(oD),p}o(f,"treemap");function d(p){var m=i[p.depth],g=p.x0+m,y=p.y0+m,v=p.x1-m,x=p.y1-m;v{"use strict";sq();uq();iq();aq();o(D5,"default")});var fq=N(()=>{"use strict";rq();hq()});var dq=N(()=>{"use strict"});var pq=N(()=>{"use strict"});function Rh(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}var Nv=N(()=>{"use strict";o(Rh,"initRange")});function Js(){var t=new C0,e=[],r=[],n=uD;function i(a){let s=t.get(a);if(s===void 0){if(n!==uD)return n;t.set(a,s=e.push(a)-1)}return r[s%r.length]}return o(i,"scale"),i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new C0;for(let s of a)t.has(s)||t.set(s,e.push(s)-1);return i},i.range=function(a){return arguments.length?(r=Array.from(a),i):r.slice()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return Js(e,r).unknown(n)},Rh.apply(i,arguments),i}var uD,hD=N(()=>{"use strict";Eh();Nv();uD=Symbol("implicit");o(Js,"ordinal")});function V0(){var t=Js().unknown(void 0),e=t.domain,r=t.range,n=0,i=1,a,s,l=!1,u=0,h=0,f=.5;delete t.unknown;function d(){var p=e().length,m=i{"use strict";Eh();Nv();hD();o(V0,"band")});function fD(t){return function(){return t}}var gq=N(()=>{"use strict";o(fD,"constants")});function dD(t){return+t}var yq=N(()=>{"use strict";o(dD,"number")});function U0(t){return t}function pD(t,e){return(e-=t=+t)?function(r){return(r-t)/e}:fD(isNaN(e)?NaN:.5)}function Nke(t,e){var r;return t>e&&(r=t,t=e,e=r),function(n){return Math.max(t,Math.min(e,n))}}function Mke(t,e,r){var n=t[0],i=t[1],a=e[0],s=e[1];return i2?Ike:Mke,u=h=null,d}o(f,"rescale");function d(p){return p==null||isNaN(p=+p)?a:(u||(u=l(t.map(n),e,r)))(n(s(p)))}return o(d,"scale"),d.invert=function(p){return s(i((h||(h=l(e,t.map(n),Ki)))(p)))},d.domain=function(p){return arguments.length?(t=Array.from(p,dD),f()):t.slice()},d.range=function(p){return arguments.length?(e=Array.from(p),f()):e.slice()},d.rangeRound=function(p){return e=Array.from(p),r=s5,f()},d.clamp=function(p){return arguments.length?(s=p?!0:U0,f()):s!==U0},d.interpolate=function(p){return arguments.length?(r=p,f()):r},d.unknown=function(p){return arguments.length?(a=p,d):a},function(p,m){return n=p,i=m,f()}}function Mv(){return Oke()(U0,U0)}var vq,mD=N(()=>{"use strict";Eh();B0();gq();yq();vq=[0,1];o(U0,"identity");o(pD,"normalize");o(Nke,"clamper");o(Mke,"bimap");o(Ike,"polymap");o(L5,"copy");o(Oke,"transformer");o(Mv,"continuous")});function gD(t,e,r,n){var i=A0(t,e,r),a;switch(n=Lh(n??",f"),n.type){case"s":{var s=Math.max(Math.abs(t),Math.abs(e));return n.precision==null&&!isNaN(a=A5(i,s))&&(n.precision=a),S5(n,s)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=_5(i,Math.max(Math.abs(t),Math.abs(e))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=C5(i))&&(n.precision=a-(n.type==="%")*2);break}}return cc(n)}var xq=N(()=>{"use strict";Eh();Y_();o(gD,"tickFormat")});function Pke(t){var e=t.domain;return t.ticks=function(r){var n=e();return U3(n[0],n[n.length-1],r??10)},t.tickFormat=function(r,n){var i=e();return gD(i[0],i[i.length-1],r??10,n)},t.nice=function(r){r==null&&(r=10);var n=e(),i=0,a=n.length-1,s=n[i],l=n[a],u,h,f=10;for(l0;){if(h=ov(s,l,r),h===u)return n[i]=s,n[a]=l,e(n);if(h>0)s=Math.floor(s/h)*h,l=Math.ceil(l/h)*h;else if(h<0)s=Math.ceil(s*h)/h,l=Math.floor(l*h)/h;else break;u=h}return t},t}function Tl(){var t=Mv();return t.copy=function(){return L5(t,Tl())},Rh.apply(t,arguments),Pke(t)}var bq=N(()=>{"use strict";Eh();mD();Nv();xq();o(Pke,"linearish");o(Tl,"linear")});function yD(t,e){t=t.slice();var r=0,n=t.length-1,i=t[r],a=t[n],s;return a{"use strict";o(yD,"nice")});function xn(t,e,r,n){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return o(i,"interval"),i.floor=a=>(t(a=new Date(+a)),a),i.ceil=a=>(t(a=new Date(a-1)),e(a,1),t(a),a),i.round=a=>{let s=i(a),l=i.ceil(a);return a-s(e(a=new Date(+a),s==null?1:Math.floor(s)),a),i.range=(a,s,l)=>{let u=[];if(a=i.ceil(a),l=l==null?1:Math.floor(l),!(a0))return u;let h;do u.push(h=new Date(+a)),e(a,l),t(a);while(hxn(s=>{if(s>=s)for(;t(s),!a(s);)s.setTime(s-1)},(s,l)=>{if(s>=s)if(l<0)for(;++l<=0;)for(;e(s,-1),!a(s););else for(;--l>=0;)for(;e(s,1),!a(s););}),r&&(i.count=(a,s)=>(vD.setTime(+a),xD.setTime(+s),t(vD),t(xD),Math.floor(r(vD,xD))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?s=>n(s)%a===0:s=>i.count(0,s)%a===0):i)),i}var vD,xD,Tu=N(()=>{"use strict";vD=new Date,xD=new Date;o(xn,"timeInterval")});var uc,wq,bD=N(()=>{"use strict";Tu();uc=xn(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);uc.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?xn(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):uc);wq=uc.range});var eo,kq,TD=N(()=>{"use strict";Tu();eo=xn(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*1e3)},(t,e)=>(e-t)/1e3,t=>t.getUTCSeconds()),kq=eo.range});var wu,Bke,R5,Fke,wD=N(()=>{"use strict";Tu();wu=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getMinutes()),Bke=wu.range,R5=xn(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getUTCMinutes()),Fke=R5.range});var ku,$ke,N5,zke,kD=N(()=>{"use strict";Tu();ku=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3-t.getMinutes()*6e4)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getHours()),$ke=ku.range,N5=xn(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getUTCHours()),zke=N5.range});var Ro,Gke,Ov,Vke,M5,Uke,ED=N(()=>{"use strict";Tu();Ro=xn(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5,t=>t.getDate()-1),Gke=Ro.range,Ov=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>t.getUTCDate()-1),Vke=Ov.range,M5=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>Math.floor(t/864e5)),Uke=M5.range});function Ad(t){return xn(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,r)=>{e.setDate(e.getDate()+r*7)},(e,r)=>(r-e-(r.getTimezoneOffset()-e.getTimezoneOffset())*6e4)/6048e5)}function _d(t){return xn(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCDate(e.getUTCDate()+r*7)},(e,r)=>(r-e)/6048e5)}var wl,Nh,I5,O5,fc,P5,B5,Sq,Hke,Wke,qke,Yke,Xke,jke,Dd,H0,Cq,Aq,Mh,_q,Dq,Lq,Kke,Qke,Zke,Jke,eEe,tEe,SD=N(()=>{"use strict";Tu();o(Ad,"timeWeekday");wl=Ad(0),Nh=Ad(1),I5=Ad(2),O5=Ad(3),fc=Ad(4),P5=Ad(5),B5=Ad(6),Sq=wl.range,Hke=Nh.range,Wke=I5.range,qke=O5.range,Yke=fc.range,Xke=P5.range,jke=B5.range;o(_d,"utcWeekday");Dd=_d(0),H0=_d(1),Cq=_d(2),Aq=_d(3),Mh=_d(4),_q=_d(5),Dq=_d(6),Lq=Dd.range,Kke=H0.range,Qke=Cq.range,Zke=Aq.range,Jke=Mh.range,eEe=_q.range,tEe=Dq.range});var Eu,rEe,F5,nEe,CD=N(()=>{"use strict";Tu();Eu=xn(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth()),rEe=Eu.range,F5=xn(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth()),nEe=F5.range});var to,iEe,kl,aEe,AD=N(()=>{"use strict";Tu();to=xn(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());to.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)});iEe=to.range,kl=xn(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());kl.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)});aEe=kl.range});function Nq(t,e,r,n,i,a){let s=[[eo,1,1e3],[eo,5,5*1e3],[eo,15,15*1e3],[eo,30,30*1e3],[a,1,6e4],[a,5,5*6e4],[a,15,15*6e4],[a,30,30*6e4],[i,1,36e5],[i,3,3*36e5],[i,6,6*36e5],[i,12,12*36e5],[n,1,864e5],[n,2,2*864e5],[r,1,6048e5],[e,1,2592e6],[e,3,3*2592e6],[t,1,31536e6]];function l(h,f,d){let p=fv).right(s,p);if(m===s.length)return t.every(A0(h/31536e6,f/31536e6,d));if(m===0)return uc.every(Math.max(A0(h,f,d),1));let[g,y]=s[p/s[m-1][2]{"use strict";Eh();bD();TD();wD();kD();ED();SD();CD();AD();o(Nq,"ticker");[oEe,lEe]=Nq(kl,F5,Dd,M5,N5,R5),[_D,DD]=Nq(to,Eu,wl,Ro,ku,wu)});var $5=N(()=>{"use strict";bD();TD();wD();kD();ED();SD();CD();AD();Mq()});function LD(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function RD(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Pv(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}function ND(t){var e=t.dateTime,r=t.date,n=t.time,i=t.periods,a=t.days,s=t.shortDays,l=t.months,u=t.shortMonths,h=Bv(i),f=Fv(i),d=Bv(a),p=Fv(a),m=Bv(s),g=Fv(s),y=Bv(l),v=Fv(l),x=Bv(u),b=Fv(u),T={a:P,A:B,b:F,B:z,c:null,d:$q,e:$q,f:REe,g:GEe,G:UEe,H:_Ee,I:DEe,j:LEe,L:Hq,m:NEe,M:MEe,p:$,q:U,Q:Vq,s:Uq,S:IEe,u:OEe,U:PEe,V:BEe,w:FEe,W:$Ee,x:null,X:null,y:zEe,Y:VEe,Z:HEe,"%":Gq},S={a:K,A:ee,b:Y,B:ce,c:null,d:zq,e:zq,f:XEe,g:iSe,G:sSe,H:WEe,I:qEe,j:YEe,L:qq,m:jEe,M:KEe,p:Z,q:ue,Q:Vq,s:Uq,S:QEe,u:ZEe,U:JEe,V:eSe,w:tSe,W:rSe,x:null,X:null,y:nSe,Y:aSe,Z:oSe,"%":Gq},w={a:O,A:R,b:k,B:L,c:A,d:Bq,e:Bq,f:EEe,g:Pq,G:Oq,H:Fq,I:Fq,j:bEe,L:kEe,m:xEe,M:TEe,p:D,q:vEe,Q:CEe,s:AEe,S:wEe,u:dEe,U:pEe,V:mEe,w:fEe,W:gEe,x:I,X:M,y:Pq,Y:Oq,Z:yEe,"%":SEe};T.x=E(r,T),T.X=E(n,T),T.c=E(e,T),S.x=E(r,S),S.X=E(n,S),S.c=E(e,S);function E(Q,j){return function(ne){var te=[],he=-1,le=0,J=Q.length,Se,se,ae;for(ne instanceof Date||(ne=new Date(+ne));++he53)return null;"w"in te||(te.w=1),"Z"in te?(le=RD(Pv(te.y,0,1)),J=le.getUTCDay(),le=J>4||J===0?H0.ceil(le):H0(le),le=Ov.offset(le,(te.V-1)*7),te.y=le.getUTCFullYear(),te.m=le.getUTCMonth(),te.d=le.getUTCDate()+(te.w+6)%7):(le=LD(Pv(te.y,0,1)),J=le.getDay(),le=J>4||J===0?Nh.ceil(le):Nh(le),le=Ro.offset(le,(te.V-1)*7),te.y=le.getFullYear(),te.m=le.getMonth(),te.d=le.getDate()+(te.w+6)%7)}else("W"in te||"U"in te)&&("w"in te||(te.w="u"in te?te.u%7:"W"in te?1:0),J="Z"in te?RD(Pv(te.y,0,1)).getUTCDay():LD(Pv(te.y,0,1)).getDay(),te.m=0,te.d="W"in te?(te.w+6)%7+te.W*7-(J+5)%7:te.w+te.U*7-(J+6)%7);return"Z"in te?(te.H+=te.Z/100|0,te.M+=te.Z%100,RD(te)):LD(te)}}o(_,"newParse");function C(Q,j,ne,te){for(var he=0,le=j.length,J=ne.length,Se,se;he=J)return-1;if(Se=j.charCodeAt(he++),Se===37){if(Se=j.charAt(he++),se=w[Se in Iq?j.charAt(he++):Se],!se||(te=se(Q,ne,te))<0)return-1}else if(Se!=ne.charCodeAt(te++))return-1}return te}o(C,"parseSpecifier");function D(Q,j,ne){var te=h.exec(j.slice(ne));return te?(Q.p=f.get(te[0].toLowerCase()),ne+te[0].length):-1}o(D,"parsePeriod");function O(Q,j,ne){var te=m.exec(j.slice(ne));return te?(Q.w=g.get(te[0].toLowerCase()),ne+te[0].length):-1}o(O,"parseShortWeekday");function R(Q,j,ne){var te=d.exec(j.slice(ne));return te?(Q.w=p.get(te[0].toLowerCase()),ne+te[0].length):-1}o(R,"parseWeekday");function k(Q,j,ne){var te=x.exec(j.slice(ne));return te?(Q.m=b.get(te[0].toLowerCase()),ne+te[0].length):-1}o(k,"parseShortMonth");function L(Q,j,ne){var te=y.exec(j.slice(ne));return te?(Q.m=v.get(te[0].toLowerCase()),ne+te[0].length):-1}o(L,"parseMonth");function A(Q,j,ne){return C(Q,e,j,ne)}o(A,"parseLocaleDateTime");function I(Q,j,ne){return C(Q,r,j,ne)}o(I,"parseLocaleDate");function M(Q,j,ne){return C(Q,n,j,ne)}o(M,"parseLocaleTime");function P(Q){return s[Q.getDay()]}o(P,"formatShortWeekday");function B(Q){return a[Q.getDay()]}o(B,"formatWeekday");function F(Q){return u[Q.getMonth()]}o(F,"formatShortMonth");function z(Q){return l[Q.getMonth()]}o(z,"formatMonth");function $(Q){return i[+(Q.getHours()>=12)]}o($,"formatPeriod");function U(Q){return 1+~~(Q.getMonth()/3)}o(U,"formatQuarter");function K(Q){return s[Q.getUTCDay()]}o(K,"formatUTCShortWeekday");function ee(Q){return a[Q.getUTCDay()]}o(ee,"formatUTCWeekday");function Y(Q){return u[Q.getUTCMonth()]}o(Y,"formatUTCShortMonth");function ce(Q){return l[Q.getUTCMonth()]}o(ce,"formatUTCMonth");function Z(Q){return i[+(Q.getUTCHours()>=12)]}o(Z,"formatUTCPeriod");function ue(Q){return 1+~~(Q.getUTCMonth()/3)}return o(ue,"formatUTCQuarter"),{format:o(function(Q){var j=E(Q+="",T);return j.toString=function(){return Q},j},"format"),parse:o(function(Q){var j=_(Q+="",!1);return j.toString=function(){return Q},j},"parse"),utcFormat:o(function(Q){var j=E(Q+="",S);return j.toString=function(){return Q},j},"utcFormat"),utcParse:o(function(Q){var j=_(Q+="",!0);return j.toString=function(){return Q},j},"utcParse")}}function Wr(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a[e.toLowerCase(),r]))}function fEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function dEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function pEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function mEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function gEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function Oq(t,e,r){var n=Qi.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function Pq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function yEe(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function vEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.q=n[0]*3-3,r+n[0].length):-1}function xEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function Bq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function bEe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function Fq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function TEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function wEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function kEe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function EEe(t,e,r){var n=Qi.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function SEe(t,e,r){var n=cEe.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function CEe(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function AEe(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function $q(t,e){return Wr(t.getDate(),e,2)}function _Ee(t,e){return Wr(t.getHours(),e,2)}function DEe(t,e){return Wr(t.getHours()%12||12,e,2)}function LEe(t,e){return Wr(1+Ro.count(to(t),t),e,3)}function Hq(t,e){return Wr(t.getMilliseconds(),e,3)}function REe(t,e){return Hq(t,e)+"000"}function NEe(t,e){return Wr(t.getMonth()+1,e,2)}function MEe(t,e){return Wr(t.getMinutes(),e,2)}function IEe(t,e){return Wr(t.getSeconds(),e,2)}function OEe(t){var e=t.getDay();return e===0?7:e}function PEe(t,e){return Wr(wl.count(to(t)-1,t),e,2)}function Wq(t){var e=t.getDay();return e>=4||e===0?fc(t):fc.ceil(t)}function BEe(t,e){return t=Wq(t),Wr(fc.count(to(t),t)+(to(t).getDay()===4),e,2)}function FEe(t){return t.getDay()}function $Ee(t,e){return Wr(Nh.count(to(t)-1,t),e,2)}function zEe(t,e){return Wr(t.getFullYear()%100,e,2)}function GEe(t,e){return t=Wq(t),Wr(t.getFullYear()%100,e,2)}function VEe(t,e){return Wr(t.getFullYear()%1e4,e,4)}function UEe(t,e){var r=t.getDay();return t=r>=4||r===0?fc(t):fc.ceil(t),Wr(t.getFullYear()%1e4,e,4)}function HEe(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Wr(e/60|0,"0",2)+Wr(e%60,"0",2)}function zq(t,e){return Wr(t.getUTCDate(),e,2)}function WEe(t,e){return Wr(t.getUTCHours(),e,2)}function qEe(t,e){return Wr(t.getUTCHours()%12||12,e,2)}function YEe(t,e){return Wr(1+Ov.count(kl(t),t),e,3)}function qq(t,e){return Wr(t.getUTCMilliseconds(),e,3)}function XEe(t,e){return qq(t,e)+"000"}function jEe(t,e){return Wr(t.getUTCMonth()+1,e,2)}function KEe(t,e){return Wr(t.getUTCMinutes(),e,2)}function QEe(t,e){return Wr(t.getUTCSeconds(),e,2)}function ZEe(t){var e=t.getUTCDay();return e===0?7:e}function JEe(t,e){return Wr(Dd.count(kl(t)-1,t),e,2)}function Yq(t){var e=t.getUTCDay();return e>=4||e===0?Mh(t):Mh.ceil(t)}function eSe(t,e){return t=Yq(t),Wr(Mh.count(kl(t),t)+(kl(t).getUTCDay()===4),e,2)}function tSe(t){return t.getUTCDay()}function rSe(t,e){return Wr(H0.count(kl(t)-1,t),e,2)}function nSe(t,e){return Wr(t.getUTCFullYear()%100,e,2)}function iSe(t,e){return t=Yq(t),Wr(t.getUTCFullYear()%100,e,2)}function aSe(t,e){return Wr(t.getUTCFullYear()%1e4,e,4)}function sSe(t,e){var r=t.getUTCDay();return t=r>=4||r===0?Mh(t):Mh.ceil(t),Wr(t.getUTCFullYear()%1e4,e,4)}function oSe(){return"+0000"}function Gq(){return"%"}function Vq(t){return+t}function Uq(t){return Math.floor(+t/1e3)}var Iq,Qi,cEe,uEe,Xq=N(()=>{"use strict";$5();o(LD,"localDate");o(RD,"utcDate");o(Pv,"newDate");o(ND,"formatLocale");Iq={"-":"",_:" ",0:"0"},Qi=/^\s*\d+/,cEe=/^%/,uEe=/[\\^$*+?|[\]().{}]/g;o(Wr,"pad");o(hEe,"requote");o(Bv,"formatRe");o(Fv,"formatLookup");o(fEe,"parseWeekdayNumberSunday");o(dEe,"parseWeekdayNumberMonday");o(pEe,"parseWeekNumberSunday");o(mEe,"parseWeekNumberISO");o(gEe,"parseWeekNumberMonday");o(Oq,"parseFullYear");o(Pq,"parseYear");o(yEe,"parseZone");o(vEe,"parseQuarter");o(xEe,"parseMonthNumber");o(Bq,"parseDayOfMonth");o(bEe,"parseDayOfYear");o(Fq,"parseHour24");o(TEe,"parseMinutes");o(wEe,"parseSeconds");o(kEe,"parseMilliseconds");o(EEe,"parseMicroseconds");o(SEe,"parseLiteralPercent");o(CEe,"parseUnixTimestamp");o(AEe,"parseUnixTimestampSeconds");o($q,"formatDayOfMonth");o(_Ee,"formatHour24");o(DEe,"formatHour12");o(LEe,"formatDayOfYear");o(Hq,"formatMilliseconds");o(REe,"formatMicroseconds");o(NEe,"formatMonthNumber");o(MEe,"formatMinutes");o(IEe,"formatSeconds");o(OEe,"formatWeekdayNumberMonday");o(PEe,"formatWeekNumberSunday");o(Wq,"dISO");o(BEe,"formatWeekNumberISO");o(FEe,"formatWeekdayNumberSunday");o($Ee,"formatWeekNumberMonday");o(zEe,"formatYear");o(GEe,"formatYearISO");o(VEe,"formatFullYear");o(UEe,"formatFullYearISO");o(HEe,"formatZone");o(zq,"formatUTCDayOfMonth");o(WEe,"formatUTCHour24");o(qEe,"formatUTCHour12");o(YEe,"formatUTCDayOfYear");o(qq,"formatUTCMilliseconds");o(XEe,"formatUTCMicroseconds");o(jEe,"formatUTCMonthNumber");o(KEe,"formatUTCMinutes");o(QEe,"formatUTCSeconds");o(ZEe,"formatUTCWeekdayNumberMonday");o(JEe,"formatUTCWeekNumberSunday");o(Yq,"UTCdISO");o(eSe,"formatUTCWeekNumberISO");o(tSe,"formatUTCWeekdayNumberSunday");o(rSe,"formatUTCWeekNumberMonday");o(nSe,"formatUTCYear");o(iSe,"formatUTCYearISO");o(aSe,"formatUTCFullYear");o(sSe,"formatUTCFullYearISO");o(oSe,"formatUTCZone");o(Gq,"formatLiteralPercent");o(Vq,"formatUnixTimestamp");o(Uq,"formatUnixTimestampSeconds")});function MD(t){return W0=ND(t),Ld=W0.format,jq=W0.parse,Kq=W0.utcFormat,Qq=W0.utcParse,W0}var W0,Ld,jq,Kq,Qq,Zq=N(()=>{"use strict";Xq();MD({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});o(MD,"defaultLocale")});var ID=N(()=>{"use strict";Zq()});function lSe(t){return new Date(t)}function cSe(t){return t instanceof Date?+t:+new Date(+t)}function Jq(t,e,r,n,i,a,s,l,u,h){var f=Mv(),d=f.invert,p=f.domain,m=h(".%L"),g=h(":%S"),y=h("%I:%M"),v=h("%I %p"),x=h("%a %d"),b=h("%b %d"),T=h("%B"),S=h("%Y");function w(E){return(u(E){"use strict";$5();ID();mD();Nv();Tq();o(lSe,"date");o(cSe,"number");o(Jq,"calendar");o(z5,"time")});var tY=N(()=>{"use strict";mq();bq();hD();eY()});function OD(t){for(var e=t.length/6|0,r=new Array(e),n=0;n{"use strict";o(OD,"default")});var PD,nY=N(()=>{"use strict";rY();PD=OD("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab")});var iY=N(()=>{"use strict";nY()});function Bn(t){return o(function(){return t},"constant")}var G5=N(()=>{"use strict";o(Bn,"default")});function sY(t){return t>1?0:t<-1?q0:Math.acos(t)}function FD(t){return t>=1?$v:t<=-1?-$v:Math.asin(t)}var BD,ha,Ih,aY,V5,El,Rd,Zi,q0,$v,Y0,U5=N(()=>{"use strict";BD=Math.abs,ha=Math.atan2,Ih=Math.cos,aY=Math.max,V5=Math.min,El=Math.sin,Rd=Math.sqrt,Zi=1e-12,q0=Math.PI,$v=q0/2,Y0=2*q0;o(sY,"acos");o(FD,"asin")});function H5(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(r==null)e=null;else{let n=Math.floor(r);if(!(n>=0))throw new RangeError(`invalid digits: ${r}`);e=n}return t},()=>new wd(e)}var $D=N(()=>{"use strict";O_();o(H5,"withPath")});function uSe(t){return t.innerRadius}function hSe(t){return t.outerRadius}function fSe(t){return t.startAngle}function dSe(t){return t.endAngle}function pSe(t){return t&&t.padAngle}function mSe(t,e,r,n,i,a,s,l){var u=r-t,h=n-e,f=s-i,d=l-a,p=d*u-f*h;if(!(p*pA*A+I*I&&(C=O,D=R),{cx:C,cy:D,x01:-f,y01:-d,x11:C*(i/w-1),y11:D*(i/w-1)}}function Sl(){var t=uSe,e=hSe,r=Bn(0),n=null,i=fSe,a=dSe,s=pSe,l=null,u=H5(h);function h(){var f,d,p=+t.apply(this,arguments),m=+e.apply(this,arguments),g=i.apply(this,arguments)-$v,y=a.apply(this,arguments)-$v,v=BD(y-g),x=y>g;if(l||(l=f=u()),mZi))l.moveTo(0,0);else if(v>Y0-Zi)l.moveTo(m*Ih(g),m*El(g)),l.arc(0,0,m,g,y,!x),p>Zi&&(l.moveTo(p*Ih(y),p*El(y)),l.arc(0,0,p,y,g,x));else{var b=g,T=y,S=g,w=y,E=v,_=v,C=s.apply(this,arguments)/2,D=C>Zi&&(n?+n.apply(this,arguments):Rd(p*p+m*m)),O=V5(BD(m-p)/2,+r.apply(this,arguments)),R=O,k=O,L,A;if(D>Zi){var I=FD(D/p*El(C)),M=FD(D/m*El(C));(E-=I*2)>Zi?(I*=x?1:-1,S+=I,w-=I):(E=0,S=w=(g+y)/2),(_-=M*2)>Zi?(M*=x?1:-1,b+=M,T-=M):(_=0,b=T=(g+y)/2)}var P=m*Ih(b),B=m*El(b),F=p*Ih(w),z=p*El(w);if(O>Zi){var $=m*Ih(T),U=m*El(T),K=p*Ih(S),ee=p*El(S),Y;if(vZi?k>Zi?(L=W5(K,ee,P,B,m,k,x),A=W5($,U,F,z,m,k,x),l.moveTo(L.cx+L.x01,L.cy+L.y01),kZi)||!(E>Zi)?l.lineTo(F,z):R>Zi?(L=W5(F,z,$,U,p,-R,x),A=W5(P,B,K,ee,p,-R,x),l.lineTo(L.cx+L.x01,L.cy+L.y01),R{"use strict";G5();U5();$D();o(uSe,"arcInnerRadius");o(hSe,"arcOuterRadius");o(fSe,"arcStartAngle");o(dSe,"arcEndAngle");o(pSe,"arcPadAngle");o(mSe,"intersect");o(W5,"cornerTangents");o(Sl,"default")});function zv(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}var yxt,zD=N(()=>{"use strict";yxt=Array.prototype.slice;o(zv,"default")});function lY(t){this._context=t}function Su(t){return new lY(t)}var GD=N(()=>{"use strict";o(lY,"Linear");lY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e);break}},"point")};o(Su,"default")});function cY(t){return t[0]}function uY(t){return t[1]}var hY=N(()=>{"use strict";o(cY,"x");o(uY,"y")});function Cl(t,e){var r=Bn(!0),n=null,i=Su,a=null,s=H5(l);t=typeof t=="function"?t:t===void 0?cY:Bn(t),e=typeof e=="function"?e:e===void 0?uY:Bn(e);function l(u){var h,f=(u=zv(u)).length,d,p=!1,m;for(n==null&&(a=i(m=s())),h=0;h<=f;++h)!(h{"use strict";zD();G5();GD();$D();hY();o(Cl,"default")});function VD(t,e){return et?1:e>=t?0:NaN}var dY=N(()=>{"use strict";o(VD,"default")});function UD(t){return t}var pY=N(()=>{"use strict";o(UD,"default")});function q5(){var t=UD,e=VD,r=null,n=Bn(0),i=Bn(Y0),a=Bn(0);function s(l){var u,h=(l=zv(l)).length,f,d,p=0,m=new Array(h),g=new Array(h),y=+n.apply(this,arguments),v=Math.min(Y0,Math.max(-Y0,i.apply(this,arguments)-y)),x,b=Math.min(Math.abs(v)/h,a.apply(this,arguments)),T=b*(v<0?-1:1),S;for(u=0;u0&&(p+=S);for(e!=null?m.sort(function(w,E){return e(g[w],g[E])}):r!=null&&m.sort(function(w,E){return r(l[w],l[E])}),u=0,d=p?(v-h*T)/p:0;u0?S*d:0)+T,g[f]={data:l[f],index:u,value:S,startAngle:y,endAngle:x,padAngle:b};return g}return o(s,"pie"),s.value=function(l){return arguments.length?(t=typeof l=="function"?l:Bn(+l),s):t},s.sortValues=function(l){return arguments.length?(e=l,r=null,s):e},s.sort=function(l){return arguments.length?(r=l,e=null,s):r},s.startAngle=function(l){return arguments.length?(n=typeof l=="function"?l:Bn(+l),s):n},s.endAngle=function(l){return arguments.length?(i=typeof l=="function"?l:Bn(+l),s):i},s.padAngle=function(l){return arguments.length?(a=typeof l=="function"?l:Bn(+l),s):a},s}var mY=N(()=>{"use strict";zD();G5();dY();pY();U5();o(q5,"default")});function Gv(t){return new Y5(t,!0)}function Vv(t){return new Y5(t,!1)}var Y5,gY=N(()=>{"use strict";Y5=class{static{o(this,"Bump")}constructor(e,r){this._context=e,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,r){switch(e=+e,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,r,e,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,e,this._y0,e,r);break}}this._x0=e,this._y0=r}};o(Gv,"bumpX");o(Vv,"bumpY")});function ro(){}var Uv=N(()=>{"use strict";o(ro,"default")});function X0(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function Hv(t){this._context=t}function No(t){return new Hv(t)}var Wv=N(()=>{"use strict";o(X0,"point");o(Hv,"Basis");Hv.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 3:X0(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(No,"default")});function yY(t){this._context=t}function X5(t){return new yY(t)}var vY=N(()=>{"use strict";Uv();Wv();o(yY,"BasisClosed");yY.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(X5,"default")});function xY(t){this._context=t}function j5(t){return new xY(t)}var bY=N(()=>{"use strict";Wv();o(xY,"BasisOpen");xY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(j5,"default")});function TY(t,e){this._basis=new Hv(t),this._beta=e}var HD,wY=N(()=>{"use strict";Wv();o(TY,"Bundle");TY.prototype={lineStart:o(function(){this._x=[],this._y=[],this._basis.lineStart()},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n=t[0],i=e[0],a=t[r]-n,s=e[r]-i,l=-1,u;++l<=r;)u=l/r,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+u*a),this._beta*e[l]+(1-this._beta)*(i+u*s));this._x=this._y=null,this._basis.lineEnd()},"lineEnd"),point:o(function(t,e){this._x.push(+t),this._y.push(+e)},"point")};HD=o(function t(e){function r(n){return e===1?new Hv(n):new TY(n,e)}return o(r,"bundle"),r.beta=function(n){return t(+n)},r},"custom")(.85)});function j0(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function K5(t,e){this._context=t,this._k=(1-e)/6}var qv,Yv=N(()=>{"use strict";o(j0,"point");o(K5,"Cardinal");K5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:j0(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};qv=o(function t(e){function r(n){return new K5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Q5(t,e){this._context=t,this._k=(1-e)/6}var WD,qD=N(()=>{"use strict";Uv();Yv();o(Q5,"CardinalClosed");Q5.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};WD=o(function t(e){function r(n){return new Q5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Z5(t,e){this._context=t,this._k=(1-e)/6}var YD,XD=N(()=>{"use strict";Yv();o(Z5,"CardinalOpen");Z5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};YD=o(function t(e){function r(n){return new Z5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Xv(t,e,r){var n=t._x1,i=t._y1,a=t._x2,s=t._y2;if(t._l01_a>Zi){var l=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,u=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*l-t._x0*t._l12_2a+t._x2*t._l01_2a)/u,i=(i*l-t._y0*t._l12_2a+t._y2*t._l01_2a)/u}if(t._l23_a>Zi){var h=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*h+t._x1*t._l23_2a-e*t._l12_2a)/f,s=(s*h+t._y1*t._l23_2a-r*t._l12_2a)/f}t._context.bezierCurveTo(n,i,a,s,t._x2,t._y2)}function kY(t,e){this._context=t,this._alpha=e}var jv,J5=N(()=>{"use strict";U5();Yv();o(Xv,"point");o(kY,"CatmullRom");kY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};jv=o(function t(e){function r(n){return e?new kY(n,e):new K5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function EY(t,e){this._context=t,this._alpha=e}var jD,SY=N(()=>{"use strict";qD();Uv();J5();o(EY,"CatmullRomClosed");EY.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};jD=o(function t(e){function r(n){return e?new EY(n,e):new Q5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function CY(t,e){this._context=t,this._alpha=e}var KD,AY=N(()=>{"use strict";XD();J5();o(CY,"CatmullRomOpen");CY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};KD=o(function t(e){function r(n){return e?new CY(n,e):new Z5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function _Y(t){this._context=t}function eT(t){return new _Y(t)}var DY=N(()=>{"use strict";Uv();o(_Y,"LinearClosed");_Y.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){this._point&&this._context.closePath()},"lineEnd"),point:o(function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))},"point")};o(eT,"default")});function LY(t){return t<0?-1:1}function RY(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),s=(r-t._y1)/(i||n<0&&-0),l=(a*i+s*n)/(n+i);return(LY(a)+LY(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(l))||0}function NY(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function QD(t,e,r){var n=t._x0,i=t._y0,a=t._x1,s=t._y1,l=(a-n)/3;t._context.bezierCurveTo(n+l,i+l*e,a-l,s-l*r,a,s)}function tT(t){this._context=t}function MY(t){this._context=new IY(t)}function IY(t){this._context=t}function Kv(t){return new tT(t)}function Qv(t){return new MY(t)}var OY=N(()=>{"use strict";o(LY,"sign");o(RY,"slope3");o(NY,"slope2");o(QD,"point");o(tT,"MonotoneX");tT.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:QD(this,this._t0,NY(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){var r=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,QD(this,NY(this,r=RY(this,t,e)),r);break;default:QD(this,this._t0,r=RY(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}},"point")};o(MY,"MonotoneY");(MY.prototype=Object.create(tT.prototype)).point=function(t,e){tT.prototype.point.call(this,e,t)};o(IY,"ReflectContext");IY.prototype={moveTo:o(function(t,e){this._context.moveTo(e,t)},"moveTo"),closePath:o(function(){this._context.closePath()},"closePath"),lineTo:o(function(t,e){this._context.lineTo(e,t)},"lineTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)},"bezierCurveTo")};o(Kv,"monotoneX");o(Qv,"monotoneY")});function BY(t){this._context=t}function PY(t){var e,r=t.length-1,n,i=new Array(r),a=new Array(r),s=new Array(r);for(i[0]=0,a[0]=2,s[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(s[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e{"use strict";o(BY,"Natural");BY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=[],this._y=[]},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),r===2)this._context.lineTo(t[1],e[1]);else for(var n=PY(t),i=PY(e),a=0,s=1;s{"use strict";o(rT,"Step");rT.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=this._y=NaN,this._point=0},"lineStart"),lineEnd:o(function(){0=0&&(this._t=1-this._t,this._line=1-this._line)},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}break}}this._x=t,this._y=e},"point")};o(Q0,"default");o(Zv,"stepBefore");o(Jv,"stepAfter")});var zY=N(()=>{"use strict";oY();fY();mY();vY();bY();Wv();gY();wY();qD();XD();Yv();SY();AY();J5();DY();GD();OY();FY();$Y()});var GY=N(()=>{"use strict"});var VY=N(()=>{"use strict"});function Oh(t,e,r){this.k=t,this.x=e,this.y=r}function JD(t){for(;!t.__zoom;)if(!(t=t.parentNode))return ZD;return t.__zoom}var ZD,e9=N(()=>{"use strict";o(Oh,"Transform");Oh.prototype={constructor:Oh,scale:o(function(t){return t===1?this:new Oh(this.k*t,this.x,this.y)},"scale"),translate:o(function(t,e){return t===0&e===0?this:new Oh(this.k,this.x+this.k*t,this.y+this.k*e)},"translate"),apply:o(function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},"apply"),applyX:o(function(t){return t*this.k+this.x},"applyX"),applyY:o(function(t){return t*this.k+this.y},"applyY"),invert:o(function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},"invert"),invertX:o(function(t){return(t-this.x)/this.k},"invertX"),invertY:o(function(t){return(t-this.y)/this.k},"invertY"),rescaleX:o(function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},"rescaleX"),rescaleY:o(function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},"rescaleY"),toString:o(function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"},"toString")};ZD=new Oh(1,0,0);JD.prototype=Oh.prototype;o(JD,"transform")});var UY=N(()=>{"use strict"});var HY=N(()=>{"use strict";b5();GY();VY();e9();UY()});var WY=N(()=>{"use strict";HY();e9()});var fr=N(()=>{"use strict";Eh();JV();vW();wW();I0();kW();EW();VA();HU();SW();L_();CW();_W();Y_();VW();fq();B0();O_();dq();AW();pq();tY();iY();yl();zY();$5();ID();p5();b5();WY()});var qY=Pi(Ji=>{"use strict";Object.defineProperty(Ji,"__esModule",{value:!0});Ji.BLANK_URL=Ji.relativeFirstCharacters=Ji.whitespaceEscapeCharsRegex=Ji.urlSchemeRegex=Ji.ctrlCharactersRegex=Ji.htmlCtrlEntityRegex=Ji.htmlEntitiesRegex=Ji.invalidProtocolRegex=void 0;Ji.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im;Ji.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g;Ji.htmlCtrlEntityRegex=/&(newline|tab);/gi;Ji.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim;Ji.urlSchemeRegex=/^.+(:|:)/gim;Ji.whitespaceEscapeCharsRegex=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g;Ji.relativeFirstCharacters=[".","/"];Ji.BLANK_URL="about:blank"});var Z0=Pi(nT=>{"use strict";Object.defineProperty(nT,"__esModule",{value:!0});nT.sanitizeUrl=void 0;var La=qY();function gSe(t){return La.relativeFirstCharacters.indexOf(t[0])>-1}o(gSe,"isRelativeUrlWithoutProtocol");function ySe(t){var e=t.replace(La.ctrlCharactersRegex,"");return e.replace(La.htmlEntitiesRegex,function(r,n){return String.fromCharCode(n)})}o(ySe,"decodeHtmlCharacters");function vSe(t){return URL.canParse(t)}o(vSe,"isValidUrl");function YY(t){try{return decodeURIComponent(t)}catch{return t}}o(YY,"decodeURI");function xSe(t){if(!t)return La.BLANK_URL;var e,r=YY(t.trim());do r=ySe(r).replace(La.htmlCtrlEntityRegex,"").replace(La.ctrlCharactersRegex,"").replace(La.whitespaceEscapeCharsRegex,"").trim(),r=YY(r),e=r.match(La.ctrlCharactersRegex)||r.match(La.htmlEntitiesRegex)||r.match(La.htmlCtrlEntityRegex)||r.match(La.whitespaceEscapeCharsRegex);while(e&&e.length>0);var n=r;if(!n)return La.BLANK_URL;if(gSe(n))return n;var i=n.trimStart(),a=i.match(La.urlSchemeRegex);if(!a)return n;var s=a[0].toLowerCase().trim();if(La.invalidProtocolRegex.test(s))return La.BLANK_URL;var l=i.replace(/\\/g,"/");if(s==="mailto:"||s.includes("://"))return l;if(s==="http:"||s==="https:"){if(!vSe(l))return La.BLANK_URL;var u=new URL(l);return u.protocol=u.protocol.toLowerCase(),u.hostname=u.hostname.toLowerCase(),u.toString()}return l}o(xSe,"sanitizeUrl");nT.sanitizeUrl=xSe});var t9,Nd,iT,XY,jY,KY,Al,e2,t2=N(()=>{"use strict";t9=Aa(Z0(),1);pr();Nd=o((t,e)=>{let r=t.append("rect");if(r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),e.name&&r.attr("name",e.name),e.rx&&r.attr("rx",e.rx),e.ry&&r.attr("ry",e.ry),e.attrs!==void 0)for(let n in e.attrs)r.attr(n,e.attrs[n]);return e.class&&r.attr("class",e.class),r},"drawRect"),iT=o((t,e)=>{let r={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};Nd(t,r).lower()},"drawBackgroundRect"),XY=o((t,e)=>{let r=e.text.replace(ud," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),jY=o((t,e,r,n)=>{let i=t.append("image");i.attr("x",e),i.attr("y",r);let a=(0,t9.sanitizeUrl)(n);i.attr("xlink:href",a)},"drawImage"),KY=o((t,e,r,n)=>{let i=t.append("use");i.attr("x",e),i.attr("y",r);let a=(0,t9.sanitizeUrl)(n);i.attr("xlink:href",`#${a}`)},"drawEmbeddedImage"),Al=o(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),e2=o(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")});var QY,r9,ZY,bSe,TSe,wSe,kSe,ESe,SSe,CSe,ASe,_Se,DSe,LSe,RSe,Cu,_l,JY=N(()=>{"use strict";pr();t2();QY=Aa(Z0(),1),r9=o(function(t,e){return Nd(t,e)},"drawRect"),ZY=o(function(t,e,r,n,i,a){let s=t.append("image");s.attr("width",e),s.attr("height",r),s.attr("x",n),s.attr("y",i);let l=a.startsWith("data:image/png;base64")?a:(0,QY.sanitizeUrl)(a);s.attr("xlink:href",l)},"drawImage"),bSe=o((t,e,r)=>{let n=t.append("g"),i=0;for(let a of e){let s=a.textColor?a.textColor:"#444444",l=a.lineColor?a.lineColor:"#444444",u=a.offsetX?parseInt(a.offsetX):0,h=a.offsetY?parseInt(a.offsetY):0,f="";if(i===0){let p=n.append("line");p.attr("x1",a.startPoint.x),p.attr("y1",a.startPoint.y),p.attr("x2",a.endPoint.x),p.attr("y2",a.endPoint.y),p.attr("stroke-width","1"),p.attr("stroke",l),p.style("fill","none"),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)"),i=-1}else{let p=n.append("path");p.attr("fill","none").attr("stroke-width","1").attr("stroke",l).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",a.startPoint.x).replaceAll("starty",a.startPoint.y).replaceAll("controlx",a.startPoint.x+(a.endPoint.x-a.startPoint.x)/2-(a.endPoint.x-a.startPoint.x)/4).replaceAll("controly",a.startPoint.y+(a.endPoint.y-a.startPoint.y)/2).replaceAll("stopx",a.endPoint.x).replaceAll("stopy",a.endPoint.y)),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)")}let d=r.messageFont();Cu(r)(a.label.text,n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+h,a.label.width,a.label.height,{fill:s},d),a.techn&&a.techn.text!==""&&(d=r.messageFont(),Cu(r)("["+a.techn.text+"]",n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+r.messageFontSize+5+h,Math.max(a.label.width,a.techn.width),a.techn.height,{fill:s,"font-style":"italic"},d))}},"drawRels"),TSe=o(function(t,e,r){let n=t.append("g"),i=e.bgColor?e.bgColor:"none",a=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let u={x:e.x,y:e.y,fill:i,stroke:a,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};r9(n,u);let h=r.boundaryFont();h.fontWeight="bold",h.fontSize=h.fontSize+2,h.fontColor=s,Cu(r)(e.label.text,n,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},h),e.type&&e.type.text!==""&&(h=r.boundaryFont(),h.fontColor=s,Cu(r)(e.type.text,n,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},h)),e.descr&&e.descr.text!==""&&(h=r.boundaryFont(),h.fontSize=h.fontSize-2,h.fontColor=s,Cu(r)(e.descr.text,n,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},h))},"drawBoundary"),wSe=o(function(t,e,r){let n=e.bgColor?e.bgColor:r[e.typeC4Shape.text+"_bg_color"],i=e.borderColor?e.borderColor:r[e.typeC4Shape.text+"_border_color"],a=e.fontColor?e.fontColor:"#FFFFFF",s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII=";break}let l=t.append("g");l.attr("class","person-man");let u=Al();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":u.x=e.x,u.y=e.y,u.fill=n,u.width=e.width,u.height=e.height,u.stroke=i,u.rx=2.5,u.ry=2.5,u.attrs={"stroke-width":.5},r9(l,u);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2));break}let h=RSe(r,e.typeC4Shape.text);switch(l.append("text").attr("fill",a).attr("font-family",h.fontFamily).attr("font-size",h.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":ZY(l,48,48,e.x+e.width/2-24,e.y+e.image.Y,s);break}let f=r[e.typeC4Shape.text+"Font"]();return f.fontWeight="bold",f.fontSize=f.fontSize+2,f.fontColor=a,Cu(r)(e.label.text,l,e.x,e.y+e.label.Y,e.width,e.height,{fill:a},f),f=r[e.typeC4Shape.text+"Font"](),f.fontColor=a,e.techn&&e.techn?.text!==""?Cu(r)(e.techn.text,l,e.x,e.y+e.techn.Y,e.width,e.height,{fill:a,"font-style":"italic"},f):e.type&&e.type.text!==""&&Cu(r)(e.type.text,l,e.x,e.y+e.type.Y,e.width,e.height,{fill:a,"font-style":"italic"},f),e.descr&&e.descr.text!==""&&(f=r.personFont(),f.fontColor=a,Cu(r)(e.descr.text,l,e.x,e.y+e.descr.Y,e.width,e.height,{fill:a},f)),e.height},"drawC4Shape"),kSe=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),ESe=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),SSe=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),CSe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},"insertArrowHead"),ASe=o(function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},"insertArrowEnd"),_Se=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),DSe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertDynamicNumber"),LSe=o(function(t){let r=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);r.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),r.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},"insertArrowCrossHead"),RSe=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"getC4ShapeFont"),Cu=function(){function t(i,a,s,l,u,h,f){let d=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("text-anchor","middle").text(i);n(d,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d){let{fontSize:p,fontFamily:m,fontWeight:g}=d,y=i.split(Ze.lineBreakRegex);for(let v=0;v{"use strict";NSe=typeof global=="object"&&global&&global.Object===Object&&global,sT=NSe});var MSe,ISe,hi,Mo=N(()=>{"use strict";n9();MSe=typeof self=="object"&&self&&self.Object===Object&&self,ISe=sT||MSe||Function("return this")(),hi=ISe});var OSe,ea,Md=N(()=>{"use strict";Mo();OSe=hi.Symbol,ea=OSe});function FSe(t){var e=PSe.call(t,r2),r=t[r2];try{t[r2]=void 0;var n=!0}catch{}var i=BSe.call(t);return n&&(e?t[r2]=r:delete t[r2]),i}var eX,PSe,BSe,r2,tX,rX=N(()=>{"use strict";Md();eX=Object.prototype,PSe=eX.hasOwnProperty,BSe=eX.toString,r2=ea?ea.toStringTag:void 0;o(FSe,"getRawTag");tX=FSe});function GSe(t){return zSe.call(t)}var $Se,zSe,nX,iX=N(()=>{"use strict";$Se=Object.prototype,zSe=$Se.toString;o(GSe,"objectToString");nX=GSe});function HSe(t){return t==null?t===void 0?USe:VSe:aX&&aX in Object(t)?tX(t):nX(t)}var VSe,USe,aX,fa,Au=N(()=>{"use strict";Md();rX();iX();VSe="[object Null]",USe="[object Undefined]",aX=ea?ea.toStringTag:void 0;o(HSe,"baseGetTag");fa=HSe});function WSe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}var bn,no=N(()=>{"use strict";o(WSe,"isObject");bn=WSe});function KSe(t){if(!bn(t))return!1;var e=fa(t);return e==YSe||e==XSe||e==qSe||e==jSe}var qSe,YSe,XSe,jSe,Ai,n2=N(()=>{"use strict";Au();no();qSe="[object AsyncFunction]",YSe="[object Function]",XSe="[object GeneratorFunction]",jSe="[object Proxy]";o(KSe,"isFunction");Ai=KSe});var QSe,oT,sX=N(()=>{"use strict";Mo();QSe=hi["__core-js_shared__"],oT=QSe});function ZSe(t){return!!oX&&oX in t}var oX,lX,cX=N(()=>{"use strict";sX();oX=function(){var t=/[^.]+$/.exec(oT&&oT.keys&&oT.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();o(ZSe,"isMasked");lX=ZSe});function t6e(t){if(t!=null){try{return e6e.call(t)}catch{}try{return t+""}catch{}}return""}var JSe,e6e,_u,i9=N(()=>{"use strict";JSe=Function.prototype,e6e=JSe.toString;o(t6e,"toSource");_u=t6e});function c6e(t){if(!bn(t)||lX(t))return!1;var e=Ai(t)?l6e:n6e;return e.test(_u(t))}var r6e,n6e,i6e,a6e,s6e,o6e,l6e,uX,hX=N(()=>{"use strict";n2();cX();no();i9();r6e=/[\\^$.*+?()[\]{}|]/g,n6e=/^\[object .+?Constructor\]$/,i6e=Function.prototype,a6e=Object.prototype,s6e=i6e.toString,o6e=a6e.hasOwnProperty,l6e=RegExp("^"+s6e.call(o6e).replace(r6e,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");o(c6e,"baseIsNative");uX=c6e});function u6e(t,e){return t?.[e]}var fX,dX=N(()=>{"use strict";o(u6e,"getValue");fX=u6e});function h6e(t,e){var r=fX(t,e);return uX(r)?r:void 0}var Ls,Ph=N(()=>{"use strict";hX();dX();o(h6e,"getNative");Ls=h6e});var f6e,Du,i2=N(()=>{"use strict";Ph();f6e=Ls(Object,"create"),Du=f6e});function d6e(){this.__data__=Du?Du(null):{},this.size=0}var pX,mX=N(()=>{"use strict";i2();o(d6e,"hashClear");pX=d6e});function p6e(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}var gX,yX=N(()=>{"use strict";o(p6e,"hashDelete");gX=p6e});function v6e(t){var e=this.__data__;if(Du){var r=e[t];return r===m6e?void 0:r}return y6e.call(e,t)?e[t]:void 0}var m6e,g6e,y6e,vX,xX=N(()=>{"use strict";i2();m6e="__lodash_hash_undefined__",g6e=Object.prototype,y6e=g6e.hasOwnProperty;o(v6e,"hashGet");vX=v6e});function T6e(t){var e=this.__data__;return Du?e[t]!==void 0:b6e.call(e,t)}var x6e,b6e,bX,TX=N(()=>{"use strict";i2();x6e=Object.prototype,b6e=x6e.hasOwnProperty;o(T6e,"hashHas");bX=T6e});function k6e(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=Du&&e===void 0?w6e:e,this}var w6e,wX,kX=N(()=>{"use strict";i2();w6e="__lodash_hash_undefined__";o(k6e,"hashSet");wX=k6e});function J0(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";mX();yX();xX();TX();kX();o(J0,"Hash");J0.prototype.clear=pX;J0.prototype.delete=gX;J0.prototype.get=vX;J0.prototype.has=bX;J0.prototype.set=wX;a9=J0});function E6e(){this.__data__=[],this.size=0}var SX,CX=N(()=>{"use strict";o(E6e,"listCacheClear");SX=E6e});function S6e(t,e){return t===e||t!==t&&e!==e}var Io,Id=N(()=>{"use strict";o(S6e,"eq");Io=S6e});function C6e(t,e){for(var r=t.length;r--;)if(Io(t[r][0],e))return r;return-1}var Bh,a2=N(()=>{"use strict";Id();o(C6e,"assocIndexOf");Bh=C6e});function D6e(t){var e=this.__data__,r=Bh(e,t);if(r<0)return!1;var n=e.length-1;return r==n?e.pop():_6e.call(e,r,1),--this.size,!0}var A6e,_6e,AX,_X=N(()=>{"use strict";a2();A6e=Array.prototype,_6e=A6e.splice;o(D6e,"listCacheDelete");AX=D6e});function L6e(t){var e=this.__data__,r=Bh(e,t);return r<0?void 0:e[r][1]}var DX,LX=N(()=>{"use strict";a2();o(L6e,"listCacheGet");DX=L6e});function R6e(t){return Bh(this.__data__,t)>-1}var RX,NX=N(()=>{"use strict";a2();o(R6e,"listCacheHas");RX=R6e});function N6e(t,e){var r=this.__data__,n=Bh(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}var MX,IX=N(()=>{"use strict";a2();o(N6e,"listCacheSet");MX=N6e});function em(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";CX();_X();LX();NX();IX();o(em,"ListCache");em.prototype.clear=SX;em.prototype.delete=AX;em.prototype.get=DX;em.prototype.has=RX;em.prototype.set=MX;Fh=em});var M6e,$h,lT=N(()=>{"use strict";Ph();Mo();M6e=Ls(hi,"Map"),$h=M6e});function I6e(){this.size=0,this.__data__={hash:new a9,map:new($h||Fh),string:new a9}}var OX,PX=N(()=>{"use strict";EX();s2();lT();o(I6e,"mapCacheClear");OX=I6e});function O6e(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}var BX,FX=N(()=>{"use strict";o(O6e,"isKeyable");BX=O6e});function P6e(t,e){var r=t.__data__;return BX(e)?r[typeof e=="string"?"string":"hash"]:r.map}var zh,o2=N(()=>{"use strict";FX();o(P6e,"getMapData");zh=P6e});function B6e(t){var e=zh(this,t).delete(t);return this.size-=e?1:0,e}var $X,zX=N(()=>{"use strict";o2();o(B6e,"mapCacheDelete");$X=B6e});function F6e(t){return zh(this,t).get(t)}var GX,VX=N(()=>{"use strict";o2();o(F6e,"mapCacheGet");GX=F6e});function $6e(t){return zh(this,t).has(t)}var UX,HX=N(()=>{"use strict";o2();o($6e,"mapCacheHas");UX=$6e});function z6e(t,e){var r=zh(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this}var WX,qX=N(()=>{"use strict";o2();o(z6e,"mapCacheSet");WX=z6e});function tm(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";PX();zX();VX();HX();qX();o(tm,"MapCache");tm.prototype.clear=OX;tm.prototype.delete=$X;tm.prototype.get=GX;tm.prototype.has=UX;tm.prototype.set=WX;Od=tm});function s9(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(G6e);var r=o(function(){var n=arguments,i=e?e.apply(this,n):n[0],a=r.cache;if(a.has(i))return a.get(i);var s=t.apply(this,n);return r.cache=a.set(i,s)||a,s},"memoized");return r.cache=new(s9.Cache||Od),r}var G6e,rm,o9=N(()=>{"use strict";cT();G6e="Expected a function";o(s9,"memoize");s9.Cache=Od;rm=s9});function V6e(){this.__data__=new Fh,this.size=0}var YX,XX=N(()=>{"use strict";s2();o(V6e,"stackClear");YX=V6e});function U6e(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}var jX,KX=N(()=>{"use strict";o(U6e,"stackDelete");jX=U6e});function H6e(t){return this.__data__.get(t)}var QX,ZX=N(()=>{"use strict";o(H6e,"stackGet");QX=H6e});function W6e(t){return this.__data__.has(t)}var JX,ej=N(()=>{"use strict";o(W6e,"stackHas");JX=W6e});function Y6e(t,e){var r=this.__data__;if(r instanceof Fh){var n=r.__data__;if(!$h||n.length{"use strict";s2();lT();cT();q6e=200;o(Y6e,"stackSet");tj=Y6e});function nm(t){var e=this.__data__=new Fh(t);this.size=e.size}var dc,l2=N(()=>{"use strict";s2();XX();KX();ZX();ej();rj();o(nm,"Stack");nm.prototype.clear=YX;nm.prototype.delete=jX;nm.prototype.get=QX;nm.prototype.has=JX;nm.prototype.set=tj;dc=nm});var X6e,im,l9=N(()=>{"use strict";Ph();X6e=function(){try{var t=Ls(Object,"defineProperty");return t({},"",{}),t}catch{}}(),im=X6e});function j6e(t,e,r){e=="__proto__"&&im?im(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}var pc,am=N(()=>{"use strict";l9();o(j6e,"baseAssignValue");pc=j6e});function K6e(t,e,r){(r!==void 0&&!Io(t[e],r)||r===void 0&&!(e in t))&&pc(t,e,r)}var c2,c9=N(()=>{"use strict";am();Id();o(K6e,"assignMergeValue");c2=K6e});function Q6e(t){return function(e,r,n){for(var i=-1,a=Object(e),s=n(e),l=s.length;l--;){var u=s[t?l:++i];if(r(a[u],u,a)===!1)break}return e}}var nj,ij=N(()=>{"use strict";o(Q6e,"createBaseFor");nj=Q6e});var Z6e,sm,uT=N(()=>{"use strict";ij();Z6e=nj(),sm=Z6e});function eCe(t,e){if(e)return t.slice();var r=t.length,n=oj?oj(r):new t.constructor(r);return t.copy(n),n}var lj,aj,J6e,sj,oj,hT,u9=N(()=>{"use strict";Mo();lj=typeof exports=="object"&&exports&&!exports.nodeType&&exports,aj=lj&&typeof module=="object"&&module&&!module.nodeType&&module,J6e=aj&&aj.exports===lj,sj=J6e?hi.Buffer:void 0,oj=sj?sj.allocUnsafe:void 0;o(eCe,"cloneBuffer");hT=eCe});var tCe,om,h9=N(()=>{"use strict";Mo();tCe=hi.Uint8Array,om=tCe});function rCe(t){var e=new t.constructor(t.byteLength);return new om(e).set(new om(t)),e}var lm,fT=N(()=>{"use strict";h9();o(rCe,"cloneArrayBuffer");lm=rCe});function nCe(t,e){var r=e?lm(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}var dT,f9=N(()=>{"use strict";fT();o(nCe,"cloneTypedArray");dT=nCe});function iCe(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r{"use strict";o(iCe,"copyArray");pT=iCe});var cj,aCe,uj,hj=N(()=>{"use strict";no();cj=Object.create,aCe=function(){function t(){}return o(t,"object"),function(e){if(!bn(e))return{};if(cj)return cj(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}(),uj=aCe});function sCe(t,e){return function(r){return t(e(r))}}var mT,p9=N(()=>{"use strict";o(sCe,"overArg");mT=sCe});var oCe,cm,gT=N(()=>{"use strict";p9();oCe=mT(Object.getPrototypeOf,Object),cm=oCe});function cCe(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||lCe;return t===r}var lCe,mc,um=N(()=>{"use strict";lCe=Object.prototype;o(cCe,"isPrototype");mc=cCe});function uCe(t){return typeof t.constructor=="function"&&!mc(t)?uj(cm(t)):{}}var yT,m9=N(()=>{"use strict";hj();gT();um();o(uCe,"initCloneObject");yT=uCe});function hCe(t){return t!=null&&typeof t=="object"}var ii,Oo=N(()=>{"use strict";o(hCe,"isObjectLike");ii=hCe});function dCe(t){return ii(t)&&fa(t)==fCe}var fCe,g9,fj=N(()=>{"use strict";Au();Oo();fCe="[object Arguments]";o(dCe,"baseIsArguments");g9=dCe});var dj,pCe,mCe,gCe,Dl,hm=N(()=>{"use strict";fj();Oo();dj=Object.prototype,pCe=dj.hasOwnProperty,mCe=dj.propertyIsEnumerable,gCe=g9(function(){return arguments}())?g9:function(t){return ii(t)&&pCe.call(t,"callee")&&!mCe.call(t,"callee")},Dl=gCe});var yCe,Pt,Wn=N(()=>{"use strict";yCe=Array.isArray,Pt=yCe});function xCe(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=vCe}var vCe,fm,vT=N(()=>{"use strict";vCe=9007199254740991;o(xCe,"isLength");fm=xCe});function bCe(t){return t!=null&&fm(t.length)&&!Ai(t)}var fi,Po=N(()=>{"use strict";n2();vT();o(bCe,"isArrayLike");fi=bCe});function TCe(t){return ii(t)&&fi(t)}var Pd,xT=N(()=>{"use strict";Po();Oo();o(TCe,"isArrayLikeObject");Pd=TCe});function wCe(){return!1}var pj,mj=N(()=>{"use strict";o(wCe,"stubFalse");pj=wCe});var vj,gj,kCe,yj,ECe,SCe,Ll,dm=N(()=>{"use strict";Mo();mj();vj=typeof exports=="object"&&exports&&!exports.nodeType&&exports,gj=vj&&typeof module=="object"&&module&&!module.nodeType&&module,kCe=gj&&gj.exports===vj,yj=kCe?hi.Buffer:void 0,ECe=yj?yj.isBuffer:void 0,SCe=ECe||pj,Ll=SCe});function RCe(t){if(!ii(t)||fa(t)!=CCe)return!1;var e=cm(t);if(e===null)return!0;var r=DCe.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&xj.call(r)==LCe}var CCe,ACe,_Ce,xj,DCe,LCe,bj,Tj=N(()=>{"use strict";Au();gT();Oo();CCe="[object Object]",ACe=Function.prototype,_Ce=Object.prototype,xj=ACe.toString,DCe=_Ce.hasOwnProperty,LCe=xj.call(Object);o(RCe,"isPlainObject");bj=RCe});function r7e(t){return ii(t)&&fm(t.length)&&!!Fn[fa(t)]}var NCe,MCe,ICe,OCe,PCe,BCe,FCe,$Ce,zCe,GCe,VCe,UCe,HCe,WCe,qCe,YCe,XCe,jCe,KCe,QCe,ZCe,JCe,e7e,t7e,Fn,wj,kj=N(()=>{"use strict";Au();vT();Oo();NCe="[object Arguments]",MCe="[object Array]",ICe="[object Boolean]",OCe="[object Date]",PCe="[object Error]",BCe="[object Function]",FCe="[object Map]",$Ce="[object Number]",zCe="[object Object]",GCe="[object RegExp]",VCe="[object Set]",UCe="[object String]",HCe="[object WeakMap]",WCe="[object ArrayBuffer]",qCe="[object DataView]",YCe="[object Float32Array]",XCe="[object Float64Array]",jCe="[object Int8Array]",KCe="[object Int16Array]",QCe="[object Int32Array]",ZCe="[object Uint8Array]",JCe="[object Uint8ClampedArray]",e7e="[object Uint16Array]",t7e="[object Uint32Array]",Fn={};Fn[YCe]=Fn[XCe]=Fn[jCe]=Fn[KCe]=Fn[QCe]=Fn[ZCe]=Fn[JCe]=Fn[e7e]=Fn[t7e]=!0;Fn[NCe]=Fn[MCe]=Fn[WCe]=Fn[ICe]=Fn[qCe]=Fn[OCe]=Fn[PCe]=Fn[BCe]=Fn[FCe]=Fn[$Ce]=Fn[zCe]=Fn[GCe]=Fn[VCe]=Fn[UCe]=Fn[HCe]=!1;o(r7e,"baseIsTypedArray");wj=r7e});function n7e(t){return function(e){return t(e)}}var Bo,Bd=N(()=>{"use strict";o(n7e,"baseUnary");Bo=n7e});var Ej,u2,i7e,y9,a7e,Fo,h2=N(()=>{"use strict";n9();Ej=typeof exports=="object"&&exports&&!exports.nodeType&&exports,u2=Ej&&typeof module=="object"&&module&&!module.nodeType&&module,i7e=u2&&u2.exports===Ej,y9=i7e&&sT.process,a7e=function(){try{var t=u2&&u2.require&&u2.require("util").types;return t||y9&&y9.binding&&y9.binding("util")}catch{}}(),Fo=a7e});var Sj,s7e,Gh,f2=N(()=>{"use strict";kj();Bd();h2();Sj=Fo&&Fo.isTypedArray,s7e=Sj?Bo(Sj):wj,Gh=s7e});function o7e(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}var d2,v9=N(()=>{"use strict";o(o7e,"safeGet");d2=o7e});function u7e(t,e,r){var n=t[e];(!(c7e.call(t,e)&&Io(n,r))||r===void 0&&!(e in t))&&pc(t,e,r)}var l7e,c7e,gc,pm=N(()=>{"use strict";am();Id();l7e=Object.prototype,c7e=l7e.hasOwnProperty;o(u7e,"assignValue");gc=u7e});function h7e(t,e,r,n){var i=!r;r||(r={});for(var a=-1,s=e.length;++a{"use strict";pm();am();o(h7e,"copyObject");$o=h7e});function f7e(t,e){for(var r=-1,n=Array(t);++r{"use strict";o(f7e,"baseTimes");Cj=f7e});function m7e(t,e){var r=typeof t;return e=e??d7e,!!e&&(r=="number"||r!="symbol"&&p7e.test(t))&&t>-1&&t%1==0&&t{"use strict";d7e=9007199254740991,p7e=/^(?:0|[1-9]\d*)$/;o(m7e,"isIndex");Vh=m7e});function v7e(t,e){var r=Pt(t),n=!r&&Dl(t),i=!r&&!n&&Ll(t),a=!r&&!n&&!i&&Gh(t),s=r||n||i||a,l=s?Cj(t.length,String):[],u=l.length;for(var h in t)(e||y7e.call(t,h))&&!(s&&(h=="length"||i&&(h=="offset"||h=="parent")||a&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||Vh(h,u)))&&l.push(h);return l}var g7e,y7e,bT,x9=N(()=>{"use strict";Aj();hm();Wn();dm();p2();f2();g7e=Object.prototype,y7e=g7e.hasOwnProperty;o(v7e,"arrayLikeKeys");bT=v7e});function x7e(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}var _j,Dj=N(()=>{"use strict";o(x7e,"nativeKeysIn");_j=x7e});function w7e(t){if(!bn(t))return _j(t);var e=mc(t),r=[];for(var n in t)n=="constructor"&&(e||!T7e.call(t,n))||r.push(n);return r}var b7e,T7e,Lj,Rj=N(()=>{"use strict";no();um();Dj();b7e=Object.prototype,T7e=b7e.hasOwnProperty;o(w7e,"baseKeysIn");Lj=w7e});function k7e(t){return fi(t)?bT(t,!0):Lj(t)}var Rs,Uh=N(()=>{"use strict";x9();Rj();Po();o(k7e,"keysIn");Rs=k7e});function E7e(t){return $o(t,Rs(t))}var Nj,Mj=N(()=>{"use strict";Fd();Uh();o(E7e,"toPlainObject");Nj=E7e});function S7e(t,e,r,n,i,a,s){var l=d2(t,r),u=d2(e,r),h=s.get(u);if(h){c2(t,r,h);return}var f=a?a(l,u,r+"",t,e,s):void 0,d=f===void 0;if(d){var p=Pt(u),m=!p&&Ll(u),g=!p&&!m&&Gh(u);f=u,p||m||g?Pt(l)?f=l:Pd(l)?f=pT(l):m?(d=!1,f=hT(u,!0)):g?(d=!1,f=dT(u,!0)):f=[]:bj(u)||Dl(u)?(f=l,Dl(l)?f=Nj(l):(!bn(l)||Ai(l))&&(f=yT(u))):d=!1}d&&(s.set(u,f),i(f,u,n,a,s),s.delete(u)),c2(t,r,f)}var Ij,Oj=N(()=>{"use strict";c9();u9();f9();d9();m9();hm();Wn();xT();dm();n2();no();Tj();f2();v9();Mj();o(S7e,"baseMergeDeep");Ij=S7e});function Pj(t,e,r,n,i){t!==e&&sm(e,function(a,s){if(i||(i=new dc),bn(a))Ij(t,e,s,r,Pj,n,i);else{var l=n?n(d2(t,s),a,s+"",t,e,i):void 0;l===void 0&&(l=a),c2(t,s,l)}},Rs)}var Bj,Fj=N(()=>{"use strict";l2();c9();uT();Oj();no();Uh();v9();o(Pj,"baseMerge");Bj=Pj});function C7e(t){return t}var ta,Lu=N(()=>{"use strict";o(C7e,"identity");ta=C7e});function A7e(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}var $j,zj=N(()=>{"use strict";o(A7e,"apply");$j=A7e});function _7e(t,e,r){return e=Gj(e===void 0?t.length-1:e,0),function(){for(var n=arguments,i=-1,a=Gj(n.length-e,0),s=Array(a);++i{"use strict";zj();Gj=Math.max;o(_7e,"overRest");TT=_7e});function D7e(t){return function(){return t}}var Ns,T9=N(()=>{"use strict";o(D7e,"constant");Ns=D7e});var L7e,Vj,Uj=N(()=>{"use strict";T9();l9();Lu();L7e=im?function(t,e){return im(t,"toString",{configurable:!0,enumerable:!1,value:Ns(e),writable:!0})}:ta,Vj=L7e});function I7e(t){var e=0,r=0;return function(){var n=M7e(),i=N7e-(n-r);if(r=n,i>0){if(++e>=R7e)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}var R7e,N7e,M7e,Hj,Wj=N(()=>{"use strict";R7e=800,N7e=16,M7e=Date.now;o(I7e,"shortOut");Hj=I7e});var O7e,wT,w9=N(()=>{"use strict";Uj();Wj();O7e=Hj(Vj),wT=O7e});function P7e(t,e){return wT(TT(t,e,ta),t+"")}var yc,mm=N(()=>{"use strict";Lu();b9();w9();o(P7e,"baseRest");yc=P7e});function B7e(t,e,r){if(!bn(r))return!1;var n=typeof e;return(n=="number"?fi(r)&&Vh(e,r.length):n=="string"&&e in r)?Io(r[e],t):!1}var io,$d=N(()=>{"use strict";Id();Po();p2();no();o(B7e,"isIterateeCall");io=B7e});function F7e(t){return yc(function(e,r){var n=-1,i=r.length,a=i>1?r[i-1]:void 0,s=i>2?r[2]:void 0;for(a=t.length>3&&typeof a=="function"?(i--,a):void 0,s&&io(r[0],r[1],s)&&(a=i<3?void 0:a,i=1),e=Object(e);++n{"use strict";mm();$d();o(F7e,"createAssigner");kT=F7e});var $7e,Hh,E9=N(()=>{"use strict";Fj();k9();$7e=kT(function(t,e,r){Bj(t,e,r)}),Hh=$7e});function A9(t,e){if(!t)return e;let r=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return z7e[r]??e}function H7e(t,e){let r=t.trim();if(r)return e.securityLevel!=="loose"?(0,Xj.sanitizeUrl)(r):r}function Qj(t,e){return!t||!e?0:Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function q7e(t){let e,r=0;t.forEach(i=>{r+=Qj(i,e),e=i});let n=r/2;return _9(t,n)}function Y7e(t){return t.length===1?t[0]:q7e(t)}function j7e(t,e,r){let n=structuredClone(r);X.info("our points",n),e!=="start_left"&&e!=="start_right"&&n.reverse();let i=25+t,a=_9(n,i),s=10+t*.5,l=Math.atan2(n[0].y-a.y,n[0].x-a.x),u={x:0,y:0};return e==="start_left"?(u.x=Math.sin(l+Math.PI)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l+Math.PI)*s+(n[0].y+a.y)/2):e==="end_right"?(u.x=Math.sin(l-Math.PI)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l-Math.PI)*s+(n[0].y+a.y)/2-5):e==="end_left"?(u.x=Math.sin(l)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2-5):(u.x=Math.sin(l)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2),u}function D9(t){let e="",r="";for(let n of t)n!==void 0&&(n.startsWith("color:")||n.startsWith("text-align:")?r=r+n+";":e=e+n+";");return{style:e,labelStyle:r}}function K7e(t){let e="",r="0123456789abcdef",n=r.length;for(let i=0;i{"use strict";Xj=Aa(Z0(),1);fr();pr();b7();yt();rd();g0();o9();E9();Q4();C9="\u200B",z7e={curveBasis:No,curveBasisClosed:X5,curveBasisOpen:j5,curveBumpX:Gv,curveBumpY:Vv,curveBundle:HD,curveCardinalClosed:WD,curveCardinalOpen:YD,curveCardinal:qv,curveCatmullRomClosed:jD,curveCatmullRomOpen:KD,curveCatmullRom:jv,curveLinear:Su,curveLinearClosed:eT,curveMonotoneX:Kv,curveMonotoneY:Qv,curveNatural:K0,curveStep:Q0,curveStepAfter:Jv,curveStepBefore:Zv},G7e=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,V7e=o(function(t,e){let r=jj(t,/(?:init\b)|(?:initialize\b)/),n={};if(Array.isArray(r)){let s=r.map(l=>l.args);v0(s),n=Un(n,[...s])}else n=r.args;if(!n)return;let i=m0(t,e),a="config";return n[a]!==void 0&&(i==="flowchart-v2"&&(i="flowchart"),n[i]=n[a],delete n[a]),n},"detectInit"),jj=o(function(t,e=null){try{let r=new RegExp(`[%]{2}(?![{]${G7e.source})(?=[}][%]{2}).* +`,"ig");t=t.trim().replace(r,"").replace(/'/gm,'"'),X.debug(`Detecting diagram directive${e!==null?" type:"+e:""} based on the text:${t}`);let n,i=[];for(;(n=td.exec(t))!==null;)if(n.index===td.lastIndex&&td.lastIndex++,n&&!e||e&&n[1]?.match(e)||e&&n[2]?.match(e)){let a=n[1]?n[1]:n[2],s=n[3]?n[3].trim():n[4]?JSON.parse(n[4].trim()):null;i.push({type:a,args:s})}return i.length===0?{type:t,args:null}:i.length===1?i[0]:i}catch(r){return X.error(`ERROR: ${r.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},"detectDirective"),Kj=o(function(t){return t.replace(td,"")},"removeDirectives"),U7e=o(function(t,e){for(let[r,n]of e.entries())if(n.match(t))return r;return-1},"isSubstringInArray");o(A9,"interpolateToCurve");o(H7e,"formatUrl");W7e=o((t,...e)=>{let r=t.split("."),n=r.length-1,i=r[n],a=window;for(let s=0;s{let r=Math.pow(10,e);return Math.round(t*r)/r},"roundNumber"),_9=o((t,e)=>{let r,n=e;for(let i of t){if(r){let a=Qj(i,r);if(a===0)return r;if(a=1)return{x:i.x,y:i.y};if(s>0&&s<1)return{x:qj((1-s)*r.x+s*i.x,5),y:qj((1-s)*r.y+s*i.y,5)}}}r=i}throw new Error("Could not find a suitable point for the given distance")},"calculatePoint"),X7e=o((t,e,r)=>{X.info(`our points ${JSON.stringify(e)}`),e[0]!==r&&(e=e.reverse());let i=_9(e,25),a=t?10:5,s=Math.atan2(e[0].y-i.y,e[0].x-i.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+i.x)/2,l.y=-Math.cos(s)*a+(e[0].y+i.y)/2,l},"calcCardinalityPosition");o(j7e,"calcTerminalLabelPosition");o(D9,"getStylesFromArray");Yj=0,L9=o(()=>(Yj++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Yj),"generateId");o(K7e,"makeRandomHex");R9=o(t=>K7e(t.length),"random"),Q7e=o(function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},"getTextObj"),Z7e=o(function(t,e){let r=e.text.replace(Ze.lineBreakRegex," "),[,n]=zo(e.fontSize),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.style("text-anchor",e.anchor),i.style("font-family",e.fontFamily),i.style("font-size",n),i.style("font-weight",e.fontWeight),i.attr("fill",e.fill),e.class!==void 0&&i.attr("class",e.class);let a=i.append("tspan");return a.attr("x",e.x+e.textMargin*2),a.attr("fill",e.fill),a.text(r),i},"drawSimpleText"),N9=rm((t,e,r)=>{if(!t||(r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
    "},r),Ze.lineBreakRegex.test(t)))return t;let n=t.split(" ").filter(Boolean),i=[],a="";return n.forEach((s,l)=>{let u=ra(`${s} `,r),h=ra(a,r);if(u>e){let{hyphenatedStrings:p,remainingWord:m}=J7e(s,e,"-",r);i.push(a,...p),a=m}else h+u>=e?(i.push(a),a=s):a=[a,s].filter(Boolean).join(" ");l+1===n.length&&i.push(a)}),i.filter(s=>s!=="").join(r.joinWith)},(t,e,r)=>`${t}${e}${r.fontSize}${r.fontWeight}${r.fontFamily}${r.joinWith}`),J7e=rm((t,e,r="-",n)=>{n=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},n);let i=[...t],a=[],s="";return i.forEach((l,u)=>{let h=`${s}${l}`;if(ra(h,n)>=e){let d=u+1,p=i.length===d,m=`${h}${r}`;a.push(p?h:m),s=""}else s=h}),{hyphenatedStrings:a,remainingWord:s}},(t,e,r="-",n)=>`${t}${e}${r}${n.fontSize}${n.fontWeight}${n.fontFamily}`);o(ST,"calculateTextHeight");o(ra,"calculateTextWidth");M9=rm((t,e)=>{let{fontSize:r=12,fontFamily:n="Arial",fontWeight:i=400}=e;if(!t)return{width:0,height:0};let[,a]=zo(r),s=["sans-serif",n],l=t.split(Ze.lineBreakRegex),u=[],h=Ge("body");if(!h.remove)return{width:0,height:0,lineHeight:0};let f=h.append("svg");for(let p of s){let m=0,g={width:0,height:0,lineHeight:0};for(let y of l){let v=Q7e();v.text=y||C9;let x=Z7e(f,v).style("font-size",a).style("font-weight",i).style("font-family",p),b=(x._groups||x)[0][0].getBBox();if(b.width===0&&b.height===0)throw new Error("svg element not in render tree");g.width=Math.round(Math.max(g.width,b.width)),m=Math.round(b.height),g.height+=m,g.lineHeight=Math.round(Math.max(g.lineHeight,m))}u.push(g)}f.remove();let d=isNaN(u[1].height)||isNaN(u[1].width)||isNaN(u[1].lineHeight)||u[0].height>u[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1;return u[d]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`),S9=class{constructor(e=!1,r){this.count=0;this.count=r?r.length:0,this.next=e?()=>this.count++:()=>Date.now()}static{o(this,"InitIDGenerator")}},eAe=o(function(t){return ET=ET||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),ET.innerHTML=t,unescape(ET.textContent)},"entityDecode");o(I9,"isDetailedError");tAe=o((t,e,r,n)=>{if(!n)return;let i=t.node()?.getBBox();i&&t.append("text").text(n).attr("text-anchor","middle").attr("x",i.x+i.width/2).attr("y",-r).attr("class",e)},"insertTitle"),zo=o(t=>{if(typeof t=="number")return[t,t+"px"];let e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]},"parseFontSize");o($n,"cleanAndMerge");Vt={assignWithDepth:Un,wrapLabel:N9,calculateTextHeight:ST,calculateTextWidth:ra,calculateTextDimensions:M9,cleanAndMerge:$n,detectInit:V7e,detectDirective:jj,isSubstringInArray:U7e,interpolateToCurve:A9,calcLabelPosition:Y7e,calcCardinalityPosition:X7e,calcTerminalLabelPosition:j7e,formatUrl:H7e,getStylesFromArray:D9,generateId:L9,random:R9,runFunc:W7e,entityDecode:eAe,insertTitle:tAe,parseFontSize:zo,InitIDGenerator:S9},Zj=o(function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/#\w+;/g,function(r){let n=r.substring(1,r.length-1);return/^\+?\d+$/.test(n)?"\uFB02\xB0\xB0"+n+"\xB6\xDF":"\uFB02\xB0"+n+"\xB6\xDF"}),e},"encodeEntities"),na=o(function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},"decodeEntities"),Wh=o((t,e,{counter:r=0,prefix:n,suffix:i},a)=>a||`${n?`${n}_`:""}${t}_${e}_${r}${i?`_${i}`:""}`,"getEdgeId");o(zn,"handleUndefinedAttr")});function Rl(t,e,r,n,i){if(!e[t].width)if(r)e[t].text=N9(e[t].text,i,n),e[t].textLines=e[t].text.split(Ze.lineBreakRegex).length,e[t].width=i,e[t].height=ST(e[t].text,n);else{let a=e[t].text.split(Ze.lineBreakRegex);e[t].textLines=a.length;let s=0;e[t].height=0,e[t].width=0;for(let l of a)e[t].width=Math.max(ra(l,n),e[t].width),s=ST(l,n),e[t].height=e[t].height+s}}function nK(t,e,r,n,i){let a=new DT(i);a.data.widthLimit=r.data.widthLimit/Math.min(O9,n.length);for(let[s,l]of n.entries()){let u=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=u,u=l.image.Y+l.image.height);let h=l.wrap&&Ut.wrap,f=CT(Ut);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Rl("label",l,h,f,a.data.widthLimit),l.label.Y=u+8,u=l.label.Y+l.label.height,l.type&&l.type.text!==""){l.type.text="["+l.type.text+"]";let g=CT(Ut);Rl("type",l,h,g,a.data.widthLimit),l.type.Y=u+5,u=l.type.Y+l.type.height}if(l.descr&&l.descr.text!==""){let g=CT(Ut);g.fontSize=g.fontSize-2,Rl("descr",l,h,g,a.data.widthLimit),l.descr.Y=u+20,u=l.descr.Y+l.descr.height}if(s==0||s%O9===0){let g=r.data.startx+Ut.diagramMarginX,y=r.data.stopy+Ut.diagramMarginY+u;a.setData(g,g,y,y)}else{let g=a.data.stopx!==a.data.startx?a.data.stopx+Ut.diagramMarginX:a.data.startx,y=a.data.starty;a.setData(g,g,y,y)}a.name=l.alias;let d=i.db.getC4ShapeArray(l.alias),p=i.db.getC4ShapeKeys(l.alias);p.length>0&&rK(a,t,d,p),e=l.alias;let m=i.db.getBoundaries(e);m.length>0&&nK(t,e,a,m,i),l.alias!=="global"&&tK(t,l,a),r.data.stopy=Math.max(a.data.stopy+Ut.c4ShapeMargin,r.data.stopy),r.data.stopx=Math.max(a.data.stopx+Ut.c4ShapeMargin,r.data.stopx),AT=Math.max(AT,r.data.stopx),_T=Math.max(_T,r.data.stopy)}}var AT,_T,eK,O9,Ut,DT,P9,m2,CT,rAe,tK,rK,Ms,Jj,nAe,iAe,aAe,B9,iK=N(()=>{"use strict";fr();JY();yt();a7();pr();LA();Gt();g0();er();xi();AT=0,_T=0,eK=4,O9=2;Ry.yy=sv;Ut={},DT=class{static{o(this,"Bounds")}constructor(e){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,P9(e.db.getConfig())}setData(e,r,n,i){this.nextData.startx=this.data.startx=e,this.nextData.stopx=this.data.stopx=r,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=i}updateVal(e,r,n,i){e[r]===void 0?e[r]=n:e[r]=i(n,e[r])}insert(e){this.nextData.cnt=this.nextData.cnt+1;let r=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+e.margin:this.nextData.stopx+e.margin*2,n=r+e.width,i=this.nextData.starty+e.margin*2,a=i+e.height;(r>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>eK)&&(r=this.nextData.startx+e.margin+Ut.nextLinePaddingX,i=this.nextData.stopy+e.margin*2,this.nextData.stopx=n=r+e.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=i+e.height,this.nextData.cnt=1),e.x=r,e.y=i,this.updateVal(this.data,"startx",r,Math.min),this.updateVal(this.data,"starty",i,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",r,Math.min),this.updateVal(this.nextData,"starty",i,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(e){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},P9(e.db.getConfig())}bumpLastMargin(e){this.data.stopx+=e,this.data.stopy+=e}},P9=o(function(t){Un(Ut,t),t.fontFamily&&(Ut.personFontFamily=Ut.systemFontFamily=Ut.messageFontFamily=t.fontFamily),t.fontSize&&(Ut.personFontSize=Ut.systemFontSize=Ut.messageFontSize=t.fontSize),t.fontWeight&&(Ut.personFontWeight=Ut.systemFontWeight=Ut.messageFontWeight=t.fontWeight)},"setConf"),m2=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"c4ShapeFont"),CT=o(t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight}),"boundaryFont"),rAe=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont");o(Rl,"calcC4ShapeTextWH");tK=o(function(t,e,r){e.x=r.data.startx,e.y=r.data.starty,e.width=r.data.stopx-r.data.startx,e.height=r.data.stopy-r.data.starty,e.label.y=Ut.c4ShapeMargin-35;let n=e.wrap&&Ut.wrap,i=CT(Ut);i.fontSize=i.fontSize+2,i.fontWeight="bold";let a=ra(e.label.text,i);Rl("label",e,n,i,a),_l.drawBoundary(t,e,Ut)},"drawBoundary"),rK=o(function(t,e,r,n){let i=0;for(let a of n){i=0;let s=r[a],l=m2(Ut,s.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,s.typeC4Shape.width=ra("\xAB"+s.typeC4Shape.text+"\xBB",l),s.typeC4Shape.height=l.fontSize+2,s.typeC4Shape.Y=Ut.c4ShapePadding,i=s.typeC4Shape.Y+s.typeC4Shape.height-4,s.image={width:0,height:0,Y:0},s.typeC4Shape.text){case"person":case"external_person":s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height;break}s.sprite&&(s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height);let u=s.wrap&&Ut.wrap,h=Ut.width-Ut.c4ShapePadding*2,f=m2(Ut,s.typeC4Shape.text);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Rl("label",s,u,f,h),s.label.Y=i+8,i=s.label.Y+s.label.height,s.type&&s.type.text!==""){s.type.text="["+s.type.text+"]";let m=m2(Ut,s.typeC4Shape.text);Rl("type",s,u,m,h),s.type.Y=i+5,i=s.type.Y+s.type.height}else if(s.techn&&s.techn.text!==""){s.techn.text="["+s.techn.text+"]";let m=m2(Ut,s.techn.text);Rl("techn",s,u,m,h),s.techn.Y=i+5,i=s.techn.Y+s.techn.height}let d=i,p=s.label.width;if(s.descr&&s.descr.text!==""){let m=m2(Ut,s.typeC4Shape.text);Rl("descr",s,u,m,h),s.descr.Y=i+20,i=s.descr.Y+s.descr.height,p=Math.max(s.label.width,s.descr.width),d=i-s.descr.textLines*5}p=p+Ut.c4ShapePadding,s.width=Math.max(s.width||Ut.width,p,Ut.width),s.height=Math.max(s.height||Ut.height,d,Ut.height),s.margin=s.margin||Ut.c4ShapeMargin,t.insert(s),_l.drawC4Shape(e,s,Ut)}t.bumpLastMargin(Ut.c4ShapeMargin)},"drawC4ShapeArray"),Ms=class{static{o(this,"Point")}constructor(e,r){this.x=e,this.y=r}},Jj=o(function(t,e){let r=t.x,n=t.y,i=e.x,a=e.y,s=r+t.width/2,l=n+t.height/2,u=Math.abs(r-i),h=Math.abs(n-a),f=h/u,d=t.height/t.width,p=null;return n==a&&ri?p=new Ms(r,l):r==i&&na&&(p=new Ms(s,n)),r>i&&n=f?p=new Ms(r,l+f*t.width/2):p=new Ms(s-u/h*t.height/2,n+t.height):r=f?p=new Ms(r+t.width,l+f*t.width/2):p=new Ms(s+u/h*t.height/2,n+t.height):ra?d>=f?p=new Ms(r+t.width,l-f*t.width/2):p=new Ms(s+t.height/2*u/h,n):r>i&&n>a&&(d>=f?p=new Ms(r,l-t.width/2*f):p=new Ms(s-t.height/2*u/h,n)),p},"getIntersectPoint"),nAe=o(function(t,e){let r={x:0,y:0};r.x=e.x+e.width/2,r.y=e.y+e.height/2;let n=Jj(t,r);r.x=t.x+t.width/2,r.y=t.y+t.height/2;let i=Jj(e,r);return{startPoint:n,endPoint:i}},"getIntersectPoints"),iAe=o(function(t,e,r,n){let i=0;for(let a of e){i=i+1;let s=a.wrap&&Ut.wrap,l=rAe(Ut);n.db.getC4Type()==="C4Dynamic"&&(a.label.text=i+": "+a.label.text);let h=ra(a.label.text,l);Rl("label",a,s,l,h),a.techn&&a.techn.text!==""&&(h=ra(a.techn.text,l),Rl("techn",a,s,l,h)),a.descr&&a.descr.text!==""&&(h=ra(a.descr.text,l),Rl("descr",a,s,l,h));let f=r(a.from),d=r(a.to),p=nAe(f,d);a.startPoint=p.startPoint,a.endPoint=p.endPoint}_l.drawRels(t,e,Ut)},"drawRels");o(nK,"drawInsideBoundary");aAe=o(function(t,e,r,n){Ut=me().c4;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=n.db;n.db.setWrap(Ut.wrap),eK=l.getC4ShapeInRow(),O9=l.getC4BoundaryInRow(),X.debug(`C:${JSON.stringify(Ut,null,2)}`);let u=i==="sandbox"?s.select(`[id="${e}"]`):Ge(`[id="${e}"]`);_l.insertComputerIcon(u),_l.insertDatabaseIcon(u),_l.insertClockIcon(u);let h=new DT(n);h.setData(Ut.diagramMarginX,Ut.diagramMarginX,Ut.diagramMarginY,Ut.diagramMarginY),h.data.widthLimit=screen.availWidth,AT=Ut.diagramMarginX,_T=Ut.diagramMarginY;let f=n.db.getTitle(),d=n.db.getBoundaries("");nK(u,"",h,d,n),_l.insertArrowHead(u),_l.insertArrowEnd(u),_l.insertArrowCrossHead(u),_l.insertArrowFilledHead(u),iAe(u,n.db.getRels(),n.db.getC4Shape,n),h.data.stopx=AT,h.data.stopy=_T;let p=h.data,g=p.stopy-p.starty+2*Ut.diagramMarginY,v=p.stopx-p.startx+2*Ut.diagramMarginX;f&&u.append("text").text(f).attr("x",(p.stopx-p.startx)/2-4*Ut.diagramMarginX).attr("y",p.starty+Ut.diagramMarginY),fn(u,g,v,Ut.useMaxWidth);let x=f?60:0;u.attr("viewBox",p.startx-Ut.diagramMarginX+" -"+(Ut.diagramMarginY+x)+" "+v+" "+(g+x)),X.debug("models:",p)},"draw"),B9={drawPersonOrSystemArray:rK,drawBoundary:tK,setConf:P9,draw:aAe}});var sAe,aK,sK=N(()=>{"use strict";sAe=o(t=>`.person { + stroke: ${t.personBorder}; + fill: ${t.personBkg}; + } +`,"getStyles"),aK=sAe});var oK={};ur(oK,{diagram:()=>oAe});var oAe,lK=N(()=>{"use strict";a7();LA();iK();sK();oAe={parser:G$,db:sv,renderer:B9,styles:aK,init:o(({c4:t,wrap:e})=>{B9.setConf(t),sv.setWrap(e)},"init")}});function CK(t){return typeof t>"u"||t===null}function hAe(t){return typeof t=="object"&&t!==null}function fAe(t){return Array.isArray(t)?t:CK(t)?[]:[t]}function dAe(t,e){var r,n,i,a;if(e)for(a=Object.keys(e),r=0,n=a.length;rl&&(a=" ... ",e=n-l+a.length),r-n>l&&(s=" ...",r=n+l-s.length),{str:a+t.slice(e,r).replace(/\t/g,"\u2192")+s,pos:n-e+a.length}}function $9(t,e){return Gi.repeat(" ",e-t.length)+t}function wAe(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),typeof e.indent!="number"&&(e.indent=1),typeof e.linesBefore!="number"&&(e.linesBefore=3),typeof e.linesAfter!="number"&&(e.linesAfter=2);for(var r=/\r?\n|\r|\0/g,n=[0],i=[],a,s=-1;a=r.exec(t.buffer);)i.push(a.index),n.push(a.index+a[0].length),t.position<=a.index&&s<0&&(s=n.length-2);s<0&&(s=n.length-1);var l="",u,h,f=Math.min(t.line+e.linesAfter,i.length).toString().length,d=e.maxLength-(e.indent+f+3);for(u=1;u<=e.linesBefore&&!(s-u<0);u++)h=F9(t.buffer,n[s-u],i[s-u],t.position-(n[s]-n[s-u]),d),l=Gi.repeat(" ",e.indent)+$9((t.line-u+1).toString(),f)+" | "+h.str+` +`+l;for(h=F9(t.buffer,n[s],i[s],t.position,d),l+=Gi.repeat(" ",e.indent)+$9((t.line+1).toString(),f)+" | "+h.str+` +`,l+=Gi.repeat("-",e.indent+f+3+h.pos)+`^ +`,u=1;u<=e.linesAfter&&!(s+u>=i.length);u++)h=F9(t.buffer,n[s+u],i[s+u],t.position-(n[s]-n[s+u]),d),l+=Gi.repeat(" ",e.indent)+$9((t.line+u+1).toString(),f)+" | "+h.str+` +`;return l.replace(/\n$/,"")}function CAe(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(n){e[String(n)]=r})}),e}function AAe(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(EAe.indexOf(r)===-1)throw new Is('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=CAe(e.styleAliases||null),SAe.indexOf(this.kind)===-1)throw new Is('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}function hK(t,e){var r=[];return t[e].forEach(function(n){var i=r.length;r.forEach(function(a,s){a.tag===n.tag&&a.kind===n.kind&&a.multi===n.multi&&(i=s)}),r[i]=n}),r}function _Ae(){var t={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},e,r;function n(i){i.multi?(t.multi[i.kind].push(i),t.multi.fallback.push(i)):t[i.kind][i.tag]=t.fallback[i.tag]=i}for(o(n,"collectType"),e=0,r=arguments.length;e=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:r*parseFloat(e,10)}function JAe(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(Gi.isNegativeZero(t))return"-0.0";return r=t.toString(10),ZAe.test(r)?r.replace("e",".e"):r}function e8e(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!==0||Gi.isNegativeZero(t))}function n8e(t){return t===null?!1:DK.exec(t)!==null||LK.exec(t)!==null}function i8e(t){var e,r,n,i,a,s,l,u=0,h=null,f,d,p;if(e=DK.exec(t),e===null&&(e=LK.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],n=+e[2]-1,i=+e[3],!e[4])return new Date(Date.UTC(r,n,i));if(a=+e[4],s=+e[5],l=+e[6],e[7]){for(u=e[7].slice(0,3);u.length<3;)u+="0";u=+u}return e[9]&&(f=+e[10],d=+(e[11]||0),h=(f*60+d)*6e4,e[9]==="-"&&(h=-h)),p=new Date(Date.UTC(r,n,i,a,s,l,u)),h&&p.setTime(p.getTime()-h),p}function a8e(t){return t.toISOString()}function o8e(t){return t==="<<"||t===null}function c8e(t){if(t===null)return!1;var e,r,n=0,i=t.length,a=q9;for(r=0;r64)){if(e<0)return!1;n+=6}return n%8===0}function u8e(t){var e,r,n=t.replace(/[\r\n=]/g,""),i=n.length,a=q9,s=0,l=[];for(e=0;e>16&255),l.push(s>>8&255),l.push(s&255)),s=s<<6|a.indexOf(n.charAt(e));return r=i%4*6,r===0?(l.push(s>>16&255),l.push(s>>8&255),l.push(s&255)):r===18?(l.push(s>>10&255),l.push(s>>2&255)):r===12&&l.push(s>>4&255),new Uint8Array(l)}function h8e(t){var e="",r=0,n,i,a=t.length,s=q9;for(n=0;n>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]),r=(r<<8)+t[n];return i=a%3,i===0?(e+=s[r>>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]):i===2?(e+=s[r>>10&63],e+=s[r>>4&63],e+=s[r<<2&63],e+=s[64]):i===1&&(e+=s[r>>2&63],e+=s[r<<4&63],e+=s[64],e+=s[64]),e}function f8e(t){return Object.prototype.toString.call(t)==="[object Uint8Array]"}function g8e(t){if(t===null)return!0;var e=[],r,n,i,a,s,l=t;for(r=0,n=l.length;r>10)+55296,(t-65536&1023)+56320)}function O8e(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||RK,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function FK(t,e){var r={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return r.snippet=kAe(r),new Is(e,r)}function Qt(t,e){throw FK(t,e)}function NT(t,e){t.onWarning&&t.onWarning.call(null,FK(t,e))}function qh(t,e,r,n){var i,a,s,l;if(e1&&(t.result+=Gi.repeat(` +`,e-1))}function P8e(t,e,r){var n,i,a,s,l,u,h,f,d=t.kind,p=t.result,m;if(m=t.input.charCodeAt(t.position),Os(m)||ym(m)||m===35||m===38||m===42||m===33||m===124||m===62||m===39||m===34||m===37||m===64||m===96||(m===63||m===45)&&(i=t.input.charCodeAt(t.position+1),Os(i)||r&&ym(i)))return!1;for(t.kind="scalar",t.result="",a=s=t.position,l=!1;m!==0;){if(m===58){if(i=t.input.charCodeAt(t.position+1),Os(i)||r&&ym(i))break}else if(m===35){if(n=t.input.charCodeAt(t.position-1),Os(n))break}else{if(t.position===t.lineStart&&OT(t)||r&&ym(m))break;if(vc(m))if(u=t.line,h=t.lineStart,f=t.lineIndent,_i(t,!1,-1),t.lineIndent>=e){l=!0,m=t.input.charCodeAt(t.position);continue}else{t.position=s,t.line=u,t.lineStart=h,t.lineIndent=f;break}}l&&(qh(t,a,s,!1),X9(t,t.line-u),a=s=t.position,l=!1),Gd(m)||(s=t.position+1),m=t.input.charCodeAt(++t.position)}return qh(t,a,s,!1),t.result?!0:(t.kind=d,t.result=p,!1)}function B8e(t,e){var r,n,i;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,n=i=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(qh(t,n,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)n=t.position,t.position++,i=t.position;else return!0;else vc(r)?(qh(t,n,i,!0),X9(t,_i(t,!1,e)),n=i=t.position):t.position===t.lineStart&&OT(t)?Qt(t,"unexpected end of the document within a single quoted scalar"):(t.position++,i=t.position);Qt(t,"unexpected end of the stream within a single quoted scalar")}function F8e(t,e){var r,n,i,a,s,l;if(l=t.input.charCodeAt(t.position),l!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;(l=t.input.charCodeAt(t.position))!==0;){if(l===34)return qh(t,r,t.position,!0),t.position++,!0;if(l===92){if(qh(t,r,t.position,!0),l=t.input.charCodeAt(++t.position),vc(l))_i(t,!1,e);else if(l<256&&PK[l])t.result+=BK[l],t.position++;else if((s=N8e(l))>0){for(i=s,a=0;i>0;i--)l=t.input.charCodeAt(++t.position),(s=R8e(l))>=0?a=(a<<4)+s:Qt(t,"expected hexadecimal character");t.result+=I8e(a),t.position++}else Qt(t,"unknown escape sequence");r=n=t.position}else vc(l)?(qh(t,r,n,!0),X9(t,_i(t,!1,e)),r=n=t.position):t.position===t.lineStart&&OT(t)?Qt(t,"unexpected end of the document within a double quoted scalar"):(t.position++,n=t.position)}Qt(t,"unexpected end of the stream within a double quoted scalar")}function $8e(t,e){var r=!0,n,i,a,s=t.tag,l,u=t.anchor,h,f,d,p,m,g=Object.create(null),y,v,x,b;if(b=t.input.charCodeAt(t.position),b===91)f=93,m=!1,l=[];else if(b===123)f=125,m=!0,l={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=l),b=t.input.charCodeAt(++t.position);b!==0;){if(_i(t,!0,e),b=t.input.charCodeAt(t.position),b===f)return t.position++,t.tag=s,t.anchor=u,t.kind=m?"mapping":"sequence",t.result=l,!0;r?b===44&&Qt(t,"expected the node content, but found ','"):Qt(t,"missed comma between flow collection entries"),v=y=x=null,d=p=!1,b===63&&(h=t.input.charCodeAt(t.position+1),Os(h)&&(d=p=!0,t.position++,_i(t,!0,e))),n=t.line,i=t.lineStart,a=t.position,xm(t,e,LT,!1,!0),v=t.tag,y=t.result,_i(t,!0,e),b=t.input.charCodeAt(t.position),(p||t.line===n)&&b===58&&(d=!0,b=t.input.charCodeAt(++t.position),_i(t,!0,e),xm(t,e,LT,!1,!0),x=t.result),m?vm(t,l,g,v,y,x,n,i,a):d?l.push(vm(t,null,g,v,y,x,n,i,a)):l.push(y),_i(t,!0,e),b=t.input.charCodeAt(t.position),b===44?(r=!0,b=t.input.charCodeAt(++t.position)):r=!1}Qt(t,"unexpected end of the stream within a flow collection")}function z8e(t,e){var r,n,i=z9,a=!1,s=!1,l=e,u=0,h=!1,f,d;if(d=t.input.charCodeAt(t.position),d===124)n=!1;else if(d===62)n=!0;else return!1;for(t.kind="scalar",t.result="";d!==0;)if(d=t.input.charCodeAt(++t.position),d===43||d===45)z9===i?i=d===43?fK:A8e:Qt(t,"repeat of a chomping mode identifier");else if((f=M8e(d))>=0)f===0?Qt(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):s?Qt(t,"repeat of an indentation width identifier"):(l=e+f-1,s=!0);else break;if(Gd(d)){do d=t.input.charCodeAt(++t.position);while(Gd(d));if(d===35)do d=t.input.charCodeAt(++t.position);while(!vc(d)&&d!==0)}for(;d!==0;){for(Y9(t),t.lineIndent=0,d=t.input.charCodeAt(t.position);(!s||t.lineIndentl&&(l=t.lineIndent),vc(d)){u++;continue}if(t.lineIndente)&&u!==0)Qt(t,"bad indentation of a sequence entry");else if(t.lineIndente)&&(v&&(s=t.line,l=t.lineStart,u=t.position),xm(t,e,RT,!0,i)&&(v?g=t.result:y=t.result),v||(vm(t,d,p,m,g,y,s,l,u),m=g=y=null),_i(t,!0,-1),b=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&b!==0)Qt(t,"bad indentation of a mapping entry");else if(t.lineIndente?u=1:t.lineIndent===e?u=0:t.lineIndente?u=1:t.lineIndent===e?u=0:t.lineIndent tag; it should be "scalar", not "'+t.kind+'"'),d=0,p=t.implicitTypes.length;d"),t.result!==null&&g.kind!==t.kind&&Qt(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+g.kind+'", not "'+t.kind+'"'),g.resolve(t.result,t.tag)?(t.result=g.construct(t.result,t.tag),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):Qt(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||f}function W8e(t){var e=t.position,r,n,i,a=!1,s;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);(s=t.input.charCodeAt(t.position))!==0&&(_i(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||s!==37));){for(a=!0,s=t.input.charCodeAt(++t.position),r=t.position;s!==0&&!Os(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(r,t.position),i=[],n.length<1&&Qt(t,"directive name must not be less than one character in length");s!==0;){for(;Gd(s);)s=t.input.charCodeAt(++t.position);if(s===35){do s=t.input.charCodeAt(++t.position);while(s!==0&&!vc(s));break}if(vc(s))break;for(r=t.position;s!==0&&!Os(s);)s=t.input.charCodeAt(++t.position);i.push(t.input.slice(r,t.position))}s!==0&&Y9(t),Yh.call(mK,n)?mK[n](t,n,i):NT(t,'unknown document directive "'+n+'"')}if(_i(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,_i(t,!0,-1)):a&&Qt(t,"directives end mark is expected"),xm(t,t.lineIndent-1,RT,!1,!0),_i(t,!0,-1),t.checkLineBreaks&&D8e.test(t.input.slice(e,t.position))&&NT(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&OT(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,_i(t,!0,-1));return}if(t.position"u"&&(r=e,e=null);var n=$K(t,r);if(typeof e!="function")return n;for(var i=0,a=n.length;i=55296&&r<=56319&&e+1=56320&&n<=57343)?(r-55296)*1024+n-56320+65536:r}function XK(t){var e=/^\n* /;return e.test(t)}function T_e(t,e,r,n,i,a,s,l){var u,h=0,f=null,d=!1,p=!1,m=n!==-1,g=-1,y=x_e(g2(t,0))&&b_e(g2(t,t.length-1));if(e||s)for(u=0;u=65536?u+=2:u++){if(h=g2(t,u),!b2(h))return gm;y=y&&bK(h,f,l),f=h}else{for(u=0;u=65536?u+=2:u++){if(h=g2(t,u),h===v2)d=!0,m&&(p=p||u-g-1>n&&t[g+1]!==" ",g=u);else if(!b2(h))return gm;y=y&&bK(h,f,l),f=h}p=p||m&&u-g-1>n&&t[g+1]!==" "}return!d&&!p?y&&!s&&!i(t)?jK:a===x2?gm:H9:r>9&&XK(t)?gm:s?a===x2?gm:H9:p?QK:KK}function w_e(t,e,r,n,i){t.dump=function(){if(e.length===0)return t.quotingType===x2?'""':"''";if(!t.noCompatMode&&(f_e.indexOf(e)!==-1||d_e.test(e)))return t.quotingType===x2?'"'+e+'"':"'"+e+"'";var a=t.indent*Math.max(1,r),s=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-a),l=n||t.flowLevel>-1&&r>=t.flowLevel;function u(h){return v_e(t,h)}switch(o(u,"testAmbiguity"),T_e(e,l,t.indent,s,u,t.quotingType,t.forceQuotes&&!n,i)){case jK:return e;case H9:return"'"+e.replace(/'/g,"''")+"'";case KK:return"|"+TK(e,t.indent)+wK(vK(e,a));case QK:return">"+TK(e,t.indent)+wK(vK(k_e(e,s),a));case gm:return'"'+E_e(e)+'"';default:throw new Is("impossible error: invalid scalar style")}}()}function TK(t,e){var r=XK(t)?String(e):"",n=t[t.length-1]===` +`,i=n&&(t[t.length-2]===` +`||t===` +`),a=i?"+":n?"":"-";return r+a+` +`}function wK(t){return t[t.length-1]===` +`?t.slice(0,-1):t}function k_e(t,e){for(var r=/(\n+)([^\n]*)/g,n=function(){var h=t.indexOf(` +`);return h=h!==-1?h:t.length,r.lastIndex=h,kK(t.slice(0,h),e)}(),i=t[0]===` +`||t[0]===" ",a,s;s=r.exec(t);){var l=s[1],u=s[2];a=u[0]===" ",n+=l+(!i&&!a&&u!==""?` +`:"")+kK(u,e),i=a}return n}function kK(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,n,i=0,a,s=0,l=0,u="";n=r.exec(t);)l=n.index,l-i>e&&(a=s>i?s:l,u+=` +`+t.slice(i,a),i=a+1),s=l;return u+=` +`,t.length-i>e&&s>i?u+=t.slice(i,s)+` +`+t.slice(s+1):u+=t.slice(i),u.slice(1)}function E_e(t){for(var e="",r=0,n,i=0;i=65536?i+=2:i++)r=g2(t,i),n=Na[r],!n&&b2(r)?(e+=t[i],r>=65536&&(e+=t[i+1])):e+=n||m_e(r);return e}function S_e(t,e,r){var n="",i=t.tag,a,s,l;for(a=0,s=r.length;a"u"&&Ru(t,e,null,!1,!1))&&(n!==""&&(n+=","+(t.condenseFlow?"":" ")),n+=t.dump);t.tag=i,t.dump="["+n+"]"}function EK(t,e,r,n){var i="",a=t.tag,s,l,u;for(s=0,l=r.length;s"u"&&Ru(t,e+1,null,!0,!0,!1,!0))&&((!n||i!=="")&&(i+=U9(t,e)),t.dump&&v2===t.dump.charCodeAt(0)?i+="-":i+="- ",i+=t.dump);t.tag=a,t.dump=i||"[]"}function C_e(t,e,r){var n="",i=t.tag,a=Object.keys(r),s,l,u,h,f;for(s=0,l=a.length;s1024&&(f+="? "),f+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Ru(t,e,h,!1,!1)&&(f+=t.dump,n+=f));t.tag=i,t.dump="{"+n+"}"}function A_e(t,e,r,n){var i="",a=t.tag,s=Object.keys(r),l,u,h,f,d,p;if(t.sortKeys===!0)s.sort();else if(typeof t.sortKeys=="function")s.sort(t.sortKeys);else if(t.sortKeys)throw new Is("sortKeys must be a boolean or a function");for(l=0,u=s.length;l1024,d&&(t.dump&&v2===t.dump.charCodeAt(0)?p+="?":p+="? "),p+=t.dump,d&&(p+=U9(t,e)),Ru(t,e+1,f,!0,d)&&(t.dump&&v2===t.dump.charCodeAt(0)?p+=":":p+=": ",p+=t.dump,i+=p));t.tag=a,t.dump=i||"{}"}function SK(t,e,r){var n,i,a,s,l,u;for(i=r?t.explicitTypes:t.implicitTypes,a=0,s=i.length;a tag resolver accepts not "'+u+'" style');t.dump=n}return!0}return!1}function Ru(t,e,r,n,i,a,s){t.tag=null,t.dump=r,SK(t,r,!1)||SK(t,r,!0);var l=GK.call(t.dump),u=n,h;n&&(n=t.flowLevel<0||t.flowLevel>e);var f=l==="[object Object]"||l==="[object Array]",d,p;if(f&&(d=t.duplicates.indexOf(r),p=d!==-1),(t.tag!==null&&t.tag!=="?"||p||t.indent!==2&&e>0)&&(i=!1),p&&t.usedDuplicates[d])t.dump="*ref_"+d;else{if(f&&p&&!t.usedDuplicates[d]&&(t.usedDuplicates[d]=!0),l==="[object Object]")n&&Object.keys(t.dump).length!==0?(A_e(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(C_e(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object Array]")n&&t.dump.length!==0?(t.noArrayIndent&&!s&&e>0?EK(t,e-1,t.dump,i):EK(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(S_e(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object String]")t.tag!=="?"&&w_e(t,t.dump,e,a,u);else{if(l==="[object Undefined]")return!1;if(t.skipInvalid)return!1;throw new Is("unacceptable kind of an object to dump "+l)}t.tag!==null&&t.tag!=="?"&&(h=encodeURI(t.tag[0]==="!"?t.tag.slice(1):t.tag).replace(/!/g,"%21"),t.tag[0]==="!"?h="!"+h:h.slice(0,18)==="tag:yaml.org,2002:"?h="!!"+h.slice(18):h="!<"+h+">",t.dump=h+" "+t.dump)}return!0}function __e(t,e){var r=[],n=[],i,a;for(W9(t,r,n),i=0,a=n.length;i{"use strict";o(CK,"isNothing");o(hAe,"isObject");o(fAe,"toArray");o(dAe,"extend");o(pAe,"repeat");o(mAe,"isNegativeZero");gAe=CK,yAe=hAe,vAe=fAe,xAe=pAe,bAe=mAe,TAe=dAe,Gi={isNothing:gAe,isObject:yAe,toArray:vAe,repeat:xAe,isNegativeZero:bAe,extend:TAe};o(AK,"formatError");o(y2,"YAMLException$1");y2.prototype=Object.create(Error.prototype);y2.prototype.constructor=y2;y2.prototype.toString=o(function(e){return this.name+": "+AK(this,e)},"toString");Is=y2;o(F9,"getLine");o($9,"padStart");o(wAe,"makeSnippet");kAe=wAe,EAe=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],SAe=["scalar","sequence","mapping"];o(CAe,"compileStyleAliases");o(AAe,"Type$1");Ra=AAe;o(hK,"compileList");o(_Ae,"compileMap");o(G9,"Schema$1");G9.prototype.extend=o(function(e){var r=[],n=[];if(e instanceof Ra)n.push(e);else if(Array.isArray(e))n=n.concat(e);else if(e&&(Array.isArray(e.implicit)||Array.isArray(e.explicit)))e.implicit&&(r=r.concat(e.implicit)),e.explicit&&(n=n.concat(e.explicit));else throw new Is("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");r.forEach(function(a){if(!(a instanceof Ra))throw new Is("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(a.loadKind&&a.loadKind!=="scalar")throw new Is("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(a.multi)throw new Is("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),n.forEach(function(a){if(!(a instanceof Ra))throw new Is("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var i=Object.create(G9.prototype);return i.implicit=(this.implicit||[]).concat(r),i.explicit=(this.explicit||[]).concat(n),i.compiledImplicit=hK(i,"implicit"),i.compiledExplicit=hK(i,"explicit"),i.compiledTypeMap=_Ae(i.compiledImplicit,i.compiledExplicit),i},"extend");DAe=G9,LAe=new Ra("tag:yaml.org,2002:str",{kind:"scalar",construct:o(function(t){return t!==null?t:""},"construct")}),RAe=new Ra("tag:yaml.org,2002:seq",{kind:"sequence",construct:o(function(t){return t!==null?t:[]},"construct")}),NAe=new Ra("tag:yaml.org,2002:map",{kind:"mapping",construct:o(function(t){return t!==null?t:{}},"construct")}),MAe=new DAe({explicit:[LAe,RAe,NAe]});o(IAe,"resolveYamlNull");o(OAe,"constructYamlNull");o(PAe,"isNull");BAe=new Ra("tag:yaml.org,2002:null",{kind:"scalar",resolve:IAe,construct:OAe,predicate:PAe,represent:{canonical:o(function(){return"~"},"canonical"),lowercase:o(function(){return"null"},"lowercase"),uppercase:o(function(){return"NULL"},"uppercase"),camelcase:o(function(){return"Null"},"camelcase"),empty:o(function(){return""},"empty")},defaultStyle:"lowercase"});o(FAe,"resolveYamlBoolean");o($Ae,"constructYamlBoolean");o(zAe,"isBoolean");GAe=new Ra("tag:yaml.org,2002:bool",{kind:"scalar",resolve:FAe,construct:$Ae,predicate:zAe,represent:{lowercase:o(function(t){return t?"true":"false"},"lowercase"),uppercase:o(function(t){return t?"TRUE":"FALSE"},"uppercase"),camelcase:o(function(t){return t?"True":"False"},"camelcase")},defaultStyle:"lowercase"});o(VAe,"isHexCode");o(UAe,"isOctCode");o(HAe,"isDecCode");o(WAe,"resolveYamlInteger");o(qAe,"constructYamlInteger");o(YAe,"isInteger");XAe=new Ra("tag:yaml.org,2002:int",{kind:"scalar",resolve:WAe,construct:qAe,predicate:YAe,represent:{binary:o(function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},"binary"),octal:o(function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},"octal"),decimal:o(function(t){return t.toString(10)},"decimal"),hexadecimal:o(function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)},"hexadecimal")},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),jAe=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");o(KAe,"resolveYamlFloat");o(QAe,"constructYamlFloat");ZAe=/^[-+]?[0-9]+e/;o(JAe,"representYamlFloat");o(e8e,"isFloat");t8e=new Ra("tag:yaml.org,2002:float",{kind:"scalar",resolve:KAe,construct:QAe,predicate:e8e,represent:JAe,defaultStyle:"lowercase"}),_K=MAe.extend({implicit:[BAe,GAe,XAe,t8e]}),r8e=_K,DK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),LK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");o(n8e,"resolveYamlTimestamp");o(i8e,"constructYamlTimestamp");o(a8e,"representYamlTimestamp");s8e=new Ra("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:n8e,construct:i8e,instanceOf:Date,represent:a8e});o(o8e,"resolveYamlMerge");l8e=new Ra("tag:yaml.org,2002:merge",{kind:"scalar",resolve:o8e}),q9=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;o(c8e,"resolveYamlBinary");o(u8e,"constructYamlBinary");o(h8e,"representYamlBinary");o(f8e,"isBinary");d8e=new Ra("tag:yaml.org,2002:binary",{kind:"scalar",resolve:c8e,construct:u8e,predicate:f8e,represent:h8e}),p8e=Object.prototype.hasOwnProperty,m8e=Object.prototype.toString;o(g8e,"resolveYamlOmap");o(y8e,"constructYamlOmap");v8e=new Ra("tag:yaml.org,2002:omap",{kind:"sequence",resolve:g8e,construct:y8e}),x8e=Object.prototype.toString;o(b8e,"resolveYamlPairs");o(T8e,"constructYamlPairs");w8e=new Ra("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:b8e,construct:T8e}),k8e=Object.prototype.hasOwnProperty;o(E8e,"resolveYamlSet");o(S8e,"constructYamlSet");C8e=new Ra("tag:yaml.org,2002:set",{kind:"mapping",resolve:E8e,construct:S8e}),RK=r8e.extend({implicit:[s8e,l8e],explicit:[d8e,v8e,w8e,C8e]}),Yh=Object.prototype.hasOwnProperty,LT=1,NK=2,MK=3,RT=4,z9=1,A8e=2,fK=3,_8e=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,D8e=/[\x85\u2028\u2029]/,L8e=/[,\[\]\{\}]/,IK=/^(?:!|!!|![a-z\-]+!)$/i,OK=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;o(dK,"_class");o(vc,"is_EOL");o(Gd,"is_WHITE_SPACE");o(Os,"is_WS_OR_EOL");o(ym,"is_FLOW_INDICATOR");o(R8e,"fromHexCode");o(N8e,"escapedHexLen");o(M8e,"fromDecimalCode");o(pK,"simpleEscapeSequence");o(I8e,"charFromCodepoint");PK=new Array(256),BK=new Array(256);for(zd=0;zd<256;zd++)PK[zd]=pK(zd)?1:0,BK[zd]=pK(zd);o(O8e,"State$1");o(FK,"generateError");o(Qt,"throwError");o(NT,"throwWarning");mK={YAML:o(function(e,r,n){var i,a,s;e.version!==null&&Qt(e,"duplication of %YAML directive"),n.length!==1&&Qt(e,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),i===null&&Qt(e,"ill-formed argument of the YAML directive"),a=parseInt(i[1],10),s=parseInt(i[2],10),a!==1&&Qt(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=s<2,s!==1&&s!==2&&NT(e,"unsupported YAML version of the document")},"handleYamlDirective"),TAG:o(function(e,r,n){var i,a;n.length!==2&&Qt(e,"TAG directive accepts exactly two arguments"),i=n[0],a=n[1],IK.test(i)||Qt(e,"ill-formed tag handle (first argument) of the TAG directive"),Yh.call(e.tagMap,i)&&Qt(e,'there is a previously declared suffix for "'+i+'" tag handle'),OK.test(a)||Qt(e,"ill-formed tag prefix (second argument) of the TAG directive");try{a=decodeURIComponent(a)}catch{Qt(e,"tag prefix is malformed: "+a)}e.tagMap[i]=a},"handleTagDirective")};o(qh,"captureSegment");o(gK,"mergeMappings");o(vm,"storeMappingPair");o(Y9,"readLineBreak");o(_i,"skipSeparationSpace");o(OT,"testDocumentSeparator");o(X9,"writeFoldedLines");o(P8e,"readPlainScalar");o(B8e,"readSingleQuotedScalar");o(F8e,"readDoubleQuotedScalar");o($8e,"readFlowCollection");o(z8e,"readBlockScalar");o(yK,"readBlockSequence");o(G8e,"readBlockMapping");o(V8e,"readTagProperty");o(U8e,"readAnchorProperty");o(H8e,"readAlias");o(xm,"composeNode");o(W8e,"readDocument");o($K,"loadDocuments");o(q8e,"loadAll$1");o(Y8e,"load$1");X8e=q8e,j8e=Y8e,zK={loadAll:X8e,load:j8e},GK=Object.prototype.toString,VK=Object.prototype.hasOwnProperty,j9=65279,K8e=9,v2=10,Q8e=13,Z8e=32,J8e=33,e_e=34,V9=35,t_e=37,r_e=38,n_e=39,i_e=42,UK=44,a_e=45,MT=58,s_e=61,o_e=62,l_e=63,c_e=64,HK=91,WK=93,u_e=96,qK=123,h_e=124,YK=125,Na={};Na[0]="\\0";Na[7]="\\a";Na[8]="\\b";Na[9]="\\t";Na[10]="\\n";Na[11]="\\v";Na[12]="\\f";Na[13]="\\r";Na[27]="\\e";Na[34]='\\"';Na[92]="\\\\";Na[133]="\\N";Na[160]="\\_";Na[8232]="\\L";Na[8233]="\\P";f_e=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],d_e=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;o(p_e,"compileStyleMap");o(m_e,"encodeHex");g_e=1,x2=2;o(y_e,"State");o(vK,"indentString");o(U9,"generateNextLine");o(v_e,"testImplicitResolving");o(IT,"isWhitespace");o(b2,"isPrintable");o(xK,"isNsCharOrWhitespace");o(bK,"isPlainSafe");o(x_e,"isPlainSafeFirst");o(b_e,"isPlainSafeLast");o(g2,"codePointAt");o(XK,"needIndentIndicator");jK=1,H9=2,KK=3,QK=4,gm=5;o(T_e,"chooseScalarStyle");o(w_e,"writeScalar");o(TK,"blockHeader");o(wK,"dropEndingNewline");o(k_e,"foldString");o(kK,"foldLine");o(E_e,"escapeString");o(S_e,"writeFlowSequence");o(EK,"writeBlockSequence");o(C_e,"writeFlowMapping");o(A_e,"writeBlockMapping");o(SK,"detectType");o(Ru,"writeNode");o(__e,"getDuplicateReferences");o(W9,"inspectNode");o(D_e,"dump$1");L_e=D_e,R_e={dump:L_e};o(K9,"renamed");bm=_K,Tm=zK.load,qSt=zK.loadAll,YSt=R_e.dump,XSt=K9("safeLoad","load"),jSt=K9("safeLoadAll","loadAll"),KSt=K9("safeDump","dump")});function tL(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function nQ(t){Ud=t}function nn(t,e=""){let r=typeof t=="string"?t:t.source,n={replace:o((i,a)=>{let s=typeof a=="string"?a:a.source;return s=s.replace(ss.caret,"$1"),r=r.replace(i,s),n},"replace"),getRegex:o(()=>new RegExp(r,e),"getRegex")};return n}function xc(t,e){if(e){if(ss.escapeTest.test(t))return t.replace(ss.escapeReplace,JK)}else if(ss.escapeTestNoEncode.test(t))return t.replace(ss.escapeReplaceNoEncode,JK);return t}function eQ(t){try{t=encodeURI(t).replace(ss.percentDecode,"%")}catch{return null}return t}function tQ(t,e){let r=t.replace(ss.findPipe,(a,s,l)=>{let u=!1,h=s;for(;--h>=0&&l[h]==="\\";)u=!u;return u?"|":" |"}),n=r.split(ss.splitPipe),i=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length0?-2:-1}function rQ(t,e,r,n,i){let a=e.href,s=e.title||null,l=t[1].replace(i.other.outputLinkReplace,"$1");n.state.inLink=!0;let u={type:t[0].charAt(0)==="!"?"image":"link",raw:r,href:a,title:s,text:l,tokens:n.inlineTokens(l)};return n.state.inLink=!1,u}function fDe(t,e,r){let n=t.match(r.other.indentCodeCompensation);if(n===null)return e;let i=n[1];return e.split(` +`).map(a=>{let s=a.match(r.other.beginningSpace);if(s===null)return a;let[l]=s;return l.length>=i.length?a.slice(i.length):a}).join(` +`)}function Jr(t,e){return Vd.parse(t,e)}var Ud,k2,ss,N_e,M_e,I_e,E2,O_e,rL,iQ,aQ,P_e,nL,B_e,iL,F_e,$_e,VT,aL,z_e,sQ,G_e,sL,ZK,V_e,U_e,H_e,W_e,oQ,q_e,UT,oL,lQ,Y_e,cQ,X_e,j_e,K_e,uQ,Q_e,Z_e,hQ,J_e,eDe,tDe,rDe,nDe,iDe,aDe,$T,sDe,fQ,dQ,oDe,lL,lDe,Z9,cDe,BT,T2,uDe,JK,zT,Nu,GT,cL,Mu,FT,dDe,Vd,ZSt,JSt,e6t,t6t,r6t,n6t,i6t,pQ=N(()=>{"use strict";o(tL,"M");Ud=tL();o(nQ,"H");k2={exec:o(()=>null,"exec")};o(nn,"h");ss={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:o(t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\n]*)?(?:\\n|$))`),"listItemRegex"),nextBulletRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),"nextBulletRegex"),hrRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),"hrRegex"),fencesBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:\`\`\`|~~~)`),"fencesBeginRegex"),headingBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}#`),"headingBeginRegex"),htmlBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}<(?:[a-z].*>|!--)`,"i"),"htmlBeginRegex")},N_e=/^(?:[ \t]*(?:\n|$))+/,M_e=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,I_e=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,E2=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,O_e=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,rL=/(?:[*+-]|\d{1,9}[.)])/,iQ=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,aQ=nn(iQ).replace(/bull/g,rL).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),P_e=nn(iQ).replace(/bull/g,rL).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),nL=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,B_e=/^[^\n]+/,iL=/(?!\s*\])(?:\\.|[^\[\]\\])+/,F_e=nn(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",iL).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),$_e=nn(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,rL).getRegex(),VT="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",aL=/|$))/,z_e=nn("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",aL).replace("tag",VT).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),sQ=nn(nL).replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex(),G_e=nn(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",sQ).getRegex(),sL={blockquote:G_e,code:M_e,def:F_e,fences:I_e,heading:O_e,hr:E2,html:z_e,lheading:aQ,list:$_e,newline:N_e,paragraph:sQ,table:k2,text:B_e},ZK=nn("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex(),V_e={...sL,lheading:P_e,table:ZK,paragraph:nn(nL).replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",ZK).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex()},U_e={...sL,html:nn(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",aL).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:k2,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:nn(nL).replace("hr",E2).replace("heading",` *#{1,6} *[^ +]`).replace("lheading",aQ).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},H_e=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,W_e=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,oQ=/^( {2,}|\\)\n(?!\s*$)/,q_e=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\]*?>/g,uQ=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,Q_e=nn(uQ,"u").replace(/punct/g,UT).getRegex(),Z_e=nn(uQ,"u").replace(/punct/g,cQ).getRegex(),hQ="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",J_e=nn(hQ,"gu").replace(/notPunctSpace/g,lQ).replace(/punctSpace/g,oL).replace(/punct/g,UT).getRegex(),eDe=nn(hQ,"gu").replace(/notPunctSpace/g,j_e).replace(/punctSpace/g,X_e).replace(/punct/g,cQ).getRegex(),tDe=nn("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,lQ).replace(/punctSpace/g,oL).replace(/punct/g,UT).getRegex(),rDe=nn(/\\(punct)/,"gu").replace(/punct/g,UT).getRegex(),nDe=nn(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),iDe=nn(aL).replace("(?:-->|$)","-->").getRegex(),aDe=nn("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",iDe).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),$T=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,sDe=nn(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",$T).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),fQ=nn(/^!?\[(label)\]\[(ref)\]/).replace("label",$T).replace("ref",iL).getRegex(),dQ=nn(/^!?\[(ref)\](?:\[\])?/).replace("ref",iL).getRegex(),oDe=nn("reflink|nolink(?!\\()","g").replace("reflink",fQ).replace("nolink",dQ).getRegex(),lL={_backpedal:k2,anyPunctuation:rDe,autolink:nDe,blockSkip:K_e,br:oQ,code:W_e,del:k2,emStrongLDelim:Q_e,emStrongRDelimAst:J_e,emStrongRDelimUnd:tDe,escape:H_e,link:sDe,nolink:dQ,punctuation:Y_e,reflink:fQ,reflinkSearch:oDe,tag:aDe,text:q_e,url:k2},lDe={...lL,link:nn(/^!?\[(label)\]\((.*?)\)/).replace("label",$T).getRegex(),reflink:nn(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",$T).getRegex()},Z9={...lL,emStrongRDelimAst:eDe,emStrongLDelim:Z_e,url:nn(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},JK=o(t=>uDe[t],"ge");o(xc,"R");o(eQ,"J");o(tQ,"V");o(w2,"A");o(hDe,"fe");o(rQ,"de");o(fDe,"Je");zT=class{static{o(this,"S")}options;rules;lexer;constructor(t){this.options=t||Ud}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let r=e[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?r:w2(r,` +`)}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let r=e[0],n=fDe(r,e[3]||"",this.rules);return{type:"code",raw:r,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:n}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let r=e[2].trim();if(this.rules.other.endingHash.test(r)){let n=w2(r,"#");(this.options.pedantic||!n||this.rules.other.endingSpaceChar.test(n))&&(r=n.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:r,tokens:this.lexer.inline(r)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:w2(e[0],` +`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let r=w2(e[0],` +`).split(` +`),n="",i="",a=[];for(;r.length>0;){let s=!1,l=[],u;for(u=0;u1,i={type:"list",raw:"",ordered:n,start:n?+r.slice(0,-1):"",loose:!1,items:[]};r=n?`\\d{1,9}\\${r.slice(-1)}`:`\\${r}`,this.options.pedantic&&(r=n?r:"[*+-]");let a=this.rules.other.listItemRegex(r),s=!1;for(;t;){let u=!1,h="",f="";if(!(e=a.exec(t))||this.rules.block.hr.test(t))break;h=e[0],t=t.substring(h.length);let d=e[2].split(` +`,1)[0].replace(this.rules.other.listReplaceTabs,x=>" ".repeat(3*x.length)),p=t.split(` +`,1)[0],m=!d.trim(),g=0;if(this.options.pedantic?(g=2,f=d.trimStart()):m?g=e[1].length+1:(g=e[2].search(this.rules.other.nonSpaceChar),g=g>4?1:g,f=d.slice(g),g+=e[1].length),m&&this.rules.other.blankLine.test(p)&&(h+=p+` +`,t=t.substring(p.length+1),u=!0),!u){let x=this.rules.other.nextBulletRegex(g),b=this.rules.other.hrRegex(g),T=this.rules.other.fencesBeginRegex(g),S=this.rules.other.headingBeginRegex(g),w=this.rules.other.htmlBeginRegex(g);for(;t;){let E=t.split(` +`,1)[0],_;if(p=E,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),_=p):_=p.replace(this.rules.other.tabCharGlobal," "),T.test(p)||S.test(p)||w.test(p)||x.test(p)||b.test(p))break;if(_.search(this.rules.other.nonSpaceChar)>=g||!p.trim())f+=` +`+_.slice(g);else{if(m||d.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||T.test(d)||S.test(d)||b.test(d))break;f+=` +`+p}!m&&!p.trim()&&(m=!0),h+=E+` +`,t=t.substring(E.length+1),d=_.slice(g)}}i.loose||(s?i.loose=!0:this.rules.other.doubleBlankLine.test(h)&&(s=!0));let y=null,v;this.options.gfm&&(y=this.rules.other.listIsTask.exec(f),y&&(v=y[0]!=="[ ] ",f=f.replace(this.rules.other.listReplaceTask,""))),i.items.push({type:"list_item",raw:h,task:!!y,checked:v,loose:!1,text:f,tokens:[]}),i.raw+=h}let l=i.items.at(-1);if(l)l.raw=l.raw.trimEnd(),l.text=l.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let u=0;ud.type==="space"),f=h.length>0&&h.some(d=>this.rules.other.anyLine.test(d.raw));i.loose=f}if(i.loose)for(let u=0;u({text:l,tokens:this.lexer.inline(l),header:!1,align:a.align[u]})));return a}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e)return{type:"heading",raw:e[0],depth:e[2].charAt(0)==="="?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let r=e[1].charAt(e[1].length-1)===` +`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:r,tokens:this.lexer.inline(r)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){let e=this.rules.inline.link.exec(t);if(e){let r=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(r)){if(!this.rules.other.endAngleBracket.test(r))return;let a=w2(r.slice(0,-1),"\\");if((r.length-a.length)%2===0)return}else{let a=hDe(e[2],"()");if(a===-2)return;if(a>-1){let s=(e[0].indexOf("!")===0?5:4)+e[1].length+a;e[2]=e[2].substring(0,a),e[0]=e[0].substring(0,s).trim(),e[3]=""}}let n=e[2],i="";if(this.options.pedantic){let a=this.rules.other.pedanticHrefTitle.exec(n);a&&(n=a[1],i=a[3])}else i=e[3]?e[3].slice(1,-1):"";return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(r)?n=n.slice(1):n=n.slice(1,-1)),rQ(e,{href:n&&n.replace(this.rules.inline.anyPunctuation,"$1"),title:i&&i.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let r;if((r=this.rules.inline.reflink.exec(t))||(r=this.rules.inline.nolink.exec(t))){let n=(r[2]||r[1]).replace(this.rules.other.multipleSpaceGlobal," "),i=e[n.toLowerCase()];if(!i){let a=r[0].charAt(0);return{type:"text",raw:a,text:a}}return rQ(r,i,r[0],this.lexer,this.rules)}}emStrong(t,e,r=""){let n=this.rules.inline.emStrongLDelim.exec(t);if(!(!n||n[3]&&r.match(this.rules.other.unicodeAlphaNumeric))&&(!(n[1]||n[2])||!r||this.rules.inline.punctuation.exec(r))){let i=[...n[0]].length-1,a,s,l=i,u=0,h=n[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(h.lastIndex=0,e=e.slice(-1*t.length+i);(n=h.exec(e))!=null;){if(a=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!a)continue;if(s=[...a].length,n[3]||n[4]){l+=s;continue}else if((n[5]||n[6])&&i%3&&!((i+s)%3)){u+=s;continue}if(l-=s,l>0)continue;s=Math.min(s,s+l+u);let f=[...n[0]][0].length,d=t.slice(0,i+n.index+f+s);if(Math.min(i,s)%2){let m=d.slice(1,-1);return{type:"em",raw:d,text:m,tokens:this.lexer.inlineTokens(m)}}let p=d.slice(2,-2);return{type:"strong",raw:d,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let r=e[2].replace(this.rules.other.newLineCharGlobal," "),n=this.rules.other.nonSpaceChar.test(r),i=this.rules.other.startingSpaceChar.test(r)&&this.rules.other.endingSpaceChar.test(r);return n&&i&&(r=r.substring(1,r.length-1)),{type:"codespan",raw:e[0],text:r}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t){let e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let r,n;return e[2]==="@"?(r=e[1],n="mailto:"+r):(r=e[1],n=r),{type:"link",raw:e[0],text:r,href:n,tokens:[{type:"text",raw:r,text:r}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let r,n;if(e[2]==="@")r=e[0],n="mailto:"+r;else{let i;do i=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(i!==e[0]);r=e[0],e[1]==="www."?n="http://"+e[0]:n=e[0]}return{type:"link",raw:e[0],text:r,href:n,tokens:[{type:"text",raw:r,text:r}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let r=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:r}}}},Nu=class J9{static{o(this,"a")}tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||Ud,this.options.tokenizer=this.options.tokenizer||new zT,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let r={other:ss,block:BT.normal,inline:T2.normal};this.options.pedantic?(r.block=BT.pedantic,r.inline=T2.pedantic):this.options.gfm&&(r.block=BT.gfm,this.options.breaks?r.inline=T2.breaks:r.inline=T2.gfm),this.tokenizer.rules=r}static get rules(){return{block:BT,inline:T2}}static lex(e,r){return new J9(r).lex(e)}static lexInline(e,r){return new J9(r).inlineTokens(e)}lex(e){e=e.replace(ss.carriageReturn,` +`),this.blockTokens(e,this.tokens);for(let r=0;r(i=s.call({lexer:this},e,r))?(e=e.substring(i.raw.length),r.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let s=r.at(-1);i.raw.length===1&&s!==void 0?s.raw+=` +`:r.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=` +`+i.raw,s.text+=` +`+i.text,this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=` +`+i.raw,s.text+=` +`+i.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title});continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),r.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let s=1/0,l=e.slice(1),u;this.options.extensions.startBlock.forEach(h=>{u=h.call({lexer:this},l),typeof u=="number"&&u>=0&&(s=Math.min(s,u))}),s<1/0&&s>=0&&(a=e.substring(0,s+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let s=r.at(-1);n&&s?.type==="paragraph"?(s.raw+=` +`+i.raw,s.text+=` +`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i),n=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="text"?(s.raw+=` +`+i.raw,s.text+=` +`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(e){let s="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,r}inline(e,r=[]){return this.inlineQueue.push({src:e,tokens:r}),r}inlineTokens(e,r=[]){let n=e,i=null;if(this.tokens.links){let l=Object.keys(this.tokens.links);if(l.length>0)for(;(i=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)l.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(i=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,i.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(i=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);let a=!1,s="";for(;e;){a||(s=""),a=!1;let l;if(this.options.extensions?.inline?.some(h=>(l=h.call({lexer:this},e,r))?(e=e.substring(l.raw.length),r.push(l),!0):!1))continue;if(l=this.tokenizer.escape(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.tag(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.link(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(l.raw.length);let h=r.at(-1);l.type==="text"&&h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(l=this.tokenizer.emStrong(e,n,s)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.codespan(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.br(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.del(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.autolink(e)){e=e.substring(l.raw.length),r.push(l);continue}if(!this.state.inLink&&(l=this.tokenizer.url(e))){e=e.substring(l.raw.length),r.push(l);continue}let u=e;if(this.options.extensions?.startInline){let h=1/0,f=e.slice(1),d;this.options.extensions.startInline.forEach(p=>{d=p.call({lexer:this},f),typeof d=="number"&&d>=0&&(h=Math.min(h,d))}),h<1/0&&h>=0&&(u=e.substring(0,h+1))}if(l=this.tokenizer.inlineText(u)){e=e.substring(l.raw.length),l.raw.slice(-1)!=="_"&&(s=l.raw.slice(-1)),a=!0;let h=r.at(-1);h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(e){let h="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(h);break}else throw new Error(h)}}return r}},GT=class{static{o(this,"$")}options;parser;constructor(t){this.options=t||Ud}space(t){return""}code({text:t,lang:e,escaped:r}){let n=(e||"").match(ss.notSpaceStart)?.[0],i=t.replace(ss.endingNewline,"")+` +`;return n?'
    '+(r?i:xc(i,!0))+`
    +`:"
    "+(r?i:xc(i,!0))+`
    +`}blockquote({tokens:t}){return`
    +${this.parser.parse(t)}
    +`}html({text:t}){return t}heading({tokens:t,depth:e}){return`${this.parser.parseInline(t)} +`}hr(t){return`
    +`}list(t){let e=t.ordered,r=t.start,n="";for(let s=0;s +`+n+" +`}listitem(t){let e="";if(t.task){let r=this.checkbox({checked:!!t.checked});t.loose?t.tokens[0]?.type==="paragraph"?(t.tokens[0].text=r+" "+t.tokens[0].text,t.tokens[0].tokens&&t.tokens[0].tokens.length>0&&t.tokens[0].tokens[0].type==="text"&&(t.tokens[0].tokens[0].text=r+" "+xc(t.tokens[0].tokens[0].text),t.tokens[0].tokens[0].escaped=!0)):t.tokens.unshift({type:"text",raw:r+" ",text:r+" ",escaped:!0}):e+=r+" "}return e+=this.parser.parse(t.tokens,!!t.loose),`
  • ${e}
  • +`}checkbox({checked:t}){return"'}paragraph({tokens:t}){return`

    ${this.parser.parseInline(t)}

    +`}table(t){let e="",r="";for(let i=0;i${n}`),` + +`+e+` +`+n+`
    +`}tablerow({text:t}){return` +${t} +`}tablecell(t){let e=this.parser.parseInline(t.tokens),r=t.header?"th":"td";return(t.align?`<${r} align="${t.align}">`:`<${r}>`)+e+` +`}strong({tokens:t}){return`${this.parser.parseInline(t)}`}em({tokens:t}){return`${this.parser.parseInline(t)}`}codespan({text:t}){return`${xc(t,!0)}`}br(t){return"
    "}del({tokens:t}){return`${this.parser.parseInline(t)}`}link({href:t,title:e,tokens:r}){let n=this.parser.parseInline(r),i=eQ(t);if(i===null)return n;t=i;let a='
    ",a}image({href:t,title:e,text:r,tokens:n}){n&&(r=this.parser.parseInline(n,this.parser.textRenderer));let i=eQ(t);if(i===null)return xc(r);t=i;let a=`${r}{let s=i[a].flat(1/0);r=r.concat(this.walkTokens(s,e))}):i.tokens&&(r=r.concat(this.walkTokens(i.tokens,e)))}}return r}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(r=>{let n={...r};if(n.async=this.defaults.async||n.async||!1,r.extensions&&(r.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let a=e.renderers[i.name];a?e.renderers[i.name]=function(...s){let l=i.renderer.apply(this,s);return l===!1&&(l=a.apply(this,s)),l}:e.renderers[i.name]=i.renderer}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let a=e[i.level];a?a.unshift(i.tokenizer):e[i.level]=[i.tokenizer],i.start&&(i.level==="block"?e.startBlock?e.startBlock.push(i.start):e.startBlock=[i.start]:i.level==="inline"&&(e.startInline?e.startInline.push(i.start):e.startInline=[i.start]))}"childTokens"in i&&i.childTokens&&(e.childTokens[i.name]=i.childTokens)}),n.extensions=e),r.renderer){let i=this.defaults.renderer||new GT(this.defaults);for(let a in r.renderer){if(!(a in i))throw new Error(`renderer '${a}' does not exist`);if(["options","parser"].includes(a))continue;let s=a,l=r.renderer[s],u=i[s];i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f||""}}n.renderer=i}if(r.tokenizer){let i=this.defaults.tokenizer||new zT(this.defaults);for(let a in r.tokenizer){if(!(a in i))throw new Error(`tokenizer '${a}' does not exist`);if(["options","rules","lexer"].includes(a))continue;let s=a,l=r.tokenizer[s],u=i[s];i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f}}n.tokenizer=i}if(r.hooks){let i=this.defaults.hooks||new FT;for(let a in r.hooks){if(!(a in i))throw new Error(`hook '${a}' does not exist`);if(["options","block"].includes(a))continue;let s=a,l=r.hooks[s],u=i[s];FT.passThroughHooks.has(a)?i[s]=h=>{if(this.defaults.async)return Promise.resolve(l.call(i,h)).then(d=>u.call(i,d));let f=l.call(i,h);return u.call(i,f)}:i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f}}n.hooks=i}if(r.walkTokens){let i=this.defaults.walkTokens,a=r.walkTokens;n.walkTokens=function(s){let l=[];return l.push(a.call(this,s)),i&&(l=l.concat(i.call(this,s))),l}}this.defaults={...this.defaults,...n}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return Nu.lex(t,e??this.defaults)}parser(t,e){return Mu.parse(t,e??this.defaults)}parseMarkdown(t){return(e,r)=>{let n={...r},i={...this.defaults,...n},a=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&n.async===!1)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return a(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return a(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));i.hooks&&(i.hooks.options=i,i.hooks.block=t);let s=i.hooks?i.hooks.provideLexer():t?Nu.lex:Nu.lexInline,l=i.hooks?i.hooks.provideParser():t?Mu.parse:Mu.parseInline;if(i.async)return Promise.resolve(i.hooks?i.hooks.preprocess(e):e).then(u=>s(u,i)).then(u=>i.hooks?i.hooks.processAllTokens(u):u).then(u=>i.walkTokens?Promise.all(this.walkTokens(u,i.walkTokens)).then(()=>u):u).then(u=>l(u,i)).then(u=>i.hooks?i.hooks.postprocess(u):u).catch(a);try{i.hooks&&(e=i.hooks.preprocess(e));let u=s(e,i);i.hooks&&(u=i.hooks.processAllTokens(u)),i.walkTokens&&this.walkTokens(u,i.walkTokens);let h=l(u,i);return i.hooks&&(h=i.hooks.postprocess(h)),h}catch(u){return a(u)}}}onError(t,e){return r=>{if(r.message+=` +Please report this to https://github.com/markedjs/marked.`,t){let n="

    An error occurred:

    "+xc(r.message+"",!0)+"
    ";return e?Promise.resolve(n):n}if(e)return Promise.reject(r);throw r}}},Vd=new dDe;o(Jr,"k");Jr.options=Jr.setOptions=function(t){return Vd.setOptions(t),Jr.defaults=Vd.defaults,nQ(Jr.defaults),Jr};Jr.getDefaults=tL;Jr.defaults=Ud;Jr.use=function(...t){return Vd.use(...t),Jr.defaults=Vd.defaults,nQ(Jr.defaults),Jr};Jr.walkTokens=function(t,e){return Vd.walkTokens(t,e)};Jr.parseInline=Vd.parseInline;Jr.Parser=Mu;Jr.parser=Mu.parse;Jr.Renderer=GT;Jr.TextRenderer=cL;Jr.Lexer=Nu;Jr.lexer=Nu.lex;Jr.Tokenizer=zT;Jr.Hooks=FT;Jr.parse=Jr;ZSt=Jr.options,JSt=Jr.setOptions,e6t=Jr.use,t6t=Jr.walkTokens,r6t=Jr.parseInline,n6t=Mu.parse,i6t=Nu.lex});function pDe(t,{markdownAutoWrap:e}){let n=t.replace(//g,` +`).replace(/\n{2,}/g,` +`),i=j4(n);return e===!1?i.replace(/ /g," "):i}function mQ(t,e={}){let r=pDe(t,e),n=Jr.lexer(r),i=[[]],a=0;function s(l,u="normal"){l.type==="text"?l.text.split(` +`).forEach((f,d)=>{d!==0&&(a++,i.push([])),f.split(" ").forEach(p=>{p=p.replace(/'/g,"'"),p&&i[a].push({content:p,type:u})})}):l.type==="strong"||l.type==="em"?l.tokens.forEach(h=>{s(h,l.type)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}return o(s,"processNode"),n.forEach(l=>{l.type==="paragraph"?l.tokens?.forEach(u=>{s(u)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}),i}function gQ(t,{markdownAutoWrap:e}={}){let r=Jr.lexer(t);function n(i){return i.type==="text"?e===!1?i.text.replace(/\n */g,"
    ").replace(/ /g," "):i.text.replace(/\n */g,"
    "):i.type==="strong"?`${i.tokens?.map(n).join("")}`:i.type==="em"?`${i.tokens?.map(n).join("")}`:i.type==="paragraph"?`

    ${i.tokens?.map(n).join("")}

    `:i.type==="space"?"":i.type==="html"?`${i.text}`:i.type==="escape"?i.text:`Unsupported markdown: ${i.type}`}return o(n,"output"),r.map(n).join("")}var yQ=N(()=>{"use strict";pQ();r7();o(pDe,"preprocessMarkdown");o(mQ,"markdownToLines");o(gQ,"markdownToHTML")});function mDe(t){return Intl.Segmenter?[...new Intl.Segmenter().segment(t)].map(e=>e.segment):[...t]}function gDe(t,e){let r=mDe(e.content);return vQ(t,[],r,e.type)}function vQ(t,e,r,n){if(r.length===0)return[{content:e.join(""),type:n},{content:"",type:n}];let[i,...a]=r,s=[...e,i];return t([{content:s.join(""),type:n}])?vQ(t,s,a,n):(e.length===0&&i&&(e.push(i),r.shift()),[{content:e.join(""),type:n},{content:r.join(""),type:n}])}function xQ(t,e){if(t.some(({content:r})=>r.includes(` +`)))throw new Error("splitLineToFitWidth does not support newlines in the line");return uL(t,e)}function uL(t,e,r=[],n=[]){if(t.length===0)return n.length>0&&r.push(n),r.length>0?r:[];let i="";t[0].content===" "&&(i=" ",t.shift());let a=t.shift()??{content:" ",type:"normal"},s=[...n];if(i!==""&&s.push({content:i,type:"normal"}),s.push(a),e(s))return uL(t,e,r,s);if(n.length>0)r.push(n),t.unshift(a);else if(a.content){let[l,u]=gDe(e,a);r.push([l]),u.content&&t.unshift(u)}return uL(t,e,r)}var bQ=N(()=>{"use strict";o(mDe,"splitTextToChars");o(gDe,"splitWordToFitWidth");o(vQ,"splitWordToFitWidthRecursion");o(xQ,"splitLineToFitWidth");o(uL,"splitLineToFitWidthRecursion")});function TQ(t,e){e&&t.attr("style",e)}async function yDe(t,e,r,n,i=!1){let a=t.append("foreignObject");a.attr("width",`${10*r}px`),a.attr("height",`${10*r}px`);let s=a.append("xhtml:div"),l=e.label;e.label&&yi(e.label)&&(l=await Th(e.label.replace(Ze.lineBreakRegex,` +`),me()));let u=e.isNode?"nodeLabel":"edgeLabel",h=s.append("span");h.html(l),TQ(h,e.labelStyle),h.attr("class",`${u} ${n}`),TQ(s,e.labelStyle),s.style("display","table-cell"),s.style("white-space","nowrap"),s.style("line-height","1.5"),s.style("max-width",r+"px"),s.style("text-align","center"),s.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&s.attr("class","labelBkg");let f=s.node().getBoundingClientRect();return f.width===r&&(s.style("display","table"),s.style("white-space","break-spaces"),s.style("width",r+"px"),f=s.node().getBoundingClientRect()),a.node()}function hL(t,e,r){return t.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",e*r-.1+"em").attr("dy",r+"em")}function vDe(t,e,r){let n=t.append("text"),i=hL(n,1,e);fL(i,r);let a=i.node().getComputedTextLength();return n.remove(),a}function wQ(t,e,r){let n=t.append("text"),i=hL(n,1,e);fL(i,[{content:r,type:"normal"}]);let a=i.node()?.getBoundingClientRect();return a&&n.remove(),a}function xDe(t,e,r,n=!1){let a=e.append("g"),s=a.insert("rect").attr("class","background").attr("style","stroke: none"),l=a.append("text").attr("y","-10.1"),u=0;for(let h of r){let f=o(p=>vDe(a,1.1,p)<=t,"checkWidth"),d=f(h)?[h]:xQ(h,f);for(let p of d){let m=hL(l,u,1.1);fL(m,p),u++}}if(n){let h=l.node().getBBox(),f=2;return s.attr("x",h.x-f).attr("y",h.y-f).attr("width",h.width+2*f).attr("height",h.height+2*f),a.node()}else return l.node()}function fL(t,e){t.text(""),e.forEach((r,n)=>{let i=t.append("tspan").attr("font-style",r.type==="em"?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight",r.type==="strong"?"bold":"normal");n===0?i.text(r.content):i.text(" "+r.content)})}async function dL(t){let e=[];t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,(n,i,a)=>(e.push((async()=>{let s=`${i}:${a}`;return await F$(s)?await Es(s,void 0,{class:"label-icon"}):``})()),n));let r=await Promise.all(e);return t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,()=>r.shift()??"")}var qn,ao=N(()=>{"use strict";fr();Gt();pr();yt();yQ();er();jl();bQ();o(TQ,"applyStyle");o(yDe,"addHtmlSpan");o(hL,"createTspan");o(vDe,"computeWidthOfText");o(wQ,"computeDimensionOfText");o(xDe,"createFormattedText");o(fL,"updateTextContentAndStyles");o(dL,"replaceIconSubstring");qn=o(async(t,e="",{style:r="",isTitle:n=!1,classes:i="",useHtmlLabels:a=!0,isNode:s=!0,width:l=200,addSvgBackground:u=!1}={},h)=>{if(X.debug("XYZ createText",e,r,n,i,a,s,"addSvgBackground: ",u),a){let f=gQ(e,h),d=await dL(na(f)),p=e.replace(/\\\\/g,"\\"),m={isNode:s,label:yi(e)?p:d,labelStyle:r.replace("fill:","color:")};return await yDe(t,m,l,i,u)}else{let f=e.replace(//g,"
    "),d=mQ(f.replace("
    ","
    "),h),p=xDe(l,t,d,e?u:!1);if(s){/stroke:/.exec(r)&&(r=r.replace("stroke:","lineColor:"));let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).attr("style",m)}else{let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/background:/g,"fill:");Ge(p).select("rect").attr("style",m.replace(/background:/g,"fill:"));let g=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).select("text").attr("style",g)}return p}},"createText")});function Xt(t){let e=t.map((r,n)=>`${n===0?"M":"L"}${r.x},${r.y}`);return e.push("Z"),e.join(" ")}function Go(t,e,r,n,i,a){let s=[],u=r-t,h=n-e,f=u/a,d=2*Math.PI/f,p=e+h/2;for(let m=0;m<=50;m++){let g=m/50,y=t+g*u,v=p+i*Math.sin(d*(y-t));s.push({x:y,y:v})}return s}function WT(t,e,r,n,i,a){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d{"use strict";ao();Gt();fr();_a();pr();er();mt=o(async(t,e,r)=>{let n,i=e.useHtmlLabels||dr(me()?.htmlLabels);r?n=r:n="node default";let a=t.insert("g").attr("class",n).attr("id",e.domId||e.id),s=a.insert("g").attr("class","label").attr("style",zn(e.labelStyle)),l;e.label===void 0?l="":l=typeof e.label=="string"?e.label:e.label[0];let u=await qn(s,wr(na(l),me()),{useHtmlLabels:i,width:e.width||me().flowchart?.wrappingWidth,cssClasses:"markdown-node-label",style:e.labelStyle,addSvgBackground:!!e.icon||!!e.img}),h=u.getBBox(),f=(e?.padding??0)/2;if(i){let d=u.children[0],p=Ge(u),m=d.getElementsByTagName("img");if(m){let g=l.replace(/]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=me().fontSize?me().fontSize:window.getComputedStyle(document.body).fontSize,T=5,[S=or.fontSize]=zo(b),w=S*T+"px";y.style.minWidth=w,y.style.maxWidth=w}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}return i?s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"):s.attr("transform","translate(0, "+-h.height/2+")"),e.centerLabel&&s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),s.insert("rect",":first-child"),{shapeSvg:a,bbox:h,halfPadding:f,label:s}},"labelHelper"),HT=o(async(t,e,r)=>{let n=r.useHtmlLabels||dr(me()?.flowchart?.htmlLabels),i=t.insert("g").attr("class","label").attr("style",r.labelStyle||""),a=await qn(i,wr(na(e),me()),{useHtmlLabels:n,width:r.width||me()?.flowchart?.wrappingWidth,style:r.labelStyle,addSvgBackground:!!r.icon||!!r.img}),s=a.getBBox(),l=r.padding/2;if(dr(me()?.flowchart?.htmlLabels)){let u=a.children[0],h=Ge(a);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}return n?i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"):i.attr("transform","translate(0, "+-s.height/2+")"),r.centerLabel&&i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),i.insert("rect",":first-child"),{shapeSvg:t,bbox:s,halfPadding:l,label:i}},"insertLabel"),Ke=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds"),ht=o((t,e)=>(t.look==="handDrawn"?"rough-node":"node")+" "+t.cssClasses+" "+(e||""),"getNodeClasses");o(Xt,"createPathFromPoints");o(Go,"generateFullSineWavePoints");o(WT,"generateCirclePoints")});function bDe(t,e){return t.intersect(e)}var kQ,EQ=N(()=>{"use strict";o(bDe,"intersectNode");kQ=bDe});function TDe(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x{"use strict";o(TDe,"intersectEllipse");qT=TDe});function wDe(t,e,r){return qT(t,e,e,r)}var SQ,CQ=N(()=>{"use strict";pL();o(wDe,"intersectCircle");SQ=wDe});function kDe(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&AQ(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&AQ(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function AQ(t,e){return t*e>0}var _Q,DQ=N(()=>{"use strict";o(kDe,"intersectLine");o(AQ,"sameSign");_Q=kDe});function EDe(t,e,r){let n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(f){s=Math.min(s,f.x),l=Math.min(l,f.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));let u=n-t.width/2-s,h=i-t.height/2-l;for(let f=0;f1&&a.sort(function(f,d){let p=f.x-r.x,m=f.y-r.y,g=Math.sqrt(p*p+m*m),y=d.x-r.x,v=d.y-r.y,x=Math.sqrt(y*y+v*v);return g{"use strict";DQ();o(EDe,"intersectPolygon");LQ=EDe});var SDe,Xh,mL=N(()=>{"use strict";SDe=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),Xh=SDe});var Xe,Ht=N(()=>{"use strict";EQ();CQ();pL();RQ();mL();Xe={node:kQ,circle:SQ,ellipse:qT,polygon:LQ,rect:Xh}});var NQ,bc,CDe,S2,Ye,Qe,zt=N(()=>{"use strict";Gt();NQ=o(t=>{let{handDrawnSeed:e}=me();return{fill:t,hachureAngle:120,hachureGap:4,fillWeight:2,roughness:.7,stroke:t,seed:e}},"solidStateFill"),bc=o(t=>{let e=CDe([...t.cssCompiledStyles||[],...t.cssStyles||[]]);return{stylesMap:e,stylesArray:[...e]}},"compileStyles"),CDe=o(t=>{let e=new Map;return t.forEach(r=>{let[n,i]=r.split(":");e.set(n.trim(),i?.trim())}),e},"styles2Map"),S2=o(t=>t==="color"||t==="font-size"||t==="font-family"||t==="font-weight"||t==="font-style"||t==="text-decoration"||t==="text-align"||t==="text-transform"||t==="line-height"||t==="letter-spacing"||t==="word-spacing"||t==="text-shadow"||t==="text-overflow"||t==="white-space"||t==="word-wrap"||t==="word-break"||t==="overflow-wrap"||t==="hyphens","isLabelStyle"),Ye=o(t=>{let{stylesArray:e}=bc(t),r=[],n=[],i=[],a=[];return e.forEach(s=>{let l=s[0];S2(l)?r.push(s.join(":")+" !important"):(n.push(s.join(":")+" !important"),l.includes("stroke")&&i.push(s.join(":")+" !important"),l==="fill"&&a.push(s.join(":")+" !important"))}),{labelStyles:r.join(";"),nodeStyles:n.join(";"),stylesArray:e,borderStyles:i,backgroundStyles:a}},"styles2String"),Qe=o((t,e)=>{let{themeVariables:r,handDrawnSeed:n}=me(),{nodeBorder:i,mainBkg:a}=r,{stylesMap:s}=bc(t);return Object.assign({roughness:.7,fill:s.get("fill")||a,fillStyle:"hachure",fillWeight:4,hachureGap:5.2,stroke:s.get("stroke")||i,seed:n,strokeWidth:s.get("stroke-width")?.replace("px","")||1.3,fillLineDash:[0,0]},e)},"userNodeOverrides")});function gL(t,e,r){if(t&&t.length){let[n,i]=e,a=Math.PI/180*r,s=Math.cos(a),l=Math.sin(a);for(let u of t){let[h,f]=u;u[0]=(h-n)*s-(f-i)*l+n,u[1]=(h-n)*l+(f-i)*s+i}}}function ADe(t,e){return t[0]===e[0]&&t[1]===e[1]}function _De(t,e,r,n=1){let i=r,a=Math.max(e,.1),s=t[0]&&t[0][0]&&typeof t[0][0]=="number"?[t]:t,l=[0,0];if(i)for(let h of s)gL(h,l,i);let u=function(h,f,d){let p=[];for(let b of h){let T=[...b];ADe(T[0],T[T.length-1])||T.push([T[0][0],T[0][1]]),T.length>2&&p.push(T)}let m=[];f=Math.max(f,.1);let g=[];for(let b of p)for(let T=0;Tb.yminT.ymin?1:b.xT.x?1:b.ymax===T.ymax?0:(b.ymax-T.ymax)/Math.abs(b.ymax-T.ymax)),!g.length)return m;let y=[],v=g[0].ymin,x=0;for(;y.length||g.length;){if(g.length){let b=-1;for(let T=0;Tv);T++)b=T;g.splice(0,b+1).forEach(T=>{y.push({s:v,edge:T})})}if(y=y.filter(b=>!(b.edge.ymax<=v)),y.sort((b,T)=>b.edge.x===T.edge.x?0:(b.edge.x-T.edge.x)/Math.abs(b.edge.x-T.edge.x)),(d!==1||x%f==0)&&y.length>1)for(let b=0;b=y.length)break;let S=y[b].edge,w=y[T].edge;m.push([[Math.round(S.x),v],[Math.round(w.x),v]])}v+=d,y.forEach(b=>{b.edge.x=b.edge.x+d*b.edge.islope}),x++}return m}(s,a,n);if(i){for(let h of s)gL(h,l,-i);(function(h,f,d){let p=[];h.forEach(m=>p.push(...m)),gL(p,f,d)})(u,l,-i)}return u}function D2(t,e){var r;let n=e.hachureAngle+90,i=e.hachureGap;i<0&&(i=4*e.strokeWidth),i=Math.round(Math.max(i,.1));let a=1;return e.roughness>=1&&(((r=e.randomizer)===null||r===void 0?void 0:r.next())||Math.random())>.7&&(a=i),_De(t,i,n,a||1)}function tw(t){let e=t[0],r=t[1];return Math.sqrt(Math.pow(e[0]-r[0],2)+Math.pow(e[1]-r[1],2))}function vL(t,e){return t.type===e}function NL(t){let e=[],r=function(s){let l=new Array;for(;s!=="";)if(s.match(/^([ \t\r\n,]+)/))s=s.substr(RegExp.$1.length);else if(s.match(/^([aAcChHlLmMqQsStTvVzZ])/))l[l.length]={type:DDe,text:RegExp.$1},s=s.substr(RegExp.$1.length);else{if(!s.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];l[l.length]={type:yL,text:`${parseFloat(RegExp.$1)}`},s=s.substr(RegExp.$1.length)}return l[l.length]={type:MQ,text:""},l}(t),n="BOD",i=0,a=r[i];for(;!vL(a,MQ);){let s=0,l=[];if(n==="BOD"){if(a.text!=="M"&&a.text!=="m")return NL("M0,0"+t);i++,s=YT[a.text],n=a.text}else vL(a,yL)?s=YT[n]:(i++,s=YT[a.text],n=a.text);if(!(i+sf%2?h+r:h+e);a.push({key:"C",data:u}),e=u[4],r=u[5];break}case"Q":a.push({key:"Q",data:[...l]}),e=l[2],r=l[3];break;case"q":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"Q",data:u}),e=u[2],r=u[3];break}case"A":a.push({key:"A",data:[...l]}),e=l[5],r=l[6];break;case"a":e+=l[5],r+=l[6],a.push({key:"A",data:[l[0],l[1],l[2],l[3],l[4],e,r]});break;case"H":a.push({key:"H",data:[...l]}),e=l[0];break;case"h":e+=l[0],a.push({key:"H",data:[e]});break;case"V":a.push({key:"V",data:[...l]}),r=l[0];break;case"v":r+=l[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...l]}),e=l[2],r=l[3];break;case"s":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"S",data:u}),e=u[2],r=u[3];break}case"T":a.push({key:"T",data:[...l]}),e=l[0],r=l[1];break;case"t":e+=l[0],r+=l[1],a.push({key:"T",data:[e,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),e=n,r=i}return a}function VQ(t){let e=[],r="",n=0,i=0,a=0,s=0,l=0,u=0;for(let{key:h,data:f}of t){switch(h){case"M":e.push({key:"M",data:[...f]}),[n,i]=f,[a,s]=f;break;case"C":e.push({key:"C",data:[...f]}),n=f[4],i=f[5],l=f[2],u=f[3];break;case"L":e.push({key:"L",data:[...f]}),[n,i]=f;break;case"H":n=f[0],e.push({key:"L",data:[n,i]});break;case"V":i=f[0],e.push({key:"L",data:[n,i]});break;case"S":{let d=0,p=0;r==="C"||r==="S"?(d=n+(n-l),p=i+(i-u)):(d=n,p=i),e.push({key:"C",data:[d,p,...f]}),l=f[0],u=f[1],n=f[2],i=f[3];break}case"T":{let[d,p]=f,m=0,g=0;r==="Q"||r==="T"?(m=n+(n-l),g=i+(i-u)):(m=n,g=i);let y=n+2*(m-n)/3,v=i+2*(g-i)/3,x=d+2*(m-d)/3,b=p+2*(g-p)/3;e.push({key:"C",data:[y,v,x,b,d,p]}),l=m,u=g,n=d,i=p;break}case"Q":{let[d,p,m,g]=f,y=n+2*(d-n)/3,v=i+2*(p-i)/3,x=m+2*(d-m)/3,b=g+2*(p-g)/3;e.push({key:"C",data:[y,v,x,b,m,g]}),l=d,u=p,n=m,i=g;break}case"A":{let d=Math.abs(f[0]),p=Math.abs(f[1]),m=f[2],g=f[3],y=f[4],v=f[5],x=f[6];d===0||p===0?(e.push({key:"C",data:[n,i,v,x,v,x]}),n=v,i=x):(n!==v||i!==x)&&(UQ(n,i,v,x,d,p,m,g,y).forEach(function(b){e.push({key:"C",data:b})}),n=v,i=x);break}case"Z":e.push({key:"Z",data:[]}),n=a,i=s}r=h}return e}function C2(t,e,r){return[t*Math.cos(r)-e*Math.sin(r),t*Math.sin(r)+e*Math.cos(r)]}function UQ(t,e,r,n,i,a,s,l,u,h){let f=(d=s,Math.PI*d/180);var d;let p=[],m=0,g=0,y=0,v=0;if(h)[m,g,y,v]=h;else{[t,e]=C2(t,e,-f),[r,n]=C2(r,n,-f);let L=(t-r)/2,A=(e-n)/2,I=L*L/(i*i)+A*A/(a*a);I>1&&(I=Math.sqrt(I),i*=I,a*=I);let M=i*i,P=a*a,B=M*P-M*A*A-P*L*L,F=M*A*A+P*L*L,z=(l===u?-1:1)*Math.sqrt(Math.abs(B/F));y=z*i*A/a+(t+r)/2,v=z*-a*L/i+(e+n)/2,m=Math.asin(parseFloat(((e-v)/a).toFixed(9))),g=Math.asin(parseFloat(((n-v)/a).toFixed(9))),tg&&(m-=2*Math.PI),!u&&g>m&&(g-=2*Math.PI)}let x=g-m;if(Math.abs(x)>120*Math.PI/180){let L=g,A=r,I=n;g=u&&g>m?m+120*Math.PI/180*1:m+120*Math.PI/180*-1,p=UQ(r=y+i*Math.cos(g),n=v+a*Math.sin(g),A,I,i,a,s,0,u,[g,L,y,v])}x=g-m;let b=Math.cos(m),T=Math.sin(m),S=Math.cos(g),w=Math.sin(g),E=Math.tan(x/4),_=4/3*i*E,C=4/3*a*E,D=[t,e],O=[t+_*T,e-C*b],R=[r+_*w,n-C*S],k=[r,n];if(O[0]=2*D[0]-O[0],O[1]=2*D[1]-O[1],h)return[O,R,k].concat(p);{p=[O,R,k].concat(p);let L=[];for(let A=0;A2){let i=[];for(let a=0;a2*Math.PI&&(m=0,g=2*Math.PI);let y=2*Math.PI/u.curveStepCount,v=Math.min(y/2,(g-m)/2),x=$Q(v,h,f,d,p,m,g,1,u);if(!u.disableMultiStroke){let b=$Q(v,h,f,d,p,m,g,1.5,u);x.push(...b)}return s&&(l?x.push(...jh(h,f,h+d*Math.cos(m),f+p*Math.sin(m),u),...jh(h,f,h+d*Math.cos(g),f+p*Math.sin(g),u)):x.push({op:"lineTo",data:[h,f]},{op:"lineTo",data:[h+d*Math.cos(m),f+p*Math.sin(m)]})),{type:"path",ops:x}}function PQ(t,e){let r=VQ(GQ(NL(t))),n=[],i=[0,0],a=[0,0];for(let{key:s,data:l}of r)switch(s){case"M":a=[l[0],l[1]],i=[l[0],l[1]];break;case"L":n.push(...jh(a[0],a[1],l[0],l[1],e)),a=[l[0],l[1]];break;case"C":{let[u,h,f,d,p,m]=l;n.push(...NDe(u,h,f,d,p,m,a,e)),a=[p,m];break}case"Z":n.push(...jh(a[0],a[1],i[0],i[1],e)),a=[i[0],i[1]]}return{type:"path",ops:n}}function xL(t,e){let r=[];for(let n of t)if(n.length){let i=e.maxRandomnessOffset||0,a=n.length;if(a>2){r.push({op:"move",data:[n[0][0]+ar(i,e),n[0][1]+ar(i,e)]});for(let s=1;s500?.4:-.0016668*u+1.233334;let f=i.maxRandomnessOffset||0;f*f*100>l&&(f=u/10);let d=f/2,p=.2+.2*qQ(i),m=i.bowing*i.maxRandomnessOffset*(n-e)/200,g=i.bowing*i.maxRandomnessOffset*(t-r)/200;m=ar(m,i,h),g=ar(g,i,h);let y=[],v=o(()=>ar(d,i,h),"M"),x=o(()=>ar(f,i,h),"k"),b=i.preserveVertices;return a&&(s?y.push({op:"move",data:[t+(b?0:v()),e+(b?0:v())]}):y.push({op:"move",data:[t+(b?0:ar(f,i,h)),e+(b?0:ar(f,i,h))]})),s?y.push({op:"bcurveTo",data:[m+t+(r-t)*p+v(),g+e+(n-e)*p+v(),m+t+2*(r-t)*p+v(),g+e+2*(n-e)*p+v(),r+(b?0:v()),n+(b?0:v())]}):y.push({op:"bcurveTo",data:[m+t+(r-t)*p+x(),g+e+(n-e)*p+x(),m+t+2*(r-t)*p+x(),g+e+2*(n-e)*p+x(),r+(b?0:x()),n+(b?0:x())]}),y}function XT(t,e,r){if(!t.length)return[];let n=[];n.push([t[0][0]+ar(e,r),t[0][1]+ar(e,r)]),n.push([t[0][0]+ar(e,r),t[0][1]+ar(e,r)]);for(let i=1;i3){let a=[],s=1-r.curveTightness;i.push({op:"move",data:[t[1][0],t[1][1]]});for(let l=1;l+21&&i.push(l)):i.push(l),i.push(t[e+3])}else{let u=t[e+0],h=t[e+1],f=t[e+2],d=t[e+3],p=Hd(u,h,.5),m=Hd(h,f,.5),g=Hd(f,d,.5),y=Hd(p,m,.5),v=Hd(m,g,.5),x=Hd(y,v,.5);DL([u,p,y,x],0,r,i),DL([x,v,g,d],0,r,i)}var a,s;return i}function IDe(t,e){return ew(t,0,t.length,e)}function ew(t,e,r,n,i){let a=i||[],s=t[e],l=t[r-1],u=0,h=1;for(let f=e+1;fu&&(u=d,h=f)}return Math.sqrt(u)>n?(ew(t,e,h+1,n,a),ew(t,h,r,n,a)):(a.length||a.push(s),a.push(l)),a}function bL(t,e=.15,r){let n=[],i=(t.length-1)/3;for(let a=0;a0?ew(n,0,n.length,r):n}var _2,TL,wL,kL,EL,SL,Ps,CL,DDe,yL,MQ,YT,LDe,so,km,LL,jT,RL,je,Wt=N(()=>{"use strict";o(gL,"t");o(ADe,"e");o(_De,"s");o(D2,"n");_2=class{static{o(this,"o")}constructor(e){this.helper=e}fillPolygons(e,r){return this._fillPolygons(e,r)}_fillPolygons(e,r){let n=D2(e,r);return{type:"fillSketch",ops:this.renderLines(n,r)}}renderLines(e,r){let n=[];for(let i of e)n.push(...this.helper.doubleLineOps(i[0][0],i[0][1],i[1][0],i[1][1],r));return n}};o(tw,"a");TL=class extends _2{static{o(this,"h")}fillPolygons(e,r){let n=r.hachureGap;n<0&&(n=4*r.strokeWidth),n=Math.max(n,.1);let i=D2(e,Object.assign({},r,{hachureGap:n})),a=Math.PI/180*r.hachureAngle,s=[],l=.5*n*Math.cos(a),u=.5*n*Math.sin(a);for(let[h,f]of i)tw([h,f])&&s.push([[h[0]-l,h[1]+u],[...f]],[[h[0]+l,h[1]-u],[...f]]);return{type:"fillSketch",ops:this.renderLines(s,r)}}},wL=class extends _2{static{o(this,"r")}fillPolygons(e,r){let n=this._fillPolygons(e,r),i=Object.assign({},r,{hachureAngle:r.hachureAngle+90}),a=this._fillPolygons(e,i);return n.ops=n.ops.concat(a.ops),n}},kL=class{static{o(this,"i")}constructor(e){this.helper=e}fillPolygons(e,r){let n=D2(e,r=Object.assign({},r,{hachureAngle:0}));return this.dotsOnLines(n,r)}dotsOnLines(e,r){let n=[],i=r.hachureGap;i<0&&(i=4*r.strokeWidth),i=Math.max(i,.1);let a=r.fillWeight;a<0&&(a=r.strokeWidth/2);let s=i/4;for(let l of e){let u=tw(l),h=u/i,f=Math.ceil(h)-1,d=u-f*i,p=(l[0][0]+l[1][0])/2-i/4,m=Math.min(l[0][1],l[1][1]);for(let g=0;g{let l=tw(s),u=Math.floor(l/(n+i)),h=(l+i-u*(n+i))/2,f=s[0],d=s[1];f[0]>d[0]&&(f=s[1],d=s[0]);let p=Math.atan((d[1]-f[1])/(d[0]-f[0]));for(let m=0;m{let s=tw(a),l=Math.round(s/(2*r)),u=a[0],h=a[1];u[0]>h[0]&&(u=a[1],h=a[0]);let f=Math.atan((h[1]-u[1])/(h[0]-u[0]));for(let d=0;d2*Math.PI&&(_=0,C=2*Math.PI);let D=(C-_)/b.curveStepCount,O=[];for(let R=_;R<=C;R+=D)O.push([T+w*Math.cos(R),S+E*Math.sin(R)]);return O.push([T+w*Math.cos(C),S+E*Math.sin(C)]),O.push([T,S]),wm([O],b)}(e,r,n,i,a,s,h));return h.stroke!==so&&f.push(d),this._d("arc",f,h)}curve(e,r){let n=this._o(r),i=[],a=IQ(e,n);if(n.fill&&n.fill!==so)if(n.fillStyle==="solid"){let s=IQ(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(s.ops)})}else{let s=[],l=e;if(l.length){let u=typeof l[0][0]=="number"?[l]:l;for(let h of u)h.length<3?s.push(...h):h.length===3?s.push(...bL(zQ([h[0],h[0],h[1],h[2]]),10,(1+n.roughness)/2)):s.push(...bL(zQ(h),10,(1+n.roughness)/2))}s.length&&i.push(wm([s],n))}return n.stroke!==so&&i.push(a),this._d("curve",i,n)}polygon(e,r){let n=this._o(r),i=[],a=KT(e,!0,n);return n.fill&&(n.fillStyle==="solid"?i.push(xL([e],n)):i.push(wm([e],n))),n.stroke!==so&&i.push(a),this._d("polygon",i,n)}path(e,r){let n=this._o(r),i=[];if(!e)return this._d("path",i,n);e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");let a=n.fill&&n.fill!=="transparent"&&n.fill!==so,s=n.stroke!==so,l=!!(n.simplification&&n.simplification<1),u=function(f,d,p){let m=VQ(GQ(NL(f))),g=[],y=[],v=[0,0],x=[],b=o(()=>{x.length>=4&&y.push(...bL(x,d)),x=[]},"i"),T=o(()=>{b(),y.length&&(g.push(y),y=[])},"c");for(let{key:w,data:E}of m)switch(w){case"M":T(),v=[E[0],E[1]],y.push(v);break;case"L":b(),y.push([E[0],E[1]]);break;case"C":if(!x.length){let _=y.length?y[y.length-1]:v;x.push([_[0],_[1]])}x.push([E[0],E[1]]),x.push([E[2],E[3]]),x.push([E[4],E[5]]);break;case"Z":b(),y.push([v[0],v[1]])}if(T(),!p)return g;let S=[];for(let w of g){let E=IDe(w,p);E.length&&S.push(E)}return S}(e,1,l?4-4*(n.simplification||1):(1+n.roughness)/2),h=PQ(e,n);if(a)if(n.fillStyle==="solid")if(u.length===1){let f=PQ(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(f.ops)})}else i.push(xL(u,n));else i.push(wm(u,n));return s&&(l?u.forEach(f=>{i.push(KT(f,!1,n))}):i.push(h)),this._d("path",i,n)}opsToPath(e,r){let n="";for(let i of e.ops){let a=typeof r=="number"&&r>=0?i.data.map(s=>+s.toFixed(r)):i.data;switch(i.op){case"move":n+=`M${a[0]} ${a[1]} `;break;case"bcurveTo":n+=`C${a[0]} ${a[1]}, ${a[2]} ${a[3]}, ${a[4]} ${a[5]} `;break;case"lineTo":n+=`L${a[0]} ${a[1]} `}}return n.trim()}toPaths(e){let r=e.sets||[],n=e.options||this.defaultOptions,i=[];for(let a of r){let s=null;switch(a.type){case"path":s={d:this.opsToPath(a),stroke:n.stroke,strokeWidth:n.strokeWidth,fill:so};break;case"fillPath":s={d:this.opsToPath(a),stroke:so,strokeWidth:0,fill:n.fill||so};break;case"fillSketch":s=this.fillSketch(a,n)}s&&i.push(s)}return i}fillSketch(e,r){let n=r.fillWeight;return n<0&&(n=r.strokeWidth/2),{d:this.opsToPath(e),stroke:r.fill||so,strokeWidth:n,fill:so}}_mergedShape(e){return e.filter((r,n)=>n===0||r.op!=="move")}},LL=class{static{o(this,"st")}constructor(e,r){this.canvas=e,this.ctx=this.canvas.getContext("2d"),this.gen=new km(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.ctx,a=e.options.fixedDecimalPlaceDigits;for(let s of r)switch(s.type){case"path":i.save(),i.strokeStyle=n.stroke==="none"?"transparent":n.stroke,i.lineWidth=n.strokeWidth,n.strokeLineDash&&i.setLineDash(n.strokeLineDash),n.strokeLineDashOffset&&(i.lineDashOffset=n.strokeLineDashOffset),this._drawToContext(i,s,a),i.restore();break;case"fillPath":{i.save(),i.fillStyle=n.fill||"";let l=e.shape==="curve"||e.shape==="polygon"||e.shape==="path"?"evenodd":"nonzero";this._drawToContext(i,s,a,l),i.restore();break}case"fillSketch":this.fillSketch(i,s,n)}}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2),e.save(),n.fillLineDash&&e.setLineDash(n.fillLineDash),n.fillLineDashOffset&&(e.lineDashOffset=n.fillLineDashOffset),e.strokeStyle=n.fill||"",e.lineWidth=i,this._drawToContext(e,r,n.fixedDecimalPlaceDigits),e.restore()}_drawToContext(e,r,n,i="nonzero"){e.beginPath();for(let a of r.ops){let s=typeof n=="number"&&n>=0?a.data.map(l=>+l.toFixed(n)):a.data;switch(a.op){case"move":e.moveTo(s[0],s[1]);break;case"bcurveTo":e.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5]);break;case"lineTo":e.lineTo(s[0],s[1])}}r.type==="fillPath"?e.fill(i):e.stroke()}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s),s}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s),s}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s),s}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a),a}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n),n}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n),n}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h),h}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n),n}path(e,r){let n=this.gen.path(e,r);return this.draw(n),n}},jT="http://www.w3.org/2000/svg",RL=class{static{o(this,"ot")}constructor(e,r){this.svg=e,this.gen=new km(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.svg.ownerDocument||window.document,a=i.createElementNS(jT,"g"),s=e.options.fixedDecimalPlaceDigits;for(let l of r){let u=null;switch(l.type){case"path":u=i.createElementNS(jT,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke",n.stroke),u.setAttribute("stroke-width",n.strokeWidth+""),u.setAttribute("fill","none"),n.strokeLineDash&&u.setAttribute("stroke-dasharray",n.strokeLineDash.join(" ").trim()),n.strokeLineDashOffset&&u.setAttribute("stroke-dashoffset",`${n.strokeLineDashOffset}`);break;case"fillPath":u=i.createElementNS(jT,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke","none"),u.setAttribute("stroke-width","0"),u.setAttribute("fill",n.fill||""),e.shape!=="curve"&&e.shape!=="polygon"||u.setAttribute("fill-rule","evenodd");break;case"fillSketch":u=this.fillSketch(i,l,n)}u&&a.appendChild(u)}return a}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2);let a=e.createElementNS(jT,"path");return a.setAttribute("d",this.opsToPath(r,n.fixedDecimalPlaceDigits)),a.setAttribute("stroke",n.fill||""),a.setAttribute("stroke-width",i+""),a.setAttribute("fill","none"),n.fillLineDash&&a.setAttribute("stroke-dasharray",n.fillLineDash.join(" ").trim()),n.fillLineDashOffset&&a.setAttribute("stroke-dashoffset",`${n.fillLineDashOffset}`),a}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e,r){return this.gen.opsToPath(e,r)}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s)}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s)}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s)}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a)}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n)}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n)}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h)}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n)}path(e,r){let n=this.gen.path(e,r);return this.draw(n)}},je={canvas:o((t,e)=>new LL(t,e),"canvas"),svg:o((t,e)=>new RL(t,e),"svg"),generator:o(t=>new km(t),"generator"),newSeed:o(()=>km.newSeed(),"newSeed")}});function YQ(t,e){let{labelStyles:r}=Ye(e);e.labelStyle=r;let n=ht(e),i=n;n||(i="anchor");let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=1,{cssStyles:l}=e,u=je.svg(a),h=Qe(e,{fill:"black",stroke:"none",fillStyle:"solid"});e.look!=="handDrawn"&&(h.roughness=0);let f=u.circle(0,0,s*2,h),d=a.insert(()=>f,":first-child");return d.attr("class","anchor").attr("style",zn(l)),Ke(e,d),e.intersect=function(p){return X.info("Circle intersect",e,s,p),Xe.circle(e,s,p)},a}var XQ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(YQ,"anchor")});function jQ(t,e,r,n,i,a,s){let u=(t+r)/2,h=(e+n)/2,f=Math.atan2(n-e,r-t),d=(r-t)/2,p=(n-e)/2,m=d/i,g=p/a,y=Math.sqrt(m**2+g**2);if(y>1)throw new Error("The given radii are too small to create an arc between the points.");let v=Math.sqrt(1-y**2),x=u+v*a*Math.sin(f)*(s?-1:1),b=h-v*i*Math.cos(f)*(s?-1:1),T=Math.atan2((e-b)/a,(t-x)/i),w=Math.atan2((n-b)/a,(r-x)/i)-T;s&&w<0&&(w+=2*Math.PI),!s&&w>0&&(w-=2*Math.PI);let E=[];for(let _=0;_<20;_++){let C=_/19,D=T+C*w,O=x+i*Math.cos(D),R=b+a*Math.sin(D);E.push({x:O,y:R})}return E}async function KQ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding+20,l=a.height+e.padding,u=l/2,h=u/(2.5+l/50),{cssStyles:f}=e,d=[{x:s/2,y:-l/2},{x:-s/2,y:-l/2},...jQ(-s/2,-l/2,-s/2,l/2,h,u,!1),{x:s/2,y:l/2},...jQ(s/2,l/2,s/2,-l/2,h,u,!0)],p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(d),y=p.path(g,m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(${h/2}, 0)`),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,d,x)},i}var QQ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(jQ,"generateArcPoints");o(KQ,"bowTieRect")});function Ma(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var Iu=N(()=>{"use strict";o(Ma,"insertPolygonShape")});async function ZQ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.height+e.padding,l=12,u=a.width+e.padding+l,h=0,f=u,d=-s,p=0,m=[{x:h+l,y:d},{x:f,y:d},{x:f,y:p},{x:h,y:p},{x:h,y:d+l},{x:h+l,y:d}],g,{cssStyles:y}=e;if(e.look==="handDrawn"){let v=je.svg(i),x=Qe(e,{}),b=Xt(m),T=v.path(b,x);g=i.insert(()=>T,":first-child").attr("transform",`translate(${-u/2}, ${s/2})`),y&&g.attr("style",y)}else g=Ma(i,u,s,m);return n&&g.attr("style",n),Ke(e,g),e.intersect=function(v){return Xe.polygon(e,m,v)},i}var JQ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();Ft();o(ZQ,"card")});function eZ(t,e){let{nodeStyles:r}=Ye(e);e.label="";let n=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:i}=e,a=Math.max(28,e.width??0),s=[{x:0,y:a/2},{x:a/2,y:0},{x:0,y:-a/2},{x:-a/2,y:0}],l=je.svg(n),u=Qe(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=Xt(s),f=l.path(h,u),d=n.insert(()=>f,":first-child");return i&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",i),r&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",r),e.width=28,e.height=28,e.intersect=function(p){return Xe.polygon(e,s,p)},n}var tZ=N(()=>{"use strict";Ht();Wt();zt();Ft();o(eZ,"choice")});async function rZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await mt(t,e,ht(e)),l=a.width/2+s,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=je.svg(i),d=Qe(e,{}),p=f.circle(0,0,l*2,d);u=i.insert(()=>p,":first-child"),u.attr("class","basic label-container").attr("style",zn(h))}else u=i.insert("circle",":first-child").attr("class","basic label-container").attr("style",n).attr("r",l).attr("cx",0).attr("cy",0);return Ke(e,u),e.intersect=function(f){return X.info("Circle intersect",e,l,f),Xe.circle(e,l,f)},i}var nZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(rZ,"circle")});function ODe(t){let e=Math.cos(Math.PI/4),r=Math.sin(Math.PI/4),n=t*2,i={x:n/2*e,y:n/2*r},a={x:-(n/2)*e,y:n/2*r},s={x:-(n/2)*e,y:-(n/2)*r},l={x:n/2*e,y:-(n/2)*r};return`M ${a.x},${a.y} L ${l.x},${l.y} + M ${i.x},${i.y} L ${s.x},${s.y}`}function iZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r,e.label="";let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),a=Math.max(30,e?.width??0),{cssStyles:s}=e,l=je.svg(i),u=Qe(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=l.circle(0,0,a*2,u),f=ODe(a),d=l.path(f,u),p=i.insert(()=>h,":first-child");return p.insert(()=>d),s&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",s),n&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",n),Ke(e,p),e.intersect=function(m){return X.info("crossedCircle intersect",e,{radius:a,point:m}),Xe.circle(e,a,m)},i}var aZ=N(()=>{"use strict";yt();Ft();zt();Wt();Ht();o(ODe,"createLine");o(iZ,"crossedCircle")});function Kh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;dT,":first-child").attr("stroke-opacity",0),S.insert(()=>x,":first-child"),S.attr("class","text"),f&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(${h}, 0)`),s.attr("transform",`translate(${-l/2+h-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,p,w)},i}var oZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Kh,"generateCirclePoints");o(sZ,"curlyBraceLeft")});function Qh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;dT,":first-child").attr("stroke-opacity",0),S.insert(()=>x,":first-child"),S.attr("class","text"),f&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(${-h}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,p,w)},i}var cZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Qh,"generateCirclePoints");o(lZ,"curlyBraceRight")});function Ia(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d_,":first-child").attr("stroke-opacity",0),C.insert(()=>b,":first-child"),C.insert(()=>w,":first-child"),C.attr("class","text"),f&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${h-h/4}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,C),e.intersect=function(D){return Xe.polygon(e,m,D)},i}var hZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Ia,"generateCirclePoints");o(uZ,"curlyBraces")});async function fZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=80,l=20,u=Math.max(s,(a.width+(e.padding??0)*2)*1.25,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=u,y=h,v=g-f,x=y/4,b=[{x:v,y:0},{x,y:0},{x:0,y:y/2},{x,y},{x:v,y},...WT(-v,-y/2,f,50,270,90)],T=Xt(b),S=p.path(T,m),w=i.insert(()=>S,":first-child");return w.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&w.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&w.selectChildren("path").attr("style",n),w.attr("transform",`translate(${-u/2}, ${-h/2})`),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,b,E)},i}var dZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(fZ,"curvedTrapezoid")});async function pZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+e.padding,e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+e.padding,e.height??0),d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=je.svg(i),g=BDe(0,0,l,f,u,h),y=FDe(0,h,l,f,u,h),v=m.path(g,Qe(e,{})),x=m.path(y,Qe(e,{fill:"none"}));d=i.insert(()=>x,":first-child"),d=i.insert(()=>v,":first-child"),d.attr("class","basic label-container"),p&&d.attr("style",p)}else{let m=PDe(0,0,l,f,u,h);d=i.insert("path",":first-child").attr("d",m).attr("class","basic label-container").attr("style",zn(p)).attr("style",n)}return d.attr("label-offset-y",h),d.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),Ke(e,d),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+(e.padding??0)/1.5-(a.y-(a.top??0))})`),e.intersect=function(m){let g=Xe.rect(e,m),y=g.x-(e.x??0);if(u!=0&&(Math.abs(y)<(e.width??0)/2||Math.abs(y)==(e.width??0)/2&&Math.abs(g.y-(e.y??0))>(e.height??0)/2-h)){let v=h*h*(1-y*y/(u*u));v>0&&(v=Math.sqrt(v)),v=h-v,m.y-(e.y??0)>0&&(v=-v),g.y+=v}return g},i}var PDe,BDe,FDe,mZ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();PDe=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createCylinderPathD"),BDe=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createOuterCylinderPathD"),FDe=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(pZ,"cylinder")});async function gZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=a.width+e.padding,u=a.height+e.padding,h=u*.2,f=-l/2,d=-u/2-h/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d+h},{x:-f,y:d+h},{x:-f,y:-d},{x:f,y:-d},{x:f,y:d},{x:-f,y:d},{x:-f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${f+(e.padding??0)/2-(a.x-(a.left??0))}, ${d+h+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},i}var yZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(gZ,"dividedRectangle")});async function vZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await mt(t,e,ht(e)),u=a.width/2+s+5,h=a.width/2+s,f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{roughness:.2,strokeWidth:2.5}),g=Qe(e,{roughness:.2,strokeWidth:1.5}),y=p.circle(0,0,u*2,m),v=p.circle(0,0,h*2,g);f=i.insert("g",":first-child"),f.attr("class",zn(e.cssClasses)).attr("style",zn(d)),f.node()?.appendChild(y),f.node()?.appendChild(v)}else{f=i.insert("g",":first-child");let p=f.insert("circle",":first-child"),m=f.insert("circle");f.attr("class","basic label-container").attr("style",n),p.attr("class","outer-circle").attr("style",n).attr("r",u).attr("cx",0).attr("cy",0),m.attr("class","inner-circle").attr("style",n).attr("r",h).attr("cx",0).attr("cy",0)}return Ke(e,f),e.intersect=function(p){return X.info("DoubleCircle intersect",e,u,p),Xe.circle(e,u,p)},i}var xZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(vZ,"doublecircle")});function bZ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.label="",e.labelStyle=n;let a=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),s=7,{cssStyles:l}=e,u=je.svg(a),{nodeBorder:h}=r,f=Qe(e,{fillStyle:"solid"});e.look!=="handDrawn"&&(f.roughness=0);let d=u.circle(0,0,s*2,f),p=a.insert(()=>d,":first-child");return p.selectAll("path").attr("style",`fill: ${h} !important;`),l&&l.length>0&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",l),i&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",i),Ke(e,p),e.intersect=function(m){return X.info("filledCircle intersect",e,{radius:s,point:m}),Xe.circle(e,s,m)},a}var TZ=N(()=>{"use strict";Wt();yt();Ht();zt();Ft();o(bZ,"filledCircle")});async function wZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=a.width+(e.padding??0),u=l+a.height,h=l+a.height,f=[{x:0,y:-u},{x:h,y:-u},{x:h/2,y:0}],{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(f),y=p.path(g,m),v=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`);return d&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),e.width=l,e.height=u,Ke(e,v),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-u/2+(e.padding??0)/2+(a.y-(a.top??0))})`),e.intersect=function(x){return X.info("Triangle intersect",e,f,x),Xe.polygon(e,f,x)},i}var kZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Ft();o(wZ,"flippedTriangle")});function EZ(t,e,{dir:r,config:{state:n,themeVariables:i}}){let{nodeStyles:a}=Ye(e);e.label="";let s=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:l}=e,u=Math.max(70,e?.width??0),h=Math.max(10,e?.height??0);r==="LR"&&(u=Math.max(10,e?.width??0),h=Math.max(70,e?.height??0));let f=-1*u/2,d=-1*h/2,p=je.svg(s),m=Qe(e,{stroke:i.lineColor,fill:i.lineColor});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=p.rectangle(f,d,u,h,m),y=s.insert(()=>g,":first-child");l&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",l),a&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",a),Ke(e,y);let v=n?.padding??0;return e.width&&e.height&&(e.width+=v/2||0,e.height+=v/2||0),e.intersect=function(x){return Xe.rect(e,x)},s}var SZ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(EZ,"forkJoin")});async function CZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i=80,a=50,{shapeSvg:s,bbox:l}=await mt(t,e,ht(e)),u=Math.max(i,l.width+(e.padding??0)*2,e?.width??0),h=Math.max(a,l.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=je.svg(s),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-u/2,y:-h/2},{x:u/2-f,y:-h/2},...WT(-u/2+f,0,f,50,90,270),{x:u/2-f,y:h/2},{x:-u/2,y:h/2}],y=Xt(g),v=p.path(y,m),x=s.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),Ke(e,x),e.intersect=function(b){return X.info("Pill intersect",e,{radius:f,point:b}),Xe.polygon(e,g,b)},s}var AZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();o(CZ,"halfRoundedRectangle")});async function _Z(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=4,l=a.height+e.padding,u=l/s,h=a.width+2*u+e.padding,f=[{x:u,y:0},{x:h-u,y:0},{x:h,y:-l/2},{x:h-u,y:-l},{x:u,y:-l},{x:0,y:-l/2}],d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=je.svg(i),g=Qe(e,{}),y=$De(0,0,h,l,u),v=m.path(y,g);d=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${l/2})`),p&&d.attr("style",p)}else d=Ma(i,h,l,f);return n&&d.attr("style",n),e.width=h,e.height=l,Ke(e,d),e.intersect=function(m){return Xe.polygon(e,f,m)},i}var $De,DZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();$De=o((t,e,r,n,i)=>[`M${t+i},${e}`,`L${t+r-i},${e}`,`L${t+r},${e-n/2}`,`L${t+r-i},${e-n}`,`L${t+i},${e-n}`,`L${t},${e-n/2}`,"Z"].join(" "),"createHexagonPathD");o(_Z,"hexagon")});async function LZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.label="",e.labelStyle=r;let{shapeSvg:i}=await mt(t,e,ht(e)),a=Math.max(30,e?.width??0),s=Math.max(30,e?.height??0),{cssStyles:l}=e,u=je.svg(i),h=Qe(e,{});e.look!=="handDrawn"&&(h.roughness=0,h.fillStyle="solid");let f=[{x:0,y:0},{x:a,y:0},{x:0,y:s},{x:a,y:s}],d=Xt(f),p=u.path(d,h),m=i.insert(()=>p,":first-child");return m.attr("class","basic label-container"),l&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",l),n&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",n),m.attr("transform",`translate(${-a/2}, ${-s/2})`),Ke(e,m),e.intersect=function(g){return X.info("Pill intersect",e,{points:f}),Xe.polygon(e,f,g)},i}var RZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();o(LZ,"hourglass")});async function NZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await mt(t,e,"icon-shape default"),p=e.pos==="t",m=l,g=l,{nodeBorder:y}=r,{stylesMap:v}=bc(e),x=-g/2,b=-m/2,T=e.label?8:0,S=je.svg(h),w=Qe(e,{stroke:"none",fill:"none"});e.look!=="handDrawn"&&(w.roughness=0,w.fillStyle="solid");let E=S.rectangle(x,b,g,m,w),_=Math.max(g,f.width),C=m+f.height+T,D=S.rectangle(-_/2,-C/2,_,C,{...w,fill:"transparent",stroke:"none"}),O=h.insert(()=>E,":first-child"),R=h.insert(()=>D);if(e.icon){let k=h.append("g");k.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let L=k.node().getBBox(),A=L.width,I=L.height,M=L.x,P=L.y;k.attr("transform",`translate(${-A/2-M},${p?f.height/2+T/2-I/2-P:-f.height/2-T/2-I/2-P})`),k.attr("style",`color: ${v.get("stroke")??y};`)}return d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${p?-C/2:C/2-f.height})`),O.attr("transform",`translate(0,${p?f.height/2+T/2:-f.height/2-T/2})`),Ke(e,R),e.intersect=function(k){if(X.info("iconSquare intersect",e,k),!e.label)return Xe.rect(e,k);let L=e.x??0,A=e.y??0,I=e.height??0,M=[];return p?M=[{x:L-f.width/2,y:A-I/2},{x:L+f.width/2,y:A-I/2},{x:L+f.width/2,y:A-I/2+f.height+T},{x:L+g/2,y:A-I/2+f.height+T},{x:L+g/2,y:A+I/2},{x:L-g/2,y:A+I/2},{x:L-g/2,y:A-I/2+f.height+T},{x:L-f.width/2,y:A-I/2+f.height+T}]:M=[{x:L-g/2,y:A-I/2},{x:L+g/2,y:A-I/2},{x:L+g/2,y:A-I/2+m},{x:L+f.width/2,y:A-I/2+m},{x:L+f.width/2/2,y:A+I/2},{x:L-f.width/2,y:A+I/2},{x:L-f.width/2,y:A-I/2+m},{x:L-g/2,y:A-I/2+m}],Xe.polygon(e,M,k)},h}var MZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Ft();o(NZ,"icon")});async function IZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await mt(t,e,"icon-shape default"),p=20,m=e.label?8:0,g=e.pos==="t",{nodeBorder:y,mainBkg:v}=r,{stylesMap:x}=bc(e),b=je.svg(h),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=x.get("fill");T.stroke=S??v;let w=h.append("g");e.icon&&w.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let E=w.node().getBBox(),_=E.width,C=E.height,D=E.x,O=E.y,R=Math.max(_,C)*Math.SQRT2+p*2,k=b.circle(0,0,R,T),L=Math.max(R,f.width),A=R+f.height+m,I=b.rectangle(-L/2,-A/2,L,A,{...T,fill:"transparent",stroke:"none"}),M=h.insert(()=>k,":first-child"),P=h.insert(()=>I);return w.attr("transform",`translate(${-_/2-D},${g?f.height/2+m/2-C/2-O:-f.height/2-m/2-C/2-O})`),w.attr("style",`color: ${x.get("stroke")??y};`),d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${g?-A/2:A/2-f.height})`),M.attr("transform",`translate(0,${g?f.height/2+m/2:-f.height/2-m/2})`),Ke(e,P),e.intersect=function(B){return X.info("iconSquare intersect",e,B),Xe.rect(e,B)},h}var OZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Ft();o(IZ,"iconCircle")});var Oa,Zh=N(()=>{"use strict";Oa=o((t,e,r,n,i)=>["M",t+i,e,"H",t+r-i,"A",i,i,0,0,1,t+r,e+i,"V",e+n-i,"A",i,i,0,0,1,t+r-i,e+n,"H",t+i,"A",i,i,0,0,1,t,e+n-i,"V",e+i,"A",i,i,0,0,1,t+i,e,"Z"].join(" "),"createRoundedRectPathD")});async function PZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await mt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=bc(e),T=-y/2,S=-g/2,w=e.label?8:0,E=je.svg(h),_=Qe(e,{});e.look!=="handDrawn"&&(_.roughness=0,_.fillStyle="solid");let C=b.get("fill");_.stroke=C??x;let D=E.path(Oa(T,S,y,g,5),_),O=Math.max(y,f.width),R=g+f.height+w,k=E.rectangle(-O/2,-R/2,O,R,{..._,fill:"transparent",stroke:"none"}),L=h.insert(()=>D,":first-child").attr("class","icon-shape2"),A=h.insert(()=>k);if(e.icon){let I=h.append("g");I.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let M=I.node().getBBox(),P=M.width,B=M.height,F=M.x,z=M.y;I.attr("transform",`translate(${-P/2-F},${m?f.height/2+w/2-B/2-z:-f.height/2-w/2-B/2-z})`),I.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-R/2:R/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+w/2:-f.height/2-w/2})`),Ke(e,A),e.intersect=function(I){if(X.info("iconSquare intersect",e,I),!e.label)return Xe.rect(e,I);let M=e.x??0,P=e.y??0,B=e.height??0,F=[];return m?F=[{x:M-f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2+f.height+w},{x:M+y/2,y:P-B/2+f.height+w},{x:M+y/2,y:P+B/2},{x:M-y/2,y:P+B/2},{x:M-y/2,y:P-B/2+f.height+w},{x:M-f.width/2,y:P-B/2+f.height+w}]:F=[{x:M-y/2,y:P-B/2},{x:M+y/2,y:P-B/2},{x:M+y/2,y:P-B/2+g},{x:M+f.width/2,y:P-B/2+g},{x:M+f.width/2/2,y:P+B/2},{x:M-f.width/2,y:P+B/2},{x:M-f.width/2,y:P-B/2+g},{x:M-y/2,y:P-B/2+g}],Xe.polygon(e,F,I)},h}var BZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Zh();Ft();o(PZ,"iconRounded")});async function FZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await mt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=bc(e),T=-y/2,S=-g/2,w=e.label?8:0,E=je.svg(h),_=Qe(e,{});e.look!=="handDrawn"&&(_.roughness=0,_.fillStyle="solid");let C=b.get("fill");_.stroke=C??x;let D=E.path(Oa(T,S,y,g,.1),_),O=Math.max(y,f.width),R=g+f.height+w,k=E.rectangle(-O/2,-R/2,O,R,{..._,fill:"transparent",stroke:"none"}),L=h.insert(()=>D,":first-child"),A=h.insert(()=>k);if(e.icon){let I=h.append("g");I.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let M=I.node().getBBox(),P=M.width,B=M.height,F=M.x,z=M.y;I.attr("transform",`translate(${-P/2-F},${m?f.height/2+w/2-B/2-z:-f.height/2-w/2-B/2-z})`),I.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-R/2:R/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+w/2:-f.height/2-w/2})`),Ke(e,A),e.intersect=function(I){if(X.info("iconSquare intersect",e,I),!e.label)return Xe.rect(e,I);let M=e.x??0,P=e.y??0,B=e.height??0,F=[];return m?F=[{x:M-f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2+f.height+w},{x:M+y/2,y:P-B/2+f.height+w},{x:M+y/2,y:P+B/2},{x:M-y/2,y:P+B/2},{x:M-y/2,y:P-B/2+f.height+w},{x:M-f.width/2,y:P-B/2+f.height+w}]:F=[{x:M-y/2,y:P-B/2},{x:M+y/2,y:P-B/2},{x:M+y/2,y:P-B/2+g},{x:M+f.width/2,y:P-B/2+g},{x:M+f.width/2/2,y:P+B/2},{x:M-f.width/2,y:P+B/2},{x:M-f.width/2,y:P-B/2+g},{x:M-y/2,y:P-B/2+g}],Xe.polygon(e,F,I)},h}var $Z=N(()=>{"use strict";Wt();yt();jl();Ht();Zh();zt();Ft();o(FZ,"iconSquare")});async function zZ(t,e,{config:{flowchart:r}}){let n=new Image;n.src=e?.img??"",await n.decode();let i=Number(n.naturalWidth.toString().replace("px","")),a=Number(n.naturalHeight.toString().replace("px",""));e.imageAspectRatio=i/a;let{labelStyles:s}=Ye(e);e.labelStyle=s;let l=r?.wrappingWidth;e.defaultWidth=r?.wrappingWidth;let u=Math.max(e.label?l??0:0,e?.assetWidth??i),h=e.constraint==="on"&&e?.assetHeight?e.assetHeight*e.imageAspectRatio:u,f=e.constraint==="on"?h/e.imageAspectRatio:e?.assetHeight??a;e.width=Math.max(h,l??0);let{shapeSvg:d,bbox:p,label:m}=await mt(t,e,"image-shape default"),g=e.pos==="t",y=-h/2,v=-f/2,x=e.label?8:0,b=je.svg(d),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=b.rectangle(y,v,h,f,T),w=Math.max(h,p.width),E=f+p.height+x,_=b.rectangle(-w/2,-E/2,w,E,{...T,fill:"none",stroke:"none"}),C=d.insert(()=>S,":first-child"),D=d.insert(()=>_);if(e.img){let O=d.append("image");O.attr("href",e.img),O.attr("width",h),O.attr("height",f),O.attr("preserveAspectRatio","none"),O.attr("transform",`translate(${-h/2},${g?E/2-f:-E/2})`)}return m.attr("transform",`translate(${-p.width/2-(p.x-(p.left??0))},${g?-f/2-p.height/2-x/2:f/2-p.height/2+x/2})`),C.attr("transform",`translate(0,${g?p.height/2+x/2:-p.height/2-x/2})`),Ke(e,D),e.intersect=function(O){if(X.info("iconSquare intersect",e,O),!e.label)return Xe.rect(e,O);let R=e.x??0,k=e.y??0,L=e.height??0,A=[];return g?A=[{x:R-p.width/2,y:k-L/2},{x:R+p.width/2,y:k-L/2},{x:R+p.width/2,y:k-L/2+p.height+x},{x:R+h/2,y:k-L/2+p.height+x},{x:R+h/2,y:k+L/2},{x:R-h/2,y:k+L/2},{x:R-h/2,y:k-L/2+p.height+x},{x:R-p.width/2,y:k-L/2+p.height+x}]:A=[{x:R-h/2,y:k-L/2},{x:R+h/2,y:k-L/2},{x:R+h/2,y:k-L/2+f},{x:R+p.width/2,y:k-L/2+f},{x:R+p.width/2/2,y:k+L/2},{x:R-p.width/2,y:k+L/2},{x:R-p.width/2,y:k-L/2+f},{x:R-h/2,y:k-L/2+f}],Xe.polygon(e,A,O)},d}var GZ=N(()=>{"use strict";Wt();yt();Ht();zt();Ft();o(zZ,"imageSquare")});async function VZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=[{x:0,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:-3*l/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var UZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(VZ,"inv_trapezoid")});async function Ou(t,e,r){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n;let{shapeSvg:a,bbox:s}=await mt(t,e,ht(e)),l=Math.max(s.width+r.labelPaddingX*2,e?.width||0),u=Math.max(s.height+r.labelPaddingY*2,e?.height||0),h=-l/2,f=-u/2,d,{rx:p,ry:m}=e,{cssStyles:g}=e;if(r?.rx&&r.ry&&(p=r.rx,m=r.ry),e.look==="handDrawn"){let y=je.svg(a),v=Qe(e,{}),x=p||m?y.path(Oa(h,f,l,u,p||0),v):y.rectangle(h,f,l,u,v);d=a.insert(()=>x,":first-child"),d.attr("class","basic label-container").attr("style",zn(g))}else d=a.insert("rect",":first-child"),d.attr("class","basic label-container").attr("style",i).attr("rx",zn(p)).attr("ry",zn(m)).attr("x",h).attr("y",f).attr("width",l).attr("height",u);return Ke(e,d),e.intersect=function(y){return Xe.rect(e,y)},a}var Em=N(()=>{"use strict";Ft();Ht();Zh();zt();Wt();er();o(Ou,"drawRect")});async function HZ(t,e){let{shapeSvg:r,bbox:n,label:i}=await mt(t,e,"label"),a=r.insert("rect",":first-child");return a.attr("width",.1).attr("height",.1),r.attr("class","label edgeLabel"),i.attr("transform",`translate(${-(n.width/2)-(n.x-(n.left??0))}, ${-(n.height/2)-(n.y-(n.top??0))})`),Ke(e,a),e.intersect=function(u){return Xe.rect(e,u)},r}var WZ=N(()=>{"use strict";Em();Ft();Ht();o(HZ,"labelRect")});async function qZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:0,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:-(3*l)/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var YZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(qZ,"lean_left")});async function XZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:-3*l/6,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var jZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(XZ,"lean_right")});function KZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.label="",e.labelStyle=r;let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:a}=e,s=Math.max(35,e?.width??0),l=Math.max(35,e?.height??0),u=7,h=[{x:s,y:0},{x:0,y:l+u/2},{x:s-2*u,y:l+u/2},{x:0,y:2*l},{x:s,y:l-u/2},{x:2*u,y:l-u/2}],f=je.svg(i),d=Qe(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=Xt(h),m=f.path(p,d),g=i.insert(()=>m,":first-child");return a&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",a),n&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",n),g.attr("transform",`translate(-${s/2},${-l})`),Ke(e,g),e.intersect=function(y){return X.info("lightningBolt intersect",e,y),Xe.polygon(e,h,y)},i}var QZ=N(()=>{"use strict";yt();Ft();zt();Wt();Ht();Ft();o(KZ,"lightningBolt")});async function ZZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+(e.padding??0),e.height??0),d=f*.1,p,{cssStyles:m}=e;if(e.look==="handDrawn"){let g=je.svg(i),y=GDe(0,0,l,f,u,h,d),v=VDe(0,h,l,f,u,h),x=Qe(e,{}),b=g.path(y,x),T=g.path(v,x);i.insert(()=>T,":first-child").attr("class","line"),p=i.insert(()=>b,":first-child"),p.attr("class","basic label-container"),m&&p.attr("style",m)}else{let g=zDe(0,0,l,f,u,h,d);p=i.insert("path",":first-child").attr("d",g).attr("class","basic label-container").attr("style",zn(m)).attr("style",n)}return p.attr("label-offset-y",h),p.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),Ke(e,p),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),e.intersect=function(g){let y=Xe.rect(e,g),v=y.x-(e.x??0);if(u!=0&&(Math.abs(v)<(e.width??0)/2||Math.abs(v)==(e.width??0)/2&&Math.abs(y.y-(e.y??0))>(e.height??0)/2-h)){let x=h*h*(1-v*v/(u*u));x>0&&(x=Math.sqrt(x)),x=h-x,g.y-(e.y??0)>0&&(x=-x),y.y+=x}return y},i}var zDe,GDe,VDe,JZ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();zDe=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createCylinderPathD"),GDe=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createOuterCylinderPathD"),VDe=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(ZZ,"linedCylinder")});async function eJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-l/2-l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:f/2},...Go(-l/2-l/2*.1,f/2,l/2+l/2*.1,f/2,h,.8),{x:l/2+l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:-f/2},{x:-l/2,y:-f/2},{x:-l/2,y:f/2*1.1},{x:-l/2,y:-f/2}],y=p.polygon(g.map(x=>[x.x,x.y]),m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)+l/2*.1/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,g,x)},i}var tJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(eJ,"linedWaveEdgedRect")});async function rJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:f-h,y:d+h},{x:f-h,y:d+u+h},{x:f+l-h,y:d+u+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d+u-h},{x:f+l+h,y:d+u-h},{x:f+l+h,y:d-h},{x:f+h,y:d-h},{x:f+h,y:d},{x:f,y:d},{x:f,y:d+h}],v=[{x:f,y:d+h},{x:f+l-h,y:d+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d},{x:f,y:d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),T=Xt(v),S=m.path(T,{...g,fill:"none"}),w=i.insert(()=>S,":first-child");return w.insert(()=>b,":first-child"),w.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)-h-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,y,E)},i}var nJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(rJ,"multiRect")});async function iJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,d=-l/2,p=-f/2,m=5,{cssStyles:g}=e,y=Go(d-m,p+f+m,d+l-m,p+f+m,h,.8),v=y?.[y.length-1],x=[{x:d-m,y:p+m},{x:d-m,y:p+f+m},...y,{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:v.y-2*m},{x:d+l+m,y:v.y-2*m},{x:d+l+m,y:p-m},{x:d+m,y:p-m},{x:d+m,y:p},{x:d,y:p},{x:d,y:p+m}],b=[{x:d,y:p+m},{x:d+l-m,y:p+m},{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:p},{x:d,y:p}],T=je.svg(i),S=Qe(e,{});e.look!=="handDrawn"&&(S.roughness=0,S.fillStyle="solid");let w=Xt(x),E=T.path(w,S),_=Xt(b),C=T.path(_,S),D=i.insert(()=>E,":first-child");return D.insert(()=>C),D.attr("class","basic label-container"),g&&e.look!=="handDrawn"&&D.selectAll("path").attr("style",g),n&&e.look!=="handDrawn"&&D.selectAll("path").attr("style",n),D.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-(a.width/2)-m-(a.x-(a.left??0))}, ${-(a.height/2)+m-h/2-(a.y-(a.top??0))})`),Ke(e,D),e.intersect=function(O){return Xe.polygon(e,x,O)},i}var aJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(iJ,"multiWaveEdgedRectangle")});async function sJ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n,e.useHtmlLabels||tr().flowchart?.htmlLabels!==!1||(e.centerLabel=!0);let{shapeSvg:s,bbox:l,label:u}=await mt(t,e,ht(e)),h=Math.max(l.width+(e.padding??0)*2,e?.width??0),f=Math.max(l.height+(e.padding??0)*2,e?.height??0),d=-h/2,p=-f/2,{cssStyles:m}=e,g=je.svg(s),y=Qe(e,{fill:r.noteBkgColor,stroke:r.noteBorderColor});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=g.rectangle(d,p,h,f,y),x=s.insert(()=>v,":first-child");return x.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",m),i&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",i),u.attr("transform",`translate(${-l.width/2-(l.x-(l.left??0))}, ${-(l.height/2)-(l.y-(l.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},s}var oJ=N(()=>{"use strict";Wt();Ht();zt();Ft();mi();o(sJ,"note")});async function lJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=s+l,h=[{x:u/2,y:0},{x:u,y:-u/2},{x:u/2,y:-u},{x:0,y:-u/2}],f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{}),g=UDe(0,0,u),y=p.path(g,m);f=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`),d&&f.attr("style",d)}else f=Ma(i,u,u,h);return n&&f.attr("style",n),Ke(e,f),e.intersect=function(p){return X.debug(`APA12 Intersect called SPLIT +point:`,p,` +node: +`,e,` +res:`,Xe.polygon(e,h,p)),Xe.polygon(e,h,p)},i}var UDe,cJ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Iu();UDe=o((t,e,r)=>[`M${t+r/2},${e}`,`L${t+r},${e-r/2}`,`L${t+r/2},${e-r}`,`L${t},${e-r/2}`,"Z"].join(" "),"createDecisionBoxPathD");o(lJ,"question")});async function uJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e?.width??0),u=Math.max(a.height+(e.padding??0),e?.height??0),h=-l/2,f=-u/2,d=f/2,p=[{x:h+d,y:f},{x:h,y:0},{x:h+d,y:-f},{x:-h,y:-f},{x:-h,y:f}],{cssStyles:m}=e,g=je.svg(i),y=Qe(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=Xt(p),x=g.path(v,y),b=i.insert(()=>x,":first-child");return b.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),b.attr("transform",`translate(${-d/2},0)`),s.attr("transform",`translate(${-d/2-a.width/2-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),Ke(e,b),e.intersect=function(T){return Xe.polygon(e,p,T)},i}var hJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(uJ,"rect_left_inv_arrow")});function HDe(t,e){e&&t.attr("style",e)}async function WDe(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label;t.label&&yi(t.label)&&(n=await Th(t.label.replace(Ze.lineBreakRegex,` +`),me()));let i=t.isNode?"nodeLabel":"edgeLabel";return r.html('"+n+""),HDe(r,t.labelStyle),r.style("display","inline-block"),r.style("padding-right","1px"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var qDe,Tc,rw=N(()=>{"use strict";fr();yt();Gt();pr();er();o(HDe,"applyStyle");o(WDe,"addHtmlLabel");qDe=o(async(t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),dr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"
    "),X.info("vertexText"+i);let a={isNode:n,label:na(i).replace(/fa[blrs]?:fa-[\w-]+/g,l=>``),labelStyle:e&&e.replace("fill:","color:")};return await WDe(a)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),Tc=qDe});async function fJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i;e.cssClasses?i="node "+e.cssClasses:i="node default";let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=a.insert("g"),l=a.insert("g").attr("class","label").attr("style",n),u=e.description,h=e.label,f=l.node().appendChild(await Tc(h,e.labelStyle,!0,!0)),d={width:0,height:0};if(dr(me()?.flowchart?.htmlLabels)){let C=f.children[0],D=Ge(f);d=C.getBoundingClientRect(),D.attr("width",d.width),D.attr("height",d.height)}X.info("Text 2",u);let p=u||[],m=f.getBBox(),g=l.node().appendChild(await Tc(p.join?p.join("
    "):p,e.labelStyle,!0,!0)),y=g.children[0],v=Ge(g);d=y.getBoundingClientRect(),v.attr("width",d.width),v.attr("height",d.height);let x=(e.padding||0)/2;Ge(g).attr("transform","translate( "+(d.width>m.width?0:(m.width-d.width)/2)+", "+(m.height+x+5)+")"),Ge(f).attr("transform","translate( "+(d.width(X.debug("Rough node insert CXC",O),R),":first-child"),E=a.insert(()=>(X.debug("Rough node insert CXC",O),O),":first-child")}else E=s.insert("rect",":first-child"),_=s.insert("line"),E.attr("class","outer title-state").attr("style",n).attr("x",-d.width/2-x).attr("y",-d.height/2-x).attr("width",d.width+(e.padding||0)).attr("height",d.height+(e.padding||0)),_.attr("class","divider").attr("x1",-d.width/2-x).attr("x2",d.width/2+x).attr("y1",-d.height/2-x+m.height+x).attr("y2",-d.height/2-x+m.height+x);return Ke(e,E),e.intersect=function(C){return Xe.rect(e,C)},a}var dJ=N(()=>{"use strict";fr();pr();Ft();rw();Ht();zt();Wt();Gt();Zh();yt();o(fJ,"rectWithTitle")});async function pJ(t,e){let r={rx:5,ry:5,classes:"",labelPaddingX:(e?.padding||0)*1,labelPaddingY:(e?.padding||0)*1};return Ou(t,e,r)}var mJ=N(()=>{"use strict";Em();o(pJ,"roundedRect")});async function gJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=e?.padding??0,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=-a.width/2-l,d=-a.height/2-l,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d},{x:f+u+8,y:d},{x:f+u+8,y:d+h},{x:f-8,y:d+h},{x:f-8,y:d},{x:f,y:d},{x:f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container").attr("style",zn(p)),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${-u/2+4+(e.padding??0)-(a.x-(a.left??0))},${-h/2+(e.padding??0)-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},i}var yJ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();o(gJ,"shadedProcess")});async function vJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=-l/2,f=-u/2,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:h,y:f},{x:h,y:f+u},{x:h+l,y:f+u},{x:h+l,y:f-u/2}],y=Xt(g),v=p.path(y,m),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),x.attr("transform",`translate(0, ${u/4})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))}, ${-u/4+(e.padding??0)-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.polygon(e,g,b)},i}var xJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(vJ,"slopedRect")});async function bJ(t,e){let r={rx:0,ry:0,classes:"",labelPaddingX:(e?.padding||0)*2,labelPaddingY:(e?.padding||0)*1};return Ou(t,e,r)}var TJ=N(()=>{"use strict";Em();o(bJ,"squareRect")});async function wJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.height+e.padding,l=a.width+s/4+e.padding,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=je.svg(i),d=Qe(e,{}),p=Oa(-l/2,-s/2,l,s,s/2),m=f.path(p,d);u=i.insert(()=>m,":first-child"),u.attr("class","basic label-container").attr("style",zn(h))}else u=i.insert("rect",":first-child"),u.attr("class","basic label-container").attr("style",n).attr("rx",s/2).attr("ry",s/2).attr("x",-l/2).attr("y",-s/2).attr("width",l).attr("height",s);return Ke(e,u),e.intersect=function(f){return Xe.rect(e,f)},i}var kJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Zh();er();o(wJ,"stadium")});async function EJ(t,e){return Ou(t,e,{rx:5,ry:5,classes:"flowchart-node"})}var SJ=N(()=>{"use strict";Em();o(EJ,"state")});function CJ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n;let{cssStyles:a}=e,{lineColor:s,stateBorder:l,nodeBorder:u}=r,h=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),f=je.svg(h),d=Qe(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=f.circle(0,0,14,{...d,stroke:s,strokeWidth:2}),m=l??u,g=f.circle(0,0,5,{...d,fill:m,stroke:m,strokeWidth:2,fillStyle:"solid"}),y=h.insert(()=>p,":first-child");return y.insert(()=>g),a&&y.selectAll("path").attr("style",a),i&&y.selectAll("path").attr("style",i),Ke(e,y),e.intersect=function(v){return Xe.circle(e,7,v)},h}var AJ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(CJ,"stateEnd")});function _J(t,e,{config:{themeVariables:r}}){let{lineColor:n}=r,i=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a;if(e.look==="handDrawn"){let l=je.svg(i).circle(0,0,14,NQ(n));a=i.insert(()=>l),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14)}else a=i.insert("circle",":first-child"),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14);return Ke(e,a),e.intersect=function(s){return Xe.circle(e,7,s)},i}var DJ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(_J,"stateStart")});async function LJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=(e?.padding||0)/2,l=a.width+e.padding,u=a.height+e.padding,h=-a.width/2-s,f=-a.height/2-s,d=[{x:0,y:0},{x:l,y:0},{x:l,y:-u},{x:0,y:-u},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-u},{x:-8,y:-u},{x:-8,y:0}];if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{}),g=p.rectangle(h-8,f,l+16,u,m),y=p.line(h,f,h,f+u,m),v=p.line(h+l,f,h+l,f+u,m);i.insert(()=>y,":first-child"),i.insert(()=>v,":first-child");let x=i.insert(()=>g,":first-child"),{cssStyles:b}=e;x.attr("class","basic label-container").attr("style",zn(b)),Ke(e,x)}else{let p=Ma(i,l,u,d);n&&p.attr("style",n),Ke(e,p)}return e.intersect=function(p){return Xe.polygon(e,d,p)},i}var RJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();er();o(LJ,"subroutine")});async function NJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=-s/2,h=-l/2,f=.2*l,d=.2*l,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:u-f/2,y:h},{x:u+s+f/2,y:h},{x:u+s+f/2,y:h+l},{x:u-f/2,y:h+l}],v=[{x:u+s-f/2,y:h+l},{x:u+s+f/2,y:h+l},{x:u+s+f/2,y:h+l-d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),T=Xt(v),S=m.path(T,{...g,fillStyle:"solid"}),w=i.insert(()=>S,":first-child");return w.insert(()=>b,":first-child"),w.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,y,E)},i}var MJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(NJ,"taggedRect")});async function IJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=.2*l,d=.2*u,p=u+h,{cssStyles:m}=e,g=je.svg(i),y=Qe(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=[{x:-l/2-l/2*.1,y:p/2},...Go(-l/2-l/2*.1,p/2,l/2+l/2*.1,p/2,h,.8),{x:l/2+l/2*.1,y:-p/2},{x:-l/2-l/2*.1,y:-p/2}],x=-l/2+l/2*.1,b=-p/2-d*.4,T=[{x:x+l-f,y:(b+u)*1.4},{x:x+l,y:b+u-d},{x:x+l,y:(b+u)*.9},...Go(x+l,(b+u)*1.3,x+l-f,(b+u)*1.5,-u*.03,.5)],S=Xt(v),w=g.path(S,y),E=Xt(T),_=g.path(E,{...y,fillStyle:"solid"}),C=i.insert(()=>_,":first-child");return C.insert(()=>w,":first-child"),C.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),Ke(e,C),e.intersect=function(D){return Xe.polygon(e,v,D)},i}var OJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(IJ,"taggedWaveEdgedRectangle")});async function PJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+e.padding,e?.width||0),l=Math.max(a.height+e.padding,e?.height||0),u=-s/2,h=-l/2,f=i.insert("rect",":first-child");return f.attr("class","text").attr("style",n).attr("rx",0).attr("ry",0).attr("x",u).attr("y",h).attr("width",s).attr("height",l),Ke(e,f),e.intersect=function(d){return Xe.rect(e,d)},i}var BJ=N(()=>{"use strict";Ft();Ht();zt();o(PJ,"text")});async function FJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s,halfPadding:l}=await mt(t,e,ht(e)),u=e.look==="neo"?l*2:l,h=a.height+u,f=h/2,d=f/(2.5+h/50),p=a.width+d+u,{cssStyles:m}=e,g;if(e.look==="handDrawn"){let y=je.svg(i),v=XDe(0,0,p,h,d,f),x=jDe(0,0,p,h,d,f),b=y.path(v,Qe(e,{})),T=y.path(x,Qe(e,{fill:"none"}));g=i.insert(()=>T,":first-child"),g=i.insert(()=>b,":first-child"),g.attr("class","basic label-container"),m&&g.attr("style",m)}else{let y=YDe(0,0,p,h,d,f);g=i.insert("path",":first-child").attr("d",y).attr("class","basic label-container").attr("style",zn(m)).attr("style",n),g.attr("class","basic label-container"),m&&g.selectAll("path").attr("style",m),n&&g.selectAll("path").attr("style",n)}return g.attr("label-offset-x",d),g.attr("transform",`translate(${-p/2}, ${h/2} )`),s.attr("transform",`translate(${-(a.width/2)-d-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),Ke(e,g),e.intersect=function(y){let v=Xe.rect(e,y),x=v.y-(e.y??0);if(f!=0&&(Math.abs(x)<(e.height??0)/2||Math.abs(x)==(e.height??0)/2&&Math.abs(v.x-(e.x??0))>(e.width??0)/2-d)){let b=d*d*(1-x*x/(f*f));b!=0&&(b=Math.sqrt(Math.abs(b))),b=d-b,y.x-(e.x??0)>0&&(b=-b),v.x+=b}return v},i}var YDe,XDe,jDe,$J=N(()=>{"use strict";Ft();zt();Wt();Ht();er();YDe=o((t,e,r,n,i,a)=>`M${t},${e} + a${i},${a} 0,0,1 0,${-n} + l${r},0 + a${i},${a} 0,0,1 0,${n} + M${r},${-n} + a${i},${a} 0,0,0 0,${n} + l${-r},0`,"createCylinderPathD"),XDe=o((t,e,r,n,i,a)=>[`M${t},${e}`,`M${t+r},${e}`,`a${i},${a} 0,0,0 0,${-n}`,`l${-r},0`,`a${i},${a} 0,0,0 0,${n}`,`l${r},0`].join(" "),"createOuterCylinderPathD"),jDe=o((t,e,r,n,i,a)=>[`M${t+r/2},${-n/2}`,`a${i},${a} 0,0,0 0,${n}`].join(" "),"createInnerCylinderPathD");o(FJ,"tiltedCylinder")});async function zJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=[{x:-3*l/6,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var GJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(zJ,"trapezoid")});async function VJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=60,l=20,u=Math.max(s,a.width+(e.padding??0)*2,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),{cssStyles:f}=e,d=je.svg(i),p=Qe(e,{});e.look!=="handDrawn"&&(p.roughness=0,p.fillStyle="solid");let m=[{x:-u/2*.8,y:-h/2},{x:u/2*.8,y:-h/2},{x:u/2,y:-h/2*.6},{x:u/2,y:h/2},{x:-u/2,y:h/2},{x:-u/2,y:-h/2*.6}],g=Xt(m),y=d.path(g,p),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,m,x)},i}var UJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(VJ,"trapezoidalPentagon")});async function HJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=dr(me().flowchart?.htmlLabels),u=a.width+(e.padding??0),h=u+a.height,f=u+a.height,d=[{x:0,y:0},{x:f,y:0},{x:f/2,y:-h}],{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=Xt(d),v=m.path(y,g),x=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${h/2})`);return p&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),e.width=u,e.height=h,Ke(e,x),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${h/2-(a.height+(e.padding??0)/(l?2:1)-(a.y-(a.top??0)))})`),e.intersect=function(b){return X.info("Triangle intersect",e,d,b),Xe.polygon(e,d,b)},i}var WJ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Ft();pr();Gt();o(HJ,"triangle")});async function qJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/8,f=u+h,{cssStyles:d}=e,m=70-l,g=m>0?m/2:0,y=je.svg(i),v=Qe(e,{});e.look!=="handDrawn"&&(v.roughness=0,v.fillStyle="solid");let x=[{x:-l/2-g,y:f/2},...Go(-l/2-g,f/2,l/2+g,f/2,h,.8),{x:l/2+g,y:-f/2},{x:-l/2-g,y:-f/2}],b=Xt(x),T=y.path(b,v),S=i.insert(()=>T,":first-child");return S.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,x,w)},i}var YJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(qJ,"waveEdgedRectangle")});async function XJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=100,l=50,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=u/h,d=u,p=h;d>p*f?p=d/f:d=p*f,d=Math.max(d,s),p=Math.max(p,l);let m=Math.min(p*.2,p/4),g=p+m*2,{cssStyles:y}=e,v=je.svg(i),x=Qe(e,{});e.look!=="handDrawn"&&(x.roughness=0,x.fillStyle="solid");let b=[{x:-d/2,y:g/2},...Go(-d/2,g/2,d/2,g/2,m,1),{x:d/2,y:-g/2},...Go(d/2,-g/2,-d/2,-g/2,m,-1)],T=Xt(b),S=v.path(T,x),w=i.insert(()=>S,":first-child");return w.attr("class","basic label-container"),y&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",y),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,b,E)},i}var jJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(XJ,"waveRectangle")});async function KJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:f-h,y:d-h},{x:f-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d-h}],v=`M${f-h},${d-h} L${f+l},${d-h} L${f+l},${d+u} L${f-h},${d+u} L${f-h},${d-h} + M${f-h},${d} L${f+l},${d} + M${f},${d-h} L${f},${d+u}`;e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=m.path(v,g),b=i.insert(()=>x,":first-child");return b.attr("transform",`translate(${h/2}, ${h/2})`),b.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)+h/2-(a.x-(a.left??0))}, ${-(a.height/2)+h/2-(a.y-(a.top??0))})`),Ke(e,b),e.intersect=function(T){return Xe.polygon(e,y,T)},i}var QJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(KJ,"windowPane")});async function ML(t,e){let r=e;if(r.alias&&(e.label=r.alias),e.look==="handDrawn"){let{themeVariables:U}=tr(),{background:K}=U,ee={...e,id:e.id+"-background",look:"default",cssStyles:["stroke: none",`fill: ${K}`]};await ML(t,ee)}let n=tr();e.useHtmlLabels=n.htmlLabels;let i=n.er?.diagramPadding??10,a=n.er?.entityPadding??6,{cssStyles:s}=e,{labelStyles:l,nodeStyles:u}=Ye(e);if(r.attributes.length===0&&e.label){let U={rx:0,ry:0,labelPaddingX:i,labelPaddingY:i*1.5,classes:""};ra(e.label,n)+U.labelPaddingX*20){let U=d.width+i*2-(y+v+x+b);y+=U/w,v+=U/w,x>0&&(x+=U/w),b>0&&(b+=U/w)}let _=y+v+x+b,C=je.svg(f),D=Qe(e,{});e.look!=="handDrawn"&&(D.roughness=0,D.fillStyle="solid");let O=0;g.length>0&&(O=g.reduce((U,K)=>U+(K?.rowHeight??0),0));let R=Math.max(E.width+i*2,e?.width||0,_),k=Math.max((O??0)+d.height,e?.height||0),L=-R/2,A=-k/2;f.selectAll("g:not(:first-child)").each((U,K,ee)=>{let Y=Ge(ee[K]),ce=Y.attr("transform"),Z=0,ue=0;if(ce){let j=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(ce);j&&(Z=parseFloat(j[1]),ue=parseFloat(j[2]),Y.attr("class").includes("attribute-name")?Z+=y:Y.attr("class").includes("attribute-keys")?Z+=y+v:Y.attr("class").includes("attribute-comment")&&(Z+=y+v+x))}Y.attr("transform",`translate(${L+i/2+Z}, ${ue+A+d.height+a/2})`)}),f.select(".name").attr("transform","translate("+-d.width/2+", "+(A+a/2)+")");let I=C.rectangle(L,A,R,k,D),M=f.insert(()=>I,":first-child").attr("style",s.join("")),{themeVariables:P}=tr(),{rowEven:B,rowOdd:F,nodeBorder:z}=P;m.push(0);for(let[U,K]of g.entries()){let Y=(U+1)%2===0&&K.yOffset!==0,ce=C.rectangle(L,d.height+A+K?.yOffset,R,K?.rowHeight,{...D,fill:Y?B:F,stroke:z});f.insert(()=>ce,"g.label").attr("style",s.join("")).attr("class",`row-rect-${Y?"even":"odd"}`)}let $=C.line(L,d.height+A,R+L,d.height+A,D);f.insert(()=>$).attr("class","divider"),$=C.line(y+L,d.height+A,y+L,k+A,D),f.insert(()=>$).attr("class","divider"),T&&($=C.line(y+v+L,d.height+A,y+v+L,k+A,D),f.insert(()=>$).attr("class","divider")),S&&($=C.line(y+v+x+L,d.height+A,y+v+x+L,k+A,D),f.insert(()=>$).attr("class","divider"));for(let U of m)$=C.line(L,d.height+A+U,R+L,d.height+A+U,D),f.insert(()=>$).attr("class","divider");if(Ke(e,M),u&&e.look!=="handDrawn"){let K=u.split(";")?.filter(ee=>ee.includes("stroke"))?.map(ee=>`${ee}`).join("; ");f.selectAll("path").attr("style",K??""),f.selectAll(".row-rect-even path").attr("style",u)}return e.intersect=function(U){return Xe.rect(e,U)},f}async function L2(t,e,r,n=0,i=0,a=[],s=""){let l=t.insert("g").attr("class",`label ${a.join(" ")}`).attr("transform",`translate(${n}, ${i})`).attr("style",s);e!==ic(e)&&(e=ic(e),e=e.replaceAll("<","<").replaceAll(">",">"));let u=l.node().appendChild(await qn(l,e,{width:ra(e,r)+100,style:s,useHtmlLabels:r.htmlLabels},r));if(e.includes("<")||e.includes(">")){let f=u.children[0];for(f.textContent=f.textContent.replaceAll("<","<").replaceAll(">",">");f.childNodes[0];)f=f.childNodes[0],f.textContent=f.textContent.replaceAll("<","<").replaceAll(">",">")}let h=u.getBBox();if(dr(r.htmlLabels)){let f=u.children[0];f.style.textAlign="start";let d=Ge(u);h=f.getBoundingClientRect(),d.attr("width",h.width),d.attr("height",h.height)}return h}var ZJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Em();mi();ao();pr();fr();er();o(ML,"erBox");o(L2,"addText")});async function JJ(t,e,r,n,i=r.class.padding??12){let a=n?0:3,s=t.insert("g").attr("class",ht(e)).attr("id",e.domId||e.id),l=null,u=null,h=null,f=null,d=0,p=0,m=0;if(l=s.insert("g").attr("class","annotation-group text"),e.annotations.length>0){let b=e.annotations[0];await nw(l,{text:`\xAB${b}\xBB`},0),d=l.node().getBBox().height}u=s.insert("g").attr("class","label-group text"),await nw(u,e,0,["font-weight: bolder"]);let g=u.node().getBBox();p=g.height,h=s.insert("g").attr("class","members-group text");let y=0;for(let b of e.members){let T=await nw(h,b,y,[b.parseClassifier()]);y+=T+a}m=h.node().getBBox().height,m<=0&&(m=i/2),f=s.insert("g").attr("class","methods-group text");let v=0;for(let b of e.methods){let T=await nw(f,b,v,[b.parseClassifier()]);v+=T+a}let x=s.node().getBBox();if(l!==null){let b=l.node().getBBox();l.attr("transform",`translate(${-b.width/2})`)}return u.attr("transform",`translate(${-g.width/2}, ${d})`),x=s.node().getBBox(),h.attr("transform",`translate(0, ${d+p+i*2})`),x=s.node().getBBox(),f.attr("transform",`translate(0, ${d+p+(m?m+i*4:i*2)})`),x=s.node().getBBox(),{shapeSvg:s,bbox:x}}async function nw(t,e,r,n=[]){let i=t.insert("g").attr("class","label").attr("style",n.join("; ")),a=tr(),s="useHtmlLabels"in e?e.useHtmlLabels:dr(a.htmlLabels)??!0,l="";"text"in e?l=e.text:l=e.label,!s&&l.startsWith("\\")&&(l=l.substring(1)),yi(l)&&(s=!0);let u=await qn(i,fd(na(l)),{width:ra(l,a)+50,classes:"markdown-node-label",useHtmlLabels:s},a),h,f=1;if(s){let d=u.children[0],p=Ge(u);f=d.innerHTML.split("
    ").length,d.innerHTML.includes("")&&(f+=d.innerHTML.split("").length-1);let m=d.getElementsByTagName("img");if(m){let g=l.replace(/]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=a.fontSize?.toString()??window.getComputedStyle(document.body).fontSize,S=parseInt(b,10)*5+"px";y.style.minWidth=S,y.style.maxWidth=S}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}else{n.includes("font-weight: bolder")&&Ge(u).selectAll("tspan").attr("font-weight",""),f=u.children.length;let d=u.children[0];(u.textContent===""||u.textContent.includes(">"))&&(d.textContent=l[0]+l.substring(1).replaceAll(">",">").replaceAll("<","<").trim(),l[1]===" "&&(d.textContent=d.textContent[0]+" "+d.textContent.substring(1))),d.textContent==="undefined"&&(d.textContent=""),h=u.getBBox()}return i.attr("transform","translate(0,"+(-h.height/(2*f)+r)+")"),h.height}var eee=N(()=>{"use strict";fr();mi();Ft();er();Gt();ao();pr();o(JJ,"textHelper");o(nw,"addText")});async function tee(t,e){let r=me(),n=r.class.padding??12,i=n,a=e.useHtmlLabels??dr(r.htmlLabels)??!0,s=e;s.annotations=s.annotations??[],s.members=s.members??[],s.methods=s.methods??[];let{shapeSvg:l,bbox:u}=await JJ(t,e,r,a,i),{labelStyles:h,nodeStyles:f}=Ye(e);e.labelStyle=h,e.cssStyles=s.styles||"";let d=s.styles?.join(";")||f||"";e.cssStyles||(e.cssStyles=d.replaceAll("!important","").split(";"));let p=s.members.length===0&&s.methods.length===0&&!r.class?.hideEmptyMembersBox,m=je.svg(l),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=u.width,v=u.height;s.members.length===0&&s.methods.length===0?v+=i:s.members.length>0&&s.methods.length===0&&(v+=i*2);let x=-y/2,b=-v/2,T=m.rectangle(x-n,b-n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0),y+2*n,v+2*n+(p?n*2:s.members.length===0&&s.methods.length===0?-n:0),g),S=l.insert(()=>T,":first-child");S.attr("class","basic label-container");let w=S.node().getBBox();l.selectAll(".text").each((D,O,R)=>{let k=Ge(R[O]),L=k.attr("transform"),A=0;if(L){let B=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(L);B&&(A=parseFloat(B[2]))}let I=A+b+n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0);a||(I-=4);let M=x;(k.attr("class").includes("label-group")||k.attr("class").includes("annotation-group"))&&(M=-k.node()?.getBBox().width/2||0,l.selectAll("text").each(function(P,B,F){window.getComputedStyle(F[B]).textAnchor==="middle"&&(M=0)})),k.attr("transform",`translate(${M}, ${I})`)});let E=l.select(".annotation-group").node().getBBox().height-(p?n/2:0)||0,_=l.select(".label-group").node().getBBox().height-(p?n/2:0)||0,C=l.select(".members-group").node().getBBox().height-(p?n/2:0)||0;if(s.members.length>0||s.methods.length>0||p){let D=m.line(w.x,E+_+b+n,w.x+w.width,E+_+b+n,g);l.insert(()=>D).attr("class","divider").attr("style",d)}if(p||s.members.length>0||s.methods.length>0){let D=m.line(w.x,E+_+C+b+i*2+n,w.x+w.width,E+_+C+b+n+i*2,g);l.insert(()=>D).attr("class","divider").attr("style",d)}if(s.look!=="handDrawn"&&l.selectAll("path").attr("style",d),S.select(":nth-child(2)").attr("style",d),l.selectAll(".divider").select("path").attr("style",d),e.labelStyle?l.selectAll("span").attr("style",e.labelStyle):l.selectAll("span").attr("style",d),!a){let D=RegExp(/color\s*:\s*([^;]*)/),O=D.exec(d);if(O){let R=O[0].replace("color","fill");l.selectAll("tspan").attr("style",R)}else if(h){let R=D.exec(h);if(R){let k=R[0].replace("color","fill");l.selectAll("tspan").attr("style",k)}}}return Ke(e,S),e.intersect=function(D){return Xe.rect(e,D)},l}var ree=N(()=>{"use strict";Ft();Gt();fr();Wt();zt();Ht();eee();pr();o(tee,"classBox")});async function nee(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i=e,a=e,s=20,l=20,u="verifyMethod"in e,h=ht(e),f=t.insert("g").attr("class",h).attr("id",e.domId??e.id),d;u?d=await Pu(f,`<<${i.type}>>`,0,e.labelStyle):d=await Pu(f,"<<Element>>",0,e.labelStyle);let p=d,m=await Pu(f,i.name,p,e.labelStyle+"; font-weight: bold;");if(p+=m+l,u){let E=await Pu(f,`${i.requirementId?`id: ${i.requirementId}`:""}`,p,e.labelStyle);p+=E;let _=await Pu(f,`${i.text?`Text: ${i.text}`:""}`,p,e.labelStyle);p+=_;let C=await Pu(f,`${i.risk?`Risk: ${i.risk}`:""}`,p,e.labelStyle);p+=C,await Pu(f,`${i.verifyMethod?`Verification: ${i.verifyMethod}`:""}`,p,e.labelStyle)}else{let E=await Pu(f,`${a.type?`Type: ${a.type}`:""}`,p,e.labelStyle);p+=E,await Pu(f,`${a.docRef?`Doc Ref: ${a.docRef}`:""}`,p,e.labelStyle)}let g=(f.node()?.getBBox().width??200)+s,y=(f.node()?.getBBox().height??200)+s,v=-g/2,x=-y/2,b=je.svg(f),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=b.rectangle(v,x,g,y,T),w=f.insert(()=>S,":first-child");if(w.attr("class","basic label-container").attr("style",n),f.selectAll(".label").each((E,_,C)=>{let D=Ge(C[_]),O=D.attr("transform"),R=0,k=0;if(O){let M=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(O);M&&(R=parseFloat(M[1]),k=parseFloat(M[2]))}let L=k-y/2,A=v+s/2;(_===0||_===1)&&(A=R),D.attr("transform",`translate(${A}, ${L+s})`)}),p>d+m+l){let E=b.line(v,x+d+m+l,v+g,x+d+m+l,T);f.insert(()=>E).attr("style",n)}return Ke(e,w),e.intersect=function(E){return Xe.rect(e,E)},f}async function Pu(t,e,r,n=""){if(e==="")return 0;let i=t.insert("g").attr("class","label").attr("style",n),a=me(),s=a.htmlLabels??!0,l=await qn(i,fd(na(e)),{width:ra(e,a)+50,classes:"markdown-node-label",useHtmlLabels:s,style:n},a),u;if(s){let h=l.children[0],f=Ge(l);u=h.getBoundingClientRect(),f.attr("width",u.width),f.attr("height",u.height)}else{let h=l.children[0];for(let f of h.children)f.textContent=f.textContent.replaceAll(">",">").replaceAll("<","<"),n&&f.setAttribute("style",n);u=l.getBBox(),u.height+=6}return i.attr("transform",`translate(${-u.width/2},${-u.height/2+r})`),u.height}var iee=N(()=>{"use strict";Ft();Ht();zt();Wt();er();Gt();ao();fr();o(nee,"requirementBox");o(Pu,"addText")});async function aee(t,e,{config:r}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n||"";let a=10,s=e.width;e.width=(e.width??200)-10;let{shapeSvg:l,bbox:u,label:h}=await mt(t,e,ht(e)),f=e.padding||10,d="",p;"ticket"in e&&e.ticket&&r?.kanban?.ticketBaseUrl&&(d=r?.kanban?.ticketBaseUrl.replace("#TICKET#",e.ticket),p=l.insert("svg:a",":first-child").attr("class","kanban-ticket-link").attr("xlink:href",d).attr("target","_blank"));let m={useHtmlLabels:e.useHtmlLabels,labelStyle:e.labelStyle||"",width:e.width,img:e.img,padding:e.padding||8,centerLabel:!1},g,y;p?{label:g,bbox:y}=await HT(p,"ticket"in e&&e.ticket||"",m):{label:g,bbox:y}=await HT(l,"ticket"in e&&e.ticket||"",m);let{label:v,bbox:x}=await HT(l,"assigned"in e&&e.assigned||"",m);e.width=s;let b=10,T=e?.width||0,S=Math.max(y.height,x.height)/2,w=Math.max(u.height+b*2,e?.height||0)+S,E=-T/2,_=-w/2;h.attr("transform","translate("+(f-T/2)+", "+(-S-u.height/2)+")"),g.attr("transform","translate("+(f-T/2)+", "+(-S+u.height/2)+")"),v.attr("transform","translate("+(f+T/2-x.width-2*a)+", "+(-S+u.height/2)+")");let C,{rx:D,ry:O}=e,{cssStyles:R}=e;if(e.look==="handDrawn"){let k=je.svg(l),L=Qe(e,{}),A=D||O?k.path(Oa(E,_,T,w,D||0),L):k.rectangle(E,_,T,w,L);C=l.insert(()=>A,":first-child"),C.attr("class","basic label-container").attr("style",R||null)}else{C=l.insert("rect",":first-child"),C.attr("class","basic label-container __APA__").attr("style",i).attr("rx",D??5).attr("ry",O??5).attr("x",E).attr("y",_).attr("width",T).attr("height",w);let k="priority"in e&&e.priority;if(k){let L=l.append("line"),A=E+2,I=_+Math.floor((D??0)/2),M=_+w-Math.floor((D??0)/2);L.attr("x1",A).attr("y1",I).attr("x2",A).attr("y2",M).attr("stroke-width","4").attr("stroke",KDe(k))}}return Ke(e,C),e.height=w,e.intersect=function(k){return Xe.rect(e,k)},l}var KDe,see=N(()=>{"use strict";Ft();Ht();Zh();zt();Wt();KDe=o(t=>{switch(t){case"Very High":return"red";case"High":return"orange";case"Medium":return null;case"Low":return"blue";case"Very Low":return"lightblue"}},"colorFromPriority");o(aee,"kanbanItem")});function oee(t){return t in IL}var QDe,ZDe,IL,OL=N(()=>{"use strict";XQ();QQ();JQ();tZ();nZ();aZ();oZ();cZ();hZ();dZ();mZ();yZ();xZ();TZ();kZ();SZ();AZ();DZ();RZ();MZ();OZ();BZ();$Z();GZ();UZ();WZ();YZ();jZ();QZ();JZ();tJ();nJ();aJ();oJ();cJ();hJ();dJ();mJ();yJ();xJ();TJ();kJ();SJ();AJ();DJ();RJ();MJ();OJ();BJ();$J();GJ();UJ();WJ();YJ();jJ();QJ();ZJ();ree();iee();see();QDe=[{semanticName:"Process",name:"Rectangle",shortName:"rect",description:"Standard process shape",aliases:["proc","process","rectangle"],internalAliases:["squareRect"],handler:bJ},{semanticName:"Event",name:"Rounded Rectangle",shortName:"rounded",description:"Represents an event",aliases:["event"],internalAliases:["roundedRect"],handler:pJ},{semanticName:"Terminal Point",name:"Stadium",shortName:"stadium",description:"Terminal point",aliases:["terminal","pill"],handler:wJ},{semanticName:"Subprocess",name:"Framed Rectangle",shortName:"fr-rect",description:"Subprocess",aliases:["subprocess","subproc","framed-rectangle","subroutine"],handler:LJ},{semanticName:"Database",name:"Cylinder",shortName:"cyl",description:"Database storage",aliases:["db","database","cylinder"],handler:pZ},{semanticName:"Start",name:"Circle",shortName:"circle",description:"Starting point",aliases:["circ"],handler:rZ},{semanticName:"Decision",name:"Diamond",shortName:"diam",description:"Decision-making step",aliases:["decision","diamond","question"],handler:lJ},{semanticName:"Prepare Conditional",name:"Hexagon",shortName:"hex",description:"Preparation or condition step",aliases:["hexagon","prepare"],handler:_Z},{semanticName:"Data Input/Output",name:"Lean Right",shortName:"lean-r",description:"Represents input or output",aliases:["lean-right","in-out"],internalAliases:["lean_right"],handler:XZ},{semanticName:"Data Input/Output",name:"Lean Left",shortName:"lean-l",description:"Represents output or input",aliases:["lean-left","out-in"],internalAliases:["lean_left"],handler:qZ},{semanticName:"Priority Action",name:"Trapezoid Base Bottom",shortName:"trap-b",description:"Priority action",aliases:["priority","trapezoid-bottom","trapezoid"],handler:zJ},{semanticName:"Manual Operation",name:"Trapezoid Base Top",shortName:"trap-t",description:"Represents a manual task",aliases:["manual","trapezoid-top","inv-trapezoid"],internalAliases:["inv_trapezoid"],handler:VZ},{semanticName:"Stop",name:"Double Circle",shortName:"dbl-circ",description:"Represents a stop point",aliases:["double-circle"],internalAliases:["doublecircle"],handler:vZ},{semanticName:"Text Block",name:"Text Block",shortName:"text",description:"Text block",handler:PJ},{semanticName:"Card",name:"Notched Rectangle",shortName:"notch-rect",description:"Represents a card",aliases:["card","notched-rectangle"],handler:ZQ},{semanticName:"Lined/Shaded Process",name:"Lined Rectangle",shortName:"lin-rect",description:"Lined process shape",aliases:["lined-rectangle","lined-process","lin-proc","shaded-process"],handler:gJ},{semanticName:"Start",name:"Small Circle",shortName:"sm-circ",description:"Small starting point",aliases:["start","small-circle"],internalAliases:["stateStart"],handler:_J},{semanticName:"Stop",name:"Framed Circle",shortName:"fr-circ",description:"Stop point",aliases:["stop","framed-circle"],internalAliases:["stateEnd"],handler:CJ},{semanticName:"Fork/Join",name:"Filled Rectangle",shortName:"fork",description:"Fork or join in process flow",aliases:["join"],internalAliases:["forkJoin"],handler:EZ},{semanticName:"Collate",name:"Hourglass",shortName:"hourglass",description:"Represents a collate operation",aliases:["hourglass","collate"],handler:LZ},{semanticName:"Comment",name:"Curly Brace",shortName:"brace",description:"Adds a comment",aliases:["comment","brace-l"],handler:sZ},{semanticName:"Comment Right",name:"Curly Brace",shortName:"brace-r",description:"Adds a comment",handler:lZ},{semanticName:"Comment with braces on both sides",name:"Curly Braces",shortName:"braces",description:"Adds a comment",handler:uZ},{semanticName:"Com Link",name:"Lightning Bolt",shortName:"bolt",description:"Communication link",aliases:["com-link","lightning-bolt"],handler:KZ},{semanticName:"Document",name:"Document",shortName:"doc",description:"Represents a document",aliases:["doc","document"],handler:qJ},{semanticName:"Delay",name:"Half-Rounded Rectangle",shortName:"delay",description:"Represents a delay",aliases:["half-rounded-rectangle"],handler:CZ},{semanticName:"Direct Access Storage",name:"Horizontal Cylinder",shortName:"h-cyl",description:"Direct access storage",aliases:["das","horizontal-cylinder"],handler:FJ},{semanticName:"Disk Storage",name:"Lined Cylinder",shortName:"lin-cyl",description:"Disk storage",aliases:["disk","lined-cylinder"],handler:ZZ},{semanticName:"Display",name:"Curved Trapezoid",shortName:"curv-trap",description:"Represents a display",aliases:["curved-trapezoid","display"],handler:fZ},{semanticName:"Divided Process",name:"Divided Rectangle",shortName:"div-rect",description:"Divided process shape",aliases:["div-proc","divided-rectangle","divided-process"],handler:gZ},{semanticName:"Extract",name:"Triangle",shortName:"tri",description:"Extraction process",aliases:["extract","triangle"],handler:HJ},{semanticName:"Internal Storage",name:"Window Pane",shortName:"win-pane",description:"Internal storage",aliases:["internal-storage","window-pane"],handler:KJ},{semanticName:"Junction",name:"Filled Circle",shortName:"f-circ",description:"Junction point",aliases:["junction","filled-circle"],handler:bZ},{semanticName:"Loop Limit",name:"Trapezoidal Pentagon",shortName:"notch-pent",description:"Loop limit step",aliases:["loop-limit","notched-pentagon"],handler:VJ},{semanticName:"Manual File",name:"Flipped Triangle",shortName:"flip-tri",description:"Manual file operation",aliases:["manual-file","flipped-triangle"],handler:wZ},{semanticName:"Manual Input",name:"Sloped Rectangle",shortName:"sl-rect",description:"Manual input step",aliases:["manual-input","sloped-rectangle"],handler:vJ},{semanticName:"Multi-Document",name:"Stacked Document",shortName:"docs",description:"Multiple documents",aliases:["documents","st-doc","stacked-document"],handler:iJ},{semanticName:"Multi-Process",name:"Stacked Rectangle",shortName:"st-rect",description:"Multiple processes",aliases:["procs","processes","stacked-rectangle"],handler:rJ},{semanticName:"Stored Data",name:"Bow Tie Rectangle",shortName:"bow-rect",description:"Stored data",aliases:["stored-data","bow-tie-rectangle"],handler:KQ},{semanticName:"Summary",name:"Crossed Circle",shortName:"cross-circ",description:"Summary",aliases:["summary","crossed-circle"],handler:iZ},{semanticName:"Tagged Document",name:"Tagged Document",shortName:"tag-doc",description:"Tagged document",aliases:["tag-doc","tagged-document"],handler:IJ},{semanticName:"Tagged Process",name:"Tagged Rectangle",shortName:"tag-rect",description:"Tagged process",aliases:["tagged-rectangle","tag-proc","tagged-process"],handler:NJ},{semanticName:"Paper Tape",name:"Flag",shortName:"flag",description:"Paper tape",aliases:["paper-tape"],handler:XJ},{semanticName:"Odd",name:"Odd",shortName:"odd",description:"Odd shape",internalAliases:["rect_left_inv_arrow"],handler:uJ},{semanticName:"Lined Document",name:"Lined Document",shortName:"lin-doc",description:"Lined document",aliases:["lined-document"],handler:eJ}],ZDe=o(()=>{let e=[...Object.entries({state:EJ,choice:eZ,note:sJ,rectWithTitle:fJ,labelRect:HZ,iconSquare:FZ,iconCircle:IZ,icon:NZ,iconRounded:PZ,imageSquare:zZ,anchor:YQ,kanbanItem:aee,classBox:tee,erBox:ML,requirementBox:nee}),...QDe.flatMap(r=>[r.shortName,..."aliases"in r?r.aliases:[],..."internalAliases"in r?r.internalAliases:[]].map(i=>[i,r.handler]))];return Object.fromEntries(e)},"generateShapeMap"),IL=ZDe();o(oee,"isValidShape")});var JDe,iw,lee=N(()=>{"use strict";fr();PT();Gt();yt();OL();er();pr();ci();JDe="flowchart-",iw=class{constructor(){this.vertexCounter=0;this.config=me();this.vertices=new Map;this.edges=[];this.classes=new Map;this.subGraphs=[];this.subGraphLookup=new Map;this.tooltips=new Map;this.subCount=0;this.firstGraphFlag=!0;this.secCount=-1;this.posCrossRef=[];this.funs=[];this.setAccTitle=Ar;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getAccTitle=Dr;this.getAccDescription=Rr;this.getDiagramTitle=Nr;this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{o(this,"FlowDB")}sanitizeText(e){return Ze.sanitizeText(e,this.config)}lookUpDomId(e){for(let r of this.vertices.values())if(r.id===e)return r.domId;return e}addVertex(e,r,n,i,a,s,l={},u){if(!e||e.trim().length===0)return;let h;if(u!==void 0){let m;u.includes(` +`)?m=u+` +`:m=`{ +`+u+` +}`,h=Tm(m,{schema:bm})}let f=this.edges.find(m=>m.id===e);if(f){let m=h;m?.animate!==void 0&&(f.animate=m.animate),m?.animation!==void 0&&(f.animation=m.animation);return}let d,p=this.vertices.get(e);if(p===void 0&&(p={id:e,labelType:"text",domId:JDe+e+"-"+this.vertexCounter,styles:[],classes:[]},this.vertices.set(e,p)),this.vertexCounter++,r!==void 0?(this.config=me(),d=this.sanitizeText(r.text.trim()),p.labelType=r.type,d.startsWith('"')&&d.endsWith('"')&&(d=d.substring(1,d.length-1)),p.text=d):p.text===void 0&&(p.text=e),n!==void 0&&(p.type=n),i?.forEach(m=>{p.styles.push(m)}),a?.forEach(m=>{p.classes.push(m)}),s!==void 0&&(p.dir=s),p.props===void 0?p.props=l:l!==void 0&&Object.assign(p.props,l),h!==void 0){if(h.shape){if(h.shape!==h.shape.toLowerCase()||h.shape.includes("_"))throw new Error(`No such shape: ${h.shape}. Shape names should be lowercase.`);if(!oee(h.shape))throw new Error(`No such shape: ${h.shape}.`);p.type=h?.shape}h?.label&&(p.text=h?.label),h?.icon&&(p.icon=h?.icon,!h.label?.trim()&&p.text===e&&(p.text="")),h?.form&&(p.form=h?.form),h?.pos&&(p.pos=h?.pos),h?.img&&(p.img=h?.img,!h.label?.trim()&&p.text===e&&(p.text="")),h?.constraint&&(p.constraint=h.constraint),h.w&&(p.assetWidth=Number(h.w)),h.h&&(p.assetHeight=Number(h.h))}}addSingleLink(e,r,n,i){let l={start:e,end:r,type:void 0,text:"",labelType:"text",classes:[],isUserDefinedId:!1,interpolate:this.edges.defaultInterpolate};X.info("abc78 Got edge...",l);let u=n.text;if(u!==void 0&&(l.text=this.sanitizeText(u.text.trim()),l.text.startsWith('"')&&l.text.endsWith('"')&&(l.text=l.text.substring(1,l.text.length-1)),l.labelType=u.type),n!==void 0&&(l.type=n.type,l.stroke=n.stroke,l.length=n.length>10?10:n.length),i&&!this.edges.some(h=>h.id===i))l.id=i,l.isUserDefinedId=!0;else{let h=this.edges.filter(f=>f.start===l.start&&f.end===l.end);h.length===0?l.id=Wh(l.start,l.end,{counter:0,prefix:"L"}):l.id=Wh(l.start,l.end,{counter:h.length+1,prefix:"L"})}if(this.edges.length<(this.config.maxEdges??500))X.info("Pushing edge..."),this.edges.push(l);else throw new Error(`Edge limit exceeded. ${this.edges.length} edges found, but the limit is ${this.config.maxEdges}. + +Initialize mermaid with maxEdges set to a higher number to allow more edges. +You cannot set this config via configuration inside the diagram as it is a secure config. +You have to call mermaid.initialize.`)}isLinkData(e){return e!==null&&typeof e=="object"&&"id"in e&&typeof e.id=="string"}addLink(e,r,n){let i=this.isLinkData(n)?n.id.replace("@",""):void 0;X.info("addLink",e,r,i);for(let a of e)for(let s of r){let l=a===e[e.length-1],u=s===r[0];l&&u?this.addSingleLink(a,s,n,i):this.addSingleLink(a,s,n,void 0)}}updateLinkInterpolate(e,r){e.forEach(n=>{n==="default"?this.edges.defaultInterpolate=r:this.edges[n].interpolate=r})}updateLink(e,r){e.forEach(n=>{if(typeof n=="number"&&n>=this.edges.length)throw new Error(`The index ${n} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${this.edges.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);n==="default"?this.edges.defaultStyle=r:(this.edges[n].style=r,(this.edges[n]?.style?.length??0)>0&&!this.edges[n]?.style?.some(i=>i?.startsWith("fill"))&&this.edges[n]?.style?.push("fill:none"))})}addClass(e,r){let n=r.join().replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");e.split(",").forEach(i=>{let a=this.classes.get(i);a===void 0&&(a={id:i,styles:[],textStyles:[]},this.classes.set(i,a)),n?.forEach(s=>{if(/color/.exec(s)){let l=s.replace("fill","bgFill");a.textStyles.push(l)}a.styles.push(s)})})}setDirection(e){this.direction=e,/.*/.exec(this.direction)&&(this.direction="LR"),/.*v/.exec(this.direction)&&(this.direction="TB"),this.direction==="TD"&&(this.direction="TB")}setClass(e,r){for(let n of e.split(",")){let i=this.vertices.get(n);i&&i.classes.push(r);let a=this.edges.find(l=>l.id===n);a&&a.classes.push(r);let s=this.subGraphLookup.get(n);s&&s.classes.push(r)}}setTooltip(e,r){if(r!==void 0){r=this.sanitizeText(r);for(let n of e.split(","))this.tooltips.set(this.version==="gen-1"?this.lookUpDomId(n):n,r)}}setClickFun(e,r,n){let i=this.lookUpDomId(e);if(me().securityLevel!=="loose"||r===void 0)return;let a=[];if(typeof n=="string"){a=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let l=0;l{let l=document.querySelector(`[id="${i}"]`);l!==null&&l.addEventListener("click",()=>{Vt.runFunc(r,...a)},!1)}))}setLink(e,r,n){e.split(",").forEach(i=>{let a=this.vertices.get(i);a!==void 0&&(a.link=Vt.formatUrl(r,this.config),a.linkTarget=n)}),this.setClass(e,"clickable")}getTooltip(e){return this.tooltips.get(e)}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFun(i,r,n)}),this.setClass(e,"clickable")}bindFunctions(e){this.funs.forEach(r=>{r(e)})}getDirection(){return this.direction?.trim()}getVertices(){return this.vertices}getEdges(){return this.edges}getClasses(){return this.classes}setupToolTips(e){let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=a.currentTarget?.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.bottom+"px"),r.html(r.html().replace(/<br\/>/g,"
    ")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})}clear(e="gen-2"){this.vertices=new Map,this.classes=new Map,this.edges=[],this.funs=[this.setupToolTips.bind(this)],this.subGraphs=[],this.subGraphLookup=new Map,this.subCount=0,this.tooltips=new Map,this.firstGraphFlag=!0,this.version=e,this.config=me(),kr()}setGen(e){this.version=e||"gen-2"}defaultStyle(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"}addSubGraph(e,r,n){let i=e.text.trim(),a=n.text;e===n&&/\s/.exec(n.text)&&(i=void 0);let l=o(p=>{let m={boolean:{},number:{},string:{}},g=[],y;return{nodeList:p.filter(function(x){let b=typeof x;return x.stmt&&x.stmt==="dir"?(y=x.value,!1):x.trim()===""?!1:b in m?m[b].hasOwnProperty(x)?!1:m[b][x]=!0:g.includes(x)?!1:g.push(x)}),dir:y}},"uniq")(r.flat()),u=l.nodeList,h=l.dir,f=me().flowchart??{};if(h=h??(f.inheritDir?this.getDirection()??me().direction??void 0:void 0),this.version==="gen-1")for(let p=0;p2e3)return{result:!1,count:0};if(this.posCrossRef[this.secCount]=r,this.subGraphs[r].id===e)return{result:!0,count:0};let i=0,a=1;for(;i=0){let l=this.indexNodes2(e,s);if(l.result)return{result:!0,count:a+l.count};a=a+l.count}i=i+1}return{result:!1,count:a}}getDepthFirstPos(e){return this.posCrossRef[e]}indexNodes(){this.secCount=-1,this.subGraphs.length>0&&this.indexNodes2("none",this.subGraphs.length-1)}getSubGraphs(){return this.subGraphs}firstGraph(){return this.firstGraphFlag?(this.firstGraphFlag=!1,!0):!1}destructStartLink(e){let r=e.trim(),n="arrow_open";switch(r[0]){case"<":n="arrow_point",r=r.slice(1);break;case"x":n="arrow_cross",r=r.slice(1);break;case"o":n="arrow_circle",r=r.slice(1);break}let i="normal";return r.includes("=")&&(i="thick"),r.includes(".")&&(i="dotted"),{type:n,stroke:i}}countChar(e,r){let n=r.length,i=0;for(let a=0;a":i="arrow_point",r.startsWith("<")&&(i="double_"+i,n=n.slice(1));break;case"o":i="arrow_circle",r.startsWith("o")&&(i="double_"+i,n=n.slice(1));break}let a="normal",s=n.length-1;n.startsWith("=")&&(a="thick"),n.startsWith("~")&&(a="invisible");let l=this.countChar(".",n);return l&&(a="dotted",s=l),{type:i,stroke:a,length:s}}destructLink(e,r){let n=this.destructEndLink(e),i;if(r){if(i=this.destructStartLink(r),i.stroke!==n.stroke)return{type:"INVALID",stroke:"INVALID"};if(i.type==="arrow_open")i.type=n.type;else{if(i.type!==n.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return i.type==="double_arrow"&&(i.type="double_arrow_point"),i.length=n.length,i}return n}exists(e,r){for(let n of e)if(n.nodes.includes(r))return!0;return!1}makeUniq(e,r){let n=[];return e.nodes.forEach((i,a)=>{this.exists(r,i)||n.push(e.nodes[a])}),{nodes:n}}getTypeFromVertex(e){if(e.img)return"imageSquare";if(e.icon)return e.form==="circle"?"iconCircle":e.form==="square"?"iconSquare":e.form==="rounded"?"iconRounded":"icon";switch(e.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";case"ellipse":return"ellipse";default:return e.type}}findNode(e,r){return e.find(n=>n.id===r)}destructEdgeType(e){let r="none",n="arrow_point";switch(e){case"arrow_point":case"arrow_circle":case"arrow_cross":n=e;break;case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":r=e.replace("double_",""),n=r;break}return{arrowTypeStart:r,arrowTypeEnd:n}}addNodeFromVertex(e,r,n,i,a,s){let l=n.get(e.id),u=i.get(e.id)??!1,h=this.findNode(r,e.id);if(h)h.cssStyles=e.styles,h.cssCompiledStyles=this.getCompiledStyles(e.classes),h.cssClasses=e.classes.join(" ");else{let f={id:e.id,label:e.text,labelStyle:"",parentId:l,padding:a.flowchart?.padding||8,cssStyles:e.styles,cssCompiledStyles:this.getCompiledStyles(["default","node",...e.classes]),cssClasses:"default "+e.classes.join(" "),dir:e.dir,domId:e.domId,look:s,link:e.link,linkTarget:e.linkTarget,tooltip:this.getTooltip(e.id),icon:e.icon,pos:e.pos,img:e.img,assetWidth:e.assetWidth,assetHeight:e.assetHeight,constraint:e.constraint};u?r.push({...f,isGroup:!0,shape:"rect"}):r.push({...f,isGroup:!1,shape:this.getTypeFromVertex(e)})}}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}getData(){let e=me(),r=[],n=[],i=this.getSubGraphs(),a=new Map,s=new Map;for(let h=i.length-1;h>=0;h--){let f=i[h];f.nodes.length>0&&s.set(f.id,!0);for(let d of f.nodes)a.set(d,f.id)}for(let h=i.length-1;h>=0;h--){let f=i[h];r.push({id:f.id,label:f.title,labelStyle:"",parentId:a.get(f.id),padding:8,cssCompiledStyles:this.getCompiledStyles(f.classes),cssClasses:f.classes.join(" "),shape:"rect",dir:f.dir,isGroup:!0,look:e.look})}this.getVertices().forEach(h=>{this.addNodeFromVertex(h,r,a,s,e,e.look||"classic")});let u=this.getEdges();return u.forEach((h,f)=>{let{arrowTypeStart:d,arrowTypeEnd:p}=this.destructEdgeType(h.type),m=[...u.defaultStyle??[]];h.style&&m.push(...h.style);let g={id:Wh(h.start,h.end,{counter:f,prefix:"L"},h.id),isUserDefinedId:h.isUserDefinedId,start:h.start,end:h.end,type:h.type??"normal",label:h.text,labelpos:"c",thickness:h.stroke,minlen:h.length,classes:h?.stroke==="invisible"?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":d,arrowTypeEnd:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":p,arrowheadStyle:"fill: #333",cssCompiledStyles:this.getCompiledStyles(h.classes),labelStyle:m,style:m,pattern:h.stroke,look:e.look,animate:h.animate,animation:h.animation,curve:h.interpolate||this.edges.defaultInterpolate||e.flowchart?.curve};n.push(g)}),{nodes:r,edges:n,other:{},config:e}}defaultConfig(){return $3.flowchart}}});var wc,Sm=N(()=>{"use strict";fr();wc=o((t,e)=>{let r;return e==="sandbox"&&(r=Ge("#i"+t)),(e==="sandbox"?Ge(r.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${t}"]`)},"getDiagramElement")});var Bu,R2=N(()=>{"use strict";Bu=o(({flowchart:t})=>{let e=t?.subGraphTitleMargin?.top??0,r=t?.subGraphTitleMargin?.bottom??0,n=e+r;return{subGraphTitleTopMargin:e,subGraphTitleBottomMargin:r,subGraphTitleTotalMargin:n}},"getSubGraphTitleMargins")});var cee,e9e,t9e,r9e,n9e,i9e,a9e,uee,Cm,hee,aw=N(()=>{"use strict";Gt();pr();yt();R2();fr();Wt();ao();mL();rw();Zh();zt();cee=o(async(t,e)=>{X.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Ye(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=dr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await qn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0}),y=g.getBBox();if(dr(r.flowchart.htmlLabels)){let _=g.children[0],C=Ge(g);y=_.getBoundingClientRect(),C.attr("width",y.width),C.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,T=e.y-x/2;X.trace("Data ",e,JSON.stringify(e));let S;if(e.look==="handDrawn"){let _=je.svg(d),C=Qe(e,{roughness:.7,fill:a,stroke:s,fillWeight:3,seed:i}),D=_.path(Oa(b,T,v,x,0),C);S=d.insert(()=>(X.debug("Rough node insert CXC",D),D),":first-child"),S.select("path:nth-child(2)").attr("style",h.join(";")),S.select("path").attr("style",f.join(";").replace("fill","stroke"))}else S=d.insert("rect",":first-child"),S.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",T).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:w}=Bu(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+w})`),l){let _=m.select("span");_&&_.attr("style",l)}let E=S.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(_){return Xh(e,_)},{cluster:d,labelBBox:y}},"rect"),e9e=o((t,e)=>{let r=t.insert("g").attr("class","note-cluster").attr("id",e.id),n=r.insert("rect",":first-child"),i=0*e.padding,a=i/2;n.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+i).attr("height",e.height+i).attr("fill","none");let s=n.node().getBBox();return e.width=s.width,e.height=s.height,e.intersect=function(l){return Xh(e,l)},{cluster:r,labelBBox:{width:0,height:0}}},"noteGroup"),t9e=o(async(t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{altBackground:a,compositeBackground:s,compositeTitleBackground:l,nodeBorder:u}=n,h=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-id",e.id).attr("data-look",e.look),f=h.insert("g",":first-child"),d=h.insert("g").attr("class","cluster-label"),p=h.append("rect"),m=d.node().appendChild(await Tc(e.label,e.labelStyle,void 0,!0)),g=m.getBBox();if(dr(r.flowchart.htmlLabels)){let D=m.children[0],O=Ge(m);g=D.getBoundingClientRect(),O.attr("width",g.width),O.attr("height",g.height)}let y=0*e.padding,v=y/2,x=(e.width<=g.width+e.padding?g.width+e.padding:e.width)+y;e.width<=g.width+e.padding?e.diff=(x-e.width)/2-e.padding:e.diff=-e.padding;let b=e.height+y,T=e.height+y-g.height-6,S=e.x-x/2,w=e.y-b/2;e.width=x;let E=e.y-e.height/2-v+g.height+2,_;if(e.look==="handDrawn"){let D=e.cssClasses.includes("statediagram-cluster-alt"),O=je.svg(h),R=e.rx||e.ry?O.path(Oa(S,w,x,b,10),{roughness:.7,fill:l,fillStyle:"solid",stroke:u,seed:i}):O.rectangle(S,w,x,b,{seed:i});_=h.insert(()=>R,":first-child");let k=O.rectangle(S,E,x,T,{fill:D?a:s,fillStyle:D?"hachure":"solid",stroke:u,seed:i});_=h.insert(()=>R,":first-child"),p=h.insert(()=>k)}else _=f.insert("rect",":first-child"),_.attr("class","outer").attr("x",S).attr("y",w).attr("width",x).attr("height",b).attr("data-look",e.look),p.attr("class","inner").attr("x",S).attr("y",E).attr("width",x).attr("height",T);d.attr("transform",`translate(${e.x-g.width/2}, ${w+1-(dr(r.flowchart.htmlLabels)?0:3)})`);let C=_.node().getBBox();return e.height=C.height,e.offsetX=0,e.offsetY=g.height-e.padding/2,e.labelBBox=g,e.intersect=function(D){return Xh(e,D)},{cluster:h,labelBBox:g}},"roundedWithTitle"),r9e=o(async(t,e)=>{X.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Ye(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=dr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await qn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0,width:e.width}),y=g.getBBox();if(dr(r.flowchart.htmlLabels)){let _=g.children[0],C=Ge(g);y=_.getBoundingClientRect(),C.attr("width",y.width),C.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,T=e.y-x/2;X.trace("Data ",e,JSON.stringify(e));let S;if(e.look==="handDrawn"){let _=je.svg(d),C=Qe(e,{roughness:.7,fill:a,stroke:s,fillWeight:4,seed:i}),D=_.path(Oa(b,T,v,x,e.rx),C);S=d.insert(()=>(X.debug("Rough node insert CXC",D),D),":first-child"),S.select("path:nth-child(2)").attr("style",h.join(";")),S.select("path").attr("style",f.join(";").replace("fill","stroke"))}else S=d.insert("rect",":first-child"),S.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",T).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:w}=Bu(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+w})`),l){let _=m.select("span");_&&_.attr("style",l)}let E=S.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(_){return Xh(e,_)},{cluster:d,labelBBox:y}},"kanbanSection"),n9e=o((t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{nodeBorder:a}=n,s=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-look",e.look),l=s.insert("g",":first-child"),u=0*e.padding,h=e.width+u;e.diff=-e.padding;let f=e.height+u,d=e.x-h/2,p=e.y-f/2;e.width=h;let m;if(e.look==="handDrawn"){let v=je.svg(s).rectangle(d,p,h,f,{fill:"lightgrey",roughness:.5,strokeLineDash:[5],stroke:a,seed:i});m=s.insert(()=>v,":first-child")}else m=l.insert("rect",":first-child"),m.attr("class","divider").attr("x",d).attr("y",p).attr("width",h).attr("height",f).attr("data-look",e.look);let g=m.node().getBBox();return e.height=g.height,e.offsetX=0,e.offsetY=0,e.intersect=function(y){return Xh(e,y)},{cluster:s,labelBBox:{}}},"divider"),i9e=cee,a9e={rect:cee,squareRect:i9e,roundedWithTitle:t9e,noteGroup:e9e,divider:n9e,kanbanSection:r9e},uee=new Map,Cm=o(async(t,e)=>{let r=e.shape||"rect",n=await a9e[r](t,e);return uee.set(e.id,n),n},"insertCluster"),hee=o(()=>{uee=new Map},"clear")});function sw(t,e){if(t===void 0||e===void 0)return{angle:0,deltaX:0,deltaY:0};t=Yn(t),e=Yn(e);let[r,n]=[t.x,t.y],[i,a]=[e.x,e.y],s=i-r,l=a-n;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}var Vo,Yn,ow,PL=N(()=>{"use strict";Vo={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:4};o(sw,"calculateDeltaAndAngle");Yn=o(t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,"pointTransformer"),ow=o(t=>({x:o(function(e,r,n){let i=0,a=Yn(n[0]).x=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(Vo,t.arrowTypeEnd)){let{angle:m,deltaX:g}=sw(n[n.length-1],n[n.length-2]);i=Vo[t.arrowTypeEnd]*Math.cos(m)*(g>=0?1:-1)}let s=Math.abs(Yn(e).x-Yn(n[n.length-1]).x),l=Math.abs(Yn(e).y-Yn(n[n.length-1]).y),u=Math.abs(Yn(e).x-Yn(n[0]).x),h=Math.abs(Yn(e).y-Yn(n[0]).y),f=Vo[t.arrowTypeStart],d=Vo[t.arrowTypeEnd],p=1;if(s0&&l0&&h=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(Vo,t.arrowTypeEnd)){let{angle:m,deltaY:g}=sw(n[n.length-1],n[n.length-2]);i=Vo[t.arrowTypeEnd]*Math.abs(Math.sin(m))*(g>=0?1:-1)}let s=Math.abs(Yn(e).y-Yn(n[n.length-1]).y),l=Math.abs(Yn(e).x-Yn(n[n.length-1]).x),u=Math.abs(Yn(e).y-Yn(n[0]).y),h=Math.abs(Yn(e).x-Yn(n[0]).x),f=Vo[t.arrowTypeStart],d=Vo[t.arrowTypeEnd],p=1;if(s0&&l0&&h{"use strict";yt();dee=o((t,e,r,n,i,a)=>{e.arrowTypeStart&&fee(t,"start",e.arrowTypeStart,r,n,i,a),e.arrowTypeEnd&&fee(t,"end",e.arrowTypeEnd,r,n,i,a)},"addEdgeMarkers"),s9e={arrow_cross:{type:"cross",fill:!1},arrow_point:{type:"point",fill:!0},arrow_barb:{type:"barb",fill:!0},arrow_circle:{type:"circle",fill:!1},aggregation:{type:"aggregation",fill:!1},extension:{type:"extension",fill:!1},composition:{type:"composition",fill:!0},dependency:{type:"dependency",fill:!0},lollipop:{type:"lollipop",fill:!1},only_one:{type:"onlyOne",fill:!1},zero_or_one:{type:"zeroOrOne",fill:!1},one_or_more:{type:"oneOrMore",fill:!1},zero_or_more:{type:"zeroOrMore",fill:!1},requirement_arrow:{type:"requirement_arrow",fill:!1},requirement_contains:{type:"requirement_contains",fill:!1}},fee=o((t,e,r,n,i,a,s)=>{let l=s9e[r];if(!l){X.warn(`Unknown arrow type: ${r}`);return}let u=l.type,f=`${i}_${a}-${u}${e==="start"?"Start":"End"}`;if(s&&s.trim()!==""){let d=s.replace(/[^\dA-Za-z]/g,"_"),p=`${f}_${d}`;if(!document.getElementById(p)){let m=document.getElementById(f);if(m){let g=m.cloneNode(!0);g.id=p,g.querySelectorAll("path, circle, line").forEach(v=>{v.setAttribute("stroke",s),l.fill&&v.setAttribute("fill",s)}),m.parentNode?.appendChild(g)}}t.attr(`marker-${e}`,`url(${n}#${p})`)}else t.attr(`marker-${e}`,`url(${n}#${f})`)},"addEdgeMarker")});function lw(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}function c9e(t){let e=[],r=[];for(let n=1;n5&&Math.abs(a.y-i.y)>5||i.y===a.y&&a.x===s.x&&Math.abs(a.x-i.x)>5&&Math.abs(a.y-s.y)>5)&&(e.push(a),r.push(n))}return{cornerPoints:e,cornerPointPositions:r}}var cw,da,yee,N2,uw,hw,o9e,l9e,mee,gee,u9e,fw,BL=N(()=>{"use strict";Gt();pr();yt();ao();er();PL();R2();fr();Wt();rw();pee();zt();cw=new Map,da=new Map,yee=o(()=>{cw.clear(),da.clear()},"clear"),N2=o(t=>t?t.reduce((r,n)=>r+";"+n,""):"","getLabelStyles"),uw=o(async(t,e)=>{let r=dr(me().flowchart.htmlLabels),n=await qn(t,e.label,{style:N2(e.labelStyle),useHtmlLabels:r,addSvgBackground:!0,isNode:!1});X.info("abc82",e,e.labelType);let i=t.insert("g").attr("class","edgeLabel"),a=i.insert("g").attr("class","label");a.node().appendChild(n);let s=n.getBBox();if(r){let u=n.children[0],h=Ge(n);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}a.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),cw.set(e.id,i),e.width=s.width,e.height=s.height;let l;if(e.startLabelLeft){let u=await Tc(e.startLabelLeft,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),da.get(e.id)||da.set(e.id,{}),da.get(e.id).startLeft=h,lw(l,e.startLabelLeft)}if(e.startLabelRight){let u=await Tc(e.startLabelRight,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=h.node().appendChild(u),f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),da.get(e.id)||da.set(e.id,{}),da.get(e.id).startRight=h,lw(l,e.startLabelRight)}if(e.endLabelLeft){let u=await Tc(e.endLabelLeft,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),da.get(e.id)||da.set(e.id,{}),da.get(e.id).endLeft=h,lw(l,e.endLabelLeft)}if(e.endLabelRight){let u=await Tc(e.endLabelRight,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),da.get(e.id)||da.set(e.id,{}),da.get(e.id).endRight=h,lw(l,e.endLabelRight)}return n},"insertEdgeLabel");o(lw,"setTerminalWidth");hw=o((t,e)=>{X.debug("Moving label abc88 ",t.id,t.label,cw.get(t.id),e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Bu(n);if(t.label){let a=cw.get(t.id),s=t.x,l=t.y;if(r){let u=Vt.calcLabelPosition(r);X.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=da.get(t.id).startLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=da.get(t.id).startRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=da.get(t.id).endLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=da.get(t.id).endRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),o9e=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),l9e=o((t,e,r)=>{X.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(e)} + insidePoint : ${JSON.stringify(r)} + node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.xMath.abs(n-e.x)*u){let d=r.y{X.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(X.info("abc88 checking point",a,e),!o9e(e,a)&&!i){let s=l9e(e,n,a);X.debug("abc88 inside",a,n,s),X.debug("abc88 intersection",s,e);let l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)?X.warn("abc88 no intersect",s,r):r.push(s),i=!0}else X.warn("abc88 outside",a,n),n=a,i||r.push(a)}),X.debug("returning points",r),r},"cutPathAtIntersect");o(c9e,"extractCornerPoints");gee=o(function(t,e,r){let n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),s=r/a;return{x:e.x-s*n,y:e.y-s*i}},"findAdjacentPoint"),u9e=o(function(t){let{cornerPointPositions:e}=c9e(t),r=[];for(let n=0;n10&&Math.abs(a.y-i.y)>=10){X.debug("Corner point fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));let m=5;s.x===l.x?p={x:h<0?l.x-m+d:l.x+m-d,y:f<0?l.y-d:l.y+d}:p={x:h<0?l.x-d:l.x+d,y:f<0?l.y-m+d:l.y+m-d}}else X.debug("Corner point skipping fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));r.push(p,u)}else r.push(t[n]);return r},"fixCorners"),fw=o(function(t,e,r,n,i,a,s){let{handDrawnSeed:l}=me(),u=e.points,h=!1,f=i;var d=a;let p=[];for(let D in e.cssCompiledStyles)S2(D)||p.push(e.cssCompiledStyles[D]);d.intersect&&f.intersect&&(u=u.slice(1,e.points.length-1),u.unshift(f.intersect(u[0])),X.debug("Last point APA12",e.start,"-->",e.end,u[u.length-1],d,d.intersect(u[u.length-1])),u.push(d.intersect(u[u.length-1]))),e.toCluster&&(X.info("to cluster abc88",r.get(e.toCluster)),u=mee(e.points,r.get(e.toCluster).node),h=!0),e.fromCluster&&(X.debug("from cluster abc88",r.get(e.fromCluster),JSON.stringify(u,null,2)),u=mee(u.reverse(),r.get(e.fromCluster).node).reverse(),h=!0);let m=u.filter(D=>!Number.isNaN(D.y));m=u9e(m);let g=No;switch(g=Su,e.curve){case"linear":g=Su;break;case"basis":g=No;break;case"cardinal":g=qv;break;case"bumpX":g=Gv;break;case"bumpY":g=Vv;break;case"catmullRom":g=jv;break;case"monotoneX":g=Kv;break;case"monotoneY":g=Qv;break;case"natural":g=K0;break;case"step":g=Q0;break;case"stepAfter":g=Jv;break;case"stepBefore":g=Zv;break;default:g=No}let{x:y,y:v}=ow(e),x=Cl().x(y).y(v).curve(g),b;switch(e.thickness){case"normal":b="edge-thickness-normal";break;case"thick":b="edge-thickness-thick";break;case"invisible":b="edge-thickness-invisible";break;default:b="edge-thickness-normal"}switch(e.pattern){case"solid":b+=" edge-pattern-solid";break;case"dotted":b+=" edge-pattern-dotted";break;case"dashed":b+=" edge-pattern-dashed";break;default:b+=" edge-pattern-solid"}let T,S=x(m),w=Array.isArray(e.style)?e.style:e.style?[e.style]:[],E=w.find(D=>D?.startsWith("stroke:"));if(e.look==="handDrawn"){let D=je.svg(t);Object.assign([],m);let O=D.path(S,{roughness:.3,seed:l});b+=" transition",T=Ge(O).select("path").attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")).attr("style",w?w.reduce((k,L)=>k+";"+L,""):"");let R=T.attr("d");T.attr("d",R),t.node().appendChild(T.node())}else{let D=p.join(";"),O=w?w.reduce((L,A)=>L+A+";",""):"",R="";e.animate&&(R=" edge-animation-fast"),e.animation&&(R=" edge-animation-"+e.animation);let k=D?D+";"+O+";":O;T=t.append("path").attr("d",S).attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")+(R??"")).attr("style",k),E=k.match(/stroke:([^;]+)/)?.[1]}let _="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(_=mu(!0)),X.info("arrowTypeStart",e.arrowTypeStart),X.info("arrowTypeEnd",e.arrowTypeEnd),dee(T,e,_,s,n,E);let C={};return h&&(C.updatedPath=u),C.originalPath=e.points,C},"insertEdge")});var h9e,f9e,d9e,p9e,m9e,g9e,y9e,v9e,x9e,b9e,T9e,w9e,k9e,E9e,S9e,C9e,A9e,dw,FL=N(()=>{"use strict";yt();h9e=o((t,e,r,n)=>{e.forEach(i=>{A9e[i](t,r,n)})},"insertMarkers"),f9e=o((t,e,r)=>{X.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),d9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),p9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),m9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),g9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),y9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),v9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),x9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),b9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","userSpaceOnUse").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),T9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneStart").attr("class","marker onlyOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneEnd").attr("class","marker onlyOne "+e).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M3,0 L3,18 M9,0 L9,18")},"only_one"),w9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneStart").attr("class","marker zeroOrOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),n.append("path").attr("d","M9,0 L9,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneEnd").attr("class","marker zeroOrOne "+e).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),i.append("path").attr("d","M21,0 L21,18")},"zero_or_one"),k9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreStart").attr("class","marker oneOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreEnd").attr("class","marker oneOrMore "+e).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18")},"one_or_more"),E9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreStart").attr("class","marker zeroOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),n.append("path").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreEnd").attr("class","marker zeroOrMore "+e).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),i.append("path").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},"zero_or_more"),S9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_arrowEnd").attr("refX",20).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("path").attr("d",`M0,0 + L20,10 + M20,10 + L0,20`)},"requirement_arrow"),C9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");n.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),n.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),n.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains"),A9e={extension:f9e,composition:d9e,aggregation:p9e,dependency:m9e,lollipop:g9e,point:y9e,circle:v9e,cross:x9e,barb:b9e,only_one:T9e,zero_or_one:w9e,one_or_more:k9e,zero_or_more:E9e,requirement_arrow:S9e,requirement_contains:C9e},dw=h9e});async function Am(t,e,r){let n,i;e.shape==="rect"&&(e.rx&&e.ry?e.shape="roundedRect":e.shape="squareRect");let a=e.shape?IL[e.shape]:void 0;if(!a)throw new Error(`No such shape: ${e.shape}. Please check your syntax.`);if(e.link){let s;r.config.securityLevel==="sandbox"?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s??null),i=await a(n,e,r)}else i=await a(t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),pw.set(e.id,n),e.haveCallback&&n.attr("class",n.attr("class")+" clickable"),n}var pw,vee,xee,M2,mw=N(()=>{"use strict";yt();OL();pw=new Map;o(Am,"insertNode");vee=o((t,e)=>{pw.set(e.id,t)},"setNodeElem"),xee=o(()=>{pw.clear()},"clear"),M2=o(t=>{let e=pw.get(t.id);X.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});var bee,Tee=N(()=>{"use strict";mi();pr();yt();aw();BL();FL();mw();Ft();er();bee={common:Ze,getConfig:tr,insertCluster:Cm,insertEdge:fw,insertEdgeLabel:uw,insertMarkers:dw,insertNode:Am,interpolateToCurve:A9,labelHelper:mt,log:X,positionEdgeLabel:hw}});function D9e(t){return typeof t=="symbol"||ii(t)&&fa(t)==_9e}var _9e,oo,Wd=N(()=>{"use strict";Au();Oo();_9e="[object Symbol]";o(D9e,"isSymbol");oo=D9e});function L9e(t,e){for(var r=-1,n=t==null?0:t.length,i=Array(n);++r{"use strict";o(L9e,"arrayMap");Bs=L9e});function Eee(t){if(typeof t=="string")return t;if(Pt(t))return Bs(t,Eee)+"";if(oo(t))return kee?kee.call(t):"";var e=t+"";return e=="0"&&1/t==-R9e?"-0":e}var R9e,wee,kee,See,Cee=N(()=>{"use strict";Md();qd();Wn();Wd();R9e=1/0,wee=ea?ea.prototype:void 0,kee=wee?wee.toString:void 0;o(Eee,"baseToString");See=Eee});function M9e(t){for(var e=t.length;e--&&N9e.test(t.charAt(e)););return e}var N9e,Aee,_ee=N(()=>{"use strict";N9e=/\s/;o(M9e,"trimmedEndIndex");Aee=M9e});function O9e(t){return t&&t.slice(0,Aee(t)+1).replace(I9e,"")}var I9e,Dee,Lee=N(()=>{"use strict";_ee();I9e=/^\s+/;o(O9e,"baseTrim");Dee=O9e});function z9e(t){if(typeof t=="number")return t;if(oo(t))return Ree;if(bn(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=bn(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=Dee(t);var r=B9e.test(t);return r||F9e.test(t)?$9e(t.slice(2),r?2:8):P9e.test(t)?Ree:+t}var Ree,P9e,B9e,F9e,$9e,Nee,Mee=N(()=>{"use strict";Lee();no();Wd();Ree=NaN,P9e=/^[-+]0x[0-9a-f]+$/i,B9e=/^0b[01]+$/i,F9e=/^0o[0-7]+$/i,$9e=parseInt;o(z9e,"toNumber");Nee=z9e});function V9e(t){if(!t)return t===0?t:0;if(t=Nee(t),t===Iee||t===-Iee){var e=t<0?-1:1;return e*G9e}return t===t?t:0}var Iee,G9e,_m,$L=N(()=>{"use strict";Mee();Iee=1/0,G9e=17976931348623157e292;o(V9e,"toFinite");_m=V9e});function U9e(t){var e=_m(t),r=e%1;return e===e?r?e-r:e:0}var kc,Dm=N(()=>{"use strict";$L();o(U9e,"toInteger");kc=U9e});var H9e,gw,Oee=N(()=>{"use strict";Ph();Mo();H9e=Ls(hi,"WeakMap"),gw=H9e});function W9e(){}var ai,zL=N(()=>{"use strict";o(W9e,"noop");ai=W9e});function q9e(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(q9e,"arrayEach");yw=q9e});function Y9e(t,e,r,n){for(var i=t.length,a=r+(n?1:-1);n?a--:++a{"use strict";o(Y9e,"baseFindIndex");vw=Y9e});function X9e(t){return t!==t}var Pee,Bee=N(()=>{"use strict";o(X9e,"baseIsNaN");Pee=X9e});function j9e(t,e,r){for(var n=r-1,i=t.length;++n{"use strict";o(j9e,"strictIndexOf");Fee=j9e});function K9e(t,e,r){return e===e?Fee(t,e,r):vw(t,Pee,r)}var Lm,xw=N(()=>{"use strict";VL();Bee();$ee();o(K9e,"baseIndexOf");Lm=K9e});function Q9e(t,e){var r=t==null?0:t.length;return!!r&&Lm(t,e,0)>-1}var bw,UL=N(()=>{"use strict";xw();o(Q9e,"arrayIncludes");bw=Q9e});var Z9e,zee,Gee=N(()=>{"use strict";p9();Z9e=mT(Object.keys,Object),zee=Z9e});function tLe(t){if(!mc(t))return zee(t);var e=[];for(var r in Object(t))eLe.call(t,r)&&r!="constructor"&&e.push(r);return e}var J9e,eLe,Rm,Tw=N(()=>{"use strict";um();Gee();J9e=Object.prototype,eLe=J9e.hasOwnProperty;o(tLe,"baseKeys");Rm=tLe});function rLe(t){return fi(t)?bT(t):Rm(t)}var zr,Ec=N(()=>{"use strict";x9();Tw();Po();o(rLe,"keys");zr=rLe});var nLe,iLe,aLe,pa,Vee=N(()=>{"use strict";pm();Fd();k9();Po();um();Ec();nLe=Object.prototype,iLe=nLe.hasOwnProperty,aLe=kT(function(t,e){if(mc(e)||fi(e)){$o(e,zr(e),t);return}for(var r in e)iLe.call(e,r)&&gc(t,r,e[r])}),pa=aLe});function lLe(t,e){if(Pt(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||oo(t)?!0:oLe.test(t)||!sLe.test(t)||e!=null&&t in Object(e)}var sLe,oLe,Nm,ww=N(()=>{"use strict";Wn();Wd();sLe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,oLe=/^\w*$/;o(lLe,"isKey");Nm=lLe});function uLe(t){var e=rm(t,function(n){return r.size===cLe&&r.clear(),n}),r=e.cache;return e}var cLe,Uee,Hee=N(()=>{"use strict";o9();cLe=500;o(uLe,"memoizeCapped");Uee=uLe});var hLe,fLe,dLe,Wee,qee=N(()=>{"use strict";Hee();hLe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,fLe=/\\(\\)?/g,dLe=Uee(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(hLe,function(r,n,i,a){e.push(i?a.replace(fLe,"$1"):n||r)}),e}),Wee=dLe});function pLe(t){return t==null?"":See(t)}var kw,HL=N(()=>{"use strict";Cee();o(pLe,"toString");kw=pLe});function mLe(t,e){return Pt(t)?t:Nm(t,e)?[t]:Wee(kw(t))}var Jh,I2=N(()=>{"use strict";Wn();ww();qee();HL();o(mLe,"castPath");Jh=mLe});function yLe(t){if(typeof t=="string"||oo(t))return t;var e=t+"";return e=="0"&&1/t==-gLe?"-0":e}var gLe,Sc,Mm=N(()=>{"use strict";Wd();gLe=1/0;o(yLe,"toKey");Sc=yLe});function vLe(t,e){e=Jh(e,t);for(var r=0,n=e.length;t!=null&&r{"use strict";I2();Mm();o(vLe,"baseGet");ef=vLe});function xLe(t,e,r){var n=t==null?void 0:ef(t,e);return n===void 0?r:n}var Yee,Xee=N(()=>{"use strict";O2();o(xLe,"get");Yee=xLe});function bLe(t,e){for(var r=-1,n=e.length,i=t.length;++r{"use strict";o(bLe,"arrayPush");Im=bLe});function TLe(t){return Pt(t)||Dl(t)||!!(jee&&t&&t[jee])}var jee,Kee,Qee=N(()=>{"use strict";Md();hm();Wn();jee=ea?ea.isConcatSpreadable:void 0;o(TLe,"isFlattenable");Kee=TLe});function Zee(t,e,r,n,i){var a=-1,s=t.length;for(r||(r=Kee),i||(i=[]);++a0&&r(l)?e>1?Zee(l,e-1,r,n,i):Im(i,l):n||(i[i.length]=l)}return i}var Cc,Om=N(()=>{"use strict";Ew();Qee();o(Zee,"baseFlatten");Cc=Zee});function wLe(t){var e=t==null?0:t.length;return e?Cc(t,1):[]}var qr,Sw=N(()=>{"use strict";Om();o(wLe,"flatten");qr=wLe});function kLe(t){return wT(TT(t,void 0,qr),t+"")}var Jee,ete=N(()=>{"use strict";Sw();b9();w9();o(kLe,"flatRest");Jee=kLe});function ELe(t,e,r){var n=-1,i=t.length;e<0&&(e=-e>i?0:i+e),r=r>i?i:r,r<0&&(r+=i),i=e>r?0:r-e>>>0,e>>>=0;for(var a=Array(i);++n{"use strict";o(ELe,"baseSlice");Cw=ELe});function MLe(t){return NLe.test(t)}var SLe,CLe,ALe,_Le,DLe,LLe,RLe,NLe,tte,rte=N(()=>{"use strict";SLe="\\ud800-\\udfff",CLe="\\u0300-\\u036f",ALe="\\ufe20-\\ufe2f",_Le="\\u20d0-\\u20ff",DLe=CLe+ALe+_Le,LLe="\\ufe0e\\ufe0f",RLe="\\u200d",NLe=RegExp("["+RLe+SLe+DLe+LLe+"]");o(MLe,"hasUnicode");tte=MLe});function ILe(t,e,r,n){var i=-1,a=t==null?0:t.length;for(n&&a&&(r=t[++i]);++i{"use strict";o(ILe,"arrayReduce");nte=ILe});function OLe(t,e){return t&&$o(e,zr(e),t)}var ate,ste=N(()=>{"use strict";Fd();Ec();o(OLe,"baseAssign");ate=OLe});function PLe(t,e){return t&&$o(e,Rs(e),t)}var ote,lte=N(()=>{"use strict";Fd();Uh();o(PLe,"baseAssignIn");ote=PLe});function BLe(t,e){for(var r=-1,n=t==null?0:t.length,i=0,a=[];++r{"use strict";o(BLe,"arrayFilter");Pm=BLe});function FLe(){return[]}var _w,qL=N(()=>{"use strict";o(FLe,"stubArray");_w=FLe});var $Le,zLe,cte,GLe,Bm,Dw=N(()=>{"use strict";Aw();qL();$Le=Object.prototype,zLe=$Le.propertyIsEnumerable,cte=Object.getOwnPropertySymbols,GLe=cte?function(t){return t==null?[]:(t=Object(t),Pm(cte(t),function(e){return zLe.call(t,e)}))}:_w,Bm=GLe});function VLe(t,e){return $o(t,Bm(t),e)}var ute,hte=N(()=>{"use strict";Fd();Dw();o(VLe,"copySymbols");ute=VLe});var ULe,HLe,Lw,YL=N(()=>{"use strict";Ew();gT();Dw();qL();ULe=Object.getOwnPropertySymbols,HLe=ULe?function(t){for(var e=[];t;)Im(e,Bm(t)),t=cm(t);return e}:_w,Lw=HLe});function WLe(t,e){return $o(t,Lw(t),e)}var fte,dte=N(()=>{"use strict";Fd();YL();o(WLe,"copySymbolsIn");fte=WLe});function qLe(t,e,r){var n=e(t);return Pt(t)?n:Im(n,r(t))}var Rw,XL=N(()=>{"use strict";Ew();Wn();o(qLe,"baseGetAllKeys");Rw=qLe});function YLe(t){return Rw(t,zr,Bm)}var P2,jL=N(()=>{"use strict";XL();Dw();Ec();o(YLe,"getAllKeys");P2=YLe});function XLe(t){return Rw(t,Rs,Lw)}var Nw,KL=N(()=>{"use strict";XL();YL();Uh();o(XLe,"getAllKeysIn");Nw=XLe});var jLe,Mw,pte=N(()=>{"use strict";Ph();Mo();jLe=Ls(hi,"DataView"),Mw=jLe});var KLe,Iw,mte=N(()=>{"use strict";Ph();Mo();KLe=Ls(hi,"Promise"),Iw=KLe});var QLe,tf,QL=N(()=>{"use strict";Ph();Mo();QLe=Ls(hi,"Set"),tf=QLe});var gte,ZLe,yte,vte,xte,bte,JLe,eRe,tRe,rRe,nRe,Yd,lo,Xd=N(()=>{"use strict";pte();lT();mte();QL();Oee();Au();i9();gte="[object Map]",ZLe="[object Object]",yte="[object Promise]",vte="[object Set]",xte="[object WeakMap]",bte="[object DataView]",JLe=_u(Mw),eRe=_u($h),tRe=_u(Iw),rRe=_u(tf),nRe=_u(gw),Yd=fa;(Mw&&Yd(new Mw(new ArrayBuffer(1)))!=bte||$h&&Yd(new $h)!=gte||Iw&&Yd(Iw.resolve())!=yte||tf&&Yd(new tf)!=vte||gw&&Yd(new gw)!=xte)&&(Yd=o(function(t){var e=fa(t),r=e==ZLe?t.constructor:void 0,n=r?_u(r):"";if(n)switch(n){case JLe:return bte;case eRe:return gte;case tRe:return yte;case rRe:return vte;case nRe:return xte}return e},"getTag"));lo=Yd});function sRe(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&aRe.call(t,"index")&&(r.index=t.index,r.input=t.input),r}var iRe,aRe,Tte,wte=N(()=>{"use strict";iRe=Object.prototype,aRe=iRe.hasOwnProperty;o(sRe,"initCloneArray");Tte=sRe});function oRe(t,e){var r=e?lm(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}var kte,Ete=N(()=>{"use strict";fT();o(oRe,"cloneDataView");kte=oRe});function cRe(t){var e=new t.constructor(t.source,lRe.exec(t));return e.lastIndex=t.lastIndex,e}var lRe,Ste,Cte=N(()=>{"use strict";lRe=/\w*$/;o(cRe,"cloneRegExp");Ste=cRe});function uRe(t){return _te?Object(_te.call(t)):{}}var Ate,_te,Dte,Lte=N(()=>{"use strict";Md();Ate=ea?ea.prototype:void 0,_te=Ate?Ate.valueOf:void 0;o(uRe,"cloneSymbol");Dte=uRe});function LRe(t,e,r){var n=t.constructor;switch(e){case xRe:return lm(t);case hRe:case fRe:return new n(+t);case bRe:return kte(t,r);case TRe:case wRe:case kRe:case ERe:case SRe:case CRe:case ARe:case _Re:case DRe:return dT(t,r);case dRe:return new n;case pRe:case yRe:return new n(t);case mRe:return Ste(t);case gRe:return new n;case vRe:return Dte(t)}}var hRe,fRe,dRe,pRe,mRe,gRe,yRe,vRe,xRe,bRe,TRe,wRe,kRe,ERe,SRe,CRe,ARe,_Re,DRe,Rte,Nte=N(()=>{"use strict";fT();Ete();Cte();Lte();f9();hRe="[object Boolean]",fRe="[object Date]",dRe="[object Map]",pRe="[object Number]",mRe="[object RegExp]",gRe="[object Set]",yRe="[object String]",vRe="[object Symbol]",xRe="[object ArrayBuffer]",bRe="[object DataView]",TRe="[object Float32Array]",wRe="[object Float64Array]",kRe="[object Int8Array]",ERe="[object Int16Array]",SRe="[object Int32Array]",CRe="[object Uint8Array]",ARe="[object Uint8ClampedArray]",_Re="[object Uint16Array]",DRe="[object Uint32Array]";o(LRe,"initCloneByTag");Rte=LRe});function NRe(t){return ii(t)&&lo(t)==RRe}var RRe,Mte,Ite=N(()=>{"use strict";Xd();Oo();RRe="[object Map]";o(NRe,"baseIsMap");Mte=NRe});var Ote,MRe,Pte,Bte=N(()=>{"use strict";Ite();Bd();h2();Ote=Fo&&Fo.isMap,MRe=Ote?Bo(Ote):Mte,Pte=MRe});function ORe(t){return ii(t)&&lo(t)==IRe}var IRe,Fte,$te=N(()=>{"use strict";Xd();Oo();IRe="[object Set]";o(ORe,"baseIsSet");Fte=ORe});var zte,PRe,Gte,Vte=N(()=>{"use strict";$te();Bd();h2();zte=Fo&&Fo.isSet,PRe=zte?Bo(zte):Fte,Gte=PRe});function Ow(t,e,r,n,i,a){var s,l=e&BRe,u=e&FRe,h=e&$Re;if(r&&(s=i?r(t,n,i,a):r(t)),s!==void 0)return s;if(!bn(t))return t;var f=Pt(t);if(f){if(s=Tte(t),!l)return pT(t,s)}else{var d=lo(t),p=d==Hte||d==HRe;if(Ll(t))return hT(t,l);if(d==Wte||d==Ute||p&&!i){if(s=u||p?{}:yT(t),!l)return u?fte(t,ote(s,t)):ute(t,ate(s,t))}else{if(!_n[d])return i?t:{};s=Rte(t,d,l)}}a||(a=new dc);var m=a.get(t);if(m)return m;a.set(t,s),Gte(t)?t.forEach(function(v){s.add(Ow(v,e,r,v,t,a))}):Pte(t)&&t.forEach(function(v,x){s.set(x,Ow(v,e,r,x,t,a))});var g=h?u?Nw:P2:u?Rs:zr,y=f?void 0:g(t);return yw(y||t,function(v,x){y&&(x=v,v=t[x]),gc(s,x,Ow(v,e,r,x,t,a))}),s}var BRe,FRe,$Re,Ute,zRe,GRe,VRe,URe,Hte,HRe,WRe,qRe,Wte,YRe,XRe,jRe,KRe,QRe,ZRe,JRe,eNe,tNe,rNe,nNe,iNe,aNe,sNe,oNe,lNe,_n,Pw,ZL=N(()=>{"use strict";l2();GL();pm();ste();lte();u9();d9();hte();dte();jL();KL();Xd();wte();Nte();m9();Wn();dm();Bte();no();Vte();Ec();Uh();BRe=1,FRe=2,$Re=4,Ute="[object Arguments]",zRe="[object Array]",GRe="[object Boolean]",VRe="[object Date]",URe="[object Error]",Hte="[object Function]",HRe="[object GeneratorFunction]",WRe="[object Map]",qRe="[object Number]",Wte="[object Object]",YRe="[object RegExp]",XRe="[object Set]",jRe="[object String]",KRe="[object Symbol]",QRe="[object WeakMap]",ZRe="[object ArrayBuffer]",JRe="[object DataView]",eNe="[object Float32Array]",tNe="[object Float64Array]",rNe="[object Int8Array]",nNe="[object Int16Array]",iNe="[object Int32Array]",aNe="[object Uint8Array]",sNe="[object Uint8ClampedArray]",oNe="[object Uint16Array]",lNe="[object Uint32Array]",_n={};_n[Ute]=_n[zRe]=_n[ZRe]=_n[JRe]=_n[GRe]=_n[VRe]=_n[eNe]=_n[tNe]=_n[rNe]=_n[nNe]=_n[iNe]=_n[WRe]=_n[qRe]=_n[Wte]=_n[YRe]=_n[XRe]=_n[jRe]=_n[KRe]=_n[aNe]=_n[sNe]=_n[oNe]=_n[lNe]=!0;_n[URe]=_n[Hte]=_n[QRe]=!1;o(Ow,"baseClone");Pw=Ow});function uNe(t){return Pw(t,cNe)}var cNe,an,JL=N(()=>{"use strict";ZL();cNe=4;o(uNe,"clone");an=uNe});function dNe(t){return Pw(t,hNe|fNe)}var hNe,fNe,eR,qte=N(()=>{"use strict";ZL();hNe=1,fNe=4;o(dNe,"cloneDeep");eR=dNe});function pNe(t){for(var e=-1,r=t==null?0:t.length,n=0,i=[];++e{"use strict";o(pNe,"compact");Ac=pNe});function gNe(t){return this.__data__.set(t,mNe),this}var mNe,Xte,jte=N(()=>{"use strict";mNe="__lodash_hash_undefined__";o(gNe,"setCacheAdd");Xte=gNe});function yNe(t){return this.__data__.has(t)}var Kte,Qte=N(()=>{"use strict";o(yNe,"setCacheHas");Kte=yNe});function Bw(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new Od;++e{"use strict";cT();jte();Qte();o(Bw,"SetCache");Bw.prototype.add=Bw.prototype.push=Xte;Bw.prototype.has=Kte;Fm=Bw});function vNe(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(vNe,"arraySome");$w=vNe});function xNe(t,e){return t.has(e)}var $m,zw=N(()=>{"use strict";o(xNe,"cacheHas");$m=xNe});function wNe(t,e,r,n,i,a){var s=r&bNe,l=t.length,u=e.length;if(l!=u&&!(s&&u>l))return!1;var h=a.get(t),f=a.get(e);if(h&&f)return h==e&&f==t;var d=-1,p=!0,m=r&TNe?new Fm:void 0;for(a.set(t,e),a.set(e,t);++d{"use strict";Fw();tR();zw();bNe=1,TNe=2;o(wNe,"equalArrays");Gw=wNe});function kNe(t){var e=-1,r=Array(t.size);return t.forEach(function(n,i){r[++e]=[i,n]}),r}var Zte,Jte=N(()=>{"use strict";o(kNe,"mapToArray");Zte=kNe});function ENe(t){var e=-1,r=Array(t.size);return t.forEach(function(n){r[++e]=n}),r}var zm,Vw=N(()=>{"use strict";o(ENe,"setToArray");zm=ENe});function FNe(t,e,r,n,i,a,s){switch(r){case BNe:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case PNe:return!(t.byteLength!=e.byteLength||!a(new om(t),new om(e)));case ANe:case _Ne:case RNe:return Io(+t,+e);case DNe:return t.name==e.name&&t.message==e.message;case NNe:case INe:return t==e+"";case LNe:var l=Zte;case MNe:var u=n&SNe;if(l||(l=zm),t.size!=e.size&&!u)return!1;var h=s.get(t);if(h)return h==e;n|=CNe,s.set(t,e);var f=Gw(l(t),l(e),n,i,a,s);return s.delete(t),f;case ONe:if(nR)return nR.call(t)==nR.call(e)}return!1}var SNe,CNe,ANe,_Ne,DNe,LNe,RNe,NNe,MNe,INe,ONe,PNe,BNe,ere,nR,tre,rre=N(()=>{"use strict";Md();h9();Id();rR();Jte();Vw();SNe=1,CNe=2,ANe="[object Boolean]",_Ne="[object Date]",DNe="[object Error]",LNe="[object Map]",RNe="[object Number]",NNe="[object RegExp]",MNe="[object Set]",INe="[object String]",ONe="[object Symbol]",PNe="[object ArrayBuffer]",BNe="[object DataView]",ere=ea?ea.prototype:void 0,nR=ere?ere.valueOf:void 0;o(FNe,"equalByTag");tre=FNe});function VNe(t,e,r,n,i,a){var s=r&$Ne,l=P2(t),u=l.length,h=P2(e),f=h.length;if(u!=f&&!s)return!1;for(var d=u;d--;){var p=l[d];if(!(s?p in e:GNe.call(e,p)))return!1}var m=a.get(t),g=a.get(e);if(m&&g)return m==e&&g==t;var y=!0;a.set(t,e),a.set(e,t);for(var v=s;++d{"use strict";jL();$Ne=1,zNe=Object.prototype,GNe=zNe.hasOwnProperty;o(VNe,"equalObjects");nre=VNe});function WNe(t,e,r,n,i,a){var s=Pt(t),l=Pt(e),u=s?sre:lo(t),h=l?sre:lo(e);u=u==are?Uw:u,h=h==are?Uw:h;var f=u==Uw,d=h==Uw,p=u==h;if(p&&Ll(t)){if(!Ll(e))return!1;s=!0,f=!1}if(p&&!f)return a||(a=new dc),s||Gh(t)?Gw(t,e,r,n,i,a):tre(t,e,u,r,n,i,a);if(!(r&UNe)){var m=f&&ore.call(t,"__wrapped__"),g=d&&ore.call(e,"__wrapped__");if(m||g){var y=m?t.value():t,v=g?e.value():e;return a||(a=new dc),i(y,v,r,n,a)}}return p?(a||(a=new dc),nre(t,e,r,n,i,a)):!1}var UNe,are,sre,Uw,HNe,ore,lre,cre=N(()=>{"use strict";l2();rR();rre();ire();Xd();Wn();dm();f2();UNe=1,are="[object Arguments]",sre="[object Array]",Uw="[object Object]",HNe=Object.prototype,ore=HNe.hasOwnProperty;o(WNe,"baseIsEqualDeep");lre=WNe});function ure(t,e,r,n,i){return t===e?!0:t==null||e==null||!ii(t)&&!ii(e)?t!==t&&e!==e:lre(t,e,r,n,ure,i)}var Hw,iR=N(()=>{"use strict";cre();Oo();o(ure,"baseIsEqual");Hw=ure});function XNe(t,e,r,n){var i=r.length,a=i,s=!n;if(t==null)return!a;for(t=Object(t);i--;){var l=r[i];if(s&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++i{"use strict";l2();iR();qNe=1,YNe=2;o(XNe,"baseIsMatch");hre=XNe});function jNe(t){return t===t&&!bn(t)}var Ww,aR=N(()=>{"use strict";no();o(jNe,"isStrictComparable");Ww=jNe});function KNe(t){for(var e=zr(t),r=e.length;r--;){var n=e[r],i=t[n];e[r]=[n,i,Ww(i)]}return e}var dre,pre=N(()=>{"use strict";aR();Ec();o(KNe,"getMatchData");dre=KNe});function QNe(t,e){return function(r){return r==null?!1:r[t]===e&&(e!==void 0||t in Object(r))}}var qw,sR=N(()=>{"use strict";o(QNe,"matchesStrictComparable");qw=QNe});function ZNe(t){var e=dre(t);return e.length==1&&e[0][2]?qw(e[0][0],e[0][1]):function(r){return r===t||hre(r,t,e)}}var mre,gre=N(()=>{"use strict";fre();pre();sR();o(ZNe,"baseMatches");mre=ZNe});function JNe(t,e){return t!=null&&e in Object(t)}var yre,vre=N(()=>{"use strict";o(JNe,"baseHasIn");yre=JNe});function eMe(t,e,r){e=Jh(e,t);for(var n=-1,i=e.length,a=!1;++n{"use strict";I2();hm();Wn();p2();vT();Mm();o(eMe,"hasPath");Yw=eMe});function tMe(t,e){return t!=null&&Yw(t,e,yre)}var Xw,lR=N(()=>{"use strict";vre();oR();o(tMe,"hasIn");Xw=tMe});function iMe(t,e){return Nm(t)&&Ww(e)?qw(Sc(t),e):function(r){var n=Yee(r,t);return n===void 0&&n===e?Xw(r,t):Hw(e,n,rMe|nMe)}}var rMe,nMe,xre,bre=N(()=>{"use strict";iR();Xee();lR();ww();aR();sR();Mm();rMe=1,nMe=2;o(iMe,"baseMatchesProperty");xre=iMe});function aMe(t){return function(e){return e?.[t]}}var jw,cR=N(()=>{"use strict";o(aMe,"baseProperty");jw=aMe});function sMe(t){return function(e){return ef(e,t)}}var Tre,wre=N(()=>{"use strict";O2();o(sMe,"basePropertyDeep");Tre=sMe});function oMe(t){return Nm(t)?jw(Sc(t)):Tre(t)}var kre,Ere=N(()=>{"use strict";cR();wre();ww();Mm();o(oMe,"property");kre=oMe});function lMe(t){return typeof t=="function"?t:t==null?ta:typeof t=="object"?Pt(t)?xre(t[0],t[1]):mre(t):kre(t)}var mn,os=N(()=>{"use strict";gre();bre();Lu();Wn();Ere();o(lMe,"baseIteratee");mn=lMe});function cMe(t,e,r,n){for(var i=-1,a=t==null?0:t.length;++i{"use strict";o(cMe,"arrayAggregator");Sre=cMe});function uMe(t,e){return t&&sm(t,e,zr)}var Gm,Kw=N(()=>{"use strict";uT();Ec();o(uMe,"baseForOwn");Gm=uMe});function hMe(t,e){return function(r,n){if(r==null)return r;if(!fi(r))return t(r,n);for(var i=r.length,a=e?i:-1,s=Object(r);(e?a--:++a{"use strict";Po();o(hMe,"createBaseEach");Are=hMe});var fMe,Fs,rf=N(()=>{"use strict";Kw();_re();fMe=Are(Gm),Fs=fMe});function dMe(t,e,r,n){return Fs(t,function(i,a,s){e(n,i,r(i),s)}),n}var Dre,Lre=N(()=>{"use strict";rf();o(dMe,"baseAggregator");Dre=dMe});function pMe(t,e){return function(r,n){var i=Pt(r)?Sre:Dre,a=e?e():{};return i(r,t,mn(n,2),a)}}var Rre,Nre=N(()=>{"use strict";Cre();Lre();os();Wn();o(pMe,"createAggregator");Rre=pMe});var mMe,Qw,Mre=N(()=>{"use strict";Mo();mMe=o(function(){return hi.Date.now()},"now"),Qw=mMe});var Ire,gMe,yMe,nf,Ore=N(()=>{"use strict";mm();Id();$d();Uh();Ire=Object.prototype,gMe=Ire.hasOwnProperty,yMe=yc(function(t,e){t=Object(t);var r=-1,n=e.length,i=n>2?e[2]:void 0;for(i&&io(e[0],e[1],i)&&(n=1);++r{"use strict";o(vMe,"arrayIncludesWith");Zw=vMe});function bMe(t,e,r,n){var i=-1,a=bw,s=!0,l=t.length,u=[],h=e.length;if(!l)return u;r&&(e=Bs(e,Bo(r))),n?(a=Zw,s=!1):e.length>=xMe&&(a=$m,s=!1,e=new Fm(e));e:for(;++i{"use strict";Fw();UL();uR();qd();Bd();zw();xMe=200;o(bMe,"baseDifference");Pre=bMe});var TMe,af,Fre=N(()=>{"use strict";Bre();Om();mm();xT();TMe=yc(function(t,e){return Pd(t)?Pre(t,Cc(e,1,Pd,!0)):[]}),af=TMe});function wMe(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}var ma,$re=N(()=>{"use strict";o(wMe,"last");ma=wMe});function kMe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:kc(e),Cw(t,e<0?0:e,n)):[]}var bi,zre=N(()=>{"use strict";WL();Dm();o(kMe,"drop");bi=kMe});function EMe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:kc(e),e=n-e,Cw(t,0,e<0?0:e)):[]}var Fu,Gre=N(()=>{"use strict";WL();Dm();o(EMe,"dropRight");Fu=EMe});function SMe(t){return typeof t=="function"?t:ta}var Vm,Jw=N(()=>{"use strict";Lu();o(SMe,"castFunction");Vm=SMe});function CMe(t,e){var r=Pt(t)?yw:Fs;return r(t,Vm(e))}var Ae,ek=N(()=>{"use strict";GL();rf();Jw();Wn();o(CMe,"forEach");Ae=CMe});var Vre=N(()=>{"use strict";ek()});function AMe(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(AMe,"arrayEvery");Ure=AMe});function _Me(t,e){var r=!0;return Fs(t,function(n,i,a){return r=!!e(n,i,a),r}),r}var Wre,qre=N(()=>{"use strict";rf();o(_Me,"baseEvery");Wre=_Me});function DMe(t,e,r){var n=Pt(t)?Ure:Wre;return r&&io(t,e,r)&&(e=void 0),n(t,mn(e,3))}var Pa,Yre=N(()=>{"use strict";Hre();qre();os();Wn();$d();o(DMe,"every");Pa=DMe});function LMe(t,e){var r=[];return Fs(t,function(n,i,a){e(n,i,a)&&r.push(n)}),r}var tk,hR=N(()=>{"use strict";rf();o(LMe,"baseFilter");tk=LMe});function RMe(t,e){var r=Pt(t)?Pm:tk;return r(t,mn(e,3))}var Yr,fR=N(()=>{"use strict";Aw();hR();os();Wn();o(RMe,"filter");Yr=RMe});function NMe(t){return function(e,r,n){var i=Object(e);if(!fi(e)){var a=mn(r,3);e=zr(e),r=o(function(l){return a(i[l],l,i)},"predicate")}var s=t(e,r,n);return s>-1?i[a?e[s]:s]:void 0}}var Xre,jre=N(()=>{"use strict";os();Po();Ec();o(NMe,"createFind");Xre=NMe});function IMe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:kc(r);return i<0&&(i=MMe(n+i,0)),vw(t,mn(e,3),i)}var MMe,Kre,Qre=N(()=>{"use strict";VL();os();Dm();MMe=Math.max;o(IMe,"findIndex");Kre=IMe});var OMe,ls,Zre=N(()=>{"use strict";jre();Qre();OMe=Xre(Kre),ls=OMe});function PMe(t){return t&&t.length?t[0]:void 0}var ia,Jre=N(()=>{"use strict";o(PMe,"head");ia=PMe});var ene=N(()=>{"use strict";Jre()});function BMe(t,e){var r=-1,n=fi(t)?Array(t.length):[];return Fs(t,function(i,a,s){n[++r]=e(i,a,s)}),n}var rk,dR=N(()=>{"use strict";rf();Po();o(BMe,"baseMap");rk=BMe});function FMe(t,e){var r=Pt(t)?Bs:rk;return r(t,mn(e,3))}var Je,Um=N(()=>{"use strict";qd();os();dR();Wn();o(FMe,"map");Je=FMe});function $Me(t,e){return Cc(Je(t,e),1)}var ga,pR=N(()=>{"use strict";Om();Um();o($Me,"flatMap");ga=$Me});function zMe(t,e){return t==null?t:sm(t,Vm(e),Rs)}var mR,tne=N(()=>{"use strict";uT();Jw();Uh();o(zMe,"forIn");mR=zMe});function GMe(t,e){return t&&Gm(t,Vm(e))}var gR,rne=N(()=>{"use strict";Kw();Jw();o(GMe,"forOwn");gR=GMe});var VMe,UMe,HMe,yR,nne=N(()=>{"use strict";am();Nre();VMe=Object.prototype,UMe=VMe.hasOwnProperty,HMe=Rre(function(t,e,r){UMe.call(t,r)?t[r].push(e):pc(t,r,[e])}),yR=HMe});function WMe(t,e){return t>e}var ine,ane=N(()=>{"use strict";o(WMe,"baseGt");ine=WMe});function XMe(t,e){return t!=null&&YMe.call(t,e)}var qMe,YMe,sne,one=N(()=>{"use strict";qMe=Object.prototype,YMe=qMe.hasOwnProperty;o(XMe,"baseHas");sne=XMe});function jMe(t,e){return t!=null&&Yw(t,e,sne)}var Bt,lne=N(()=>{"use strict";one();oR();o(jMe,"has");Bt=jMe});function QMe(t){return typeof t=="string"||!Pt(t)&&ii(t)&&fa(t)==KMe}var KMe,Ti,nk=N(()=>{"use strict";Au();Wn();Oo();KMe="[object String]";o(QMe,"isString");Ti=QMe});function ZMe(t,e){return Bs(e,function(r){return t[r]})}var cne,une=N(()=>{"use strict";qd();o(ZMe,"baseValues");cne=ZMe});function JMe(t){return t==null?[]:cne(t,zr(t))}var br,vR=N(()=>{"use strict";une();Ec();o(JMe,"values");br=JMe});function tIe(t,e,r,n){t=fi(t)?t:br(t),r=r&&!n?kc(r):0;var i=t.length;return r<0&&(r=eIe(i+r,0)),Ti(t)?r<=i&&t.indexOf(e,r)>-1:!!i&&Lm(t,e,r)>-1}var eIe,Xn,hne=N(()=>{"use strict";xw();Po();nk();Dm();vR();eIe=Math.max;o(tIe,"includes");Xn=tIe});function nIe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:kc(r);return i<0&&(i=rIe(n+i,0)),Lm(t,e,i)}var rIe,ik,fne=N(()=>{"use strict";xw();Dm();rIe=Math.max;o(nIe,"indexOf");ik=nIe});function lIe(t){if(t==null)return!0;if(fi(t)&&(Pt(t)||typeof t=="string"||typeof t.splice=="function"||Ll(t)||Gh(t)||Dl(t)))return!t.length;var e=lo(t);if(e==iIe||e==aIe)return!t.size;if(mc(t))return!Rm(t).length;for(var r in t)if(oIe.call(t,r))return!1;return!0}var iIe,aIe,sIe,oIe,hr,ak=N(()=>{"use strict";Tw();Xd();hm();Wn();Po();dm();um();f2();iIe="[object Map]",aIe="[object Set]",sIe=Object.prototype,oIe=sIe.hasOwnProperty;o(lIe,"isEmpty");hr=lIe});function uIe(t){return ii(t)&&fa(t)==cIe}var cIe,dne,pne=N(()=>{"use strict";Au();Oo();cIe="[object RegExp]";o(uIe,"baseIsRegExp");dne=uIe});var mne,hIe,Uo,gne=N(()=>{"use strict";pne();Bd();h2();mne=Fo&&Fo.isRegExp,hIe=mne?Bo(mne):dne,Uo=hIe});function fIe(t){return t===void 0}var mr,yne=N(()=>{"use strict";o(fIe,"isUndefined");mr=fIe});function dIe(t,e){return t{"use strict";o(dIe,"baseLt");sk=dIe});function pIe(t,e){var r={};return e=mn(e,3),Gm(t,function(n,i,a){pc(r,i,e(n,i,a))}),r}var jd,vne=N(()=>{"use strict";am();Kw();os();o(pIe,"mapValues");jd=pIe});function mIe(t,e,r){for(var n=-1,i=t.length;++n{"use strict";Wd();o(mIe,"baseExtremum");Hm=mIe});function gIe(t){return t&&t.length?Hm(t,ta,ine):void 0}var $s,xne=N(()=>{"use strict";ok();ane();Lu();o(gIe,"max");$s=gIe});function yIe(t){return t&&t.length?Hm(t,ta,sk):void 0}var Nl,bR=N(()=>{"use strict";ok();xR();Lu();o(yIe,"min");Nl=yIe});function vIe(t,e){return t&&t.length?Hm(t,mn(e,2),sk):void 0}var Kd,bne=N(()=>{"use strict";ok();os();xR();o(vIe,"minBy");Kd=vIe});function bIe(t){if(typeof t!="function")throw new TypeError(xIe);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}var xIe,Tne,wne=N(()=>{"use strict";xIe="Expected a function";o(bIe,"negate");Tne=bIe});function TIe(t,e,r,n){if(!bn(t))return t;e=Jh(e,t);for(var i=-1,a=e.length,s=a-1,l=t;l!=null&&++i{"use strict";pm();I2();p2();no();Mm();o(TIe,"baseSet");kne=TIe});function wIe(t,e,r){for(var n=-1,i=e.length,a={};++n{"use strict";O2();Ene();I2();o(wIe,"basePickBy");lk=wIe});function kIe(t,e){if(t==null)return{};var r=Bs(Nw(t),function(n){return[n]});return e=mn(e),lk(t,r,function(n,i){return e(n,i[0])})}var zs,Sne=N(()=>{"use strict";qd();os();TR();KL();o(kIe,"pickBy");zs=kIe});function EIe(t,e){var r=t.length;for(t.sort(e);r--;)t[r]=t[r].value;return t}var Cne,Ane=N(()=>{"use strict";o(EIe,"baseSortBy");Cne=EIe});function SIe(t,e){if(t!==e){var r=t!==void 0,n=t===null,i=t===t,a=oo(t),s=e!==void 0,l=e===null,u=e===e,h=oo(e);if(!l&&!h&&!a&&t>e||a&&s&&u&&!l&&!h||n&&s&&u||!r&&u||!i)return 1;if(!n&&!a&&!h&&t{"use strict";Wd();o(SIe,"compareAscending");_ne=SIe});function CIe(t,e,r){for(var n=-1,i=t.criteria,a=e.criteria,s=i.length,l=r.length;++n=l)return u;var h=r[n];return u*(h=="desc"?-1:1)}}return t.index-e.index}var Lne,Rne=N(()=>{"use strict";Dne();o(CIe,"compareMultiple");Lne=CIe});function AIe(t,e,r){e.length?e=Bs(e,function(a){return Pt(a)?function(s){return ef(s,a.length===1?a[0]:a)}:a}):e=[ta];var n=-1;e=Bs(e,Bo(mn));var i=rk(t,function(a,s,l){var u=Bs(e,function(h){return h(a)});return{criteria:u,index:++n,value:a}});return Cne(i,function(a,s){return Lne(a,s,r)})}var Nne,Mne=N(()=>{"use strict";qd();O2();os();dR();Ane();Bd();Rne();Lu();Wn();o(AIe,"baseOrderBy");Nne=AIe});var _Ie,Ine,One=N(()=>{"use strict";cR();_Ie=jw("length"),Ine=_Ie});function zIe(t){for(var e=Pne.lastIndex=0;Pne.test(t);)++e;return e}var Bne,DIe,LIe,RIe,NIe,MIe,IIe,wR,kR,OIe,Fne,$ne,zne,PIe,Gne,Vne,BIe,FIe,$Ie,Pne,Une,Hne=N(()=>{"use strict";Bne="\\ud800-\\udfff",DIe="\\u0300-\\u036f",LIe="\\ufe20-\\ufe2f",RIe="\\u20d0-\\u20ff",NIe=DIe+LIe+RIe,MIe="\\ufe0e\\ufe0f",IIe="["+Bne+"]",wR="["+NIe+"]",kR="\\ud83c[\\udffb-\\udfff]",OIe="(?:"+wR+"|"+kR+")",Fne="[^"+Bne+"]",$ne="(?:\\ud83c[\\udde6-\\uddff]){2}",zne="[\\ud800-\\udbff][\\udc00-\\udfff]",PIe="\\u200d",Gne=OIe+"?",Vne="["+MIe+"]?",BIe="(?:"+PIe+"(?:"+[Fne,$ne,zne].join("|")+")"+Vne+Gne+")*",FIe=Vne+Gne+BIe,$Ie="(?:"+[Fne+wR+"?",wR,$ne,zne,IIe].join("|")+")",Pne=RegExp(kR+"(?="+kR+")|"+$Ie+FIe,"g");o(zIe,"unicodeSize");Une=zIe});function GIe(t){return tte(t)?Une(t):Ine(t)}var Wne,qne=N(()=>{"use strict";One();rte();Hne();o(GIe,"stringSize");Wne=GIe});function VIe(t,e){return lk(t,e,function(r,n){return Xw(t,n)})}var Yne,Xne=N(()=>{"use strict";TR();lR();o(VIe,"basePick");Yne=VIe});var UIe,Qd,jne=N(()=>{"use strict";Xne();ete();UIe=Jee(function(t,e){return t==null?{}:Yne(t,e)}),Qd=UIe});function qIe(t,e,r,n){for(var i=-1,a=WIe(HIe((e-t)/(r||1)),0),s=Array(a);a--;)s[n?a:++i]=t,t+=r;return s}var HIe,WIe,Kne,Qne=N(()=>{"use strict";HIe=Math.ceil,WIe=Math.max;o(qIe,"baseRange");Kne=qIe});function YIe(t){return function(e,r,n){return n&&typeof n!="number"&&io(e,r,n)&&(r=n=void 0),e=_m(e),r===void 0?(r=e,e=0):r=_m(r),n=n===void 0?e{"use strict";Qne();$d();$L();o(YIe,"createRange");Zne=YIe});var XIe,Ho,eie=N(()=>{"use strict";Jne();XIe=Zne(),Ho=XIe});function jIe(t,e,r,n,i){return i(t,function(a,s,l){r=n?(n=!1,a):e(r,a,s,l)}),r}var tie,rie=N(()=>{"use strict";o(jIe,"baseReduce");tie=jIe});function KIe(t,e,r){var n=Pt(t)?nte:tie,i=arguments.length<3;return n(t,mn(e,4),r,i,Fs)}var Xr,ER=N(()=>{"use strict";ite();rf();os();rie();Wn();o(KIe,"reduce");Xr=KIe});function QIe(t,e){var r=Pt(t)?Pm:tk;return r(t,Tne(mn(e,3)))}var sf,nie=N(()=>{"use strict";Aw();hR();os();Wn();wne();o(QIe,"reject");sf=QIe});function eOe(t){if(t==null)return 0;if(fi(t))return Ti(t)?Wne(t):t.length;var e=lo(t);return e==ZIe||e==JIe?t.size:Rm(t).length}var ZIe,JIe,SR,iie=N(()=>{"use strict";Tw();Xd();Po();nk();qne();ZIe="[object Map]",JIe="[object Set]";o(eOe,"size");SR=eOe});function tOe(t,e){var r;return Fs(t,function(n,i,a){return r=e(n,i,a),!r}),!!r}var aie,sie=N(()=>{"use strict";rf();o(tOe,"baseSome");aie=tOe});function rOe(t,e,r){var n=Pt(t)?$w:aie;return r&&io(t,e,r)&&(e=void 0),n(t,mn(e,3))}var B2,oie=N(()=>{"use strict";tR();os();sie();Wn();$d();o(rOe,"some");B2=rOe});var nOe,_c,lie=N(()=>{"use strict";Om();Mne();mm();$d();nOe=yc(function(t,e){if(t==null)return[];var r=e.length;return r>1&&io(t,e[0],e[1])?e=[]:r>2&&io(e[0],e[1],e[2])&&(e=[e[0]]),Nne(t,Cc(e,1),[])}),_c=nOe});var iOe,aOe,cie,uie=N(()=>{"use strict";QL();zL();Vw();iOe=1/0,aOe=tf&&1/zm(new tf([,-0]))[1]==iOe?function(t){return new tf(t)}:ai,cie=aOe});function oOe(t,e,r){var n=-1,i=bw,a=t.length,s=!0,l=[],u=l;if(r)s=!1,i=Zw;else if(a>=sOe){var h=e?null:cie(t);if(h)return zm(h);s=!1,i=$m,u=new Fm}else u=e?[]:l;e:for(;++n{"use strict";Fw();UL();uR();zw();uie();Vw();sOe=200;o(oOe,"baseUniq");Wm=oOe});var lOe,CR,hie=N(()=>{"use strict";Om();mm();ck();xT();lOe=yc(function(t){return Wm(Cc(t,1,Pd,!0))}),CR=lOe});function cOe(t){return t&&t.length?Wm(t):[]}var qm,fie=N(()=>{"use strict";ck();o(cOe,"uniq");qm=cOe});function uOe(t,e){return t&&t.length?Wm(t,mn(e,2)):[]}var die,pie=N(()=>{"use strict";os();ck();o(uOe,"uniqBy");die=uOe});function fOe(t){var e=++hOe;return kw(t)+e}var hOe,Zd,mie=N(()=>{"use strict";HL();hOe=0;o(fOe,"uniqueId");Zd=fOe});function dOe(t,e,r){for(var n=-1,i=t.length,a=e.length,s={};++n{"use strict";o(dOe,"baseZipObject");gie=dOe});function pOe(t,e){return gie(t||[],e||[],gc)}var uk,vie=N(()=>{"use strict";pm();yie();o(pOe,"zipObject");uk=pOe});var qt=N(()=>{"use strict";Vee();JL();qte();Yte();T9();Ore();Fre();zre();Gre();Vre();Yre();fR();Zre();ene();pR();Sw();ek();tne();rne();nne();lne();Lu();hne();fne();Wn();ak();n2();no();gne();nk();yne();Ec();$re();Um();vne();xne();E9();bR();bne();zL();Mre();jne();Sne();eie();ER();nie();iie();oie();lie();hie();fie();mie();vR();vie();});function bie(t,e){t[e]?t[e]++:t[e]=1}function Tie(t,e){--t[e]||delete t[e]}function F2(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}return i+xie+a+xie+(mr(n)?mOe:n)}function gOe(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}var l={v:i,w:a};return n&&(l.name=n),l}function AR(t,e){return F2(t,e.v,e.w,e.name)}var mOe,Jd,xie,sn,hk=N(()=>{"use strict";qt();mOe="\0",Jd="\0",xie="",sn=class{static{o(this,"Graph")}constructor(e={}){this._isDirected=Object.prototype.hasOwnProperty.call(e,"directed")?e.directed:!0,this._isMultigraph=Object.prototype.hasOwnProperty.call(e,"multigraph")?e.multigraph:!1,this._isCompound=Object.prototype.hasOwnProperty.call(e,"compound")?e.compound:!1,this._label=void 0,this._defaultNodeLabelFn=Ns(void 0),this._defaultEdgeLabelFn=Ns(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[Jd]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(e){return this._label=e,this}graph(){return this._label}setDefaultNodeLabel(e){return Ai(e)||(e=Ns(e)),this._defaultNodeLabelFn=e,this}nodeCount(){return this._nodeCount}nodes(){return zr(this._nodes)}sources(){var e=this;return Yr(this.nodes(),function(r){return hr(e._in[r])})}sinks(){var e=this;return Yr(this.nodes(),function(r){return hr(e._out[r])})}setNodes(e,r){var n=arguments,i=this;return Ae(e,function(a){n.length>1?i.setNode(a,r):i.setNode(a)}),this}setNode(e,r){return Object.prototype.hasOwnProperty.call(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=r),this):(this._nodes[e]=arguments.length>1?r:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]=Jd,this._children[e]={},this._children[Jd][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return Object.prototype.hasOwnProperty.call(this._nodes,e)}removeNode(e){if(Object.prototype.hasOwnProperty.call(this._nodes,e)){var r=o(n=>this.removeEdge(this._edgeObjs[n]),"removeEdge");delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],Ae(this.children(e),n=>{this.setParent(n)}),delete this._children[e]),Ae(zr(this._in[e]),r),delete this._in[e],delete this._preds[e],Ae(zr(this._out[e]),r),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(mr(r))r=Jd;else{r+="";for(var n=r;!mr(n);n=this.parent(n))if(n===e)throw new Error("Setting "+r+" as parent of "+e+" would create a cycle");this.setNode(r)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=r,this._children[r][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var r=this._parent[e];if(r!==Jd)return r}}children(e){if(mr(e)&&(e=Jd),this._isCompound){var r=this._children[e];if(r)return zr(r)}else{if(e===Jd)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var r=this._preds[e];if(r)return zr(r)}successors(e){var r=this._sucs[e];if(r)return zr(r)}neighbors(e){var r=this.predecessors(e);if(r)return CR(r,this.successors(e))}isLeaf(e){var r;return this.isDirected()?r=this.successors(e):r=this.neighbors(e),r.length===0}filterNodes(e){var r=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});r.setGraph(this.graph());var n=this;Ae(this._nodes,function(s,l){e(l)&&r.setNode(l,s)}),Ae(this._edgeObjs,function(s){r.hasNode(s.v)&&r.hasNode(s.w)&&r.setEdge(s,n.edge(s))});var i={};function a(s){var l=n.parent(s);return l===void 0||r.hasNode(l)?(i[s]=l,l):l in i?i[l]:a(l)}return o(a,"findParent"),this._isCompound&&Ae(r.nodes(),function(s){r.setParent(s,a(s))}),r}setDefaultEdgeLabel(e){return Ai(e)||(e=Ns(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return br(this._edgeObjs)}setPath(e,r){var n=this,i=arguments;return Xr(e,function(a,s){return i.length>1?n.setEdge(a,s,r):n.setEdge(a,s),s}),this}setEdge(){var e,r,n,i,a=!1,s=arguments[0];typeof s=="object"&&s!==null&&"v"in s?(e=s.v,r=s.w,n=s.name,arguments.length===2&&(i=arguments[1],a=!0)):(e=s,r=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],a=!0)),e=""+e,r=""+r,mr(n)||(n=""+n);var l=F2(this._isDirected,e,r,n);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,l))return a&&(this._edgeLabels[l]=i),this;if(!mr(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(r),this._edgeLabels[l]=a?i:this._defaultEdgeLabelFn(e,r,n);var u=gOe(this._isDirected,e,r,n);return e=u.v,r=u.w,Object.freeze(u),this._edgeObjs[l]=u,bie(this._preds[r],e),bie(this._sucs[e],r),this._in[r][l]=u,this._out[e][l]=u,this._edgeCount++,this}edge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n);return this._edgeLabels[i]}hasEdge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n);return Object.prototype.hasOwnProperty.call(this._edgeLabels,i)}removeEdge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n),a=this._edgeObjs[i];return a&&(e=a.v,r=a.w,delete this._edgeLabels[i],delete this._edgeObjs[i],Tie(this._preds[r],e),Tie(this._sucs[e],r),delete this._in[r][i],delete this._out[e][i],this._edgeCount--),this}inEdges(e,r){var n=this._in[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.v===r}):i}}outEdges(e,r){var n=this._out[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.w===r}):i}}nodeEdges(e,r){var n=this.inEdges(e,r);if(n)return n.concat(this.outEdges(e,r))}};sn.prototype._nodeCount=0;sn.prototype._edgeCount=0;o(bie,"incrementOrInitEntry");o(Tie,"decrementOrRemoveEntry");o(F2,"edgeArgsToId");o(gOe,"edgeArgsToObj");o(AR,"edgeObjToId")});var Wo=N(()=>{"use strict";hk()});function wie(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function yOe(t,e){if(t!=="_next"&&t!=="_prev")return e}var dk,kie=N(()=>{"use strict";dk=class{static{o(this,"List")}constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,r=e._prev;if(r!==e)return wie(r),r}enqueue(e){var r=this._sentinel;e._prev&&e._next&&wie(e),e._next=r._next,r._next._prev=e,r._next=e,e._prev=r}toString(){for(var e=[],r=this._sentinel,n=r._prev;n!==r;)e.push(JSON.stringify(n,yOe)),n=n._prev;return"["+e.join(", ")+"]"}};o(wie,"unlink");o(yOe,"filterOutLinks")});function Eie(t,e){if(t.nodeCount()<=1)return[];var r=bOe(t,e||vOe),n=xOe(r.graph,r.buckets,r.zeroIdx);return qr(Je(n,function(i){return t.outEdges(i.v,i.w)}))}function xOe(t,e,r){for(var n=[],i=e[e.length-1],a=e[0],s;t.nodeCount();){for(;s=a.dequeue();)_R(t,e,r,s);for(;s=i.dequeue();)_R(t,e,r,s);if(t.nodeCount()){for(var l=e.length-2;l>0;--l)if(s=e[l].dequeue(),s){n=n.concat(_R(t,e,r,s,!0));break}}}return n}function _R(t,e,r,n,i){var a=i?[]:void 0;return Ae(t.inEdges(n.v),function(s){var l=t.edge(s),u=t.node(s.v);i&&a.push({v:s.v,w:s.w}),u.out-=l,DR(e,r,u)}),Ae(t.outEdges(n.v),function(s){var l=t.edge(s),u=s.w,h=t.node(u);h.in-=l,DR(e,r,h)}),t.removeNode(n.v),a}function bOe(t,e){var r=new sn,n=0,i=0;Ae(t.nodes(),function(l){r.setNode(l,{v:l,in:0,out:0})}),Ae(t.edges(),function(l){var u=r.edge(l.v,l.w)||0,h=e(l),f=u+h;r.setEdge(l.v,l.w,f),i=Math.max(i,r.node(l.v).out+=h),n=Math.max(n,r.node(l.w).in+=h)});var a=Ho(i+n+3).map(function(){return new dk}),s=n+1;return Ae(r.nodes(),function(l){DR(a,s,r.node(l))}),{graph:r,buckets:a,zeroIdx:s}}function DR(t,e,r){r.out?r.in?t[r.out-r.in+e].enqueue(r):t[t.length-1].enqueue(r):t[0].enqueue(r)}var vOe,Sie=N(()=>{"use strict";qt();Wo();kie();vOe=Ns(1);o(Eie,"greedyFAS");o(xOe,"doGreedyFAS");o(_R,"removeNode");o(bOe,"buildState");o(DR,"assignBucket")});function Cie(t){var e=t.graph().acyclicer==="greedy"?Eie(t,r(t)):TOe(t);Ae(e,function(n){var i=t.edge(n);t.removeEdge(n),i.forwardName=n.name,i.reversed=!0,t.setEdge(n.w,n.v,i,Zd("rev"))});function r(n){return function(i){return n.edge(i).weight}}o(r,"weightFn")}function TOe(t){var e=[],r={},n={};function i(a){Object.prototype.hasOwnProperty.call(n,a)||(n[a]=!0,r[a]=!0,Ae(t.outEdges(a),function(s){Object.prototype.hasOwnProperty.call(r,s.w)?e.push(s):i(s.w)}),delete r[a])}return o(i,"dfs"),Ae(t.nodes(),i),e}function Aie(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.reversed){t.removeEdge(e);var n=r.forwardName;delete r.reversed,delete r.forwardName,t.setEdge(e.w,e.v,r,n)}})}var LR=N(()=>{"use strict";qt();Sie();o(Cie,"run");o(TOe,"dfsFAS");o(Aie,"undo")});function Dc(t,e,r,n){var i;do i=Zd(n);while(t.hasNode(i));return r.dummy=e,t.setNode(i,r),i}function Die(t){var e=new sn().setGraph(t.graph());return Ae(t.nodes(),function(r){e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){var n=e.edge(r.v,r.w)||{weight:0,minlen:1},i=t.edge(r);e.setEdge(r.v,r.w,{weight:n.weight+i.weight,minlen:Math.max(n.minlen,i.minlen)})}),e}function pk(t){var e=new sn({multigraph:t.isMultigraph()}).setGraph(t.graph());return Ae(t.nodes(),function(r){t.children(r).length||e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){e.setEdge(r,t.edge(r))}),e}function RR(t,e){var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2;if(!i&&!a)throw new Error("Not possible to find intersection inside of the rectangle");var u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=l*i/a,h=l):(i<0&&(s=-s),u=s,h=s*a/i),{x:r+u,y:n+h}}function of(t){var e=Je(Ho(MR(t)+1),function(){return[]});return Ae(t.nodes(),function(r){var n=t.node(r),i=n.rank;mr(i)||(e[i][n.order]=r)}),e}function Lie(t){var e=Nl(Je(t.nodes(),function(r){return t.node(r).rank}));Ae(t.nodes(),function(r){var n=t.node(r);Bt(n,"rank")&&(n.rank-=e)})}function Rie(t){var e=Nl(Je(t.nodes(),function(a){return t.node(a).rank})),r=[];Ae(t.nodes(),function(a){var s=t.node(a).rank-e;r[s]||(r[s]=[]),r[s].push(a)});var n=0,i=t.graph().nodeRankFactor;Ae(r,function(a,s){mr(a)&&s%i!==0?--n:n&&Ae(a,function(l){t.node(l).rank+=n})})}function NR(t,e,r,n){var i={width:0,height:0};return arguments.length>=4&&(i.rank=r,i.order=n),Dc(t,"border",i,e)}function MR(t){return $s(Je(t.nodes(),function(e){var r=t.node(e).rank;if(!mr(r))return r}))}function Nie(t,e){var r={lhs:[],rhs:[]};return Ae(t,function(n){e(n)?r.lhs.push(n):r.rhs.push(n)}),r}function Mie(t,e){var r=Qw();try{return e()}finally{console.log(t+" time: "+(Qw()-r)+"ms")}}function Iie(t,e){return e()}var Lc=N(()=>{"use strict";qt();Wo();o(Dc,"addDummyNode");o(Die,"simplify");o(pk,"asNonCompoundGraph");o(RR,"intersectRect");o(of,"buildLayerMatrix");o(Lie,"normalizeRanks");o(Rie,"removeEmptyRanks");o(NR,"addBorderNode");o(MR,"maxRank");o(Nie,"partition");o(Mie,"time");o(Iie,"notime")});function Pie(t){function e(r){var n=t.children(r),i=t.node(r);if(n.length&&Ae(n,e),Object.prototype.hasOwnProperty.call(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var a=i.minRank,s=i.maxRank+1;a{"use strict";qt();Lc();o(Pie,"addBorderSegments");o(Oie,"addBorderNode")});function $ie(t){var e=t.graph().rankdir.toLowerCase();(e==="lr"||e==="rl")&&Gie(t)}function zie(t){var e=t.graph().rankdir.toLowerCase();(e==="bt"||e==="rl")&&wOe(t),(e==="lr"||e==="rl")&&(kOe(t),Gie(t))}function Gie(t){Ae(t.nodes(),function(e){Fie(t.node(e))}),Ae(t.edges(),function(e){Fie(t.edge(e))})}function Fie(t){var e=t.width;t.width=t.height,t.height=e}function wOe(t){Ae(t.nodes(),function(e){IR(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,IR),Object.prototype.hasOwnProperty.call(r,"y")&&IR(r)})}function IR(t){t.y=-t.y}function kOe(t){Ae(t.nodes(),function(e){OR(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,OR),Object.prototype.hasOwnProperty.call(r,"x")&&OR(r)})}function OR(t){var e=t.x;t.x=t.y,t.y=e}var Vie=N(()=>{"use strict";qt();o($ie,"adjust");o(zie,"undo");o(Gie,"swapWidthHeight");o(Fie,"swapWidthHeightOne");o(wOe,"reverseY");o(IR,"reverseYOne");o(kOe,"swapXY");o(OR,"swapXYOne")});function Uie(t){t.graph().dummyChains=[],Ae(t.edges(),function(e){SOe(t,e)})}function SOe(t,e){var r=e.v,n=t.node(r).rank,i=e.w,a=t.node(i).rank,s=e.name,l=t.edge(e),u=l.labelRank;if(a!==n+1){t.removeEdge(e);var h=void 0,f,d;for(d=0,++n;n{"use strict";qt();Lc();o(Uie,"run");o(SOe,"normalizeEdge");o(Hie,"undo")});function $2(t){var e={};function r(n){var i=t.node(n);if(Object.prototype.hasOwnProperty.call(e,n))return i.rank;e[n]=!0;var a=Nl(Je(t.outEdges(n),function(s){return r(s.w)-t.edge(s).minlen}));return(a===Number.POSITIVE_INFINITY||a===void 0||a===null)&&(a=0),i.rank=a}o(r,"dfs"),Ae(t.sources(),r)}function ep(t,e){return t.node(e.w).rank-t.node(e.v).rank-t.edge(e).minlen}var mk=N(()=>{"use strict";qt();o($2,"longestPath");o(ep,"slack")});function gk(t){var e=new sn({directed:!1}),r=t.nodes()[0],n=t.nodeCount();e.setNode(r,{});for(var i,a;COe(e,t){"use strict";qt();Wo();mk();o(gk,"feasibleTree");o(COe,"tightTree");o(AOe,"findMinSlackEdge");o(_Oe,"shiftRanks")});var qie=N(()=>{"use strict"});var FR=N(()=>{"use strict"});var eXt,$R=N(()=>{"use strict";qt();FR();eXt=Ns(1)});var Yie=N(()=>{"use strict";$R()});var zR=N(()=>{"use strict"});var Xie=N(()=>{"use strict";zR()});var hXt,jie=N(()=>{"use strict";qt();hXt=Ns(1)});function GR(t){var e={},r={},n=[];function i(a){if(Object.prototype.hasOwnProperty.call(r,a))throw new z2;Object.prototype.hasOwnProperty.call(e,a)||(r[a]=!0,e[a]=!0,Ae(t.predecessors(a),i),delete r[a],n.push(a))}if(o(i,"visit"),Ae(t.sinks(),i),SR(e)!==t.nodeCount())throw new z2;return n}function z2(){}var VR=N(()=>{"use strict";qt();GR.CycleException=z2;o(GR,"topsort");o(z2,"CycleException");z2.prototype=new Error});var Kie=N(()=>{"use strict";VR()});function yk(t,e,r){Pt(e)||(e=[e]);var n=(t.isDirected()?t.successors:t.neighbors).bind(t),i=[],a={};return Ae(e,function(s){if(!t.hasNode(s))throw new Error("Graph does not have node: "+s);Qie(t,s,r==="post",a,n,i)}),i}function Qie(t,e,r,n,i,a){Object.prototype.hasOwnProperty.call(n,e)||(n[e]=!0,r||a.push(e),Ae(i(e),function(s){Qie(t,s,r,n,i,a)}),r&&a.push(e))}var UR=N(()=>{"use strict";qt();o(yk,"dfs");o(Qie,"doDfs")});function HR(t,e){return yk(t,e,"post")}var Zie=N(()=>{"use strict";UR();o(HR,"postorder")});function WR(t,e){return yk(t,e,"pre")}var Jie=N(()=>{"use strict";UR();o(WR,"preorder")});var eae=N(()=>{"use strict";FR();hk()});var tae=N(()=>{"use strict";qie();$R();Yie();Xie();jie();Kie();Zie();Jie();eae();zR();VR()});function cf(t){t=Die(t),$2(t);var e=gk(t);YR(e),qR(e,t);for(var r,n;r=aae(e);)n=sae(e,t,r),oae(e,t,r,n)}function qR(t,e){var r=HR(t,t.nodes());r=r.slice(0,r.length-1),Ae(r,function(n){MOe(t,e,n)})}function MOe(t,e,r){var n=t.node(r),i=n.parent;t.edge(r,i).cutvalue=nae(t,e,r)}function nae(t,e,r){var n=t.node(r),i=n.parent,a=!0,s=e.edge(r,i),l=0;return s||(a=!1,s=e.edge(i,r)),l=s.weight,Ae(e.nodeEdges(r),function(u){var h=u.v===r,f=h?u.w:u.v;if(f!==i){var d=h===a,p=e.edge(u).weight;if(l+=d?p:-p,OOe(t,r,f)){var m=t.edge(r,f).cutvalue;l+=d?-m:m}}}),l}function YR(t,e){arguments.length<2&&(e=t.nodes()[0]),iae(t,{},1,e)}function iae(t,e,r,n,i){var a=r,s=t.node(n);return e[n]=!0,Ae(t.neighbors(n),function(l){Object.prototype.hasOwnProperty.call(e,l)||(r=iae(t,e,r,l,n))}),s.low=a,s.lim=r++,i?s.parent=i:delete s.parent,r}function aae(t){return ls(t.edges(),function(e){return t.edge(e).cutvalue<0})}function sae(t,e,r){var n=r.v,i=r.w;e.hasEdge(n,i)||(n=r.w,i=r.v);var a=t.node(n),s=t.node(i),l=a,u=!1;a.lim>s.lim&&(l=s,u=!0);var h=Yr(e.edges(),function(f){return u===rae(t,t.node(f.v),l)&&u!==rae(t,t.node(f.w),l)});return Kd(h,function(f){return ep(e,f)})}function oae(t,e,r,n){var i=r.v,a=r.w;t.removeEdge(i,a),t.setEdge(n.v,n.w,{}),YR(t),qR(t,e),IOe(t,e)}function IOe(t,e){var r=ls(t.nodes(),function(i){return!e.node(i).parent}),n=WR(t,r);n=n.slice(1),Ae(n,function(i){var a=t.node(i).parent,s=e.edge(i,a),l=!1;s||(s=e.edge(a,i),l=!0),e.node(i).rank=e.node(a).rank+(l?s.minlen:-s.minlen)})}function OOe(t,e,r){return t.hasEdge(e,r)}function rae(t,e,r){return r.low<=e.lim&&e.lim<=r.lim}var lae=N(()=>{"use strict";qt();tae();Lc();BR();mk();cf.initLowLimValues=YR;cf.initCutValues=qR;cf.calcCutValue=nae;cf.leaveEdge=aae;cf.enterEdge=sae;cf.exchangeEdges=oae;o(cf,"networkSimplex");o(qR,"initCutValues");o(MOe,"assignCutValue");o(nae,"calcCutValue");o(YR,"initLowLimValues");o(iae,"dfsAssignLowLim");o(aae,"leaveEdge");o(sae,"enterEdge");o(oae,"exchangeEdges");o(IOe,"updateRanks");o(OOe,"isTreeEdge");o(rae,"isDescendant")});function XR(t){switch(t.graph().ranker){case"network-simplex":cae(t);break;case"tight-tree":BOe(t);break;case"longest-path":POe(t);break;default:cae(t)}}function BOe(t){$2(t),gk(t)}function cae(t){cf(t)}var POe,jR=N(()=>{"use strict";BR();lae();mk();o(XR,"rank");POe=$2;o(BOe,"tightTreeRanker");o(cae,"networkSimplexRanker")});function uae(t){var e=Dc(t,"root",{},"_root"),r=FOe(t),n=$s(br(r))-1,i=2*n+1;t.graph().nestingRoot=e,Ae(t.edges(),function(s){t.edge(s).minlen*=i});var a=$Oe(t)+1;Ae(t.children(),function(s){hae(t,e,i,a,n,r,s)}),t.graph().nodeRankFactor=i}function hae(t,e,r,n,i,a,s){var l=t.children(s);if(!l.length){s!==e&&t.setEdge(e,s,{weight:0,minlen:r});return}var u=NR(t,"_bt"),h=NR(t,"_bb"),f=t.node(s);t.setParent(u,s),f.borderTop=u,t.setParent(h,s),f.borderBottom=h,Ae(l,function(d){hae(t,e,r,n,i,a,d);var p=t.node(d),m=p.borderTop?p.borderTop:d,g=p.borderBottom?p.borderBottom:d,y=p.borderTop?n:2*n,v=m!==g?1:i-a[s]+1;t.setEdge(u,m,{weight:y,minlen:v,nestingEdge:!0}),t.setEdge(g,h,{weight:y,minlen:v,nestingEdge:!0})}),t.parent(s)||t.setEdge(e,u,{weight:0,minlen:i+a[s]})}function FOe(t){var e={};function r(n,i){var a=t.children(n);a&&a.length&&Ae(a,function(s){r(s,i+1)}),e[n]=i}return o(r,"dfs"),Ae(t.children(),function(n){r(n,1)}),e}function $Oe(t){return Xr(t.edges(),function(e,r){return e+t.edge(r).weight},0)}function fae(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,Ae(t.edges(),function(r){var n=t.edge(r);n.nestingEdge&&t.removeEdge(r)})}var dae=N(()=>{"use strict";qt();Lc();o(uae,"run");o(hae,"dfs");o(FOe,"treeDepths");o($Oe,"sumWeights");o(fae,"cleanup")});function pae(t,e,r){var n={},i;Ae(r,function(a){for(var s=t.parent(a),l,u;s;){if(l=t.parent(s),l?(u=n[l],n[l]=s):(u=i,i=s),u&&u!==s){e.setEdge(u,s);return}s=l}})}var mae=N(()=>{"use strict";qt();o(pae,"addSubgraphConstraints")});function gae(t,e,r){var n=GOe(t),i=new sn({compound:!0}).setGraph({root:n}).setDefaultNodeLabel(function(a){return t.node(a)});return Ae(t.nodes(),function(a){var s=t.node(a),l=t.parent(a);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(i.setNode(a),i.setParent(a,l||n),Ae(t[r](a),function(u){var h=u.v===a?u.w:u.v,f=i.edge(h,a),d=mr(f)?0:f.weight;i.setEdge(h,a,{weight:t.edge(u).weight+d})}),Object.prototype.hasOwnProperty.call(s,"minRank")&&i.setNode(a,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))}),i}function GOe(t){for(var e;t.hasNode(e=Zd("_root")););return e}var yae=N(()=>{"use strict";qt();Wo();o(gae,"buildLayerGraph");o(GOe,"createRootNode")});function vae(t,e){for(var r=0,n=1;n0;)f%2&&(d+=l[f+1]),f=f-1>>1,l[f]+=h.weight;u+=h.weight*d})),u}var xae=N(()=>{"use strict";qt();o(vae,"crossCount");o(VOe,"twoLayerCrossCount")});function bae(t){var e={},r=Yr(t.nodes(),function(l){return!t.children(l).length}),n=$s(Je(r,function(l){return t.node(l).rank})),i=Je(Ho(n+1),function(){return[]});function a(l){if(!Bt(e,l)){e[l]=!0;var u=t.node(l);i[u.rank].push(l),Ae(t.successors(l),a)}}o(a,"dfs");var s=_c(r,function(l){return t.node(l).rank});return Ae(s,a),i}var Tae=N(()=>{"use strict";qt();o(bae,"initOrder")});function wae(t,e){return Je(e,function(r){var n=t.inEdges(r);if(n.length){var i=Xr(n,function(a,s){var l=t.edge(s),u=t.node(s.v);return{sum:a.sum+l.weight*u.order,weight:a.weight+l.weight}},{sum:0,weight:0});return{v:r,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:r}})}var kae=N(()=>{"use strict";qt();o(wae,"barycenter")});function Eae(t,e){var r={};Ae(t,function(i,a){var s=r[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:a};mr(i.barycenter)||(s.barycenter=i.barycenter,s.weight=i.weight)}),Ae(e.edges(),function(i){var a=r[i.v],s=r[i.w];!mr(a)&&!mr(s)&&(s.indegree++,a.out.push(r[i.w]))});var n=Yr(r,function(i){return!i.indegree});return UOe(n)}function UOe(t){var e=[];function r(a){return function(s){s.merged||(mr(s.barycenter)||mr(a.barycenter)||s.barycenter>=a.barycenter)&&HOe(a,s)}}o(r,"handleIn");function n(a){return function(s){s.in.push(a),--s.indegree===0&&t.push(s)}}for(o(n,"handleOut");t.length;){var i=t.pop();e.push(i),Ae(i.in.reverse(),r(i)),Ae(i.out,n(i))}return Je(Yr(e,function(a){return!a.merged}),function(a){return Qd(a,["vs","i","barycenter","weight"])})}function HOe(t,e){var r=0,n=0;t.weight&&(r+=t.barycenter*t.weight,n+=t.weight),e.weight&&(r+=e.barycenter*e.weight,n+=e.weight),t.vs=e.vs.concat(t.vs),t.barycenter=r/n,t.weight=n,t.i=Math.min(e.i,t.i),e.merged=!0}var Sae=N(()=>{"use strict";qt();o(Eae,"resolveConflicts");o(UOe,"doResolveConflicts");o(HOe,"mergeEntries")});function Aae(t,e){var r=Nie(t,function(f){return Object.prototype.hasOwnProperty.call(f,"barycenter")}),n=r.lhs,i=_c(r.rhs,function(f){return-f.i}),a=[],s=0,l=0,u=0;n.sort(WOe(!!e)),u=Cae(a,i,u),Ae(n,function(f){u+=f.vs.length,a.push(f.vs),s+=f.barycenter*f.weight,l+=f.weight,u=Cae(a,i,u)});var h={vs:qr(a)};return l&&(h.barycenter=s/l,h.weight=l),h}function Cae(t,e,r){for(var n;e.length&&(n=ma(e)).i<=r;)e.pop(),t.push(n.vs),r++;return r}function WOe(t){return function(e,r){return e.barycenterr.barycenter?1:t?r.i-e.i:e.i-r.i}}var _ae=N(()=>{"use strict";qt();Lc();o(Aae,"sort");o(Cae,"consumeUnsortable");o(WOe,"compareWithBias")});function KR(t,e,r,n){var i=t.children(e),a=t.node(e),s=a?a.borderLeft:void 0,l=a?a.borderRight:void 0,u={};s&&(i=Yr(i,function(g){return g!==s&&g!==l}));var h=wae(t,i);Ae(h,function(g){if(t.children(g.v).length){var y=KR(t,g.v,r,n);u[g.v]=y,Object.prototype.hasOwnProperty.call(y,"barycenter")&&YOe(g,y)}});var f=Eae(h,r);qOe(f,u);var d=Aae(f,n);if(s&&(d.vs=qr([s,d.vs,l]),t.predecessors(s).length)){var p=t.node(t.predecessors(s)[0]),m=t.node(t.predecessors(l)[0]);Object.prototype.hasOwnProperty.call(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+p.order+m.order)/(d.weight+2),d.weight+=2}return d}function qOe(t,e){Ae(t,function(r){r.vs=qr(r.vs.map(function(n){return e[n]?e[n].vs:n}))})}function YOe(t,e){mr(t.barycenter)?(t.barycenter=e.barycenter,t.weight=e.weight):(t.barycenter=(t.barycenter*t.weight+e.barycenter*e.weight)/(t.weight+e.weight),t.weight+=e.weight)}var Dae=N(()=>{"use strict";qt();kae();Sae();_ae();o(KR,"sortSubgraph");o(qOe,"expandSubgraphs");o(YOe,"mergeBarycenters")});function Nae(t){var e=MR(t),r=Lae(t,Ho(1,e+1),"inEdges"),n=Lae(t,Ho(e-1,-1,-1),"outEdges"),i=bae(t);Rae(t,i);for(var a=Number.POSITIVE_INFINITY,s,l=0,u=0;u<4;++l,++u){XOe(l%2?r:n,l%4>=2),i=of(t);var h=vae(t,i);h{"use strict";qt();Wo();Lc();mae();yae();xae();Tae();Dae();o(Nae,"order");o(Lae,"buildLayerGraphs");o(XOe,"sweepLayerGraphs");o(Rae,"assignOrder")});function Iae(t){var e=KOe(t);Ae(t.graph().dummyChains,function(r){for(var n=t.node(r),i=n.edgeObj,a=jOe(t,e,i.v,i.w),s=a.path,l=a.lca,u=0,h=s[u],f=!0;r!==i.w;){if(n=t.node(r),f){for(;(h=s[u])!==l&&t.node(h).maxRanks||l>e[u].lim));for(h=u,u=n;(u=t.parent(u))!==h;)a.push(u);return{path:i.concat(a.reverse()),lca:h}}function KOe(t){var e={},r=0;function n(i){var a=r;Ae(t.children(i),n),e[i]={low:a,lim:r++}}return o(n,"dfs"),Ae(t.children(),n),e}var Oae=N(()=>{"use strict";qt();o(Iae,"parentDummyChains");o(jOe,"findPath");o(KOe,"postorder")});function QOe(t,e){var r={};function n(i,a){var s=0,l=0,u=i.length,h=ma(a);return Ae(a,function(f,d){var p=JOe(t,f),m=p?t.node(p).order:u;(p||f===h)&&(Ae(a.slice(l,d+1),function(g){Ae(t.predecessors(g),function(y){var v=t.node(y),x=v.order;(xh)&&Pae(r,p,f)})})}o(n,"scan");function i(a,s){var l=-1,u,h=0;return Ae(s,function(f,d){if(t.node(f).dummy==="border"){var p=t.predecessors(f);p.length&&(u=t.node(p[0]).order,n(s,h,d,l,u),h=d,l=u)}n(s,h,s.length,u,a.length)}),s}return o(i,"visitLayer"),Xr(e,i),r}function JOe(t,e){if(t.node(e).dummy)return ls(t.predecessors(e),function(r){return t.node(r).dummy})}function Pae(t,e,r){if(e>r){var n=e;e=r,r=n}var i=t[e];i||(t[e]=i={}),i[r]=!0}function ePe(t,e,r){if(e>r){var n=e;e=r,r=n}return!!t[e]&&Object.prototype.hasOwnProperty.call(t[e],r)}function tPe(t,e,r,n){var i={},a={},s={};return Ae(e,function(l){Ae(l,function(u,h){i[u]=u,a[u]=u,s[u]=h})}),Ae(e,function(l){var u=-1;Ae(l,function(h){var f=n(h);if(f.length){f=_c(f,function(y){return s[y]});for(var d=(f.length-1)/2,p=Math.floor(d),m=Math.ceil(d);p<=m;++p){var g=f[p];a[h]===h&&u{"use strict";qt();Wo();Lc();o(QOe,"findType1Conflicts");o(ZOe,"findType2Conflicts");o(JOe,"findOtherInnerSegmentNode");o(Pae,"addConflict");o(ePe,"hasConflict");o(tPe,"verticalAlignment");o(rPe,"horizontalCompaction");o(nPe,"buildBlockGraph");o(iPe,"findSmallestWidthAlignment");o(aPe,"alignCoordinates");o(sPe,"balance");o(Bae,"positionX");o(oPe,"sep");o(lPe,"width")});function $ae(t){t=pk(t),cPe(t),gR(Bae(t),function(e,r){t.node(r).x=e})}function cPe(t){var e=of(t),r=t.graph().ranksep,n=0;Ae(e,function(i){var a=$s(Je(i,function(s){return t.node(s).height}));Ae(i,function(s){t.node(s).y=n+a/2}),n+=a+r})}var zae=N(()=>{"use strict";qt();Lc();Fae();o($ae,"position");o(cPe,"positionY")});function G2(t,e){var r=e&&e.debugTiming?Mie:Iie;r("layout",()=>{var n=r(" buildLayoutGraph",()=>bPe(t));r(" runLayout",()=>uPe(n,r)),r(" updateInputGraph",()=>hPe(t,n))})}function uPe(t,e){e(" makeSpaceForEdgeLabels",()=>TPe(t)),e(" removeSelfEdges",()=>LPe(t)),e(" acyclic",()=>Cie(t)),e(" nestingGraph.run",()=>uae(t)),e(" rank",()=>XR(pk(t))),e(" injectEdgeLabelProxies",()=>wPe(t)),e(" removeEmptyRanks",()=>Rie(t)),e(" nestingGraph.cleanup",()=>fae(t)),e(" normalizeRanks",()=>Lie(t)),e(" assignRankMinMax",()=>kPe(t)),e(" removeEdgeLabelProxies",()=>EPe(t)),e(" normalize.run",()=>Uie(t)),e(" parentDummyChains",()=>Iae(t)),e(" addBorderSegments",()=>Pie(t)),e(" order",()=>Nae(t)),e(" insertSelfEdges",()=>RPe(t)),e(" adjustCoordinateSystem",()=>$ie(t)),e(" position",()=>$ae(t)),e(" positionSelfEdges",()=>NPe(t)),e(" removeBorderNodes",()=>DPe(t)),e(" normalize.undo",()=>Hie(t)),e(" fixupEdgeLabelCoords",()=>APe(t)),e(" undoCoordinateSystem",()=>zie(t)),e(" translateGraph",()=>SPe(t)),e(" assignNodeIntersects",()=>CPe(t)),e(" reversePoints",()=>_Pe(t)),e(" acyclic.undo",()=>Aie(t))}function hPe(t,e){Ae(t.nodes(),function(r){var n=t.node(r),i=e.node(r);n&&(n.x=i.x,n.y=i.y,e.children(r).length&&(n.width=i.width,n.height=i.height))}),Ae(t.edges(),function(r){var n=t.edge(r),i=e.edge(r);n.points=i.points,Object.prototype.hasOwnProperty.call(i,"x")&&(n.x=i.x,n.y=i.y)}),t.graph().width=e.graph().width,t.graph().height=e.graph().height}function bPe(t){var e=new sn({multigraph:!0,compound:!0}),r=ZR(t.graph());return e.setGraph(Hh({},dPe,QR(r,fPe),Qd(r,pPe))),Ae(t.nodes(),function(n){var i=ZR(t.node(n));e.setNode(n,nf(QR(i,mPe),gPe)),e.setParent(n,t.parent(n))}),Ae(t.edges(),function(n){var i=ZR(t.edge(n));e.setEdge(n,Hh({},vPe,QR(i,yPe),Qd(i,xPe)))}),e}function TPe(t){var e=t.graph();e.ranksep/=2,Ae(t.edges(),function(r){var n=t.edge(r);n.minlen*=2,n.labelpos.toLowerCase()!=="c"&&(e.rankdir==="TB"||e.rankdir==="BT"?n.width+=n.labeloffset:n.height+=n.labeloffset)})}function wPe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.width&&r.height){var n=t.node(e.v),i=t.node(e.w),a={rank:(i.rank-n.rank)/2+n.rank,e};Dc(t,"edge-proxy",a,"_ep")}})}function kPe(t){var e=0;Ae(t.nodes(),function(r){var n=t.node(r);n.borderTop&&(n.minRank=t.node(n.borderTop).rank,n.maxRank=t.node(n.borderBottom).rank,e=$s(e,n.maxRank))}),t.graph().maxRank=e}function EPe(t){Ae(t.nodes(),function(e){var r=t.node(e);r.dummy==="edge-proxy"&&(t.edge(r.e).labelRank=r.rank,t.removeNode(e))})}function SPe(t){var e=Number.POSITIVE_INFINITY,r=0,n=Number.POSITIVE_INFINITY,i=0,a=t.graph(),s=a.marginx||0,l=a.marginy||0;function u(h){var f=h.x,d=h.y,p=h.width,m=h.height;e=Math.min(e,f-p/2),r=Math.max(r,f+p/2),n=Math.min(n,d-m/2),i=Math.max(i,d+m/2)}o(u,"getExtremes"),Ae(t.nodes(),function(h){u(t.node(h))}),Ae(t.edges(),function(h){var f=t.edge(h);Object.prototype.hasOwnProperty.call(f,"x")&&u(f)}),e-=s,n-=l,Ae(t.nodes(),function(h){var f=t.node(h);f.x-=e,f.y-=n}),Ae(t.edges(),function(h){var f=t.edge(h);Ae(f.points,function(d){d.x-=e,d.y-=n}),Object.prototype.hasOwnProperty.call(f,"x")&&(f.x-=e),Object.prototype.hasOwnProperty.call(f,"y")&&(f.y-=n)}),a.width=r-e+s,a.height=i-n+l}function CPe(t){Ae(t.edges(),function(e){var r=t.edge(e),n=t.node(e.v),i=t.node(e.w),a,s;r.points?(a=r.points[0],s=r.points[r.points.length-1]):(r.points=[],a=i,s=n),r.points.unshift(RR(n,a)),r.points.push(RR(i,s))})}function APe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(Object.prototype.hasOwnProperty.call(r,"x"))switch((r.labelpos==="l"||r.labelpos==="r")&&(r.width-=r.labeloffset),r.labelpos){case"l":r.x-=r.width/2+r.labeloffset;break;case"r":r.x+=r.width/2+r.labeloffset;break}})}function _Pe(t){Ae(t.edges(),function(e){var r=t.edge(e);r.reversed&&r.points.reverse()})}function DPe(t){Ae(t.nodes(),function(e){if(t.children(e).length){var r=t.node(e),n=t.node(r.borderTop),i=t.node(r.borderBottom),a=t.node(ma(r.borderLeft)),s=t.node(ma(r.borderRight));r.width=Math.abs(s.x-a.x),r.height=Math.abs(i.y-n.y),r.x=a.x+r.width/2,r.y=n.y+r.height/2}}),Ae(t.nodes(),function(e){t.node(e).dummy==="border"&&t.removeNode(e)})}function LPe(t){Ae(t.edges(),function(e){if(e.v===e.w){var r=t.node(e.v);r.selfEdges||(r.selfEdges=[]),r.selfEdges.push({e,label:t.edge(e)}),t.removeEdge(e)}})}function RPe(t){var e=of(t);Ae(e,function(r){var n=0;Ae(r,function(i,a){var s=t.node(i);s.order=a+n,Ae(s.selfEdges,function(l){Dc(t,"selfedge",{width:l.label.width,height:l.label.height,rank:s.rank,order:a+ ++n,e:l.e,label:l.label},"_se")}),delete s.selfEdges})})}function NPe(t){Ae(t.nodes(),function(e){var r=t.node(e);if(r.dummy==="selfedge"){var n=t.node(r.e.v),i=n.x+n.width/2,a=n.y,s=r.x-i,l=n.height/2;t.setEdge(r.e,r.label),t.removeNode(e),r.label.points=[{x:i+2*s/3,y:a-l},{x:i+5*s/6,y:a-l},{x:i+s,y:a},{x:i+5*s/6,y:a+l},{x:i+2*s/3,y:a+l}],r.label.x=r.x,r.label.y=r.y}})}function QR(t,e){return jd(Qd(t,e),Number)}function ZR(t){var e={};return Ae(t,function(r,n){e[n.toLowerCase()]=r}),e}var fPe,dPe,pPe,mPe,gPe,yPe,vPe,xPe,Gae=N(()=>{"use strict";qt();Wo();Bie();Vie();LR();PR();jR();dae();Mae();Oae();zae();Lc();o(G2,"layout");o(uPe,"runLayout");o(hPe,"updateInputGraph");fPe=["nodesep","edgesep","ranksep","marginx","marginy"],dPe={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},pPe=["acyclicer","ranker","rankdir","align"],mPe=["width","height"],gPe={width:0,height:0},yPe=["minlen","weight","width","height","labeloffset"],vPe={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},xPe=["labelpos"];o(bPe,"buildLayoutGraph");o(TPe,"makeSpaceForEdgeLabels");o(wPe,"injectEdgeLabelProxies");o(kPe,"assignRankMinMax");o(EPe,"removeEdgeLabelProxies");o(SPe,"translateGraph");o(CPe,"assignNodeIntersects");o(APe,"fixupEdgeLabelCoords");o(_Pe,"reversePointsForReversedEdges");o(DPe,"removeBorderNodes");o(LPe,"removeSelfEdges");o(RPe,"insertSelfEdges");o(NPe,"positionSelfEdges");o(QR,"selectNumberAttrs");o(ZR,"canonicalize")});var JR=N(()=>{"use strict";LR();Gae();PR();jR()});function qo(t){var e={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:MPe(t),edges:IPe(t)};return mr(t.graph())||(e.value=an(t.graph())),e}function MPe(t){return Je(t.nodes(),function(e){var r=t.node(e),n=t.parent(e),i={v:e};return mr(r)||(i.value=r),mr(n)||(i.parent=n),i})}function IPe(t){return Je(t.edges(),function(e){var r=t.edge(e),n={v:e.v,w:e.w};return mr(e.name)||(n.name=e.name),mr(r)||(n.value=r),n})}var eN=N(()=>{"use strict";qt();hk();o(qo,"write");o(MPe,"writeNodes");o(IPe,"writeEdges")});var Tr,tp,Hae,Wae,vk,OPe,qae,Yae,PPe,Ym,Uae,Xae,jae,Kae,Qae,Zae=N(()=>{"use strict";yt();Wo();eN();Tr=new Map,tp=new Map,Hae=new Map,Wae=o(()=>{tp.clear(),Hae.clear(),Tr.clear()},"clear"),vk=o((t,e)=>{let r=tp.get(e)||[];return X.trace("In isDescendant",e," ",t," = ",r.includes(t)),r.includes(t)},"isDescendant"),OPe=o((t,e)=>{let r=tp.get(e)||[];return X.info("Descendants of ",e," is ",r),X.info("Edge is ",t),t.v===e||t.w===e?!1:r?r.includes(t.v)||vk(t.v,e)||vk(t.w,e)||r.includes(t.w):(X.debug("Tilt, ",e,",not in descendants"),!1)},"edgeInCluster"),qae=o((t,e,r,n)=>{X.warn("Copying children of ",t,"root",n,"data",e.node(t),n);let i=e.children(t)||[];t!==n&&i.push(t),X.warn("Copying (nodes) clusterId",t,"nodes",i),i.forEach(a=>{if(e.children(a).length>0)qae(a,e,r,n);else{let s=e.node(a);X.info("cp ",a," to ",n," with parent ",t),r.setNode(a,s),n!==e.parent(a)&&(X.warn("Setting parent",a,e.parent(a)),r.setParent(a,e.parent(a))),t!==n&&a!==t?(X.debug("Setting parent",a,t),r.setParent(a,t)):(X.info("In copy ",t,"root",n,"data",e.node(t),n),X.debug("Not Setting parent for node=",a,"cluster!==rootId",t!==n,"node!==clusterId",a!==t));let l=e.edges(a);X.debug("Copying Edges",l),l.forEach(u=>{X.info("Edge",u);let h=e.edge(u.v,u.w,u.name);X.info("Edge data",h,n);try{OPe(u,n)?(X.info("Copying as ",u.v,u.w,h,u.name),r.setEdge(u.v,u.w,h,u.name),X.info("newGraph edges ",r.edges(),r.edge(r.edges()[0]))):X.info("Skipping copy of edge ",u.v,"-->",u.w," rootId: ",n," clusterId:",t)}catch(f){X.error(f)}})}X.debug("Removing node",a),e.removeNode(a)})},"copy"),Yae=o((t,e)=>{let r=e.children(t),n=[...r];for(let i of r)Hae.set(i,t),n=[...n,...Yae(i,e)];return n},"extractDescendants"),PPe=o((t,e,r)=>{let n=t.edges().filter(u=>u.v===e||u.w===e),i=t.edges().filter(u=>u.v===r||u.w===r),a=n.map(u=>({v:u.v===e?r:u.v,w:u.w===e?e:u.w})),s=i.map(u=>({v:u.v,w:u.w}));return a.filter(u=>s.some(h=>u.v===h.v&&u.w===h.w))},"findCommonEdges"),Ym=o((t,e,r)=>{let n=e.children(t);if(X.trace("Searching children of id ",t,n),n.length<1)return t;let i;for(let a of n){let s=Ym(a,e,r),l=PPe(e,r,s);if(s)if(l.length>0)i=s;else return s}return i},"findNonClusterChild"),Uae=o(t=>!Tr.has(t)||!Tr.get(t).externalConnections?t:Tr.has(t)?Tr.get(t).id:t,"getAnchorId"),Xae=o((t,e)=>{if(!t||e>10){X.debug("Opting out, no graph ");return}else X.debug("Opting in, graph ");t.nodes().forEach(function(r){t.children(r).length>0&&(X.warn("Cluster identified",r," Replacement id in edges: ",Ym(r,t,r)),tp.set(r,Yae(r,t)),Tr.set(r,{id:Ym(r,t,r),clusterData:t.node(r)}))}),t.nodes().forEach(function(r){let n=t.children(r),i=t.edges();n.length>0?(X.debug("Cluster identified",r,tp),i.forEach(a=>{let s=vk(a.v,r),l=vk(a.w,r);s^l&&(X.warn("Edge: ",a," leaves cluster ",r),X.warn("Descendants of XXX ",r,": ",tp.get(r)),Tr.get(r).externalConnections=!0)})):X.debug("Not a cluster ",r,tp)});for(let r of Tr.keys()){let n=Tr.get(r).id,i=t.parent(n);i!==r&&Tr.has(i)&&!Tr.get(i).externalConnections&&(Tr.get(r).id=i)}t.edges().forEach(function(r){let n=t.edge(r);X.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(r)),X.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(t.edge(r)));let i=r.v,a=r.w;if(X.warn("Fix XXX",Tr,"ids:",r.v,r.w,"Translating: ",Tr.get(r.v)," --- ",Tr.get(r.w)),Tr.get(r.v)||Tr.get(r.w)){if(X.warn("Fixing and trying - removing XXX",r.v,r.w,r.name),i=Uae(r.v),a=Uae(r.w),t.removeEdge(r.v,r.w,r.name),i!==r.v){let s=t.parent(i);Tr.get(s).externalConnections=!0,n.fromCluster=r.v}if(a!==r.w){let s=t.parent(a);Tr.get(s).externalConnections=!0,n.toCluster=r.w}X.warn("Fix Replacing with XXX",i,a,r.name),t.setEdge(i,a,n,r.name)}}),X.warn("Adjusted Graph",qo(t)),jae(t,0),X.trace(Tr)},"adjustClustersAndEdges"),jae=o((t,e)=>{if(X.warn("extractor - ",e,qo(t),t.children("D")),e>10){X.error("Bailing out");return}let r=t.nodes(),n=!1;for(let i of r){let a=t.children(i);n=n||a.length>0}if(!n){X.debug("Done, no node has children",t.nodes());return}X.debug("Nodes = ",r,e);for(let i of r)if(X.debug("Extracting node",i,Tr,Tr.has(i)&&!Tr.get(i).externalConnections,!t.parent(i),t.node(i),t.children("D")," Depth ",e),!Tr.has(i))X.debug("Not a cluster",i,e);else if(!Tr.get(i).externalConnections&&t.children(i)&&t.children(i).length>0){X.warn("Cluster without external connections, without a parent and with children",i,e);let s=t.graph().rankdir==="TB"?"LR":"TB";Tr.get(i)?.clusterData?.dir&&(s=Tr.get(i).clusterData.dir,X.warn("Fixing dir",Tr.get(i).clusterData.dir,s));let l=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:s,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});X.warn("Old graph before copy",qo(t)),qae(i,t,l,i),t.setNode(i,{clusterNode:!0,id:i,clusterData:Tr.get(i).clusterData,label:Tr.get(i).label,graph:l}),X.warn("New graph after copy node: (",i,")",qo(l)),X.debug("Old graph after copy",qo(t))}else X.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!Tr.get(i).externalConnections," no parent: ",!t.parent(i)," children ",t.children(i)&&t.children(i).length>0,t.children("D"),e),X.debug(Tr);r=t.nodes(),X.warn("New list of nodes",r);for(let i of r){let a=t.node(i);X.warn(" Now next level",i,a),a?.clusterNode&&jae(a.graph,e+1)}},"extractor"),Kae=o((t,e)=>{if(e.length===0)return[];let r=Object.assign([],e);return e.forEach(n=>{let i=t.children(n),a=Kae(t,i);r=[...r,...a]}),r},"sorter"),Qae=o(t=>Kae(t,t.children()),"sortNodesByHierarchy")});var ese={};ur(ese,{render:()=>BPe});var Jae,BPe,tse=N(()=>{"use strict";JR();eN();Wo();FL();Ft();Zae();mw();aw();BL();yt();R2();Gt();Jae=o(async(t,e,r,n,i,a)=>{X.warn("Graph in recursive render:XAX",qo(e),i);let s=e.graph().rankdir;X.trace("Dir in recursive render - dir:",s);let l=t.insert("g").attr("class","root");e.nodes()?X.info("Recursive render XXX",e.nodes()):X.info("No nodes found for",e),e.edges().length>0&&X.info("Recursive edges",e.edge(e.edges()[0]));let u=l.insert("g").attr("class","clusters"),h=l.insert("g").attr("class","edgePaths"),f=l.insert("g").attr("class","edgeLabels"),d=l.insert("g").attr("class","nodes");await Promise.all(e.nodes().map(async function(y){let v=e.node(y);if(i!==void 0){let x=JSON.parse(JSON.stringify(i.clusterData));X.trace(`Setting data for parent cluster XXX + Node.id = `,y,` + data=`,x.height,` +Parent cluster`,i.height),e.setNode(i.id,x),e.parent(y)||(X.trace("Setting parent",y,i.id),e.setParent(y,i.id,x))}if(X.info("(Insert) Node XXX"+y+": "+JSON.stringify(e.node(y))),v?.clusterNode){X.info("Cluster identified XBX",y,v.width,e.node(y));let{ranksep:x,nodesep:b}=e.graph();v.graph.setGraph({...v.graph.graph(),ranksep:x+25,nodesep:b});let T=await Jae(d,v.graph,r,n,e.node(y),a),S=T.elem;Ke(v,S),v.diff=T.diff||0,X.info("New compound node after recursive render XAX",y,"width",v.width,"height",v.height),vee(S,v)}else e.children(y).length>0?(X.trace("Cluster - the non recursive path XBX",y,v.id,v,v.width,"Graph:",e),X.trace(Ym(v.id,e)),Tr.set(v.id,{id:Ym(v.id,e),node:v})):(X.trace("Node - the non recursive path XAX",y,d,e.node(y),s),await Am(d,e.node(y),{config:a,dir:s}))})),await o(async()=>{let y=e.edges().map(async function(v){let x=e.edge(v.v,v.w,v.name);X.info("Edge "+v.v+" -> "+v.w+": "+JSON.stringify(v)),X.info("Edge "+v.v+" -> "+v.w+": ",v," ",JSON.stringify(e.edge(v))),X.info("Fix",Tr,"ids:",v.v,v.w,"Translating: ",Tr.get(v.v),Tr.get(v.w)),await uw(f,x)});await Promise.all(y)},"processEdges")(),X.info("Graph before layout:",JSON.stringify(qo(e))),X.info("############################################# XXX"),X.info("### Layout ### XXX"),X.info("############################################# XXX"),G2(e),X.info("Graph after layout:",JSON.stringify(qo(e)));let m=0,{subGraphTitleTotalMargin:g}=Bu(a);return await Promise.all(Qae(e).map(async function(y){let v=e.node(y);if(X.info("Position XBX => "+y+": ("+v.x,","+v.y,") width: ",v.width," height: ",v.height),v?.clusterNode)v.y+=g,X.info("A tainted cluster node XBX1",y,v.id,v.width,v.height,v.x,v.y,e.parent(y)),Tr.get(v.id).node=v,M2(v);else if(e.children(y).length>0){X.info("A pure cluster node XBX1",y,v.id,v.x,v.y,v.width,v.height,e.parent(y)),v.height+=g,e.node(v.parentId);let x=v?.padding/2||0,b=v?.labelBBox?.height||0,T=b-x||0;X.debug("OffsetY",T,"labelHeight",b,"halfPadding",x),await Cm(u,v),Tr.get(v.id).node=v}else{let x=e.node(v.parentId);v.y+=g/2,X.info("A regular node XBX1 - using the padding",v.id,"parent",v.parentId,v.width,v.height,v.x,v.y,"offsetY",v.offsetY,"parent",x,x?.offsetY,v),M2(v)}})),e.edges().forEach(function(y){let v=e.edge(y);X.info("Edge "+y.v+" -> "+y.w+": "+JSON.stringify(v),v),v.points.forEach(S=>S.y+=g/2);let x=e.node(y.v);var b=e.node(y.w);let T=fw(h,v,Tr,r,x,b,n);hw(v,T)}),e.nodes().forEach(function(y){let v=e.node(y);X.info(y,v.type,v.diff),v.isGroup&&(m=v.diff)}),X.warn("Returning from recursive render XAX",l,m),{elem:l,diff:m}},"recursiveRender"),BPe=o(async(t,e)=>{let r=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:t.direction,nodesep:t.config?.nodeSpacing||t.config?.flowchart?.nodeSpacing||t.nodeSpacing,ranksep:t.config?.rankSpacing||t.config?.flowchart?.rankSpacing||t.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),n=e.select("g");dw(n,t.markers,t.type,t.diagramId),xee(),yee(),hee(),Wae(),t.nodes.forEach(a=>{r.setNode(a.id,{...a}),a.parentId&&r.setParent(a.id,a.parentId)}),X.debug("Edges:",t.edges),t.edges.forEach(a=>{if(a.start===a.end){let s=a.start,l=s+"---"+s+"---1",u=s+"---"+s+"---2",h=r.node(s);r.setNode(l,{domId:l,id:l,parentId:h.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),r.setParent(l,h.parentId),r.setNode(u,{domId:u,id:u,parentId:h.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),r.setParent(u,h.parentId);let f=structuredClone(a),d=structuredClone(a),p=structuredClone(a);f.label="",f.arrowTypeEnd="none",f.id=s+"-cyclic-special-1",d.arrowTypeStart="none",d.arrowTypeEnd="none",d.id=s+"-cyclic-special-mid",p.label="",h.isGroup&&(f.fromCluster=s,p.toCluster=s),p.id=s+"-cyclic-special-2",p.arrowTypeStart="none",r.setEdge(s,l,f,s+"-cyclic-special-0"),r.setEdge(l,u,d,s+"-cyclic-special-1"),r.setEdge(u,s,p,s+"-cyc{"use strict";Tee();yt();V2={},tN=o(t=>{for(let e of t)V2[e.name]=e},"registerLayoutLoaders"),FPe=o(()=>{tN([{name:"dagre",loader:o(async()=>await Promise.resolve().then(()=>(tse(),ese)),"loader")}])},"registerDefaultLayoutLoaders");FPe();Rc=o(async(t,e)=>{if(!(t.layoutAlgorithm in V2))throw new Error(`Unknown layout algorithm: ${t.layoutAlgorithm}`);let r=V2[t.layoutAlgorithm];return(await r.loader()).render(t,e,bee,{algorithm:r.algorithm})},"render"),uf=o((t="",{fallback:e="dagre"}={})=>{if(t in V2)return t;if(e in V2)return X.warn(`Layout algorithm ${t} is not registered. Using ${e} as fallback.`),e;throw new Error(`Both layout algorithms ${t} and ${e} are not registered.`)},"getRegisteredLayoutAlgorithm")});var Yo,$Pe,zPe,np=N(()=>{"use strict";xi();yt();Yo=o((t,e,r,n)=>{t.attr("class",r);let{width:i,height:a,x:s,y:l}=$Pe(t,e);fn(t,a,i,n);let u=zPe(s,l,i,a,e);t.attr("viewBox",u),X.debug(`viewBox configured: ${u} with padding: ${e}`)},"setupViewPortForSVG"),$Pe=o((t,e)=>{let r=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:r.width+e*2,height:r.height+e*2,x:r.x,y:r.y}},"calculateDimensionsWithPadding"),zPe=o((t,e,r,n,i)=>`${t-i} ${e-i} ${r} ${n}`,"createViewBox")});var GPe,VPe,rse,nse=N(()=>{"use strict";fr();Gt();yt();Sm();rp();np();er();GPe=o(function(t,e){return e.db.getClasses()},"getClasses"),VPe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing state diagram (v2)",e);let{securityLevel:i,flowchart:a,layout:s}=me(),l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?l.nodes()[0].contentDocument:document;X.debug("Before getData: ");let h=n.db.getData();X.debug("Data: ",h);let f=wc(e,i),d=n.db.getDirection();h.type=n.type,h.layoutAlgorithm=uf(s),h.layoutAlgorithm==="dagre"&&s==="elk"&&X.warn("flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0) for more details. This diagram will be rendered using `dagre` layout as a fallback."),h.direction=d,h.nodeSpacing=a?.nodeSpacing||50,h.rankSpacing=a?.rankSpacing||50,h.markers=["point","circle","cross"],h.diagramId=e,X.debug("REF1:",h),await Rc(h,f);let p=h.config.flowchart?.diagramPadding??8;Vt.insertTitle(f,"flowchartTitleText",a?.titleTopMargin||0,n.db.getDiagramTitle()),Yo(f,p,"flowchart",a?.useMaxWidth||!1);for(let m of h.nodes){let g=Ge(`#${e} [id="${m.id}"]`);if(!g||!m.link)continue;let y=u.createElementNS("http://www.w3.org/2000/svg","a");y.setAttributeNS("http://www.w3.org/2000/svg","class",m.cssClasses),y.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),i==="sandbox"?y.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):m.linkTarget&&y.setAttributeNS("http://www.w3.org/2000/svg","target",m.linkTarget);let v=g.insert(function(){return y},":first-child"),x=g.select(".label-container");x&&v.append(function(){return x.node()});let b=g.select(".label");b&&v.append(function(){return b.node()})}},"draw"),rse={getClasses:GPe,draw:VPe}});var rN,nN,ise=N(()=>{"use strict";rN=function(){var t=o(function(Hr,et,gt,Kt){for(gt=gt||{},Kt=Hr.length;Kt--;gt[Hr[Kt]]=et);return gt},"o"),e=[1,4],r=[1,3],n=[1,5],i=[1,8,9,10,11,27,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],a=[2,2],s=[1,13],l=[1,14],u=[1,15],h=[1,16],f=[1,23],d=[1,25],p=[1,26],m=[1,27],g=[1,49],y=[1,48],v=[1,29],x=[1,30],b=[1,31],T=[1,32],S=[1,33],w=[1,44],E=[1,46],_=[1,42],C=[1,47],D=[1,43],O=[1,50],R=[1,45],k=[1,51],L=[1,52],A=[1,34],I=[1,35],M=[1,36],P=[1,37],B=[1,57],F=[1,8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],z=[1,61],$=[1,60],U=[1,62],K=[8,9,11,75,77,78],ee=[1,78],Y=[1,91],ce=[1,96],Z=[1,95],ue=[1,92],Q=[1,88],j=[1,94],ne=[1,90],te=[1,97],he=[1,93],le=[1,98],J=[1,89],Se=[8,9,10,11,40,75,77,78],se=[8,9,10,11,40,46,75,77,78],ae=[8,9,10,11,29,40,44,46,48,50,52,54,56,58,60,63,65,67,68,70,75,77,78,89,102,105,106,109,111,114,115,116],Oe=[8,9,11,44,60,75,77,78,89,102,105,106,109,111,114,115,116],ye=[44,60,89,102,105,106,109,111,114,115,116],Be=[1,121],He=[1,122],ze=[1,124],Le=[1,123],Ie=[44,60,62,74,89,102,105,106,109,111,114,115,116],xe=[1,133],q=[1,147],de=[1,148],ie=[1,149],oe=[1,150],V=[1,135],Te=[1,137],W=[1,141],pe=[1,142],ve=[1,143],Pe=[1,144],_e=[1,145],be=[1,146],Ve=[1,151],De=[1,152],qe=[1,131],at=[1,132],Rt=[1,139],st=[1,134],Ue=[1,138],ct=[1,136],We=[8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],ot=[1,154],Yt=[1,156],Tt=[8,9,11],Mt=[8,9,10,11,14,44,60,89,105,106,109,111,114,115,116],bt=[1,176],ut=[1,172],St=[1,173],ft=[1,177],vt=[1,174],nt=[1,175],pn=[77,116,119],kt=[8,9,10,11,12,14,27,29,32,44,60,75,84,85,86,87,88,89,90,105,109,111,114,115,116],On=[10,106],tn=[31,49,51,53,55,57,62,64,66,67,69,71,116,117,118],Mr=[1,247],Ir=[1,245],Pn=[1,249],Dt=[1,243],Ce=[1,244],tt=[1,246],Ct=[1,248],gr=[1,250],rn=[1,268],yn=[8,9,11,106],Zr=[8,9,10,11,60,84,105,106,109,110,111,112],Oi={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,shapeData:39,SHAPE_DATA:40,link:41,node:42,styledVertex:43,AMP:44,vertex:45,STYLE_SEPARATOR:46,idString:47,DOUBLECIRCLESTART:48,DOUBLECIRCLEEND:49,PS:50,PE:51,"(-":52,"-)":53,STADIUMSTART:54,STADIUMEND:55,SUBROUTINESTART:56,SUBROUTINEEND:57,VERTEX_WITH_PROPS_START:58,"NODE_STRING[field]":59,COLON:60,"NODE_STRING[value]":61,PIPE:62,CYLINDERSTART:63,CYLINDEREND:64,DIAMOND_START:65,DIAMOND_STOP:66,TAGEND:67,TRAPSTART:68,TRAPEND:69,INVTRAPSTART:70,INVTRAPEND:71,linkStatement:72,arrowText:73,TESTSTR:74,START_LINK:75,edgeText:76,LINK:77,LINK_ID:78,edgeTextToken:79,STR:80,MD_STR:81,textToken:82,keywords:83,STYLE:84,LINKSTYLE:85,CLASSDEF:86,CLASS:87,CLICK:88,DOWN:89,UP:90,textNoTagsToken:91,stylesOpt:92,"idString[vertex]":93,"idString[class]":94,CALLBACKNAME:95,CALLBACKARGS:96,HREF:97,LINK_TARGET:98,"STR[link]":99,"STR[tooltip]":100,alphaNum:101,DEFAULT:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,NODE_STRING:109,UNIT:110,BRKT:111,PCT:112,idStringToken:113,MINUS:114,MULT:115,UNICODE_TEXT:116,TEXT:117,TAGSTART:118,EDGE_TEXT:119,alphaNumToken:120,direction_tb:121,direction_bt:122,direction_rl:123,direction_lr:124,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",40:"SHAPE_DATA",44:"AMP",46:"STYLE_SEPARATOR",48:"DOUBLECIRCLESTART",49:"DOUBLECIRCLEEND",50:"PS",51:"PE",52:"(-",53:"-)",54:"STADIUMSTART",55:"STADIUMEND",56:"SUBROUTINESTART",57:"SUBROUTINEEND",58:"VERTEX_WITH_PROPS_START",59:"NODE_STRING[field]",60:"COLON",61:"NODE_STRING[value]",62:"PIPE",63:"CYLINDERSTART",64:"CYLINDEREND",65:"DIAMOND_START",66:"DIAMOND_STOP",67:"TAGEND",68:"TRAPSTART",69:"TRAPEND",70:"INVTRAPSTART",71:"INVTRAPEND",74:"TESTSTR",75:"START_LINK",77:"LINK",78:"LINK_ID",80:"STR",81:"MD_STR",84:"STYLE",85:"LINKSTYLE",86:"CLASSDEF",87:"CLASS",88:"CLICK",89:"DOWN",90:"UP",93:"idString[vertex]",94:"idString[class]",95:"CALLBACKNAME",96:"CALLBACKARGS",97:"HREF",98:"LINK_TARGET",99:"STR[link]",100:"STR[tooltip]",102:"DEFAULT",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"NODE_STRING",110:"UNIT",111:"BRKT",112:"PCT",114:"MINUS",115:"MULT",116:"UNICODE_TEXT",117:"TEXT",118:"TAGSTART",119:"EDGE_TEXT",121:"direction_tb",122:"direction_bt",123:"direction_rl",124:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[39,2],[39,1],[20,4],[20,3],[20,4],[20,2],[20,2],[20,1],[42,1],[42,6],[42,5],[43,1],[43,3],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,8],[45,4],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,4],[45,4],[45,1],[41,2],[41,3],[41,3],[41,1],[41,3],[41,4],[76,1],[76,2],[76,1],[76,1],[72,1],[72,2],[73,3],[30,1],[30,2],[30,1],[30,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[103,1],[103,3],[92,1],[92,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[82,1],[82,1],[82,1],[82,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[79,1],[79,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[47,1],[47,2],[101,1],[101,2],[33,1],[33,1],[33,1],[33,1]],performAction:o(function(et,gt,Kt,lt,Cn,ge,Qf){var we=ge.length-1;switch(Cn){case 2:this.$=[];break;case 3:(!Array.isArray(ge[we])||ge[we].length>0)&&ge[we-1].push(ge[we]),this.$=ge[we-1];break;case 4:case 183:this.$=ge[we];break;case 11:lt.setDirection("TB"),this.$="TB";break;case 12:lt.setDirection(ge[we-1]),this.$=ge[we-1];break;case 27:this.$=ge[we-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=lt.addSubGraph(ge[we-6],ge[we-1],ge[we-4]);break;case 34:this.$=lt.addSubGraph(ge[we-3],ge[we-1],ge[we-3]);break;case 35:this.$=lt.addSubGraph(void 0,ge[we-1],void 0);break;case 37:this.$=ge[we].trim(),lt.setAccTitle(this.$);break;case 38:case 39:this.$=ge[we].trim(),lt.setAccDescription(this.$);break;case 43:this.$=ge[we-1]+ge[we];break;case 44:this.$=ge[we];break;case 45:lt.addVertex(ge[we-1][ge[we-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we]),lt.addLink(ge[we-3].stmt,ge[we-1],ge[we-2]),this.$={stmt:ge[we-1],nodes:ge[we-1].concat(ge[we-3].nodes)};break;case 46:lt.addLink(ge[we-2].stmt,ge[we],ge[we-1]),this.$={stmt:ge[we],nodes:ge[we].concat(ge[we-2].nodes)};break;case 47:lt.addLink(ge[we-3].stmt,ge[we-1],ge[we-2]),this.$={stmt:ge[we-1],nodes:ge[we-1].concat(ge[we-3].nodes)};break;case 48:this.$={stmt:ge[we-1],nodes:ge[we-1]};break;case 49:lt.addVertex(ge[we-1][ge[we-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we]),this.$={stmt:ge[we-1],nodes:ge[we-1],shapeData:ge[we]};break;case 50:this.$={stmt:ge[we],nodes:ge[we]};break;case 51:this.$=[ge[we]];break;case 52:lt.addVertex(ge[we-5][ge[we-5].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we-4]),this.$=ge[we-5].concat(ge[we]);break;case 53:this.$=ge[we-4].concat(ge[we]);break;case 54:this.$=ge[we];break;case 55:this.$=ge[we-2],lt.setClass(ge[we-2],ge[we]);break;case 56:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"square");break;case 57:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"doublecircle");break;case 58:this.$=ge[we-5],lt.addVertex(ge[we-5],ge[we-2],"circle");break;case 59:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"ellipse");break;case 60:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"stadium");break;case 61:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"subroutine");break;case 62:this.$=ge[we-7],lt.addVertex(ge[we-7],ge[we-1],"rect",void 0,void 0,void 0,Object.fromEntries([[ge[we-5],ge[we-3]]]));break;case 63:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"cylinder");break;case 64:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"round");break;case 65:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"diamond");break;case 66:this.$=ge[we-5],lt.addVertex(ge[we-5],ge[we-2],"hexagon");break;case 67:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"odd");break;case 68:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"trapezoid");break;case 69:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"inv_trapezoid");break;case 70:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"lean_right");break;case 71:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"lean_left");break;case 72:this.$=ge[we],lt.addVertex(ge[we]);break;case 73:ge[we-1].text=ge[we],this.$=ge[we-1];break;case 74:case 75:ge[we-2].text=ge[we-1],this.$=ge[we-2];break;case 76:this.$=ge[we];break;case 77:var Ei=lt.destructLink(ge[we],ge[we-2]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,text:ge[we-1]};break;case 78:var Ei=lt.destructLink(ge[we],ge[we-2]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,text:ge[we-1],id:ge[we-3]};break;case 79:this.$={text:ge[we],type:"text"};break;case 80:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 81:this.$={text:ge[we],type:"string"};break;case 82:this.$={text:ge[we],type:"markdown"};break;case 83:var Ei=lt.destructLink(ge[we]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length};break;case 84:var Ei=lt.destructLink(ge[we]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,id:ge[we-1]};break;case 85:this.$=ge[we-1];break;case 86:this.$={text:ge[we],type:"text"};break;case 87:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 88:this.$={text:ge[we],type:"string"};break;case 89:case 104:this.$={text:ge[we],type:"markdown"};break;case 101:this.$={text:ge[we],type:"text"};break;case 102:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 103:this.$={text:ge[we],type:"text"};break;case 105:this.$=ge[we-4],lt.addClass(ge[we-2],ge[we]);break;case 106:this.$=ge[we-4],lt.setClass(ge[we-2],ge[we]);break;case 107:case 115:this.$=ge[we-1],lt.setClickEvent(ge[we-1],ge[we]);break;case 108:case 116:this.$=ge[we-3],lt.setClickEvent(ge[we-3],ge[we-2]),lt.setTooltip(ge[we-3],ge[we]);break;case 109:this.$=ge[we-2],lt.setClickEvent(ge[we-2],ge[we-1],ge[we]);break;case 110:this.$=ge[we-4],lt.setClickEvent(ge[we-4],ge[we-3],ge[we-2]),lt.setTooltip(ge[we-4],ge[we]);break;case 111:this.$=ge[we-2],lt.setLink(ge[we-2],ge[we]);break;case 112:this.$=ge[we-4],lt.setLink(ge[we-4],ge[we-2]),lt.setTooltip(ge[we-4],ge[we]);break;case 113:this.$=ge[we-4],lt.setLink(ge[we-4],ge[we-2],ge[we]);break;case 114:this.$=ge[we-6],lt.setLink(ge[we-6],ge[we-4],ge[we]),lt.setTooltip(ge[we-6],ge[we-2]);break;case 117:this.$=ge[we-1],lt.setLink(ge[we-1],ge[we]);break;case 118:this.$=ge[we-3],lt.setLink(ge[we-3],ge[we-2]),lt.setTooltip(ge[we-3],ge[we]);break;case 119:this.$=ge[we-3],lt.setLink(ge[we-3],ge[we-2],ge[we]);break;case 120:this.$=ge[we-5],lt.setLink(ge[we-5],ge[we-4],ge[we]),lt.setTooltip(ge[we-5],ge[we-2]);break;case 121:this.$=ge[we-4],lt.addVertex(ge[we-2],void 0,void 0,ge[we]);break;case 122:this.$=ge[we-4],lt.updateLink([ge[we-2]],ge[we]);break;case 123:this.$=ge[we-4],lt.updateLink(ge[we-2],ge[we]);break;case 124:this.$=ge[we-8],lt.updateLinkInterpolate([ge[we-6]],ge[we-2]),lt.updateLink([ge[we-6]],ge[we]);break;case 125:this.$=ge[we-8],lt.updateLinkInterpolate(ge[we-6],ge[we-2]),lt.updateLink(ge[we-6],ge[we]);break;case 126:this.$=ge[we-6],lt.updateLinkInterpolate([ge[we-4]],ge[we]);break;case 127:this.$=ge[we-6],lt.updateLinkInterpolate(ge[we-4],ge[we]);break;case 128:case 130:this.$=[ge[we]];break;case 129:case 131:ge[we-2].push(ge[we]),this.$=ge[we-2];break;case 133:this.$=ge[we-1]+ge[we];break;case 181:this.$=ge[we];break;case 182:this.$=ge[we-1]+""+ge[we];break;case 184:this.$=ge[we-1]+""+ge[we];break;case 185:this.$={stmt:"dir",value:"TB"};break;case 186:this.$={stmt:"dir",value:"BT"};break;case 187:this.$={stmt:"dir",value:"RL"};break;case 188:this.$={stmt:"dir",value:"LR"};break}},"anonymous"),table:[{3:1,4:2,9:e,10:r,12:n},{1:[3]},t(i,a,{5:6}),{4:7,9:e,10:r,12:n},{4:8,9:e,10:r,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:B,15:53,18:56},t(F,[2,3]),t(F,[2,4]),t(F,[2,5]),t(F,[2,6]),t(F,[2,7]),t(F,[2,8]),{8:z,9:$,11:U,21:58,41:59,72:63,75:[1,64],77:[1,66],78:[1,65]},{8:z,9:$,11:U,21:67},{8:z,9:$,11:U,21:68},{8:z,9:$,11:U,21:69},{8:z,9:$,11:U,21:70},{8:z,9:$,11:U,21:71},{8:z,9:$,10:[1,72],11:U,21:73},t(F,[2,36]),{35:[1,74]},{37:[1,75]},t(F,[2,39]),t(K,[2,50],{18:76,39:77,10:B,40:ee}),{10:[1,79]},{10:[1,80]},{10:[1,81]},{10:[1,82]},{14:Y,44:ce,60:Z,80:[1,86],89:ue,95:[1,83],97:[1,84],101:85,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},t(F,[2,185]),t(F,[2,186]),t(F,[2,187]),t(F,[2,188]),t(Se,[2,51]),t(Se,[2,54],{46:[1,99]}),t(se,[2,72],{113:112,29:[1,100],44:g,48:[1,101],50:[1,102],52:[1,103],54:[1,104],56:[1,105],58:[1,106],60:y,63:[1,107],65:[1,108],67:[1,109],68:[1,110],70:[1,111],89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),t(ae,[2,181]),t(ae,[2,142]),t(ae,[2,143]),t(ae,[2,144]),t(ae,[2,145]),t(ae,[2,146]),t(ae,[2,147]),t(ae,[2,148]),t(ae,[2,149]),t(ae,[2,150]),t(ae,[2,151]),t(ae,[2,152]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,113]},t(Oe,[2,26],{18:114,10:B}),t(F,[2,27]),{42:115,43:38,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(F,[2,40]),t(F,[2,41]),t(F,[2,42]),t(ye,[2,76],{73:116,62:[1,118],74:[1,117]}),{76:119,79:120,80:Be,81:He,116:ze,119:Le},{75:[1,125],77:[1,126]},t(Ie,[2,83]),t(F,[2,28]),t(F,[2,29]),t(F,[2,30]),t(F,[2,31]),t(F,[2,32]),{10:xe,12:q,14:de,27:ie,28:127,32:oe,44:V,60:Te,75:W,80:[1,129],81:[1,130],83:140,84:pe,85:ve,86:Pe,87:_e,88:be,89:Ve,90:De,91:128,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(We,a,{5:153}),t(F,[2,37]),t(F,[2,38]),t(K,[2,48],{44:ot}),t(K,[2,49],{18:155,10:B,40:Yt}),t(Se,[2,44]),{44:g,47:157,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{102:[1,158],103:159,105:[1,160]},{44:g,47:161,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{44:g,47:162,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,107],{10:[1,163],96:[1,164]}),{80:[1,165]},t(Tt,[2,115],{120:167,10:[1,166],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,117],{10:[1,168]}),t(Mt,[2,183]),t(Mt,[2,170]),t(Mt,[2,171]),t(Mt,[2,172]),t(Mt,[2,173]),t(Mt,[2,174]),t(Mt,[2,175]),t(Mt,[2,176]),t(Mt,[2,177]),t(Mt,[2,178]),t(Mt,[2,179]),t(Mt,[2,180]),{44:g,47:169,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{30:170,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:178,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:180,50:[1,179],67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:181,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:182,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:183,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{109:[1,184]},{30:185,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:186,65:[1,187],67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:188,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:189,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:190,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(ae,[2,182]),t(i,[2,20]),t(Oe,[2,25]),t(K,[2,46],{39:191,18:192,10:B,40:ee}),t(ye,[2,73],{10:[1,193]}),{10:[1,194]},{30:195,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{77:[1,196],79:197,116:ze,119:Le},t(pn,[2,79]),t(pn,[2,81]),t(pn,[2,82]),t(pn,[2,168]),t(pn,[2,169]),{76:198,79:120,80:Be,81:He,116:ze,119:Le},t(Ie,[2,84]),{8:z,9:$,10:xe,11:U,12:q,14:de,21:200,27:ie,29:[1,199],32:oe,44:V,60:Te,75:W,83:140,84:pe,85:ve,86:Pe,87:_e,88:be,89:Ve,90:De,91:201,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(kt,[2,101]),t(kt,[2,103]),t(kt,[2,104]),t(kt,[2,157]),t(kt,[2,158]),t(kt,[2,159]),t(kt,[2,160]),t(kt,[2,161]),t(kt,[2,162]),t(kt,[2,163]),t(kt,[2,164]),t(kt,[2,165]),t(kt,[2,166]),t(kt,[2,167]),t(kt,[2,90]),t(kt,[2,91]),t(kt,[2,92]),t(kt,[2,93]),t(kt,[2,94]),t(kt,[2,95]),t(kt,[2,96]),t(kt,[2,97]),t(kt,[2,98]),t(kt,[2,99]),t(kt,[2,100]),{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,202],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},{10:B,18:203},{44:[1,204]},t(Se,[2,43]),{10:[1,205],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{10:[1,206]},{10:[1,207],106:[1,208]},t(On,[2,128]),{10:[1,209],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{10:[1,210],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{80:[1,211]},t(Tt,[2,109],{10:[1,212]}),t(Tt,[2,111],{10:[1,213]}),{80:[1,214]},t(Mt,[2,184]),{80:[1,215],98:[1,216]},t(Se,[2,55],{113:112,44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),{31:[1,217],67:bt,82:218,116:ft,117:vt,118:nt},t(tn,[2,86]),t(tn,[2,88]),t(tn,[2,89]),t(tn,[2,153]),t(tn,[2,154]),t(tn,[2,155]),t(tn,[2,156]),{49:[1,219],67:bt,82:218,116:ft,117:vt,118:nt},{30:220,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{51:[1,221],67:bt,82:218,116:ft,117:vt,118:nt},{53:[1,222],67:bt,82:218,116:ft,117:vt,118:nt},{55:[1,223],67:bt,82:218,116:ft,117:vt,118:nt},{57:[1,224],67:bt,82:218,116:ft,117:vt,118:nt},{60:[1,225]},{64:[1,226],67:bt,82:218,116:ft,117:vt,118:nt},{66:[1,227],67:bt,82:218,116:ft,117:vt,118:nt},{30:228,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{31:[1,229],67:bt,82:218,116:ft,117:vt,118:nt},{67:bt,69:[1,230],71:[1,231],82:218,116:ft,117:vt,118:nt},{67:bt,69:[1,233],71:[1,232],82:218,116:ft,117:vt,118:nt},t(K,[2,45],{18:155,10:B,40:Yt}),t(K,[2,47],{44:ot}),t(ye,[2,75]),t(ye,[2,74]),{62:[1,234],67:bt,82:218,116:ft,117:vt,118:nt},t(ye,[2,77]),t(pn,[2,80]),{77:[1,235],79:197,116:ze,119:Le},{30:236,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(We,a,{5:237}),t(kt,[2,102]),t(F,[2,35]),{43:238,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{10:B,18:239},{10:Mr,60:Ir,84:Pn,92:240,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:251,104:[1,252],105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:253,104:[1,254],105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{105:[1,255]},{10:Mr,60:Ir,84:Pn,92:256,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{44:g,47:257,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,108]),{80:[1,258]},{80:[1,259],98:[1,260]},t(Tt,[2,116]),t(Tt,[2,118],{10:[1,261]}),t(Tt,[2,119]),t(se,[2,56]),t(tn,[2,87]),t(se,[2,57]),{51:[1,262],67:bt,82:218,116:ft,117:vt,118:nt},t(se,[2,64]),t(se,[2,59]),t(se,[2,60]),t(se,[2,61]),{109:[1,263]},t(se,[2,63]),t(se,[2,65]),{66:[1,264],67:bt,82:218,116:ft,117:vt,118:nt},t(se,[2,67]),t(se,[2,68]),t(se,[2,70]),t(se,[2,69]),t(se,[2,71]),t([10,44,60,89,102,105,106,109,111,114,115,116],[2,85]),t(ye,[2,78]),{31:[1,265],67:bt,82:218,116:ft,117:vt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,266],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},t(Se,[2,53]),{43:267,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,121],{106:rn}),t(yn,[2,130],{108:269,10:Mr,60:Ir,84:Pn,105:Dt,109:Ce,110:tt,111:Ct,112:gr}),t(Zr,[2,132]),t(Zr,[2,134]),t(Zr,[2,135]),t(Zr,[2,136]),t(Zr,[2,137]),t(Zr,[2,138]),t(Zr,[2,139]),t(Zr,[2,140]),t(Zr,[2,141]),t(Tt,[2,122],{106:rn}),{10:[1,270]},t(Tt,[2,123],{106:rn}),{10:[1,271]},t(On,[2,129]),t(Tt,[2,105],{106:rn}),t(Tt,[2,106],{113:112,44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),t(Tt,[2,110]),t(Tt,[2,112],{10:[1,272]}),t(Tt,[2,113]),{98:[1,273]},{51:[1,274]},{62:[1,275]},{66:[1,276]},{8:z,9:$,11:U,21:277},t(F,[2,34]),t(Se,[2,52]),{10:Mr,60:Ir,84:Pn,105:Dt,107:278,108:242,109:Ce,110:tt,111:Ct,112:gr},t(Zr,[2,133]),{14:Y,44:ce,60:Z,89:ue,101:279,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},{14:Y,44:ce,60:Z,89:ue,101:280,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},{98:[1,281]},t(Tt,[2,120]),t(se,[2,58]),{30:282,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(se,[2,66]),t(We,a,{5:283}),t(yn,[2,131],{108:269,10:Mr,60:Ir,84:Pn,105:Dt,109:Ce,110:tt,111:Ct,112:gr}),t(Tt,[2,126],{120:167,10:[1,284],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,127],{120:167,10:[1,285],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,114]),{31:[1,286],67:bt,82:218,116:ft,117:vt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,287],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},{10:Mr,60:Ir,84:Pn,92:288,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:289,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},t(se,[2,62]),t(F,[2,33]),t(Tt,[2,124],{106:rn}),t(Tt,[2,125],{106:rn})],defaultActions:{},parseError:o(function(et,gt){if(gt.recoverable)this.trace(et);else{var Kt=new Error(et);throw Kt.hash=gt,Kt}},"parseError"),parse:o(function(et){var gt=this,Kt=[0],lt=[],Cn=[null],ge=[],Qf=this.table,we="",Ei=0,l$=0,c$=0,tbe=2,u$=1,rbe=ge.slice.call(arguments,1),ji=Object.create(this.lexer),Zf={yy:{}};for(var $C in this.yy)Object.prototype.hasOwnProperty.call(this.yy,$C)&&(Zf.yy[$C]=this.yy[$C]);ji.setInput(et,Zf.yy),Zf.yy.lexer=ji,Zf.yy.parser=this,typeof ji.yylloc>"u"&&(ji.yylloc={});var zC=ji.yylloc;ge.push(zC);var nbe=ji.options&&ji.options.ranges;typeof Zf.yy.parseError=="function"?this.parseError=Zf.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Qit(Xs){Kt.length=Kt.length-2*Xs,Cn.length=Cn.length-Xs,ge.length=ge.length-Xs}o(Qit,"popStack");function ibe(){var Xs;return Xs=lt.pop()||ji.lex()||u$,typeof Xs!="number"&&(Xs instanceof Array&&(lt=Xs,Xs=lt.pop()),Xs=gt.symbols_[Xs]||Xs),Xs}o(ibe,"lex");for(var Ka,GC,Jf,wo,Zit,VC,c0={},z4,nu,h$,G4;;){if(Jf=Kt[Kt.length-1],this.defaultActions[Jf]?wo=this.defaultActions[Jf]:((Ka===null||typeof Ka>"u")&&(Ka=ibe()),wo=Qf[Jf]&&Qf[Jf][Ka]),typeof wo>"u"||!wo.length||!wo[0]){var UC="";G4=[];for(z4 in Qf[Jf])this.terminals_[z4]&&z4>tbe&&G4.push("'"+this.terminals_[z4]+"'");ji.showPosition?UC="Parse error on line "+(Ei+1)+`: +`+ji.showPosition()+` +Expecting `+G4.join(", ")+", got '"+(this.terminals_[Ka]||Ka)+"'":UC="Parse error on line "+(Ei+1)+": Unexpected "+(Ka==u$?"end of input":"'"+(this.terminals_[Ka]||Ka)+"'"),this.parseError(UC,{text:ji.match,token:this.terminals_[Ka]||Ka,line:ji.yylineno,loc:zC,expected:G4})}if(wo[0]instanceof Array&&wo.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Jf+", token: "+Ka);switch(wo[0]){case 1:Kt.push(Ka),Cn.push(ji.yytext),ge.push(ji.yylloc),Kt.push(wo[1]),Ka=null,GC?(Ka=GC,GC=null):(l$=ji.yyleng,we=ji.yytext,Ei=ji.yylineno,zC=ji.yylloc,c$>0&&c$--);break;case 2:if(nu=this.productions_[wo[1]][1],c0.$=Cn[Cn.length-nu],c0._$={first_line:ge[ge.length-(nu||1)].first_line,last_line:ge[ge.length-1].last_line,first_column:ge[ge.length-(nu||1)].first_column,last_column:ge[ge.length-1].last_column},nbe&&(c0._$.range=[ge[ge.length-(nu||1)].range[0],ge[ge.length-1].range[1]]),VC=this.performAction.apply(c0,[we,l$,Ei,Zf.yy,wo[1],Cn,ge].concat(rbe)),typeof VC<"u")return VC;nu&&(Kt=Kt.slice(0,-1*nu*2),Cn=Cn.slice(0,-1*nu),ge=ge.slice(0,-1*nu)),Kt.push(this.productions_[wo[1]][0]),Cn.push(c0.$),ge.push(c0._$),h$=Qf[Kt[Kt.length-2]][Kt[Kt.length-1]],Kt.push(h$);break;case 3:return!0}}return!0},"parse")},ei=function(){var Hr={EOF:1,parseError:o(function(gt,Kt){if(this.yy.parser)this.yy.parser.parseError(gt,Kt);else throw new Error(gt)},"parseError"),setInput:o(function(et,gt){return this.yy=gt||this.yy||{},this._input=et,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var et=this._input[0];this.yytext+=et,this.yyleng++,this.offset++,this.match+=et,this.matched+=et;var gt=et.match(/(?:\r\n?|\n).*/g);return gt?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),et},"input"),unput:o(function(et){var gt=et.length,Kt=et.split(/(?:\r\n?|\n)/g);this._input=et+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-gt),this.offset-=gt;var lt=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Kt.length-1&&(this.yylineno-=Kt.length-1);var Cn=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Kt?(Kt.length===lt.length?this.yylloc.first_column:0)+lt[lt.length-Kt.length].length-Kt[0].length:this.yylloc.first_column-gt},this.options.ranges&&(this.yylloc.range=[Cn[0],Cn[0]+this.yyleng-gt]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(et){this.unput(this.match.slice(et))},"less"),pastInput:o(function(){var et=this.matched.substr(0,this.matched.length-this.match.length);return(et.length>20?"...":"")+et.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var et=this.match;return et.length<20&&(et+=this._input.substr(0,20-et.length)),(et.substr(0,20)+(et.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var et=this.pastInput(),gt=new Array(et.length+1).join("-");return et+this.upcomingInput()+` +`+gt+"^"},"showPosition"),test_match:o(function(et,gt){var Kt,lt,Cn;if(this.options.backtrack_lexer&&(Cn={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(Cn.yylloc.range=this.yylloc.range.slice(0))),lt=et[0].match(/(?:\r\n?|\n).*/g),lt&&(this.yylineno+=lt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:lt?lt[lt.length-1].length-lt[lt.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+et[0].length},this.yytext+=et[0],this.match+=et[0],this.matches=et,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(et[0].length),this.matched+=et[0],Kt=this.performAction.call(this,this.yy,this,gt,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Kt)return Kt;if(this._backtrack){for(var ge in Cn)this[ge]=Cn[ge];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var et,gt,Kt,lt;this._more||(this.yytext="",this.match="");for(var Cn=this._currentRules(),ge=0;gegt[0].length)){if(gt=Kt,lt=ge,this.options.backtrack_lexer){if(et=this.test_match(Kt,Cn[ge]),et!==!1)return et;if(this._backtrack){gt=!1;continue}else return!1}else if(!this.options.flex)break}return gt?(et=this.test_match(gt,Cn[lt]),et!==!1?et:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var gt=this.next();return gt||this.lex()},"lex"),begin:o(function(gt){this.conditionStack.push(gt)},"begin"),popState:o(function(){var gt=this.conditionStack.length-1;return gt>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(gt){return gt=this.conditionStack.length-1-Math.abs(gt||0),gt>=0?this.conditionStack[gt]:"INITIAL"},"topState"),pushState:o(function(gt){this.begin(gt)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(gt,Kt,lt,Cn){var ge=Cn;switch(lt){case 0:return this.begin("acc_title"),34;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),36;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.pushState("shapeData"),Kt.yytext="",40;break;case 8:return this.pushState("shapeDataStr"),40;break;case 9:return this.popState(),40;break;case 10:let Qf=/\n\s*/g;return Kt.yytext=Kt.yytext.replace(Qf,"
    "),40;break;case 11:return 40;case 12:this.popState();break;case 13:this.begin("callbackname");break;case 14:this.popState();break;case 15:this.popState(),this.begin("callbackargs");break;case 16:return 95;case 17:this.popState();break;case 18:return 96;case 19:return"MD_STR";case 20:this.popState();break;case 21:this.begin("md_string");break;case 22:return"STR";case 23:this.popState();break;case 24:this.pushState("string");break;case 25:return 84;case 26:return 102;case 27:return 85;case 28:return 104;case 29:return 86;case 30:return 87;case 31:return 97;case 32:this.begin("click");break;case 33:this.popState();break;case 34:return 88;case 35:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 36:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 37:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 38:return 27;case 39:return 32;case 40:return 98;case 41:return 98;case 42:return 98;case 43:return 98;case 44:return this.popState(),13;break;case 45:return this.popState(),14;break;case 46:return this.popState(),14;break;case 47:return this.popState(),14;break;case 48:return this.popState(),14;break;case 49:return this.popState(),14;break;case 50:return this.popState(),14;break;case 51:return this.popState(),14;break;case 52:return this.popState(),14;break;case 53:return this.popState(),14;break;case 54:return this.popState(),14;break;case 55:return 121;case 56:return 122;case 57:return 123;case 58:return 124;case 59:return 78;case 60:return 105;case 61:return 111;case 62:return 46;case 63:return 60;case 64:return 44;case 65:return 8;case 66:return 106;case 67:return 115;case 68:return this.popState(),77;break;case 69:return this.pushState("edgeText"),75;break;case 70:return 119;case 71:return this.popState(),77;break;case 72:return this.pushState("thickEdgeText"),75;break;case 73:return 119;case 74:return this.popState(),77;break;case 75:return this.pushState("dottedEdgeText"),75;break;case 76:return 119;case 77:return 77;case 78:return this.popState(),53;break;case 79:return"TEXT";case 80:return this.pushState("ellipseText"),52;break;case 81:return this.popState(),55;break;case 82:return this.pushState("text"),54;break;case 83:return this.popState(),57;break;case 84:return this.pushState("text"),56;break;case 85:return 58;case 86:return this.pushState("text"),67;break;case 87:return this.popState(),64;break;case 88:return this.pushState("text"),63;break;case 89:return this.popState(),49;break;case 90:return this.pushState("text"),48;break;case 91:return this.popState(),69;break;case 92:return this.popState(),71;break;case 93:return 117;case 94:return this.pushState("trapText"),68;break;case 95:return this.pushState("trapText"),70;break;case 96:return 118;case 97:return 67;case 98:return 90;case 99:return"SEP";case 100:return 89;case 101:return 115;case 102:return 111;case 103:return 44;case 104:return 109;case 105:return 114;case 106:return 116;case 107:return this.popState(),62;break;case 108:return this.pushState("text"),62;break;case 109:return this.popState(),51;break;case 110:return this.pushState("text"),50;break;case 111:return this.popState(),31;break;case 112:return this.pushState("text"),29;break;case 113:return this.popState(),66;break;case 114:return this.pushState("text"),65;break;case 115:return"TEXT";case 116:return"QUOTE";case 117:return 9;case 118:return 10;case 119:return 11}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:@\{)/,/^(?:["])/,/^(?:["])/,/^(?:[^\"]+)/,/^(?:[^}^"]+)/,/^(?:\})/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[^\s\"]+@(?=[^\{\"]))/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{shapeDataEndBracket:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeDataStr:{rules:[9,10,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeData:{rules:[8,11,12,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackargs:{rules:[17,18,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackname:{rules:[14,15,16,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},href:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},click:{rules:[21,24,33,34,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dottedEdgeText:{rules:[21,24,74,76,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},thickEdgeText:{rules:[21,24,71,73,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},edgeText:{rules:[21,24,68,70,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},trapText:{rules:[21,24,77,80,82,84,88,90,91,92,93,94,95,108,110,112,114],inclusive:!1},ellipseText:{rules:[21,24,77,78,79,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},text:{rules:[21,24,77,80,81,82,83,84,87,88,89,90,94,95,107,108,109,110,111,112,113,114,115],inclusive:!1},vertex:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dir:{rules:[21,24,44,45,46,47,48,49,50,51,52,53,54,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr_multiline:{rules:[5,6,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr:{rules:[3,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_title:{rules:[1,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},md_string:{rules:[19,20,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},string:{rules:[21,22,23,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},INITIAL:{rules:[0,2,4,7,13,21,24,25,26,27,28,29,30,31,32,35,36,37,38,39,40,41,42,43,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,71,72,74,75,77,80,82,84,85,86,88,90,94,95,96,97,98,99,100,101,102,103,104,105,106,108,110,112,114,116,117,118,119],inclusive:!0}}};return Hr}();Oi.lexer=ei;function Sn(){this.yy={}}return o(Sn,"Parser"),Sn.prototype=Oi,Oi.Parser=Sn,new Sn}();rN.parser=rN;nN=rN});var ase,sse,ose=N(()=>{"use strict";ise();ase=Object.assign({},nN);ase.parse=t=>{let e=t.replace(/}\s*\n/g,`} +`);return nN.parse(e)};sse=ase});var Nc,Xm=N(()=>{"use strict";Nc=o(()=>` + /* Font Awesome icon styling - consolidated */ + .label-icon { + display: inline-block; + height: 1em; + overflow: visible; + vertical-align: -0.125em; + } + + .node .label-icon path { + fill: currentColor; + stroke: revert; + stroke-width: revert; + } +`,"getIconStyles")});var UPe,HPe,lse,cse=N(()=>{"use strict";Ks();Xm();UPe=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),HPe=o(t=>`.label { + font-family: ${t.fontFamily}; + color: ${t.nodeTextColor||t.textColor}; + } + .cluster-label text { + fill: ${t.titleColor}; + } + .cluster-label span { + color: ${t.titleColor}; + } + .cluster-label span p { + background-color: transparent; + } + + .label text,span { + fill: ${t.nodeTextColor||t.textColor}; + color: ${t.nodeTextColor||t.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + stroke-width: 1px; + } + .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .katex path { + fill: #000; + stroke: #000; + stroke-width: 1px; + } + + .rough-node .label,.node .label, .image-shape .label, .icon-shape .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + + .root .anchor path { + fill: ${t.lineColor} !important; + stroke-width: 0; + stroke: ${t.lineColor}; + } + + .arrowheadPath { + fill: ${t.arrowheadColor}; + } + + .edgePath .path { + stroke: ${t.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${t.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${t.edgeLabelBackground}; + p { + background-color: ${t.edgeLabelBackground}; + } + rect { + opacity: 0.5; + background-color: ${t.edgeLabelBackground}; + fill: ${t.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${UPe(t.edgeLabelBackground,.5)}; + // background-color: + } + + .cluster rect { + fill: ${t.clusterBkg}; + stroke: ${t.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${t.titleColor}; + } + + .cluster span { + color: ${t.titleColor}; + } + /* .cluster div { + color: ${t.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${t.fontFamily}; + font-size: 12px; + background: ${t.tertiaryColor}; + border: 1px solid ${t.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.textColor}; + } + + rect.text { + fill: none; + stroke-width: 0; + } + + .icon-shape, .image-shape { + background-color: ${t.edgeLabelBackground}; + p { + background-color: ${t.edgeLabelBackground}; + padding: 2px; + } + rect { + opacity: 0.5; + background-color: ${t.edgeLabelBackground}; + fill: ${t.edgeLabelBackground}; + } + text-align: center; + } + ${Nc()} +`,"getStyles"),lse=HPe});var xk={};ur(xk,{diagram:()=>WPe});var WPe,bk=N(()=>{"use strict";Gt();lee();nse();ose();cse();WPe={parser:sse,get db(){return new iw},renderer:rse,styles:lse,init:o(t=>{t.flowchart||(t.flowchart={}),t.layout&&nv({layout:t.layout}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,nv({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}})},"init")}});var iN,pse,mse=N(()=>{"use strict";iN=function(){var t=o(function(te,he,le,J){for(le=le||{},J=te.length;J--;le[te[J]]=he);return le},"o"),e=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,50],r=[1,10],n=[1,11],i=[1,12],a=[1,13],s=[1,20],l=[1,21],u=[1,22],h=[1,23],f=[1,24],d=[1,19],p=[1,25],m=[1,26],g=[1,18],y=[1,33],v=[1,34],x=[1,35],b=[1,36],T=[1,37],S=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,50,63,64,65,66,67],w=[1,42],E=[1,43],_=[1,52],C=[40,50,68,69],D=[1,63],O=[1,61],R=[1,58],k=[1,62],L=[1,64],A=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,63,64,65,66,67],I=[63,64,65,66,67],M=[1,81],P=[1,80],B=[1,78],F=[1,79],z=[6,10,42,47],$=[6,10,13,41,42,47,48,49],U=[1,89],K=[1,88],ee=[1,87],Y=[19,56],ce=[1,98],Z=[1,97],ue=[19,56,58,60],Q={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,attribute:51,attributeType:52,attributeName:53,attributeKeyTypeList:54,attributeComment:55,ATTRIBUTE_WORD:56,attributeKeyType:57,",":58,ATTRIBUTE_KEY:59,COMMENT:60,cardinality:61,relType:62,ZERO_OR_ONE:63,ZERO_OR_MORE:64,ONE_OR_MORE:65,ONLY_ONE:66,MD_PARENT:67,NON_IDENTIFYING:68,IDENTIFYING:69,WORD:70,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",56:"ATTRIBUTE_WORD",58:",",59:"ATTRIBUTE_KEY",60:"COMMENT",63:"ZERO_OR_ONE",64:"ZERO_OR_MORE",65:"ONE_OR_MORE",66:"ONLY_ONE",67:"MD_PARENT",68:"NON_IDENTIFYING",69:"IDENTIFYING",70:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[18,1],[18,2],[51,2],[51,3],[51,3],[51,4],[52,1],[53,1],[54,1],[54,3],[57,1],[55,1],[12,3],[61,1],[61,1],[61,1],[61,1],[61,1],[62,1],[62,1],[14,1],[14,1],[14,1]],performAction:o(function(he,le,J,Se,se,ae,Oe){var ye=ae.length-1;switch(se){case 1:break;case 2:this.$=[];break;case 3:ae[ye-1].push(ae[ye]),this.$=ae[ye-1];break;case 4:case 5:this.$=ae[ye];break;case 6:case 7:this.$=[];break;case 8:Se.addEntity(ae[ye-4]),Se.addEntity(ae[ye-2]),Se.addRelationship(ae[ye-4],ae[ye],ae[ye-2],ae[ye-3]);break;case 9:Se.addEntity(ae[ye-8]),Se.addEntity(ae[ye-4]),Se.addRelationship(ae[ye-8],ae[ye],ae[ye-4],ae[ye-5]),Se.setClass([ae[ye-8]],ae[ye-6]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 10:Se.addEntity(ae[ye-6]),Se.addEntity(ae[ye-2]),Se.addRelationship(ae[ye-6],ae[ye],ae[ye-2],ae[ye-3]),Se.setClass([ae[ye-6]],ae[ye-4]);break;case 11:Se.addEntity(ae[ye-6]),Se.addEntity(ae[ye-4]),Se.addRelationship(ae[ye-6],ae[ye],ae[ye-4],ae[ye-5]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 12:Se.addEntity(ae[ye-3]),Se.addAttributes(ae[ye-3],ae[ye-1]);break;case 13:Se.addEntity(ae[ye-5]),Se.addAttributes(ae[ye-5],ae[ye-1]),Se.setClass([ae[ye-5]],ae[ye-3]);break;case 14:Se.addEntity(ae[ye-2]);break;case 15:Se.addEntity(ae[ye-4]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 16:Se.addEntity(ae[ye]);break;case 17:Se.addEntity(ae[ye-2]),Se.setClass([ae[ye-2]],ae[ye]);break;case 18:Se.addEntity(ae[ye-6],ae[ye-4]),Se.addAttributes(ae[ye-6],ae[ye-1]);break;case 19:Se.addEntity(ae[ye-8],ae[ye-6]),Se.addAttributes(ae[ye-8],ae[ye-1]),Se.setClass([ae[ye-8]],ae[ye-3]);break;case 20:Se.addEntity(ae[ye-5],ae[ye-3]);break;case 21:Se.addEntity(ae[ye-7],ae[ye-5]),Se.setClass([ae[ye-7]],ae[ye-2]);break;case 22:Se.addEntity(ae[ye-3],ae[ye-1]);break;case 23:Se.addEntity(ae[ye-5],ae[ye-3]),Se.setClass([ae[ye-5]],ae[ye]);break;case 24:case 25:this.$=ae[ye].trim(),Se.setAccTitle(this.$);break;case 26:case 27:this.$=ae[ye].trim(),Se.setAccDescription(this.$);break;case 32:Se.setDirection("TB");break;case 33:Se.setDirection("BT");break;case 34:Se.setDirection("RL");break;case 35:Se.setDirection("LR");break;case 36:this.$=ae[ye-3],Se.addClass(ae[ye-2],ae[ye-1]);break;case 37:case 38:case 56:case 64:this.$=[ae[ye]];break;case 39:case 40:this.$=ae[ye-2].concat([ae[ye]]);break;case 41:this.$=ae[ye-2],Se.setClass(ae[ye-1],ae[ye]);break;case 42:this.$=ae[ye-3],Se.addCssStyles(ae[ye-2],ae[ye-1]);break;case 43:this.$=[ae[ye]];break;case 44:ae[ye-2].push(ae[ye]),this.$=ae[ye-2];break;case 46:this.$=ae[ye-1]+ae[ye];break;case 54:case 76:case 77:this.$=ae[ye].replace(/"/g,"");break;case 55:case 78:this.$=ae[ye];break;case 57:ae[ye].push(ae[ye-1]),this.$=ae[ye];break;case 58:this.$={type:ae[ye-1],name:ae[ye]};break;case 59:this.$={type:ae[ye-2],name:ae[ye-1],keys:ae[ye]};break;case 60:this.$={type:ae[ye-2],name:ae[ye-1],comment:ae[ye]};break;case 61:this.$={type:ae[ye-3],name:ae[ye-2],keys:ae[ye-1],comment:ae[ye]};break;case 62:case 63:case 66:this.$=ae[ye];break;case 65:ae[ye-2].push(ae[ye]),this.$=ae[ye-2];break;case 67:this.$=ae[ye].replace(/"/g,"");break;case 68:this.$={cardA:ae[ye],relType:ae[ye-1],cardB:ae[ye-2]};break;case 69:this.$=Se.Cardinality.ZERO_OR_ONE;break;case 70:this.$=Se.Cardinality.ZERO_OR_MORE;break;case 71:this.$=Se.Cardinality.ONE_OR_MORE;break;case 72:this.$=Se.Cardinality.ONLY_ONE;break;case 73:this.$=Se.Cardinality.MD_PARENT;break;case 74:this.$=Se.Identification.NON_IDENTIFYING;break;case 75:this.$=Se.Identification.IDENTIFYING;break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:27,11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,5]),t(e,[2,6]),t(e,[2,16],{12:28,61:32,15:[1,29],17:[1,30],20:[1,31],63:y,64:v,65:x,66:b,67:T}),{23:[1,38]},{25:[1,39]},{27:[1,40]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),t(e,[2,30]),t(e,[2,31]),t(S,[2,54]),t(S,[2,55]),t(e,[2,32]),t(e,[2,33]),t(e,[2,34]),t(e,[2,35]),{16:41,40:w,41:E},{16:44,40:w,41:E},{16:45,40:w,41:E},t(e,[2,4]),{11:46,40:d,50:g},{16:47,40:w,41:E},{18:48,19:[1,49],51:50,52:51,56:_},{11:53,40:d,50:g},{62:54,68:[1,55],69:[1,56]},t(C,[2,69]),t(C,[2,70]),t(C,[2,71]),t(C,[2,72]),t(C,[2,73]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),{13:D,38:57,41:O,42:R,45:59,46:60,48:k,49:L},t(A,[2,37]),t(A,[2,38]),{16:65,40:w,41:E,42:R},{13:D,38:66,41:O,42:R,45:59,46:60,48:k,49:L},{13:[1,67],15:[1,68]},t(e,[2,17],{61:32,12:69,17:[1,70],42:R,63:y,64:v,65:x,66:b,67:T}),{19:[1,71]},t(e,[2,14]),{18:72,19:[2,56],51:50,52:51,56:_},{53:73,56:[1,74]},{56:[2,62]},{21:[1,75]},{61:76,63:y,64:v,65:x,66:b,67:T},t(I,[2,74]),t(I,[2,75]),{6:M,10:P,39:77,42:B,47:F},{40:[1,82],41:[1,83]},t(z,[2,43],{46:84,13:D,41:O,48:k,49:L}),t($,[2,45]),t($,[2,50]),t($,[2,51]),t($,[2,52]),t($,[2,53]),t(e,[2,41],{42:R}),{6:M,10:P,39:85,42:B,47:F},{14:86,40:U,50:K,70:ee},{16:90,40:w,41:E},{11:91,40:d,50:g},{18:92,19:[1,93],51:50,52:51,56:_},t(e,[2,12]),{19:[2,57]},t(Y,[2,58],{54:94,55:95,57:96,59:ce,60:Z}),t([19,56,59,60],[2,63]),t(e,[2,22],{15:[1,100],17:[1,99]}),t([40,50],[2,68]),t(e,[2,36]),{13:D,41:O,45:101,46:60,48:k,49:L},t(e,[2,47]),t(e,[2,48]),t(e,[2,49]),t(A,[2,39]),t(A,[2,40]),t($,[2,46]),t(e,[2,42]),t(e,[2,8]),t(e,[2,76]),t(e,[2,77]),t(e,[2,78]),{13:[1,102],42:R},{13:[1,104],15:[1,103]},{19:[1,105]},t(e,[2,15]),t(Y,[2,59],{55:106,58:[1,107],60:Z}),t(Y,[2,60]),t(ue,[2,64]),t(Y,[2,67]),t(ue,[2,66]),{18:108,19:[1,109],51:50,52:51,56:_},{16:110,40:w,41:E},t(z,[2,44],{46:84,13:D,41:O,48:k,49:L}),{14:111,40:U,50:K,70:ee},{16:112,40:w,41:E},{14:113,40:U,50:K,70:ee},t(e,[2,13]),t(Y,[2,61]),{57:114,59:ce},{19:[1,115]},t(e,[2,20]),t(e,[2,23],{17:[1,116],42:R}),t(e,[2,11]),{13:[1,117],42:R},t(e,[2,10]),t(ue,[2,65]),t(e,[2,18]),{18:118,19:[1,119],51:50,52:51,56:_},{14:120,40:U,50:K,70:ee},{19:[1,121]},t(e,[2,21]),t(e,[2,9]),t(e,[2,19])],defaultActions:{52:[2,62],72:[2,57]},parseError:o(function(he,le){if(le.recoverable)this.trace(he);else{var J=new Error(he);throw J.hash=le,J}},"parseError"),parse:o(function(he){var le=this,J=[0],Se=[],se=[null],ae=[],Oe=this.table,ye="",Be=0,He=0,ze=0,Le=2,Ie=1,xe=ae.slice.call(arguments,1),q=Object.create(this.lexer),de={yy:{}};for(var ie in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ie)&&(de.yy[ie]=this.yy[ie]);q.setInput(he,de.yy),de.yy.lexer=q,de.yy.parser=this,typeof q.yylloc>"u"&&(q.yylloc={});var oe=q.yylloc;ae.push(oe);var V=q.options&&q.options.ranges;typeof de.yy.parseError=="function"?this.parseError=de.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Te(ct){J.length=J.length-2*ct,se.length=se.length-ct,ae.length=ae.length-ct}o(Te,"popStack");function W(){var ct;return ct=Se.pop()||q.lex()||Ie,typeof ct!="number"&&(ct instanceof Array&&(Se=ct,ct=Se.pop()),ct=le.symbols_[ct]||ct),ct}o(W,"lex");for(var pe,ve,Pe,_e,be,Ve,De={},qe,at,Rt,st;;){if(Pe=J[J.length-1],this.defaultActions[Pe]?_e=this.defaultActions[Pe]:((pe===null||typeof pe>"u")&&(pe=W()),_e=Oe[Pe]&&Oe[Pe][pe]),typeof _e>"u"||!_e.length||!_e[0]){var Ue="";st=[];for(qe in Oe[Pe])this.terminals_[qe]&&qe>Le&&st.push("'"+this.terminals_[qe]+"'");q.showPosition?Ue="Parse error on line "+(Be+1)+`: +`+q.showPosition()+` +Expecting `+st.join(", ")+", got '"+(this.terminals_[pe]||pe)+"'":Ue="Parse error on line "+(Be+1)+": Unexpected "+(pe==Ie?"end of input":"'"+(this.terminals_[pe]||pe)+"'"),this.parseError(Ue,{text:q.match,token:this.terminals_[pe]||pe,line:q.yylineno,loc:oe,expected:st})}if(_e[0]instanceof Array&&_e.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Pe+", token: "+pe);switch(_e[0]){case 1:J.push(pe),se.push(q.yytext),ae.push(q.yylloc),J.push(_e[1]),pe=null,ve?(pe=ve,ve=null):(He=q.yyleng,ye=q.yytext,Be=q.yylineno,oe=q.yylloc,ze>0&&ze--);break;case 2:if(at=this.productions_[_e[1]][1],De.$=se[se.length-at],De._$={first_line:ae[ae.length-(at||1)].first_line,last_line:ae[ae.length-1].last_line,first_column:ae[ae.length-(at||1)].first_column,last_column:ae[ae.length-1].last_column},V&&(De._$.range=[ae[ae.length-(at||1)].range[0],ae[ae.length-1].range[1]]),Ve=this.performAction.apply(De,[ye,He,Be,de.yy,_e[1],se,ae].concat(xe)),typeof Ve<"u")return Ve;at&&(J=J.slice(0,-1*at*2),se=se.slice(0,-1*at),ae=ae.slice(0,-1*at)),J.push(this.productions_[_e[1]][0]),se.push(De.$),ae.push(De._$),Rt=Oe[J[J.length-2]][J[J.length-1]],J.push(Rt);break;case 3:return!0}}return!0},"parse")},j=function(){var te={EOF:1,parseError:o(function(le,J){if(this.yy.parser)this.yy.parser.parseError(le,J);else throw new Error(le)},"parseError"),setInput:o(function(he,le){return this.yy=le||this.yy||{},this._input=he,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var he=this._input[0];this.yytext+=he,this.yyleng++,this.offset++,this.match+=he,this.matched+=he;var le=he.match(/(?:\r\n?|\n).*/g);return le?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),he},"input"),unput:o(function(he){var le=he.length,J=he.split(/(?:\r\n?|\n)/g);this._input=he+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-le),this.offset-=le;var Se=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),J.length-1&&(this.yylineno-=J.length-1);var se=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:J?(J.length===Se.length?this.yylloc.first_column:0)+Se[Se.length-J.length].length-J[0].length:this.yylloc.first_column-le},this.options.ranges&&(this.yylloc.range=[se[0],se[0]+this.yyleng-le]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(he){this.unput(this.match.slice(he))},"less"),pastInput:o(function(){var he=this.matched.substr(0,this.matched.length-this.match.length);return(he.length>20?"...":"")+he.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var he=this.match;return he.length<20&&(he+=this._input.substr(0,20-he.length)),(he.substr(0,20)+(he.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var he=this.pastInput(),le=new Array(he.length+1).join("-");return he+this.upcomingInput()+` +`+le+"^"},"showPosition"),test_match:o(function(he,le){var J,Se,se;if(this.options.backtrack_lexer&&(se={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(se.yylloc.range=this.yylloc.range.slice(0))),Se=he[0].match(/(?:\r\n?|\n).*/g),Se&&(this.yylineno+=Se.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Se?Se[Se.length-1].length-Se[Se.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+he[0].length},this.yytext+=he[0],this.match+=he[0],this.matches=he,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(he[0].length),this.matched+=he[0],J=this.performAction.call(this,this.yy,this,le,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),J)return J;if(this._backtrack){for(var ae in se)this[ae]=se[ae];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var he,le,J,Se;this._more||(this.yytext="",this.match="");for(var se=this._currentRules(),ae=0;aele[0].length)){if(le=J,Se=ae,this.options.backtrack_lexer){if(he=this.test_match(J,se[ae]),he!==!1)return he;if(this._backtrack){le=!1;continue}else return!1}else if(!this.options.flex)break}return le?(he=this.test_match(le,se[Se]),he!==!1?he:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var le=this.next();return le||this.lex()},"lex"),begin:o(function(le){this.conditionStack.push(le)},"begin"),popState:o(function(){var le=this.conditionStack.length-1;return le>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(le){return le=this.conditionStack.length-1-Math.abs(le||0),le>=0?this.conditionStack[le]:"INITIAL"},"topState"),pushState:o(function(le){this.begin(le)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(le,J,Se,se){var ae=se;switch(Se){case 0:return this.begin("acc_title"),24;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),26;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 33;case 8:return 34;case 9:return 35;case 10:return 36;case 11:return 10;case 12:break;case 13:return 8;case 14:return 50;case 15:return 70;case 16:return 4;case 17:return this.begin("block"),17;break;case 18:return 49;case 19:return 49;case 20:return 42;case 21:return 15;case 22:return 13;case 23:break;case 24:return 59;case 25:return 56;case 26:return 56;case 27:return 60;case 28:break;case 29:return this.popState(),19;break;case 30:return J.yytext[0];case 31:return 20;case 32:return 21;case 33:return this.begin("style"),44;break;case 34:return this.popState(),10;break;case 35:break;case 36:return 13;case 37:return 42;case 38:return 49;case 39:return this.begin("style"),37;break;case 40:return 43;case 41:return 63;case 42:return 65;case 43:return 65;case 44:return 65;case 45:return 63;case 46:return 63;case 47:return 64;case 48:return 64;case 49:return 64;case 50:return 64;case 51:return 64;case 52:return 65;case 53:return 64;case 54:return 65;case 55:return 66;case 56:return 66;case 57:return 66;case 58:return 66;case 59:return 63;case 60:return 64;case 61:return 65;case 62:return 67;case 63:return 68;case 64:return 69;case 65:return 69;case 66:return 68;case 67:return 68;case 68:return 68;case 69:return 41;case 70:return 47;case 71:return 40;case 72:return 48;case 73:return J.yytext[0];case 74:return 6}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:#)/i,/^(?:#)/i,/^(?:,)/i,/^(?::::)/i,/^(?::)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:([^\s]*)[~].*[~]([^\s]*))/i,/^(?:([\*A-Za-z_\u00C0-\uFFFF][A-Za-z0-9\-\_\[\]\(\)\u00C0-\uFFFF\*]*))/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:style\b)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?::)/i,/^(?:,)/i,/^(?:#)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:;)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:[0-9])/i,/^(?:.)/i,/^(?:$)/i],conditions:{style:{rules:[34,35,36,37,38,69,70],inclusive:!1},acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[23,24,25,26,27,28,29,30],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,31,32,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,71,72,73,74],inclusive:!0}}};return te}();Q.lexer=j;function ne(){this.yy={}}return o(ne,"Parser"),ne.prototype=Q,Q.Parser=ne,new ne}();iN.parser=iN;pse=iN});var Tk,gse=N(()=>{"use strict";yt();Gt();ci();er();Tk=class{constructor(){this.entities=new Map;this.relationships=[];this.classes=new Map;this.direction="TB";this.Cardinality={ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"};this.Identification={NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"};this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().er,"getConfig");this.clear(),this.addEntity=this.addEntity.bind(this),this.addAttributes=this.addAttributes.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setDirection=this.setDirection.bind(this),this.addCssStyles=this.addCssStyles.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"ErDB")}addEntity(e,r=""){return this.entities.has(e)?!this.entities.get(e)?.alias&&r&&(this.entities.get(e).alias=r,X.info(`Add alias '${r}' to entity '${e}'`)):(this.entities.set(e,{id:`entity-${e}-${this.entities.size}`,label:e,attributes:[],alias:r,shape:"erBox",look:me().look??"default",cssClasses:"default",cssStyles:[]}),X.info("Added new entity :",e)),this.entities.get(e)}getEntity(e){return this.entities.get(e)}getEntities(){return this.entities}getClasses(){return this.classes}addAttributes(e,r){let n=this.addEntity(e),i;for(i=r.length-1;i>=0;i--)r[i].keys||(r[i].keys=[]),r[i].comment||(r[i].comment=""),n.attributes.push(r[i]),X.debug("Added attribute ",r[i].name)}addRelationship(e,r,n,i){let a=this.entities.get(e),s=this.entities.get(n);if(!a||!s)return;let l={entityA:a.id,roleA:r,entityB:s.id,relSpec:i};this.relationships.push(l),X.debug("Added new relationship :",l)}getRelationships(){return this.relationships}getDirection(){return this.direction}setDirection(e){this.direction=e}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}addCssStyles(e,r){for(let n of e){let i=this.entities.get(n);if(!r||!i)return;for(let a of r)i.cssStyles.push(a)}}addClass(e,r){e.forEach(n=>{let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)})})}setClass(e,r){for(let n of e){let i=this.entities.get(n);if(i)for(let a of r)i.cssClasses+=" "+a}}clear(){this.entities=new Map,this.classes=new Map,this.relationships=[],kr()}getData(){let e=[],r=[],n=me();for(let a of this.entities.keys()){let s=this.entities.get(a);s&&(s.cssCompiledStyles=this.getCompiledStyles(s.cssClasses.split(" ")),e.push(s))}let i=0;for(let a of this.relationships){let s={id:Wh(a.entityA,a.entityB,{prefix:"id",counter:i++}),type:"normal",curve:"basis",start:a.entityA,end:a.entityB,label:a.roleA,labelpos:"c",thickness:"normal",classes:"relationshipLine",arrowTypeStart:a.relSpec.cardB.toLowerCase(),arrowTypeEnd:a.relSpec.cardA.toLowerCase(),pattern:a.relSpec.relType=="IDENTIFYING"?"solid":"dashed",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:"TB"}}}});var aN={};ur(aN,{draw:()=>ZPe});var ZPe,yse=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();fr();ZPe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing er diagram (unified)",e);let{securityLevel:i,er:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.config.flowchart.nodeSpacing=a?.nodeSpacing||140,l.config.flowchart.rankSpacing=a?.rankSpacing||80,l.direction=n.db.getDirection(),l.markers=["only_one","zero_or_one","one_or_more","zero_or_more"],l.diagramId=e,await Rc(l,u),l.layoutAlgorithm==="elk"&&u.select(".edges").lower();let h=u.selectAll('[id*="-background"]');Array.from(h).length>0&&h.each(function(){let d=Ge(this),m=d.attr("id").replace("-background",""),g=u.select(`#${CSS.escape(m)}`);if(!g.empty()){let y=g.attr("transform");d.attr("transform",y)}});let f=8;Vt.insertTitle(u,"erDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,f,"erDiagram",a?.useMaxWidth??!0)},"draw")});var JPe,eBe,vse,xse=N(()=>{"use strict";Ks();JPe=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),eBe=o(t=>` + .entityBox { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + } + + .relationshipLabelBox { + fill: ${t.tertiaryColor}; + opacity: 0.7; + background-color: ${t.tertiaryColor}; + rect { + opacity: 0.5; + } + } + + .labelBkg { + background-color: ${JPe(t.tertiaryColor,.5)}; + } + + .edgeLabel .label { + fill: ${t.nodeBorder}; + font-size: 14px; + } + + .label { + font-family: ${t.fontFamily}; + color: ${t.nodeTextColor||t.textColor}; + } + + .edge-pattern-dashed { + stroke-dasharray: 8,8; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon + { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + stroke-width: 1px; + } + + .relationshipLine { + stroke: ${t.lineColor}; + stroke-width: 1; + fill: none; + } + + .marker { + fill: none !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; + } +`,"getStyles"),vse=eBe});var bse={};ur(bse,{diagram:()=>tBe});var tBe,Tse=N(()=>{"use strict";mse();gse();yse();xse();tBe={parser:pse,get db(){return new Tk},renderer:aN,styles:vse}});function si(t){return typeof t=="object"&&t!==null&&typeof t.$type=="string"}function ya(t){return typeof t=="object"&&t!==null&&typeof t.$refText=="string"}function sN(t){return typeof t=="object"&&t!==null&&typeof t.name=="string"&&typeof t.type=="string"&&typeof t.path=="string"}function ap(t){return typeof t=="object"&&t!==null&&si(t.container)&&ya(t.reference)&&typeof t.message=="string"}function Ml(t){return typeof t=="object"&&t!==null&&Array.isArray(t.content)}function hf(t){return typeof t=="object"&&t!==null&&typeof t.tokenType=="object"}function U2(t){return Ml(t)&&typeof t.fullText=="string"}var ip,Il=N(()=>{"use strict";o(si,"isAstNode");o(ya,"isReference");o(sN,"isAstNodeDescription");o(ap,"isLinkingError");ip=class{static{o(this,"AbstractAstReflection")}constructor(){this.subtypes={},this.allSubtypes={}}isInstance(e,r){return si(e)&&this.isSubtype(e.$type,r)}isSubtype(e,r){if(e===r)return!0;let n=this.subtypes[e];n||(n=this.subtypes[e]={});let i=n[r];if(i!==void 0)return i;{let a=this.computeIsSubtype(e,r);return n[r]=a,a}}getAllSubTypes(e){let r=this.allSubtypes[e];if(r)return r;{let n=this.getAllTypes(),i=[];for(let a of n)this.isSubtype(a,e)&&i.push(a);return this.allSubtypes[e]=i,i}}};o(Ml,"isCompositeCstNode");o(hf,"isLeafCstNode");o(U2,"isRootCstNode")});function aBe(t){return typeof t=="string"?t:typeof t>"u"?"undefined":typeof t.toString=="function"?t.toString():Object.prototype.toString.call(t)}function wk(t){return!!t&&typeof t[Symbol.iterator]=="function"}function en(...t){if(t.length===1){let e=t[0];if(e instanceof co)return e;if(wk(e))return new co(()=>e[Symbol.iterator](),r=>r.next());if(typeof e.length=="number")return new co(()=>({index:0}),r=>r.index1?new co(()=>({collIndex:0,arrIndex:0}),e=>{do{if(e.iterator){let r=e.iterator.next();if(!r.done)return r;e.iterator=void 0}if(e.array){if(e.arrIndex{"use strict";co=class t{static{o(this,"StreamImpl")}constructor(e,r){this.startFn=e,this.nextFn=r}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),[Symbol.iterator]:()=>e};return e}[Symbol.iterator](){return this.iterator()}isEmpty(){return!!this.iterator().next().done}count(){let e=this.iterator(),r=0,n=e.next();for(;!n.done;)r++,n=e.next();return r}toArray(){let e=[],r=this.iterator(),n;do n=r.next(),n.value!==void 0&&e.push(n.value);while(!n.done);return e}toSet(){return new Set(this)}toMap(e,r){let n=this.map(i=>[e?e(i):i,r?r(i):i]);return new Map(n)}toString(){return this.join()}concat(e){return new t(()=>({first:this.startFn(),firstDone:!1,iterator:e[Symbol.iterator]()}),r=>{let n;if(!r.firstDone){do if(n=this.nextFn(r.first),!n.done)return n;while(!n.done);r.firstDone=!0}do if(n=r.iterator.next(),!n.done)return n;while(!n.done);return Ba})}join(e=","){let r=this.iterator(),n="",i,a=!1;do i=r.next(),i.done||(a&&(n+=e),n+=aBe(i.value)),a=!0;while(!i.done);return n}indexOf(e,r=0){let n=this.iterator(),i=0,a=n.next();for(;!a.done;){if(i>=r&&a.value===e)return i;a=n.next(),i++}return-1}every(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(!e(n.value))return!1;n=r.next()}return!0}some(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return!0;n=r.next()}return!1}forEach(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;)e(i.value,n),i=r.next(),n++}map(e){return new t(this.startFn,r=>{let{done:n,value:i}=this.nextFn(r);return n?Ba:{done:!1,value:e(i)}})}filter(e){return new t(this.startFn,r=>{let n;do if(n=this.nextFn(r),!n.done&&e(n.value))return n;while(!n.done);return Ba})}nonNullable(){return this.filter(e=>e!=null)}reduce(e,r){let n=this.iterator(),i=r,a=n.next();for(;!a.done;)i===void 0?i=a.value:i=e(i,a.value),a=n.next();return i}reduceRight(e,r){return this.recursiveReduce(this.iterator(),e,r)}recursiveReduce(e,r,n){let i=e.next();if(i.done)return n;let a=this.recursiveReduce(e,r,n);return a===void 0?i.value:r(a,i.value)}find(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return n.value;n=r.next()}}findIndex(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;){if(e(i.value))return n;i=r.next(),n++}return-1}includes(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(n.value===e)return!0;n=r.next()}return!1}flatMap(e){return new t(()=>({this:this.startFn()}),r=>{do{if(r.iterator){let a=r.iterator.next();if(a.done)r.iterator=void 0;else return a}let{done:n,value:i}=this.nextFn(r.this);if(!n){let a=e(i);if(wk(a))r.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}}while(r.iterator);return Ba})}flat(e){if(e===void 0&&(e=1),e<=0)return this;let r=e>1?this.flat(e-1):this;return new t(()=>({this:r.startFn()}),n=>{do{if(n.iterator){let s=n.iterator.next();if(s.done)n.iterator=void 0;else return s}let{done:i,value:a}=r.nextFn(n.this);if(!i)if(wk(a))n.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}while(n.iterator);return Ba})}head(){let r=this.iterator().next();if(!r.done)return r.value}tail(e=1){return new t(()=>{let r=this.startFn();for(let n=0;n({size:0,state:this.startFn()}),r=>(r.size++,r.size>e?Ba:this.nextFn(r.state)))}distinct(e){return new t(()=>({set:new Set,internalState:this.startFn()}),r=>{let n;do if(n=this.nextFn(r.internalState),!n.done){let i=e?e(n.value):n.value;if(!r.set.has(i))return r.set.add(i),n}while(!n.done);return Ba})}exclude(e,r){let n=new Set;for(let i of e){let a=r?r(i):i;n.add(a)}return this.filter(i=>{let a=r?r(i):i;return!n.has(a)})}};o(aBe,"toString");o(wk,"isIterable");H2=new co(()=>{},()=>Ba),Ba=Object.freeze({done:!0,value:void 0});o(en,"stream");Mc=class extends co{static{o(this,"TreeStreamImpl")}constructor(e,r,n){super(()=>({iterators:n?.includeRoot?[[e][Symbol.iterator]()]:[r(e)[Symbol.iterator]()],pruned:!1}),i=>{for(i.pruned&&(i.iterators.pop(),i.pruned=!1);i.iterators.length>0;){let s=i.iterators[i.iterators.length-1].next();if(s.done)i.iterators.pop();else return i.iterators.push(r(s.value)[Symbol.iterator]()),s}return Ba})}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),prune:o(()=>{e.state.pruned=!0},"prune"),[Symbol.iterator]:()=>e};return e}};(function(t){function e(a){return a.reduce((s,l)=>s+l,0)}o(e,"sum"),t.sum=e;function r(a){return a.reduce((s,l)=>s*l,0)}o(r,"product"),t.product=r;function n(a){return a.reduce((s,l)=>Math.min(s,l))}o(n,"min"),t.min=n;function i(a){return a.reduce((s,l)=>Math.max(s,l))}o(i,"max"),t.max=i})(jm||(jm={}))});var Ek={};ur(Ek,{DefaultNameRegexp:()=>kk,RangeComparison:()=>Ic,compareRange:()=>Sse,findCommentNode:()=>uN,findDeclarationNodeAtOffset:()=>oBe,findLeafNodeAtOffset:()=>hN,findLeafNodeBeforeOffset:()=>Cse,flattenCst:()=>sBe,getInteriorNodes:()=>uBe,getNextNode:()=>lBe,getPreviousNode:()=>_se,getStartlineNode:()=>cBe,inRange:()=>cN,isChildNode:()=>lN,isCommentNode:()=>oN,streamCst:()=>sp,toDocumentSegment:()=>op,tokenToRange:()=>Km});function sp(t){return new Mc(t,e=>Ml(e)?e.content:[],{includeRoot:!0})}function sBe(t){return sp(t).filter(hf)}function lN(t,e){for(;t.container;)if(t=t.container,t===e)return!0;return!1}function Km(t){return{start:{character:t.startColumn-1,line:t.startLine-1},end:{character:t.endColumn,line:t.endLine-1}}}function op(t){if(!t)return;let{offset:e,end:r,range:n}=t;return{range:n,offset:e,end:r,length:r-e}}function Sse(t,e){if(t.end.linee.end.line||t.start.line===e.end.line&&t.start.character>=e.end.character)return Ic.After;let r=t.start.line>e.start.line||t.start.line===e.start.line&&t.start.character>=e.start.character,n=t.end.lineIc.After}function oBe(t,e,r=kk){if(t){if(e>0){let n=e-t.offset,i=t.text.charAt(n);r.test(i)||e--}return hN(t,e)}}function uN(t,e){if(t){let r=_se(t,!0);if(r&&oN(r,e))return r;if(U2(t)){let n=t.content.findIndex(i=>!i.hidden);for(let i=n-1;i>=0;i--){let a=t.content[i];if(oN(a,e))return a}}}}function oN(t,e){return hf(t)&&e.includes(t.tokenType.name)}function hN(t,e){if(hf(t))return t;if(Ml(t)){let r=Ase(t,e,!1);if(r)return hN(r,e)}}function Cse(t,e){if(hf(t))return t;if(Ml(t)){let r=Ase(t,e,!0);if(r)return Cse(r,e)}}function Ase(t,e,r){let n=0,i=t.content.length-1,a;for(;n<=i;){let s=Math.floor((n+i)/2),l=t.content[s];if(l.offset<=e&&l.end>e)return l;l.end<=e?(a=r?l:void 0,n=s+1):i=s-1}return a}function _se(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t);for(;n>0;){n--;let i=r.content[n];if(e||!i.hidden)return i}t=r}}function lBe(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t),i=r.content.length-1;for(;n{"use strict";Il();Gs();o(sp,"streamCst");o(sBe,"flattenCst");o(lN,"isChildNode");o(Km,"tokenToRange");o(op,"toDocumentSegment");(function(t){t[t.Before=0]="Before",t[t.After=1]="After",t[t.OverlapFront=2]="OverlapFront",t[t.OverlapBack=3]="OverlapBack",t[t.Inside=4]="Inside",t[t.Outside=5]="Outside"})(Ic||(Ic={}));o(Sse,"compareRange");o(cN,"inRange");kk=/^[\w\p{L}]$/u;o(oBe,"findDeclarationNodeAtOffset");o(uN,"findCommentNode");o(oN,"isCommentNode");o(hN,"findLeafNodeAtOffset");o(Cse,"findLeafNodeBeforeOffset");o(Ase,"binarySearch");o(_se,"getPreviousNode");o(lBe,"getNextNode");o(cBe,"getStartlineNode");o(uBe,"getInteriorNodes");o(hBe,"getCommonParent");o(Ese,"getParentChain")});function Oc(t){throw new Error("Error! The input value was not handled.")}var lp,Sk=N(()=>{"use strict";lp=class extends Error{static{o(this,"ErrorWithLocation")}constructor(e,r){super(e?`${r} at ${e.range.start.line}:${e.range.start.character}`:r)}};o(Oc,"assertUnreachable")});var J2={};ur(J2,{AbstractElement:()=>Jm,AbstractRule:()=>Qm,AbstractType:()=>Zm,Action:()=>vg,Alternatives:()=>xg,ArrayLiteral:()=>eg,ArrayType:()=>tg,Assignment:()=>bg,BooleanLiteral:()=>rg,CharacterRange:()=>Tg,Condition:()=>W2,Conjunction:()=>ng,CrossReference:()=>wg,Disjunction:()=>ig,EndOfFile:()=>kg,Grammar:()=>ag,GrammarImport:()=>Y2,Group:()=>Eg,InferredType:()=>sg,Interface:()=>og,Keyword:()=>Sg,LangiumGrammarAstReflection:()=>Og,LangiumGrammarTerminals:()=>fBe,NamedArgument:()=>X2,NegatedToken:()=>Cg,Negation:()=>lg,NumberLiteral:()=>cg,Parameter:()=>ug,ParameterReference:()=>hg,ParserRule:()=>fg,ReferenceType:()=>dg,RegexToken:()=>Ag,ReturnType:()=>j2,RuleCall:()=>_g,SimpleType:()=>pg,StringLiteral:()=>mg,TerminalAlternatives:()=>Dg,TerminalGroup:()=>Lg,TerminalRule:()=>cp,TerminalRuleCall:()=>Rg,Type:()=>gg,TypeAttribute:()=>K2,TypeDefinition:()=>Ck,UnionType:()=>yg,UnorderedGroup:()=>Ng,UntilToken:()=>Mg,ValueLiteral:()=>q2,Wildcard:()=>Ig,isAbstractElement:()=>Q2,isAbstractRule:()=>dBe,isAbstractType:()=>pBe,isAction:()=>$u,isAlternatives:()=>Lk,isArrayLiteral:()=>xBe,isArrayType:()=>fN,isAssignment:()=>Pl,isBooleanLiteral:()=>dN,isCharacterRange:()=>TN,isCondition:()=>mBe,isConjunction:()=>pN,isCrossReference:()=>up,isDisjunction:()=>mN,isEndOfFile:()=>wN,isFeatureName:()=>gBe,isGrammar:()=>bBe,isGrammarImport:()=>TBe,isGroup:()=>ff,isInferredType:()=>Ak,isInterface:()=>_k,isKeyword:()=>Xo,isNamedArgument:()=>wBe,isNegatedToken:()=>kN,isNegation:()=>gN,isNumberLiteral:()=>kBe,isParameter:()=>EBe,isParameterReference:()=>yN,isParserRule:()=>Fa,isPrimitiveType:()=>Dse,isReferenceType:()=>vN,isRegexToken:()=>EN,isReturnType:()=>xN,isRuleCall:()=>Bl,isSimpleType:()=>Dk,isStringLiteral:()=>SBe,isTerminalAlternatives:()=>SN,isTerminalGroup:()=>CN,isTerminalRule:()=>uo,isTerminalRuleCall:()=>Rk,isType:()=>Z2,isTypeAttribute:()=>CBe,isTypeDefinition:()=>yBe,isUnionType:()=>bN,isUnorderedGroup:()=>Nk,isUntilToken:()=>AN,isValueLiteral:()=>vBe,isWildcard:()=>_N,reflection:()=>cr});function dBe(t){return cr.isInstance(t,Qm)}function pBe(t){return cr.isInstance(t,Zm)}function mBe(t){return cr.isInstance(t,W2)}function gBe(t){return Dse(t)||t==="current"||t==="entry"||t==="extends"||t==="false"||t==="fragment"||t==="grammar"||t==="hidden"||t==="import"||t==="interface"||t==="returns"||t==="terminal"||t==="true"||t==="type"||t==="infer"||t==="infers"||t==="with"||typeof t=="string"&&/\^?[_a-zA-Z][\w_]*/.test(t)}function Dse(t){return t==="string"||t==="number"||t==="boolean"||t==="Date"||t==="bigint"}function yBe(t){return cr.isInstance(t,Ck)}function vBe(t){return cr.isInstance(t,q2)}function Q2(t){return cr.isInstance(t,Jm)}function xBe(t){return cr.isInstance(t,eg)}function fN(t){return cr.isInstance(t,tg)}function dN(t){return cr.isInstance(t,rg)}function pN(t){return cr.isInstance(t,ng)}function mN(t){return cr.isInstance(t,ig)}function bBe(t){return cr.isInstance(t,ag)}function TBe(t){return cr.isInstance(t,Y2)}function Ak(t){return cr.isInstance(t,sg)}function _k(t){return cr.isInstance(t,og)}function wBe(t){return cr.isInstance(t,X2)}function gN(t){return cr.isInstance(t,lg)}function kBe(t){return cr.isInstance(t,cg)}function EBe(t){return cr.isInstance(t,ug)}function yN(t){return cr.isInstance(t,hg)}function Fa(t){return cr.isInstance(t,fg)}function vN(t){return cr.isInstance(t,dg)}function xN(t){return cr.isInstance(t,j2)}function Dk(t){return cr.isInstance(t,pg)}function SBe(t){return cr.isInstance(t,mg)}function uo(t){return cr.isInstance(t,cp)}function Z2(t){return cr.isInstance(t,gg)}function CBe(t){return cr.isInstance(t,K2)}function bN(t){return cr.isInstance(t,yg)}function $u(t){return cr.isInstance(t,vg)}function Lk(t){return cr.isInstance(t,xg)}function Pl(t){return cr.isInstance(t,bg)}function TN(t){return cr.isInstance(t,Tg)}function up(t){return cr.isInstance(t,wg)}function wN(t){return cr.isInstance(t,kg)}function ff(t){return cr.isInstance(t,Eg)}function Xo(t){return cr.isInstance(t,Sg)}function kN(t){return cr.isInstance(t,Cg)}function EN(t){return cr.isInstance(t,Ag)}function Bl(t){return cr.isInstance(t,_g)}function SN(t){return cr.isInstance(t,Dg)}function CN(t){return cr.isInstance(t,Lg)}function Rk(t){return cr.isInstance(t,Rg)}function Nk(t){return cr.isInstance(t,Ng)}function AN(t){return cr.isInstance(t,Mg)}function _N(t){return cr.isInstance(t,Ig)}var fBe,Qm,Zm,W2,Ck,q2,Jm,eg,tg,rg,ng,ig,ag,Y2,sg,og,X2,lg,cg,ug,hg,fg,dg,j2,pg,mg,cp,gg,K2,yg,vg,xg,bg,Tg,wg,kg,Eg,Sg,Cg,Ag,_g,Dg,Lg,Rg,Ng,Mg,Ig,Og,cr,Pc=N(()=>{"use strict";Il();fBe={ID:/\^?[_a-zA-Z][\w_]*/,STRING:/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/,NUMBER:/NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)/,RegexLiteral:/\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/[a-z]*/,WS:/\s+/,ML_COMMENT:/\/\*[\s\S]*?\*\//,SL_COMMENT:/\/\/[^\n\r]*/},Qm="AbstractRule";o(dBe,"isAbstractRule");Zm="AbstractType";o(pBe,"isAbstractType");W2="Condition";o(mBe,"isCondition");o(gBe,"isFeatureName");o(Dse,"isPrimitiveType");Ck="TypeDefinition";o(yBe,"isTypeDefinition");q2="ValueLiteral";o(vBe,"isValueLiteral");Jm="AbstractElement";o(Q2,"isAbstractElement");eg="ArrayLiteral";o(xBe,"isArrayLiteral");tg="ArrayType";o(fN,"isArrayType");rg="BooleanLiteral";o(dN,"isBooleanLiteral");ng="Conjunction";o(pN,"isConjunction");ig="Disjunction";o(mN,"isDisjunction");ag="Grammar";o(bBe,"isGrammar");Y2="GrammarImport";o(TBe,"isGrammarImport");sg="InferredType";o(Ak,"isInferredType");og="Interface";o(_k,"isInterface");X2="NamedArgument";o(wBe,"isNamedArgument");lg="Negation";o(gN,"isNegation");cg="NumberLiteral";o(kBe,"isNumberLiteral");ug="Parameter";o(EBe,"isParameter");hg="ParameterReference";o(yN,"isParameterReference");fg="ParserRule";o(Fa,"isParserRule");dg="ReferenceType";o(vN,"isReferenceType");j2="ReturnType";o(xN,"isReturnType");pg="SimpleType";o(Dk,"isSimpleType");mg="StringLiteral";o(SBe,"isStringLiteral");cp="TerminalRule";o(uo,"isTerminalRule");gg="Type";o(Z2,"isType");K2="TypeAttribute";o(CBe,"isTypeAttribute");yg="UnionType";o(bN,"isUnionType");vg="Action";o($u,"isAction");xg="Alternatives";o(Lk,"isAlternatives");bg="Assignment";o(Pl,"isAssignment");Tg="CharacterRange";o(TN,"isCharacterRange");wg="CrossReference";o(up,"isCrossReference");kg="EndOfFile";o(wN,"isEndOfFile");Eg="Group";o(ff,"isGroup");Sg="Keyword";o(Xo,"isKeyword");Cg="NegatedToken";o(kN,"isNegatedToken");Ag="RegexToken";o(EN,"isRegexToken");_g="RuleCall";o(Bl,"isRuleCall");Dg="TerminalAlternatives";o(SN,"isTerminalAlternatives");Lg="TerminalGroup";o(CN,"isTerminalGroup");Rg="TerminalRuleCall";o(Rk,"isTerminalRuleCall");Ng="UnorderedGroup";o(Nk,"isUnorderedGroup");Mg="UntilToken";o(AN,"isUntilToken");Ig="Wildcard";o(_N,"isWildcard");Og=class extends ip{static{o(this,"LangiumGrammarAstReflection")}getAllTypes(){return[Jm,Qm,Zm,vg,xg,eg,tg,bg,rg,Tg,W2,ng,wg,ig,kg,ag,Y2,Eg,sg,og,Sg,X2,Cg,lg,cg,ug,hg,fg,dg,Ag,j2,_g,pg,mg,Dg,Lg,cp,Rg,gg,K2,Ck,yg,Ng,Mg,q2,Ig]}computeIsSubtype(e,r){switch(e){case vg:case xg:case bg:case Tg:case wg:case kg:case Eg:case Sg:case Cg:case Ag:case _g:case Dg:case Lg:case Rg:case Ng:case Mg:case Ig:return this.isSubtype(Jm,r);case eg:case cg:case mg:return this.isSubtype(q2,r);case tg:case dg:case pg:case yg:return this.isSubtype(Ck,r);case rg:return this.isSubtype(W2,r)||this.isSubtype(q2,r);case ng:case ig:case lg:case hg:return this.isSubtype(W2,r);case sg:case og:case gg:return this.isSubtype(Zm,r);case fg:return this.isSubtype(Qm,r)||this.isSubtype(Zm,r);case cp:return this.isSubtype(Qm,r);default:return!1}}getReferenceType(e){let r=`${e.container.$type}:${e.property}`;switch(r){case"Action:type":case"CrossReference:type":case"Interface:superTypes":case"ParserRule:returnType":case"SimpleType:typeRef":return Zm;case"Grammar:hiddenTokens":case"ParserRule:hiddenTokens":case"RuleCall:rule":return Qm;case"Grammar:usedGrammars":return ag;case"NamedArgument:parameter":case"ParameterReference:parameter":return ug;case"TerminalRuleCall:rule":return cp;default:throw new Error(`${r} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case Jm:return{name:Jm,properties:[{name:"cardinality"},{name:"lookahead"}]};case eg:return{name:eg,properties:[{name:"elements",defaultValue:[]}]};case tg:return{name:tg,properties:[{name:"elementType"}]};case rg:return{name:rg,properties:[{name:"true",defaultValue:!1}]};case ng:return{name:ng,properties:[{name:"left"},{name:"right"}]};case ig:return{name:ig,properties:[{name:"left"},{name:"right"}]};case ag:return{name:ag,properties:[{name:"definesHiddenTokens",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"imports",defaultValue:[]},{name:"interfaces",defaultValue:[]},{name:"isDeclared",defaultValue:!1},{name:"name"},{name:"rules",defaultValue:[]},{name:"types",defaultValue:[]},{name:"usedGrammars",defaultValue:[]}]};case Y2:return{name:Y2,properties:[{name:"path"}]};case sg:return{name:sg,properties:[{name:"name"}]};case og:return{name:og,properties:[{name:"attributes",defaultValue:[]},{name:"name"},{name:"superTypes",defaultValue:[]}]};case X2:return{name:X2,properties:[{name:"calledByName",defaultValue:!1},{name:"parameter"},{name:"value"}]};case lg:return{name:lg,properties:[{name:"value"}]};case cg:return{name:cg,properties:[{name:"value"}]};case ug:return{name:ug,properties:[{name:"name"}]};case hg:return{name:hg,properties:[{name:"parameter"}]};case fg:return{name:fg,properties:[{name:"dataType"},{name:"definesHiddenTokens",defaultValue:!1},{name:"definition"},{name:"entry",defaultValue:!1},{name:"fragment",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"inferredType"},{name:"name"},{name:"parameters",defaultValue:[]},{name:"returnType"},{name:"wildcard",defaultValue:!1}]};case dg:return{name:dg,properties:[{name:"referenceType"}]};case j2:return{name:j2,properties:[{name:"name"}]};case pg:return{name:pg,properties:[{name:"primitiveType"},{name:"stringType"},{name:"typeRef"}]};case mg:return{name:mg,properties:[{name:"value"}]};case cp:return{name:cp,properties:[{name:"definition"},{name:"fragment",defaultValue:!1},{name:"hidden",defaultValue:!1},{name:"name"},{name:"type"}]};case gg:return{name:gg,properties:[{name:"name"},{name:"type"}]};case K2:return{name:K2,properties:[{name:"defaultValue"},{name:"isOptional",defaultValue:!1},{name:"name"},{name:"type"}]};case yg:return{name:yg,properties:[{name:"types",defaultValue:[]}]};case vg:return{name:vg,properties:[{name:"cardinality"},{name:"feature"},{name:"inferredType"},{name:"lookahead"},{name:"operator"},{name:"type"}]};case xg:return{name:xg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case bg:return{name:bg,properties:[{name:"cardinality"},{name:"feature"},{name:"lookahead"},{name:"operator"},{name:"terminal"}]};case Tg:return{name:Tg,properties:[{name:"cardinality"},{name:"left"},{name:"lookahead"},{name:"right"}]};case wg:return{name:wg,properties:[{name:"cardinality"},{name:"deprecatedSyntax",defaultValue:!1},{name:"lookahead"},{name:"terminal"},{name:"type"}]};case kg:return{name:kg,properties:[{name:"cardinality"},{name:"lookahead"}]};case Eg:return{name:Eg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"guardCondition"},{name:"lookahead"}]};case Sg:return{name:Sg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"value"}]};case Cg:return{name:Cg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case Ag:return{name:Ag,properties:[{name:"cardinality"},{name:"lookahead"},{name:"regex"}]};case _g:return{name:_g,properties:[{name:"arguments",defaultValue:[]},{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case Dg:return{name:Dg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Lg:return{name:Lg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Rg:return{name:Rg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case Ng:return{name:Ng,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Mg:return{name:Mg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case Ig:return{name:Ig,properties:[{name:"cardinality"},{name:"lookahead"}]};default:return{name:e,properties:[]}}}},cr=new Og});var Ik={};ur(Ik,{assignMandatoryProperties:()=>RN,copyAstNode:()=>LN,findLocalReferences:()=>_Be,findRootNode:()=>ex,getContainerOfType:()=>hp,getDocument:()=>$a,hasContainerOfType:()=>ABe,linkContentToContainer:()=>Mk,streamAllContents:()=>Bc,streamAst:()=>jo,streamContents:()=>tx,streamReferences:()=>Pg});function Mk(t){for(let[e,r]of Object.entries(t))e.startsWith("$")||(Array.isArray(r)?r.forEach((n,i)=>{si(n)&&(n.$container=t,n.$containerProperty=e,n.$containerIndex=i)}):si(r)&&(r.$container=t,r.$containerProperty=e))}function hp(t,e){let r=t;for(;r;){if(e(r))return r;r=r.$container}}function ABe(t,e){let r=t;for(;r;){if(e(r))return!0;r=r.$container}return!1}function $a(t){let r=ex(t).$document;if(!r)throw new Error("AST node has no document.");return r}function ex(t){for(;t.$container;)t=t.$container;return t}function tx(t,e){if(!t)throw new Error("Node must be an AstNode.");let r=e?.range;return new co(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),n=>{for(;n.keyIndextx(r,e))}function jo(t,e){if(t){if(e?.range&&!DN(t,e.range))return new Mc(t,()=>[])}else throw new Error("Root node must be an AstNode.");return new Mc(t,r=>tx(r,e),{includeRoot:!0})}function DN(t,e){var r;if(!e)return!0;let n=(r=t.$cstNode)===null||r===void 0?void 0:r.range;return n?cN(n,e):!1}function Pg(t){return new co(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),e=>{for(;e.keyIndex{Pg(n).forEach(i=>{i.reference.ref===t&&r.push(i.reference)})}),en(r)}function RN(t,e){let r=t.getTypeMetaData(e.$type),n=e;for(let i of r.properties)i.defaultValue!==void 0&&n[i.name]===void 0&&(n[i.name]=Lse(i.defaultValue))}function Lse(t){return Array.isArray(t)?[...t.map(Lse)]:t}function LN(t,e){let r={$type:t.$type};for(let[n,i]of Object.entries(t))if(!n.startsWith("$"))if(si(i))r[n]=LN(i,e);else if(ya(i))r[n]=e(r,n,i.$refNode,i.$refText);else if(Array.isArray(i)){let a=[];for(let s of i)si(s)?a.push(LN(s,e)):ya(s)?a.push(e(r,n,s.$refNode,s.$refText)):a.push(s);r[n]=a}else r[n]=i;return Mk(r),r}var cs=N(()=>{"use strict";Il();Gs();Ol();o(Mk,"linkContentToContainer");o(hp,"getContainerOfType");o(ABe,"hasContainerOfType");o($a,"getDocument");o(ex,"findRootNode");o(tx,"streamContents");o(Bc,"streamAllContents");o(jo,"streamAst");o(DN,"isAstNodeInRange");o(Pg,"streamReferences");o(_Be,"findLocalReferences");o(RN,"assignMandatoryProperties");o(Lse,"copyDefaultValue");o(LN,"copyAstNode")});function sr(t){return t.charCodeAt(0)}function Ok(t,e){Array.isArray(t)?t.forEach(function(r){e.push(r)}):e.push(t)}function Bg(t,e){if(t[e]===!0)throw"duplicate flag "+e;let r=t[e];t[e]=!0}function fp(t){if(t===void 0)throw Error("Internal Error - Should never get here!");return!0}function rx(){throw Error("Internal Error - Should never get here!")}function NN(t){return t.type==="Character"}var MN=N(()=>{"use strict";o(sr,"cc");o(Ok,"insertToSet");o(Bg,"addFlag");o(fp,"ASSERT_EXISTS");o(rx,"ASSERT_NEVER_REACH_HERE");o(NN,"isCharacter")});var nx,ix,IN,Rse=N(()=>{"use strict";MN();nx=[];for(let t=sr("0");t<=sr("9");t++)nx.push(t);ix=[sr("_")].concat(nx);for(let t=sr("a");t<=sr("z");t++)ix.push(t);for(let t=sr("A");t<=sr("Z");t++)ix.push(t);IN=[sr(" "),sr("\f"),sr(` +`),sr("\r"),sr(" "),sr("\v"),sr(" "),sr("\xA0"),sr("\u1680"),sr("\u2000"),sr("\u2001"),sr("\u2002"),sr("\u2003"),sr("\u2004"),sr("\u2005"),sr("\u2006"),sr("\u2007"),sr("\u2008"),sr("\u2009"),sr("\u200A"),sr("\u2028"),sr("\u2029"),sr("\u202F"),sr("\u205F"),sr("\u3000"),sr("\uFEFF")]});var DBe,Pk,LBe,dp,Nse=N(()=>{"use strict";MN();Rse();DBe=/[0-9a-fA-F]/,Pk=/[0-9]/,LBe=/[1-9]/,dp=class{static{o(this,"RegExpParser")}constructor(){this.idx=0,this.input="",this.groupIdx=0}saveState(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}}restoreState(e){this.idx=e.idx,this.input=e.input,this.groupIdx=e.groupIdx}pattern(e){this.idx=0,this.input=e,this.groupIdx=0,this.consumeChar("/");let r=this.disjunction();this.consumeChar("/");let n={type:"Flags",loc:{begin:this.idx,end:e.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};for(;this.isRegExpFlag();)switch(this.popChar()){case"g":Bg(n,"global");break;case"i":Bg(n,"ignoreCase");break;case"m":Bg(n,"multiLine");break;case"u":Bg(n,"unicode");break;case"y":Bg(n,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:r,loc:this.loc(0)}}disjunction(){let e=[],r=this.idx;for(e.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),e.push(this.alternative());return{type:"Disjunction",value:e,loc:this.loc(r)}}alternative(){let e=[],r=this.idx;for(;this.isTerm();)e.push(this.term());return{type:"Alternative",value:e,loc:this.loc(r)}}term(){return this.isAssertion()?this.assertion():this.atom()}assertion(){let e=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(e)};case"$":return{type:"EndAnchor",loc:this.loc(e)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(e)};case"B":return{type:"NonWordBoundary",loc:this.loc(e)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");let r;switch(this.popChar()){case"=":r="Lookahead";break;case"!":r="NegativeLookahead";break}fp(r);let n=this.disjunction();return this.consumeChar(")"),{type:r,value:n,loc:this.loc(e)}}return rx()}quantifier(e=!1){let r,n=this.idx;switch(this.popChar()){case"*":r={atLeast:0,atMost:1/0};break;case"+":r={atLeast:1,atMost:1/0};break;case"?":r={atLeast:0,atMost:1};break;case"{":let i=this.integerIncludingZero();switch(this.popChar()){case"}":r={atLeast:i,atMost:i};break;case",":let a;this.isDigit()?(a=this.integerIncludingZero(),r={atLeast:i,atMost:a}):r={atLeast:i,atMost:1/0},this.consumeChar("}");break}if(e===!0&&r===void 0)return;fp(r);break}if(!(e===!0&&r===void 0)&&fp(r))return this.peekChar(0)==="?"?(this.consumeChar("?"),r.greedy=!1):r.greedy=!0,r.type="Quantifier",r.loc=this.loc(n),r}atom(){let e,r=this.idx;switch(this.peekChar()){case".":e=this.dotAll();break;case"\\":e=this.atomEscape();break;case"[":e=this.characterClass();break;case"(":e=this.group();break}return e===void 0&&this.isPatternCharacter()&&(e=this.patternCharacter()),fp(e)?(e.loc=this.loc(r),this.isQuantifier()&&(e.quantifier=this.quantifier()),e):rx()}dotAll(){return this.consumeChar("."),{type:"Set",complement:!0,value:[sr(` +`),sr("\r"),sr("\u2028"),sr("\u2029")]}}atomEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}decimalEscapeAtom(){return{type:"GroupBackReference",value:this.positiveInteger()}}characterClassEscape(){let e,r=!1;switch(this.popChar()){case"d":e=nx;break;case"D":e=nx,r=!0;break;case"s":e=IN;break;case"S":e=IN,r=!0;break;case"w":e=ix;break;case"W":e=ix,r=!0;break}return fp(e)?{type:"Set",value:e,complement:r}:rx()}controlEscapeAtom(){let e;switch(this.popChar()){case"f":e=sr("\f");break;case"n":e=sr(` +`);break;case"r":e=sr("\r");break;case"t":e=sr(" ");break;case"v":e=sr("\v");break}return fp(e)?{type:"Character",value:e}:rx()}controlLetterEscapeAtom(){this.consumeChar("c");let e=this.popChar();if(/[a-zA-Z]/.test(e)===!1)throw Error("Invalid ");return{type:"Character",value:e.toUpperCase().charCodeAt(0)-64}}nulCharacterAtom(){return this.consumeChar("0"),{type:"Character",value:sr("\0")}}hexEscapeSequenceAtom(){return this.consumeChar("x"),this.parseHexDigits(2)}regExpUnicodeEscapeSequenceAtom(){return this.consumeChar("u"),this.parseHexDigits(4)}identityEscapeAtom(){let e=this.popChar();return{type:"Character",value:sr(e)}}classPatternCharacterAtom(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:let e=this.popChar();return{type:"Character",value:sr(e)}}}characterClass(){let e=[],r=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),r=!0);this.isClassAtom();){let n=this.classAtom(),i=n.type==="Character";if(NN(n)&&this.isRangeDash()){this.consumeChar("-");let a=this.classAtom(),s=a.type==="Character";if(NN(a)){if(a.value=this.input.length)throw Error("Unexpected end of input");this.idx++}loc(e){return{begin:e,end:this.idx}}}});var Fc,Mse=N(()=>{"use strict";Fc=class{static{o(this,"BaseRegExpVisitor")}visitChildren(e){for(let r in e){let n=e[r];e.hasOwnProperty(r)&&(n.type!==void 0?this.visit(n):Array.isArray(n)&&n.forEach(i=>{this.visit(i)},this))}}visit(e){switch(e.type){case"Pattern":this.visitPattern(e);break;case"Flags":this.visitFlags(e);break;case"Disjunction":this.visitDisjunction(e);break;case"Alternative":this.visitAlternative(e);break;case"StartAnchor":this.visitStartAnchor(e);break;case"EndAnchor":this.visitEndAnchor(e);break;case"WordBoundary":this.visitWordBoundary(e);break;case"NonWordBoundary":this.visitNonWordBoundary(e);break;case"Lookahead":this.visitLookahead(e);break;case"NegativeLookahead":this.visitNegativeLookahead(e);break;case"Character":this.visitCharacter(e);break;case"Set":this.visitSet(e);break;case"Group":this.visitGroup(e);break;case"GroupBackReference":this.visitGroupBackReference(e);break;case"Quantifier":this.visitQuantifier(e);break}this.visitChildren(e)}visitPattern(e){}visitFlags(e){}visitDisjunction(e){}visitAlternative(e){}visitStartAnchor(e){}visitEndAnchor(e){}visitWordBoundary(e){}visitNonWordBoundary(e){}visitLookahead(e){}visitNegativeLookahead(e){}visitCharacter(e){}visitSet(e){}visitGroup(e){}visitGroupBackReference(e){}visitQuantifier(e){}}});var ax=N(()=>{"use strict";Nse();Mse()});var Bk={};ur(Bk,{NEWLINE_REGEXP:()=>PN,escapeRegExp:()=>mp,getCaseInsensitivePattern:()=>FN,getTerminalParts:()=>RBe,isMultilineComment:()=>BN,isWhitespace:()=>Fg,partialMatches:()=>$N,partialRegExp:()=>Pse,whitespaceCharacters:()=>Ose});function RBe(t){try{typeof t!="string"&&(t=t.source),t=`/${t}/`;let e=Ise.pattern(t),r=[];for(let n of e.value.value)pp.reset(t),pp.visit(n),r.push({start:pp.startRegexp,end:pp.endRegex});return r}catch{return[]}}function BN(t){try{return typeof t=="string"&&(t=new RegExp(t)),t=t.toString(),pp.reset(t),pp.visit(Ise.pattern(t)),pp.multiline}catch{return!1}}function Fg(t){let e=typeof t=="string"?new RegExp(t):t;return Ose.some(r=>e.test(r))}function mp(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function FN(t){return Array.prototype.map.call(t,e=>/\w/.test(e)?`[${e.toLowerCase()}${e.toUpperCase()}]`:mp(e)).join("")}function $N(t,e){let r=Pse(t),n=e.match(r);return!!n&&n[0].length>0}function Pse(t){typeof t=="string"&&(t=new RegExp(t));let e=t,r=t.source,n=0;function i(){let a="",s;function l(h){a+=r.substr(n,h),n+=h}o(l,"appendRaw");function u(h){a+="(?:"+r.substr(n,h)+"|$)",n+=h}for(o(u,"appendOptional");n",n)-n+1);break;default:u(2);break}break;case"[":s=/\[(?:\\.|.)*?\]/g,s.lastIndex=n,s=s.exec(r)||[],u(s[0].length);break;case"|":case"^":case"$":case"*":case"+":case"?":l(1);break;case"{":s=/\{\d+,?\d*\}/g,s.lastIndex=n,s=s.exec(r),s?l(s[0].length):u(1);break;case"(":if(r[n+1]==="?")switch(r[n+2]){case":":a+="(?:",n+=3,a+=i()+"|$)";break;case"=":a+="(?=",n+=3,a+=i()+")";break;case"!":s=n,n+=3,i(),a+=r.substr(s,n-s);break;case"<":switch(r[n+3]){case"=":case"!":s=n,n+=4,i(),a+=r.substr(s,n-s);break;default:l(r.indexOf(">",n)-n+1),a+=i()+"|$)";break}break}else l(1),a+=i()+"|$)";break;case")":return++n,a;default:u(1);break}return a}return o(i,"process"),new RegExp(i(),t.flags)}var PN,Ise,ON,pp,Ose,$g=N(()=>{"use strict";ax();PN=/\r?\n/gm,Ise=new dp,ON=class extends Fc{static{o(this,"TerminalRegExpVisitor")}constructor(){super(...arguments),this.isStarting=!0,this.endRegexpStack=[],this.multiline=!1}get endRegex(){return this.endRegexpStack.join("")}reset(e){this.multiline=!1,this.regex=e,this.startRegexp="",this.isStarting=!0,this.endRegexpStack=[]}visitGroup(e){e.quantifier&&(this.isStarting=!1,this.endRegexpStack=[])}visitCharacter(e){let r=String.fromCharCode(e.value);if(!this.multiline&&r===` +`&&(this.multiline=!0),e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let n=mp(r);this.endRegexpStack.push(n),this.isStarting&&(this.startRegexp+=n)}}visitSet(e){if(!this.multiline){let r=this.regex.substring(e.loc.begin,e.loc.end),n=new RegExp(r);this.multiline=!!` +`.match(n)}if(e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let r=this.regex.substring(e.loc.begin,e.loc.end);this.endRegexpStack.push(r),this.isStarting&&(this.startRegexp+=r)}}visitChildren(e){e.type==="Group"&&e.quantifier||super.visitChildren(e)}},pp=new ON;o(RBe,"getTerminalParts");o(BN,"isMultilineComment");Ose=`\f +\r \v \xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF`.split("");o(Fg,"isWhitespace");o(mp,"escapeRegExp");o(FN,"getCaseInsensitivePattern");o($N,"partialMatches");o(Pse,"partialRegExp")});var $k={};ur($k,{findAssignment:()=>XN,findNameAssignment:()=>Fk,findNodeForKeyword:()=>qN,findNodeForProperty:()=>ox,findNodesForKeyword:()=>NBe,findNodesForKeywordInternal:()=>YN,findNodesForProperty:()=>HN,getActionAtElement:()=>Gse,getActionType:()=>Use,getAllReachableRules:()=>sx,getCrossReferenceTerminal:()=>VN,getEntryRule:()=>Bse,getExplicitRuleType:()=>zg,getHiddenRules:()=>Fse,getRuleType:()=>jN,getRuleTypeName:()=>BBe,getTypeName:()=>cx,isArrayCardinality:()=>IBe,isArrayOperator:()=>OBe,isCommentTerminal:()=>UN,isDataType:()=>PBe,isDataTypeRule:()=>lx,isOptionalCardinality:()=>MBe,terminalRegex:()=>Gg});function Bse(t){return t.rules.find(e=>Fa(e)&&e.entry)}function Fse(t){return t.rules.filter(e=>uo(e)&&e.hidden)}function sx(t,e){let r=new Set,n=Bse(t);if(!n)return new Set(t.rules);let i=[n].concat(Fse(t));for(let s of i)$se(s,r,e);let a=new Set;for(let s of t.rules)(r.has(s.name)||uo(s)&&s.hidden)&&a.add(s);return a}function $se(t,e,r){e.add(t.name),Bc(t).forEach(n=>{if(Bl(n)||r&&Rk(n)){let i=n.rule.ref;i&&!e.has(i.name)&&$se(i,e,r)}})}function VN(t){if(t.terminal)return t.terminal;if(t.type.ref){let e=Fk(t.type.ref);return e?.terminal}}function UN(t){return t.hidden&&!Fg(Gg(t))}function HN(t,e){return!t||!e?[]:WN(t,e,t.astNode,!0)}function ox(t,e,r){if(!t||!e)return;let n=WN(t,e,t.astNode,!0);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function WN(t,e,r,n){if(!n){let i=hp(t.grammarSource,Pl);if(i&&i.feature===e)return[t]}return Ml(t)&&t.astNode===r?t.content.flatMap(i=>WN(i,e,r,!1)):[]}function NBe(t,e){return t?YN(t,e,t?.astNode):[]}function qN(t,e,r){if(!t)return;let n=YN(t,e,t?.astNode);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function YN(t,e,r){if(t.astNode!==r)return[];if(Xo(t.grammarSource)&&t.grammarSource.value===e)return[t];let n=sp(t).iterator(),i,a=[];do if(i=n.next(),!i.done){let s=i.value;s.astNode===r?Xo(s.grammarSource)&&s.grammarSource.value===e&&a.push(s):n.prune()}while(!i.done);return a}function XN(t){var e;let r=t.astNode;for(;r===((e=t.container)===null||e===void 0?void 0:e.astNode);){let n=hp(t.grammarSource,Pl);if(n)return n;t=t.container}}function Fk(t){let e=t;return Ak(e)&&($u(e.$container)?e=e.$container.$container:Fa(e.$container)?e=e.$container:Oc(e.$container)),zse(t,e,new Map)}function zse(t,e,r){var n;function i(a,s){let l;return hp(a,Pl)||(l=zse(s,s,r)),r.set(t,l),l}if(o(i,"go"),r.has(t))return r.get(t);r.set(t,void 0);for(let a of Bc(e)){if(Pl(a)&&a.feature.toLowerCase()==="name")return r.set(t,a),a;if(Bl(a)&&Fa(a.rule.ref))return i(a,a.rule.ref);if(Dk(a)&&(!((n=a.typeRef)===null||n===void 0)&&n.ref))return i(a,a.typeRef.ref)}}function Gse(t){let e=t.$container;if(ff(e)){let r=e.elements,n=r.indexOf(t);for(let i=n-1;i>=0;i--){let a=r[i];if($u(a))return a;{let s=Bc(r[i]).find($u);if(s)return s}}}if(Q2(e))return Gse(e)}function MBe(t,e){return t==="?"||t==="*"||ff(e)&&!!e.guardCondition}function IBe(t){return t==="*"||t==="+"}function OBe(t){return t==="+="}function lx(t){return Vse(t,new Set)}function Vse(t,e){if(e.has(t))return!0;e.add(t);for(let r of Bc(t))if(Bl(r)){if(!r.rule.ref||Fa(r.rule.ref)&&!Vse(r.rule.ref,e))return!1}else{if(Pl(r))return!1;if($u(r))return!1}return!!t.definition}function PBe(t){return GN(t.type,new Set)}function GN(t,e){if(e.has(t))return!0;if(e.add(t),fN(t))return!1;if(vN(t))return!1;if(bN(t))return t.types.every(r=>GN(r,e));if(Dk(t)){if(t.primitiveType!==void 0)return!0;if(t.stringType!==void 0)return!0;if(t.typeRef!==void 0){let r=t.typeRef.ref;return Z2(r)?GN(r.type,e):!1}else return!1}else return!1}function zg(t){if(t.inferredType)return t.inferredType.name;if(t.dataType)return t.dataType;if(t.returnType){let e=t.returnType.ref;if(e){if(Fa(e))return e.name;if(_k(e)||Z2(e))return e.name}}}function cx(t){var e;if(Fa(t))return lx(t)?t.name:(e=zg(t))!==null&&e!==void 0?e:t.name;if(_k(t)||Z2(t)||xN(t))return t.name;if($u(t)){let r=Use(t);if(r)return r}else if(Ak(t))return t.name;throw new Error("Cannot get name of Unknown Type")}function Use(t){var e;if(t.inferredType)return t.inferredType.name;if(!((e=t.type)===null||e===void 0)&&e.ref)return cx(t.type.ref)}function BBe(t){var e,r,n;return uo(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":lx(t)?t.name:(n=zg(t))!==null&&n!==void 0?n:t.name}function jN(t){var e,r,n;return uo(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":(n=zg(t))!==null&&n!==void 0?n:t.name}function Gg(t){let e={s:!1,i:!1,u:!1},r=Vg(t.definition,e),n=Object.entries(e).filter(([,i])=>i).map(([i])=>i).join("");return new RegExp(r,n)}function Vg(t,e){if(SN(t))return FBe(t);if(CN(t))return $Be(t);if(TN(t))return VBe(t);if(Rk(t)){let r=t.rule.ref;if(!r)throw new Error("Missing rule reference.");return zu(Vg(r.definition),{cardinality:t.cardinality,lookahead:t.lookahead})}else{if(kN(t))return GBe(t);if(AN(t))return zBe(t);if(EN(t)){let r=t.regex.lastIndexOf("/"),n=t.regex.substring(1,r),i=t.regex.substring(r+1);return e&&(e.i=i.includes("i"),e.s=i.includes("s"),e.u=i.includes("u")),zu(n,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}else{if(_N(t))return zu(KN,{cardinality:t.cardinality,lookahead:t.lookahead});throw new Error(`Invalid terminal element: ${t?.$type}`)}}}function FBe(t){return zu(t.elements.map(e=>Vg(e)).join("|"),{cardinality:t.cardinality,lookahead:t.lookahead})}function $Be(t){return zu(t.elements.map(e=>Vg(e)).join(""),{cardinality:t.cardinality,lookahead:t.lookahead})}function zBe(t){return zu(`${KN}*?${Vg(t.terminal)}`,{cardinality:t.cardinality,lookahead:t.lookahead})}function GBe(t){return zu(`(?!${Vg(t.terminal)})${KN}*?`,{cardinality:t.cardinality,lookahead:t.lookahead})}function VBe(t){return t.right?zu(`[${zN(t.left)}-${zN(t.right)}]`,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1}):zu(zN(t.left),{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}function zN(t){return mp(t.value)}function zu(t,e){var r;return(e.wrap!==!1||e.lookahead)&&(t=`(${(r=e.lookahead)!==null&&r!==void 0?r:""}${t})`),e.cardinality?`${t}${e.cardinality}`:t}var KN,Fl=N(()=>{"use strict";Sk();Pc();Il();cs();Ol();$g();o(Bse,"getEntryRule");o(Fse,"getHiddenRules");o(sx,"getAllReachableRules");o($se,"ruleDfs");o(VN,"getCrossReferenceTerminal");o(UN,"isCommentTerminal");o(HN,"findNodesForProperty");o(ox,"findNodeForProperty");o(WN,"findNodesForPropertyInternal");o(NBe,"findNodesForKeyword");o(qN,"findNodeForKeyword");o(YN,"findNodesForKeywordInternal");o(XN,"findAssignment");o(Fk,"findNameAssignment");o(zse,"findNameAssignmentInternal");o(Gse,"getActionAtElement");o(MBe,"isOptionalCardinality");o(IBe,"isArrayCardinality");o(OBe,"isArrayOperator");o(lx,"isDataTypeRule");o(Vse,"isDataTypeRuleInternal");o(PBe,"isDataType");o(GN,"isDataTypeInternal");o(zg,"getExplicitRuleType");o(cx,"getTypeName");o(Use,"getActionType");o(BBe,"getRuleTypeName");o(jN,"getRuleType");o(Gg,"terminalRegex");KN=/[\s\S]/.source;o(Vg,"abstractElementToRegex");o(FBe,"terminalAlternativesToRegex");o($Be,"terminalGroupToRegex");o(zBe,"untilTokenToRegex");o(GBe,"negateTokenToRegex");o(VBe,"characterRangeToRegex");o(zN,"keywordToRegex");o(zu,"withCardinality")});function QN(t){let e=[],r=t.Grammar;for(let n of r.rules)uo(n)&&UN(n)&&BN(Gg(n))&&e.push(n.name);return{multilineCommentRules:e,nameRegexp:kk}}var ZN=N(()=>{"use strict";Ol();Fl();$g();Pc();o(QN,"createGrammarConfig")});var JN=N(()=>{"use strict"});function Ug(t){console&&console.error&&console.error(`Error: ${t}`)}function ux(t){console&&console.warn&&console.warn(`Warning: ${t}`)}var Hse=N(()=>{"use strict";o(Ug,"PRINT_ERROR");o(ux,"PRINT_WARNING")});function hx(t){let e=new Date().getTime(),r=t();return{time:new Date().getTime()-e,value:r}}var Wse=N(()=>{"use strict";o(hx,"timer")});function fx(t){function e(){}o(e,"FakeConstructor"),e.prototype=t;let r=new e;function n(){return typeof r.bar}return o(n,"fakeAccess"),n(),n(),t;(0,eval)(t)}var qse=N(()=>{"use strict";o(fx,"toFastProperties")});var Hg=N(()=>{"use strict";Hse();Wse();qse()});function UBe(t){return HBe(t)?t.LABEL:t.name}function HBe(t){return Ti(t.LABEL)&&t.LABEL!==""}function zk(t){return Je(t,Wg)}function Wg(t){function e(r){return Je(r,Wg)}if(o(e,"convertDefinition"),t instanceof on){let r={type:"NonTerminal",name:t.nonTerminalName,idx:t.idx};return Ti(t.label)&&(r.label=t.label),r}else{if(t instanceof Dn)return{type:"Alternative",definition:e(t.definition)};if(t instanceof ln)return{type:"Option",idx:t.idx,definition:e(t.definition)};if(t instanceof Ln)return{type:"RepetitionMandatory",idx:t.idx,definition:e(t.definition)};if(t instanceof Rn)return{type:"RepetitionMandatoryWithSeparator",idx:t.idx,separator:Wg(new Er({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof Tn)return{type:"RepetitionWithSeparator",idx:t.idx,separator:Wg(new Er({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof Pr)return{type:"Repetition",idx:t.idx,definition:e(t.definition)};if(t instanceof wn)return{type:"Alternation",idx:t.idx,definition:e(t.definition)};if(t instanceof Er){let r={type:"Terminal",name:t.terminalType.name,label:UBe(t.terminalType),idx:t.idx};Ti(t.label)&&(r.terminalLabel=t.label);let n=t.terminalType.PATTERN;return t.terminalType.PATTERN&&(r.pattern=Uo(n)?n.source:n),r}else{if(t instanceof us)return{type:"Rule",name:t.name,orgText:t.orgText,definition:e(t.definition)};throw Error("non exhaustive match")}}}var ho,on,us,Dn,ln,Ln,Rn,Pr,Tn,wn,Er,Gk=N(()=>{"use strict";qt();o(UBe,"tokenLabel");o(HBe,"hasTokenLabel");ho=class{static{o(this,"AbstractProduction")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){this._definition=e}accept(e){e.visit(this),Ae(this.definition,r=>{r.accept(e)})}},on=class extends ho{static{o(this,"NonTerminal")}constructor(e){super([]),this.idx=1,pa(this,zs(e,r=>r!==void 0))}set definition(e){}get definition(){return this.referencedRule!==void 0?this.referencedRule.definition:[]}accept(e){e.visit(this)}},us=class extends ho{static{o(this,"Rule")}constructor(e){super(e.definition),this.orgText="",pa(this,zs(e,r=>r!==void 0))}},Dn=class extends ho{static{o(this,"Alternative")}constructor(e){super(e.definition),this.ignoreAmbiguities=!1,pa(this,zs(e,r=>r!==void 0))}},ln=class extends ho{static{o(this,"Option")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Ln=class extends ho{static{o(this,"RepetitionMandatory")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Rn=class extends ho{static{o(this,"RepetitionMandatoryWithSeparator")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Pr=class extends ho{static{o(this,"Repetition")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Tn=class extends ho{static{o(this,"RepetitionWithSeparator")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},wn=class extends ho{static{o(this,"Alternation")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){super(e.definition),this.idx=1,this.ignoreAmbiguities=!1,this.hasPredicates=!1,pa(this,zs(e,r=>r!==void 0))}},Er=class{static{o(this,"Terminal")}constructor(e){this.idx=1,pa(this,zs(e,r=>r!==void 0))}accept(e){e.visit(this)}};o(zk,"serializeGrammar");o(Wg,"serializeProduction")});var hs,Yse=N(()=>{"use strict";Gk();hs=class{static{o(this,"GAstVisitor")}visit(e){let r=e;switch(r.constructor){case on:return this.visitNonTerminal(r);case Dn:return this.visitAlternative(r);case ln:return this.visitOption(r);case Ln:return this.visitRepetitionMandatory(r);case Rn:return this.visitRepetitionMandatoryWithSeparator(r);case Tn:return this.visitRepetitionWithSeparator(r);case Pr:return this.visitRepetition(r);case wn:return this.visitAlternation(r);case Er:return this.visitTerminal(r);case us:return this.visitRule(r);default:throw Error("non exhaustive match")}}visitNonTerminal(e){}visitAlternative(e){}visitOption(e){}visitRepetition(e){}visitRepetitionMandatory(e){}visitRepetitionMandatoryWithSeparator(e){}visitRepetitionWithSeparator(e){}visitAlternation(e){}visitTerminal(e){}visitRule(e){}}});function eM(t){return t instanceof Dn||t instanceof ln||t instanceof Pr||t instanceof Ln||t instanceof Rn||t instanceof Tn||t instanceof Er||t instanceof us}function gp(t,e=[]){return t instanceof ln||t instanceof Pr||t instanceof Tn?!0:t instanceof wn?B2(t.definition,n=>gp(n,e)):t instanceof on&&Xn(e,t)?!1:t instanceof ho?(t instanceof on&&e.push(t),Pa(t.definition,n=>gp(n,e))):!1}function tM(t){return t instanceof wn}function Vs(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof wn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof Tn)return"MANY_SEP";if(t instanceof Pr)return"MANY";if(t instanceof Er)return"CONSUME";throw Error("non exhaustive match")}var Xse=N(()=>{"use strict";qt();Gk();o(eM,"isSequenceProd");o(gp,"isOptionalProd");o(tM,"isBranchingProd");o(Vs,"getProductionDslName")});var fs=N(()=>{"use strict";Gk();Yse();Xse()});function jse(t,e,r){return[new ln({definition:[new Er({terminalType:t.separator})].concat(t.definition)})].concat(e,r)}var Gu,Vk=N(()=>{"use strict";qt();fs();Gu=class{static{o(this,"RestWalker")}walk(e,r=[]){Ae(e.definition,(n,i)=>{let a=bi(e.definition,i+1);if(n instanceof on)this.walkProdRef(n,a,r);else if(n instanceof Er)this.walkTerminal(n,a,r);else if(n instanceof Dn)this.walkFlat(n,a,r);else if(n instanceof ln)this.walkOption(n,a,r);else if(n instanceof Ln)this.walkAtLeastOne(n,a,r);else if(n instanceof Rn)this.walkAtLeastOneSep(n,a,r);else if(n instanceof Tn)this.walkManySep(n,a,r);else if(n instanceof Pr)this.walkMany(n,a,r);else if(n instanceof wn)this.walkOr(n,a,r);else throw Error("non exhaustive match")})}walkTerminal(e,r,n){}walkProdRef(e,r,n){}walkFlat(e,r,n){let i=r.concat(n);this.walk(e,i)}walkOption(e,r,n){let i=r.concat(n);this.walk(e,i)}walkAtLeastOne(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkAtLeastOneSep(e,r,n){let i=jse(e,r,n);this.walk(e,i)}walkMany(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkManySep(e,r,n){let i=jse(e,r,n);this.walk(e,i)}walkOr(e,r,n){let i=r.concat(n);Ae(e.definition,a=>{let s=new Dn({definition:[a]});this.walk(s,i)})}};o(jse,"restForRepetitionWithSeparator")});function yp(t){if(t instanceof on)return yp(t.referencedRule);if(t instanceof Er)return YBe(t);if(eM(t))return WBe(t);if(tM(t))return qBe(t);throw Error("non exhaustive match")}function WBe(t){let e=[],r=t.definition,n=0,i=r.length>n,a,s=!0;for(;i&&s;)a=r[n],s=gp(a),e=e.concat(yp(a)),n=n+1,i=r.length>n;return qm(e)}function qBe(t){let e=Je(t.definition,r=>yp(r));return qm(qr(e))}function YBe(t){return[t.terminalType]}var rM=N(()=>{"use strict";qt();fs();o(yp,"first");o(WBe,"firstForSequence");o(qBe,"firstForBranching");o(YBe,"firstForTerminal")});var Uk,nM=N(()=>{"use strict";Uk="_~IN~_"});function Kse(t){let e={};return Ae(t,r=>{let n=new iM(r).startWalking();pa(e,n)}),e}function XBe(t,e){return t.name+e+Uk}var iM,Qse=N(()=>{"use strict";Vk();rM();qt();nM();fs();iM=class extends Gu{static{o(this,"ResyncFollowsWalker")}constructor(e){super(),this.topProd=e,this.follows={}}startWalking(){return this.walk(this.topProd),this.follows}walkTerminal(e,r,n){}walkProdRef(e,r,n){let i=XBe(e.referencedRule,e.idx)+this.topProd.name,a=r.concat(n),s=new Dn({definition:a}),l=yp(s);this.follows[i]=l}};o(Kse,"computeAllProdsFollows");o(XBe,"buildBetweenProdsFollowPrefix")});function qg(t){let e=t.toString();if(Hk.hasOwnProperty(e))return Hk[e];{let r=jBe.pattern(e);return Hk[e]=r,r}}function Zse(){Hk={}}var Hk,jBe,Wk=N(()=>{"use strict";ax();Hk={},jBe=new dp;o(qg,"getRegExpAst");o(Zse,"clearRegExpParserCache")});function toe(t,e=!1){try{let r=qg(t);return aM(r.value,{},r.flags.ignoreCase)}catch(r){if(r.message===eoe)e&&ux(`${dx} Unable to optimize: < ${t.toString()} > + Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{let n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),Ug(`${dx} + Failed parsing: < ${t.toString()} > + Using the @chevrotain/regexp-to-ast library + Please open an issue at: https://github.com/chevrotain/chevrotain/issues`+n)}}return[]}function aM(t,e,r){switch(t.type){case"Disjunction":for(let i=0;i{if(typeof u=="number")qk(u,e,r);else{let h=u;if(r===!0)for(let f=h.from;f<=h.to;f++)qk(f,e,r);else{for(let f=h.from;f<=h.to&&f=Yg){let f=h.from>=Yg?h.from:Yg,d=h.to,p=$c(f),m=$c(d);for(let g=p;g<=m;g++)e[g]=g}}}});break;case"Group":aM(s.value,e,r);break;default:throw Error("Non Exhaustive Match")}let l=s.quantifier!==void 0&&s.quantifier.atLeast===0;if(s.type==="Group"&&sM(s)===!1||s.type!=="Group"&&l===!1)break}break;default:throw Error("non exhaustive match!")}return br(e)}function qk(t,e,r){let n=$c(t);e[n]=n,r===!0&&KBe(t,e)}function KBe(t,e){let r=String.fromCharCode(t),n=r.toUpperCase();if(n!==r){let i=$c(n.charCodeAt(0));e[i]=i}else{let i=r.toLowerCase();if(i!==r){let a=$c(i.charCodeAt(0));e[a]=a}}}function Jse(t,e){return ls(t.value,r=>{if(typeof r=="number")return Xn(e,r);{let n=r;return ls(e,i=>n.from<=i&&i<=n.to)!==void 0}})}function sM(t){let e=t.quantifier;return e&&e.atLeast===0?!0:t.value?Pt(t.value)?Pa(t.value,sM):sM(t.value):!1}function Yk(t,e){if(e instanceof RegExp){let r=qg(e),n=new oM(t);return n.visit(r),n.found}else return ls(e,r=>Xn(t,r.charCodeAt(0)))!==void 0}var eoe,dx,oM,roe=N(()=>{"use strict";ax();qt();Hg();Wk();lM();eoe="Complement Sets are not supported for first char optimization",dx=`Unable to use "first char" lexer optimizations: +`;o(toe,"getOptimizedStartCodesIndices");o(aM,"firstCharOptimizedIndices");o(qk,"addOptimizedIdxToResult");o(KBe,"handleIgnoreCase");o(Jse,"findCode");o(sM,"isWholeOptional");oM=class extends Fc{static{o(this,"CharCodeFinder")}constructor(e){super(),this.targetCharCodes=e,this.found=!1}visitChildren(e){if(this.found!==!0){switch(e.type){case"Lookahead":this.visitLookahead(e);return;case"NegativeLookahead":this.visitNegativeLookahead(e);return}super.visitChildren(e)}}visitCharacter(e){Xn(this.targetCharCodes,e.value)&&(this.found=!0)}visitSet(e){e.complement?Jse(e,this.targetCharCodes)===void 0&&(this.found=!0):Jse(e,this.targetCharCodes)!==void 0&&(this.found=!0)}};o(Yk,"canMatchCharCode")});function aoe(t,e){e=nf(e,{useSticky:uM,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:o((b,T)=>T(),"tracer")});let r=e.tracer;r("initCharCodeToOptimizedIndexMap",()=>{pFe()});let n;r("Reject Lexer.NA",()=>{n=sf(t,b=>b[vp]===Kn.NA)});let i=!1,a;r("Transform Patterns",()=>{i=!1,a=Je(n,b=>{let T=b[vp];if(Uo(T)){let S=T.source;return S.length===1&&S!=="^"&&S!=="$"&&S!=="."&&!T.ignoreCase?S:S.length===2&&S[0]==="\\"&&!Xn(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],S[1])?S[1]:e.useSticky?ioe(T):noe(T)}else{if(Ai(T))return i=!0,{exec:T};if(typeof T=="object")return i=!0,T;if(typeof T=="string"){if(T.length===1)return T;{let S=T.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),w=new RegExp(S);return e.useSticky?ioe(w):noe(w)}}else throw Error("non exhaustive match")}})});let s,l,u,h,f;r("misc mapping",()=>{s=Je(n,b=>b.tokenTypeIdx),l=Je(n,b=>{let T=b.GROUP;if(T!==Kn.SKIPPED){if(Ti(T))return T;if(mr(T))return!1;throw Error("non exhaustive match")}}),u=Je(n,b=>{let T=b.LONGER_ALT;if(T)return Pt(T)?Je(T,w=>ik(n,w)):[ik(n,T)]}),h=Je(n,b=>b.PUSH_MODE),f=Je(n,b=>Bt(b,"POP_MODE"))});let d;r("Line Terminator Handling",()=>{let b=doe(e.lineTerminatorCharacters);d=Je(n,T=>!1),e.positionTracking!=="onlyOffset"&&(d=Je(n,T=>Bt(T,"LINE_BREAKS")?!!T.LINE_BREAKS:foe(T,b)===!1&&Yk(b,T.PATTERN)))});let p,m,g,y;r("Misc Mapping #2",()=>{p=Je(n,uoe),m=Je(a,fFe),g=Xr(n,(b,T)=>{let S=T.GROUP;return Ti(S)&&S!==Kn.SKIPPED&&(b[S]=[]),b},{}),y=Je(a,(b,T)=>({pattern:a[T],longerAlt:u[T],canLineTerminator:d[T],isCustom:p[T],short:m[T],group:l[T],push:h[T],pop:f[T],tokenTypeIdx:s[T],tokenType:n[T]}))});let v=!0,x=[];return e.safeMode||r("First Char Optimization",()=>{x=Xr(n,(b,T,S)=>{if(typeof T.PATTERN=="string"){let w=T.PATTERN.charCodeAt(0),E=$c(w);cM(b,E,y[S])}else if(Pt(T.START_CHARS_HINT)){let w;Ae(T.START_CHARS_HINT,E=>{let _=typeof E=="string"?E.charCodeAt(0):E,C=$c(_);w!==C&&(w=C,cM(b,C,y[S]))})}else if(Uo(T.PATTERN))if(T.PATTERN.unicode)v=!1,e.ensureOptimizations&&Ug(`${dx} Unable to analyze < ${T.PATTERN.toString()} > pattern. + The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{let w=toe(T.PATTERN,e.ensureOptimizations);hr(w)&&(v=!1),Ae(w,E=>{cM(b,E,y[S])})}else e.ensureOptimizations&&Ug(`${dx} TokenType: <${T.name}> is using a custom token pattern without providing parameter. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),v=!1;return b},[])}),{emptyGroups:g,patternIdxToConfig:y,charCodeToPatternIdxToConfig:x,hasCustom:i,canBeOptimized:v}}function soe(t,e){let r=[],n=ZBe(t);r=r.concat(n.errors);let i=JBe(n.valid),a=i.valid;return r=r.concat(i.errors),r=r.concat(QBe(a)),r=r.concat(oFe(a)),r=r.concat(lFe(a,e)),r=r.concat(cFe(a)),r}function QBe(t){let e=[],r=Yr(t,n=>Uo(n[vp]));return e=e.concat(tFe(r)),e=e.concat(iFe(r)),e=e.concat(aFe(r)),e=e.concat(sFe(r)),e=e.concat(rFe(r)),e}function ZBe(t){let e=Yr(t,i=>!Bt(i,vp)),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- missing static 'PATTERN' property",type:jn.MISSING_PATTERN,tokenTypes:[i]})),n=af(t,e);return{errors:r,valid:n}}function JBe(t){let e=Yr(t,i=>{let a=i[vp];return!Uo(a)&&!Ai(a)&&!Bt(a,"exec")&&!Ti(a)}),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:jn.INVALID_PATTERN,tokenTypes:[i]})),n=af(t,e);return{errors:r,valid:n}}function tFe(t){class e extends Fc{static{o(this,"EndAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitEndAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=qg(a),l=new e;return l.visit(s),l.found}catch{return eFe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error: + Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:jn.EOI_ANCHOR_FOUND,tokenTypes:[i]}))}function rFe(t){let e=Yr(t,n=>n.PATTERN.test(""));return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' must not match an empty string",type:jn.EMPTY_MATCH_PATTERN,tokenTypes:[n]}))}function iFe(t){class e extends Fc{static{o(this,"StartAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitStartAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=qg(a),l=new e;return l.visit(s),l.found}catch{return nFe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error: + Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:jn.SOI_ANCHOR_FOUND,tokenTypes:[i]}))}function aFe(t){let e=Yr(t,n=>{let i=n[vp];return i instanceof RegExp&&(i.multiline||i.global)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:jn.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[n]}))}function sFe(t){let e=[],r=Je(t,a=>Xr(t,(s,l)=>(a.PATTERN.source===l.PATTERN.source&&!Xn(e,l)&&l.PATTERN!==Kn.NA&&(e.push(l),s.push(l)),s),[]));r=Ac(r);let n=Yr(r,a=>a.length>1);return Je(n,a=>{let s=Je(a,u=>u.name);return{message:`The same RegExp pattern ->${ia(a).PATTERN}<-has been used in all of the following Token Types: ${s.join(", ")} <-`,type:jn.DUPLICATE_PATTERNS_FOUND,tokenTypes:a}})}function oFe(t){let e=Yr(t,n=>{if(!Bt(n,"GROUP"))return!1;let i=n.GROUP;return i!==Kn.SKIPPED&&i!==Kn.NA&&!Ti(i)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:jn.INVALID_GROUP_TYPE_FOUND,tokenTypes:[n]}))}function lFe(t,e){let r=Yr(t,i=>i.PUSH_MODE!==void 0&&!Xn(e,i.PUSH_MODE));return Je(r,i=>({message:`Token Type: ->${i.name}<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->${i.PUSH_MODE}<-which does not exist`,type:jn.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[i]}))}function cFe(t){let e=[],r=Xr(t,(n,i,a)=>{let s=i.PATTERN;return s===Kn.NA||(Ti(s)?n.push({str:s,idx:a,tokenType:i}):Uo(s)&&hFe(s)&&n.push({str:s.source,idx:a,tokenType:i})),n},[]);return Ae(t,(n,i)=>{Ae(r,({str:a,idx:s,tokenType:l})=>{if(i${l.name}<- can never be matched. +Because it appears AFTER the Token Type ->${n.name}<-in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:u,type:jn.UNREACHABLE_PATTERN,tokenTypes:[n,l]})}})}),e}function uFe(t,e){if(Uo(e)){let r=e.exec(t);return r!==null&&r.index===0}else{if(Ai(e))return e(t,0,[],{});if(Bt(e,"exec"))return e.exec(t,0,[],{});if(typeof e=="string")return e===t;throw Error("non exhaustive match")}}function hFe(t){return ls([".","\\","[","]","|","^","$","(",")","?","*","+","{"],r=>t.source.indexOf(r)!==-1)===void 0}function noe(t){let e=t.ignoreCase?"i":"";return new RegExp(`^(?:${t.source})`,e)}function ioe(t){let e=t.ignoreCase?"iy":"y";return new RegExp(`${t.source}`,e)}function ooe(t,e,r){let n=[];return Bt(t,Xg)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+Xg+`> property in its definition +`,type:jn.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),Bt(t,Xk)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+Xk+`> property in its definition +`,type:jn.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),Bt(t,Xk)&&Bt(t,Xg)&&!Bt(t.modes,t.defaultMode)&&n.push({message:`A MultiMode Lexer cannot be initialized with a ${Xg}: <${t.defaultMode}>which does not exist +`,type:jn.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),Bt(t,Xk)&&Ae(t.modes,(i,a)=>{Ae(i,(s,l)=>{if(mr(s))n.push({message:`A Lexer cannot be initialized using an undefined Token Type. Mode:<${a}> at index: <${l}> +`,type:jn.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED});else if(Bt(s,"LONGER_ALT")){let u=Pt(s.LONGER_ALT)?s.LONGER_ALT:[s.LONGER_ALT];Ae(u,h=>{!mr(h)&&!Xn(i,h)&&n.push({message:`A MultiMode Lexer cannot be initialized with a longer_alt <${h.name}> on token <${s.name}> outside of mode <${a}> +`,type:jn.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE})})}})}),n}function loe(t,e,r){let n=[],i=!1,a=Ac(qr(br(t.modes))),s=sf(a,u=>u[vp]===Kn.NA),l=doe(r);return e&&Ae(s,u=>{let h=foe(u,l);if(h!==!1){let d={message:dFe(u,h),type:h.issue,tokenType:u};n.push(d)}else Bt(u,"LINE_BREAKS")?u.LINE_BREAKS===!0&&(i=!0):Yk(l,u.PATTERN)&&(i=!0)}),e&&!i&&n.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:jn.NO_LINE_BREAKS_FLAGS}),n}function coe(t){let e={},r=zr(t);return Ae(r,n=>{let i=t[n];if(Pt(i))e[n]=[];else throw Error("non exhaustive match")}),e}function uoe(t){let e=t.PATTERN;if(Uo(e))return!1;if(Ai(e))return!0;if(Bt(e,"exec"))return!0;if(Ti(e))return!1;throw Error("non exhaustive match")}function fFe(t){return Ti(t)&&t.length===1?t.charCodeAt(0):!1}function foe(t,e){if(Bt(t,"LINE_BREAKS"))return!1;if(Uo(t.PATTERN)){try{Yk(e,t.PATTERN)}catch(r){return{issue:jn.IDENTIFY_TERMINATOR,errMsg:r.message}}return!1}else{if(Ti(t.PATTERN))return!1;if(uoe(t))return{issue:jn.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}}function dFe(t,e){if(e.issue===jn.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern. + The problem is in the <${t.name}> Token Type + Root cause: ${e.errMsg}. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR`;if(e.issue===jn.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. + The problem is in the <${t.name}> Token Type + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK`;throw Error("non exhaustive match")}function doe(t){return Je(t,r=>Ti(r)?r.charCodeAt(0):r)}function cM(t,e,r){t[e]===void 0?t[e]=[r]:t[e].push(r)}function $c(t){return t255?255+~~(t/255):t}}var vp,Xg,Xk,uM,eFe,nFe,hoe,Yg,jk,lM=N(()=>{"use strict";ax();px();qt();Hg();roe();Wk();vp="PATTERN",Xg="defaultMode",Xk="modes",uM=typeof new RegExp("(?:)").sticky=="boolean";o(aoe,"analyzeTokenTypes");o(soe,"validatePatterns");o(QBe,"validateRegExpPattern");o(ZBe,"findMissingPatterns");o(JBe,"findInvalidPatterns");eFe=/[^\\][$]/;o(tFe,"findEndOfInputAnchor");o(rFe,"findEmptyMatchRegExps");nFe=/[^\\[][\^]|^\^/;o(iFe,"findStartOfInputAnchor");o(aFe,"findUnsupportedFlags");o(sFe,"findDuplicatePatterns");o(oFe,"findInvalidGroupType");o(lFe,"findModesThatDoNotExist");o(cFe,"findUnreachablePatterns");o(uFe,"testTokenType");o(hFe,"noMetaChar");o(noe,"addStartOfInput");o(ioe,"addStickyFlag");o(ooe,"performRuntimeChecks");o(loe,"performWarningRuntimeChecks");o(coe,"cloneEmptyGroups");o(uoe,"isCustomPattern");o(fFe,"isShortPattern");hoe={test:o(function(t){let e=t.length;for(let r=this.lastIndex;r{r.isParent=r.categoryMatches.length>0})}function mFe(t){let e=an(t),r=t,n=!0;for(;n;){r=Ac(qr(Je(r,a=>a.CATEGORIES)));let i=af(r,e);e=e.concat(i),hr(i)?n=!1:r=i}return e}function gFe(t){Ae(t,e=>{hM(e)||(goe[poe]=e,e.tokenTypeIdx=poe++),moe(e)&&!Pt(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),moe(e)||(e.CATEGORIES=[]),xFe(e)||(e.categoryMatches=[]),bFe(e)||(e.categoryMatchesMap={})})}function yFe(t){Ae(t,e=>{e.categoryMatches=[],Ae(e.categoryMatchesMap,(r,n)=>{e.categoryMatches.push(goe[n].tokenTypeIdx)})})}function vFe(t){Ae(t,e=>{yoe([],e)})}function yoe(t,e){Ae(t,r=>{e.categoryMatchesMap[r.tokenTypeIdx]=!0}),Ae(e.CATEGORIES,r=>{let n=t.concat(e);Xn(n,r)||yoe(n,r)})}function hM(t){return Bt(t,"tokenTypeIdx")}function moe(t){return Bt(t,"CATEGORIES")}function xFe(t){return Bt(t,"categoryMatches")}function bFe(t){return Bt(t,"categoryMatchesMap")}function voe(t){return Bt(t,"tokenTypeIdx")}var poe,goe,xp=N(()=>{"use strict";qt();o(Vu,"tokenStructuredMatcher");o(jg,"tokenStructuredMatcherNoCategories");poe=1,goe={};o(Uu,"augmentTokenTypes");o(mFe,"expandCategories");o(gFe,"assignTokenDefaultProps");o(yFe,"assignCategoriesTokensProp");o(vFe,"assignCategoriesMapProp");o(yoe,"singleAssignCategoriesToksMap");o(hM,"hasShortKeyProperty");o(moe,"hasCategoriesProperty");o(xFe,"hasExtendingTokensTypesProperty");o(bFe,"hasExtendingTokensTypesMapProperty");o(voe,"isTokenType")});var Kg,fM=N(()=>{"use strict";Kg={buildUnableToPopLexerModeMessage(t){return`Unable to pop Lexer Mode after encountering Token ->${t.image}<- The Mode Stack is empty`},buildUnexpectedCharactersMessage(t,e,r,n,i){return`unexpected character: ->${t.charAt(e)}<- at offset: ${e}, skipped ${r} characters.`}}});var jn,mx,Kn,px=N(()=>{"use strict";lM();qt();Hg();xp();fM();Wk();(function(t){t[t.MISSING_PATTERN=0]="MISSING_PATTERN",t[t.INVALID_PATTERN=1]="INVALID_PATTERN",t[t.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",t[t.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",t[t.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",t[t.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",t[t.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",t[t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",t[t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",t[t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",t[t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",t[t.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",t[t.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",t[t.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",t[t.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",t[t.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",t[t.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK",t[t.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE=17]="MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE"})(jn||(jn={}));mx={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:Kg,traceInitPerf:!1,skipValidations:!1,recoveryEnabled:!0};Object.freeze(mx);Kn=class{static{o(this,"Lexer")}constructor(e,r=mx){if(this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},this.TRACE_INIT=(i,a)=>{if(this.traceInitPerf===!0){this.traceInitIndent++;let s=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <${i}>`);let{time:l,value:u}=hx(a),h=l>10?console.warn:console.log;return this.traceInitIndent time: ${l}ms`),this.traceInitIndent--,u}else return a()},typeof r=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=pa({},mx,r);let n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",()=>{let i,a=!0;this.TRACE_INIT("Lexer Config handling",()=>{if(this.config.lineTerminatorsPattern===mx.lineTerminatorsPattern)this.config.lineTerminatorsPattern=hoe;else if(this.config.lineTerminatorCharacters===mx.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(r.safeMode&&r.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking),Pt(e)?i={modes:{defaultMode:an(e)},defaultMode:Xg}:(a=!1,i=an(e))}),this.config.skipValidations===!1&&(this.TRACE_INIT("performRuntimeChecks",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(ooe(i,this.trackStartLines,this.config.lineTerminatorCharacters))}),this.TRACE_INIT("performWarningRuntimeChecks",()=>{this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(loe(i,this.trackStartLines,this.config.lineTerminatorCharacters))})),i.modes=i.modes?i.modes:{},Ae(i.modes,(l,u)=>{i.modes[u]=sf(l,h=>mr(h))});let s=zr(i.modes);if(Ae(i.modes,(l,u)=>{this.TRACE_INIT(`Mode: <${u}> processing`,()=>{if(this.modes.push(u),this.config.skipValidations===!1&&this.TRACE_INIT("validatePatterns",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(soe(l,s))}),hr(this.lexerDefinitionErrors)){Uu(l);let h;this.TRACE_INIT("analyzeTokenTypes",()=>{h=aoe(l,{lineTerminatorCharacters:this.config.lineTerminatorCharacters,positionTracking:r.positionTracking,ensureOptimizations:r.ensureOptimizations,safeMode:r.safeMode,tracer:this.TRACE_INIT})}),this.patternIdxToConfig[u]=h.patternIdxToConfig,this.charCodeToPatternIdxToConfig[u]=h.charCodeToPatternIdxToConfig,this.emptyGroups=pa({},this.emptyGroups,h.emptyGroups),this.hasCustom=h.hasCustom||this.hasCustom,this.canModeBeOptimized[u]=h.canBeOptimized}})}),this.defaultMode=i.defaultMode,!hr(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){let u=Je(this.lexerDefinitionErrors,h=>h.message).join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+u)}Ae(this.lexerDefinitionWarning,l=>{ux(l.message)}),this.TRACE_INIT("Choosing sub-methods implementations",()=>{if(uM?(this.chopInput=ta,this.match=this.matchWithTest):(this.updateLastIndex=ai,this.match=this.matchWithExec),a&&(this.handleModes=ai),this.trackStartLines===!1&&(this.computeNewColumn=ta),this.trackEndLines===!1&&(this.updateTokenEndLineColumnLocation=ai),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else if(/onlyOffset/i.test(this.config.positionTracking))this.createTokenInstance=this.createOffsetOnlyToken;else throw Error(`Invalid config option: "${this.config.positionTracking}"`);this.hasCustom?(this.addToken=this.addTokenUsingPush,this.handlePayload=this.handlePayloadWithCustom):(this.addToken=this.addTokenUsingMemberAccess,this.handlePayload=this.handlePayloadNoCustom)}),this.TRACE_INIT("Failed Optimization Warnings",()=>{let l=Xr(this.canModeBeOptimized,(u,h,f)=>(h===!1&&u.push(f),u),[]);if(r.ensureOptimizations&&!hr(l))throw Error(`Lexer Modes: < ${l.join(", ")} > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),this.TRACE_INIT("clearRegExpParserCache",()=>{Zse()}),this.TRACE_INIT("toFastProperties",()=>{fx(this)})})}tokenize(e,r=this.defaultMode){if(!hr(this.lexerDefinitionErrors)){let i=Je(this.lexerDefinitionErrors,a=>a.message).join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+i)}return this.tokenizeInternal(e,r)}tokenizeInternal(e,r){let n,i,a,s,l,u,h,f,d,p,m,g,y,v,x,b,T=e,S=T.length,w=0,E=0,_=this.hasCustom?0:Math.floor(e.length/10),C=new Array(_),D=[],O=this.trackStartLines?1:void 0,R=this.trackStartLines?1:void 0,k=coe(this.emptyGroups),L=this.trackStartLines,A=this.config.lineTerminatorsPattern,I=0,M=[],P=[],B=[],F=[];Object.freeze(F);let z;function $(){return M}o($,"getPossiblePatternsSlow");function U(Z){let ue=$c(Z),Q=P[ue];return Q===void 0?F:Q}o(U,"getPossiblePatternsOptimized");let K=o(Z=>{if(B.length===1&&Z.tokenType.PUSH_MODE===void 0){let ue=this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(Z);D.push({offset:Z.startOffset,line:Z.startLine,column:Z.startColumn,length:Z.image.length,message:ue})}else{B.pop();let ue=ma(B);M=this.patternIdxToConfig[ue],P=this.charCodeToPatternIdxToConfig[ue],I=M.length;let Q=this.canModeBeOptimized[ue]&&this.config.safeMode===!1;P&&Q?z=U:z=$}},"pop_mode");function ee(Z){B.push(Z),P=this.charCodeToPatternIdxToConfig[Z],M=this.patternIdxToConfig[Z],I=M.length,I=M.length;let ue=this.canModeBeOptimized[Z]&&this.config.safeMode===!1;P&&ue?z=U:z=$}o(ee,"push_mode"),ee.call(this,r);let Y,ce=this.config.recoveryEnabled;for(;wu.length){u=s,h=f,Y=he;break}}}break}}if(u!==null){if(d=u.length,p=Y.group,p!==void 0&&(m=Y.tokenTypeIdx,g=this.createTokenInstance(u,w,m,Y.tokenType,O,R,d),this.handlePayload(g,h),p===!1?E=this.addToken(C,E,g):k[p].push(g)),e=this.chopInput(e,d),w=w+d,R=this.computeNewColumn(R,d),L===!0&&Y.canLineTerminator===!0){let j=0,ne,te;A.lastIndex=0;do ne=A.test(u),ne===!0&&(te=A.lastIndex-1,j++);while(ne===!0);j!==0&&(O=O+j,R=d-te,this.updateTokenEndLineColumnLocation(g,p,te,j,O,R,d))}this.handleModes(Y,K,ee,g)}else{let j=w,ne=O,te=R,he=ce===!1;for(;he===!1&&w{"use strict";qt();px();xp();o(Hu,"tokenLabel");o(dM,"hasTokenLabel");TFe="parent",xoe="categories",boe="label",Toe="group",woe="push_mode",koe="pop_mode",Eoe="longer_alt",Soe="line_breaks",Coe="start_chars_hint";o(df,"createToken");o(wFe,"createTokenInternal");fo=df({name:"EOF",pattern:Kn.NA});Uu([fo]);o(Wu,"createTokenInstance");o(gx,"tokenMatcher")});var qu,Aoe,$l,Qg=N(()=>{"use strict";bp();qt();fs();qu={buildMismatchTokenMessage({expected:t,actual:e,previous:r,ruleName:n}){return`Expecting ${dM(t)?`--> ${Hu(t)} <--`:`token of type --> ${t.name} <--`} but found --> '${e.image}' <--`},buildNotAllInputParsedMessage({firstRedundant:t,ruleName:e}){return"Redundant input, expecting EOF but found: "+t.image},buildNoViableAltMessage({expectedPathsPerAlt:t,actual:e,previous:r,customUserDescription:n,ruleName:i}){let a="Expecting: ",l=` +but found: '`+ia(e).image+"'";if(n)return a+n+l;{let u=Xr(t,(p,m)=>p.concat(m),[]),h=Je(u,p=>`[${Je(p,m=>Hu(m)).join(", ")}]`),d=`one of these possible Token sequences: +${Je(h,(p,m)=>` ${m+1}. ${p}`).join(` +`)}`;return a+d+l}},buildEarlyExitMessage({expectedIterationPaths:t,actual:e,customUserDescription:r,ruleName:n}){let i="Expecting: ",s=` +but found: '`+ia(e).image+"'";if(r)return i+r+s;{let u=`expecting at least one iteration which starts with one of these possible Token sequences:: + <${Je(t,h=>`[${Je(h,f=>Hu(f)).join(",")}]`).join(" ,")}>`;return i+u+s}}};Object.freeze(qu);Aoe={buildRuleNotFoundError(t,e){return"Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+t.name+"<-"}},$l={buildDuplicateFoundError(t,e){function r(f){return f instanceof Er?f.terminalType.name:f instanceof on?f.nonTerminalName:""}o(r,"getExtraProductionArgument");let n=t.name,i=ia(e),a=i.idx,s=Vs(i),l=r(i),u=a>0,h=`->${s}${u?a:""}<- ${l?`with argument: ->${l}<-`:""} + appears more than once (${e.length} times) in the top level rule: ->${n}<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return h=h.replace(/[ \t]+/g," "),h=h.replace(/\s\s+/g,` +`),h},buildNamespaceConflictError(t){return`Namespace conflict found in grammar. +The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${t.name}>. +To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`},buildAlternationPrefixAmbiguityError(t){let e=Je(t.prefixPath,i=>Hu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx;return`Ambiguous alternatives: <${t.ambiguityIndices.join(" ,")}> due to common lookahead prefix +in inside <${t.topLevelRule.name}> Rule, +<${e}> may appears as a prefix path in all these alternatives. +See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`},buildAlternationAmbiguityError(t){let e=Je(t.prefixPath,i=>Hu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(" ,")}> in inside <${t.topLevelRule.name}> Rule, +<${e}> may appears as a prefix path in all these alternatives. +`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,n},buildEmptyRepetitionError(t){let e=Vs(t.repetition);return t.repetition.idx!==0&&(e+=t.repetition.idx),`The repetition <${e}> within Rule <${t.topLevelRule.name}> can never consume any tokens. +This could lead to an infinite loop.`},buildTokenNameError(t){return"deprecated"},buildEmptyAlternationError(t){return`Ambiguous empty alternative: <${t.emptyChoiceIdx+1}> in inside <${t.topLevelRule.name}> Rule. +Only the last alternative may be an empty alternative.`},buildTooManyAlternativesError(t){return`An Alternation cannot have more than 256 alternatives: + inside <${t.topLevelRule.name}> Rule. + has ${t.alternation.definition.length+1} alternatives.`},buildLeftRecursionError(t){let e=t.topLevelRule.name,r=Je(t.leftRecursionPath,a=>a.name),n=`${e} --> ${r.concat([e]).join(" --> ")}`;return`Left Recursion found in grammar. +rule: <${e}> can be invoked from itself (directly or indirectly) +without consuming any Tokens. The grammar path that causes this is: + ${n} + To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`},buildInvalidRuleNameError(t){return"deprecated"},buildDuplicateRuleNameError(t){let e;return t.topLevelRule instanceof us?e=t.topLevelRule.name:e=t.topLevelRule,`Duplicate definition, rule: ->${e}<- is already defined in the grammar: ->${t.grammarName}<-`}}});function _oe(t,e){let r=new pM(t,e);return r.resolveRefs(),r.errors}var pM,Doe=N(()=>{"use strict";Us();qt();fs();o(_oe,"resolveGrammar");pM=class extends hs{static{o(this,"GastRefResolverVisitor")}constructor(e,r){super(),this.nameToTopRule=e,this.errMsgProvider=r,this.errors=[]}resolveRefs(){Ae(br(this.nameToTopRule),e=>{this.currTopLevel=e,e.accept(this)})}visitNonTerminal(e){let r=this.nameToTopRule[e.nonTerminalName];if(r)e.referencedRule=r;else{let n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,e);this.errors.push({message:n,type:Vi.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:e.nonTerminalName})}}}});function Jk(t,e,r=[]){r=an(r);let n=[],i=0;function a(l){return l.concat(bi(t,i+1))}o(a,"remainingPathWith");function s(l){let u=Jk(a(l),e,r);return n.concat(u)}for(o(s,"getAlternativesForProd");r.length{hr(u.definition)===!1&&(n=s(u.definition))}),n;if(l instanceof Er)r.push(l.terminalType);else throw Error("non exhaustive match")}i++}return n.push({partialPath:r,suffixDef:bi(t,i)}),n}function eE(t,e,r,n){let i="EXIT_NONE_TERMINAL",a=[i],s="EXIT_ALTERNATIVE",l=!1,u=e.length,h=u-n-1,f=[],d=[];for(d.push({idx:-1,def:t,ruleStack:[],occurrenceStack:[]});!hr(d);){let p=d.pop();if(p===s){l&&ma(d).idx<=h&&d.pop();continue}let m=p.def,g=p.idx,y=p.ruleStack,v=p.occurrenceStack;if(hr(m))continue;let x=m[0];if(x===i){let b={idx:g,def:bi(m),ruleStack:Fu(y),occurrenceStack:Fu(v)};d.push(b)}else if(x instanceof Er)if(g=0;b--){let T=x.definition[b],S={idx:g,def:T.definition.concat(bi(m)),ruleStack:y,occurrenceStack:v};d.push(S),d.push(s)}else if(x instanceof Dn)d.push({idx:g,def:x.definition.concat(bi(m)),ruleStack:y,occurrenceStack:v});else if(x instanceof us)d.push(kFe(x,g,y,v));else throw Error("non exhaustive match")}return f}function kFe(t,e,r,n){let i=an(r);i.push(t.name);let a=an(n);return a.push(1),{idx:e,def:t.definition,ruleStack:i,occurrenceStack:a}}var mM,Kk,Zg,Qk,yx,Zk,vx,xx=N(()=>{"use strict";qt();rM();Vk();fs();mM=class extends Gu{static{o(this,"AbstractNextPossibleTokensWalker")}constructor(e,r){super(),this.topProd=e,this.path=r,this.possibleTokTypes=[],this.nextProductionName="",this.nextProductionOccurrence=0,this.found=!1,this.isAtEndOfPath=!1}startWalking(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=an(this.path.ruleStack).reverse(),this.occurrenceStack=an(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes}walk(e,r=[]){this.found||super.walk(e,r)}walkProdRef(e,r,n){if(e.referencedRule.name===this.nextProductionName&&e.idx===this.nextProductionOccurrence){let i=r.concat(n);this.updateExpectedNext(),this.walk(e.referencedRule,i)}}updateExpectedNext(){hr(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())}},Kk=class extends mM{static{o(this,"NextAfterTokenWalker")}constructor(e,r){super(e,r),this.path=r,this.nextTerminalName="",this.nextTerminalOccurrence=0,this.nextTerminalName=this.path.lastTok.name,this.nextTerminalOccurrence=this.path.lastTokOccurrence}walkTerminal(e,r,n){if(this.isAtEndOfPath&&e.terminalType.name===this.nextTerminalName&&e.idx===this.nextTerminalOccurrence&&!this.found){let i=r.concat(n),a=new Dn({definition:i});this.possibleTokTypes=yp(a),this.found=!0}}},Zg=class extends Gu{static{o(this,"AbstractNextTerminalAfterProductionWalker")}constructor(e,r){super(),this.topRule=e,this.occurrence=r,this.result={token:void 0,occurrence:void 0,isEndOfRule:void 0}}startWalking(){return this.walk(this.topRule),this.result}},Qk=class extends Zg{static{o(this,"NextTerminalAfterManyWalker")}walkMany(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkMany(e,r,n)}},yx=class extends Zg{static{o(this,"NextTerminalAfterManySepWalker")}walkManySep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkManySep(e,r,n)}},Zk=class extends Zg{static{o(this,"NextTerminalAfterAtLeastOneWalker")}walkAtLeastOne(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOne(e,r,n)}},vx=class extends Zg{static{o(this,"NextTerminalAfterAtLeastOneSepWalker")}walkAtLeastOneSep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOneSep(e,r,n)}};o(Jk,"possiblePathsFrom");o(eE,"nextPossibleTokensAfter");o(kFe,"expandTopLevelRule")});function bx(t){if(t instanceof ln||t==="Option")return Qn.OPTION;if(t instanceof Pr||t==="Repetition")return Qn.REPETITION;if(t instanceof Ln||t==="RepetitionMandatory")return Qn.REPETITION_MANDATORY;if(t instanceof Rn||t==="RepetitionMandatoryWithSeparator")return Qn.REPETITION_MANDATORY_WITH_SEPARATOR;if(t instanceof Tn||t==="RepetitionWithSeparator")return Qn.REPETITION_WITH_SEPARATOR;if(t instanceof wn||t==="Alternation")return Qn.ALTERNATION;throw Error("non exhaustive match")}function rE(t){let{occurrence:e,rule:r,prodType:n,maxLookahead:i}=t,a=bx(n);return a===Qn.ALTERNATION?Jg(e,r,i):e1(e,r,a,i)}function Roe(t,e,r,n,i,a){let s=Jg(t,e,r),l=Boe(s)?jg:Vu;return a(s,n,l,i)}function Noe(t,e,r,n,i,a){let s=e1(t,e,i,r),l=Boe(s)?jg:Vu;return a(s[0],l,n)}function Moe(t,e,r,n){let i=t.length,a=Pa(t,s=>Pa(s,l=>l.length===1));if(e)return function(s){let l=Je(s,u=>u.GATE);for(let u=0;uqr(u)),l=Xr(s,(u,h,f)=>(Ae(h,d=>{Bt(u,d.tokenTypeIdx)||(u[d.tokenTypeIdx]=f),Ae(d.categoryMatches,p=>{Bt(u,p)||(u[p]=f)})}),u),{});return function(){let u=this.LA(1);return l[u.tokenTypeIdx]}}else return function(){for(let s=0;sa.length===1),i=t.length;if(n&&!r){let a=qr(t);if(a.length===1&&hr(a[0].categoryMatches)){let l=a[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===l}}else{let s=Xr(a,(l,u,h)=>(l[u.tokenTypeIdx]=!0,Ae(u.categoryMatches,f=>{l[f]=!0}),l),[]);return function(){let l=this.LA(1);return s[l.tokenTypeIdx]===!0}}}else return function(){e:for(let a=0;aJk([s],1)),n=Loe(r.length),i=Je(r,s=>{let l={};return Ae(s,u=>{let h=gM(u.partialPath);Ae(h,f=>{l[f]=!0})}),l}),a=r;for(let s=1;s<=e;s++){let l=a;a=Loe(l.length);for(let u=0;u{let x=gM(v.partialPath);Ae(x,b=>{i[u][b]=!0})})}}}}return n}function Jg(t,e,r,n){let i=new tE(t,Qn.ALTERNATION,n);return e.accept(i),Ooe(i.result,r)}function e1(t,e,r,n){let i=new tE(t,r);e.accept(i);let a=i.result,l=new yM(e,t,r).startWalking(),u=new Dn({definition:a}),h=new Dn({definition:l});return Ooe([u,h],n)}function nE(t,e){e:for(let r=0;r{let i=e[n];return r===i||i.categoryMatchesMap[r.tokenTypeIdx]})}function Boe(t){return Pa(t,e=>Pa(e,r=>Pa(r,n=>hr(n.categoryMatches))))}var Qn,yM,tE,t1=N(()=>{"use strict";qt();xx();Vk();xp();fs();(function(t){t[t.OPTION=0]="OPTION",t[t.REPETITION=1]="REPETITION",t[t.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",t[t.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",t[t.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",t[t.ALTERNATION=5]="ALTERNATION"})(Qn||(Qn={}));o(bx,"getProdType");o(rE,"getLookaheadPaths");o(Roe,"buildLookaheadFuncForOr");o(Noe,"buildLookaheadFuncForOptionalProd");o(Moe,"buildAlternativesLookAheadFunc");o(Ioe,"buildSingleAlternativeLookaheadFunction");yM=class extends Gu{static{o(this,"RestDefinitionFinderWalker")}constructor(e,r,n){super(),this.topProd=e,this.targetOccurrence=r,this.targetProdType=n}startWalking(){return this.walk(this.topProd),this.restDef}checkIsTarget(e,r,n,i){return e.idx===this.targetOccurrence&&this.targetProdType===r?(this.restDef=n.concat(i),!0):!1}walkOption(e,r,n){this.checkIsTarget(e,Qn.OPTION,r,n)||super.walkOption(e,r,n)}walkAtLeastOne(e,r,n){this.checkIsTarget(e,Qn.REPETITION_MANDATORY,r,n)||super.walkOption(e,r,n)}walkAtLeastOneSep(e,r,n){this.checkIsTarget(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}walkMany(e,r,n){this.checkIsTarget(e,Qn.REPETITION,r,n)||super.walkOption(e,r,n)}walkManySep(e,r,n){this.checkIsTarget(e,Qn.REPETITION_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}},tE=class extends hs{static{o(this,"InsideDefinitionFinderVisitor")}constructor(e,r,n){super(),this.targetOccurrence=e,this.targetProdType=r,this.targetRef=n,this.result=[]}checkIsTarget(e,r){e.idx===this.targetOccurrence&&this.targetProdType===r&&(this.targetRef===void 0||e===this.targetRef)&&(this.result=e.definition)}visitOption(e){this.checkIsTarget(e,Qn.OPTION)}visitRepetition(e){this.checkIsTarget(e,Qn.REPETITION)}visitRepetitionMandatory(e){this.checkIsTarget(e,Qn.REPETITION_MANDATORY)}visitRepetitionMandatoryWithSeparator(e){this.checkIsTarget(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR)}visitRepetitionWithSeparator(e){this.checkIsTarget(e,Qn.REPETITION_WITH_SEPARATOR)}visitAlternation(e){this.checkIsTarget(e,Qn.ALTERNATION)}};o(Loe,"initializeArrayOfArrays");o(gM,"pathToHashKeys");o(EFe,"isUniquePrefixHash");o(Ooe,"lookAheadSequenceFromAlternatives");o(Jg,"getLookaheadPathsForOr");o(e1,"getLookaheadPathsForOptionalProd");o(nE,"containsPath");o(Poe,"isStrictPrefixOfPath");o(Boe,"areTokenCategoriesNotUsed")});function Foe(t){let e=t.lookaheadStrategy.validate({rules:t.rules,tokenTypes:t.tokenTypes,grammarName:t.grammarName});return Je(e,r=>Object.assign({type:Vi.CUSTOM_LOOKAHEAD_VALIDATION},r))}function $oe(t,e,r,n){let i=ga(t,u=>SFe(u,r)),a=RFe(t,e,r),s=ga(t,u=>_Fe(u,r)),l=ga(t,u=>AFe(u,t,n,r));return i.concat(a,s,l)}function SFe(t,e){let r=new vM;t.accept(r);let n=r.allProductions,i=yR(n,CFe),a=zs(i,l=>l.length>1);return Je(br(a),l=>{let u=ia(l),h=e.buildDuplicateFoundError(t,l),f=Vs(u),d={message:h,type:Vi.DUPLICATE_PRODUCTIONS,ruleName:t.name,dslName:f,occurrence:u.idx},p=zoe(u);return p&&(d.parameter=p),d})}function CFe(t){return`${Vs(t)}_#_${t.idx}_#_${zoe(t)}`}function zoe(t){return t instanceof Er?t.terminalType.name:t instanceof on?t.nonTerminalName:""}function AFe(t,e,r,n){let i=[];if(Xr(e,(s,l)=>l.name===t.name?s+1:s,0)>1){let s=n.buildDuplicateRuleNameError({topLevelRule:t,grammarName:r});i.push({message:s,type:Vi.DUPLICATE_RULE_NAME,ruleName:t.name})}return i}function Goe(t,e,r){let n=[],i;return Xn(e,t)||(i=`Invalid rule override, rule: ->${t}<- cannot be overridden in the grammar: ->${r}<-as it is not defined in any of the super grammars `,n.push({message:i,type:Vi.INVALID_RULE_OVERRIDE,ruleName:t})),n}function bM(t,e,r,n=[]){let i=[],a=iE(e.definition);if(hr(a))return[];{let s=t.name;Xn(a,t)&&i.push({message:r.buildLeftRecursionError({topLevelRule:t,leftRecursionPath:n}),type:Vi.LEFT_RECURSION,ruleName:s});let u=af(a,n.concat([t])),h=ga(u,f=>{let d=an(n);return d.push(f),bM(t,f,r,d)});return i.concat(h)}}function iE(t){let e=[];if(hr(t))return e;let r=ia(t);if(r instanceof on)e.push(r.referencedRule);else if(r instanceof Dn||r instanceof ln||r instanceof Ln||r instanceof Rn||r instanceof Tn||r instanceof Pr)e=e.concat(iE(r.definition));else if(r instanceof wn)e=qr(Je(r.definition,a=>iE(a.definition)));else if(!(r instanceof Er))throw Error("non exhaustive match");let n=gp(r),i=t.length>1;if(n&&i){let a=bi(t);return e.concat(iE(a))}else return e}function Voe(t,e){let r=new Tx;t.accept(r);let n=r.alternations;return ga(n,a=>{let s=Fu(a.definition);return ga(s,(l,u)=>{let h=eE([l],[],Vu,1);return hr(h)?[{message:e.buildEmptyAlternationError({topLevelRule:t,alternation:a,emptyChoiceIdx:u}),type:Vi.NONE_LAST_EMPTY_ALT,ruleName:t.name,occurrence:a.idx,alternative:u+1}]:[]})})}function Uoe(t,e,r){let n=new Tx;t.accept(n);let i=n.alternations;return i=sf(i,s=>s.ignoreAmbiguities===!0),ga(i,s=>{let l=s.idx,u=s.maxLookahead||e,h=Jg(l,t,u,s),f=DFe(h,s,t,r),d=LFe(h,s,t,r);return f.concat(d)})}function _Fe(t,e){let r=new Tx;t.accept(r);let n=r.alternations;return ga(n,a=>a.definition.length>255?[{message:e.buildTooManyAlternativesError({topLevelRule:t,alternation:a}),type:Vi.TOO_MANY_ALTS,ruleName:t.name,occurrence:a.idx}]:[])}function Hoe(t,e,r){let n=[];return Ae(t,i=>{let a=new xM;i.accept(a);let s=a.allProductions;Ae(s,l=>{let u=bx(l),h=l.maxLookahead||e,f=l.idx,p=e1(f,i,u,h)[0];if(hr(qr(p))){let m=r.buildEmptyRepetitionError({topLevelRule:i,repetition:l});n.push({message:m,type:Vi.NO_NON_EMPTY_LOOKAHEAD,ruleName:i.name})}})}),n}function DFe(t,e,r,n){let i=[],a=Xr(t,(l,u,h)=>(e.definition[h].ignoreAmbiguities===!0||Ae(u,f=>{let d=[h];Ae(t,(p,m)=>{h!==m&&nE(p,f)&&e.definition[m].ignoreAmbiguities!==!0&&d.push(m)}),d.length>1&&!nE(i,f)&&(i.push(f),l.push({alts:d,path:f}))}),l),[]);return Je(a,l=>{let u=Je(l.alts,f=>f+1);return{message:n.buildAlternationAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:u,prefixPath:l.path}),type:Vi.AMBIGUOUS_ALTS,ruleName:r.name,occurrence:e.idx,alternatives:l.alts}})}function LFe(t,e,r,n){let i=Xr(t,(s,l,u)=>{let h=Je(l,f=>({idx:u,path:f}));return s.concat(h)},[]);return Ac(ga(i,s=>{if(e.definition[s.idx].ignoreAmbiguities===!0)return[];let u=s.idx,h=s.path,f=Yr(i,p=>e.definition[p.idx].ignoreAmbiguities!==!0&&p.idx{let m=[p.idx+1,u+1],g=e.idx===0?"":e.idx;return{message:n.buildAlternationPrefixAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:m,prefixPath:p.path}),type:Vi.AMBIGUOUS_PREFIX_ALTS,ruleName:r.name,occurrence:g,alternatives:m}})}))}function RFe(t,e,r){let n=[],i=Je(e,a=>a.name);return Ae(t,a=>{let s=a.name;if(Xn(i,s)){let l=r.buildNamespaceConflictError(a);n.push({message:l,type:Vi.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:s})}}),n}var vM,Tx,xM,wx=N(()=>{"use strict";qt();Us();fs();t1();xx();xp();o(Foe,"validateLookahead");o($oe,"validateGrammar");o(SFe,"validateDuplicateProductions");o(CFe,"identifyProductionForDuplicates");o(zoe,"getExtraProductionArgument");vM=class extends hs{static{o(this,"OccurrenceValidationCollector")}constructor(){super(...arguments),this.allProductions=[]}visitNonTerminal(e){this.allProductions.push(e)}visitOption(e){this.allProductions.push(e)}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}visitAlternation(e){this.allProductions.push(e)}visitTerminal(e){this.allProductions.push(e)}};o(AFe,"validateRuleDoesNotAlreadyExist");o(Goe,"validateRuleIsOverridden");o(bM,"validateNoLeftRecursion");o(iE,"getFirstNoneTerminal");Tx=class extends hs{static{o(this,"OrCollector")}constructor(){super(...arguments),this.alternations=[]}visitAlternation(e){this.alternations.push(e)}};o(Voe,"validateEmptyOrAlternative");o(Uoe,"validateAmbiguousAlternationAlternatives");xM=class extends hs{static{o(this,"RepetitionCollector")}constructor(){super(...arguments),this.allProductions=[]}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}};o(_Fe,"validateTooManyAlts");o(Hoe,"validateSomeNonEmptyLookaheadPath");o(DFe,"checkAlternativesAmbiguities");o(LFe,"checkPrefixAlternativesAmbiguities");o(RFe,"checkTerminalAndNoneTerminalsNameSpace")});function Woe(t){let e=nf(t,{errMsgProvider:Aoe}),r={};return Ae(t.rules,n=>{r[n.name]=n}),_oe(r,e.errMsgProvider)}function qoe(t){return t=nf(t,{errMsgProvider:$l}),$oe(t.rules,t.tokenTypes,t.errMsgProvider,t.grammarName)}var Yoe=N(()=>{"use strict";qt();Doe();wx();Qg();o(Woe,"resolveGrammar");o(qoe,"validateGrammar")});function pf(t){return Xn(Zoe,t.name)}var Xoe,joe,Koe,Qoe,Zoe,r1,Tp,kx,Ex,Sx,n1=N(()=>{"use strict";qt();Xoe="MismatchedTokenException",joe="NoViableAltException",Koe="EarlyExitException",Qoe="NotAllInputParsedException",Zoe=[Xoe,joe,Koe,Qoe];Object.freeze(Zoe);o(pf,"isRecognitionException");r1=class extends Error{static{o(this,"RecognitionException")}constructor(e,r){super(e),this.token=r,this.resyncedTokens=[],Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},Tp=class extends r1{static{o(this,"MismatchedTokenException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Xoe}},kx=class extends r1{static{o(this,"NoViableAltException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=joe}},Ex=class extends r1{static{o(this,"NotAllInputParsedException")}constructor(e,r){super(e,r),this.name=Qoe}},Sx=class extends r1{static{o(this,"EarlyExitException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Koe}}});function NFe(t,e,r,n,i,a,s){let l=this.getKeyForAutomaticLookahead(n,i),u=this.firstAfterRepMap[l];if(u===void 0){let p=this.getCurrRuleFullName(),m=this.getGAstProductions()[p];u=new a(m,i).startWalking(),this.firstAfterRepMap[l]=u}let h=u.token,f=u.occurrence,d=u.isEndOfRule;this.RULE_STACK.length===1&&d&&h===void 0&&(h=fo,f=1),!(h===void 0||f===void 0)&&this.shouldInRepetitionRecoveryBeTried(h,f,s)&&this.tryInRepetitionRecovery(t,e,r,h)}var TM,kM,wM,aE,EM=N(()=>{"use strict";bp();qt();n1();nM();Us();TM={},kM="InRuleRecoveryException",wM=class extends Error{static{o(this,"InRuleRecoveryException")}constructor(e){super(e),this.name=kM}},aE=class{static{o(this,"Recoverable")}initRecoverable(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=Bt(e,"recoveryEnabled")?e.recoveryEnabled:ds.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=NFe)}getTokenToInsert(e){let r=Wu(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return r.isInsertedInRecovery=!0,r}canTokenTypeBeInsertedInRecovery(e){return!0}canTokenTypeBeDeletedInRecovery(e){return!0}tryInRepetitionRecovery(e,r,n,i){let a=this.findReSyncTokenType(),s=this.exportLexerState(),l=[],u=!1,h=this.LA(1),f=this.LA(1),d=o(()=>{let p=this.LA(0),m=this.errorMessageProvider.buildMismatchTokenMessage({expected:i,actual:h,previous:p,ruleName:this.getCurrRuleFullName()}),g=new Tp(m,h,this.LA(0));g.resyncedTokens=Fu(l),this.SAVE_ERROR(g)},"generateErrorMessage");for(;!u;)if(this.tokenMatcher(f,i)){d();return}else if(n.call(this)){d(),e.apply(this,r);return}else this.tokenMatcher(f,a)?u=!0:(f=this.SKIP_TOKEN(),this.addToResyncTokens(f,l));this.importLexerState(s)}shouldInRepetitionRecoveryBeTried(e,r,n){return!(n===!1||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,r)))}getFollowsForInRuleRecovery(e,r){let n=this.getCurrentGrammarPath(e,r);return this.getNextPossibleTokenTypes(n)}tryInRuleRecovery(e,r){if(this.canRecoverWithSingleTokenInsertion(e,r))return this.getTokenToInsert(e);if(this.canRecoverWithSingleTokenDeletion(e)){let n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new wM("sad sad panda")}canPerformInRuleRecovery(e,r){return this.canRecoverWithSingleTokenInsertion(e,r)||this.canRecoverWithSingleTokenDeletion(e)}canRecoverWithSingleTokenInsertion(e,r){if(!this.canTokenTypeBeInsertedInRecovery(e)||hr(r))return!1;let n=this.LA(1);return ls(r,a=>this.tokenMatcher(n,a))!==void 0}canRecoverWithSingleTokenDeletion(e){return this.canTokenTypeBeDeletedInRecovery(e)?this.tokenMatcher(this.LA(2),e):!1}isInCurrentRuleReSyncSet(e){let r=this.getCurrFollowKey(),n=this.getFollowSetFromFollowKey(r);return Xn(n,e)}findReSyncTokenType(){let e=this.flattenFollowSet(),r=this.LA(1),n=2;for(;;){let i=ls(e,a=>gx(r,a));if(i!==void 0)return i;r=this.LA(n),n++}}getCurrFollowKey(){if(this.RULE_STACK.length===1)return TM;let e=this.getLastExplicitRuleShortName(),r=this.getLastExplicitRuleOccurrenceIndex(),n=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:r,inRule:this.shortRuleNameToFullName(n)}}buildFullFollowKeyStack(){let e=this.RULE_STACK,r=this.RULE_OCCURRENCE_STACK;return Je(e,(n,i)=>i===0?TM:{ruleName:this.shortRuleNameToFullName(n),idxInCallingRule:r[i],inRule:this.shortRuleNameToFullName(e[i-1])})}flattenFollowSet(){let e=Je(this.buildFullFollowKeyStack(),r=>this.getFollowSetFromFollowKey(r));return qr(e)}getFollowSetFromFollowKey(e){if(e===TM)return[fo];let r=e.ruleName+e.idxInCallingRule+Uk+e.inRule;return this.resyncFollows[r]}addToResyncTokens(e,r){return this.tokenMatcher(e,fo)||r.push(e),r}reSyncTo(e){let r=[],n=this.LA(1);for(;this.tokenMatcher(n,e)===!1;)n=this.SKIP_TOKEN(),this.addToResyncTokens(n,r);return Fu(r)}attemptInRepetitionRecovery(e,r,n,i,a,s,l){}getCurrentGrammarPath(e,r){let n=this.getHumanReadableRuleStack(),i=an(this.RULE_OCCURRENCE_STACK);return{ruleStack:n,occurrenceStack:i,lastTok:e,lastTokOccurrence:r}}getHumanReadableRuleStack(){return Je(this.RULE_STACK,e=>this.shortRuleNameToFullName(e))}};o(NFe,"attemptInRepetitionRecovery")});function sE(t,e,r){return r|e|t}var oE=N(()=>{"use strict";o(sE,"getKeyForAutomaticLookahead")});var Yu,SM=N(()=>{"use strict";qt();Qg();Us();wx();t1();Yu=class{static{o(this,"LLkLookaheadStrategy")}constructor(e){var r;this.maxLookahead=(r=e?.maxLookahead)!==null&&r!==void 0?r:ds.maxLookahead}validate(e){let r=this.validateNoLeftRecursion(e.rules);if(hr(r)){let n=this.validateEmptyOrAlternatives(e.rules),i=this.validateAmbiguousAlternationAlternatives(e.rules,this.maxLookahead),a=this.validateSomeNonEmptyLookaheadPath(e.rules,this.maxLookahead);return[...r,...n,...i,...a]}return r}validateNoLeftRecursion(e){return ga(e,r=>bM(r,r,$l))}validateEmptyOrAlternatives(e){return ga(e,r=>Voe(r,$l))}validateAmbiguousAlternationAlternatives(e,r){return ga(e,n=>Uoe(n,r,$l))}validateSomeNonEmptyLookaheadPath(e,r){return Hoe(e,r,$l)}buildLookaheadForAlternation(e){return Roe(e.prodOccurrence,e.rule,e.maxLookahead,e.hasPredicates,e.dynamicTokensEnabled,Moe)}buildLookaheadForOptional(e){return Noe(e.prodOccurrence,e.rule,e.maxLookahead,e.dynamicTokensEnabled,bx(e.prodType),Ioe)}}});function MFe(t){lE.reset(),t.accept(lE);let e=lE.dslMethods;return lE.reset(),e}var cE,CM,lE,Joe=N(()=>{"use strict";qt();Us();oE();fs();SM();cE=class{static{o(this,"LooksAhead")}initLooksAhead(e){this.dynamicTokensEnabled=Bt(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:ds.dynamicTokensEnabled,this.maxLookahead=Bt(e,"maxLookahead")?e.maxLookahead:ds.maxLookahead,this.lookaheadStrategy=Bt(e,"lookaheadStrategy")?e.lookaheadStrategy:new Yu({maxLookahead:this.maxLookahead}),this.lookAheadFuncsCache=new Map}preComputeLookaheadFunctions(e){Ae(e,r=>{this.TRACE_INIT(`${r.name} Rule Lookahead`,()=>{let{alternation:n,repetition:i,option:a,repetitionMandatory:s,repetitionMandatoryWithSeparator:l,repetitionWithSeparator:u}=MFe(r);Ae(n,h=>{let f=h.idx===0?"":h.idx;this.TRACE_INIT(`${Vs(h)}${f}`,()=>{let d=this.lookaheadStrategy.buildLookaheadForAlternation({prodOccurrence:h.idx,rule:r,maxLookahead:h.maxLookahead||this.maxLookahead,hasPredicates:h.hasPredicates,dynamicTokensEnabled:this.dynamicTokensEnabled}),p=sE(this.fullRuleNameToShort[r.name],256,h.idx);this.setLaFuncCache(p,d)})}),Ae(i,h=>{this.computeLookaheadFunc(r,h.idx,768,"Repetition",h.maxLookahead,Vs(h))}),Ae(a,h=>{this.computeLookaheadFunc(r,h.idx,512,"Option",h.maxLookahead,Vs(h))}),Ae(s,h=>{this.computeLookaheadFunc(r,h.idx,1024,"RepetitionMandatory",h.maxLookahead,Vs(h))}),Ae(l,h=>{this.computeLookaheadFunc(r,h.idx,1536,"RepetitionMandatoryWithSeparator",h.maxLookahead,Vs(h))}),Ae(u,h=>{this.computeLookaheadFunc(r,h.idx,1280,"RepetitionWithSeparator",h.maxLookahead,Vs(h))})})})}computeLookaheadFunc(e,r,n,i,a,s){this.TRACE_INIT(`${s}${r===0?"":r}`,()=>{let l=this.lookaheadStrategy.buildLookaheadForOptional({prodOccurrence:r,rule:e,maxLookahead:a||this.maxLookahead,dynamicTokensEnabled:this.dynamicTokensEnabled,prodType:i}),u=sE(this.fullRuleNameToShort[e.name],n,r);this.setLaFuncCache(u,l)})}getKeyForAutomaticLookahead(e,r){let n=this.getLastExplicitRuleShortName();return sE(n,e,r)}getLaFuncFromCache(e){return this.lookAheadFuncsCache.get(e)}setLaFuncCache(e,r){this.lookAheadFuncsCache.set(e,r)}},CM=class extends hs{static{o(this,"DslMethodsCollectorVisitor")}constructor(){super(...arguments),this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}reset(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}visitOption(e){this.dslMethods.option.push(e)}visitRepetitionWithSeparator(e){this.dslMethods.repetitionWithSeparator.push(e)}visitRepetitionMandatory(e){this.dslMethods.repetitionMandatory.push(e)}visitRepetitionMandatoryWithSeparator(e){this.dslMethods.repetitionMandatoryWithSeparator.push(e)}visitRepetition(e){this.dslMethods.repetition.push(e)}visitAlternation(e){this.dslMethods.alternation.push(e)}},lE=new CM;o(MFe,"collectMethods")});function DM(t,e){isNaN(t.startOffset)===!0?(t.startOffset=e.startOffset,t.endOffset=e.endOffset):t.endOffset{"use strict";o(DM,"setNodeLocationOnlyOffset");o(LM,"setNodeLocationFull");o(ele,"addTerminalToCst");o(tle,"addNoneTerminalToCst")});function RM(t,e){Object.defineProperty(t,IFe,{enumerable:!1,configurable:!0,writable:!1,value:e})}var IFe,nle=N(()=>{"use strict";IFe="name";o(RM,"defineNameProp")});function OFe(t,e){let r=zr(t),n=r.length;for(let i=0;is.msg);throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>: + ${a.join(` + +`).replace(/\n/g,` + `)}`)}},"validateVisitor")};return r.prototype=n,r.prototype.constructor=r,r._RULE_NAMES=e,r}function ale(t,e,r){let n=o(function(){},"derivedConstructor");RM(n,t+"BaseSemanticsWithDefaults");let i=Object.create(r.prototype);return Ae(e,a=>{i[a]=OFe}),n.prototype=i,n.prototype.constructor=n,n}function PFe(t,e){return BFe(t,e)}function BFe(t,e){let r=Yr(e,i=>Ai(t[i])===!1),n=Je(r,i=>({msg:`Missing visitor method: <${i}> on ${t.constructor.name} CST Visitor.`,type:NM.MISSING_METHOD,methodName:i}));return Ac(n)}var NM,sle=N(()=>{"use strict";qt();nle();o(OFe,"defaultVisit");o(ile,"createBaseSemanticVisitorConstructor");o(ale,"createBaseVisitorConstructorWithDefaults");(function(t){t[t.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",t[t.MISSING_METHOD=1]="MISSING_METHOD"})(NM||(NM={}));o(PFe,"validateVisitor");o(BFe,"validateMissingCstMethods")});var dE,ole=N(()=>{"use strict";rle();qt();sle();Us();dE=class{static{o(this,"TreeBuilder")}initTreeBuilder(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=Bt(e,"nodeLocationTracking")?e.nodeLocationTracking:ds.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=ai,this.cstFinallyStateUpdate=ai,this.cstPostTerminal=ai,this.cstPostNonTerminal=ai,this.cstPostRule=ai;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=LM,this.setNodeLocationFromNode=LM,this.cstPostRule=ai,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=DM,this.setNodeLocationFromNode=DM,this.cstPostRule=ai,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=ai,this.setInitialNodeLocation=ai;else throw Error(`Invalid config option: "${e.nodeLocationTracking}"`)}setInitialNodeLocationOnlyOffsetRecovery(e){e.location={startOffset:NaN,endOffset:NaN}}setInitialNodeLocationOnlyOffsetRegular(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}}setInitialNodeLocationFullRecovery(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}}setInitialNodeLocationFullRegular(e){let r=this.LA(1);e.location={startOffset:r.startOffset,startLine:r.startLine,startColumn:r.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}}cstInvocationStateUpdate(e){let r={name:e,children:Object.create(null)};this.setInitialNodeLocation(r),this.CST_STACK.push(r)}cstFinallyStateUpdate(){this.CST_STACK.pop()}cstPostRuleFull(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?(n.endOffset=r.endOffset,n.endLine=r.endLine,n.endColumn=r.endColumn):(n.startOffset=NaN,n.startLine=NaN,n.startColumn=NaN)}cstPostRuleOnlyOffset(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?n.endOffset=r.endOffset:n.startOffset=NaN}cstPostTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];ele(n,r,e),this.setNodeLocationFromToken(n.location,r)}cstPostNonTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];tle(n,r,e),this.setNodeLocationFromNode(n.location,e.location)}getBaseCstVisitorConstructor(){if(mr(this.baseCstVisitorConstructor)){let e=ile(this.className,zr(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor}getBaseCstVisitorConstructorWithDefaults(){if(mr(this.baseCstVisitorWithDefaultsConstructor)){let e=ale(this.className,zr(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor}getLastExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-1]}getPreviousExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-2]}getLastExplicitRuleOccurrenceIndex(){let e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]}}});var pE,lle=N(()=>{"use strict";Us();pE=class{static{o(this,"LexerAdapter")}initLexerAdapter(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1}set input(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length}get input(){return this.tokVector}SKIP_TOKEN(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):i1}LA(e){let r=this.currIdx+e;return r<0||this.tokVectorLength<=r?i1:this.tokVector[r]}consumeToken(){this.currIdx++}exportLexerState(){return this.currIdx}importLexerState(e){this.currIdx=e}resetLexerState(){this.currIdx=-1}moveToTerminatedState(){this.currIdx=this.tokVector.length-1}getLexerPosition(){return this.exportLexerState()}}});var mE,cle=N(()=>{"use strict";qt();n1();Us();Qg();wx();fs();mE=class{static{o(this,"RecognizerApi")}ACTION(e){return e.call(this)}consume(e,r,n){return this.consumeInternal(r,e,n)}subrule(e,r,n){return this.subruleInternal(r,e,n)}option(e,r){return this.optionInternal(r,e)}or(e,r){return this.orInternal(r,e)}many(e,r){return this.manyInternal(e,r)}atLeastOne(e,r){return this.atLeastOneInternal(e,r)}CONSUME(e,r){return this.consumeInternal(e,0,r)}CONSUME1(e,r){return this.consumeInternal(e,1,r)}CONSUME2(e,r){return this.consumeInternal(e,2,r)}CONSUME3(e,r){return this.consumeInternal(e,3,r)}CONSUME4(e,r){return this.consumeInternal(e,4,r)}CONSUME5(e,r){return this.consumeInternal(e,5,r)}CONSUME6(e,r){return this.consumeInternal(e,6,r)}CONSUME7(e,r){return this.consumeInternal(e,7,r)}CONSUME8(e,r){return this.consumeInternal(e,8,r)}CONSUME9(e,r){return this.consumeInternal(e,9,r)}SUBRULE(e,r){return this.subruleInternal(e,0,r)}SUBRULE1(e,r){return this.subruleInternal(e,1,r)}SUBRULE2(e,r){return this.subruleInternal(e,2,r)}SUBRULE3(e,r){return this.subruleInternal(e,3,r)}SUBRULE4(e,r){return this.subruleInternal(e,4,r)}SUBRULE5(e,r){return this.subruleInternal(e,5,r)}SUBRULE6(e,r){return this.subruleInternal(e,6,r)}SUBRULE7(e,r){return this.subruleInternal(e,7,r)}SUBRULE8(e,r){return this.subruleInternal(e,8,r)}SUBRULE9(e,r){return this.subruleInternal(e,9,r)}OPTION(e){return this.optionInternal(e,0)}OPTION1(e){return this.optionInternal(e,1)}OPTION2(e){return this.optionInternal(e,2)}OPTION3(e){return this.optionInternal(e,3)}OPTION4(e){return this.optionInternal(e,4)}OPTION5(e){return this.optionInternal(e,5)}OPTION6(e){return this.optionInternal(e,6)}OPTION7(e){return this.optionInternal(e,7)}OPTION8(e){return this.optionInternal(e,8)}OPTION9(e){return this.optionInternal(e,9)}OR(e){return this.orInternal(e,0)}OR1(e){return this.orInternal(e,1)}OR2(e){return this.orInternal(e,2)}OR3(e){return this.orInternal(e,3)}OR4(e){return this.orInternal(e,4)}OR5(e){return this.orInternal(e,5)}OR6(e){return this.orInternal(e,6)}OR7(e){return this.orInternal(e,7)}OR8(e){return this.orInternal(e,8)}OR9(e){return this.orInternal(e,9)}MANY(e){this.manyInternal(0,e)}MANY1(e){this.manyInternal(1,e)}MANY2(e){this.manyInternal(2,e)}MANY3(e){this.manyInternal(3,e)}MANY4(e){this.manyInternal(4,e)}MANY5(e){this.manyInternal(5,e)}MANY6(e){this.manyInternal(6,e)}MANY7(e){this.manyInternal(7,e)}MANY8(e){this.manyInternal(8,e)}MANY9(e){this.manyInternal(9,e)}MANY_SEP(e){this.manySepFirstInternal(0,e)}MANY_SEP1(e){this.manySepFirstInternal(1,e)}MANY_SEP2(e){this.manySepFirstInternal(2,e)}MANY_SEP3(e){this.manySepFirstInternal(3,e)}MANY_SEP4(e){this.manySepFirstInternal(4,e)}MANY_SEP5(e){this.manySepFirstInternal(5,e)}MANY_SEP6(e){this.manySepFirstInternal(6,e)}MANY_SEP7(e){this.manySepFirstInternal(7,e)}MANY_SEP8(e){this.manySepFirstInternal(8,e)}MANY_SEP9(e){this.manySepFirstInternal(9,e)}AT_LEAST_ONE(e){this.atLeastOneInternal(0,e)}AT_LEAST_ONE1(e){return this.atLeastOneInternal(1,e)}AT_LEAST_ONE2(e){this.atLeastOneInternal(2,e)}AT_LEAST_ONE3(e){this.atLeastOneInternal(3,e)}AT_LEAST_ONE4(e){this.atLeastOneInternal(4,e)}AT_LEAST_ONE5(e){this.atLeastOneInternal(5,e)}AT_LEAST_ONE6(e){this.atLeastOneInternal(6,e)}AT_LEAST_ONE7(e){this.atLeastOneInternal(7,e)}AT_LEAST_ONE8(e){this.atLeastOneInternal(8,e)}AT_LEAST_ONE9(e){this.atLeastOneInternal(9,e)}AT_LEAST_ONE_SEP(e){this.atLeastOneSepFirstInternal(0,e)}AT_LEAST_ONE_SEP1(e){this.atLeastOneSepFirstInternal(1,e)}AT_LEAST_ONE_SEP2(e){this.atLeastOneSepFirstInternal(2,e)}AT_LEAST_ONE_SEP3(e){this.atLeastOneSepFirstInternal(3,e)}AT_LEAST_ONE_SEP4(e){this.atLeastOneSepFirstInternal(4,e)}AT_LEAST_ONE_SEP5(e){this.atLeastOneSepFirstInternal(5,e)}AT_LEAST_ONE_SEP6(e){this.atLeastOneSepFirstInternal(6,e)}AT_LEAST_ONE_SEP7(e){this.atLeastOneSepFirstInternal(7,e)}AT_LEAST_ONE_SEP8(e){this.atLeastOneSepFirstInternal(8,e)}AT_LEAST_ONE_SEP9(e){this.atLeastOneSepFirstInternal(9,e)}RULE(e,r,n=a1){if(Xn(this.definedRulesNames,e)){let s={message:$l.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),type:Vi.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);let i=this.defineRule(e,r,n);return this[e]=i,i}OVERRIDE_RULE(e,r,n=a1){let i=Goe(e,this.definedRulesNames,this.className);this.definitionErrors=this.definitionErrors.concat(i);let a=this.defineRule(e,r,n);return this[e]=a,a}BACKTRACK(e,r){return function(){this.isBackTrackingStack.push(1);let n=this.saveRecogState();try{return e.apply(this,r),!0}catch(i){if(pf(i))return!1;throw i}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}}getGAstProductions(){return this.gastProductionsCache}getSerializedGastProductions(){return zk(br(this.gastProductionsCache))}}});var gE,ule=N(()=>{"use strict";qt();oE();n1();t1();xx();Us();EM();bp();xp();gE=class{static{o(this,"RecognizerEngine")}initRecognizerEngine(e,r){if(this.className=this.constructor.name,this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=jg,this.subruleIdx=0,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},Bt(r,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if(Pt(e)){if(hr(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if(Pt(e))this.tokensMap=Xr(e,(a,s)=>(a[s.name]=s,a),{});else if(Bt(e,"modes")&&Pa(qr(br(e.modes)),voe)){let a=qr(br(e.modes)),s=qm(a);this.tokensMap=Xr(s,(l,u)=>(l[u.name]=u,l),{})}else if(bn(e))this.tokensMap=an(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=fo;let n=Bt(e,"modes")?qr(br(e.modes)):br(e),i=Pa(n,a=>hr(a.categoryMatches));this.tokenMatcher=i?jg:Vu,Uu(br(this.tokensMap))}defineRule(e,r,n){if(this.selfAnalysisDone)throw Error(`Grammar rule <${e}> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);let i=Bt(n,"resyncEnabled")?n.resyncEnabled:a1.resyncEnabled,a=Bt(n,"recoveryValueFunc")?n.recoveryValueFunc:a1.recoveryValueFunc,s=this.ruleShortNameIdx<<12;this.ruleShortNameIdx++,this.shortRuleNameToFull[s]=e,this.fullRuleNameToShort[e]=s;let l;return this.outputCst===!0?l=o(function(...f){try{this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f);let d=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(d),d}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTry"):l=o(function(...f){try{return this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f)}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTryCst"),Object.assign(l,{ruleName:e,originalGrammarAction:r})}invokeRuleCatch(e,r,n){let i=this.RULE_STACK.length===1,a=r&&!this.isBackTracking()&&this.recoveryEnabled;if(pf(e)){let s=e;if(a){let l=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(l))if(s.resyncedTokens=this.reSyncTo(l),this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];return u.recoveredNode=!0,u}else return n(e);else{if(this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];u.recoveredNode=!0,s.partialCstResult=u}throw s}}else{if(i)return this.moveToTerminatedState(),n(e);throw s}}else throw e}optionInternal(e,r){let n=this.getKeyForAutomaticLookahead(512,r);return this.optionInternalLogic(e,r,n)}optionInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof e!="function"){a=e.DEF;let s=e.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=e;if(i.call(this)===!0)return a.call(this)}atLeastOneInternal(e,r){let n=this.getKeyForAutomaticLookahead(1024,e);return this.atLeastOneInternalLogic(e,r,n)}atLeastOneInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let s=r.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=r;if(i.call(this)===!0){let s=this.doSingleRepetition(a);for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a)}else throw this.raiseEarlyExitException(e,Qn.REPETITION_MANDATORY,r.ERR_MSG);this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,r],i,1024,e,Zk)}atLeastOneSepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1536,e);this.atLeastOneSepFirstInternalLogic(e,r,n)}atLeastOneSepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,vx],l,1536,e,vx)}else throw this.raiseEarlyExitException(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR,r.ERR_MSG)}manyInternal(e,r){let n=this.getKeyForAutomaticLookahead(768,e);return this.manyInternalLogic(e,r,n)}manyInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let l=r.GATE;if(l!==void 0){let u=i;i=o(()=>l.call(this)&&u.call(this),"lookaheadFunction")}}else a=r;let s=!0;for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a);this.attemptInRepetitionRecovery(this.manyInternal,[e,r],i,768,e,Qk,s)}manySepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1280,e);this.manySepFirstInternalLogic(e,r,n)}manySepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,yx],l,1280,e,yx)}}repetitionSepSecondInternal(e,r,n,i,a){for(;n();)this.CONSUME(r),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,r,n,i,a],n,1536,e,a)}doSingleRepetition(e){let r=this.getLexerPosition();return e.call(this),this.getLexerPosition()>r}orInternal(e,r){let n=this.getKeyForAutomaticLookahead(256,r),i=Pt(e)?e:e.DEF,s=this.getLaFuncFromCache(n).call(this,i);if(s!==void 0)return i[s].ALT.call(this);this.raiseNoAltException(r,e.ERR_MSG)}ruleFinallyStateUpdate(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){let e=this.LA(1),r=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new Ex(r,e))}}subruleInternal(e,r,n){let i;try{let a=n!==void 0?n.ARGS:void 0;return this.subruleIdx=r,i=e.apply(this,a),this.cstPostNonTerminal(i,n!==void 0&&n.LABEL!==void 0?n.LABEL:e.ruleName),i}catch(a){throw this.subruleInternalError(a,n,e.ruleName)}}subruleInternalError(e,r,n){throw pf(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,r!==void 0&&r.LABEL!==void 0?r.LABEL:n),delete e.partialCstResult),e}consumeInternal(e,r,n){let i;try{let a=this.LA(1);this.tokenMatcher(a,e)===!0?(this.consumeToken(),i=a):this.consumeInternalError(e,a,n)}catch(a){i=this.consumeInternalRecovery(e,r,a)}return this.cstPostTerminal(n!==void 0&&n.LABEL!==void 0?n.LABEL:e.name,i),i}consumeInternalError(e,r,n){let i,a=this.LA(0);throw n!==void 0&&n.ERR_MSG?i=n.ERR_MSG:i=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:r,previous:a,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new Tp(i,r,a))}consumeInternalRecovery(e,r,n){if(this.recoveryEnabled&&n.name==="MismatchedTokenException"&&!this.isBackTracking()){let i=this.getFollowsForInRuleRecovery(e,r);try{return this.tryInRuleRecovery(e,i)}catch(a){throw a.name===kM?n:a}}else throw n}saveRecogState(){let e=this.errors,r=an(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:r,CST_STACK:this.CST_STACK}}reloadRecogState(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK}ruleInvocationStateUpdate(e,r,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(r)}isBackTracking(){return this.isBackTrackingStack.length!==0}getCurrRuleFullName(){let e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]}shortRuleNameToFullName(e){return this.shortRuleNameToFull[e]}isAtEndOfInput(){return this.tokenMatcher(this.LA(1),fo)}reset(){this.resetLexerState(),this.subruleIdx=0,this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]}}});var yE,hle=N(()=>{"use strict";n1();qt();t1();Us();yE=class{static{o(this,"ErrorHandler")}initErrorHandler(e){this._errors=[],this.errorMessageProvider=Bt(e,"errorMessageProvider")?e.errorMessageProvider:ds.errorMessageProvider}SAVE_ERROR(e){if(pf(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:an(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")}get errors(){return an(this._errors)}set errors(e){this._errors=e}raiseEarlyExitException(e,r,n){let i=this.getCurrRuleFullName(),a=this.getGAstProductions()[i],l=e1(e,a,r,this.maxLookahead)[0],u=[];for(let f=1;f<=this.maxLookahead;f++)u.push(this.LA(f));let h=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:l,actual:u,previous:this.LA(0),customUserDescription:n,ruleName:i});throw this.SAVE_ERROR(new Sx(h,this.LA(1),this.LA(0)))}raiseNoAltException(e,r){let n=this.getCurrRuleFullName(),i=this.getGAstProductions()[n],a=Jg(e,i,this.maxLookahead),s=[];for(let h=1;h<=this.maxLookahead;h++)s.push(this.LA(h));let l=this.LA(0),u=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:a,actual:s,previous:l,customUserDescription:r,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new kx(u,this.LA(1),l))}}});var vE,fle=N(()=>{"use strict";xx();qt();vE=class{static{o(this,"ContentAssist")}initContentAssist(){}computeContentAssist(e,r){let n=this.gastProductionsCache[e];if(mr(n))throw Error(`Rule ->${e}<- does not exist in this grammar.`);return eE([n],r,this.tokenMatcher,this.maxLookahead)}getNextPossibleTokenTypes(e){let r=ia(e.ruleStack),i=this.getGAstProductions()[r];return new Kk(i,e).startWalking()}}});function Ax(t,e,r,n=!1){bE(r);let i=ma(this.recordingProdStack),a=Ai(e)?e:e.DEF,s=new t({definition:[],idx:r});return n&&(s.separator=e.SEP),Bt(e,"MAX_LOOKAHEAD")&&(s.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(s),a.call(this),i.definition.push(s),this.recordingProdStack.pop(),TE}function zFe(t,e){bE(e);let r=ma(this.recordingProdStack),n=Pt(t)===!1,i=n===!1?t:t.DEF,a=new wn({definition:[],idx:e,ignoreAmbiguities:n&&t.IGNORE_AMBIGUITIES===!0});Bt(t,"MAX_LOOKAHEAD")&&(a.maxLookahead=t.MAX_LOOKAHEAD);let s=B2(i,l=>Ai(l.GATE));return a.hasPredicates=s,r.definition.push(a),Ae(i,l=>{let u=new Dn({definition:[]});a.definition.push(u),Bt(l,"IGNORE_AMBIGUITIES")?u.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:Bt(l,"GATE")&&(u.ignoreAmbiguities=!0),this.recordingProdStack.push(u),l.ALT.call(this),this.recordingProdStack.pop()}),TE}function mle(t){return t===0?"":`${t}`}function bE(t){if(t<0||t>ple){let e=new Error(`Invalid DSL Method idx value: <${t}> + Idx value must be a none negative value smaller than ${ple+1}`);throw e.KNOWN_RECORDER_ERROR=!0,e}}var TE,dle,ple,gle,yle,$Fe,xE,vle=N(()=>{"use strict";qt();fs();px();xp();bp();Us();oE();TE={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(TE);dle=!0,ple=Math.pow(2,8)-1,gle=df({name:"RECORDING_PHASE_TOKEN",pattern:Kn.NA});Uu([gle]);yle=Wu(gle,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(yle);$Fe={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},xE=class{static{o(this,"GastRecorder")}initGastRecorder(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1}enableRecording(){this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",()=>{for(let e=0;e<10;e++){let r=e>0?e:"";this[`CONSUME${r}`]=function(n,i){return this.consumeInternalRecord(n,e,i)},this[`SUBRULE${r}`]=function(n,i){return this.subruleInternalRecord(n,e,i)},this[`OPTION${r}`]=function(n){return this.optionInternalRecord(n,e)},this[`OR${r}`]=function(n){return this.orInternalRecord(n,e)},this[`MANY${r}`]=function(n){this.manyInternalRecord(e,n)},this[`MANY_SEP${r}`]=function(n){this.manySepFirstInternalRecord(e,n)},this[`AT_LEAST_ONE${r}`]=function(n){this.atLeastOneInternalRecord(e,n)},this[`AT_LEAST_ONE_SEP${r}`]=function(n){this.atLeastOneSepFirstInternalRecord(e,n)}}this.consume=function(e,r,n){return this.consumeInternalRecord(r,e,n)},this.subrule=function(e,r,n){return this.subruleInternalRecord(r,e,n)},this.option=function(e,r){return this.optionInternalRecord(r,e)},this.or=function(e,r){return this.orInternalRecord(r,e)},this.many=function(e,r){this.manyInternalRecord(e,r)},this.atLeastOne=function(e,r){this.atLeastOneInternalRecord(e,r)},this.ACTION=this.ACTION_RECORD,this.BACKTRACK=this.BACKTRACK_RECORD,this.LA=this.LA_RECORD})}disableRecording(){this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",()=>{let e=this;for(let r=0;r<10;r++){let n=r>0?r:"";delete e[`CONSUME${n}`],delete e[`SUBRULE${n}`],delete e[`OPTION${n}`],delete e[`OR${n}`],delete e[`MANY${n}`],delete e[`MANY_SEP${n}`],delete e[`AT_LEAST_ONE${n}`],delete e[`AT_LEAST_ONE_SEP${n}`]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})}ACTION_RECORD(e){}BACKTRACK_RECORD(e,r){return()=>!0}LA_RECORD(e){return i1}topLevelRuleRecord(e,r){try{let n=new us({definition:[],name:e});return n.name=e,this.recordingProdStack.push(n),r.call(this),this.recordingProdStack.pop(),n}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}}optionInternalRecord(e,r){return Ax.call(this,ln,e,r)}atLeastOneInternalRecord(e,r){Ax.call(this,Ln,r,e)}atLeastOneSepFirstInternalRecord(e,r){Ax.call(this,Rn,r,e,dle)}manyInternalRecord(e,r){Ax.call(this,Pr,r,e)}manySepFirstInternalRecord(e,r){Ax.call(this,Tn,r,e,dle)}orInternalRecord(e,r){return zFe.call(this,e,r)}subruleInternalRecord(e,r,n){if(bE(r),!e||Bt(e,"ruleName")===!1){let l=new Error(` argument is invalid expecting a Parser method reference but got: <${JSON.stringify(e)}> + inside top level rule: <${this.recordingProdStack[0].name}>`);throw l.KNOWN_RECORDER_ERROR=!0,l}let i=ma(this.recordingProdStack),a=e.ruleName,s=new on({idx:r,nonTerminalName:a,label:n?.LABEL,referencedRule:void 0});return i.definition.push(s),this.outputCst?$Fe:TE}consumeInternalRecord(e,r,n){if(bE(r),!hM(e)){let s=new Error(` argument is invalid expecting a TokenType reference but got: <${JSON.stringify(e)}> + inside top level rule: <${this.recordingProdStack[0].name}>`);throw s.KNOWN_RECORDER_ERROR=!0,s}let i=ma(this.recordingProdStack),a=new Er({idx:r,terminalType:e,label:n?.LABEL});return i.definition.push(a),yle}};o(Ax,"recordProd");o(zFe,"recordOrProd");o(mle,"getIdxSuffix");o(bE,"assertMethodIdxIsValid")});var wE,xle=N(()=>{"use strict";qt();Hg();Us();wE=class{static{o(this,"PerformanceTracer")}initPerformanceTracer(e){if(Bt(e,"traceInitPerf")){let r=e.traceInitPerf,n=typeof r=="number";this.traceInitMaxIdent=n?r:1/0,this.traceInitPerf=n?r>0:r}else this.traceInitMaxIdent=0,this.traceInitPerf=ds.traceInitPerf;this.traceInitIndent=-1}TRACE_INIT(e,r){if(this.traceInitPerf===!0){this.traceInitIndent++;let n=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <${e}>`);let{time:i,value:a}=hx(r),s=i>10?console.warn:console.log;return this.traceInitIndent time: ${i}ms`),this.traceInitIndent--,a}else return r()}}});function ble(t,e){e.forEach(r=>{let n=r.prototype;Object.getOwnPropertyNames(n).forEach(i=>{if(i==="constructor")return;let a=Object.getOwnPropertyDescriptor(n,i);a&&(a.get||a.set)?Object.defineProperty(t.prototype,i,a):t.prototype[i]=r.prototype[i]})})}var Tle=N(()=>{"use strict";o(ble,"applyMixins")});function kE(t=void 0){return function(){return t}}var i1,ds,a1,Vi,_x,Dx,Us=N(()=>{"use strict";qt();Hg();Qse();bp();Qg();Yoe();EM();Joe();ole();lle();cle();ule();hle();fle();vle();xle();Tle();wx();i1=Wu(fo,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(i1);ds=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:qu,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1}),a1=Object.freeze({recoveryValueFunc:o(()=>{},"recoveryValueFunc"),resyncEnabled:!0});(function(t){t[t.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",t[t.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",t[t.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",t[t.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",t[t.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",t[t.LEFT_RECURSION=5]="LEFT_RECURSION",t[t.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",t[t.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",t[t.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",t[t.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",t[t.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",t[t.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",t[t.TOO_MANY_ALTS=12]="TOO_MANY_ALTS",t[t.CUSTOM_LOOKAHEAD_VALIDATION=13]="CUSTOM_LOOKAHEAD_VALIDATION"})(Vi||(Vi={}));o(kE,"EMPTY_ALT");_x=class t{static{o(this,"Parser")}static performSelfAnalysis(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")}performSelfAnalysis(){this.TRACE_INIT("performSelfAnalysis",()=>{let e;this.selfAnalysisDone=!0;let r=this.className;this.TRACE_INIT("toFastProps",()=>{fx(this)}),this.TRACE_INIT("Grammar Recording",()=>{try{this.enableRecording(),Ae(this.definedRulesNames,i=>{let s=this[i].originalGrammarAction,l;this.TRACE_INIT(`${i} Rule`,()=>{l=this.topLevelRuleRecord(i,s)}),this.gastProductionsCache[i]=l})}finally{this.disableRecording()}});let n=[];if(this.TRACE_INIT("Grammar Resolving",()=>{n=Woe({rules:br(this.gastProductionsCache)}),this.definitionErrors=this.definitionErrors.concat(n)}),this.TRACE_INIT("Grammar Validations",()=>{if(hr(n)&&this.skipValidations===!1){let i=qoe({rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),errMsgProvider:$l,grammarName:r}),a=Foe({lookaheadStrategy:this.lookaheadStrategy,rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),grammarName:r});this.definitionErrors=this.definitionErrors.concat(i,a)}}),hr(this.definitionErrors)&&(this.recoveryEnabled&&this.TRACE_INIT("computeAllProdsFollows",()=>{let i=Kse(br(this.gastProductionsCache));this.resyncFollows=i}),this.TRACE_INIT("ComputeLookaheadFunctions",()=>{var i,a;(a=(i=this.lookaheadStrategy).initialize)===null||a===void 0||a.call(i,{rules:br(this.gastProductionsCache)}),this.preComputeLookaheadFunctions(br(this.gastProductionsCache))})),!t.DEFER_DEFINITION_ERRORS_HANDLING&&!hr(this.definitionErrors))throw e=Je(this.definitionErrors,i=>i.message),new Error(`Parser Definition Errors detected: + ${e.join(` +------------------------------- +`)}`)})}constructor(e,r){this.definitionErrors=[],this.selfAnalysisDone=!1;let n=this;if(n.initErrorHandler(r),n.initLexerAdapter(),n.initLooksAhead(r),n.initRecognizerEngine(e,r),n.initRecoverable(r),n.initTreeBuilder(r),n.initContentAssist(),n.initGastRecorder(r),n.initPerformanceTracer(r),Bt(r,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. + Please use the flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=Bt(r,"skipValidations")?r.skipValidations:ds.skipValidations}};_x.DEFER_DEFINITION_ERRORS_HANDLING=!1;ble(_x,[aE,cE,dE,pE,gE,mE,yE,vE,xE,wE]);Dx=class extends _x{static{o(this,"EmbeddedActionsParser")}constructor(e,r=ds){let n=an(r);n.outputCst=!1,super(e,n)}}});var wle=N(()=>{"use strict";fs()});var kle=N(()=>{"use strict"});var Ele=N(()=>{"use strict";wle();kle()});var Sle=N(()=>{"use strict";JN()});var mf=N(()=>{"use strict";JN();Us();px();bp();t1();SM();Qg();n1();fM();fs();fs();Ele();Sle()});function wp(t,e,r){return`${t.name}_${e}_${r}`}function Dle(t){let e={decisionMap:{},decisionStates:[],ruleToStartState:new Map,ruleToStopState:new Map,states:[]};YFe(e,t);let r=t.length;for(let n=0;nLle(t,e,s));return c1(t,e,n,r,...i)}function JFe(t,e,r){let n=aa(t,e,r,{type:gf});yf(t,n);let i=c1(t,e,n,r,kp(t,e,r));return e$e(t,e,r,i)}function kp(t,e,r){let n=Yr(Je(r.definition,i=>Lle(t,e,i)),i=>i!==void 0);return n.length===1?n[0]:n.length===0?void 0:r$e(t,n)}function Rle(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:qFe});yf(t,l);let u=aa(t,e,r,{type:_le});return a.loopback=l,u.loopback=l,t.decisionMap[wp(e,i?"RepetitionMandatoryWithSeparator":"RepetitionMandatory",r.idx)]=l,Di(s,l),i===void 0?(Di(l,a),Di(l,u)):(Di(l,u),Di(l,i.left),Di(i.right,a)),{left:a,right:u}}function Nle(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:WFe});yf(t,l);let u=aa(t,e,r,{type:_le}),h=aa(t,e,r,{type:HFe});return l.loopback=h,u.loopback=h,Di(l,a),Di(l,u),Di(s,h),i!==void 0?(Di(h,u),Di(h,i.left),Di(i.right,a)):Di(h,l),t.decisionMap[wp(e,i?"RepetitionWithSeparator":"Repetition",r.idx)]=l,{left:l,right:u}}function e$e(t,e,r,n){let i=n.left,a=n.right;return Di(i,a),t.decisionMap[wp(e,"Option",r.idx)]=i,n}function yf(t,e){return t.decisionStates.push(e),e.decision=t.decisionStates.length-1,e.decision}function c1(t,e,r,n,...i){let a=aa(t,e,n,{type:UFe,start:r});r.end=a;for(let l of i)l!==void 0?(Di(r,l.left),Di(l.right,a)):Di(r,a);let s={left:r,right:a};return t.decisionMap[wp(e,t$e(n),n.idx)]=r,s}function t$e(t){if(t instanceof wn)return"Alternation";if(t instanceof ln)return"Option";if(t instanceof Pr)return"Repetition";if(t instanceof Tn)return"RepetitionWithSeparator";if(t instanceof Ln)return"RepetitionMandatory";if(t instanceof Rn)return"RepetitionMandatoryWithSeparator";throw new Error("Invalid production type encountered")}function r$e(t,e){let r=e.length;for(let a=0;a{"use strict";Um();fR();mf();o(wp,"buildATNKey");gf=1,VFe=2,Cle=4,Ale=5,l1=7,UFe=8,HFe=9,WFe=10,qFe=11,_le=12,Lx=class{static{o(this,"AbstractTransition")}constructor(e){this.target=e}isEpsilon(){return!1}},s1=class extends Lx{static{o(this,"AtomTransition")}constructor(e,r){super(e),this.tokenType=r}},Rx=class extends Lx{static{o(this,"EpsilonTransition")}constructor(e){super(e)}isEpsilon(){return!0}},o1=class extends Lx{static{o(this,"RuleTransition")}constructor(e,r,n){super(e),this.rule=r,this.followState=n}isEpsilon(){return!0}};o(Dle,"createATN");o(YFe,"createRuleStartAndStopATNStates");o(Lle,"atom");o(XFe,"repetition");o(jFe,"repetitionSep");o(KFe,"repetitionMandatory");o(QFe,"repetitionMandatorySep");o(ZFe,"alternation");o(JFe,"option");o(kp,"block");o(Rle,"plus");o(Nle,"star");o(e$e,"optional");o(yf,"defineDecisionState");o(c1,"makeAlts");o(t$e,"getProdType");o(r$e,"makeBlock");o(IM,"tokenRef");o(n$e,"ruleRef");o(i$e,"buildRuleHandle");o(Di,"epsilon");o(aa,"newState");o(OM,"addTransition");o(a$e,"removeState")});function PM(t,e=!0){return`${e?`a${t.alt}`:""}s${t.state.stateNumber}:${t.stack.map(r=>r.stateNumber.toString()).join("_")}`}var Nx,u1,Ile=N(()=>{"use strict";Um();Nx={},u1=class{static{o(this,"ATNConfigSet")}constructor(){this.map={},this.configs=[]}get size(){return this.configs.length}finalize(){this.map={}}add(e){let r=PM(e);r in this.map||(this.map[r]=this.configs.length,this.configs.push(e))}get elements(){return this.configs}get alts(){return Je(this.configs,e=>e.alt)}get key(){let e="";for(let r in this.map)e+=r+":";return e}};o(PM,"getATNConfigKey")});function s$e(t,e){let r={};return n=>{let i=n.toString(),a=r[i];return a!==void 0||(a={atnStartState:t,decision:e,states:{}},r[i]=a),a}}function Ple(t,e=!0){let r=new Set;for(let n of t){let i=new Set;for(let a of n){if(a===void 0){if(e)break;return!1}let s=[a.tokenTypeIdx].concat(a.categoryMatches);for(let l of s)if(r.has(l)){if(!i.has(l))return!1}else r.add(l),i.add(l)}}return!0}function o$e(t){let e=t.decisionStates.length,r=Array(e);for(let n=0;nHu(i)).join(", "),r=t.production.idx===0?"":t.production.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(", ")}> in <${f$e(t.production)}${r}> inside <${t.topLevelRule.name}> Rule, +<${e}> may appears as a prefix path in all these alternatives. +`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,n}function f$e(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof wn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof Tn)return"MANY_SEP";if(t instanceof Pr)return"MANY";if(t instanceof Er)return"CONSUME";throw Error("non exhaustive match")}function d$e(t,e,r){let n=ga(e.configs.elements,a=>a.state.transitions),i=die(n.filter(a=>a instanceof s1).map(a=>a.tokenType),a=>a.tokenTypeIdx);return{actualToken:r,possibleTokenTypes:i,tokenPath:t}}function p$e(t,e){return t.edges[e.tokenTypeIdx]}function m$e(t,e,r){let n=new u1,i=[];for(let s of t.elements){if(r.is(s.alt)===!1)continue;if(s.state.type===l1){i.push(s);continue}let l=s.state.transitions.length;for(let u=0;u0&&!b$e(a))for(let s of i)a.add(s);return a}function g$e(t,e){if(t instanceof s1&&gx(e,t.tokenType))return t.target}function y$e(t,e){let r;for(let n of t.elements)if(e.is(n.alt)===!0){if(r===void 0)r=n.alt;else if(r!==n.alt)return}return r}function Fle(t){return{configs:t,edges:{},isAcceptState:!1,prediction:-1}}function Ble(t,e,r,n){return n=$le(t,n),e.edges[r.tokenTypeIdx]=n,n}function $le(t,e){if(e===Nx)return e;let r=e.configs.key,n=t.states[r];return n!==void 0?n:(e.configs.finalize(),t.states[r]=e,e)}function v$e(t){let e=new u1,r=t.transitions.length;for(let n=0;n0){let i=[...t.stack],s={state:i.pop(),alt:t.alt,stack:i};SE(s,e)}else e.add(t);return}r.epsilonOnlyTransitions||e.add(t);let n=r.transitions.length;for(let i=0;i1)return!0;return!1}function S$e(t){for(let e of Array.from(t.values()))if(Object.keys(e).length===1)return!0;return!1}var EE,Ole,Mx,zle=N(()=>{"use strict";mf();Mle();Ile();bR();pR();pie();Um();Sw();ek();ak();ER();o(s$e,"createDFACache");EE=class{static{o(this,"PredicateSet")}constructor(){this.predicates=[]}is(e){return e>=this.predicates.length||this.predicates[e]}set(e,r){this.predicates[e]=r}toString(){let e="",r=this.predicates.length;for(let n=0;nconsole.log(n)}initialize(e){this.atn=Dle(e.rules),this.dfas=o$e(this.atn)}validateAmbiguousAlternationAlternatives(){return[]}validateEmptyOrAlternatives(){return[]}buildLookaheadForAlternation(e){let{prodOccurrence:r,rule:n,hasPredicates:i,dynamicTokensEnabled:a}=e,s=this.dfas,l=this.logging,u=wp(n,"Alternation",r),f=this.atn.decisionMap[u].decision,d=Je(rE({maxLookahead:1,occurrence:r,prodType:"Alternation",rule:n}),p=>Je(p,m=>m[0]));if(Ple(d,!1)&&!a){let p=Xr(d,(m,g,y)=>(Ae(g,v=>{v&&(m[v.tokenTypeIdx]=y,Ae(v.categoryMatches,x=>{m[x]=y}))}),m),{});return i?function(m){var g;let y=this.LA(1),v=p[y.tokenTypeIdx];if(m!==void 0&&v!==void 0){let x=(g=m[v])===null||g===void 0?void 0:g.GATE;if(x!==void 0&&x.call(this)===!1)return}return v}:function(){let m=this.LA(1);return p[m.tokenTypeIdx]}}else return i?function(p){let m=new EE,g=p===void 0?0:p.length;for(let v=0;vJe(p,m=>m[0]));if(Ple(d)&&d[0][0]&&!a){let p=d[0],m=qr(p);if(m.length===1&&hr(m[0].categoryMatches)){let y=m[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===y}}else{let g=Xr(m,(y,v)=>(v!==void 0&&(y[v.tokenTypeIdx]=!0,Ae(v.categoryMatches,x=>{y[x]=!0})),y),{});return function(){let y=this.LA(1);return g[y.tokenTypeIdx]===!0}}}return function(){let p=BM.call(this,s,f,Ole,l);return typeof p=="object"?!1:p===0}}};o(Ple,"isLL1Sequence");o(o$e,"initATNSimulator");o(BM,"adaptivePredict");o(l$e,"performLookahead");o(c$e,"computeLookaheadTarget");o(u$e,"reportLookaheadAmbiguity");o(h$e,"buildAmbiguityError");o(f$e,"getProductionDslName");o(d$e,"buildAdaptivePredictError");o(p$e,"getExistingTargetState");o(m$e,"computeReachSet");o(g$e,"getReachableTarget");o(y$e,"getUniqueAlt");o(Fle,"newDFAState");o(Ble,"addDFAEdge");o($le,"addDFAState");o(v$e,"computeStartState");o(SE,"closure");o(x$e,"getEpsilonTarget");o(b$e,"hasConfigInRuleStopState");o(T$e,"allConfigsInRuleStopStates");o(w$e,"hasConflictTerminatingPrediction");o(k$e,"getConflictingAltSets");o(E$e,"hasConflictingAltSet");o(S$e,"hasStateAssociatedWithOneAlt")});var Gle=N(()=>{"use strict";zle()});var Vle,FM,Ule,CE,jr,Br,AE,Hle,$M,Wle,qle,Yle,Xle,zM,jle,Kle,Qle,_E,h1,f1,GM,d1,Zle,VM,UM,HM,WM,qM,Jle,ece,YM,tce,XM,Ix,rce,nce,ice,ace,sce,oce,lce,cce,DE,uce,hce,fce,dce,pce,mce,gce,yce,vce,xce,bce,LE,Tce,wce,kce,Ece,Sce,Cce,Ace,_ce,Dce,Lce,Rce,Nce,Mce,jM,KM,Ice,Oce,Pce,Bce,Fce,$ce,zce,Gce,Vce,QM,$e,ZM=N(()=>{"use strict";(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(Vle||(Vle={}));(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(FM||(FM={}));(function(t){t.MIN_VALUE=-2147483648,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(Ule||(Ule={}));(function(t){t.MIN_VALUE=0,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(CE||(CE={}));(function(t){function e(n,i){return n===Number.MAX_VALUE&&(n=CE.MAX_VALUE),i===Number.MAX_VALUE&&(i=CE.MAX_VALUE),{line:n,character:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.uinteger(i.line)&&$e.uinteger(i.character)}o(r,"is"),t.is=r})(jr||(jr={}));(function(t){function e(n,i,a,s){if($e.uinteger(n)&&$e.uinteger(i)&&$e.uinteger(a)&&$e.uinteger(s))return{start:jr.create(n,i),end:jr.create(a,s)};if(jr.is(n)&&jr.is(i))return{start:n,end:i};throw new Error(`Range#create called with invalid arguments[${n}, ${i}, ${a}, ${s}]`)}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&jr.is(i.start)&&jr.is(i.end)}o(r,"is"),t.is=r})(Br||(Br={}));(function(t){function e(n,i){return{uri:n,range:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&($e.string(i.uri)||$e.undefined(i.uri))}o(r,"is"),t.is=r})(AE||(AE={}));(function(t){function e(n,i,a,s){return{targetUri:n,targetRange:i,targetSelectionRange:a,originSelectionRange:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.targetRange)&&$e.string(i.targetUri)&&Br.is(i.targetSelectionRange)&&(Br.is(i.originSelectionRange)||$e.undefined(i.originSelectionRange))}o(r,"is"),t.is=r})(Hle||(Hle={}));(function(t){function e(n,i,a,s){return{red:n,green:i,blue:a,alpha:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.numberRange(i.red,0,1)&&$e.numberRange(i.green,0,1)&&$e.numberRange(i.blue,0,1)&&$e.numberRange(i.alpha,0,1)}o(r,"is"),t.is=r})($M||($M={}));(function(t){function e(n,i){return{range:n,color:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&$M.is(i.color)}o(r,"is"),t.is=r})(Wle||(Wle={}));(function(t){function e(n,i,a){return{label:n,textEdit:i,additionalTextEdits:a}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.string(i.label)&&($e.undefined(i.textEdit)||f1.is(i))&&($e.undefined(i.additionalTextEdits)||$e.typedArray(i.additionalTextEdits,f1.is))}o(r,"is"),t.is=r})(qle||(qle={}));(function(t){t.Comment="comment",t.Imports="imports",t.Region="region"})(Yle||(Yle={}));(function(t){function e(n,i,a,s,l,u){let h={startLine:n,endLine:i};return $e.defined(a)&&(h.startCharacter=a),$e.defined(s)&&(h.endCharacter=s),$e.defined(l)&&(h.kind=l),$e.defined(u)&&(h.collapsedText=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.uinteger(i.startLine)&&$e.uinteger(i.startLine)&&($e.undefined(i.startCharacter)||$e.uinteger(i.startCharacter))&&($e.undefined(i.endCharacter)||$e.uinteger(i.endCharacter))&&($e.undefined(i.kind)||$e.string(i.kind))}o(r,"is"),t.is=r})(Xle||(Xle={}));(function(t){function e(n,i){return{location:n,message:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&AE.is(i.location)&&$e.string(i.message)}o(r,"is"),t.is=r})(zM||(zM={}));(function(t){t.Error=1,t.Warning=2,t.Information=3,t.Hint=4})(jle||(jle={}));(function(t){t.Unnecessary=1,t.Deprecated=2})(Kle||(Kle={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&$e.string(n.href)}o(e,"is"),t.is=e})(Qle||(Qle={}));(function(t){function e(n,i,a,s,l,u){let h={range:n,message:i};return $e.defined(a)&&(h.severity=a),$e.defined(s)&&(h.code=s),$e.defined(l)&&(h.source=l),$e.defined(u)&&(h.relatedInformation=u),h}o(e,"create"),t.create=e;function r(n){var i;let a=n;return $e.defined(a)&&Br.is(a.range)&&$e.string(a.message)&&($e.number(a.severity)||$e.undefined(a.severity))&&($e.integer(a.code)||$e.string(a.code)||$e.undefined(a.code))&&($e.undefined(a.codeDescription)||$e.string((i=a.codeDescription)===null||i===void 0?void 0:i.href))&&($e.string(a.source)||$e.undefined(a.source))&&($e.undefined(a.relatedInformation)||$e.typedArray(a.relatedInformation,zM.is))}o(r,"is"),t.is=r})(_E||(_E={}));(function(t){function e(n,i,...a){let s={title:n,command:i};return $e.defined(a)&&a.length>0&&(s.arguments=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.title)&&$e.string(i.command)}o(r,"is"),t.is=r})(h1||(h1={}));(function(t){function e(a,s){return{range:a,newText:s}}o(e,"replace"),t.replace=e;function r(a,s){return{range:{start:a,end:a},newText:s}}o(r,"insert"),t.insert=r;function n(a){return{range:a,newText:""}}o(n,"del"),t.del=n;function i(a){let s=a;return $e.objectLiteral(s)&&$e.string(s.newText)&&Br.is(s.range)}o(i,"is"),t.is=i})(f1||(f1={}));(function(t){function e(n,i,a){let s={label:n};return i!==void 0&&(s.needsConfirmation=i),a!==void 0&&(s.description=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.string(i.label)&&($e.boolean(i.needsConfirmation)||i.needsConfirmation===void 0)&&($e.string(i.description)||i.description===void 0)}o(r,"is"),t.is=r})(GM||(GM={}));(function(t){function e(r){let n=r;return $e.string(n)}o(e,"is"),t.is=e})(d1||(d1={}));(function(t){function e(a,s,l){return{range:a,newText:s,annotationId:l}}o(e,"replace"),t.replace=e;function r(a,s,l){return{range:{start:a,end:a},newText:s,annotationId:l}}o(r,"insert"),t.insert=r;function n(a,s){return{range:a,newText:"",annotationId:s}}o(n,"del"),t.del=n;function i(a){let s=a;return f1.is(s)&&(GM.is(s.annotationId)||d1.is(s.annotationId))}o(i,"is"),t.is=i})(Zle||(Zle={}));(function(t){function e(n,i){return{textDocument:n,edits:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&YM.is(i.textDocument)&&Array.isArray(i.edits)}o(r,"is"),t.is=r})(VM||(VM={}));(function(t){function e(n,i,a){let s={kind:"create",uri:n};return i!==void 0&&(i.overwrite!==void 0||i.ignoreIfExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="create"&&$e.string(i.uri)&&(i.options===void 0||(i.options.overwrite===void 0||$e.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||$e.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(UM||(UM={}));(function(t){function e(n,i,a,s){let l={kind:"rename",oldUri:n,newUri:i};return a!==void 0&&(a.overwrite!==void 0||a.ignoreIfExists!==void 0)&&(l.options=a),s!==void 0&&(l.annotationId=s),l}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="rename"&&$e.string(i.oldUri)&&$e.string(i.newUri)&&(i.options===void 0||(i.options.overwrite===void 0||$e.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||$e.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(HM||(HM={}));(function(t){function e(n,i,a){let s={kind:"delete",uri:n};return i!==void 0&&(i.recursive!==void 0||i.ignoreIfNotExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="delete"&&$e.string(i.uri)&&(i.options===void 0||(i.options.recursive===void 0||$e.boolean(i.options.recursive))&&(i.options.ignoreIfNotExists===void 0||$e.boolean(i.options.ignoreIfNotExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(WM||(WM={}));(function(t){function e(r){let n=r;return n&&(n.changes!==void 0||n.documentChanges!==void 0)&&(n.documentChanges===void 0||n.documentChanges.every(i=>$e.string(i.kind)?UM.is(i)||HM.is(i)||WM.is(i):VM.is(i)))}o(e,"is"),t.is=e})(qM||(qM={}));(function(t){function e(n){return{uri:n}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)}o(r,"is"),t.is=r})(Jle||(Jle={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&$e.integer(i.version)}o(r,"is"),t.is=r})(ece||(ece={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&(i.version===null||$e.integer(i.version))}o(r,"is"),t.is=r})(YM||(YM={}));(function(t){function e(n,i,a,s){return{uri:n,languageId:i,version:a,text:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&$e.string(i.languageId)&&$e.integer(i.version)&&$e.string(i.text)}o(r,"is"),t.is=r})(tce||(tce={}));(function(t){t.PlainText="plaintext",t.Markdown="markdown";function e(r){let n=r;return n===t.PlainText||n===t.Markdown}o(e,"is"),t.is=e})(XM||(XM={}));(function(t){function e(r){let n=r;return $e.objectLiteral(r)&&XM.is(n.kind)&&$e.string(n.value)}o(e,"is"),t.is=e})(Ix||(Ix={}));(function(t){t.Text=1,t.Method=2,t.Function=3,t.Constructor=4,t.Field=5,t.Variable=6,t.Class=7,t.Interface=8,t.Module=9,t.Property=10,t.Unit=11,t.Value=12,t.Enum=13,t.Keyword=14,t.Snippet=15,t.Color=16,t.File=17,t.Reference=18,t.Folder=19,t.EnumMember=20,t.Constant=21,t.Struct=22,t.Event=23,t.Operator=24,t.TypeParameter=25})(rce||(rce={}));(function(t){t.PlainText=1,t.Snippet=2})(nce||(nce={}));(function(t){t.Deprecated=1})(ice||(ice={}));(function(t){function e(n,i,a){return{newText:n,insert:i,replace:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.newText)&&Br.is(i.insert)&&Br.is(i.replace)}o(r,"is"),t.is=r})(ace||(ace={}));(function(t){t.asIs=1,t.adjustIndentation=2})(sce||(sce={}));(function(t){function e(r){let n=r;return n&&($e.string(n.detail)||n.detail===void 0)&&($e.string(n.description)||n.description===void 0)}o(e,"is"),t.is=e})(oce||(oce={}));(function(t){function e(r){return{label:r}}o(e,"create"),t.create=e})(lce||(lce={}));(function(t){function e(r,n){return{items:r||[],isIncomplete:!!n}}o(e,"create"),t.create=e})(cce||(cce={}));(function(t){function e(n){return n.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}o(e,"fromPlainText"),t.fromPlainText=e;function r(n){let i=n;return $e.string(i)||$e.objectLiteral(i)&&$e.string(i.language)&&$e.string(i.value)}o(r,"is"),t.is=r})(DE||(DE={}));(function(t){function e(r){let n=r;return!!n&&$e.objectLiteral(n)&&(Ix.is(n.contents)||DE.is(n.contents)||$e.typedArray(n.contents,DE.is))&&(r.range===void 0||Br.is(r.range))}o(e,"is"),t.is=e})(uce||(uce={}));(function(t){function e(r,n){return n?{label:r,documentation:n}:{label:r}}o(e,"create"),t.create=e})(hce||(hce={}));(function(t){function e(r,n,...i){let a={label:r};return $e.defined(n)&&(a.documentation=n),$e.defined(i)?a.parameters=i:a.parameters=[],a}o(e,"create"),t.create=e})(fce||(fce={}));(function(t){t.Text=1,t.Read=2,t.Write=3})(dce||(dce={}));(function(t){function e(r,n){let i={range:r};return $e.number(n)&&(i.kind=n),i}o(e,"create"),t.create=e})(pce||(pce={}));(function(t){t.File=1,t.Module=2,t.Namespace=3,t.Package=4,t.Class=5,t.Method=6,t.Property=7,t.Field=8,t.Constructor=9,t.Enum=10,t.Interface=11,t.Function=12,t.Variable=13,t.Constant=14,t.String=15,t.Number=16,t.Boolean=17,t.Array=18,t.Object=19,t.Key=20,t.Null=21,t.EnumMember=22,t.Struct=23,t.Event=24,t.Operator=25,t.TypeParameter=26})(mce||(mce={}));(function(t){t.Deprecated=1})(gce||(gce={}));(function(t){function e(r,n,i,a,s){let l={name:r,kind:n,location:{uri:a,range:i}};return s&&(l.containerName=s),l}o(e,"create"),t.create=e})(yce||(yce={}));(function(t){function e(r,n,i,a){return a!==void 0?{name:r,kind:n,location:{uri:i,range:a}}:{name:r,kind:n,location:{uri:i}}}o(e,"create"),t.create=e})(vce||(vce={}));(function(t){function e(n,i,a,s,l,u){let h={name:n,detail:i,kind:a,range:s,selectionRange:l};return u!==void 0&&(h.children=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.name)&&$e.number(i.kind)&&Br.is(i.range)&&Br.is(i.selectionRange)&&(i.detail===void 0||$e.string(i.detail))&&(i.deprecated===void 0||$e.boolean(i.deprecated))&&(i.children===void 0||Array.isArray(i.children))&&(i.tags===void 0||Array.isArray(i.tags))}o(r,"is"),t.is=r})(xce||(xce={}));(function(t){t.Empty="",t.QuickFix="quickfix",t.Refactor="refactor",t.RefactorExtract="refactor.extract",t.RefactorInline="refactor.inline",t.RefactorRewrite="refactor.rewrite",t.Source="source",t.SourceOrganizeImports="source.organizeImports",t.SourceFixAll="source.fixAll"})(bce||(bce={}));(function(t){t.Invoked=1,t.Automatic=2})(LE||(LE={}));(function(t){function e(n,i,a){let s={diagnostics:n};return i!=null&&(s.only=i),a!=null&&(s.triggerKind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.typedArray(i.diagnostics,_E.is)&&(i.only===void 0||$e.typedArray(i.only,$e.string))&&(i.triggerKind===void 0||i.triggerKind===LE.Invoked||i.triggerKind===LE.Automatic)}o(r,"is"),t.is=r})(Tce||(Tce={}));(function(t){function e(n,i,a){let s={title:n},l=!0;return typeof i=="string"?(l=!1,s.kind=i):h1.is(i)?s.command=i:s.edit=i,l&&a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.title)&&(i.diagnostics===void 0||$e.typedArray(i.diagnostics,_E.is))&&(i.kind===void 0||$e.string(i.kind))&&(i.edit!==void 0||i.command!==void 0)&&(i.command===void 0||h1.is(i.command))&&(i.isPreferred===void 0||$e.boolean(i.isPreferred))&&(i.edit===void 0||qM.is(i.edit))}o(r,"is"),t.is=r})(wce||(wce={}));(function(t){function e(n,i){let a={range:n};return $e.defined(i)&&(a.data=i),a}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(i.range)&&($e.undefined(i.command)||h1.is(i.command))}o(r,"is"),t.is=r})(kce||(kce={}));(function(t){function e(n,i){return{tabSize:n,insertSpaces:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.uinteger(i.tabSize)&&$e.boolean(i.insertSpaces)}o(r,"is"),t.is=r})(Ece||(Ece={}));(function(t){function e(n,i,a){return{range:n,target:i,data:a}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(i.range)&&($e.undefined(i.target)||$e.string(i.target))}o(r,"is"),t.is=r})(Sce||(Sce={}));(function(t){function e(n,i){return{range:n,parent:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&(i.parent===void 0||t.is(i.parent))}o(r,"is"),t.is=r})(Cce||(Cce={}));(function(t){t.namespace="namespace",t.type="type",t.class="class",t.enum="enum",t.interface="interface",t.struct="struct",t.typeParameter="typeParameter",t.parameter="parameter",t.variable="variable",t.property="property",t.enumMember="enumMember",t.event="event",t.function="function",t.method="method",t.macro="macro",t.keyword="keyword",t.modifier="modifier",t.comment="comment",t.string="string",t.number="number",t.regexp="regexp",t.operator="operator",t.decorator="decorator"})(Ace||(Ace={}));(function(t){t.declaration="declaration",t.definition="definition",t.readonly="readonly",t.static="static",t.deprecated="deprecated",t.abstract="abstract",t.async="async",t.modification="modification",t.documentation="documentation",t.defaultLibrary="defaultLibrary"})(_ce||(_ce={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&(n.resultId===void 0||typeof n.resultId=="string")&&Array.isArray(n.data)&&(n.data.length===0||typeof n.data[0]=="number")}o(e,"is"),t.is=e})(Dce||(Dce={}));(function(t){function e(n,i){return{range:n,text:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&$e.string(i.text)}o(r,"is"),t.is=r})(Lce||(Lce={}));(function(t){function e(n,i,a){return{range:n,variableName:i,caseSensitiveLookup:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&$e.boolean(i.caseSensitiveLookup)&&($e.string(i.variableName)||i.variableName===void 0)}o(r,"is"),t.is=r})(Rce||(Rce={}));(function(t){function e(n,i){return{range:n,expression:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&($e.string(i.expression)||i.expression===void 0)}o(r,"is"),t.is=r})(Nce||(Nce={}));(function(t){function e(n,i){return{frameId:n,stoppedLocation:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(n.stoppedLocation)}o(r,"is"),t.is=r})(Mce||(Mce={}));(function(t){t.Type=1,t.Parameter=2;function e(r){return r===1||r===2}o(e,"is"),t.is=e})(jM||(jM={}));(function(t){function e(n){return{value:n}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&(i.tooltip===void 0||$e.string(i.tooltip)||Ix.is(i.tooltip))&&(i.location===void 0||AE.is(i.location))&&(i.command===void 0||h1.is(i.command))}o(r,"is"),t.is=r})(KM||(KM={}));(function(t){function e(n,i,a){let s={position:n,label:i};return a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&jr.is(i.position)&&($e.string(i.label)||$e.typedArray(i.label,KM.is))&&(i.kind===void 0||jM.is(i.kind))&&i.textEdits===void 0||$e.typedArray(i.textEdits,f1.is)&&(i.tooltip===void 0||$e.string(i.tooltip)||Ix.is(i.tooltip))&&(i.paddingLeft===void 0||$e.boolean(i.paddingLeft))&&(i.paddingRight===void 0||$e.boolean(i.paddingRight))}o(r,"is"),t.is=r})(Ice||(Ice={}));(function(t){function e(r){return{kind:"snippet",value:r}}o(e,"createSnippet"),t.createSnippet=e})(Oce||(Oce={}));(function(t){function e(r,n,i,a){return{insertText:r,filterText:n,range:i,command:a}}o(e,"create"),t.create=e})(Pce||(Pce={}));(function(t){function e(r){return{items:r}}o(e,"create"),t.create=e})(Bce||(Bce={}));(function(t){t.Invoked=0,t.Automatic=1})(Fce||(Fce={}));(function(t){function e(r,n){return{range:r,text:n}}o(e,"create"),t.create=e})($ce||($ce={}));(function(t){function e(r,n){return{triggerKind:r,selectedCompletionInfo:n}}o(e,"create"),t.create=e})(zce||(zce={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&FM.is(n.uri)&&$e.string(n.name)}o(e,"is"),t.is=e})(Gce||(Gce={}));(function(t){function e(a,s,l,u){return new QM(a,s,l,u)}o(e,"create"),t.create=e;function r(a){let s=a;return!!($e.defined(s)&&$e.string(s.uri)&&($e.undefined(s.languageId)||$e.string(s.languageId))&&$e.uinteger(s.lineCount)&&$e.func(s.getText)&&$e.func(s.positionAt)&&$e.func(s.offsetAt))}o(r,"is"),t.is=r;function n(a,s){let l=a.getText(),u=i(s,(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),h=l.length;for(let f=u.length-1;f>=0;f--){let d=u[f],p=a.offsetAt(d.range.start),m=a.offsetAt(d.range.end);if(m<=h)l=l.substring(0,p)+d.newText+l.substring(m,l.length);else throw new Error("Overlapping edit");h=p}return l}o(n,"applyEdits"),t.applyEdits=n;function i(a,s){if(a.length<=1)return a;let l=a.length/2|0,u=a.slice(0,l),h=a.slice(l);i(u,s),i(h,s);let f=0,d=0,p=0;for(;f0&&e.push(r.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let r=this.getLineOffsets(),n=0,i=r.length;if(i===0)return jr.create(0,e);for(;ne?i=s:n=s+1}let a=n-1;return jr.create(a,e-r[a])}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line],i=e.line+1"u"}o(n,"undefined"),t.undefined=n;function i(m){return m===!0||m===!1}o(i,"boolean"),t.boolean=i;function a(m){return e.call(m)==="[object String]"}o(a,"string"),t.string=a;function s(m){return e.call(m)==="[object Number]"}o(s,"number"),t.number=s;function l(m,g,y){return e.call(m)==="[object Number]"&&g<=m&&m<=y}o(l,"numberRange"),t.numberRange=l;function u(m){return e.call(m)==="[object Number]"&&-2147483648<=m&&m<=2147483647}o(u,"integer"),t.integer=u;function h(m){return e.call(m)==="[object Number]"&&0<=m&&m<=2147483647}o(h,"uinteger"),t.uinteger=h;function f(m){return e.call(m)==="[object Function]"}o(f,"func"),t.func=f;function d(m){return m!==null&&typeof m=="object"}o(d,"objectLiteral"),t.objectLiteral=d;function p(m,g){return Array.isArray(m)&&m.every(g)}o(p,"typedArray"),t.typedArray=p})($e||($e={}))});var Ox,Px,Ep,Sp,JM,p1,RE=N(()=>{"use strict";ZM();Ol();Ox=class{static{o(this,"CstNodeBuilder")}constructor(){this.nodeStack=[]}get current(){var e;return(e=this.nodeStack[this.nodeStack.length-1])!==null&&e!==void 0?e:this.rootNode}buildRootNode(e){return this.rootNode=new p1(e),this.rootNode.root=this.rootNode,this.nodeStack=[this.rootNode],this.rootNode}buildCompositeNode(e){let r=new Sp;return r.grammarSource=e,r.root=this.rootNode,this.current.content.push(r),this.nodeStack.push(r),r}buildLeafNode(e,r){let n=new Ep(e.startOffset,e.image.length,Km(e),e.tokenType,!r);return n.grammarSource=r,n.root=this.rootNode,this.current.content.push(n),n}removeNode(e){let r=e.container;if(r){let n=r.content.indexOf(e);n>=0&&r.content.splice(n,1)}}addHiddenNodes(e){let r=[];for(let a of e){let s=new Ep(a.startOffset,a.image.length,Km(a),a.tokenType,!0);s.root=this.rootNode,r.push(s)}let n=this.current,i=!1;if(n.content.length>0){n.content.push(...r);return}for(;n.container;){let a=n.container.content.indexOf(n);if(a>0){n.container.content.splice(a,0,...r),i=!0;break}n=n.container}i||this.rootNode.content.unshift(...r)}construct(e){let r=this.current;typeof e.$type=="string"&&(this.current.astNode=e),e.$cstNode=r;let n=this.nodeStack.pop();n?.content.length===0&&this.removeNode(n)}},Px=class{static{o(this,"AbstractCstNode")}get parent(){return this.container}get feature(){return this.grammarSource}get hidden(){return!1}get astNode(){var e,r;let n=typeof((e=this._astNode)===null||e===void 0?void 0:e.$type)=="string"?this._astNode:(r=this.container)===null||r===void 0?void 0:r.astNode;if(!n)throw new Error("This node has no associated AST element");return n}set astNode(e){this._astNode=e}get element(){return this.astNode}get text(){return this.root.fullText.substring(this.offset,this.end)}},Ep=class extends Px{static{o(this,"LeafCstNodeImpl")}get offset(){return this._offset}get length(){return this._length}get end(){return this._offset+this._length}get hidden(){return this._hidden}get tokenType(){return this._tokenType}get range(){return this._range}constructor(e,r,n,i,a=!1){super(),this._hidden=a,this._offset=e,this._tokenType=i,this._length=r,this._range=n}},Sp=class extends Px{static{o(this,"CompositeCstNodeImpl")}constructor(){super(...arguments),this.content=new JM(this)}get children(){return this.content}get offset(){var e,r;return(r=(e=this.firstNonHiddenNode)===null||e===void 0?void 0:e.offset)!==null&&r!==void 0?r:0}get length(){return this.end-this.offset}get end(){var e,r;return(r=(e=this.lastNonHiddenNode)===null||e===void 0?void 0:e.end)!==null&&r!==void 0?r:0}get range(){let e=this.firstNonHiddenNode,r=this.lastNonHiddenNode;if(e&&r){if(this._rangeCache===void 0){let{range:n}=e,{range:i}=r;this._rangeCache={start:n.start,end:i.end.line=0;e--){let r=this.content[e];if(!r.hidden)return r}return this.content[this.content.length-1]}},JM=class t extends Array{static{o(this,"CstNodeContainer")}constructor(e){super(),this.parent=e,Object.setPrototypeOf(this,t.prototype)}push(...e){return this.addParents(e),super.push(...e)}unshift(...e){return this.addParents(e),super.unshift(...e)}splice(e,r,...n){return this.addParents(n),super.splice(e,r,...n)}addParents(e){for(let r of e)r.container=this.parent}},p1=class extends Sp{static{o(this,"RootCstNodeImpl")}get text(){return this._text.substring(this.offset,this.end)}get fullText(){return this._text}constructor(e){super(),this._text="",this._text=e??""}}});function eI(t){return t.$type===NE}var NE,Uce,Hce,Bx,Fx,ME,m1,$x,C$e,tI,zx=N(()=>{"use strict";mf();Gle();Pc();Fl();cs();RE();NE=Symbol("Datatype");o(eI,"isDataTypeNode");Uce="\u200B",Hce=o(t=>t.endsWith(Uce)?t:t+Uce,"withRuleSuffix"),Bx=class{static{o(this,"AbstractLangiumParser")}constructor(e){this._unorderedGroups=new Map,this.allRules=new Map,this.lexer=e.parser.Lexer;let r=this.lexer.definition,n=e.LanguageMetaData.mode==="production";this.wrapper=new tI(r,Object.assign(Object.assign({},e.parser.ParserConfig),{skipValidations:n,errorMessageProvider:e.parser.ParserErrorMessageProvider}))}alternatives(e,r){this.wrapper.wrapOr(e,r)}optional(e,r){this.wrapper.wrapOption(e,r)}many(e,r){this.wrapper.wrapMany(e,r)}atLeastOne(e,r){this.wrapper.wrapAtLeastOne(e,r)}getRule(e){return this.allRules.get(e)}isRecording(){return this.wrapper.IS_RECORDING}get unorderedGroups(){return this._unorderedGroups}getRuleStack(){return this.wrapper.RULE_STACK}finalize(){this.wrapper.wrapSelfAnalysis()}},Fx=class extends Bx{static{o(this,"LangiumParser")}get current(){return this.stack[this.stack.length-1]}constructor(e){super(e),this.nodeBuilder=new Ox,this.stack=[],this.assignmentMap=new Map,this.linker=e.references.Linker,this.converter=e.parser.ValueConverter,this.astReflection=e.shared.AstReflection}rule(e,r){let n=this.computeRuleType(e),i=this.wrapper.DEFINE_RULE(Hce(e.name),this.startImplementation(n,r).bind(this));return this.allRules.set(e.name,i),e.entry&&(this.mainRule=i),i}computeRuleType(e){if(!e.fragment){if(lx(e))return NE;{let r=zg(e);return r??e.name}}}parse(e,r={}){this.nodeBuilder.buildRootNode(e);let n=this.lexerResult=this.lexer.tokenize(e);this.wrapper.input=n.tokens;let i=r.rule?this.allRules.get(r.rule):this.mainRule;if(!i)throw new Error(r.rule?`No rule found with name '${r.rule}'`:"No main rule available.");let a=i.call(this.wrapper,{});return this.nodeBuilder.addHiddenNodes(n.hidden),this.unorderedGroups.clear(),this.lexerResult=void 0,{value:a,lexerErrors:n.errors,lexerReport:n.report,parserErrors:this.wrapper.errors}}startImplementation(e,r){return n=>{let i=!this.isRecording()&&e!==void 0;if(i){let s={$type:e};this.stack.push(s),e===NE&&(s.value="")}let a;try{a=r(n)}catch{a=void 0}return a===void 0&&i&&(a=this.construct()),a}}extractHiddenTokens(e){let r=this.lexerResult.hidden;if(!r.length)return[];let n=e.startOffset;for(let i=0;in)return r.splice(0,i);return r.splice(0,r.length)}consume(e,r,n){let i=this.wrapper.wrapConsume(e,r);if(!this.isRecording()&&this.isValidToken(i)){let a=this.extractHiddenTokens(i);this.nodeBuilder.addHiddenNodes(a);let s=this.nodeBuilder.buildLeafNode(i,n),{assignment:l,isCrossRef:u}=this.getAssignment(n),h=this.current;if(l){let f=Xo(n)?i.image:this.converter.convert(i.image,s);this.assign(l.operator,l.feature,f,s,u)}else if(eI(h)){let f=i.image;Xo(n)||(f=this.converter.convert(f,s).toString()),h.value+=f}}}isValidToken(e){return!e.isInsertedInRecovery&&!isNaN(e.startOffset)&&typeof e.endOffset=="number"&&!isNaN(e.endOffset)}subrule(e,r,n,i,a){let s;!this.isRecording()&&!n&&(s=this.nodeBuilder.buildCompositeNode(i));let l=this.wrapper.wrapSubrule(e,r,a);!this.isRecording()&&s&&s.length>0&&this.performSubruleAssignment(l,i,s)}performSubruleAssignment(e,r,n){let{assignment:i,isCrossRef:a}=this.getAssignment(r);if(i)this.assign(i.operator,i.feature,e,n,a);else if(!i){let s=this.current;if(eI(s))s.value+=e.toString();else if(typeof e=="object"&&e){let u=this.assignWithoutOverride(e,s);this.stack.pop(),this.stack.push(u)}}}action(e,r){if(!this.isRecording()){let n=this.current;if(r.feature&&r.operator){n=this.construct(),this.nodeBuilder.removeNode(n.$cstNode),this.nodeBuilder.buildCompositeNode(r).content.push(n.$cstNode);let a={$type:e};this.stack.push(a),this.assign(r.operator,r.feature,n,n.$cstNode,!1)}else n.$type=e}}construct(){if(this.isRecording())return;let e=this.current;return Mk(e),this.nodeBuilder.construct(e),this.stack.pop(),eI(e)?this.converter.convert(e.value,e.$cstNode):(RN(this.astReflection,e),e)}getAssignment(e){if(!this.assignmentMap.has(e)){let r=hp(e,Pl);this.assignmentMap.set(e,{assignment:r,isCrossRef:r?up(r.terminal):!1})}return this.assignmentMap.get(e)}assign(e,r,n,i,a){let s=this.current,l;switch(a&&typeof n=="string"?l=this.linker.buildReference(s,r,i,n):l=n,e){case"=":{s[r]=l;break}case"?=":{s[r]=!0;break}case"+=":Array.isArray(s[r])||(s[r]=[]),s[r].push(l)}}assignWithoutOverride(e,r){for(let[i,a]of Object.entries(r)){let s=e[i];s===void 0?e[i]=a:Array.isArray(s)&&Array.isArray(a)&&(a.push(...s),e[i]=a)}let n=e.$cstNode;return n&&(n.astNode=void 0,e.$cstNode=void 0),e}get definitionErrors(){return this.wrapper.definitionErrors}},ME=class{static{o(this,"AbstractParserErrorMessageProvider")}buildMismatchTokenMessage(e){return qu.buildMismatchTokenMessage(e)}buildNotAllInputParsedMessage(e){return qu.buildNotAllInputParsedMessage(e)}buildNoViableAltMessage(e){return qu.buildNoViableAltMessage(e)}buildEarlyExitMessage(e){return qu.buildEarlyExitMessage(e)}},m1=class extends ME{static{o(this,"LangiumParserErrorMessageProvider")}buildMismatchTokenMessage({expected:e,actual:r}){return`Expecting ${e.LABEL?"`"+e.LABEL+"`":e.name.endsWith(":KW")?`keyword '${e.name.substring(0,e.name.length-3)}'`:`token of type '${e.name}'`} but found \`${r.image}\`.`}buildNotAllInputParsedMessage({firstRedundant:e}){return`Expecting end of file but found \`${e.image}\`.`}},$x=class extends Bx{static{o(this,"LangiumCompletionParser")}constructor(){super(...arguments),this.tokens=[],this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}action(){}construct(){}parse(e){this.resetState();let r=this.lexer.tokenize(e,{mode:"partial"});return this.tokens=r.tokens,this.wrapper.input=[...this.tokens],this.mainRule.call(this.wrapper,{}),this.unorderedGroups.clear(),{tokens:this.tokens,elementStack:[...this.lastElementStack],tokenIndex:this.nextTokenIndex}}rule(e,r){let n=this.wrapper.DEFINE_RULE(Hce(e.name),this.startImplementation(r).bind(this));return this.allRules.set(e.name,n),e.entry&&(this.mainRule=n),n}resetState(){this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}startImplementation(e){return r=>{let n=this.keepStackSize();try{e(r)}finally{this.resetStackSize(n)}}}removeUnexpectedElements(){this.elementStack.splice(this.stackSize)}keepStackSize(){let e=this.elementStack.length;return this.stackSize=e,e}resetStackSize(e){this.removeUnexpectedElements(),this.stackSize=e}consume(e,r,n){this.wrapper.wrapConsume(e,r),this.isRecording()||(this.lastElementStack=[...this.elementStack,n],this.nextTokenIndex=this.currIdx+1)}subrule(e,r,n,i,a){this.before(i),this.wrapper.wrapSubrule(e,r,a),this.after(i)}before(e){this.isRecording()||this.elementStack.push(e)}after(e){if(!this.isRecording()){let r=this.elementStack.lastIndexOf(e);r>=0&&this.elementStack.splice(r)}}get currIdx(){return this.wrapper.currIdx}},C$e={recoveryEnabled:!0,nodeLocationTracking:"full",skipValidations:!0,errorMessageProvider:new m1},tI=class extends Dx{static{o(this,"ChevrotainWrapper")}constructor(e,r){let n=r&&"maxLookahead"in r;super(e,Object.assign(Object.assign(Object.assign({},C$e),{lookaheadStrategy:n?new Yu({maxLookahead:r.maxLookahead}):new Mx({logging:r.skipValidations?()=>{}:void 0})}),r))}get IS_RECORDING(){return this.RECORDING_PHASE}DEFINE_RULE(e,r){return this.RULE(e,r)}wrapSelfAnalysis(){this.performSelfAnalysis()}wrapConsume(e,r){return this.consume(e,r)}wrapSubrule(e,r,n){return this.subrule(e,r,{ARGS:[n]})}wrapOr(e,r){this.or(e,r)}wrapOption(e,r){this.option(e,r)}wrapMany(e,r){this.many(e,r)}wrapAtLeastOne(e,r){this.atLeastOne(e,r)}}});function Gx(t,e,r){return A$e({parser:e,tokens:r,ruleNames:new Map},t),e}function A$e(t,e){let r=sx(e,!1),n=en(e.rules).filter(Fa).filter(i=>r.has(i));for(let i of n){let a=Object.assign(Object.assign({},t),{consume:1,optional:1,subrule:1,many:1,or:1});t.parser.rule(i,Cp(a,i.definition))}}function Cp(t,e,r=!1){let n;if(Xo(e))n=I$e(t,e);else if($u(e))n=_$e(t,e);else if(Pl(e))n=Cp(t,e.terminal);else if(up(e))n=Wce(t,e);else if(Bl(e))n=D$e(t,e);else if(Lk(e))n=R$e(t,e);else if(Nk(e))n=N$e(t,e);else if(ff(e))n=M$e(t,e);else if(wN(e)){let i=t.consume++;n=o(()=>t.parser.consume(i,fo,e),"method")}else throw new lp(e.$cstNode,`Unexpected element type: ${e.$type}`);return qce(t,r?void 0:IE(e),n,e.cardinality)}function _$e(t,e){let r=cx(e);return()=>t.parser.action(r,e)}function D$e(t,e){let r=e.rule.ref;if(Fa(r)){let n=t.subrule++,i=r.fragment,a=e.arguments.length>0?L$e(r,e.arguments):()=>({});return s=>t.parser.subrule(n,Yce(t,r),i,e,a(s))}else if(uo(r)){let n=t.consume++,i=rI(t,r.name);return()=>t.parser.consume(n,i,e)}else if(r)Oc(r);else throw new lp(e.$cstNode,`Undefined rule: ${e.rule.$refText}`)}function L$e(t,e){let r=e.map(n=>Xu(n.value));return n=>{let i={};for(let a=0;ae(n)||r(n)}else if(pN(t)){let e=Xu(t.left),r=Xu(t.right);return n=>e(n)&&r(n)}else if(gN(t)){let e=Xu(t.value);return r=>!e(r)}else if(yN(t)){let e=t.parameter.ref.name;return r=>r!==void 0&&r[e]===!0}else if(dN(t)){let e=!!t.true;return()=>e}Oc(t)}function R$e(t,e){if(e.elements.length===1)return Cp(t,e.elements[0]);{let r=[];for(let i of e.elements){let a={ALT:Cp(t,i,!0)},s=IE(i);s&&(a.GATE=Xu(s)),r.push(a)}let n=t.or++;return i=>t.parser.alternatives(n,r.map(a=>{let s={ALT:o(()=>a.ALT(i),"ALT")},l=a.GATE;return l&&(s.GATE=()=>l(i)),s}))}}function N$e(t,e){if(e.elements.length===1)return Cp(t,e.elements[0]);let r=[];for(let l of e.elements){let u={ALT:Cp(t,l,!0)},h=IE(l);h&&(u.GATE=Xu(h)),r.push(u)}let n=t.or++,i=o((l,u)=>{let h=u.getRuleStack().join("-");return`uGroup_${l}_${h}`},"idFunc"),a=o(l=>t.parser.alternatives(n,r.map((u,h)=>{let f={ALT:o(()=>!0,"ALT")},d=t.parser;f.ALT=()=>{if(u.ALT(l),!d.isRecording()){let m=i(n,d);d.unorderedGroups.get(m)||d.unorderedGroups.set(m,[]);let g=d.unorderedGroups.get(m);typeof g?.[h]>"u"&&(g[h]=!0)}};let p=u.GATE;return p?f.GATE=()=>p(l):f.GATE=()=>{let m=d.unorderedGroups.get(i(n,d));return!m?.[h]},f})),"alternatives"),s=qce(t,IE(e),a,"*");return l=>{s(l),t.parser.isRecording()||t.parser.unorderedGroups.delete(i(n,t.parser))}}function M$e(t,e){let r=e.elements.map(n=>Cp(t,n));return n=>r.forEach(i=>i(n))}function IE(t){if(ff(t))return t.guardCondition}function Wce(t,e,r=e.terminal){if(r)if(Bl(r)&&Fa(r.rule.ref)){let n=r.rule.ref,i=t.subrule++;return a=>t.parser.subrule(i,Yce(t,n),!1,e,a)}else if(Bl(r)&&uo(r.rule.ref)){let n=t.consume++,i=rI(t,r.rule.ref.name);return()=>t.parser.consume(n,i,e)}else if(Xo(r)){let n=t.consume++,i=rI(t,r.value);return()=>t.parser.consume(n,i,e)}else throw new Error("Could not build cross reference parser");else{if(!e.type.ref)throw new Error("Could not resolve reference to type: "+e.type.$refText);let n=Fk(e.type.ref),i=n?.terminal;if(!i)throw new Error("Could not find name assignment for type: "+cx(e.type.ref));return Wce(t,e,i)}}function I$e(t,e){let r=t.consume++,n=t.tokens[e.value];if(!n)throw new Error("Could not find token for keyword: "+e.value);return()=>t.parser.consume(r,n,e)}function qce(t,e,r,n){let i=e&&Xu(e);if(!n)if(i){let a=t.or++;return s=>t.parser.alternatives(a,[{ALT:o(()=>r(s),"ALT"),GATE:o(()=>i(s),"GATE")},{ALT:kE(),GATE:o(()=>!i(s),"GATE")}])}else return r;if(n==="*"){let a=t.many++;return s=>t.parser.many(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else if(n==="+"){let a=t.many++;if(i){let s=t.or++;return l=>t.parser.alternatives(s,[{ALT:o(()=>t.parser.atLeastOne(a,{DEF:o(()=>r(l),"DEF")}),"ALT"),GATE:o(()=>i(l),"GATE")},{ALT:kE(),GATE:o(()=>!i(l),"GATE")}])}else return s=>t.parser.atLeastOne(a,{DEF:o(()=>r(s),"DEF")})}else if(n==="?"){let a=t.optional++;return s=>t.parser.optional(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else Oc(n)}function Yce(t,e){let r=O$e(t,e),n=t.parser.getRule(r);if(!n)throw new Error(`Rule "${r}" not found."`);return n}function O$e(t,e){if(Fa(e))return e.name;if(t.ruleNames.has(e))return t.ruleNames.get(e);{let r=e,n=r.$container,i=e.$type;for(;!Fa(n);)(ff(n)||Lk(n)||Nk(n))&&(i=n.elements.indexOf(r).toString()+":"+i),r=n,n=n.$container;return i=n.name+":"+i,t.ruleNames.set(e,i),i}}function rI(t,e){let r=t.tokens[e];if(!r)throw new Error(`Token "${e}" not found."`);return r}var OE=N(()=>{"use strict";mf();Pc();Sk();Gs();Fl();o(Gx,"createParser");o(A$e,"buildRules");o(Cp,"buildElement");o(_$e,"buildAction");o(D$e,"buildRuleCall");o(L$e,"buildRuleCallPredicate");o(Xu,"buildPredicate");o(R$e,"buildAlternatives");o(N$e,"buildUnorderedGroup");o(M$e,"buildGroup");o(IE,"getGuardCondition");o(Wce,"buildCrossReference");o(I$e,"buildKeyword");o(qce,"wrap");o(Yce,"getRule");o(O$e,"getRuleName");o(rI,"getToken")});function nI(t){let e=t.Grammar,r=t.parser.Lexer,n=new $x(t);return Gx(e,n,r.definition),n.finalize(),n}var iI=N(()=>{"use strict";zx();OE();o(nI,"createCompletionParser")});function aI(t){let e=Xce(t);return e.finalize(),e}function Xce(t){let e=t.Grammar,r=t.parser.Lexer,n=new Fx(t);return Gx(e,n,r.definition)}var sI=N(()=>{"use strict";zx();OE();o(aI,"createLangiumParser");o(Xce,"prepareLangiumParser")});var ju,PE=N(()=>{"use strict";mf();Pc();cs();Fl();$g();Gs();ju=class{static{o(this,"DefaultTokenBuilder")}constructor(){this.diagnostics=[]}buildTokens(e,r){let n=en(sx(e,!1)),i=this.buildTerminalTokens(n),a=this.buildKeywordTokens(n,i,r);return i.forEach(s=>{let l=s.PATTERN;typeof l=="object"&&l&&"test"in l&&Fg(l)?a.unshift(s):a.push(s)}),a}flushLexingReport(e){return{diagnostics:this.popDiagnostics()}}popDiagnostics(){let e=[...this.diagnostics];return this.diagnostics=[],e}buildTerminalTokens(e){return e.filter(uo).filter(r=>!r.fragment).map(r=>this.buildTerminalToken(r)).toArray()}buildTerminalToken(e){let r=Gg(e),n=this.requiresCustomPattern(r)?this.regexPatternFunction(r):r,i={name:e.name,PATTERN:n};return typeof n=="function"&&(i.LINE_BREAKS=!0),e.hidden&&(i.GROUP=Fg(r)?Kn.SKIPPED:"hidden"),i}requiresCustomPattern(e){return e.flags.includes("u")||e.flags.includes("s")?!0:!!(e.source.includes("?<=")||e.source.includes("?(r.lastIndex=i,r.exec(n))}buildKeywordTokens(e,r,n){return e.filter(Fa).flatMap(i=>Bc(i).filter(Xo)).distinct(i=>i.value).toArray().sort((i,a)=>a.value.length-i.value.length).map(i=>this.buildKeywordToken(i,r,!!n?.caseInsensitive))}buildKeywordToken(e,r,n){let i=this.buildKeywordPattern(e,n),a={name:e.value,PATTERN:i,LONGER_ALT:this.findLongerAlt(e,r)};return typeof i=="function"&&(a.LINE_BREAKS=!0),a}buildKeywordPattern(e,r){return r?new RegExp(FN(e.value)):e.value}findLongerAlt(e,r){return r.reduce((n,i)=>{let a=i?.PATTERN;return a?.source&&$N("^"+a.source+"$",e.value)&&n.push(i),n},[])}}});var Ap,zc,oI=N(()=>{"use strict";Pc();Fl();Ap=class{static{o(this,"DefaultValueConverter")}convert(e,r){let n=r.grammarSource;if(up(n)&&(n=VN(n)),Bl(n)){let i=n.rule.ref;if(!i)throw new Error("This cst node was not parsed by a rule.");return this.runConverter(i,e,r)}return e}runConverter(e,r,n){var i;switch(e.name.toUpperCase()){case"INT":return zc.convertInt(r);case"STRING":return zc.convertString(r);case"ID":return zc.convertID(r)}switch((i=jN(e))===null||i===void 0?void 0:i.toLowerCase()){case"number":return zc.convertNumber(r);case"boolean":return zc.convertBoolean(r);case"bigint":return zc.convertBigint(r);case"date":return zc.convertDate(r);default:return r}}};(function(t){function e(h){let f="";for(let d=1;d{"use strict";Object.defineProperty(uI,"__esModule",{value:!0});var lI;function cI(){if(lI===void 0)throw new Error("No runtime abstraction layer installed");return lI}o(cI,"RAL");(function(t){function e(r){if(r===void 0)throw new Error("No runtime abstraction layer provided");lI=r}o(e,"install"),t.install=e})(cI||(cI={}));uI.default=cI});var Qce=Pi(za=>{"use strict";Object.defineProperty(za,"__esModule",{value:!0});za.stringArray=za.array=za.func=za.error=za.number=za.string=za.boolean=void 0;function P$e(t){return t===!0||t===!1}o(P$e,"boolean");za.boolean=P$e;function jce(t){return typeof t=="string"||t instanceof String}o(jce,"string");za.string=jce;function B$e(t){return typeof t=="number"||t instanceof Number}o(B$e,"number");za.number=B$e;function F$e(t){return t instanceof Error}o(F$e,"error");za.error=F$e;function $$e(t){return typeof t=="function"}o($$e,"func");za.func=$$e;function Kce(t){return Array.isArray(t)}o(Kce,"array");za.array=Kce;function z$e(t){return Kce(t)&&t.every(e=>jce(e))}o(z$e,"stringArray");za.stringArray=z$e});var dI=Pi(g1=>{"use strict";Object.defineProperty(g1,"__esModule",{value:!0});g1.Emitter=g1.Event=void 0;var G$e=hI(),Zce;(function(t){let e={dispose(){}};t.None=function(){return e}})(Zce||(g1.Event=Zce={}));var fI=class{static{o(this,"CallbackList")}add(e,r=null,n){this._callbacks||(this._callbacks=[],this._contexts=[]),this._callbacks.push(e),this._contexts.push(r),Array.isArray(n)&&n.push({dispose:o(()=>this.remove(e,r),"dispose")})}remove(e,r=null){if(!this._callbacks)return;let n=!1;for(let i=0,a=this._callbacks.length;i{this._callbacks||(this._callbacks=new fI),this._options&&this._options.onFirstListenerAdd&&this._callbacks.isEmpty()&&this._options.onFirstListenerAdd(this),this._callbacks.add(e,r);let i={dispose:o(()=>{this._callbacks&&(this._callbacks.remove(e,r),i.dispose=t._noop,this._options&&this._options.onLastListenerRemove&&this._callbacks.isEmpty()&&this._options.onLastListenerRemove(this))},"dispose")};return Array.isArray(n)&&n.push(i),i}),this._event}fire(e){this._callbacks&&this._callbacks.invoke.call(this._callbacks,e)}dispose(){this._callbacks&&(this._callbacks.dispose(),this._callbacks=void 0)}};g1.Emitter=BE;BE._noop=function(){}});var Jce=Pi(y1=>{"use strict";Object.defineProperty(y1,"__esModule",{value:!0});y1.CancellationTokenSource=y1.CancellationToken=void 0;var V$e=hI(),U$e=Qce(),pI=dI(),FE;(function(t){t.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:pI.Event.None}),t.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:pI.Event.None});function e(r){let n=r;return n&&(n===t.None||n===t.Cancelled||U$e.boolean(n.isCancellationRequested)&&!!n.onCancellationRequested)}o(e,"is"),t.is=e})(FE||(y1.CancellationToken=FE={}));var H$e=Object.freeze(function(t,e){let r=(0,V$e.default)().timer.setTimeout(t.bind(e),0);return{dispose(){r.dispose()}}}),$E=class{static{o(this,"MutableToken")}constructor(){this._isCancelled=!1}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?H$e:(this._emitter||(this._emitter=new pI.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=void 0)}},mI=class{static{o(this,"CancellationTokenSource")}get token(){return this._token||(this._token=new $E),this._token}cancel(){this._token?this._token.cancel():this._token=FE.Cancelled}dispose(){this._token?this._token instanceof $E&&this._token.dispose():this._token=FE.None}};y1.CancellationTokenSource=mI});var yr={};var Ko=N(()=>{"use strict";Cr(yr,Aa(Jce(),1))});function gI(){return new Promise(t=>{typeof setImmediate>"u"?setTimeout(t,0):setImmediate(t)})}function GE(){return zE=performance.now(),new yr.CancellationTokenSource}function tue(t){eue=t}function Vc(t){return t===Gc}async function wi(t){if(t===yr.CancellationToken.None)return;let e=performance.now();if(e-zE>=eue&&(zE=e,await gI(),zE=performance.now()),t.isCancellationRequested)throw Gc}var zE,eue,Gc,ps,Qo=N(()=>{"use strict";Ko();o(gI,"delayNextTick");zE=0,eue=10;o(GE,"startCancelableOperation");o(tue,"setInterruptionPeriod");Gc=Symbol("OperationCancelled");o(Vc,"isOperationCancelled");o(wi,"interruptAndCheck");ps=class{static{o(this,"Deferred")}constructor(){this.promise=new Promise((e,r)=>{this.resolve=n=>(e(n),this),this.reject=n=>(r(n),this)})}}});function yI(t,e){if(t.length<=1)return t;let r=t.length/2|0,n=t.slice(0,r),i=t.slice(r);yI(n,e),yI(i,e);let a=0,s=0,l=0;for(;ar.line||e.line===r.line&&e.character>r.character?{start:r,end:e}:t}function W$e(t){let e=iue(t.range);return e!==t.range?{newText:t.newText,range:e}:t}var VE,v1,aue=N(()=>{"use strict";VE=class t{static{o(this,"FullTextDocument")}constructor(e,r,n,i){this._uri=e,this._languageId=r,this._version=n,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let r=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(r,n)}return this._content}update(e,r){for(let n of e)if(t.isIncremental(n)){let i=iue(n.range),a=this.offsetAt(i.start),s=this.offsetAt(i.end);this._content=this._content.substring(0,a)+n.text+this._content.substring(s,this._content.length);let l=Math.max(i.start.line,0),u=Math.max(i.end.line,0),h=this._lineOffsets,f=rue(n.text,!1,a);if(u-l===f.length)for(let p=0,m=f.length;pe?i=s:n=s+1}let a=n-1;return e=this.ensureBeforeEOL(e,r[a]),{line:a,character:e-r[a]}}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line];if(e.character<=0)return n;let i=e.line+1r&&nue(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range!==void 0&&(r.rangeLength===void 0||typeof r.rangeLength=="number")}static isFull(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range===void 0&&r.rangeLength===void 0}};(function(t){function e(i,a,s,l){return new VE(i,a,s,l)}o(e,"create"),t.create=e;function r(i,a,s){if(i instanceof VE)return i.update(a,s),i;throw new Error("TextDocument.update: document must be created by TextDocument.create")}o(r,"update"),t.update=r;function n(i,a){let s=i.getText(),l=yI(a.map(W$e),(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),u=0,h=[];for(let f of l){let d=i.offsetAt(f.range.start);if(du&&h.push(s.substring(u,d)),f.newText.length&&h.push(f.newText),u=i.offsetAt(f.range.end)}return h.push(s.substr(u)),h.join("")}o(n,"applyEdits"),t.applyEdits=n})(v1||(v1={}));o(yI,"mergeSort");o(rue,"computeLineOffsets");o(nue,"isEOL");o(iue,"getWellformedRange");o(W$e,"getWellformedEdit")});var sue,ms,x1,vI=N(()=>{"use strict";(()=>{"use strict";var t={470:i=>{function a(u){if(typeof u!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(u))}o(a,"e");function s(u,h){for(var f,d="",p=0,m=-1,g=0,y=0;y<=u.length;++y){if(y2){var v=d.lastIndexOf("/");if(v!==d.length-1){v===-1?(d="",p=0):p=(d=d.slice(0,v)).length-1-d.lastIndexOf("/"),m=y,g=0;continue}}else if(d.length===2||d.length===1){d="",p=0,m=y,g=0;continue}}h&&(d.length>0?d+="/..":d="..",p=2)}else d.length>0?d+="/"+u.slice(m+1,y):d=u.slice(m+1,y),p=y-m-1;m=y,g=0}else f===46&&g!==-1?++g:g=-1}return d}o(s,"r");var l={resolve:o(function(){for(var u,h="",f=!1,d=arguments.length-1;d>=-1&&!f;d--){var p;d>=0?p=arguments[d]:(u===void 0&&(u=process.cwd()),p=u),a(p),p.length!==0&&(h=p+"/"+h,f=p.charCodeAt(0)===47)}return h=s(h,!f),f?h.length>0?"/"+h:"/":h.length>0?h:"."},"resolve"),normalize:o(function(u){if(a(u),u.length===0)return".";var h=u.charCodeAt(0)===47,f=u.charCodeAt(u.length-1)===47;return(u=s(u,!h)).length!==0||h||(u="."),u.length>0&&f&&(u+="/"),h?"/"+u:u},"normalize"),isAbsolute:o(function(u){return a(u),u.length>0&&u.charCodeAt(0)===47},"isAbsolute"),join:o(function(){if(arguments.length===0)return".";for(var u,h=0;h0&&(u===void 0?u=f:u+="/"+f)}return u===void 0?".":l.normalize(u)},"join"),relative:o(function(u,h){if(a(u),a(h),u===h||(u=l.resolve(u))===(h=l.resolve(h)))return"";for(var f=1;fy){if(h.charCodeAt(m+x)===47)return h.slice(m+x+1);if(x===0)return h.slice(m+x)}else p>y&&(u.charCodeAt(f+x)===47?v=x:x===0&&(v=0));break}var b=u.charCodeAt(f+x);if(b!==h.charCodeAt(m+x))break;b===47&&(v=x)}var T="";for(x=f+v+1;x<=d;++x)x!==d&&u.charCodeAt(x)!==47||(T.length===0?T+="..":T+="/..");return T.length>0?T+h.slice(m+v):(m+=v,h.charCodeAt(m)===47&&++m,h.slice(m))},"relative"),_makeLong:o(function(u){return u},"_makeLong"),dirname:o(function(u){if(a(u),u.length===0)return".";for(var h=u.charCodeAt(0),f=h===47,d=-1,p=!0,m=u.length-1;m>=1;--m)if((h=u.charCodeAt(m))===47){if(!p){d=m;break}}else p=!1;return d===-1?f?"/":".":f&&d===1?"//":u.slice(0,d)},"dirname"),basename:o(function(u,h){if(h!==void 0&&typeof h!="string")throw new TypeError('"ext" argument must be a string');a(u);var f,d=0,p=-1,m=!0;if(h!==void 0&&h.length>0&&h.length<=u.length){if(h.length===u.length&&h===u)return"";var g=h.length-1,y=-1;for(f=u.length-1;f>=0;--f){var v=u.charCodeAt(f);if(v===47){if(!m){d=f+1;break}}else y===-1&&(m=!1,y=f+1),g>=0&&(v===h.charCodeAt(g)?--g==-1&&(p=f):(g=-1,p=y))}return d===p?p=y:p===-1&&(p=u.length),u.slice(d,p)}for(f=u.length-1;f>=0;--f)if(u.charCodeAt(f)===47){if(!m){d=f+1;break}}else p===-1&&(m=!1,p=f+1);return p===-1?"":u.slice(d,p)},"basename"),extname:o(function(u){a(u);for(var h=-1,f=0,d=-1,p=!0,m=0,g=u.length-1;g>=0;--g){var y=u.charCodeAt(g);if(y!==47)d===-1&&(p=!1,d=g+1),y===46?h===-1?h=g:m!==1&&(m=1):h!==-1&&(m=-1);else if(!p){f=g+1;break}}return h===-1||d===-1||m===0||m===1&&h===d-1&&h===f+1?"":u.slice(h,d)},"extname"),format:o(function(u){if(u===null||typeof u!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof u);return function(h,f){var d=f.dir||f.root,p=f.base||(f.name||"")+(f.ext||"");return d?d===f.root?d+p:d+"/"+p:p}(0,u)},"format"),parse:o(function(u){a(u);var h={root:"",dir:"",base:"",ext:"",name:""};if(u.length===0)return h;var f,d=u.charCodeAt(0),p=d===47;p?(h.root="/",f=1):f=0;for(var m=-1,g=0,y=-1,v=!0,x=u.length-1,b=0;x>=f;--x)if((d=u.charCodeAt(x))!==47)y===-1&&(v=!1,y=x+1),d===46?m===-1?m=x:b!==1&&(b=1):m!==-1&&(b=-1);else if(!v){g=x+1;break}return m===-1||y===-1||b===0||b===1&&m===y-1&&m===g+1?y!==-1&&(h.base=h.name=g===0&&p?u.slice(1,y):u.slice(g,y)):(g===0&&p?(h.name=u.slice(1,m),h.base=u.slice(1,y)):(h.name=u.slice(g,m),h.base=u.slice(g,y)),h.ext=u.slice(m,y)),g>0?h.dir=u.slice(0,g-1):p&&(h.dir="/"),h},"parse"),sep:"/",delimiter:":",win32:null,posix:null};l.posix=l,i.exports=l}},e={};function r(i){var a=e[i];if(a!==void 0)return a.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,r),s.exports}o(r,"r"),r.d=(i,a)=>{for(var s in a)r.o(a,s)&&!r.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:a[s]})},r.o=(i,a)=>Object.prototype.hasOwnProperty.call(i,a),r.r=i=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var n={};(()=>{let i;r.r(n),r.d(n,{URI:o(()=>p,"URI"),Utils:o(()=>O,"Utils")}),typeof process=="object"?i=process.platform==="win32":typeof navigator=="object"&&(i=navigator.userAgent.indexOf("Windows")>=0);let a=/^\w[\w\d+.-]*$/,s=/^\//,l=/^\/\//;function u(R,k){if(!R.scheme&&k)throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${R.authority}", path: "${R.path}", query: "${R.query}", fragment: "${R.fragment}"}`);if(R.scheme&&!a.test(R.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(R.path){if(R.authority){if(!s.test(R.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(l.test(R.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}}o(u,"s");let h="",f="/",d=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;class p{static{o(this,"f")}static isUri(k){return k instanceof p||!!k&&typeof k.authority=="string"&&typeof k.fragment=="string"&&typeof k.path=="string"&&typeof k.query=="string"&&typeof k.scheme=="string"&&typeof k.fsPath=="string"&&typeof k.with=="function"&&typeof k.toString=="function"}scheme;authority;path;query;fragment;constructor(k,L,A,I,M,P=!1){typeof k=="object"?(this.scheme=k.scheme||h,this.authority=k.authority||h,this.path=k.path||h,this.query=k.query||h,this.fragment=k.fragment||h):(this.scheme=function(B,F){return B||F?B:"file"}(k,P),this.authority=L||h,this.path=function(B,F){switch(B){case"https":case"http":case"file":F?F[0]!==f&&(F=f+F):F=f}return F}(this.scheme,A||h),this.query=I||h,this.fragment=M||h,u(this,P))}get fsPath(){return b(this,!1)}with(k){if(!k)return this;let{scheme:L,authority:A,path:I,query:M,fragment:P}=k;return L===void 0?L=this.scheme:L===null&&(L=h),A===void 0?A=this.authority:A===null&&(A=h),I===void 0?I=this.path:I===null&&(I=h),M===void 0?M=this.query:M===null&&(M=h),P===void 0?P=this.fragment:P===null&&(P=h),L===this.scheme&&A===this.authority&&I===this.path&&M===this.query&&P===this.fragment?this:new g(L,A,I,M,P)}static parse(k,L=!1){let A=d.exec(k);return A?new g(A[2]||h,E(A[4]||h),E(A[5]||h),E(A[7]||h),E(A[9]||h),L):new g(h,h,h,h,h)}static file(k){let L=h;if(i&&(k=k.replace(/\\/g,f)),k[0]===f&&k[1]===f){let A=k.indexOf(f,2);A===-1?(L=k.substring(2),k=f):(L=k.substring(2,A),k=k.substring(A)||f)}return new g("file",L,k,h,h)}static from(k){let L=new g(k.scheme,k.authority,k.path,k.query,k.fragment);return u(L,!0),L}toString(k=!1){return T(this,k)}toJSON(){return this}static revive(k){if(k){if(k instanceof p)return k;{let L=new g(k);return L._formatted=k.external,L._fsPath=k._sep===m?k.fsPath:null,L}}return k}}let m=i?1:void 0;class g extends p{static{o(this,"l")}_formatted=null;_fsPath=null;get fsPath(){return this._fsPath||(this._fsPath=b(this,!1)),this._fsPath}toString(k=!1){return k?T(this,!0):(this._formatted||(this._formatted=T(this,!1)),this._formatted)}toJSON(){let k={$mid:1};return this._fsPath&&(k.fsPath=this._fsPath,k._sep=m),this._formatted&&(k.external=this._formatted),this.path&&(k.path=this.path),this.scheme&&(k.scheme=this.scheme),this.authority&&(k.authority=this.authority),this.query&&(k.query=this.query),this.fragment&&(k.fragment=this.fragment),k}}let y={58:"%3A",47:"%2F",63:"%3F",35:"%23",91:"%5B",93:"%5D",64:"%40",33:"%21",36:"%24",38:"%26",39:"%27",40:"%28",41:"%29",42:"%2A",43:"%2B",44:"%2C",59:"%3B",61:"%3D",32:"%20"};function v(R,k,L){let A,I=-1;for(let M=0;M=97&&P<=122||P>=65&&P<=90||P>=48&&P<=57||P===45||P===46||P===95||P===126||k&&P===47||L&&P===91||L&&P===93||L&&P===58)I!==-1&&(A+=encodeURIComponent(R.substring(I,M)),I=-1),A!==void 0&&(A+=R.charAt(M));else{A===void 0&&(A=R.substr(0,M));let B=y[P];B!==void 0?(I!==-1&&(A+=encodeURIComponent(R.substring(I,M)),I=-1),A+=B):I===-1&&(I=M)}}return I!==-1&&(A+=encodeURIComponent(R.substring(I))),A!==void 0?A:R}o(v,"d");function x(R){let k;for(let L=0;L1&&R.scheme==="file"?`//${R.authority}${R.path}`:R.path.charCodeAt(0)===47&&(R.path.charCodeAt(1)>=65&&R.path.charCodeAt(1)<=90||R.path.charCodeAt(1)>=97&&R.path.charCodeAt(1)<=122)&&R.path.charCodeAt(2)===58?k?R.path.substr(1):R.path[1].toLowerCase()+R.path.substr(2):R.path,i&&(L=L.replace(/\//g,"\\")),L}o(b,"m");function T(R,k){let L=k?x:v,A="",{scheme:I,authority:M,path:P,query:B,fragment:F}=R;if(I&&(A+=I,A+=":"),(M||I==="file")&&(A+=f,A+=f),M){let z=M.indexOf("@");if(z!==-1){let $=M.substr(0,z);M=M.substr(z+1),z=$.lastIndexOf(":"),z===-1?A+=L($,!1,!1):(A+=L($.substr(0,z),!1,!1),A+=":",A+=L($.substr(z+1),!1,!0)),A+="@"}M=M.toLowerCase(),z=M.lastIndexOf(":"),z===-1?A+=L(M,!1,!0):(A+=L(M.substr(0,z),!1,!0),A+=M.substr(z))}if(P){if(P.length>=3&&P.charCodeAt(0)===47&&P.charCodeAt(2)===58){let z=P.charCodeAt(1);z>=65&&z<=90&&(P=`/${String.fromCharCode(z+32)}:${P.substr(3)}`)}else if(P.length>=2&&P.charCodeAt(1)===58){let z=P.charCodeAt(0);z>=65&&z<=90&&(P=`${String.fromCharCode(z+32)}:${P.substr(2)}`)}A+=L(P,!0,!1)}return B&&(A+="?",A+=L(B,!1,!1)),F&&(A+="#",A+=k?F:v(F,!1,!1)),A}o(T,"y");function S(R){try{return decodeURIComponent(R)}catch{return R.length>3?R.substr(0,3)+S(R.substr(3)):R}}o(S,"v");let w=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function E(R){return R.match(w)?R.replace(w,k=>S(k)):R}o(E,"C");var _=r(470);let C=_.posix||_,D="/";var O;(function(R){R.joinPath=function(k,...L){return k.with({path:C.join(k.path,...L)})},R.resolvePath=function(k,...L){let A=k.path,I=!1;A[0]!==D&&(A=D+A,I=!0);let M=C.resolve(A,...L);return I&&M[0]===D&&!k.authority&&(M=M.substring(1)),k.with({path:M})},R.dirname=function(k){if(k.path.length===0||k.path===D)return k;let L=C.dirname(k.path);return L.length===1&&L.charCodeAt(0)===46&&(L=""),k.with({path:L})},R.basename=function(k){return C.basename(k.path)},R.extname=function(k){return C.extname(k.path)}})(O||(O={}))})(),sue=n})();({URI:ms,Utils:x1}=sue)});var gs,Uc=N(()=>{"use strict";vI();(function(t){t.basename=x1.basename,t.dirname=x1.dirname,t.extname=x1.extname,t.joinPath=x1.joinPath,t.resolvePath=x1.resolvePath;function e(i,a){return i?.toString()===a?.toString()}o(e,"equals"),t.equals=e;function r(i,a){let s=typeof i=="string"?i:i.path,l=typeof a=="string"?a:a.path,u=s.split("/").filter(m=>m.length>0),h=l.split("/").filter(m=>m.length>0),f=0;for(;f{"use strict";aue();b1();Ko();Gs();Uc();(function(t){t[t.Changed=0]="Changed",t[t.Parsed=1]="Parsed",t[t.IndexedContent=2]="IndexedContent",t[t.ComputedScopes=3]="ComputedScopes",t[t.Linked=4]="Linked",t[t.IndexedReferences=5]="IndexedReferences",t[t.Validated=6]="Validated"})(kn||(kn={}));Vx=class{static{o(this,"DefaultLangiumDocumentFactory")}constructor(e){this.serviceRegistry=e.ServiceRegistry,this.textDocuments=e.workspace.TextDocuments,this.fileSystemProvider=e.workspace.FileSystemProvider}async fromUri(e,r=yr.CancellationToken.None){let n=await this.fileSystemProvider.readFile(e);return this.createAsync(e,n,r)}fromTextDocument(e,r,n){return r=r??ms.parse(e.uri),yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromString(e,r,n){return yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromModel(e,r){return this.create(r,{$model:e})}create(e,r,n){if(typeof r=="string"){let i=this.parse(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else if("$model"in r){let i={value:r.$model,parserErrors:[],lexerErrors:[]};return this.createLangiumDocument(i,e)}else{let i=this.parse(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}async createAsync(e,r,n){if(typeof r=="string"){let i=await this.parseAsync(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else{let i=await this.parseAsync(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}createLangiumDocument(e,r,n,i){let a;if(n)a={parseResult:e,uri:r,state:kn.Parsed,references:[],textDocument:n};else{let s=this.createTextDocumentGetter(r,i);a={parseResult:e,uri:r,state:kn.Parsed,references:[],get textDocument(){return s()}}}return e.value.$document=a,a}async update(e,r){var n,i;let a=(n=e.parseResult.value.$cstNode)===null||n===void 0?void 0:n.root.fullText,s=(i=this.textDocuments)===null||i===void 0?void 0:i.get(e.uri.toString()),l=s?s.getText():await this.fileSystemProvider.readFile(e.uri);if(s)Object.defineProperty(e,"textDocument",{value:s});else{let u=this.createTextDocumentGetter(e.uri,l);Object.defineProperty(e,"textDocument",{get:u})}return a!==l&&(e.parseResult=await this.parseAsync(e.uri,l,r),e.parseResult.value.$document=e),e.state=kn.Parsed,e}parse(e,r,n){return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(r,n)}parseAsync(e,r,n){return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(r,n)}createTextDocumentGetter(e,r){let n=this.serviceRegistry,i;return()=>i??(i=v1.create(e.toString(),n.getServices(e).LanguageMetaData.languageId,0,r??""))}},Ux=class{static{o(this,"DefaultLangiumDocuments")}constructor(e){this.documentMap=new Map,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.serviceRegistry=e.ServiceRegistry}get all(){return en(this.documentMap.values())}addDocument(e){let r=e.uri.toString();if(this.documentMap.has(r))throw new Error(`A document with the URI '${r}' is already present.`);this.documentMap.set(r,e)}getDocument(e){let r=e.toString();return this.documentMap.get(r)}async getOrCreateDocument(e,r){let n=this.getDocument(e);return n||(n=await this.langiumDocumentFactory.fromUri(e,r),this.addDocument(n),n)}createDocument(e,r,n){if(n)return this.langiumDocumentFactory.fromString(r,e,n).then(i=>(this.addDocument(i),i));{let i=this.langiumDocumentFactory.fromString(r,e);return this.addDocument(i),i}}hasDocument(e){return this.documentMap.has(e.toString())}invalidateDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(this.serviceRegistry.getServices(e).references.Linker.unlink(n),n.state=kn.Changed,n.precomputedScopes=void 0,n.diagnostics=void 0),n}deleteDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(n.state=kn.Changed,this.documentMap.delete(r)),n}}});var xI,Hx,bI=N(()=>{"use strict";Ko();Il();cs();Qo();b1();xI=Symbol("ref_resolving"),Hx=class{static{o(this,"DefaultLinker")}constructor(e){this.reflection=e.shared.AstReflection,this.langiumDocuments=()=>e.shared.workspace.LangiumDocuments,this.scopeProvider=e.references.ScopeProvider,this.astNodeLocator=e.workspace.AstNodeLocator}async link(e,r=yr.CancellationToken.None){for(let n of jo(e.parseResult.value))await wi(r),Pg(n).forEach(i=>this.doLink(i,e))}doLink(e,r){var n;let i=e.reference;if(i._ref===void 0){i._ref=xI;try{let a=this.getCandidate(e);if(ap(a))i._ref=a;else if(i._nodeDescription=a,this.langiumDocuments().hasDocument(a.documentUri)){let s=this.loadAstNode(a);i._ref=s??this.createLinkingError(e,a)}else i._ref=void 0}catch(a){console.error(`An error occurred while resolving reference to '${i.$refText}':`,a);let s=(n=a.message)!==null&&n!==void 0?n:String(a);i._ref=Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${i.$refText}': ${s}`})}r.references.push(i)}}unlink(e){for(let r of e.references)delete r._ref,delete r._nodeDescription;e.references=[]}getCandidate(e){let n=this.scopeProvider.getScope(e).getElement(e.reference.$refText);return n??this.createLinkingError(e)}buildReference(e,r,n,i){let a=this,s={$refNode:n,$refText:i,get ref(){var l;if(si(this._ref))return this._ref;if(sN(this._nodeDescription)){let u=a.loadAstNode(this._nodeDescription);this._ref=u??a.createLinkingError({reference:s,container:e,property:r},this._nodeDescription)}else if(this._ref===void 0){this._ref=xI;let u=ex(e).$document,h=a.getLinkedNode({reference:s,container:e,property:r});if(h.error&&u&&u.state{"use strict";Fl();o(oue,"isNamed");Wx=class{static{o(this,"DefaultNameProvider")}getName(e){if(oue(e))return e.name}getNameNode(e){return ox(e.$cstNode,"name")}}});var qx,wI=N(()=>{"use strict";Fl();Il();cs();Ol();Gs();Uc();qx=class{static{o(this,"DefaultReferences")}constructor(e){this.nameProvider=e.references.NameProvider,this.index=e.shared.workspace.IndexManager,this.nodeLocator=e.workspace.AstNodeLocator}findDeclaration(e){if(e){let r=XN(e),n=e.astNode;if(r&&n){let i=n[r.feature];if(ya(i))return i.ref;if(Array.isArray(i)){for(let a of i)if(ya(a)&&a.$refNode&&a.$refNode.offset<=e.offset&&a.$refNode.end>=e.end)return a.ref}}if(n){let i=this.nameProvider.getNameNode(n);if(i&&(i===e||lN(e,i)))return n}}}findDeclarationNode(e){let r=this.findDeclaration(e);if(r?.$cstNode){let n=this.nameProvider.getNameNode(r);return n??r.$cstNode}}findReferences(e,r){let n=[];if(r.includeDeclaration){let a=this.getReferenceToSelf(e);a&&n.push(a)}let i=this.index.findAllReferences(e,this.nodeLocator.getAstNodePath(e));return r.documentUri&&(i=i.filter(a=>gs.equals(a.sourceUri,r.documentUri))),n.push(...i),en(n)}getReferenceToSelf(e){let r=this.nameProvider.getNameNode(e);if(r){let n=$a(e),i=this.nodeLocator.getAstNodePath(e);return{sourceUri:n.uri,sourcePath:i,targetUri:n.uri,targetPath:i,segment:op(r),local:!0}}}}});var zl,_p,T1=N(()=>{"use strict";Gs();zl=class{static{o(this,"MultiMap")}constructor(e){if(this.map=new Map,e)for(let[r,n]of e)this.add(r,n)}get size(){return jm.sum(en(this.map.values()).map(e=>e.length))}clear(){this.map.clear()}delete(e,r){if(r===void 0)return this.map.delete(e);{let n=this.map.get(e);if(n){let i=n.indexOf(r);if(i>=0)return n.length===1?this.map.delete(e):n.splice(i,1),!0}return!1}}get(e){var r;return(r=this.map.get(e))!==null&&r!==void 0?r:[]}has(e,r){if(r===void 0)return this.map.has(e);{let n=this.map.get(e);return n?n.indexOf(r)>=0:!1}}add(e,r){return this.map.has(e)?this.map.get(e).push(r):this.map.set(e,[r]),this}addAll(e,r){return this.map.has(e)?this.map.get(e).push(...r):this.map.set(e,Array.from(r)),this}forEach(e){this.map.forEach((r,n)=>r.forEach(i=>e(i,n,this)))}[Symbol.iterator](){return this.entries().iterator()}entries(){return en(this.map.entries()).flatMap(([e,r])=>r.map(n=>[e,n]))}keys(){return en(this.map.keys())}values(){return en(this.map.values()).flat()}entriesGroupedByKey(){return en(this.map.entries())}},_p=class{static{o(this,"BiMap")}get size(){return this.map.size}constructor(e){if(this.map=new Map,this.inverse=new Map,e)for(let[r,n]of e)this.set(r,n)}clear(){this.map.clear(),this.inverse.clear()}set(e,r){return this.map.set(e,r),this.inverse.set(r,e),this}get(e){return this.map.get(e)}getKey(e){return this.inverse.get(e)}delete(e){let r=this.map.get(e);return r!==void 0?(this.map.delete(e),this.inverse.delete(r),!0):!1}}});var Yx,kI=N(()=>{"use strict";Ko();cs();T1();Qo();Yx=class{static{o(this,"DefaultScopeComputation")}constructor(e){this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider}async computeExports(e,r=yr.CancellationToken.None){return this.computeExportsForNode(e.parseResult.value,e,void 0,r)}async computeExportsForNode(e,r,n=tx,i=yr.CancellationToken.None){let a=[];this.exportNode(e,a,r);for(let s of n(e))await wi(i),this.exportNode(s,a,r);return a}exportNode(e,r,n){let i=this.nameProvider.getName(e);i&&r.push(this.descriptions.createDescription(e,i,n))}async computeLocalScopes(e,r=yr.CancellationToken.None){let n=e.parseResult.value,i=new zl;for(let a of Bc(n))await wi(r),this.processNode(a,e,i);return i}processNode(e,r,n){let i=e.$container;if(i){let a=this.nameProvider.getName(e);a&&n.add(i,this.descriptions.createDescription(e,a,r))}}}});var w1,Xx,q$e,EI=N(()=>{"use strict";Gs();w1=class{static{o(this,"StreamScope")}constructor(e,r,n){var i;this.elements=e,this.outerScope=r,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1}getAllElements(){return this.outerScope?this.elements.concat(this.outerScope.getAllElements()):this.elements}getElement(e){let r=this.caseInsensitive?this.elements.find(n=>n.name.toLowerCase()===e.toLowerCase()):this.elements.find(n=>n.name===e);if(r)return r;if(this.outerScope)return this.outerScope.getElement(e)}},Xx=class{static{o(this,"MapScope")}constructor(e,r,n){var i;this.elements=new Map,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1;for(let a of e){let s=this.caseInsensitive?a.name.toLowerCase():a.name;this.elements.set(s,a)}this.outerScope=r}getElement(e){let r=this.caseInsensitive?e.toLowerCase():e,n=this.elements.get(r);if(n)return n;if(this.outerScope)return this.outerScope.getElement(e)}getAllElements(){let e=en(this.elements.values());return this.outerScope&&(e=e.concat(this.outerScope.getAllElements())),e}},q$e={getElement(){},getAllElements(){return H2}}});var k1,jx,Dp,UE,E1,HE=N(()=>{"use strict";k1=class{static{o(this,"DisposableCache")}constructor(){this.toDispose=[],this.isDisposed=!1}onDispose(e){this.toDispose.push(e)}dispose(){this.throwIfDisposed(),this.clear(),this.isDisposed=!0,this.toDispose.forEach(e=>e.dispose())}throwIfDisposed(){if(this.isDisposed)throw new Error("This cache has already been disposed")}},jx=class extends k1{static{o(this,"SimpleCache")}constructor(){super(...arguments),this.cache=new Map}has(e){return this.throwIfDisposed(),this.cache.has(e)}set(e,r){this.throwIfDisposed(),this.cache.set(e,r)}get(e,r){if(this.throwIfDisposed(),this.cache.has(e))return this.cache.get(e);if(r){let n=r();return this.cache.set(e,n),n}else return}delete(e){return this.throwIfDisposed(),this.cache.delete(e)}clear(){this.throwIfDisposed(),this.cache.clear()}},Dp=class extends k1{static{o(this,"ContextCache")}constructor(e){super(),this.cache=new Map,this.converter=e??(r=>r)}has(e,r){return this.throwIfDisposed(),this.cacheForContext(e).has(r)}set(e,r,n){this.throwIfDisposed(),this.cacheForContext(e).set(r,n)}get(e,r,n){this.throwIfDisposed();let i=this.cacheForContext(e);if(i.has(r))return i.get(r);if(n){let a=n();return i.set(r,a),a}else return}delete(e,r){return this.throwIfDisposed(),this.cacheForContext(e).delete(r)}clear(e){if(this.throwIfDisposed(),e){let r=this.converter(e);this.cache.delete(r)}else this.cache.clear()}cacheForContext(e){let r=this.converter(e),n=this.cache.get(r);return n||(n=new Map,this.cache.set(r,n)),n}},UE=class extends Dp{static{o(this,"DocumentCache")}constructor(e,r){super(n=>n.toString()),r?(this.toDispose.push(e.workspace.DocumentBuilder.onDocumentPhase(r,n=>{this.clear(n.uri.toString())})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{for(let a of i)this.clear(a)}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{let a=n.concat(i);for(let s of a)this.clear(s)}))}},E1=class extends jx{static{o(this,"WorkspaceCache")}constructor(e,r){super(),r?(this.toDispose.push(e.workspace.DocumentBuilder.onBuildPhase(r,()=>{this.clear()})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{i.length>0&&this.clear()}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate(()=>{this.clear()}))}}});var Kx,SI=N(()=>{"use strict";EI();cs();Gs();HE();Kx=class{static{o(this,"DefaultScopeProvider")}constructor(e){this.reflection=e.shared.AstReflection,this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider,this.indexManager=e.shared.workspace.IndexManager,this.globalScopeCache=new E1(e.shared)}getScope(e){let r=[],n=this.reflection.getReferenceType(e),i=$a(e.container).precomputedScopes;if(i){let s=e.container;do{let l=i.get(s);l.length>0&&r.push(en(l).filter(u=>this.reflection.isSubtype(u.type,n))),s=s.$container}while(s)}let a=this.getGlobalScope(n,e);for(let s=r.length-1;s>=0;s--)a=this.createScope(r[s],a);return a}createScope(e,r,n){return new w1(en(e),r,n)}createScopeForNodes(e,r,n){let i=en(e).map(a=>{let s=this.nameProvider.getName(a);if(s)return this.descriptions.createDescription(a,s)}).nonNullable();return new w1(i,r,n)}getGlobalScope(e,r){return this.globalScopeCache.get(e,()=>new Xx(this.indexManager.allElements(e)))}}});function CI(t){return typeof t.$comment=="string"}function lue(t){return typeof t=="object"&&!!t&&("$ref"in t||"$error"in t)}var Qx,WE=N(()=>{"use strict";vI();Il();cs();Fl();o(CI,"isAstNodeWithComment");o(lue,"isIntermediateReference");Qx=class{static{o(this,"DefaultJsonSerializer")}constructor(e){this.ignoreProperties=new Set(["$container","$containerProperty","$containerIndex","$document","$cstNode"]),this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider,this.commentProvider=e.documentation.CommentProvider}serialize(e,r){let n=r??{},i=r?.replacer,a=o((l,u)=>this.replacer(l,u,n),"defaultReplacer"),s=i?(l,u)=>i(l,u,a):a;try{return this.currentDocument=$a(e),JSON.stringify(e,s,r?.space)}finally{this.currentDocument=void 0}}deserialize(e,r){let n=r??{},i=JSON.parse(e);return this.linkNode(i,i,n),i}replacer(e,r,{refText:n,sourceText:i,textRegions:a,comments:s,uriConverter:l}){var u,h,f,d;if(!this.ignoreProperties.has(e))if(ya(r)){let p=r.ref,m=n?r.$refText:void 0;if(p){let g=$a(p),y="";this.currentDocument&&this.currentDocument!==g&&(l?y=l(g.uri,r):y=g.uri.toString());let v=this.astNodeLocator.getAstNodePath(p);return{$ref:`${y}#${v}`,$refText:m}}else return{$error:(h=(u=r.error)===null||u===void 0?void 0:u.message)!==null&&h!==void 0?h:"Could not resolve reference",$refText:m}}else if(si(r)){let p;if(a&&(p=this.addAstNodeRegionWithAssignmentsTo(Object.assign({},r)),(!e||r.$document)&&p?.$textRegion&&(p.$textRegion.documentURI=(f=this.currentDocument)===null||f===void 0?void 0:f.uri.toString())),i&&!e&&(p??(p=Object.assign({},r)),p.$sourceText=(d=r.$cstNode)===null||d===void 0?void 0:d.text),s){p??(p=Object.assign({},r));let m=this.commentProvider.getComment(r);m&&(p.$comment=m.replace(/\r/g,""))}return p??r}else return r}addAstNodeRegionWithAssignmentsTo(e){let r=o(n=>({offset:n.offset,end:n.end,length:n.length,range:n.range}),"createDocumentSegment");if(e.$cstNode){let n=e.$textRegion=r(e.$cstNode),i=n.assignments={};return Object.keys(e).filter(a=>!a.startsWith("$")).forEach(a=>{let s=HN(e.$cstNode,a).map(r);s.length!==0&&(i[a]=s)}),e}}linkNode(e,r,n,i,a,s){for(let[u,h]of Object.entries(e))if(Array.isArray(h))for(let f=0;f{"use strict";Uc();Zx=class{static{o(this,"DefaultServiceRegistry")}get map(){return this.fileExtensionMap}constructor(e){this.languageIdMap=new Map,this.fileExtensionMap=new Map,this.textDocuments=e?.workspace.TextDocuments}register(e){let r=e.LanguageMetaData;for(let n of r.fileExtensions)this.fileExtensionMap.has(n)&&console.warn(`The file extension ${n} is used by multiple languages. It is now assigned to '${r.languageId}'.`),this.fileExtensionMap.set(n,e);this.languageIdMap.set(r.languageId,e),this.languageIdMap.size===1?this.singleton=e:this.singleton=void 0}getServices(e){var r,n;if(this.singleton!==void 0)return this.singleton;if(this.languageIdMap.size===0)throw new Error("The service registry is empty. Use `register` to register the services of a language.");let i=(n=(r=this.textDocuments)===null||r===void 0?void 0:r.get(e))===null||n===void 0?void 0:n.languageId;if(i!==void 0){let l=this.languageIdMap.get(i);if(l)return l}let a=gs.extname(e),s=this.fileExtensionMap.get(a);if(!s)throw i?new Error(`The service registry contains no services for the extension '${a}' for language '${i}'.`):new Error(`The service registry contains no services for the extension '${a}'.`);return s}hasServices(e){try{return this.getServices(e),!0}catch{return!1}}get all(){return Array.from(this.languageIdMap.values())}}});function Lp(t){return{code:t}}var S1,Jx,eb=N(()=>{"use strict";po();T1();Qo();Gs();o(Lp,"diagnosticData");(function(t){t.all=["fast","slow","built-in"]})(S1||(S1={}));Jx=class{static{o(this,"ValidationRegistry")}constructor(e){this.entries=new zl,this.entriesBefore=[],this.entriesAfter=[],this.reflection=e.shared.AstReflection}register(e,r=this,n="fast"){if(n==="built-in")throw new Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");for(let[i,a]of Object.entries(e)){let s=a;if(Array.isArray(s))for(let l of s){let u={check:this.wrapValidationException(l,r),category:n};this.addEntry(i,u)}else if(typeof s=="function"){let l={check:this.wrapValidationException(s,r),category:n};this.addEntry(i,l)}else Oc(s)}}wrapValidationException(e,r){return async(n,i,a)=>{await this.handleException(()=>e.call(r,n,i,a),"An error occurred during validation",i,n)}}async handleException(e,r,n,i){try{await e()}catch(a){if(Vc(a))throw a;console.error(`${r}:`,a),a instanceof Error&&a.stack&&console.error(a.stack);let s=a instanceof Error?a.message:String(a);n("error",`${r}: ${s}`,{node:i})}}addEntry(e,r){if(e==="AstNode"){this.entries.add("AstNode",r);return}for(let n of this.reflection.getAllSubTypes(e))this.entries.add(n,r)}getChecks(e,r){let n=en(this.entries.get(e)).concat(this.entries.get("AstNode"));return r&&(n=n.filter(i=>r.includes(i.category))),n.map(i=>i.check)}registerBeforeDocument(e,r=this){this.entriesBefore.push(this.wrapPreparationException(e,"An error occurred during set-up of the validation",r))}registerAfterDocument(e,r=this){this.entriesAfter.push(this.wrapPreparationException(e,"An error occurred during tear-down of the validation",r))}wrapPreparationException(e,r,n){return async(i,a,s,l)=>{await this.handleException(()=>e.call(n,i,a,s,l),r,a,i)}}get checksBefore(){return this.entriesBefore}get checksAfter(){return this.entriesAfter}}});function cue(t){if(t.range)return t.range;let e;return typeof t.property=="string"?e=ox(t.node.$cstNode,t.property,t.index):typeof t.keyword=="string"&&(e=qN(t.node.$cstNode,t.keyword,t.index)),e??(e=t.node.$cstNode),e?e.range:{start:{line:0,character:0},end:{line:0,character:0}}}function qE(t){switch(t){case"error":return 1;case"warning":return 2;case"info":return 3;case"hint":return 4;default:throw new Error("Invalid diagnostic severity: "+t)}}function uue(t){switch(t){case"error":return Lp(Zo.LexingError);case"warning":return Lp(Zo.LexingWarning);case"info":return Lp(Zo.LexingInfo);case"hint":return Lp(Zo.LexingHint);default:throw new Error("Invalid diagnostic severity: "+t)}}var tb,Zo,_I=N(()=>{"use strict";Ko();Fl();cs();Ol();Qo();eb();tb=class{static{o(this,"DefaultDocumentValidator")}constructor(e){this.validationRegistry=e.validation.ValidationRegistry,this.metadata=e.LanguageMetaData}async validateDocument(e,r={},n=yr.CancellationToken.None){let i=e.parseResult,a=[];if(await wi(n),(!r.categories||r.categories.includes("built-in"))&&(this.processLexingErrors(i,a,r),r.stopAfterLexingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.LexingError})||(this.processParsingErrors(i,a,r),r.stopAfterParsingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.ParsingError}))||(this.processLinkingErrors(e,a,r),r.stopAfterLinkingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.LinkingError}))))return a;try{a.push(...await this.validateAst(i.value,r,n))}catch(s){if(Vc(s))throw s;console.error("An error occurred during validation:",s)}return await wi(n),a}processLexingErrors(e,r,n){var i,a,s;let l=[...e.lexerErrors,...(a=(i=e.lexerReport)===null||i===void 0?void 0:i.diagnostics)!==null&&a!==void 0?a:[]];for(let u of l){let h=(s=u.severity)!==null&&s!==void 0?s:"error",f={severity:qE(h),range:{start:{line:u.line-1,character:u.column-1},end:{line:u.line-1,character:u.column+u.length-1}},message:u.message,data:uue(h),source:this.getSource()};r.push(f)}}processParsingErrors(e,r,n){for(let i of e.parserErrors){let a;if(isNaN(i.token.startOffset)){if("previousToken"in i){let s=i.previousToken;if(isNaN(s.startOffset)){let l={line:0,character:0};a={start:l,end:l}}else{let l={line:s.endLine-1,character:s.endColumn};a={start:l,end:l}}}}else a=Km(i.token);if(a){let s={severity:qE("error"),range:a,message:i.message,data:Lp(Zo.ParsingError),source:this.getSource()};r.push(s)}}}processLinkingErrors(e,r,n){for(let i of e.references){let a=i.error;if(a){let s={node:a.container,property:a.property,index:a.index,data:{code:Zo.LinkingError,containerType:a.container.$type,property:a.property,refText:a.reference.$refText}};r.push(this.toDiagnostic("error",a.message,s))}}}async validateAst(e,r,n=yr.CancellationToken.None){let i=[],a=o((s,l,u)=>{i.push(this.toDiagnostic(s,l,u))},"acceptor");return await this.validateAstBefore(e,r,a,n),await this.validateAstNodes(e,r,a,n),await this.validateAstAfter(e,r,a,n),i}async validateAstBefore(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksBefore;for(let l of s)await wi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}async validateAstNodes(e,r,n,i=yr.CancellationToken.None){await Promise.all(jo(e).map(async a=>{await wi(i);let s=this.validationRegistry.getChecks(a.$type,r.categories);for(let l of s)await l(a,n,i)}))}async validateAstAfter(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksAfter;for(let l of s)await wi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}toDiagnostic(e,r,n){return{message:r,range:cue(n),severity:qE(e),code:n.code,codeDescription:n.codeDescription,tags:n.tags,relatedInformation:n.relatedInformation,data:n.data,source:this.getSource()}}getSource(){return this.metadata.languageId}};o(cue,"getDiagnosticRange");o(qE,"toDiagnosticSeverity");o(uue,"toDiagnosticData");(function(t){t.LexingError="lexing-error",t.LexingWarning="lexing-warning",t.LexingInfo="lexing-info",t.LexingHint="lexing-hint",t.ParsingError="parsing-error",t.LinkingError="linking-error"})(Zo||(Zo={}))});var rb,nb,DI=N(()=>{"use strict";Ko();Il();cs();Ol();Qo();Uc();rb=class{static{o(this,"DefaultAstNodeDescriptionProvider")}constructor(e){this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider}createDescription(e,r,n){let i=n??$a(e);r??(r=this.nameProvider.getName(e));let a=this.astNodeLocator.getAstNodePath(e);if(!r)throw new Error(`Node at path ${a} has no name.`);let s,l=o(()=>{var u;return s??(s=op((u=this.nameProvider.getNameNode(e))!==null&&u!==void 0?u:e.$cstNode))},"nameSegmentGetter");return{node:e,name:r,get nameSegment(){return l()},selectionSegment:op(e.$cstNode),type:e.$type,documentUri:i.uri,path:a}}},nb=class{static{o(this,"DefaultReferenceDescriptionProvider")}constructor(e){this.nodeLocator=e.workspace.AstNodeLocator}async createDescriptions(e,r=yr.CancellationToken.None){let n=[],i=e.parseResult.value;for(let a of jo(i))await wi(r),Pg(a).filter(s=>!ap(s)).forEach(s=>{let l=this.createDescription(s);l&&n.push(l)});return n}createDescription(e){let r=e.reference.$nodeDescription,n=e.reference.$refNode;if(!r||!n)return;let i=$a(e.container).uri;return{sourceUri:i,sourcePath:this.nodeLocator.getAstNodePath(e.container),targetUri:r.documentUri,targetPath:r.path,segment:op(n),local:gs.equals(r.documentUri,i)}}}});var ib,LI=N(()=>{"use strict";ib=class{static{o(this,"DefaultAstNodeLocator")}constructor(){this.segmentSeparator="/",this.indexSeparator="@"}getAstNodePath(e){if(e.$container){let r=this.getAstNodePath(e.$container),n=this.getPathSegment(e);return r+this.segmentSeparator+n}return""}getPathSegment({$containerProperty:e,$containerIndex:r}){if(!e)throw new Error("Missing '$containerProperty' in AST node.");return r!==void 0?e+this.indexSeparator+r:e}getAstNode(e,r){return r.split(this.segmentSeparator).reduce((i,a)=>{if(!i||a.length===0)return i;let s=a.indexOf(this.indexSeparator);if(s>0){let l=a.substring(0,s),u=parseInt(a.substring(s+1)),h=i[l];return h?.[u]}return i[a]},e)}}});var Zn={};var YE=N(()=>{"use strict";Cr(Zn,Aa(dI(),1))});var ab,RI=N(()=>{"use strict";YE();Qo();ab=class{static{o(this,"DefaultConfigurationProvider")}constructor(e){this._ready=new ps,this.settings={},this.workspaceConfig=!1,this.onConfigurationSectionUpdateEmitter=new Zn.Emitter,this.serviceRegistry=e.ServiceRegistry}get ready(){return this._ready.promise}initialize(e){var r,n;this.workspaceConfig=(n=(r=e.capabilities.workspace)===null||r===void 0?void 0:r.configuration)!==null&&n!==void 0?n:!1}async initialized(e){if(this.workspaceConfig){if(e.register){let r=this.serviceRegistry.all;e.register({section:r.map(n=>this.toSectionName(n.LanguageMetaData.languageId))})}if(e.fetchConfiguration){let r=this.serviceRegistry.all.map(i=>({section:this.toSectionName(i.LanguageMetaData.languageId)})),n=await e.fetchConfiguration(r);r.forEach((i,a)=>{this.updateSectionConfiguration(i.section,n[a])})}}this._ready.resolve()}updateConfiguration(e){e.settings&&Object.keys(e.settings).forEach(r=>{let n=e.settings[r];this.updateSectionConfiguration(r,n),this.onConfigurationSectionUpdateEmitter.fire({section:r,configuration:n})})}updateSectionConfiguration(e,r){this.settings[e]=r}async getConfiguration(e,r){await this.ready;let n=this.toSectionName(e);if(this.settings[n])return this.settings[n][r]}toSectionName(e){return`${e}`}get onConfigurationSectionUpdate(){return this.onConfigurationSectionUpdateEmitter.event}}});var vf,NI=N(()=>{"use strict";(function(t){function e(r){return{dispose:o(async()=>await r(),"dispose")}}o(e,"create"),t.create=e})(vf||(vf={}))});var sb,MI=N(()=>{"use strict";Ko();NI();T1();Qo();Gs();eb();b1();sb=class{static{o(this,"DefaultDocumentBuilder")}constructor(e){this.updateBuildOptions={validation:{categories:["built-in","fast"]}},this.updateListeners=[],this.buildPhaseListeners=new zl,this.documentPhaseListeners=new zl,this.buildState=new Map,this.documentBuildWaiters=new Map,this.currentState=kn.Changed,this.langiumDocuments=e.workspace.LangiumDocuments,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.textDocuments=e.workspace.TextDocuments,this.indexManager=e.workspace.IndexManager,this.serviceRegistry=e.ServiceRegistry}async build(e,r={},n=yr.CancellationToken.None){var i,a;for(let s of e){let l=s.uri.toString();if(s.state===kn.Validated){if(typeof r.validation=="boolean"&&r.validation)s.state=kn.IndexedReferences,s.diagnostics=void 0,this.buildState.delete(l);else if(typeof r.validation=="object"){let u=this.buildState.get(l),h=(i=u?.result)===null||i===void 0?void 0:i.validationChecks;if(h){let d=((a=r.validation.categories)!==null&&a!==void 0?a:S1.all).filter(p=>!h.includes(p));d.length>0&&(this.buildState.set(l,{completed:!1,options:{validation:Object.assign(Object.assign({},r.validation),{categories:d})},result:u.result}),s.state=kn.IndexedReferences)}}}else this.buildState.delete(l)}this.currentState=kn.Changed,await this.emitUpdate(e.map(s=>s.uri),[]),await this.buildDocuments(e,r,n)}async update(e,r,n=yr.CancellationToken.None){this.currentState=kn.Changed;for(let s of r)this.langiumDocuments.deleteDocument(s),this.buildState.delete(s.toString()),this.indexManager.remove(s);for(let s of e){if(!this.langiumDocuments.invalidateDocument(s)){let u=this.langiumDocumentFactory.fromModel({$type:"INVALID"},s);u.state=kn.Changed,this.langiumDocuments.addDocument(u)}this.buildState.delete(s.toString())}let i=en(e).concat(r).map(s=>s.toString()).toSet();this.langiumDocuments.all.filter(s=>!i.has(s.uri.toString())&&this.shouldRelink(s,i)).forEach(s=>{this.serviceRegistry.getServices(s.uri).references.Linker.unlink(s),s.state=Math.min(s.state,kn.ComputedScopes),s.diagnostics=void 0}),await this.emitUpdate(e,r),await wi(n);let a=this.sortDocuments(this.langiumDocuments.all.filter(s=>{var l;return s.staten(e,r)))}sortDocuments(e){let r=0,n=e.length-1;for(;r=0&&!this.hasTextDocument(e[n]);)n--;rn.error!==void 0)?!0:this.indexManager.isAffected(e,r)}onUpdate(e){return this.updateListeners.push(e),vf.create(()=>{let r=this.updateListeners.indexOf(e);r>=0&&this.updateListeners.splice(r,1)})}async buildDocuments(e,r,n){this.prepareBuild(e,r),await this.runCancelable(e,kn.Parsed,n,a=>this.langiumDocumentFactory.update(a,n)),await this.runCancelable(e,kn.IndexedContent,n,a=>this.indexManager.updateContent(a,n)),await this.runCancelable(e,kn.ComputedScopes,n,async a=>{let s=this.serviceRegistry.getServices(a.uri).references.ScopeComputation;a.precomputedScopes=await s.computeLocalScopes(a,n)}),await this.runCancelable(e,kn.Linked,n,a=>this.serviceRegistry.getServices(a.uri).references.Linker.link(a,n)),await this.runCancelable(e,kn.IndexedReferences,n,a=>this.indexManager.updateReferences(a,n));let i=e.filter(a=>this.shouldValidate(a));await this.runCancelable(i,kn.Validated,n,a=>this.validate(a,n));for(let a of e){let s=this.buildState.get(a.uri.toString());s&&(s.completed=!0)}}prepareBuild(e,r){for(let n of e){let i=n.uri.toString(),a=this.buildState.get(i);(!a||a.completed)&&this.buildState.set(i,{completed:!1,options:r,result:a?.result})}}async runCancelable(e,r,n,i){let a=e.filter(l=>l.statel.state===r);await this.notifyBuildPhase(s,r,n),this.currentState=r}onBuildPhase(e,r){return this.buildPhaseListeners.add(e,r),vf.create(()=>{this.buildPhaseListeners.delete(e,r)})}onDocumentPhase(e,r){return this.documentPhaseListeners.add(e,r),vf.create(()=>{this.documentPhaseListeners.delete(e,r)})}waitUntil(e,r,n){let i;if(r&&"path"in r?i=r:n=r,n??(n=yr.CancellationToken.None),i){let a=this.langiumDocuments.getDocument(i);if(a&&a.state>e)return Promise.resolve(i)}return this.currentState>=e?Promise.resolve(void 0):n.isCancellationRequested?Promise.reject(Gc):new Promise((a,s)=>{let l=this.onBuildPhase(e,()=>{if(l.dispose(),u.dispose(),i){let h=this.langiumDocuments.getDocument(i);a(h?.uri)}else a(void 0)}),u=n.onCancellationRequested(()=>{l.dispose(),u.dispose(),s(Gc)})})}async notifyDocumentPhase(e,r,n){let a=this.documentPhaseListeners.get(r).slice();for(let s of a)try{await s(e,n)}catch(l){if(!Vc(l))throw l}}async notifyBuildPhase(e,r,n){if(e.length===0)return;let a=this.buildPhaseListeners.get(r).slice();for(let s of a)await wi(n),await s(e,n)}shouldValidate(e){return!!this.getBuildOptions(e).validation}async validate(e,r){var n,i;let a=this.serviceRegistry.getServices(e.uri).validation.DocumentValidator,s=this.getBuildOptions(e).validation,l=typeof s=="object"?s:void 0,u=await a.validateDocument(e,l,r);e.diagnostics?e.diagnostics.push(...u):e.diagnostics=u;let h=this.buildState.get(e.uri.toString());if(h){(n=h.result)!==null&&n!==void 0||(h.result={});let f=(i=l?.categories)!==null&&i!==void 0?i:S1.all;h.result.validationChecks?h.result.validationChecks.push(...f):h.result.validationChecks=[...f]}}getBuildOptions(e){var r,n;return(n=(r=this.buildState.get(e.uri.toString()))===null||r===void 0?void 0:r.options)!==null&&n!==void 0?n:{}}}});var ob,II=N(()=>{"use strict";cs();HE();Ko();Gs();Uc();ob=class{static{o(this,"DefaultIndexManager")}constructor(e){this.symbolIndex=new Map,this.symbolByTypeIndex=new Dp,this.referenceIndex=new Map,this.documents=e.workspace.LangiumDocuments,this.serviceRegistry=e.ServiceRegistry,this.astReflection=e.AstReflection}findAllReferences(e,r){let n=$a(e).uri,i=[];return this.referenceIndex.forEach(a=>{a.forEach(s=>{gs.equals(s.targetUri,n)&&s.targetPath===r&&i.push(s)})}),en(i)}allElements(e,r){let n=en(this.symbolIndex.keys());return r&&(n=n.filter(i=>!r||r.has(i))),n.map(i=>this.getFileDescriptions(i,e)).flat()}getFileDescriptions(e,r){var n;return r?this.symbolByTypeIndex.get(e,r,()=>{var a;return((a=this.symbolIndex.get(e))!==null&&a!==void 0?a:[]).filter(l=>this.astReflection.isSubtype(l.type,r))}):(n=this.symbolIndex.get(e))!==null&&n!==void 0?n:[]}remove(e){let r=e.toString();this.symbolIndex.delete(r),this.symbolByTypeIndex.clear(r),this.referenceIndex.delete(r)}async updateContent(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).references.ScopeComputation.computeExports(e,r),a=e.uri.toString();this.symbolIndex.set(a,i),this.symbolByTypeIndex.clear(a)}async updateReferences(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).workspace.ReferenceDescriptionProvider.createDescriptions(e,r);this.referenceIndex.set(e.uri.toString(),i)}isAffected(e,r){let n=this.referenceIndex.get(e.uri.toString());return n?n.some(i=>!i.local&&r.has(i.targetUri.toString())):!1}}});var lb,OI=N(()=>{"use strict";Ko();Qo();Uc();lb=class{static{o(this,"DefaultWorkspaceManager")}constructor(e){this.initialBuildOptions={},this._ready=new ps,this.serviceRegistry=e.ServiceRegistry,this.langiumDocuments=e.workspace.LangiumDocuments,this.documentBuilder=e.workspace.DocumentBuilder,this.fileSystemProvider=e.workspace.FileSystemProvider,this.mutex=e.workspace.WorkspaceLock}get ready(){return this._ready.promise}get workspaceFolders(){return this.folders}initialize(e){var r;this.folders=(r=e.workspaceFolders)!==null&&r!==void 0?r:void 0}initialized(e){return this.mutex.write(r=>{var n;return this.initializeWorkspace((n=this.folders)!==null&&n!==void 0?n:[],r)})}async initializeWorkspace(e,r=yr.CancellationToken.None){let n=await this.performStartup(e);await wi(r),await this.documentBuilder.build(n,this.initialBuildOptions,r)}async performStartup(e){let r=this.serviceRegistry.all.flatMap(a=>a.LanguageMetaData.fileExtensions),n=[],i=o(a=>{n.push(a),this.langiumDocuments.hasDocument(a.uri)||this.langiumDocuments.addDocument(a)},"collector");return await this.loadAdditionalDocuments(e,i),await Promise.all(e.map(a=>[a,this.getRootFolder(a)]).map(async a=>this.traverseFolder(...a,r,i))),this._ready.resolve(),n}loadAdditionalDocuments(e,r){return Promise.resolve()}getRootFolder(e){return ms.parse(e.uri)}async traverseFolder(e,r,n,i){let a=await this.fileSystemProvider.readDirectory(r);await Promise.all(a.map(async s=>{if(this.includeEntry(e,s,n)){if(s.isDirectory)await this.traverseFolder(e,s.uri,n,i);else if(s.isFile){let l=await this.langiumDocuments.getOrCreateDocument(s.uri);i(l)}}}))}includeEntry(e,r,n){let i=gs.basename(r.uri);if(i.startsWith("."))return!1;if(r.isDirectory)return i!=="node_modules"&&i!=="out";if(r.isFile){let a=gs.extname(r.uri);return n.includes(a)}return!1}}});function jE(t){return Array.isArray(t)&&(t.length===0||"name"in t[0])}function BI(t){return t&&"modes"in t&&"defaultMode"in t}function PI(t){return!jE(t)&&!BI(t)}var cb,XE,Rp,KE=N(()=>{"use strict";mf();cb=class{static{o(this,"DefaultLexerErrorMessageProvider")}buildUnexpectedCharactersMessage(e,r,n,i,a){return Kg.buildUnexpectedCharactersMessage(e,r,n,i,a)}buildUnableToPopLexerModeMessage(e){return Kg.buildUnableToPopLexerModeMessage(e)}},XE={mode:"full"},Rp=class{static{o(this,"DefaultLexer")}constructor(e){this.errorMessageProvider=e.parser.LexerErrorMessageProvider,this.tokenBuilder=e.parser.TokenBuilder;let r=this.tokenBuilder.buildTokens(e.Grammar,{caseInsensitive:e.LanguageMetaData.caseInsensitive});this.tokenTypes=this.toTokenTypeDictionary(r);let n=PI(r)?Object.values(r):r,i=e.LanguageMetaData.mode==="production";this.chevrotainLexer=new Kn(n,{positionTracking:"full",skipValidations:i,errorMessageProvider:this.errorMessageProvider})}get definition(){return this.tokenTypes}tokenize(e,r=XE){var n,i,a;let s=this.chevrotainLexer.tokenize(e);return{tokens:s.tokens,errors:s.errors,hidden:(n=s.groups.hidden)!==null&&n!==void 0?n:[],report:(a=(i=this.tokenBuilder).flushLexingReport)===null||a===void 0?void 0:a.call(i,e)}}toTokenTypeDictionary(e){if(PI(e))return e;let r=BI(e)?Object.values(e.modes).flat():e,n={};return r.forEach(i=>n[i.name]=i),n}};o(jE,"isTokenTypeArray");o(BI,"isIMultiModeLexerDefinition");o(PI,"isTokenTypeDictionary")});function zI(t,e,r){let n,i;typeof t=="string"?(i=e,n=r):(i=t.range.start,n=e),i||(i=jr.create(0,0));let a=due(t),s=VI(n),l=X$e({lines:a,position:i,options:s});return J$e({index:0,tokens:l,position:i})}function GI(t,e){let r=VI(e),n=due(t);if(n.length===0)return!1;let i=n[0],a=n[n.length-1],s=r.start,l=r.end;return!!s?.exec(i)&&!!l?.exec(a)}function due(t){let e="";return typeof t=="string"?e=t:e=t.text,e.split(PN)}function X$e(t){var e,r,n;let i=[],a=t.position.line,s=t.position.character;for(let l=0;l=f.length){if(i.length>0){let m=jr.create(a,s);i.push({type:"break",content:"",range:Br.create(m,m)})}}else{hue.lastIndex=d;let m=hue.exec(f);if(m){let g=m[0],y=m[1],v=jr.create(a,s+d),x=jr.create(a,s+d+g.length);i.push({type:"tag",content:y,range:Br.create(v,x)}),d+=g.length,d=$I(f,d)}if(d0&&i[i.length-1].type==="break"?i.slice(0,-1):i}function j$e(t,e,r,n){let i=[];if(t.length===0){let a=jr.create(r,n),s=jr.create(r,n+e.length);i.push({type:"text",content:e,range:Br.create(a,s)})}else{let a=0;for(let l of t){let u=l.index,h=e.substring(a,u);h.length>0&&i.push({type:"text",content:e.substring(a,u),range:Br.create(jr.create(r,a+n),jr.create(r,u+n))});let f=h.length+1,d=l[1];if(i.push({type:"inline-tag",content:d,range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+d.length+n))}),f+=d.length,l.length===4){f+=l[2].length;let p=l[3];i.push({type:"text",content:p,range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+p.length+n))})}else i.push({type:"text",content:"",range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+n))});a=u+l[0].length}let s=e.substring(a);s.length>0&&i.push({type:"text",content:s,range:Br.create(jr.create(r,a+n),jr.create(r,a+n+s.length))})}return i}function $I(t,e){let r=t.substring(e).match(K$e);return r?e+r.index:t.length}function Z$e(t){let e=t.match(Q$e);if(e&&typeof e.index=="number")return e.index}function J$e(t){var e,r,n,i;let a=jr.create(t.position.line,t.position.character);if(t.tokens.length===0)return new QE([],Br.create(a,a));let s=[];for(;t.index0){let u=$I(e,a);s=e.substring(u),e=e.substring(0,a)}return(t==="linkcode"||t==="link"&&r.link==="code")&&(s=`\`${s}\``),(i=(n=r.renderLink)===null||n===void 0?void 0:n.call(r,e,s))!==null&&i!==void 0?i:ize(e,s)}}function ize(t,e){try{return ms.parse(t,!0),`[${e}](${t})`}catch{return t}}function fue(t){return t.endsWith(` +`)?` +`:` + +`}var hue,Y$e,K$e,Q$e,QE,ub,hb,ZE,UI=N(()=>{"use strict";ZM();$g();Uc();o(zI,"parseJSDoc");o(GI,"isJSDoc");o(due,"getLines");hue=/\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy,Y$e=/\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;o(X$e,"tokenize");o(j$e,"buildInlineTokens");K$e=/\S/,Q$e=/\s*$/;o($I,"skipWhitespace");o(Z$e,"lastCharacter");o(J$e,"parseJSDocComment");o(eze,"parseJSDocElement");o(tze,"appendEmptyLine");o(pue,"parseJSDocText");o(rze,"parseJSDocInline");o(mue,"parseJSDocTag");o(gue,"parseJSDocLine");o(VI,"normalizeOptions");o(FI,"normalizeOption");QE=class{static{o(this,"JSDocCommentImpl")}constructor(e,r){this.elements=e,this.range=r}getTag(e){return this.getAllTags().find(r=>r.name===e)}getTags(e){return this.getAllTags().filter(r=>r.name===e)}getAllTags(){return this.elements.filter(e=>"name"in e)}toString(){let e="";for(let r of this.elements)if(e.length===0)e=r.toString();else{let n=r.toString();e+=fue(e)+n}return e.trim()}toMarkdown(e){let r="";for(let n of this.elements)if(r.length===0)r=n.toMarkdown(e);else{let i=n.toMarkdown(e);r+=fue(r)+i}return r.trim()}},ub=class{static{o(this,"JSDocTagImpl")}constructor(e,r,n,i){this.name=e,this.content=r,this.inline=n,this.range=i}toString(){let e=`@${this.name}`,r=this.content.toString();return this.content.inlines.length===1?e=`${e} ${r}`:this.content.inlines.length>1&&(e=`${e} +${r}`),this.inline?`{${e}}`:e}toMarkdown(e){var r,n;return(n=(r=e?.renderTag)===null||r===void 0?void 0:r.call(e,this))!==null&&n!==void 0?n:this.toMarkdownDefault(e)}toMarkdownDefault(e){let r=this.content.toMarkdown(e);if(this.inline){let a=nze(this.name,r,e??{});if(typeof a=="string")return a}let n="";e?.tag==="italic"||e?.tag===void 0?n="*":e?.tag==="bold"?n="**":e?.tag==="bold-italic"&&(n="***");let i=`${n}@${this.name}${n}`;return this.content.inlines.length===1?i=`${i} \u2014 ${r}`:this.content.inlines.length>1&&(i=`${i} +${r}`),this.inline?`{${i}}`:i}};o(nze,"renderInlineTag");o(ize,"renderLinkDefault");hb=class{static{o(this,"JSDocTextImpl")}constructor(e,r){this.inlines=e,this.range=r}toString(){let e="";for(let r=0;rn.range.start.line&&(e+=` +`)}return e}toMarkdown(e){let r="";for(let n=0;ni.range.start.line&&(r+=` +`)}return r}},ZE=class{static{o(this,"JSDocLineImpl")}constructor(e,r){this.text=e,this.range=r}toString(){return this.text}toMarkdown(){return this.text}};o(fue,"fillNewlines")});var fb,HI=N(()=>{"use strict";cs();UI();fb=class{static{o(this,"JSDocDocumentationProvider")}constructor(e){this.indexManager=e.shared.workspace.IndexManager,this.commentProvider=e.documentation.CommentProvider}getDocumentation(e){let r=this.commentProvider.getComment(e);if(r&&GI(r))return zI(r).toMarkdown({renderLink:o((i,a)=>this.documentationLinkRenderer(e,i,a),"renderLink"),renderTag:o(i=>this.documentationTagRenderer(e,i),"renderTag")})}documentationLinkRenderer(e,r,n){var i;let a=(i=this.findNameInPrecomputedScopes(e,r))!==null&&i!==void 0?i:this.findNameInGlobalScope(e,r);if(a&&a.nameSegment){let s=a.nameSegment.range.start.line+1,l=a.nameSegment.range.start.character+1,u=a.documentUri.with({fragment:`L${s},${l}`});return`[${n}](${u.toString()})`}else return}documentationTagRenderer(e,r){}findNameInPrecomputedScopes(e,r){let i=$a(e).precomputedScopes;if(!i)return;let a=e;do{let l=i.get(a).find(u=>u.name===r);if(l)return l;a=a.$container}while(a)}findNameInGlobalScope(e,r){return this.indexManager.allElements().find(i=>i.name===r)}}});var db,WI=N(()=>{"use strict";WE();Ol();db=class{static{o(this,"DefaultCommentProvider")}constructor(e){this.grammarConfig=()=>e.parser.GrammarConfig}getComment(e){var r;return CI(e)?e.$comment:(r=uN(e.$cstNode,this.grammarConfig().multilineCommentRules))===null||r===void 0?void 0:r.text}}});var pb,qI,YI,XI=N(()=>{"use strict";Qo();YE();pb=class{static{o(this,"DefaultAsyncParser")}constructor(e){this.syncParser=e.parser.LangiumParser}parse(e,r){return Promise.resolve(this.syncParser.parse(e))}},qI=class{static{o(this,"AbstractThreadedAsyncParser")}constructor(e){this.threadCount=8,this.terminationDelay=200,this.workerPool=[],this.queue=[],this.hydrator=e.serializer.Hydrator}initializeWorkers(){for(;this.workerPool.length{if(this.queue.length>0){let r=this.queue.shift();r&&(e.lock(),r.resolve(e))}}),this.workerPool.push(e)}}async parse(e,r){let n=await this.acquireParserWorker(r),i=new ps,a,s=r.onCancellationRequested(()=>{a=setTimeout(()=>{this.terminateWorker(n)},this.terminationDelay)});return n.parse(e).then(l=>{let u=this.hydrator.hydrate(l);i.resolve(u)}).catch(l=>{i.reject(l)}).finally(()=>{s.dispose(),clearTimeout(a)}),i.promise}terminateWorker(e){e.terminate();let r=this.workerPool.indexOf(e);r>=0&&this.workerPool.splice(r,1)}async acquireParserWorker(e){this.initializeWorkers();for(let n of this.workerPool)if(n.ready)return n.lock(),n;let r=new ps;return e.onCancellationRequested(()=>{let n=this.queue.indexOf(r);n>=0&&this.queue.splice(n,1),r.reject(Gc)}),this.queue.push(r),r.promise}},YI=class{static{o(this,"ParserWorker")}get ready(){return this._ready}get onReady(){return this.onReadyEmitter.event}constructor(e,r,n,i){this.onReadyEmitter=new Zn.Emitter,this.deferred=new ps,this._ready=!0,this._parsing=!1,this.sendMessage=e,this._terminate=i,r(a=>{let s=a;this.deferred.resolve(s),this.unlock()}),n(a=>{this.deferred.reject(a),this.unlock()})}terminate(){this.deferred.reject(Gc),this._terminate()}lock(){this._ready=!1}unlock(){this._parsing=!1,this._ready=!0,this.onReadyEmitter.fire()}parse(e){if(this._parsing)throw new Error("Parser worker is busy");return this._parsing=!0,this.deferred=new ps,this.sendMessage(e),this.deferred.promise}}});var mb,jI=N(()=>{"use strict";Ko();Qo();mb=class{static{o(this,"DefaultWorkspaceLock")}constructor(){this.previousTokenSource=new yr.CancellationTokenSource,this.writeQueue=[],this.readQueue=[],this.done=!0}write(e){this.cancelWrite();let r=GE();return this.previousTokenSource=r,this.enqueue(this.writeQueue,e,r.token)}read(e){return this.enqueue(this.readQueue,e)}enqueue(e,r,n=yr.CancellationToken.None){let i=new ps,a={action:r,deferred:i,cancellationToken:n};return e.push(a),this.performNextOperation(),i.promise}async performNextOperation(){if(!this.done)return;let e=[];if(this.writeQueue.length>0)e.push(this.writeQueue.shift());else if(this.readQueue.length>0)e.push(...this.readQueue.splice(0,this.readQueue.length));else return;this.done=!1,await Promise.all(e.map(async({action:r,deferred:n,cancellationToken:i})=>{try{let a=await Promise.resolve().then(()=>r(i));n.resolve(a)}catch(a){Vc(a)?n.resolve(void 0):n.reject(a)}})),this.done=!0,this.performNextOperation()}cancelWrite(){this.previousTokenSource.cancel()}}});var gb,KI=N(()=>{"use strict";RE();Pc();Il();cs();T1();Ol();gb=class{static{o(this,"DefaultHydrator")}constructor(e){this.grammarElementIdMap=new _p,this.tokenTypeIdMap=new _p,this.grammar=e.Grammar,this.lexer=e.parser.Lexer,this.linker=e.references.Linker}dehydrate(e){return{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport?this.dehydrateLexerReport(e.lexerReport):void 0,parserErrors:e.parserErrors.map(r=>Object.assign(Object.assign({},r),{message:r.message})),value:this.dehydrateAstNode(e.value,this.createDehyrationContext(e.value))}}dehydrateLexerReport(e){return e}createDehyrationContext(e){let r=new Map,n=new Map;for(let i of jo(e))r.set(i,{});if(e.$cstNode)for(let i of sp(e.$cstNode))n.set(i,{});return{astNodes:r,cstNodes:n}}dehydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode!==void 0&&(n.$cstNode=this.dehydrateCstNode(e.$cstNode,r));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)si(l)?s.push(this.dehydrateAstNode(l,r)):ya(l)?s.push(this.dehydrateReference(l,r)):s.push(l)}else si(a)?n[i]=this.dehydrateAstNode(a,r):ya(a)?n[i]=this.dehydrateReference(a,r):a!==void 0&&(n[i]=a);return n}dehydrateReference(e,r){let n={};return n.$refText=e.$refText,e.$refNode&&(n.$refNode=r.cstNodes.get(e.$refNode)),n}dehydrateCstNode(e,r){let n=r.cstNodes.get(e);return U2(e)?n.fullText=e.fullText:n.grammarSource=this.getGrammarElementId(e.grammarSource),n.hidden=e.hidden,n.astNode=r.astNodes.get(e.astNode),Ml(e)?n.content=e.content.map(i=>this.dehydrateCstNode(i,r)):hf(e)&&(n.tokenType=e.tokenType.name,n.offset=e.offset,n.length=e.length,n.startLine=e.range.start.line,n.startColumn=e.range.start.character,n.endLine=e.range.end.line,n.endColumn=e.range.end.character),n}hydrate(e){let r=e.value,n=this.createHydrationContext(r);return"$cstNode"in r&&this.hydrateCstNode(r.$cstNode,n),{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport,parserErrors:e.parserErrors,value:this.hydrateAstNode(r,n)}}createHydrationContext(e){let r=new Map,n=new Map;for(let a of jo(e))r.set(a,{});let i;if(e.$cstNode)for(let a of sp(e.$cstNode)){let s;"fullText"in a?(s=new p1(a.fullText),i=s):"content"in a?s=new Sp:"tokenType"in a&&(s=this.hydrateCstLeafNode(a)),s&&(n.set(a,s),s.root=i)}return{astNodes:r,cstNodes:n}}hydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode&&(n.$cstNode=r.cstNodes.get(e.$cstNode));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)si(l)?s.push(this.setParent(this.hydrateAstNode(l,r),n)):ya(l)?s.push(this.hydrateReference(l,n,i,r)):s.push(l)}else si(a)?n[i]=this.setParent(this.hydrateAstNode(a,r),n):ya(a)?n[i]=this.hydrateReference(a,n,i,r):a!==void 0&&(n[i]=a);return n}setParent(e,r){return e.$container=r,e}hydrateReference(e,r,n,i){return this.linker.buildReference(r,n,i.cstNodes.get(e.$refNode),e.$refText)}hydrateCstNode(e,r,n=0){let i=r.cstNodes.get(e);if(typeof e.grammarSource=="number"&&(i.grammarSource=this.getGrammarElement(e.grammarSource)),i.astNode=r.astNodes.get(e.astNode),Ml(i))for(let a of e.content){let s=this.hydrateCstNode(a,r,n++);i.content.push(s)}return i}hydrateCstLeafNode(e){let r=this.getTokenType(e.tokenType),n=e.offset,i=e.length,a=e.startLine,s=e.startColumn,l=e.endLine,u=e.endColumn,h=e.hidden;return new Ep(n,i,{start:{line:a,character:s},end:{line:l,character:u}},r,h)}getTokenType(e){return this.lexer.definition[e]}getGrammarElementId(e){if(e)return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.get(e)}getGrammarElement(e){return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.getKey(e)}createGrammarElementIdMap(){let e=0;for(let r of jo(this.grammar))Q2(r)&&this.grammarElementIdMap.set(r,e++)}}});function va(t){return{documentation:{CommentProvider:o(e=>new db(e),"CommentProvider"),DocumentationProvider:o(e=>new fb(e),"DocumentationProvider")},parser:{AsyncParser:o(e=>new pb(e),"AsyncParser"),GrammarConfig:o(e=>QN(e),"GrammarConfig"),LangiumParser:o(e=>aI(e),"LangiumParser"),CompletionParser:o(e=>nI(e),"CompletionParser"),ValueConverter:o(()=>new Ap,"ValueConverter"),TokenBuilder:o(()=>new ju,"TokenBuilder"),Lexer:o(e=>new Rp(e),"Lexer"),ParserErrorMessageProvider:o(()=>new m1,"ParserErrorMessageProvider"),LexerErrorMessageProvider:o(()=>new cb,"LexerErrorMessageProvider")},workspace:{AstNodeLocator:o(()=>new ib,"AstNodeLocator"),AstNodeDescriptionProvider:o(e=>new rb(e),"AstNodeDescriptionProvider"),ReferenceDescriptionProvider:o(e=>new nb(e),"ReferenceDescriptionProvider")},references:{Linker:o(e=>new Hx(e),"Linker"),NameProvider:o(()=>new Wx,"NameProvider"),ScopeProvider:o(e=>new Kx(e),"ScopeProvider"),ScopeComputation:o(e=>new Yx(e),"ScopeComputation"),References:o(e=>new qx(e),"References")},serializer:{Hydrator:o(e=>new gb(e),"Hydrator"),JsonSerializer:o(e=>new Qx(e),"JsonSerializer")},validation:{DocumentValidator:o(e=>new tb(e),"DocumentValidator"),ValidationRegistry:o(e=>new Jx(e),"ValidationRegistry")},shared:o(()=>t.shared,"shared")}}function xa(t){return{ServiceRegistry:o(e=>new Zx(e),"ServiceRegistry"),workspace:{LangiumDocuments:o(e=>new Ux(e),"LangiumDocuments"),LangiumDocumentFactory:o(e=>new Vx(e),"LangiumDocumentFactory"),DocumentBuilder:o(e=>new sb(e),"DocumentBuilder"),IndexManager:o(e=>new ob(e),"IndexManager"),WorkspaceManager:o(e=>new lb(e),"WorkspaceManager"),FileSystemProvider:o(e=>t.fileSystemProvider(e),"FileSystemProvider"),WorkspaceLock:o(()=>new mb,"WorkspaceLock"),ConfigurationProvider:o(e=>new ab(e),"ConfigurationProvider")}}}var QI=N(()=>{"use strict";ZN();iI();sI();PE();oI();bI();TI();wI();kI();SI();WE();AI();_I();eb();DI();LI();RI();MI();b1();II();OI();KE();HI();WI();zx();XI();jI();KI();o(va,"createDefaultCoreModule");o(xa,"createDefaultSharedCoreModule")});function Gn(t,e,r,n,i,a,s,l,u){let h=[t,e,r,n,i,a,s,l,u].reduce(JE,{});return Tue(h)}function bue(t){if(t&&t[xue])for(let e of Object.values(t))bue(e);return t}function Tue(t,e){let r=new Proxy({},{deleteProperty:o(()=>!1,"deleteProperty"),set:o(()=>{throw new Error("Cannot set property on injected service container")},"set"),get:o((n,i)=>i===xue?!0:vue(n,i,t,e||r),"get"),getOwnPropertyDescriptor:o((n,i)=>(vue(n,i,t,e||r),Object.getOwnPropertyDescriptor(n,i)),"getOwnPropertyDescriptor"),has:o((n,i)=>i in t,"has"),ownKeys:o(()=>[...Object.getOwnPropertyNames(t)],"ownKeys")});return r}function vue(t,e,r,n){if(e in t){if(t[e]instanceof Error)throw new Error("Construction failure. Please make sure that your dependencies are constructable.",{cause:t[e]});if(t[e]===yue)throw new Error('Cycle detected. Please make "'+String(e)+'" lazy. Visit https://langium.org/docs/reference/configuration-services/#resolving-cyclic-dependencies');return t[e]}else if(e in r){let i=r[e];t[e]=yue;try{t[e]=typeof i=="function"?i(n):Tue(i,n)}catch(a){throw t[e]=a instanceof Error?a:void 0,a}return t[e]}else return}function JE(t,e){if(e){for(let[r,n]of Object.entries(e))if(n!==void 0){let i=t[r];i!==null&&n!==null&&typeof i=="object"&&typeof n=="object"?t[r]=JE(i,n):t[r]=n}}return t}var ZI,xue,yue,JI=N(()=>{"use strict";(function(t){t.merge=(e,r)=>JE(JE({},e),r)})(ZI||(ZI={}));o(Gn,"inject");xue=Symbol("isProxy");o(bue,"eagerLoad");o(Tue,"_inject");yue=Symbol();o(vue,"_resolve");o(JE,"_merge")});var wue=N(()=>{"use strict"});var kue=N(()=>{"use strict";WI();HI();UI()});var Eue=N(()=>{"use strict"});var Sue=N(()=>{"use strict";ZN();Eue()});var eO,Np,eS,tO,Cue=N(()=>{"use strict";mf();PE();KE();eO={indentTokenName:"INDENT",dedentTokenName:"DEDENT",whitespaceTokenName:"WS",ignoreIndentationDelimiters:[]};(function(t){t.REGULAR="indentation-sensitive",t.IGNORE_INDENTATION="ignore-indentation"})(Np||(Np={}));eS=class extends ju{static{o(this,"IndentationAwareTokenBuilder")}constructor(e=eO){super(),this.indentationStack=[0],this.whitespaceRegExp=/[ \t]+/y,this.options=Object.assign(Object.assign({},eO),e),this.indentTokenType=df({name:this.options.indentTokenName,pattern:this.indentMatcher.bind(this),line_breaks:!1}),this.dedentTokenType=df({name:this.options.dedentTokenName,pattern:this.dedentMatcher.bind(this),line_breaks:!1})}buildTokens(e,r){let n=super.buildTokens(e,r);if(!jE(n))throw new Error("Invalid tokens built by default builder");let{indentTokenName:i,dedentTokenName:a,whitespaceTokenName:s,ignoreIndentationDelimiters:l}=this.options,u,h,f,d=[];for(let p of n){for(let[m,g]of l)p.name===m?p.PUSH_MODE=Np.IGNORE_INDENTATION:p.name===g&&(p.POP_MODE=!0);p.name===a?u=p:p.name===i?h=p:p.name===s?f=p:d.push(p)}if(!u||!h||!f)throw new Error("Some indentation/whitespace tokens not found!");return l.length>0?{modes:{[Np.REGULAR]:[u,h,...d,f],[Np.IGNORE_INDENTATION]:[...d,f]},defaultMode:Np.REGULAR}:[u,h,f,...d]}flushLexingReport(e){let r=super.flushLexingReport(e);return Object.assign(Object.assign({},r),{remainingDedents:this.flushRemainingDedents(e)})}isStartOfLine(e,r){return r===0||`\r +`.includes(e[r-1])}matchWhitespace(e,r,n,i){var a;this.whitespaceRegExp.lastIndex=r;let s=this.whitespaceRegExp.exec(e);return{currIndentLevel:(a=s?.[0].length)!==null&&a!==void 0?a:0,prevIndentLevel:this.indentationStack.at(-1),match:s}}createIndentationTokenInstance(e,r,n,i){let a=this.getLineNumber(r,i);return Wu(e,n,i,i+n.length,a,a,1,n.length)}getLineNumber(e,r){return e.substring(0,r).split(/\r\n|\r|\n/).length}indentMatcher(e,r,n,i){if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:a,prevIndentLevel:s,match:l}=this.matchWhitespace(e,r,n,i);return a<=s?null:(this.indentationStack.push(a),l)}dedentMatcher(e,r,n,i){var a,s,l,u;if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:h,prevIndentLevel:f,match:d}=this.matchWhitespace(e,r,n,i);if(h>=f)return null;let p=this.indentationStack.lastIndexOf(h);if(p===-1)return this.diagnostics.push({severity:"error",message:`Invalid dedent level ${h} at offset: ${r}. Current indentation stack: ${this.indentationStack}`,offset:r,length:(s=(a=d?.[0])===null||a===void 0?void 0:a.length)!==null&&s!==void 0?s:0,line:this.getLineNumber(e,r),column:1}),null;let m=this.indentationStack.length-p-1,g=(u=(l=e.substring(0,r).match(/[\r\n]+$/))===null||l===void 0?void 0:l[0].length)!==null&&u!==void 0?u:1;for(let y=0;y1;)r.push(this.createIndentationTokenInstance(this.dedentTokenType,e,"",e.length)),this.indentationStack.pop();return this.indentationStack=[0],r}},tO=class extends Rp{static{o(this,"IndentationAwareLexer")}constructor(e){if(super(e),e.parser.TokenBuilder instanceof eS)this.indentationTokenBuilder=e.parser.TokenBuilder;else throw new Error("IndentationAwareLexer requires an accompanying IndentationAwareTokenBuilder")}tokenize(e,r=XE){let n=super.tokenize(e),i=n.report;r?.mode==="full"&&n.tokens.push(...i.remainingDedents),i.remainingDedents=[];let{indentTokenType:a,dedentTokenType:s}=this.indentationTokenBuilder,l=a.tokenTypeIdx,u=s.tokenTypeIdx,h=[],f=n.tokens.length-1;for(let d=0;d=0&&h.push(n.tokens[f]),n.tokens=h,n}}});var Aue=N(()=>{"use strict"});var _ue=N(()=>{"use strict";XI();iI();RE();Cue();sI();zx();KE();OE();Aue();PE();oI()});var Due=N(()=>{"use strict";bI();TI();wI();EI();kI();SI()});var Lue=N(()=>{"use strict";KI();WE()});var tS,ba,rO=N(()=>{"use strict";tS=class{static{o(this,"EmptyFileSystemProvider")}readFile(){throw new Error("No file system is available.")}async readDirectory(){return[]}},ba={fileSystemProvider:o(()=>new tS,"fileSystemProvider")}});function oze(){let t=Gn(xa(ba),sze),e=Gn(va({shared:t}),aze);return t.ServiceRegistry.register(e),e}function Hc(t){var e;let r=oze(),n=r.serializer.JsonSerializer.deserialize(t);return r.shared.workspace.LangiumDocumentFactory.fromModel(n,ms.parse(`memory://${(e=n.name)!==null&&e!==void 0?e:"grammar"}.langium`)),n}var aze,sze,Rue=N(()=>{"use strict";QI();JI();Pc();rO();Uc();aze={Grammar:o(()=>{},"Grammar"),LanguageMetaData:o(()=>({caseInsensitive:!1,fileExtensions:[".langium"],languageId:"langium"}),"LanguageMetaData")},sze={AstReflection:o(()=>new Og,"AstReflection")};o(oze,"createMinimalGrammarServices");o(Hc,"loadGrammarFromJson")});var Gr={};ur(Gr,{AstUtils:()=>Ik,BiMap:()=>_p,Cancellation:()=>yr,ContextCache:()=>Dp,CstUtils:()=>Ek,DONE_RESULT:()=>Ba,Deferred:()=>ps,Disposable:()=>vf,DisposableCache:()=>k1,DocumentCache:()=>UE,EMPTY_STREAM:()=>H2,ErrorWithLocation:()=>lp,GrammarUtils:()=>$k,MultiMap:()=>zl,OperationCancelled:()=>Gc,Reduction:()=>jm,RegExpUtils:()=>Bk,SimpleCache:()=>jx,StreamImpl:()=>co,TreeStreamImpl:()=>Mc,URI:()=>ms,UriUtils:()=>gs,WorkspaceCache:()=>E1,assertUnreachable:()=>Oc,delayNextTick:()=>gI,interruptAndCheck:()=>wi,isOperationCancelled:()=>Vc,loadGrammarFromJson:()=>Hc,setInterruptionPeriod:()=>tue,startCancelableOperation:()=>GE,stream:()=>en});var Nue=N(()=>{"use strict";HE();YE();Cr(Gr,Zn);T1();NI();Sk();Rue();Qo();Gs();Uc();cs();Ko();Ol();Fl();$g()});var Mue=N(()=>{"use strict";_I();eb()});var Iue=N(()=>{"use strict";DI();LI();RI();MI();b1();rO();II();jI();OI()});var Ta={};ur(Ta,{AbstractAstReflection:()=>ip,AbstractCstNode:()=>Px,AbstractLangiumParser:()=>Bx,AbstractParserErrorMessageProvider:()=>ME,AbstractThreadedAsyncParser:()=>qI,AstUtils:()=>Ik,BiMap:()=>_p,Cancellation:()=>yr,CompositeCstNodeImpl:()=>Sp,ContextCache:()=>Dp,CstNodeBuilder:()=>Ox,CstUtils:()=>Ek,DEFAULT_TOKENIZE_OPTIONS:()=>XE,DONE_RESULT:()=>Ba,DatatypeSymbol:()=>NE,DefaultAstNodeDescriptionProvider:()=>rb,DefaultAstNodeLocator:()=>ib,DefaultAsyncParser:()=>pb,DefaultCommentProvider:()=>db,DefaultConfigurationProvider:()=>ab,DefaultDocumentBuilder:()=>sb,DefaultDocumentValidator:()=>tb,DefaultHydrator:()=>gb,DefaultIndexManager:()=>ob,DefaultJsonSerializer:()=>Qx,DefaultLangiumDocumentFactory:()=>Vx,DefaultLangiumDocuments:()=>Ux,DefaultLexer:()=>Rp,DefaultLexerErrorMessageProvider:()=>cb,DefaultLinker:()=>Hx,DefaultNameProvider:()=>Wx,DefaultReferenceDescriptionProvider:()=>nb,DefaultReferences:()=>qx,DefaultScopeComputation:()=>Yx,DefaultScopeProvider:()=>Kx,DefaultServiceRegistry:()=>Zx,DefaultTokenBuilder:()=>ju,DefaultValueConverter:()=>Ap,DefaultWorkspaceLock:()=>mb,DefaultWorkspaceManager:()=>lb,Deferred:()=>ps,Disposable:()=>vf,DisposableCache:()=>k1,DocumentCache:()=>UE,DocumentState:()=>kn,DocumentValidator:()=>Zo,EMPTY_SCOPE:()=>q$e,EMPTY_STREAM:()=>H2,EmptyFileSystem:()=>ba,EmptyFileSystemProvider:()=>tS,ErrorWithLocation:()=>lp,GrammarAST:()=>J2,GrammarUtils:()=>$k,IndentationAwareLexer:()=>tO,IndentationAwareTokenBuilder:()=>eS,JSDocDocumentationProvider:()=>fb,LangiumCompletionParser:()=>$x,LangiumParser:()=>Fx,LangiumParserErrorMessageProvider:()=>m1,LeafCstNodeImpl:()=>Ep,LexingMode:()=>Np,MapScope:()=>Xx,Module:()=>ZI,MultiMap:()=>zl,OperationCancelled:()=>Gc,ParserWorker:()=>YI,Reduction:()=>jm,RegExpUtils:()=>Bk,RootCstNodeImpl:()=>p1,SimpleCache:()=>jx,StreamImpl:()=>co,StreamScope:()=>w1,TextDocument:()=>v1,TreeStreamImpl:()=>Mc,URI:()=>ms,UriUtils:()=>gs,ValidationCategory:()=>S1,ValidationRegistry:()=>Jx,ValueConverter:()=>zc,WorkspaceCache:()=>E1,assertUnreachable:()=>Oc,createCompletionParser:()=>nI,createDefaultCoreModule:()=>va,createDefaultSharedCoreModule:()=>xa,createGrammarConfig:()=>QN,createLangiumParser:()=>aI,createParser:()=>Gx,delayNextTick:()=>gI,diagnosticData:()=>Lp,eagerLoad:()=>bue,getDiagnosticRange:()=>cue,indentationBuilderDefaultOptions:()=>eO,inject:()=>Gn,interruptAndCheck:()=>wi,isAstNode:()=>si,isAstNodeDescription:()=>sN,isAstNodeWithComment:()=>CI,isCompositeCstNode:()=>Ml,isIMultiModeLexerDefinition:()=>BI,isJSDoc:()=>GI,isLeafCstNode:()=>hf,isLinkingError:()=>ap,isNamed:()=>oue,isOperationCancelled:()=>Vc,isReference:()=>ya,isRootCstNode:()=>U2,isTokenTypeArray:()=>jE,isTokenTypeDictionary:()=>PI,loadGrammarFromJson:()=>Hc,parseJSDoc:()=>zI,prepareLangiumParser:()=>Xce,setInterruptionPeriod:()=>tue,startCancelableOperation:()=>GE,stream:()=>en,toDiagnosticData:()=>uue,toDiagnosticSeverity:()=>qE});var po=N(()=>{"use strict";QI();JI();AI();wue();Il();kue();Sue();_ue();Due();Lue();Nue();Cr(Ta,Gr);Mue();Iue();Pc()});function Vue(t){return Gl.isInstance(t,yb)}function Uue(t){return Gl.isInstance(t,C1)}function Hue(t){return Gl.isInstance(t,A1)}function Wue(t){return Gl.isInstance(t,_1)}function que(t){return Gl.isInstance(t,vb)}function Yue(t){return Gl.isInstance(t,D1)}function Xue(t){return Gl.isInstance(t,xb)}function jue(t){return Gl.isInstance(t,bb)}function Kue(t){return Gl.isInstance(t,Tb)}function Que(t){return Gl.isInstance(t,wb)}function Zue(t){return Gl.isInstance(t,kb)}var lze,xt,fO,yb,rS,C1,nS,iS,nO,A1,iO,aO,sO,_1,oO,vb,aS,lO,D1,cO,xb,bb,Tb,wb,cS,uO,kb,hO,sS,oS,lS,Jue,Gl,Oue,cze,Pue,uze,Bue,hze,Fue,fze,$ue,dze,zue,pze,Gue,mze,gze,yze,vze,xze,bze,Tze,wze,ys,dO,pO,mO,gO,yO,vO,xO,kze,Eze,Sze,Cze,xf,Ku,Ga,Aze,Va=N(()=>{"use strict";po();po();po();po();lze=Object.defineProperty,xt=o((t,e)=>lze(t,"name",{value:e,configurable:!0}),"__name"),fO="Statement",yb="Architecture";o(Vue,"isArchitecture");xt(Vue,"isArchitecture");rS="Axis",C1="Branch";o(Uue,"isBranch");xt(Uue,"isBranch");nS="Checkout",iS="CherryPicking",nO="ClassDefStatement",A1="Commit";o(Hue,"isCommit");xt(Hue,"isCommit");iO="Curve",aO="Edge",sO="Entry",_1="GitGraph";o(Wue,"isGitGraph");xt(Wue,"isGitGraph");oO="Group",vb="Info";o(que,"isInfo");xt(que,"isInfo");aS="Item",lO="Junction",D1="Merge";o(Yue,"isMerge");xt(Yue,"isMerge");cO="Option",xb="Packet";o(Xue,"isPacket");xt(Xue,"isPacket");bb="PacketBlock";o(jue,"isPacketBlock");xt(jue,"isPacketBlock");Tb="Pie";o(Kue,"isPie");xt(Kue,"isPie");wb="PieSection";o(Que,"isPieSection");xt(Que,"isPieSection");cS="Radar",uO="Service",kb="Treemap";o(Zue,"isTreemap");xt(Zue,"isTreemap");hO="TreemapRow",sS="Direction",oS="Leaf",lS="Section",Jue=class extends ip{static{o(this,"MermaidAstReflection")}static{xt(this,"MermaidAstReflection")}getAllTypes(){return[yb,rS,C1,nS,iS,nO,A1,iO,sS,aO,sO,_1,oO,vb,aS,lO,oS,D1,cO,xb,bb,Tb,wb,cS,lS,uO,fO,kb,hO]}computeIsSubtype(t,e){switch(t){case C1:case nS:case iS:case A1:case D1:return this.isSubtype(fO,e);case sS:return this.isSubtype(_1,e);case oS:case lS:return this.isSubtype(aS,e);default:return!1}}getReferenceType(t){let e=`${t.container.$type}:${t.property}`;switch(e){case"Entry:axis":return rS;default:throw new Error(`${e} is not a valid reference id.`)}}getTypeMetaData(t){switch(t){case yb:return{name:yb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"edges",defaultValue:[]},{name:"groups",defaultValue:[]},{name:"junctions",defaultValue:[]},{name:"services",defaultValue:[]},{name:"title"}]};case rS:return{name:rS,properties:[{name:"label"},{name:"name"}]};case C1:return{name:C1,properties:[{name:"name"},{name:"order"}]};case nS:return{name:nS,properties:[{name:"branch"}]};case iS:return{name:iS,properties:[{name:"id"},{name:"parent"},{name:"tags",defaultValue:[]}]};case nO:return{name:nO,properties:[{name:"className"},{name:"styleText"}]};case A1:return{name:A1,properties:[{name:"id"},{name:"message"},{name:"tags",defaultValue:[]},{name:"type"}]};case iO:return{name:iO,properties:[{name:"entries",defaultValue:[]},{name:"label"},{name:"name"}]};case aO:return{name:aO,properties:[{name:"lhsDir"},{name:"lhsGroup",defaultValue:!1},{name:"lhsId"},{name:"lhsInto",defaultValue:!1},{name:"rhsDir"},{name:"rhsGroup",defaultValue:!1},{name:"rhsId"},{name:"rhsInto",defaultValue:!1},{name:"title"}]};case sO:return{name:sO,properties:[{name:"axis"},{name:"value"}]};case _1:return{name:_1,properties:[{name:"accDescr"},{name:"accTitle"},{name:"statements",defaultValue:[]},{name:"title"}]};case oO:return{name:oO,properties:[{name:"icon"},{name:"id"},{name:"in"},{name:"title"}]};case vb:return{name:vb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case aS:return{name:aS,properties:[{name:"classSelector"},{name:"name"}]};case lO:return{name:lO,properties:[{name:"id"},{name:"in"}]};case D1:return{name:D1,properties:[{name:"branch"},{name:"id"},{name:"tags",defaultValue:[]},{name:"type"}]};case cO:return{name:cO,properties:[{name:"name"},{name:"value",defaultValue:!1}]};case xb:return{name:xb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"blocks",defaultValue:[]},{name:"title"}]};case bb:return{name:bb,properties:[{name:"bits"},{name:"end"},{name:"label"},{name:"start"}]};case Tb:return{name:Tb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"sections",defaultValue:[]},{name:"showData",defaultValue:!1},{name:"title"}]};case wb:return{name:wb,properties:[{name:"label"},{name:"value"}]};case cS:return{name:cS,properties:[{name:"accDescr"},{name:"accTitle"},{name:"axes",defaultValue:[]},{name:"curves",defaultValue:[]},{name:"options",defaultValue:[]},{name:"title"}]};case uO:return{name:uO,properties:[{name:"icon"},{name:"iconText"},{name:"id"},{name:"in"},{name:"title"}]};case kb:return{name:kb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"},{name:"TreemapRows",defaultValue:[]}]};case hO:return{name:hO,properties:[{name:"indent"},{name:"item"}]};case sS:return{name:sS,properties:[{name:"accDescr"},{name:"accTitle"},{name:"dir"},{name:"statements",defaultValue:[]},{name:"title"}]};case oS:return{name:oS,properties:[{name:"classSelector"},{name:"name"},{name:"value"}]};case lS:return{name:lS,properties:[{name:"classSelector"},{name:"name"}]};default:return{name:t,properties:[]}}}},Gl=new Jue,cze=xt(()=>Oue??(Oue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Info","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Info","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"info"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"Keyword","value":"showInfo"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@7"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"InfoGrammar"),uze=xt(()=>Pue??(Pue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Packet","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Packet","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"packet"},{"$type":"Keyword","value":"packet-beta"}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PacketBlock","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"start","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"end","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}],"cardinality":"?"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"+"},{"$type":"Assignment","feature":"bits","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]}]},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@9"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"PacketGrammar"),hze=xt(()=>Bue??(Bue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Pie","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Pie","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"pie"},{"$type":"Assignment","feature":"showData","operator":"?=","terminal":{"$type":"Keyword","value":"showData"},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PieSection","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@9"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"PieGrammar"),fze=xt(()=>Fue??(Fue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Architecture","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Architecture","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"architecture-beta"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"groups","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"services","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"junctions","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"edges","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"LeftPort","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"lhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"RightPort","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"rhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Keyword","value":":"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Arrow","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Assignment","feature":"lhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"--"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]}},{"$type":"Keyword","value":"-"}]}]},{"$type":"Assignment","feature":"rhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Group","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Service","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"service"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"iconText","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]}}],"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Junction","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"junction"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Edge","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"lhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"lhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"rhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"rhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"ARROW_DIRECTION","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"L"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"R"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"T"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"B"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_GROUP","definition":{"$type":"RegexToken","regex":"/\\\\{group\\\\}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_INTO","definition":{"$type":"RegexToken","regex":"/<|>/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@18"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@19"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"ARCH_ICON","definition":{"$type":"RegexToken","regex":"/\\\\([\\\\w-:]+\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TITLE","definition":{"$type":"RegexToken","regex":"/\\\\[[\\\\w ]+\\\\]/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"ArchitectureGrammar"),dze=xt(()=>$ue??($ue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"GitGraph","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"GitGraph","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Keyword","value":":"}]},{"$type":"Keyword","value":"gitGraph:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Keyword","value":":"}]}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"Assignment","feature":"statements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Direction","definition":{"$type":"Assignment","feature":"dir","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"LR"},{"$type":"Keyword","value":"TB"},{"$type":"Keyword","value":"BT"}]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Commit","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"commit"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"msg:","cardinality":"?"},{"$type":"Assignment","feature":"message","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Branch","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"branch"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"order:"},{"$type":"Assignment","feature":"order","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Merge","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"merge"},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Checkout","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"checkout"},{"$type":"Keyword","value":"switch"}]},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CherryPicking","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"cherry-pick"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"parent:"},{"$type":"Assignment","feature":"parent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@14"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"REFERENCE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\\\w([-\\\\./\\\\w]*[-\\\\w])?/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"GitGraphGrammar"),pze=xt(()=>zue??(zue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Radar","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Radar","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":"radar-beta:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Keyword","value":"axis"},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"curve"},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Label","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"["},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}},{"$type":"Keyword","value":"]"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Axis","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Curve","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Entries","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DetailedEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"axis","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@2"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NumberEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Option","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"showLegend"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"ticks"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"max"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"min"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"graticule"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"GRATICULE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"circle"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"polygon"}}]},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@16"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"interfaces":[{"$type":"Interface","name":"Entry","attributes":[{"$type":"TypeAttribute","name":"axis","isOptional":true,"type":{"$type":"ReferenceType","referenceType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@2"}}}},{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"types":[],"usedGrammars":[]}`)),"RadarGrammar"),mze=xt(()=>Gue??(Gue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Treemap","rules":[{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"ParserRule","entry":true,"name":"Treemap","returnType":{"$ref":"#/interfaces@4"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Assignment","feature":"TreemapRows","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"TREEMAP_KEYWORD","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap-beta"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"CLASS_DEF","definition":{"$type":"RegexToken","regex":"/classDef\\\\s+([a-zA-Z_][a-zA-Z0-9_]+)(?:\\\\s+([^;\\\\r\\\\n]*))?(?:;)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STYLE_SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":::"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"COMMA","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":","}},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WS","definition":{"$type":"RegexToken","regex":"/[ \\\\t]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"ML_COMMENT","definition":{"$type":"RegexToken","regex":"/\\\\%\\\\%[^\\\\n]*/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"NL","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false},{"$type":"ParserRule","name":"TreemapRow","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"indent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"item","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ClassDef","dataType":"string","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Item","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Section","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Leaf","returnType":{"$ref":"#/interfaces@2"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INDENTATION","definition":{"$type":"RegexToken","regex":"/[ \\\\t]{1,}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID2","definition":{"$type":"RegexToken","regex":"/[a-zA-Z_][a-zA-Z0-9_]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER2","definition":{"$type":"RegexToken","regex":"/[0-9_\\\\.\\\\,]+/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"MyNumber","dataType":"number","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"STRING2","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|'[^']*'/"},"fragment":false,"hidden":false}],"interfaces":[{"$type":"Interface","name":"Item","attributes":[{"$type":"TypeAttribute","name":"name","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"classSelector","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]},{"$type":"Interface","name":"Section","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[]},{"$type":"Interface","name":"Leaf","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}]},{"$type":"Interface","name":"ClassDefStatement","attributes":[{"$type":"TypeAttribute","name":"className","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"styleText","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false}],"superTypes":[]},{"$type":"Interface","name":"Treemap","attributes":[{"$type":"TypeAttribute","name":"TreemapRows","type":{"$type":"ArrayType","elementType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@14"}}},"isOptional":false},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[],"$comment":"/**\\n * Treemap grammar for Langium\\n * Converted from mindmap grammar\\n *\\n * The ML_COMMENT and NL hidden terminals handle whitespace, comments, and newlines\\n * before the treemap keyword, allowing for empty lines and comments before the\\n * treemap declaration.\\n */"}`)),"TreemapGrammar"),gze={languageId:"info",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},yze={languageId:"packet",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},vze={languageId:"pie",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},xze={languageId:"architecture",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},bze={languageId:"gitGraph",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},Tze={languageId:"radar",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},wze={languageId:"treemap",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},ys={AstReflection:xt(()=>new Jue,"AstReflection")},dO={Grammar:xt(()=>cze(),"Grammar"),LanguageMetaData:xt(()=>gze,"LanguageMetaData"),parser:{}},pO={Grammar:xt(()=>uze(),"Grammar"),LanguageMetaData:xt(()=>yze,"LanguageMetaData"),parser:{}},mO={Grammar:xt(()=>hze(),"Grammar"),LanguageMetaData:xt(()=>vze,"LanguageMetaData"),parser:{}},gO={Grammar:xt(()=>fze(),"Grammar"),LanguageMetaData:xt(()=>xze,"LanguageMetaData"),parser:{}},yO={Grammar:xt(()=>dze(),"Grammar"),LanguageMetaData:xt(()=>bze,"LanguageMetaData"),parser:{}},vO={Grammar:xt(()=>pze(),"Grammar"),LanguageMetaData:xt(()=>Tze,"LanguageMetaData"),parser:{}},xO={Grammar:xt(()=>mze(),"Grammar"),LanguageMetaData:xt(()=>wze,"LanguageMetaData"),parser:{}},kze=/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,Eze=/accTitle[\t ]*:([^\n\r]*)/,Sze=/title([\t ][^\n\r]*|)/,Cze={ACC_DESCR:kze,ACC_TITLE:Eze,TITLE:Sze},xf=class extends Ap{static{o(this,"AbstractMermaidValueConverter")}static{xt(this,"AbstractMermaidValueConverter")}runConverter(t,e,r){let n=this.runCommonConverter(t,e,r);return n===void 0&&(n=this.runCustomConverter(t,e,r)),n===void 0?super.runConverter(t,e,r):n}runCommonConverter(t,e,r){let n=Cze[t.name];if(n===void 0)return;let i=n.exec(e);if(i!==null){if(i[1]!==void 0)return i[1].trim().replace(/[\t ]{2,}/gm," ");if(i[2]!==void 0)return i[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,` +`)}}},Ku=class extends xf{static{o(this,"CommonValueConverter")}static{xt(this,"CommonValueConverter")}runCustomConverter(t,e,r){}},Ga=class extends ju{static{o(this,"AbstractMermaidTokenBuilder")}static{xt(this,"AbstractMermaidTokenBuilder")}constructor(t){super(),this.keywords=new Set(t)}buildKeywordTokens(t,e,r){let n=super.buildKeywordTokens(t,e,r);return n.forEach(i=>{this.keywords.has(i.name)&&i.PATTERN!==void 0&&(i.PATTERN=new RegExp(i.PATTERN.toString()+"(?:(?=%%)|(?!\\S))"))}),n}},Aze=class extends Ga{static{o(this,"CommonTokenBuilder")}static{xt(this,"CommonTokenBuilder")}}});function hS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),yO,uS);return e.ServiceRegistry.register(r),{shared:e,GitGraph:r}}var _ze,uS,bO=N(()=>{"use strict";Va();po();_ze=class extends Ga{static{o(this,"GitGraphTokenBuilder")}static{xt(this,"GitGraphTokenBuilder")}constructor(){super(["gitGraph"])}},uS={parser:{TokenBuilder:xt(()=>new _ze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(hS,"createGitGraphServices");xt(hS,"createGitGraphServices")});function dS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),dO,fS);return e.ServiceRegistry.register(r),{shared:e,Info:r}}var Dze,fS,TO=N(()=>{"use strict";Va();po();Dze=class extends Ga{static{o(this,"InfoTokenBuilder")}static{xt(this,"InfoTokenBuilder")}constructor(){super(["info","showInfo"])}},fS={parser:{TokenBuilder:xt(()=>new Dze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(dS,"createInfoServices");xt(dS,"createInfoServices")});function mS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),pO,pS);return e.ServiceRegistry.register(r),{shared:e,Packet:r}}var Lze,pS,wO=N(()=>{"use strict";Va();po();Lze=class extends Ga{static{o(this,"PacketTokenBuilder")}static{xt(this,"PacketTokenBuilder")}constructor(){super(["packet"])}},pS={parser:{TokenBuilder:xt(()=>new Lze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(mS,"createPacketServices");xt(mS,"createPacketServices")});function yS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),mO,gS);return e.ServiceRegistry.register(r),{shared:e,Pie:r}}var Rze,Nze,gS,kO=N(()=>{"use strict";Va();po();Rze=class extends Ga{static{o(this,"PieTokenBuilder")}static{xt(this,"PieTokenBuilder")}constructor(){super(["pie","showData"])}},Nze=class extends xf{static{o(this,"PieValueConverter")}static{xt(this,"PieValueConverter")}runCustomConverter(t,e,r){if(t.name==="PIE_SECTION_LABEL")return e.replace(/"/g,"").trim()}},gS={parser:{TokenBuilder:xt(()=>new Rze,"TokenBuilder"),ValueConverter:xt(()=>new Nze,"ValueConverter")}};o(yS,"createPieServices");xt(yS,"createPieServices")});function xS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),gO,vS);return e.ServiceRegistry.register(r),{shared:e,Architecture:r}}var Mze,Ize,vS,EO=N(()=>{"use strict";Va();po();Mze=class extends Ga{static{o(this,"ArchitectureTokenBuilder")}static{xt(this,"ArchitectureTokenBuilder")}constructor(){super(["architecture"])}},Ize=class extends xf{static{o(this,"ArchitectureValueConverter")}static{xt(this,"ArchitectureValueConverter")}runCustomConverter(t,e,r){if(t.name==="ARCH_ICON")return e.replace(/[()]/g,"").trim();if(t.name==="ARCH_TEXT_ICON")return e.replace(/["()]/g,"");if(t.name==="ARCH_TITLE")return e.replace(/[[\]]/g,"").trim()}},vS={parser:{TokenBuilder:xt(()=>new Mze,"TokenBuilder"),ValueConverter:xt(()=>new Ize,"ValueConverter")}};o(xS,"createArchitectureServices");xt(xS,"createArchitectureServices")});function TS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),vO,bS);return e.ServiceRegistry.register(r),{shared:e,Radar:r}}var Oze,bS,SO=N(()=>{"use strict";Va();po();Oze=class extends Ga{static{o(this,"RadarTokenBuilder")}static{xt(this,"RadarTokenBuilder")}constructor(){super(["radar-beta"])}},bS={parser:{TokenBuilder:xt(()=>new Oze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(TS,"createRadarServices");xt(TS,"createRadarServices")});function ehe(t){let e=t.validation.TreemapValidator,r=t.validation.ValidationRegistry;if(r){let n={Treemap:e.checkSingleRoot.bind(e)};r.register(n,e)}}function kS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),xO,wS);return e.ServiceRegistry.register(r),ehe(r),{shared:e,Treemap:r}}var Pze,Bze,Fze,$ze,wS,CO=N(()=>{"use strict";Va();po();Pze=class extends Ga{static{o(this,"TreemapTokenBuilder")}static{xt(this,"TreemapTokenBuilder")}constructor(){super(["treemap"])}},Bze=/classDef\s+([A-Z_a-z]\w+)(?:\s+([^\n\r;]*))?;?/,Fze=class extends xf{static{o(this,"TreemapValueConverter")}static{xt(this,"TreemapValueConverter")}runCustomConverter(t,e,r){if(t.name==="NUMBER2")return parseFloat(e.replace(/,/g,""));if(t.name==="SEPARATOR")return e.substring(1,e.length-1);if(t.name==="STRING2")return e.substring(1,e.length-1);if(t.name==="INDENTATION")return e.length;if(t.name==="ClassDef"){if(typeof e!="string")return e;let n=Bze.exec(e);if(n)return{$type:"ClassDefStatement",className:n[1],styleText:n[2]||void 0}}}};o(ehe,"registerValidationChecks");xt(ehe,"registerValidationChecks");$ze=class{static{o(this,"TreemapValidator")}static{xt(this,"TreemapValidator")}checkSingleRoot(t,e){let r;for(let n of t.TreemapRows)n.item&&(r===void 0&&n.indent===void 0?r=0:n.indent===void 0?e("error","Multiple root nodes are not allowed in a treemap.",{node:n,property:"item"}):r!==void 0&&r>=parseInt(n.indent,10)&&e("error","Multiple root nodes are not allowed in a treemap.",{node:n,property:"item"}))}},wS={parser:{TokenBuilder:xt(()=>new Pze,"TokenBuilder"),ValueConverter:xt(()=>new Fze,"ValueConverter")},validation:{TreemapValidator:xt(()=>new $ze,"TreemapValidator")}};o(kS,"createTreemapServices");xt(kS,"createTreemapServices")});var the={};ur(the,{InfoModule:()=>fS,createInfoServices:()=>dS});var rhe=N(()=>{"use strict";TO();Va()});var nhe={};ur(nhe,{PacketModule:()=>pS,createPacketServices:()=>mS});var ihe=N(()=>{"use strict";wO();Va()});var ahe={};ur(ahe,{PieModule:()=>gS,createPieServices:()=>yS});var she=N(()=>{"use strict";kO();Va()});var ohe={};ur(ohe,{ArchitectureModule:()=>vS,createArchitectureServices:()=>xS});var lhe=N(()=>{"use strict";EO();Va()});var che={};ur(che,{GitGraphModule:()=>uS,createGitGraphServices:()=>hS});var uhe=N(()=>{"use strict";bO();Va()});var hhe={};ur(hhe,{RadarModule:()=>bS,createRadarServices:()=>TS});var fhe=N(()=>{"use strict";SO();Va()});var dhe={};ur(dhe,{TreemapModule:()=>wS,createTreemapServices:()=>kS});var phe=N(()=>{"use strict";CO();Va()});async function vs(t,e){let r=zze[t];if(!r)throw new Error(`Unknown diagram type: ${t}`);Qu[t]||await r();let i=Qu[t].parse(e);if(i.lexerErrors.length>0||i.parserErrors.length>0)throw new Gze(i);return i.value}var Qu,zze,Gze,bf=N(()=>{"use strict";bO();TO();wO();kO();EO();SO();CO();Va();Qu={},zze={info:xt(async()=>{let{createInfoServices:t}=await Promise.resolve().then(()=>(rhe(),the)),e=t().Info.parser.LangiumParser;Qu.info=e},"info"),packet:xt(async()=>{let{createPacketServices:t}=await Promise.resolve().then(()=>(ihe(),nhe)),e=t().Packet.parser.LangiumParser;Qu.packet=e},"packet"),pie:xt(async()=>{let{createPieServices:t}=await Promise.resolve().then(()=>(she(),ahe)),e=t().Pie.parser.LangiumParser;Qu.pie=e},"pie"),architecture:xt(async()=>{let{createArchitectureServices:t}=await Promise.resolve().then(()=>(lhe(),ohe)),e=t().Architecture.parser.LangiumParser;Qu.architecture=e},"architecture"),gitGraph:xt(async()=>{let{createGitGraphServices:t}=await Promise.resolve().then(()=>(uhe(),che)),e=t().GitGraph.parser.LangiumParser;Qu.gitGraph=e},"gitGraph"),radar:xt(async()=>{let{createRadarServices:t}=await Promise.resolve().then(()=>(fhe(),hhe)),e=t().Radar.parser.LangiumParser;Qu.radar=e},"radar"),treemap:xt(async()=>{let{createTreemapServices:t}=await Promise.resolve().then(()=>(phe(),dhe)),e=t().Treemap.parser.LangiumParser;Qu.treemap=e},"treemap")};o(vs,"parse");xt(vs,"parse");Gze=class extends Error{static{o(this,"MermaidParseError")}constructor(t){let e=t.lexerErrors.map(n=>n.message).join(` +`),r=t.parserErrors.map(n=>n.message).join(` +`);super(`Parsing failed: ${e} ${r}`),this.result=t}static{xt(this,"MermaidParseError")}}});function Jo(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}var Mp=N(()=>{"use strict";o(Jo,"populateCommonDb")});var Kr,ES=N(()=>{"use strict";Kr={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4}});var Tf,SS=N(()=>{"use strict";Tf=class{constructor(e){this.init=e;this.records=this.init()}static{o(this,"ImperativeState")}reset(){this.records=this.init()}}});function AO(){return R9({length:7})}function Uze(t,e){let r=Object.create(null);return t.reduce((n,i)=>{let a=e(i);return r[a]||(r[a]=!0,n.push(i)),n},[])}function mhe(t,e,r){let n=t.indexOf(e);n===-1?t.push(r):t.splice(n,1,r)}function yhe(t){let e=t.reduce((i,a)=>i.seq>a.seq?i:a,t[0]),r="";t.forEach(function(i){i===e?r+=" *":r+=" |"});let n=[r,e.id,e.seq];for(let i in At.records.branches)At.records.branches.get(i)===e.id&&n.push(i);if(X.debug(n.join(" ")),e.parents&&e.parents.length==2&&e.parents[0]&&e.parents[1]){let i=At.records.commits.get(e.parents[0]);mhe(t,e,i),e.parents[1]&&t.push(At.records.commits.get(e.parents[1]))}else{if(e.parents.length==0)return;if(e.parents[0]){let i=At.records.commits.get(e.parents[0]);mhe(t,e,i)}}t=Uze(t,i=>i.id),yhe(t)}var Vze,Ip,At,Hze,Wze,qze,Yze,Xze,jze,Kze,ghe,Qze,Zze,Jze,eGe,tGe,vhe,rGe,nGe,iGe,CS,_O=N(()=>{"use strict";yt();er();mi();pr();ci();ES();SS();_a();Vze=or.gitGraph,Ip=o(()=>$n({...Vze,...tr().gitGraph}),"getConfig"),At=new Tf(()=>{let t=Ip(),e=t.mainBranchName,r=t.mainBranchOrder;return{mainBranchName:e,commits:new Map,head:null,branchConfig:new Map([[e,{name:e,order:r}]]),branches:new Map([[e,null]]),currBranch:e,direction:"LR",seq:0,options:{}}});o(AO,"getID");o(Uze,"uniqBy");Hze=o(function(t){At.records.direction=t},"setDirection"),Wze=o(function(t){X.debug("options str",t),t=t?.trim(),t=t||"{}";try{At.records.options=JSON.parse(t)}catch(e){X.error("error while parsing gitGraph options",e.message)}},"setOptions"),qze=o(function(){return At.records.options},"getOptions"),Yze=o(function(t){let e=t.msg,r=t.id,n=t.type,i=t.tags;X.info("commit",e,r,n,i),X.debug("Entering commit:",e,r,n,i);let a=Ip();r=Ze.sanitizeText(r,a),e=Ze.sanitizeText(e,a),i=i?.map(l=>Ze.sanitizeText(l,a));let s={id:r||At.records.seq+"-"+AO(),message:e,seq:At.records.seq++,type:n??Kr.NORMAL,tags:i??[],parents:At.records.head==null?[]:[At.records.head.id],branch:At.records.currBranch};At.records.head=s,X.info("main branch",a.mainBranchName),At.records.commits.has(s.id)&&X.warn(`Commit ID ${s.id} already exists`),At.records.commits.set(s.id,s),At.records.branches.set(At.records.currBranch,s.id),X.debug("in pushCommit "+s.id)},"commit"),Xze=o(function(t){let e=t.name,r=t.order;if(e=Ze.sanitizeText(e,Ip()),At.records.branches.has(e))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${e}")`);At.records.branches.set(e,At.records.head!=null?At.records.head.id:null),At.records.branchConfig.set(e,{name:e,order:r}),ghe(e),X.debug("in createBranch")},"branch"),jze=o(t=>{let e=t.branch,r=t.id,n=t.type,i=t.tags,a=Ip();e=Ze.sanitizeText(e,a),r&&(r=Ze.sanitizeText(r,a));let s=At.records.branches.get(At.records.currBranch),l=At.records.branches.get(e),u=s?At.records.commits.get(s):void 0,h=l?At.records.commits.get(l):void 0;if(u&&h&&u.branch===e)throw new Error(`Cannot merge branch '${e}' into itself.`);if(At.records.currBranch===e){let p=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(u===void 0||!u){let p=new Error(`Incorrect usage of "merge". Current branch (${At.records.currBranch})has no commits`);throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["commit"]},p}if(!At.records.branches.has(e)){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") does not exist");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:[`branch ${e}`]},p}if(h===void 0||!h){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") has no commits");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:['"commit"']},p}if(u===h){let p=new Error('Incorrect usage of "merge". Both branches have same head');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(r&&At.records.commits.has(r)){let p=new Error('Incorrect usage of "merge". Commit with id:'+r+" already exists, use different custom id");throw p.hash={text:`merge ${e} ${r} ${n} ${i?.join(" ")}`,token:`merge ${e} ${r} ${n} ${i?.join(" ")}`,expected:[`merge ${e} ${r}_UNIQUE ${n} ${i?.join(" ")}`]},p}let f=l||"",d={id:r||`${At.records.seq}-${AO()}`,message:`merged branch ${e} into ${At.records.currBranch}`,seq:At.records.seq++,parents:At.records.head==null?[]:[At.records.head.id,f],branch:At.records.currBranch,type:Kr.MERGE,customType:n,customId:!!r,tags:i??[]};At.records.head=d,At.records.commits.set(d.id,d),At.records.branches.set(At.records.currBranch,d.id),X.debug(At.records.branches),X.debug("in mergeBranch")},"merge"),Kze=o(function(t){let e=t.id,r=t.targetId,n=t.tags,i=t.parent;X.debug("Entering cherryPick:",e,r,n);let a=Ip();if(e=Ze.sanitizeText(e,a),r=Ze.sanitizeText(r,a),n=n?.map(u=>Ze.sanitizeText(u,a)),i=Ze.sanitizeText(i,a),!e||!At.records.commits.has(e)){let u=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw u.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},u}let s=At.records.commits.get(e);if(s===void 0||!s)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(i&&!(Array.isArray(s.parents)&&s.parents.includes(i)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");let l=s.branch;if(s.type===Kr.MERGE&&!i)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!r||!At.records.commits.has(r)){if(l===At.records.currBranch){let d=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let u=At.records.branches.get(At.records.currBranch);if(u===void 0||!u){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${At.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let h=At.records.commits.get(u);if(h===void 0||!h){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${At.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let f={id:At.records.seq+"-"+AO(),message:`cherry-picked ${s?.message} into ${At.records.currBranch}`,seq:At.records.seq++,parents:At.records.head==null?[]:[At.records.head.id,s.id],branch:At.records.currBranch,type:Kr.CHERRY_PICK,tags:n?n.filter(Boolean):[`cherry-pick:${s.id}${s.type===Kr.MERGE?`|parent:${i}`:""}`]};At.records.head=f,At.records.commits.set(f.id,f),At.records.branches.set(At.records.currBranch,f.id),X.debug(At.records.branches),X.debug("in cherryPick")}},"cherryPick"),ghe=o(function(t){if(t=Ze.sanitizeText(t,Ip()),At.records.branches.has(t)){At.records.currBranch=t;let e=At.records.branches.get(At.records.currBranch);e===void 0||!e?At.records.head=null:At.records.head=At.records.commits.get(e)??null}else{let e=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${t}")`);throw e.hash={text:`checkout ${t}`,token:`checkout ${t}`,expected:[`branch ${t}`]},e}},"checkout");o(mhe,"upsert");o(yhe,"prettyPrintCommitHistory");Qze=o(function(){X.debug(At.records.commits);let t=vhe()[0];yhe([t])},"prettyPrint"),Zze=o(function(){At.reset(),kr()},"clear"),Jze=o(function(){return[...At.records.branchConfig.values()].map((e,r)=>e.order!==null&&e.order!==void 0?e:{...e,order:parseFloat(`0.${r}`)}).sort((e,r)=>(e.order??0)-(r.order??0)).map(({name:e})=>({name:e}))},"getBranchesAsObjArray"),eGe=o(function(){return At.records.branches},"getBranches"),tGe=o(function(){return At.records.commits},"getCommits"),vhe=o(function(){let t=[...At.records.commits.values()];return t.forEach(function(e){X.debug(e.id)}),t.sort((e,r)=>e.seq-r.seq),t},"getCommitsArray"),rGe=o(function(){return At.records.currBranch},"getCurrentBranch"),nGe=o(function(){return At.records.direction},"getDirection"),iGe=o(function(){return At.records.head},"getHead"),CS={commitType:Kr,getConfig:Ip,setDirection:Hze,setOptions:Wze,getOptions:qze,commit:Yze,branch:Xze,merge:jze,cherryPick:Kze,checkout:ghe,prettyPrint:Qze,clear:Zze,getBranchesAsObjArray:Jze,getBranches:eGe,getCommits:tGe,getCommitsArray:vhe,getCurrentBranch:rGe,getDirection:nGe,getHead:iGe,setAccTitle:Ar,getAccTitle:Dr,getAccDescription:Rr,setAccDescription:Lr,setDiagramTitle:Or,getDiagramTitle:Nr}});var aGe,sGe,oGe,lGe,cGe,uGe,hGe,xhe,bhe=N(()=>{"use strict";bf();yt();Mp();_O();ES();aGe=o((t,e)=>{Jo(t,e),t.dir&&e.setDirection(t.dir);for(let r of t.statements)sGe(r,e)},"populate"),sGe=o((t,e)=>{let n={Commit:o(i=>e.commit(oGe(i)),"Commit"),Branch:o(i=>e.branch(lGe(i)),"Branch"),Merge:o(i=>e.merge(cGe(i)),"Merge"),Checkout:o(i=>e.checkout(uGe(i)),"Checkout"),CherryPicking:o(i=>e.cherryPick(hGe(i)),"CherryPicking")}[t.$type];n?n(t):X.error(`Unknown statement type: ${t.$type}`)},"parseStatement"),oGe=o(t=>({id:t.id,msg:t.message??"",type:t.type!==void 0?Kr[t.type]:Kr.NORMAL,tags:t.tags??void 0}),"parseCommit"),lGe=o(t=>({name:t.name,order:t.order??0}),"parseBranch"),cGe=o(t=>({branch:t.branch,id:t.id??"",type:t.type!==void 0?Kr[t.type]:void 0,tags:t.tags??void 0}),"parseMerge"),uGe=o(t=>t.branch,"parseCheckout"),hGe=o(t=>({id:t.id,targetId:"",tags:t.tags?.length===0?void 0:t.tags,parent:t.parent}),"parseCherryPicking"),xhe={parse:o(async t=>{let e=await vs("gitGraph",t);X.debug(e),aGe(e,CS)},"parse")}});var fGe,el,kf,Ef,Wc,Zu,Op,Hs,Ws,AS,Eb,_S,wf,Fr,dGe,whe,khe,pGe,mGe,gGe,yGe,vGe,xGe,bGe,TGe,wGe,kGe,EGe,SGe,The,CGe,Sb,AGe,_Ge,DGe,LGe,RGe,Ehe,She=N(()=>{"use strict";fr();Gt();yt();er();ES();fGe=me(),el=fGe?.gitGraph,kf=10,Ef=40,Wc=4,Zu=2,Op=8,Hs=new Map,Ws=new Map,AS=30,Eb=new Map,_S=[],wf=0,Fr="LR",dGe=o(()=>{Hs.clear(),Ws.clear(),Eb.clear(),wf=0,_S=[],Fr="LR"},"clear"),whe=o(t=>{let e=document.createElementNS("http://www.w3.org/2000/svg","text");return(typeof t=="string"?t.split(/\\n|\n|/gi):t).forEach(n=>{let i=document.createElementNS("http://www.w3.org/2000/svg","tspan");i.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),i.setAttribute("dy","1em"),i.setAttribute("x","0"),i.setAttribute("class","row"),i.textContent=n.trim(),e.appendChild(i)}),e},"drawText"),khe=o(t=>{let e,r,n;return Fr==="BT"?(r=o((i,a)=>i<=a,"comparisonFunc"),n=1/0):(r=o((i,a)=>i>=a,"comparisonFunc"),n=0),t.forEach(i=>{let a=Fr==="TB"||Fr=="BT"?Ws.get(i)?.y:Ws.get(i)?.x;a!==void 0&&r(a,n)&&(e=i,n=a)}),e},"findClosestParent"),pGe=o(t=>{let e="",r=1/0;return t.forEach(n=>{let i=Ws.get(n).y;i<=r&&(e=n,r=i)}),e||void 0},"findClosestParentBT"),mGe=o((t,e,r)=>{let n=r,i=r,a=[];t.forEach(s=>{let l=e.get(s);if(!l)throw new Error(`Commit not found for key ${s}`);l.parents.length?(n=yGe(l),i=Math.max(n,i)):a.push(l),vGe(l,n)}),n=i,a.forEach(s=>{xGe(s,n,r)}),t.forEach(s=>{let l=e.get(s);if(l?.parents.length){let u=pGe(l.parents);n=Ws.get(u).y-Ef,n<=i&&(i=n);let h=Hs.get(l.branch).pos,f=n-kf;Ws.set(l.id,{x:h,y:f})}})},"setParallelBTPos"),gGe=o(t=>{let e=khe(t.parents.filter(n=>n!==null));if(!e)throw new Error(`Closest parent not found for commit ${t.id}`);let r=Ws.get(e)?.y;if(r===void 0)throw new Error(`Closest parent position not found for commit ${t.id}`);return r},"findClosestParentPos"),yGe=o(t=>gGe(t)+Ef,"calculateCommitPosition"),vGe=o((t,e)=>{let r=Hs.get(t.branch);if(!r)throw new Error(`Branch not found for commit ${t.id}`);let n=r.pos,i=e+kf;return Ws.set(t.id,{x:n,y:i}),{x:n,y:i}},"setCommitPosition"),xGe=o((t,e,r)=>{let n=Hs.get(t.branch);if(!n)throw new Error(`Branch not found for commit ${t.id}`);let i=e+r,a=n.pos;Ws.set(t.id,{x:a,y:i})},"setRootPosition"),bGe=o((t,e,r,n,i,a)=>{if(a===Kr.HIGHLIGHT)t.append("rect").attr("x",r.x-10).attr("y",r.y-10).attr("width",20).attr("height",20).attr("class",`commit ${e.id} commit-highlight${i%Op} ${n}-outer`),t.append("rect").attr("x",r.x-6).attr("y",r.y-6).attr("width",12).attr("height",12).attr("class",`commit ${e.id} commit${i%Op} ${n}-inner`);else if(a===Kr.CHERRY_PICK)t.append("circle").attr("cx",r.x).attr("cy",r.y).attr("r",10).attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x-3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x+3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x+3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x-3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`);else{let s=t.append("circle");if(s.attr("cx",r.x),s.attr("cy",r.y),s.attr("r",e.type===Kr.MERGE?9:10),s.attr("class",`commit ${e.id} commit${i%Op}`),a===Kr.MERGE){let l=t.append("circle");l.attr("cx",r.x),l.attr("cy",r.y),l.attr("r",6),l.attr("class",`commit ${n} ${e.id} commit${i%Op}`)}a===Kr.REVERSE&&t.append("path").attr("d",`M ${r.x-5},${r.y-5}L${r.x+5},${r.y+5}M${r.x-5},${r.y+5}L${r.x+5},${r.y-5}`).attr("class",`commit ${n} ${e.id} commit${i%Op}`)}},"drawCommitBullet"),TGe=o((t,e,r,n)=>{if(e.type!==Kr.CHERRY_PICK&&(e.customId&&e.type===Kr.MERGE||e.type!==Kr.MERGE)&&el?.showCommitLabel){let i=t.append("g"),a=i.insert("rect").attr("class","commit-label-bkg"),s=i.append("text").attr("x",n).attr("y",r.y+25).attr("class","commit-label").text(e.id),l=s.node()?.getBBox();if(l&&(a.attr("x",r.posWithOffset-l.width/2-Zu).attr("y",r.y+13.5).attr("width",l.width+2*Zu).attr("height",l.height+2*Zu),Fr==="TB"||Fr==="BT"?(a.attr("x",r.x-(l.width+4*Wc+5)).attr("y",r.y-12),s.attr("x",r.x-(l.width+4*Wc)).attr("y",r.y+l.height-12)):s.attr("x",r.posWithOffset-l.width/2),el.rotateCommitLabel))if(Fr==="TB"||Fr==="BT")s.attr("transform","rotate(-45, "+r.x+", "+r.y+")"),a.attr("transform","rotate(-45, "+r.x+", "+r.y+")");else{let u=-7.5-(l.width+10)/25*9.5,h=10+l.width/25*8.5;i.attr("transform","translate("+u+", "+h+") rotate(-45, "+n+", "+r.y+")")}}},"drawCommitLabel"),wGe=o((t,e,r,n)=>{if(e.tags.length>0){let i=0,a=0,s=0,l=[];for(let u of e.tags.reverse()){let h=t.insert("polygon"),f=t.append("circle"),d=t.append("text").attr("y",r.y-16-i).attr("class","tag-label").text(u),p=d.node()?.getBBox();if(!p)throw new Error("Tag bbox not found");a=Math.max(a,p.width),s=Math.max(s,p.height),d.attr("x",r.posWithOffset-p.width/2),l.push({tag:d,hole:f,rect:h,yOffset:i}),i+=20}for(let{tag:u,hole:h,rect:f,yOffset:d}of l){let p=s/2,m=r.y-19.2-d;if(f.attr("class","tag-label-bkg").attr("points",` + ${n-a/2-Wc/2},${m+Zu} + ${n-a/2-Wc/2},${m-Zu} + ${r.posWithOffset-a/2-Wc},${m-p-Zu} + ${r.posWithOffset+a/2+Wc},${m-p-Zu} + ${r.posWithOffset+a/2+Wc},${m+p+Zu} + ${r.posWithOffset-a/2-Wc},${m+p+Zu}`),h.attr("cy",m).attr("cx",n-a/2+Wc/2).attr("r",1.5).attr("class","tag-hole"),Fr==="TB"||Fr==="BT"){let g=n+d;f.attr("class","tag-label-bkg").attr("points",` + ${r.x},${g+2} + ${r.x},${g-2} + ${r.x+kf},${g-p-2} + ${r.x+kf+a+4},${g-p-2} + ${r.x+kf+a+4},${g+p+2} + ${r.x+kf},${g+p+2}`).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),h.attr("cx",r.x+Wc/2).attr("cy",g).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),u.attr("x",r.x+5).attr("y",g+3).attr("transform","translate(14,14) rotate(45, "+r.x+","+n+")")}}}},"drawCommitTags"),kGe=o(t=>{switch(t.customType??t.type){case Kr.NORMAL:return"commit-normal";case Kr.REVERSE:return"commit-reverse";case Kr.HIGHLIGHT:return"commit-highlight";case Kr.MERGE:return"commit-merge";case Kr.CHERRY_PICK:return"commit-cherry-pick";default:return"commit-normal"}},"getCommitClassType"),EGe=o((t,e,r,n)=>{let i={x:0,y:0};if(t.parents.length>0){let a=khe(t.parents);if(a){let s=n.get(a)??i;return e==="TB"?s.y+Ef:e==="BT"?(n.get(t.id)??i).y-Ef:s.x+Ef}}else return e==="TB"?AS:e==="BT"?(n.get(t.id)??i).y-Ef:0;return 0},"calculatePosition"),SGe=o((t,e,r)=>{let n=Fr==="BT"&&r?e:e+kf,i=Fr==="TB"||Fr==="BT"?n:Hs.get(t.branch)?.pos,a=Fr==="TB"||Fr==="BT"?Hs.get(t.branch)?.pos:n;if(a===void 0||i===void 0)throw new Error(`Position were undefined for commit ${t.id}`);return{x:a,y:i,posWithOffset:n}},"getCommitPosition"),The=o((t,e,r)=>{if(!el)throw new Error("GitGraph config not found");let n=t.append("g").attr("class","commit-bullets"),i=t.append("g").attr("class","commit-labels"),a=Fr==="TB"||Fr==="BT"?AS:0,s=[...e.keys()],l=el?.parallelCommits??!1,u=o((f,d)=>{let p=e.get(f)?.seq,m=e.get(d)?.seq;return p!==void 0&&m!==void 0?p-m:0},"sortKeys"),h=s.sort(u);Fr==="BT"&&(l&&mGe(h,e,a),h=h.reverse()),h.forEach(f=>{let d=e.get(f);if(!d)throw new Error(`Commit not found for key ${f}`);l&&(a=EGe(d,Fr,a,Ws));let p=SGe(d,a,l);if(r){let m=kGe(d),g=d.customType??d.type,y=Hs.get(d.branch)?.index??0;bGe(n,d,p,m,y,g),TGe(i,d,p,a),wGe(i,d,p,a)}Fr==="TB"||Fr==="BT"?Ws.set(d.id,{x:p.x,y:p.posWithOffset}):Ws.set(d.id,{x:p.posWithOffset,y:p.y}),a=Fr==="BT"&&l?a+Ef:a+Ef+kf,a>wf&&(wf=a)})},"drawCommits"),CGe=o((t,e,r,n,i)=>{let s=(Fr==="TB"||Fr==="BT"?r.xh.branch===s,"isOnBranchToGetCurve"),u=o(h=>h.seq>t.seq&&h.sequ(h)&&l(h))},"shouldRerouteArrow"),Sb=o((t,e,r=0)=>{let n=t+Math.abs(t-e)/2;if(r>5)return n;if(_S.every(s=>Math.abs(s-n)>=10))return _S.push(n),n;let a=Math.abs(t-e);return Sb(t,e-a/5,r+1)},"findLane"),AGe=o((t,e,r,n)=>{let i=Ws.get(e.id),a=Ws.get(r.id);if(i===void 0||a===void 0)throw new Error(`Commit positions not found for commits ${e.id} and ${r.id}`);let s=CGe(e,r,i,a,n),l="",u="",h=0,f=0,d=Hs.get(r.branch)?.index;r.type===Kr.MERGE&&e.id!==r.parents[0]&&(d=Hs.get(e.branch)?.index);let p;if(s){l="A 10 10, 0, 0, 0,",u="A 10 10, 0, 0, 1,",h=10,f=10;let m=i.ya.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y-h} ${u} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x+h} ${i.y} ${l} ${a.x} ${i.y+f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):Fr==="BT"?(i.xa.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${l} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):(i.ya.y&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${u} ${i.x+f} ${a.y} L ${a.x} ${a.y}`),i.y===a.y&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`));if(p===void 0)throw new Error("Line definition not found");t.append("path").attr("d",p).attr("class","arrow arrow"+d%Op)},"drawArrow"),_Ge=o((t,e)=>{let r=t.append("g").attr("class","commit-arrows");[...e.keys()].forEach(n=>{let i=e.get(n);i.parents&&i.parents.length>0&&i.parents.forEach(a=>{AGe(r,e.get(a),i,e)})})},"drawArrows"),DGe=o((t,e)=>{let r=t.append("g");e.forEach((n,i)=>{let a=i%Op,s=Hs.get(n.name)?.pos;if(s===void 0)throw new Error(`Position not found for branch ${n.name}`);let l=r.append("line");l.attr("x1",0),l.attr("y1",s),l.attr("x2",wf),l.attr("y2",s),l.attr("class","branch branch"+a),Fr==="TB"?(l.attr("y1",AS),l.attr("x1",s),l.attr("y2",wf),l.attr("x2",s)):Fr==="BT"&&(l.attr("y1",wf),l.attr("x1",s),l.attr("y2",AS),l.attr("x2",s)),_S.push(s);let u=n.name,h=whe(u),f=r.insert("rect"),p=r.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+a);p.node().appendChild(h);let m=h.getBBox();f.attr("class","branchLabelBkg label"+a).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(el?.rotateCommitLabel===!0?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),p.attr("transform","translate("+(-m.width-14-(el?.rotateCommitLabel===!0?30:0))+", "+(s-m.height/2-1)+")"),Fr==="TB"?(f.attr("x",s-m.width/2-10).attr("y",0),p.attr("transform","translate("+(s-m.width/2-5)+", 0)")):Fr==="BT"?(f.attr("x",s-m.width/2-10).attr("y",wf),p.attr("transform","translate("+(s-m.width/2-5)+", "+wf+")")):f.attr("transform","translate(-19, "+(s-m.height/2)+")")})},"drawBranches"),LGe=o(function(t,e,r,n,i){return Hs.set(t,{pos:e,index:r}),e+=50+(i?40:0)+(Fr==="TB"||Fr==="BT"?n.width/2:0),e},"setBranchPosition"),RGe=o(function(t,e,r,n){if(dGe(),X.debug("in gitgraph renderer",t+` +`,"id:",e,r),!el)throw new Error("GitGraph config not found");let i=el.rotateCommitLabel??!1,a=n.db;Eb=a.getCommits();let s=a.getBranchesAsObjArray();Fr=a.getDirection();let l=Ge(`[id="${e}"]`),u=0;s.forEach((h,f)=>{let d=whe(h.name),p=l.append("g"),m=p.insert("g").attr("class","branchLabel"),g=m.insert("g").attr("class","label branch-label");g.node()?.appendChild(d);let y=d.getBBox();u=LGe(h.name,u,f,y,i),g.remove(),m.remove(),p.remove()}),The(l,Eb,!1),el.showBranches&&DGe(l,s),_Ge(l,Eb),The(l,Eb,!0),Vt.insertTitle(l,"gitTitleText",el.titleTopMargin??0,a.getDiagramTitle()),AA(void 0,l,el.diagramPadding,el.useMaxWidth)},"draw"),Ehe={draw:RGe}});var NGe,Che,Ahe=N(()=>{"use strict";NGe=o(t=>` + .commit-id, + .commit-msg, + .branch-label { + fill: lightgrey; + color: lightgrey; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } + ${[0,1,2,3,4,5,6,7].map(e=>` + .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; } + .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; } + .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; } + .label${e} { fill: ${t["git"+e]}; } + .arrow${e} { stroke: ${t["git"+e]}; } + `).join(` +`)} + + .branch { + stroke-width: 1; + stroke: ${t.lineColor}; + stroke-dasharray: 2; + } + .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};} + .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; } + .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};} + .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; } + .tag-hole { fill: ${t.textColor}; } + + .commit-merge { + stroke: ${t.primaryColor}; + fill: ${t.primaryColor}; + } + .commit-reverse { + stroke: ${t.primaryColor}; + fill: ${t.primaryColor}; + stroke-width: 3; + } + .commit-highlight-outer { + } + .commit-highlight-inner { + stroke: ${t.primaryColor}; + fill: ${t.primaryColor}; + } + + .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.textColor}; + } +`,"getStyles"),Che=NGe});var _he={};ur(_he,{diagram:()=>MGe});var MGe,Dhe=N(()=>{"use strict";bhe();_O();She();Ahe();MGe={parser:xhe,db:CS,renderer:Ehe,styles:Che}});var DO,Nhe,Mhe=N(()=>{"use strict";DO=function(){var t=o(function(L,A,I,M){for(I=I||{},M=L.length;M--;I[L[M]]=A);return I},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],r=[1,26],n=[1,27],i=[1,28],a=[1,29],s=[1,30],l=[1,31],u=[1,32],h=[1,33],f=[1,34],d=[1,9],p=[1,10],m=[1,11],g=[1,12],y=[1,13],v=[1,14],x=[1,15],b=[1,16],T=[1,19],S=[1,20],w=[1,21],E=[1,22],_=[1,23],C=[1,25],D=[1,35],O={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:o(function(A,I,M,P,B,F,z){var $=F.length-1;switch(B){case 1:return F[$-1];case 2:this.$=[];break;case 3:F[$-1].push(F[$]),this.$=F[$-1];break;case 4:case 5:this.$=F[$];break;case 6:case 7:this.$=[];break;case 8:P.setWeekday("monday");break;case 9:P.setWeekday("tuesday");break;case 10:P.setWeekday("wednesday");break;case 11:P.setWeekday("thursday");break;case 12:P.setWeekday("friday");break;case 13:P.setWeekday("saturday");break;case 14:P.setWeekday("sunday");break;case 15:P.setWeekend("friday");break;case 16:P.setWeekend("saturday");break;case 17:P.setDateFormat(F[$].substr(11)),this.$=F[$].substr(11);break;case 18:P.enableInclusiveEndDates(),this.$=F[$].substr(18);break;case 19:P.TopAxis(),this.$=F[$].substr(8);break;case 20:P.setAxisFormat(F[$].substr(11)),this.$=F[$].substr(11);break;case 21:P.setTickInterval(F[$].substr(13)),this.$=F[$].substr(13);break;case 22:P.setExcludes(F[$].substr(9)),this.$=F[$].substr(9);break;case 23:P.setIncludes(F[$].substr(9)),this.$=F[$].substr(9);break;case 24:P.setTodayMarker(F[$].substr(12)),this.$=F[$].substr(12);break;case 27:P.setDiagramTitle(F[$].substr(6)),this.$=F[$].substr(6);break;case 28:this.$=F[$].trim(),P.setAccTitle(this.$);break;case 29:case 30:this.$=F[$].trim(),P.setAccDescription(this.$);break;case 31:P.addSection(F[$].substr(8)),this.$=F[$].substr(8);break;case 33:P.addTask(F[$-1],F[$]),this.$="task";break;case 34:this.$=F[$-1],P.setClickEvent(F[$-1],F[$],null);break;case 35:this.$=F[$-2],P.setClickEvent(F[$-2],F[$-1],F[$]);break;case 36:this.$=F[$-2],P.setClickEvent(F[$-2],F[$-1],null),P.setLink(F[$-2],F[$]);break;case 37:this.$=F[$-3],P.setClickEvent(F[$-3],F[$-2],F[$-1]),P.setLink(F[$-3],F[$]);break;case 38:this.$=F[$-2],P.setClickEvent(F[$-2],F[$],null),P.setLink(F[$-2],F[$-1]);break;case 39:this.$=F[$-3],P.setClickEvent(F[$-3],F[$-1],F[$]),P.setLink(F[$-3],F[$-2]);break;case 40:this.$=F[$-1],P.setLink(F[$-1],F[$]);break;case 41:case 47:this.$=F[$-1]+" "+F[$];break;case 42:case 43:case 45:this.$=F[$-2]+" "+F[$-1]+" "+F[$];break;case 44:case 46:this.$=F[$-3]+" "+F[$-2]+" "+F[$-1]+" "+F[$];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:T,31:S,33:w,35:E,36:_,37:24,38:C,40:D},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:T,31:S,33:w,35:E,36:_,37:24,38:C,40:D},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:o(function(A,I){if(I.recoverable)this.trace(A);else{var M=new Error(A);throw M.hash=I,M}},"parseError"),parse:o(function(A){var I=this,M=[0],P=[],B=[null],F=[],z=this.table,$="",U=0,K=0,ee=0,Y=2,ce=1,Z=F.slice.call(arguments,1),ue=Object.create(this.lexer),Q={yy:{}};for(var j in this.yy)Object.prototype.hasOwnProperty.call(this.yy,j)&&(Q.yy[j]=this.yy[j]);ue.setInput(A,Q.yy),Q.yy.lexer=ue,Q.yy.parser=this,typeof ue.yylloc>"u"&&(ue.yylloc={});var ne=ue.yylloc;F.push(ne);var te=ue.options&&ue.options.ranges;typeof Q.yy.parseError=="function"?this.parseError=Q.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function he(q){M.length=M.length-2*q,B.length=B.length-q,F.length=F.length-q}o(he,"popStack");function le(){var q;return q=P.pop()||ue.lex()||ce,typeof q!="number"&&(q instanceof Array&&(P=q,q=P.pop()),q=I.symbols_[q]||q),q}o(le,"lex");for(var J,Se,se,ae,Oe,ye,Be={},He,ze,Le,Ie;;){if(se=M[M.length-1],this.defaultActions[se]?ae=this.defaultActions[se]:((J===null||typeof J>"u")&&(J=le()),ae=z[se]&&z[se][J]),typeof ae>"u"||!ae.length||!ae[0]){var xe="";Ie=[];for(He in z[se])this.terminals_[He]&&He>Y&&Ie.push("'"+this.terminals_[He]+"'");ue.showPosition?xe="Parse error on line "+(U+1)+`: +`+ue.showPosition()+` +Expecting `+Ie.join(", ")+", got '"+(this.terminals_[J]||J)+"'":xe="Parse error on line "+(U+1)+": Unexpected "+(J==ce?"end of input":"'"+(this.terminals_[J]||J)+"'"),this.parseError(xe,{text:ue.match,token:this.terminals_[J]||J,line:ue.yylineno,loc:ne,expected:Ie})}if(ae[0]instanceof Array&&ae.length>1)throw new Error("Parse Error: multiple actions possible at state: "+se+", token: "+J);switch(ae[0]){case 1:M.push(J),B.push(ue.yytext),F.push(ue.yylloc),M.push(ae[1]),J=null,Se?(J=Se,Se=null):(K=ue.yyleng,$=ue.yytext,U=ue.yylineno,ne=ue.yylloc,ee>0&&ee--);break;case 2:if(ze=this.productions_[ae[1]][1],Be.$=B[B.length-ze],Be._$={first_line:F[F.length-(ze||1)].first_line,last_line:F[F.length-1].last_line,first_column:F[F.length-(ze||1)].first_column,last_column:F[F.length-1].last_column},te&&(Be._$.range=[F[F.length-(ze||1)].range[0],F[F.length-1].range[1]]),ye=this.performAction.apply(Be,[$,K,U,Q.yy,ae[1],B,F].concat(Z)),typeof ye<"u")return ye;ze&&(M=M.slice(0,-1*ze*2),B=B.slice(0,-1*ze),F=F.slice(0,-1*ze)),M.push(this.productions_[ae[1]][0]),B.push(Be.$),F.push(Be._$),Le=z[M[M.length-2]][M[M.length-1]],M.push(Le);break;case 3:return!0}}return!0},"parse")},R=function(){var L={EOF:1,parseError:o(function(I,M){if(this.yy.parser)this.yy.parser.parseError(I,M);else throw new Error(I)},"parseError"),setInput:o(function(A,I){return this.yy=I||this.yy||{},this._input=A,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var A=this._input[0];this.yytext+=A,this.yyleng++,this.offset++,this.match+=A,this.matched+=A;var I=A.match(/(?:\r\n?|\n).*/g);return I?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),A},"input"),unput:o(function(A){var I=A.length,M=A.split(/(?:\r\n?|\n)/g);this._input=A+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-I),this.offset-=I;var P=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),M.length-1&&(this.yylineno-=M.length-1);var B=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:M?(M.length===P.length?this.yylloc.first_column:0)+P[P.length-M.length].length-M[0].length:this.yylloc.first_column-I},this.options.ranges&&(this.yylloc.range=[B[0],B[0]+this.yyleng-I]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(A){this.unput(this.match.slice(A))},"less"),pastInput:o(function(){var A=this.matched.substr(0,this.matched.length-this.match.length);return(A.length>20?"...":"")+A.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var A=this.match;return A.length<20&&(A+=this._input.substr(0,20-A.length)),(A.substr(0,20)+(A.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var A=this.pastInput(),I=new Array(A.length+1).join("-");return A+this.upcomingInput()+` +`+I+"^"},"showPosition"),test_match:o(function(A,I){var M,P,B;if(this.options.backtrack_lexer&&(B={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(B.yylloc.range=this.yylloc.range.slice(0))),P=A[0].match(/(?:\r\n?|\n).*/g),P&&(this.yylineno+=P.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:P?P[P.length-1].length-P[P.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+A[0].length},this.yytext+=A[0],this.match+=A[0],this.matches=A,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(A[0].length),this.matched+=A[0],M=this.performAction.call(this,this.yy,this,I,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),M)return M;if(this._backtrack){for(var F in B)this[F]=B[F];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var A,I,M,P;this._more||(this.yytext="",this.match="");for(var B=this._currentRules(),F=0;FI[0].length)){if(I=M,P=F,this.options.backtrack_lexer){if(A=this.test_match(M,B[F]),A!==!1)return A;if(this._backtrack){I=!1;continue}else return!1}else if(!this.options.flex)break}return I?(A=this.test_match(I,B[P]),A!==!1?A:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var I=this.next();return I||this.lex()},"lex"),begin:o(function(I){this.conditionStack.push(I)},"begin"),popState:o(function(){var I=this.conditionStack.length-1;return I>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(I){return I=this.conditionStack.length-1-Math.abs(I||0),I>=0?this.conditionStack[I]:"INITIAL"},"topState"),pushState:o(function(I){this.begin(I)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(I,M,P,B){var F=B;switch(P){case 0:return this.begin("open_directive"),"open_directive";break;case 1:return this.begin("acc_title"),31;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),33;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:break;case 9:break;case 10:break;case 11:return 10;case 12:break;case 13:break;case 14:this.begin("href");break;case 15:this.popState();break;case 16:return 43;case 17:this.begin("callbackname");break;case 18:this.popState();break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 41;case 21:this.popState();break;case 22:return 42;case 23:this.begin("click");break;case 24:this.popState();break;case 25:return 40;case 26:return 4;case 27:return 22;case 28:return 23;case 29:return 24;case 30:return 25;case 31:return 26;case 32:return 28;case 33:return 27;case 34:return 29;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return 20;case 43:return 21;case 44:return"date";case 45:return 30;case 46:return"accDescription";case 47:return 36;case 48:return 38;case 49:return 39;case 50:return":";case 51:return 6;case 52:return"INVALID"}},"anonymous"),rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:weekend\s+friday\b)/i,/^(?:weekend\s+saturday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],inclusive:!0}}};return L}();O.lexer=R;function k(){this.yy={}}return o(k,"Parser"),k.prototype=O,O.Parser=k,new k}();DO.parser=DO;Nhe=DO});var Ihe=Pi((LO,RO)=>{"use strict";(function(t,e){typeof LO=="object"&&typeof RO<"u"?RO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_isoWeek=e()})(LO,function(){"use strict";var t="day";return function(e,r,n){var i=o(function(l){return l.add(4-l.isoWeekday(),t)},"a"),a=r.prototype;a.isoWeekYear=function(){return i(this).year()},a.isoWeek=function(l){if(!this.$utils().u(l))return this.add(7*(l-this.isoWeek()),t);var u,h,f,d,p=i(this),m=(u=this.isoWeekYear(),h=this.$u,f=(h?n.utc:n)().year(u).startOf("year"),d=4-f.isoWeekday(),f.isoWeekday()>4&&(d+=7),f.add(d,t));return p.diff(m,"week")+1},a.isoWeekday=function(l){return this.$utils().u(l)?this.day()||7:this.day(this.day()%7?l:l-7)};var s=a.startOf;a.startOf=function(l,u){var h=this.$utils(),f=!!h.u(u)||u;return h.p(l)==="isoweek"?f?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(l,u)}}})});var Ohe=Pi((NO,MO)=>{"use strict";(function(t,e){typeof NO=="object"&&typeof MO<"u"?MO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_customParseFormat=e()})(NO,function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,r=/\d/,n=/\d\d/,i=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,s={},l=o(function(g){return(g=+g)+(g>68?1900:2e3)},"a"),u=o(function(g){return function(y){this[g]=+y}},"f"),h=[/[+-]\d\d:?(\d\d)?|Z/,function(g){(this.zone||(this.zone={})).offset=function(y){if(!y||y==="Z")return 0;var v=y.match(/([+-]|\d\d)/g),x=60*v[1]+(+v[2]||0);return x===0?0:v[0]==="+"?-x:x}(g)}],f=o(function(g){var y=s[g];return y&&(y.indexOf?y:y.s.concat(y.f))},"u"),d=o(function(g,y){var v,x=s.meridiem;if(x){for(var b=1;b<=24;b+=1)if(g.indexOf(x(b,0,y))>-1){v=b>12;break}}else v=g===(y?"pm":"PM");return v},"d"),p={A:[a,function(g){this.afternoon=d(g,!1)}],a:[a,function(g){this.afternoon=d(g,!0)}],Q:[r,function(g){this.month=3*(g-1)+1}],S:[r,function(g){this.milliseconds=100*+g}],SS:[n,function(g){this.milliseconds=10*+g}],SSS:[/\d{3}/,function(g){this.milliseconds=+g}],s:[i,u("seconds")],ss:[i,u("seconds")],m:[i,u("minutes")],mm:[i,u("minutes")],H:[i,u("hours")],h:[i,u("hours")],HH:[i,u("hours")],hh:[i,u("hours")],D:[i,u("day")],DD:[n,u("day")],Do:[a,function(g){var y=s.ordinal,v=g.match(/\d+/);if(this.day=v[0],y)for(var x=1;x<=31;x+=1)y(x).replace(/\[|\]/g,"")===g&&(this.day=x)}],w:[i,u("week")],ww:[n,u("week")],M:[i,u("month")],MM:[n,u("month")],MMM:[a,function(g){var y=f("months"),v=(f("monthsShort")||y.map(function(x){return x.slice(0,3)})).indexOf(g)+1;if(v<1)throw new Error;this.month=v%12||v}],MMMM:[a,function(g){var y=f("months").indexOf(g)+1;if(y<1)throw new Error;this.month=y%12||y}],Y:[/[+-]?\d+/,u("year")],YY:[n,function(g){this.year=l(g)}],YYYY:[/\d{4}/,u("year")],Z:h,ZZ:h};function m(g){var y,v;y=g,v=s&&s.formats;for(var x=(g=y.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(C,D,O){var R=O&&O.toUpperCase();return D||v[O]||t[O]||v[R].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(k,L,A){return L||A.slice(1)})})).match(e),b=x.length,T=0;T-1)return new Date((M==="X"?1e3:1)*I);var F=m(M)(I),z=F.year,$=F.month,U=F.day,K=F.hours,ee=F.minutes,Y=F.seconds,ce=F.milliseconds,Z=F.zone,ue=F.week,Q=new Date,j=U||(z||$?1:Q.getDate()),ne=z||Q.getFullYear(),te=0;z&&!$||(te=$>0?$-1:Q.getMonth());var he,le=K||0,J=ee||0,Se=Y||0,se=ce||0;return Z?new Date(Date.UTC(ne,te,j,le,J,Se,se+60*Z.offset*1e3)):P?new Date(Date.UTC(ne,te,j,le,J,Se,se)):(he=new Date(ne,te,j,le,J,Se,se),ue&&(he=B(he).week(ue).toDate()),he)}catch{return new Date("")}}(S,_,w,v),this.init(),R&&R!==!0&&(this.$L=this.locale(R).$L),O&&S!=this.format(_)&&(this.$d=new Date("")),s={}}else if(_ instanceof Array)for(var k=_.length,L=1;L<=k;L+=1){E[1]=_[L-1];var A=v.apply(this,E);if(A.isValid()){this.$d=A.$d,this.$L=A.$L,this.init();break}L===k&&(this.$d=new Date(""))}else b.call(this,T)}}})});var Phe=Pi((IO,OO)=>{"use strict";(function(t,e){typeof IO=="object"&&typeof OO<"u"?OO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_advancedFormat=e()})(IO,function(){"use strict";return function(t,e){var r=e.prototype,n=r.format;r.format=function(i){var a=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var l=this.$utils(),u=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(h){switch(h){case"Q":return Math.ceil((a.$M+1)/3);case"Do":return s.ordinal(a.$D);case"gggg":return a.weekYear();case"GGGG":return a.isoWeekYear();case"wo":return s.ordinal(a.week(),"W");case"w":case"ww":return l.s(a.week(),h==="w"?1:2,"0");case"W":case"WW":return l.s(a.isoWeek(),h==="W"?1:2,"0");case"k":case"kk":return l.s(String(a.$H===0?24:a.$H),h==="k"?1:2,"0");case"X":return Math.floor(a.$d.getTime()/1e3);case"x":return a.$d.getTime();case"z":return"["+a.offsetName()+"]";case"zzz":return"["+a.offsetName("long")+"]";default:return h}});return n.bind(this)(u)}}})});function Zhe(t,e,r){let n=!0;for(;n;)n=!1,r.forEach(function(i){let a="^\\s*"+i+"\\s*$",s=new RegExp(a);t[0].match(s)&&(e[i]=!0,t.shift(1),n=!0)})}var $he,mo,zhe,Ghe,Vhe,Bhe,qc,$O,zO,GO,Cb,Ab,VO,UO,RS,R1,HO,Uhe,WO,_b,qO,YO,NS,PO,BGe,FGe,$Ge,zGe,GGe,VGe,UGe,HGe,WGe,qGe,YGe,XGe,jGe,KGe,QGe,ZGe,JGe,eVe,tVe,rVe,nVe,iVe,aVe,Hhe,sVe,oVe,lVe,Whe,cVe,BO,qhe,Yhe,DS,L1,uVe,hVe,FO,LS,Ui,Xhe,fVe,Pp,dVe,Fhe,pVe,jhe,mVe,Khe,gVe,yVe,Qhe,Jhe=N(()=>{"use strict";$he=Aa(Z0(),1),mo=Aa(U4(),1),zhe=Aa(Ihe(),1),Ghe=Aa(Ohe(),1),Vhe=Aa(Phe(),1);yt();Gt();er();ci();mo.default.extend(zhe.default);mo.default.extend(Ghe.default);mo.default.extend(Vhe.default);Bhe={friday:5,saturday:6},qc="",$O="",GO="",Cb=[],Ab=[],VO=new Map,UO=[],RS=[],R1="",HO="",Uhe=["active","done","crit","milestone","vert"],WO=[],_b=!1,qO=!1,YO="sunday",NS="saturday",PO=0,BGe=o(function(){UO=[],RS=[],R1="",WO=[],DS=0,FO=void 0,LS=void 0,Ui=[],qc="",$O="",HO="",zO=void 0,GO="",Cb=[],Ab=[],_b=!1,qO=!1,PO=0,VO=new Map,kr(),YO="sunday",NS="saturday"},"clear"),FGe=o(function(t){$O=t},"setAxisFormat"),$Ge=o(function(){return $O},"getAxisFormat"),zGe=o(function(t){zO=t},"setTickInterval"),GGe=o(function(){return zO},"getTickInterval"),VGe=o(function(t){GO=t},"setTodayMarker"),UGe=o(function(){return GO},"getTodayMarker"),HGe=o(function(t){qc=t},"setDateFormat"),WGe=o(function(){_b=!0},"enableInclusiveEndDates"),qGe=o(function(){return _b},"endDatesAreInclusive"),YGe=o(function(){qO=!0},"enableTopAxis"),XGe=o(function(){return qO},"topAxisEnabled"),jGe=o(function(t){HO=t},"setDisplayMode"),KGe=o(function(){return HO},"getDisplayMode"),QGe=o(function(){return qc},"getDateFormat"),ZGe=o(function(t){Cb=t.toLowerCase().split(/[\s,]+/)},"setIncludes"),JGe=o(function(){return Cb},"getIncludes"),eVe=o(function(t){Ab=t.toLowerCase().split(/[\s,]+/)},"setExcludes"),tVe=o(function(){return Ab},"getExcludes"),rVe=o(function(){return VO},"getLinks"),nVe=o(function(t){R1=t,UO.push(t)},"addSection"),iVe=o(function(){return UO},"getSections"),aVe=o(function(){let t=Fhe(),e=10,r=0;for(;!t&&r[\d\w- ]+)/.exec(r);if(i!==null){let s=null;for(let u of i.groups.ids.split(" ")){let h=Pp(u);h!==void 0&&(!s||h.endTime>s.endTime)&&(s=h)}if(s)return s.endTime;let l=new Date;return l.setHours(0,0,0,0),l}let a=(0,mo.default)(r,e.trim(),!0);if(a.isValid())return a.toDate();{X.debug("Invalid date:"+r),X.debug("With date format:"+e.trim());let s=new Date(r);if(s===void 0||isNaN(s.getTime())||s.getFullYear()<-1e4||s.getFullYear()>1e4)throw new Error("Invalid date:"+r);return s}},"getStartDate"),qhe=o(function(t){let e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return e!==null?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},"parseDuration"),Yhe=o(function(t,e,r,n=!1){r=r.trim();let a=/^until\s+(?[\d\w- ]+)/.exec(r);if(a!==null){let f=null;for(let p of a.groups.ids.split(" ")){let m=Pp(p);m!==void 0&&(!f||m.startTime{window.open(r,"_self")}),VO.set(n,r))}),jhe(t,"clickable")},"setLink"),jhe=o(function(t,e){t.split(",").forEach(function(r){let n=Pp(r);n!==void 0&&n.classes.push(e)})},"setClass"),mVe=o(function(t,e,r){if(me().securityLevel!=="loose"||e===void 0)return;let n=[];if(typeof r=="string"){n=r.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let a=0;a{Vt.runFunc(e,...n)})},"setClickFun"),Khe=o(function(t,e){WO.push(function(){let r=document.querySelector(`[id="${t}"]`);r!==null&&r.addEventListener("click",function(){e()})},function(){let r=document.querySelector(`[id="${t}-text"]`);r!==null&&r.addEventListener("click",function(){e()})})},"pushFun"),gVe=o(function(t,e,r){t.split(",").forEach(function(n){mVe(n,e,r)}),jhe(t,"clickable")},"setClickEvent"),yVe=o(function(t){WO.forEach(function(e){e(t)})},"bindFunctions"),Qhe={getConfig:o(()=>me().gantt,"getConfig"),clear:BGe,setDateFormat:HGe,getDateFormat:QGe,enableInclusiveEndDates:WGe,endDatesAreInclusive:qGe,enableTopAxis:YGe,topAxisEnabled:XGe,setAxisFormat:FGe,getAxisFormat:$Ge,setTickInterval:zGe,getTickInterval:GGe,setTodayMarker:VGe,getTodayMarker:UGe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,setDisplayMode:jGe,getDisplayMode:KGe,setAccDescription:Lr,getAccDescription:Rr,addSection:nVe,getSections:iVe,getTasks:aVe,addTask:fVe,findTaskById:Pp,addTaskOrg:dVe,setIncludes:ZGe,getIncludes:JGe,setExcludes:eVe,getExcludes:tVe,setClickEvent:gVe,setLink:pVe,getLinks:rVe,bindFunctions:yVe,parseDuration:qhe,isInvalidDate:Hhe,setWeekday:sVe,getWeekday:oVe,setWeekend:lVe};o(Zhe,"getTaskTags")});var MS,vVe,efe,xVe,Ju,bVe,tfe,rfe=N(()=>{"use strict";MS=Aa(U4(),1);yt();fr();pr();Gt();xi();vVe=o(function(){X.debug("Something is calling, setConf, remove the call")},"setConf"),efe={monday:Nh,tuesday:I5,wednesday:O5,thursday:fc,friday:P5,saturday:B5,sunday:wl},xVe=o((t,e)=>{let r=[...t].map(()=>-1/0),n=[...t].sort((a,s)=>a.startTime-s.startTime||a.order-s.order),i=0;for(let a of n)for(let s=0;s=r[s]){r[s]=a.endTime,a.order=s+e,s>i&&(i=s);break}return i},"getMaxIntersections"),bVe=o(function(t,e,r,n){let i=me().gantt,a=me().securityLevel,s;a==="sandbox"&&(s=Ge("#i"+e));let l=a==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=a==="sandbox"?s.nodes()[0].contentDocument:document,h=u.getElementById(e);Ju=h.parentElement.offsetWidth,Ju===void 0&&(Ju=1200),i.useWidth!==void 0&&(Ju=i.useWidth);let f=n.db.getTasks(),d=[];for(let C of f)d.push(C.type);d=_(d);let p={},m=2*i.topPadding;if(n.db.getDisplayMode()==="compact"||i.displayMode==="compact"){let C={};for(let O of f)C[O.section]===void 0?C[O.section]=[O]:C[O.section].push(O);let D=0;for(let O of Object.keys(C)){let R=xVe(C[O],D)+1;D+=R,m+=R*(i.barHeight+i.barGap),p[O]=R}}else{m+=f.length*(i.barHeight+i.barGap);for(let C of d)p[C]=f.filter(D=>D.type===C).length}h.setAttribute("viewBox","0 0 "+Ju+" "+m);let g=l.select(`[id="${e}"]`),y=z5().domain([W3(f,function(C){return C.startTime}),H3(f,function(C){return C.endTime})]).rangeRound([0,Ju-i.leftPadding-i.rightPadding]);function v(C,D){let O=C.startTime,R=D.startTime,k=0;return O>R?k=1:Oz.vert===$.vert?0:z.vert?1:-1);let M=[...new Set(C.map(z=>z.order))].map(z=>C.find($=>$.order===z));g.append("g").selectAll("rect").data(M).enter().append("rect").attr("x",0).attr("y",function(z,$){return $=z.order,$*D+O-2}).attr("width",function(){return A-i.rightPadding/2}).attr("height",D).attr("class",function(z){for(let[$,U]of d.entries())if(z.type===U)return"section section"+$%i.numberSectionStyles;return"section section0"}).enter();let P=g.append("g").selectAll("rect").data(C).enter(),B=n.db.getLinks();if(P.append("rect").attr("id",function(z){return z.id}).attr("rx",3).attr("ry",3).attr("x",function(z){return z.milestone?y(z.startTime)+R+.5*(y(z.endTime)-y(z.startTime))-.5*k:y(z.startTime)+R}).attr("y",function(z,$){return $=z.order,z.vert?i.gridLineStartPadding:$*D+O}).attr("width",function(z){return z.milestone?k:z.vert?.08*k:y(z.renderEndTime||z.endTime)-y(z.startTime)}).attr("height",function(z){return z.vert?f.length*(i.barHeight+i.barGap)+i.barHeight*2:k}).attr("transform-origin",function(z,$){return $=z.order,(y(z.startTime)+R+.5*(y(z.endTime)-y(z.startTime))).toString()+"px "+($*D+O+.5*k).toString()+"px"}).attr("class",function(z){let $="task",U="";z.classes.length>0&&(U=z.classes.join(" "));let K=0;for(let[Y,ce]of d.entries())z.type===ce&&(K=Y%i.numberSectionStyles);let ee="";return z.active?z.crit?ee+=" activeCrit":ee=" active":z.done?z.crit?ee=" doneCrit":ee=" done":z.crit&&(ee+=" crit"),ee.length===0&&(ee=" task"),z.milestone&&(ee=" milestone "+ee),z.vert&&(ee=" vert "+ee),ee+=K,ee+=" "+U,$+ee}),P.append("text").attr("id",function(z){return z.id+"-text"}).text(function(z){return z.task}).attr("font-size",i.fontSize).attr("x",function(z){let $=y(z.startTime),U=y(z.renderEndTime||z.endTime);if(z.milestone&&($+=.5*(y(z.endTime)-y(z.startTime))-.5*k,U=$+k),z.vert)return y(z.startTime)+R;let K=this.getBBox().width;return K>U-$?U+K+1.5*i.leftPadding>A?$+R-5:U+R+5:(U-$)/2+$+R}).attr("y",function(z,$){return z.vert?i.gridLineStartPadding+f.length*(i.barHeight+i.barGap)+60:($=z.order,$*D+i.barHeight/2+(i.fontSize/2-2)+O)}).attr("text-height",k).attr("class",function(z){let $=y(z.startTime),U=y(z.endTime);z.milestone&&(U=$+k);let K=this.getBBox().width,ee="";z.classes.length>0&&(ee=z.classes.join(" "));let Y=0;for(let[Z,ue]of d.entries())z.type===ue&&(Y=Z%i.numberSectionStyles);let ce="";return z.active&&(z.crit?ce="activeCritText"+Y:ce="activeText"+Y),z.done?z.crit?ce=ce+" doneCritText"+Y:ce=ce+" doneText"+Y:z.crit&&(ce=ce+" critText"+Y),z.milestone&&(ce+=" milestoneText"),z.vert&&(ce+=" vertText"),K>U-$?U+K+1.5*i.leftPadding>A?ee+" taskTextOutsideLeft taskTextOutside"+Y+" "+ce:ee+" taskTextOutsideRight taskTextOutside"+Y+" "+ce+" width-"+K:ee+" taskText taskText"+Y+" "+ce+" width-"+K}),me().securityLevel==="sandbox"){let z;z=Ge("#i"+e);let $=z.nodes()[0].contentDocument;P.filter(function(U){return B.has(U.id)}).each(function(U){var K=$.querySelector("#"+U.id),ee=$.querySelector("#"+U.id+"-text");let Y=K.parentNode;var ce=$.createElement("a");ce.setAttribute("xlink:href",B.get(U.id)),ce.setAttribute("target","_top"),Y.appendChild(ce),ce.appendChild(K),ce.appendChild(ee)})}}o(b,"drawRects");function T(C,D,O,R,k,L,A,I){if(A.length===0&&I.length===0)return;let M,P;for(let{startTime:K,endTime:ee}of L)(M===void 0||KP)&&(P=ee);if(!M||!P)return;if((0,MS.default)(P).diff((0,MS.default)(M),"year")>5){X.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");return}let B=n.db.getDateFormat(),F=[],z=null,$=(0,MS.default)(M);for(;$.valueOf()<=P;)n.db.isInvalidDate($,B,A,I)?z?z.end=$:z={start:$,end:$}:z&&(F.push(z),z=null),$=$.add(1,"d");g.append("g").selectAll("rect").data(F).enter().append("rect").attr("id",function(K){return"exclude-"+K.start.format("YYYY-MM-DD")}).attr("x",function(K){return y(K.start)+O}).attr("y",i.gridLineStartPadding).attr("width",function(K){let ee=K.end.add(1,"day");return y(ee)-y(K.start)}).attr("height",k-D-i.gridLineStartPadding).attr("transform-origin",function(K,ee){return(y(K.start)+O+.5*(y(K.end)-y(K.start))).toString()+"px "+(ee*C+.5*k).toString()+"px"}).attr("class","exclude-range")}o(T,"drawExcludeDays");function S(C,D,O,R){let k=zA(y).tickSize(-R+D+i.gridLineStartPadding).tickFormat(Ld(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d")),A=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(n.db.getTickInterval()||i.tickInterval);if(A!==null){let I=A[1],M=A[2],P=n.db.getWeekday()||i.weekday;switch(M){case"millisecond":k.ticks(uc.every(I));break;case"second":k.ticks(eo.every(I));break;case"minute":k.ticks(wu.every(I));break;case"hour":k.ticks(ku.every(I));break;case"day":k.ticks(Ro.every(I));break;case"week":k.ticks(efe[P].every(I));break;case"month":k.ticks(Eu.every(I));break}}if(g.append("g").attr("class","grid").attr("transform","translate("+C+", "+(R-50)+")").call(k).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),n.db.topAxisEnabled()||i.topAxis){let I=$A(y).tickSize(-R+D+i.gridLineStartPadding).tickFormat(Ld(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));if(A!==null){let M=A[1],P=A[2],B=n.db.getWeekday()||i.weekday;switch(P){case"millisecond":I.ticks(uc.every(M));break;case"second":I.ticks(eo.every(M));break;case"minute":I.ticks(wu.every(M));break;case"hour":I.ticks(ku.every(M));break;case"day":I.ticks(Ro.every(M));break;case"week":I.ticks(efe[B].every(M));break;case"month":I.ticks(Eu.every(M));break}}g.append("g").attr("class","grid").attr("transform","translate("+C+", "+D+")").call(I).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}o(S,"makeGrid");function w(C,D){let O=0,R=Object.keys(p).map(k=>[k,p[k]]);g.append("g").selectAll("text").data(R).enter().append(function(k){let L=k[0].split(Ze.lineBreakRegex),A=-(L.length-1)/2,I=u.createElementNS("http://www.w3.org/2000/svg","text");I.setAttribute("dy",A+"em");for(let[M,P]of L.entries()){let B=u.createElementNS("http://www.w3.org/2000/svg","tspan");B.setAttribute("alignment-baseline","central"),B.setAttribute("x","10"),M>0&&B.setAttribute("dy","1em"),B.textContent=P,I.appendChild(B)}return I}).attr("x",10).attr("y",function(k,L){if(L>0)for(let A=0;A{"use strict";TVe=o(t=>` + .mermaid-main-font { + font-family: ${t.fontFamily}; + } + + .exclude-range { + fill: ${t.excludeBkgColor}; + } + + .section { + stroke: none; + opacity: 0.2; + } + + .section0 { + fill: ${t.sectionBkgColor}; + } + + .section2 { + fill: ${t.sectionBkgColor2}; + } + + .section1, + .section3 { + fill: ${t.altSectionBkgColor}; + opacity: 0.2; + } + + .sectionTitle0 { + fill: ${t.titleColor}; + } + + .sectionTitle1 { + fill: ${t.titleColor}; + } + + .sectionTitle2 { + fill: ${t.titleColor}; + } + + .sectionTitle3 { + fill: ${t.titleColor}; + } + + .sectionTitle { + text-anchor: start; + font-family: ${t.fontFamily}; + } + + + /* Grid and axis */ + + .grid .tick { + stroke: ${t.gridColor}; + opacity: 0.8; + shape-rendering: crispEdges; + } + + .grid .tick text { + font-family: ${t.fontFamily}; + fill: ${t.textColor}; + } + + .grid path { + stroke-width: 0; + } + + + /* Today line */ + + .today { + fill: none; + stroke: ${t.todayLineColor}; + stroke-width: 2px; + } + + + /* Task styling */ + + /* Default task */ + + .task { + stroke-width: 2; + } + + .taskText { + text-anchor: middle; + font-family: ${t.fontFamily}; + } + + .taskTextOutsideRight { + fill: ${t.taskTextDarkColor}; + text-anchor: start; + font-family: ${t.fontFamily}; + } + + .taskTextOutsideLeft { + fill: ${t.taskTextDarkColor}; + text-anchor: end; + } + + + /* Special case clickable */ + + .task.clickable { + cursor: pointer; + } + + .taskText.clickable { + cursor: pointer; + fill: ${t.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideLeft.clickable { + cursor: pointer; + fill: ${t.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideRight.clickable { + cursor: pointer; + fill: ${t.taskTextClickableColor} !important; + font-weight: bold; + } + + + /* Specific task settings for the sections*/ + + .taskText0, + .taskText1, + .taskText2, + .taskText3 { + fill: ${t.taskTextColor}; + } + + .task0, + .task1, + .task2, + .task3 { + fill: ${t.taskBkgColor}; + stroke: ${t.taskBorderColor}; + } + + .taskTextOutside0, + .taskTextOutside2 + { + fill: ${t.taskTextOutsideColor}; + } + + .taskTextOutside1, + .taskTextOutside3 { + fill: ${t.taskTextOutsideColor}; + } + + + /* Active task */ + + .active0, + .active1, + .active2, + .active3 { + fill: ${t.activeTaskBkgColor}; + stroke: ${t.activeTaskBorderColor}; + } + + .activeText0, + .activeText1, + .activeText2, + .activeText3 { + fill: ${t.taskTextDarkColor} !important; + } + + + /* Completed task */ + + .done0, + .done1, + .done2, + .done3 { + stroke: ${t.doneTaskBorderColor}; + fill: ${t.doneTaskBkgColor}; + stroke-width: 2; + } + + .doneText0, + .doneText1, + .doneText2, + .doneText3 { + fill: ${t.taskTextDarkColor} !important; + } + + + /* Tasks on the critical line */ + + .crit0, + .crit1, + .crit2, + .crit3 { + stroke: ${t.critBorderColor}; + fill: ${t.critBkgColor}; + stroke-width: 2; + } + + .activeCrit0, + .activeCrit1, + .activeCrit2, + .activeCrit3 { + stroke: ${t.critBorderColor}; + fill: ${t.activeTaskBkgColor}; + stroke-width: 2; + } + + .doneCrit0, + .doneCrit1, + .doneCrit2, + .doneCrit3 { + stroke: ${t.critBorderColor}; + fill: ${t.doneTaskBkgColor}; + stroke-width: 2; + cursor: pointer; + shape-rendering: crispEdges; + } + + .milestone { + transform: rotate(45deg) scale(0.8,0.8); + } + + .milestoneText { + font-style: italic; + } + .doneCritText0, + .doneCritText1, + .doneCritText2, + .doneCritText3 { + fill: ${t.taskTextDarkColor} !important; + } + + .vert { + stroke: ${t.vertLineColor}; + } + + .vertText { + font-size: 15px; + text-anchor: middle; + fill: ${t.vertLineColor} !important; + } + + .activeCritText0, + .activeCritText1, + .activeCritText2, + .activeCritText3 { + fill: ${t.taskTextDarkColor} !important; + } + + .titleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.titleColor||t.textColor}; + font-family: ${t.fontFamily}; + } +`,"getStyles"),nfe=TVe});var afe={};ur(afe,{diagram:()=>wVe});var wVe,sfe=N(()=>{"use strict";Mhe();Jhe();rfe();ife();wVe={parser:Nhe,db:Qhe,renderer:tfe,styles:nfe}});var cfe,ufe=N(()=>{"use strict";bf();yt();cfe={parse:o(async t=>{let e=await vs("info",t);X.debug(e)},"parse")}});var Db,XO=N(()=>{Db={name:"mermaid",version:"11.9.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",type:"module",module:"./dist/mermaid.core.mjs",types:"./dist/mermaid.d.ts",exports:{".":{types:"./dist/mermaid.d.ts",import:"./dist/mermaid.core.mjs",default:"./dist/mermaid.core.mjs"},"./*":"./*"},keywords:["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph","mindmap","packet diagram","c4 diagram","er diagram","pie chart","pie diagram","quadrant chart","requirement diagram","graph"],scripts:{clean:"rimraf dist",dev:"pnpm -w dev","docs:code":"typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup","docs:build":"rimraf ../../docs && pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts","docs:verify":"pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts --verify","docs:pre:vitepress":"pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts","docs:build:vitepress":"pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing","docs:dev":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:dev:docker":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev:docker" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:serve":"pnpm docs:build:vitepress && vitepress serve src/vitepress","docs:spellcheck":'cspell "src/docs/**/*.md"',"docs:release-version":"tsx scripts/update-release-version.mts","docs:verify-version":"tsx scripts/update-release-version.mts --verify","types:build-config":"tsx scripts/create-types-from-json-schema.mts","types:verify-config":"tsx scripts/create-types-from-json-schema.mts --verify",checkCircle:"npx madge --circular ./src",prepublishOnly:"pnpm docs:verify-version"},repository:{type:"git",url:"https://github.com/mermaid-js/mermaid"},author:"Knut Sveidqvist",license:"MIT",standard:{ignore:["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],globals:["page"]},dependencies:{"@braintree/sanitize-url":"^7.0.4","@iconify/utils":"^2.1.33","@mermaid-js/parser":"workspace:^","@types/d3":"^7.4.3",cytoscape:"^3.29.3","cytoscape-cose-bilkent":"^4.1.0","cytoscape-fcose":"^2.2.0",d3:"^7.9.0","d3-sankey":"^0.12.3","dagre-d3-es":"7.0.11",dayjs:"^1.11.13",dompurify:"^3.2.5",katex:"^0.16.22",khroma:"^2.1.0","lodash-es":"^4.17.21",marked:"^16.0.0",roughjs:"^4.6.6",stylis:"^4.3.6","ts-dedent":"^2.2.0",uuid:"^11.1.0"},devDependencies:{"@adobe/jsonschema2md":"^8.0.2","@iconify/types":"^2.0.0","@types/cytoscape":"^3.21.9","@types/cytoscape-fcose":"^2.2.4","@types/d3-sankey":"^0.12.4","@types/d3-scale":"^4.0.9","@types/d3-scale-chromatic":"^3.1.0","@types/d3-selection":"^3.0.11","@types/d3-shape":"^3.1.7","@types/jsdom":"^21.1.7","@types/katex":"^0.16.7","@types/lodash-es":"^4.17.12","@types/micromatch":"^4.0.9","@types/stylis":"^4.2.7","@types/uuid":"^10.0.0",ajv:"^8.17.1",canvas:"^3.1.0",chokidar:"3.6.0",concurrently:"^9.1.2","csstree-validator":"^4.0.1",globby:"^14.0.2",jison:"^0.4.18","js-base64":"^3.7.7",jsdom:"^26.1.0","json-schema-to-typescript":"^15.0.4",micromatch:"^4.0.8","path-browserify":"^1.0.1",prettier:"^3.5.2",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-gfm":"^4.0.1",rimraf:"^6.0.1","start-server-and-test":"^2.0.10","type-fest":"^4.35.0",typedoc:"^0.27.8","typedoc-plugin-markdown":"^4.4.2",typescript:"~5.7.3","unist-util-flatmap":"^1.0.0","unist-util-visit":"^5.0.0",vitepress:"^1.0.2","vitepress-plugin-search":"1.0.4-alpha.22"},files:["dist/","README.md"],publishConfig:{access:"public"}}});var AVe,_Ve,hfe,ffe=N(()=>{"use strict";XO();AVe={version:Db.version+""},_Ve=o(()=>AVe.version,"getVersion"),hfe={getVersion:_Ve}});var Li,Vl=N(()=>{"use strict";fr();Gt();Li=o(t=>{let{securityLevel:e}=me(),r=Ge("body");if(e==="sandbox"){let a=Ge(`#i${t}`).node()?.contentDocument??document;r=Ge(a.body)}return r.select(`#${t}`)},"selectSvgElement")});var DVe,dfe,pfe=N(()=>{"use strict";yt();Vl();xi();DVe=o((t,e,r)=>{X.debug(`rendering info diagram +`+t);let n=Li(e);fn(n,100,400,!0),n.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${r}`)},"draw"),dfe={draw:DVe}});var mfe={};ur(mfe,{diagram:()=>LVe});var LVe,gfe=N(()=>{"use strict";ufe();ffe();pfe();LVe={parser:cfe,db:hfe,renderer:dfe}});var xfe,jO,IS,KO,MVe,IVe,OVe,PVe,BVe,FVe,$Ve,OS,QO=N(()=>{"use strict";yt();ci();_a();xfe=or.pie,jO={sections:new Map,showData:!1,config:xfe},IS=jO.sections,KO=jO.showData,MVe=structuredClone(xfe),IVe=o(()=>structuredClone(MVe),"getConfig"),OVe=o(()=>{IS=new Map,KO=jO.showData,kr()},"clear"),PVe=o(({label:t,value:e})=>{IS.has(t)||(IS.set(t,e),X.debug(`added new section: ${t}, with value: ${e}`))},"addSection"),BVe=o(()=>IS,"getSections"),FVe=o(t=>{KO=t},"setShowData"),$Ve=o(()=>KO,"getShowData"),OS={getConfig:IVe,clear:OVe,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,addSection:PVe,getSections:BVe,setShowData:FVe,getShowData:$Ve}});var zVe,bfe,Tfe=N(()=>{"use strict";bf();yt();Mp();QO();zVe=o((t,e)=>{Jo(t,e),e.setShowData(t.showData),t.sections.map(e.addSection)},"populateDb"),bfe={parse:o(async t=>{let e=await vs("pie",t);X.debug(e),zVe(e,OS)},"parse")}});var GVe,wfe,kfe=N(()=>{"use strict";GVe=o(t=>` + .pieCircle{ + stroke: ${t.pieStrokeColor}; + stroke-width : ${t.pieStrokeWidth}; + opacity : ${t.pieOpacity}; + } + .pieOuterCircle{ + stroke: ${t.pieOuterStrokeColor}; + stroke-width: ${t.pieOuterStrokeWidth}; + fill: none; + } + .pieTitleText { + text-anchor: middle; + font-size: ${t.pieTitleTextSize}; + fill: ${t.pieTitleTextColor}; + font-family: ${t.fontFamily}; + } + .slice { + font-family: ${t.fontFamily}; + fill: ${t.pieSectionTextColor}; + font-size:${t.pieSectionTextSize}; + // fill: white; + } + .legend text { + fill: ${t.pieLegendTextColor}; + font-family: ${t.fontFamily}; + font-size: ${t.pieLegendTextSize}; + } +`,"getStyles"),wfe=GVe});var VVe,UVe,Efe,Sfe=N(()=>{"use strict";fr();Gt();yt();Vl();xi();er();VVe=o(t=>{let e=[...t.entries()].map(n=>({label:n[0],value:n[1]})).sort((n,i)=>i.value-n.value);return q5().value(n=>n.value)(e)},"createPieArcs"),UVe=o((t,e,r,n)=>{X.debug(`rendering pie chart +`+t);let i=n.db,a=me(),s=$n(i.getConfig(),a.pie),l=40,u=18,h=4,f=450,d=f,p=Li(e),m=p.append("g");m.attr("transform","translate("+d/2+","+f/2+")");let{themeVariables:g}=a,[y]=zo(g.pieOuterStrokeWidth);y??=2;let v=s.textPosition,x=Math.min(d,f)/2-l,b=Sl().innerRadius(0).outerRadius(x),T=Sl().innerRadius(x*v).outerRadius(x*v);m.append("circle").attr("cx",0).attr("cy",0).attr("r",x+y/2).attr("class","pieOuterCircle");let S=i.getSections(),w=VVe(S),E=[g.pie1,g.pie2,g.pie3,g.pie4,g.pie5,g.pie6,g.pie7,g.pie8,g.pie9,g.pie10,g.pie11,g.pie12],_=Js(E);m.selectAll("mySlices").data(w).enter().append("path").attr("d",b).attr("fill",k=>_(k.data.label)).attr("class","pieCircle");let C=0;S.forEach(k=>{C+=k}),m.selectAll("mySlices").data(w).enter().append("text").text(k=>(k.data.value/C*100).toFixed(0)+"%").attr("transform",k=>"translate("+T.centroid(k)+")").style("text-anchor","middle").attr("class","slice"),m.append("text").text(i.getDiagramTitle()).attr("x",0).attr("y",-(f-50)/2).attr("class","pieTitleText");let D=m.selectAll(".legend").data(_.domain()).enter().append("g").attr("class","legend").attr("transform",(k,L)=>{let A=u+h,I=A*_.domain().length/2,M=12*u,P=L*A-I;return"translate("+M+","+P+")"});D.append("rect").attr("width",u).attr("height",u).style("fill",_).style("stroke",_),D.data(w).append("text").attr("x",u+h).attr("y",u-h).text(k=>{let{label:L,value:A}=k.data;return i.getShowData()?`${L} [${A}]`:L});let O=Math.max(...D.selectAll("text").nodes().map(k=>k?.getBoundingClientRect().width??0)),R=d+l+u+h+O;p.attr("viewBox",`0 0 ${R} ${f}`),fn(p,f,R,s.useMaxWidth)},"draw"),Efe={draw:UVe}});var Cfe={};ur(Cfe,{diagram:()=>HVe});var HVe,Afe=N(()=>{"use strict";Tfe();QO();kfe();Sfe();HVe={parser:bfe,db:OS,renderer:Efe,styles:wfe}});var ZO,Lfe,Rfe=N(()=>{"use strict";ZO=function(){var t=o(function(Te,W,pe,ve){for(pe=pe||{},ve=Te.length;ve--;pe[Te[ve]]=W);return pe},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[1,7],s=[1,4,5,10,12,13,14,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],l=[1,4,5,10,12,13,14,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],u=[55,56,57],h=[2,36],f=[1,37],d=[1,36],p=[1,38],m=[1,35],g=[1,43],y=[1,41],v=[1,14],x=[1,23],b=[1,18],T=[1,19],S=[1,20],w=[1,21],E=[1,22],_=[1,24],C=[1,25],D=[1,26],O=[1,27],R=[1,28],k=[1,29],L=[1,32],A=[1,33],I=[1,34],M=[1,39],P=[1,40],B=[1,42],F=[1,44],z=[1,62],$=[1,61],U=[4,5,8,10,12,13,14,18,44,47,49,55,56,57,63,64,65,66,67],K=[1,65],ee=[1,66],Y=[1,67],ce=[1,68],Z=[1,69],ue=[1,70],Q=[1,71],j=[1,72],ne=[1,73],te=[1,74],he=[1,75],le=[1,76],J=[4,5,6,7,8,9,10,11,12,13,14,15,18],Se=[1,90],se=[1,91],ae=[1,92],Oe=[1,99],ye=[1,93],Be=[1,96],He=[1,94],ze=[1,95],Le=[1,97],Ie=[1,98],xe=[1,102],q=[10,55,56,57],de=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],ie={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:o(function(W,pe,ve,Pe,_e,be,Ve){var De=be.length-1;switch(_e){case 23:this.$=be[De];break;case 24:this.$=be[De-1]+""+be[De];break;case 26:this.$=be[De-1]+be[De];break;case 27:this.$=[be[De].trim()];break;case 28:be[De-2].push(be[De].trim()),this.$=be[De-2];break;case 29:this.$=be[De-4],Pe.addClass(be[De-2],be[De]);break;case 37:this.$=[];break;case 42:this.$=be[De].trim(),Pe.setDiagramTitle(this.$);break;case 43:this.$=be[De].trim(),Pe.setAccTitle(this.$);break;case 44:case 45:this.$=be[De].trim(),Pe.setAccDescription(this.$);break;case 46:Pe.addSection(be[De].substr(8)),this.$=be[De].substr(8);break;case 47:Pe.addPoint(be[De-3],"",be[De-1],be[De],[]);break;case 48:Pe.addPoint(be[De-4],be[De-3],be[De-1],be[De],[]);break;case 49:Pe.addPoint(be[De-4],"",be[De-2],be[De-1],be[De]);break;case 50:Pe.addPoint(be[De-5],be[De-4],be[De-2],be[De-1],be[De]);break;case 51:Pe.setXAxisLeftText(be[De-2]),Pe.setXAxisRightText(be[De]);break;case 52:be[De-1].text+=" \u27F6 ",Pe.setXAxisLeftText(be[De-1]);break;case 53:Pe.setXAxisLeftText(be[De]);break;case 54:Pe.setYAxisBottomText(be[De-2]),Pe.setYAxisTopText(be[De]);break;case 55:be[De-1].text+=" \u27F6 ",Pe.setYAxisBottomText(be[De-1]);break;case 56:Pe.setYAxisBottomText(be[De]);break;case 57:Pe.setQuadrant1Text(be[De]);break;case 58:Pe.setQuadrant2Text(be[De]);break;case 59:Pe.setQuadrant3Text(be[De]);break;case 60:Pe.setQuadrant4Text(be[De]);break;case 64:this.$={text:be[De],type:"text"};break;case 65:this.$={text:be[De-1].text+""+be[De],type:be[De-1].type};break;case 66:this.$={text:be[De],type:"text"};break;case 67:this.$={text:be[De],type:"markdown"};break;case 68:this.$=be[De];break;case 69:this.$=be[De-1]+""+be[De];break}},"anonymous"),table:[{18:e,26:1,27:2,28:r,55:n,56:i,57:a},{1:[3]},{18:e,26:8,27:2,28:r,55:n,56:i,57:a},{18:e,26:9,27:2,28:r,55:n,56:i,57:a},t(s,[2,33],{29:10}),t(l,[2,61]),t(l,[2,62]),t(l,[2,63]),{1:[2,30]},{1:[2,31]},t(u,h,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:T,39:S,41:w,42:E,48:_,50:C,51:D,52:O,53:R,54:k,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(s,[2,34]),{27:45,55:n,56:i,57:a},t(u,[2,37]),t(u,h,{24:13,32:15,33:16,34:17,43:30,58:31,31:46,4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:T,39:S,41:w,42:E,48:_,50:C,51:D,52:O,53:R,54:k,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(u,[2,39]),t(u,[2,40]),t(u,[2,41]),{36:[1,47]},{38:[1,48]},{40:[1,49]},t(u,[2,45]),t(u,[2,46]),{18:[1,50]},{4:f,5:d,10:p,12:m,13:g,14:y,43:51,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:52,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:53,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:54,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:55,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:56,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,44:[1,57],47:[1,58],58:60,59:59,63:I,64:M,65:P,66:B,67:F},t(U,[2,64]),t(U,[2,66]),t(U,[2,67]),t(U,[2,70]),t(U,[2,71]),t(U,[2,72]),t(U,[2,73]),t(U,[2,74]),t(U,[2,75]),t(U,[2,76]),t(U,[2,77]),t(U,[2,78]),t(U,[2,79]),t(U,[2,80]),t(s,[2,35]),t(u,[2,38]),t(u,[2,42]),t(u,[2,43]),t(u,[2,44]),{3:64,4:K,5:ee,6:Y,7:ce,8:Z,9:ue,10:Q,11:j,12:ne,13:te,14:he,15:le,21:63},t(u,[2,53],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,77],63:I,64:M,65:P,66:B,67:F}),t(u,[2,56],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,78],63:I,64:M,65:P,66:B,67:F}),t(u,[2,57],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,58],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,59],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,60],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),{45:[1,79]},{44:[1,80]},t(U,[2,65]),t(U,[2,81]),t(U,[2,82]),t(U,[2,83]),{3:82,4:K,5:ee,6:Y,7:ce,8:Z,9:ue,10:Q,11:j,12:ne,13:te,14:he,15:le,18:[1,81]},t(J,[2,23]),t(J,[2,1]),t(J,[2,2]),t(J,[2,3]),t(J,[2,4]),t(J,[2,5]),t(J,[2,6]),t(J,[2,7]),t(J,[2,8]),t(J,[2,9]),t(J,[2,10]),t(J,[2,11]),t(J,[2,12]),t(u,[2,52],{58:31,43:83,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(u,[2,55],{58:31,43:84,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),{46:[1,85]},{45:[1,86]},{4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,16:89,17:He,18:ze,19:Le,20:Ie,22:88,23:87},t(J,[2,24]),t(u,[2,51],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,54],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,47],{22:88,16:89,23:100,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),{46:[1,101]},t(u,[2,29],{10:xe}),t(q,[2,27],{16:103,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),t(de,[2,25]),t(de,[2,13]),t(de,[2,14]),t(de,[2,15]),t(de,[2,16]),t(de,[2,17]),t(de,[2,18]),t(de,[2,19]),t(de,[2,20]),t(de,[2,21]),t(de,[2,22]),t(u,[2,49],{10:xe}),t(u,[2,48],{22:88,16:89,23:104,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),{4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,16:89,17:He,18:ze,19:Le,20:Ie,22:105},t(de,[2,26]),t(u,[2,50],{10:xe}),t(q,[2,28],{16:103,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie})],defaultActions:{8:[2,30],9:[2,31]},parseError:o(function(W,pe){if(pe.recoverable)this.trace(W);else{var ve=new Error(W);throw ve.hash=pe,ve}},"parseError"),parse:o(function(W){var pe=this,ve=[0],Pe=[],_e=[null],be=[],Ve=this.table,De="",qe=0,at=0,Rt=0,st=2,Ue=1,ct=be.slice.call(arguments,1),We=Object.create(this.lexer),ot={yy:{}};for(var Yt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Yt)&&(ot.yy[Yt]=this.yy[Yt]);We.setInput(W,ot.yy),ot.yy.lexer=We,ot.yy.parser=this,typeof We.yylloc>"u"&&(We.yylloc={});var Tt=We.yylloc;be.push(Tt);var Mt=We.options&&We.options.ranges;typeof ot.yy.parseError=="function"?this.parseError=ot.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function bt(Ce){ve.length=ve.length-2*Ce,_e.length=_e.length-Ce,be.length=be.length-Ce}o(bt,"popStack");function ut(){var Ce;return Ce=Pe.pop()||We.lex()||Ue,typeof Ce!="number"&&(Ce instanceof Array&&(Pe=Ce,Ce=Pe.pop()),Ce=pe.symbols_[Ce]||Ce),Ce}o(ut,"lex");for(var St,ft,vt,nt,pn,kt,On={},tn,Mr,Ir,Pn;;){if(vt=ve[ve.length-1],this.defaultActions[vt]?nt=this.defaultActions[vt]:((St===null||typeof St>"u")&&(St=ut()),nt=Ve[vt]&&Ve[vt][St]),typeof nt>"u"||!nt.length||!nt[0]){var Dt="";Pn=[];for(tn in Ve[vt])this.terminals_[tn]&&tn>st&&Pn.push("'"+this.terminals_[tn]+"'");We.showPosition?Dt="Parse error on line "+(qe+1)+`: +`+We.showPosition()+` +Expecting `+Pn.join(", ")+", got '"+(this.terminals_[St]||St)+"'":Dt="Parse error on line "+(qe+1)+": Unexpected "+(St==Ue?"end of input":"'"+(this.terminals_[St]||St)+"'"),this.parseError(Dt,{text:We.match,token:this.terminals_[St]||St,line:We.yylineno,loc:Tt,expected:Pn})}if(nt[0]instanceof Array&&nt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+vt+", token: "+St);switch(nt[0]){case 1:ve.push(St),_e.push(We.yytext),be.push(We.yylloc),ve.push(nt[1]),St=null,ft?(St=ft,ft=null):(at=We.yyleng,De=We.yytext,qe=We.yylineno,Tt=We.yylloc,Rt>0&&Rt--);break;case 2:if(Mr=this.productions_[nt[1]][1],On.$=_e[_e.length-Mr],On._$={first_line:be[be.length-(Mr||1)].first_line,last_line:be[be.length-1].last_line,first_column:be[be.length-(Mr||1)].first_column,last_column:be[be.length-1].last_column},Mt&&(On._$.range=[be[be.length-(Mr||1)].range[0],be[be.length-1].range[1]]),kt=this.performAction.apply(On,[De,at,qe,ot.yy,nt[1],_e,be].concat(ct)),typeof kt<"u")return kt;Mr&&(ve=ve.slice(0,-1*Mr*2),_e=_e.slice(0,-1*Mr),be=be.slice(0,-1*Mr)),ve.push(this.productions_[nt[1]][0]),_e.push(On.$),be.push(On._$),Ir=Ve[ve[ve.length-2]][ve[ve.length-1]],ve.push(Ir);break;case 3:return!0}}return!0},"parse")},oe=function(){var Te={EOF:1,parseError:o(function(pe,ve){if(this.yy.parser)this.yy.parser.parseError(pe,ve);else throw new Error(pe)},"parseError"),setInput:o(function(W,pe){return this.yy=pe||this.yy||{},this._input=W,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var W=this._input[0];this.yytext+=W,this.yyleng++,this.offset++,this.match+=W,this.matched+=W;var pe=W.match(/(?:\r\n?|\n).*/g);return pe?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),W},"input"),unput:o(function(W){var pe=W.length,ve=W.split(/(?:\r\n?|\n)/g);this._input=W+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-pe),this.offset-=pe;var Pe=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),ve.length-1&&(this.yylineno-=ve.length-1);var _e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:ve?(ve.length===Pe.length?this.yylloc.first_column:0)+Pe[Pe.length-ve.length].length-ve[0].length:this.yylloc.first_column-pe},this.options.ranges&&(this.yylloc.range=[_e[0],_e[0]+this.yyleng-pe]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(W){this.unput(this.match.slice(W))},"less"),pastInput:o(function(){var W=this.matched.substr(0,this.matched.length-this.match.length);return(W.length>20?"...":"")+W.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var W=this.match;return W.length<20&&(W+=this._input.substr(0,20-W.length)),(W.substr(0,20)+(W.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var W=this.pastInput(),pe=new Array(W.length+1).join("-");return W+this.upcomingInput()+` +`+pe+"^"},"showPosition"),test_match:o(function(W,pe){var ve,Pe,_e;if(this.options.backtrack_lexer&&(_e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(_e.yylloc.range=this.yylloc.range.slice(0))),Pe=W[0].match(/(?:\r\n?|\n).*/g),Pe&&(this.yylineno+=Pe.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Pe?Pe[Pe.length-1].length-Pe[Pe.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+W[0].length},this.yytext+=W[0],this.match+=W[0],this.matches=W,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(W[0].length),this.matched+=W[0],ve=this.performAction.call(this,this.yy,this,pe,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ve)return ve;if(this._backtrack){for(var be in _e)this[be]=_e[be];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var W,pe,ve,Pe;this._more||(this.yytext="",this.match="");for(var _e=this._currentRules(),be=0;be<_e.length;be++)if(ve=this._input.match(this.rules[_e[be]]),ve&&(!pe||ve[0].length>pe[0].length)){if(pe=ve,Pe=be,this.options.backtrack_lexer){if(W=this.test_match(ve,_e[be]),W!==!1)return W;if(this._backtrack){pe=!1;continue}else return!1}else if(!this.options.flex)break}return pe?(W=this.test_match(pe,_e[Pe]),W!==!1?W:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var pe=this.next();return pe||this.lex()},"lex"),begin:o(function(pe){this.conditionStack.push(pe)},"begin"),popState:o(function(){var pe=this.conditionStack.length-1;return pe>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(pe){return pe=this.conditionStack.length-1-Math.abs(pe||0),pe>=0?this.conditionStack[pe]:"INITIAL"},"topState"),pushState:o(function(pe){this.begin(pe)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(pe,ve,Pe,_e){var be=_e;switch(Pe){case 0:break;case 1:break;case 2:return 55;case 3:break;case 4:return this.begin("title"),35;break;case 5:return this.popState(),"title_value";break;case 6:return this.begin("acc_title"),37;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),39;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 48;case 14:return 50;case 15:return 49;case 16:return 51;case 17:return 52;case 18:return 53;case 19:return 54;case 20:return 25;case 21:this.begin("md_string");break;case 22:return"MD_STR";case 23:this.popState();break;case 24:this.begin("string");break;case 25:this.popState();break;case 26:return"STR";case 27:this.begin("class_name");break;case 28:return this.popState(),47;break;case 29:return this.begin("point_start"),44;break;case 30:return this.begin("point_x"),45;break;case 31:this.popState();break;case 32:this.popState(),this.begin("point_y");break;case 33:return this.popState(),46;break;case 34:return 28;case 35:return 4;case 36:return 11;case 37:return 64;case 38:return 10;case 39:return 65;case 40:return 65;case 41:return 14;case 42:return 13;case 43:return 67;case 44:return 66;case 45:return 12;case 46:return 8;case 47:return 5;case 48:return 18;case 49:return 56;case 50:return 63;case 51:return 57}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:classDef\b)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::::)/i,/^(?:^\w+)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{class_name:{rules:[28],inclusive:!1},point_y:{rules:[33],inclusive:!1},point_x:{rules:[32],inclusive:!1},point_start:{rules:[30,31],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[22,23],inclusive:!1},string:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,21,24,27,29,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}};return Te}();ie.lexer=oe;function V(){this.yy={}}return o(V,"Parser"),V.prototype=ie,ie.Parser=V,new V}();ZO.parser=ZO;Lfe=ZO});var xs,PS,Nfe=N(()=>{"use strict";fr();_a();yt();By();xs=dh(),PS=class{constructor(){this.classes=new Map;this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}static{o(this,"QuadrantBuilder")}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:or.quadrantChart?.chartWidth||500,chartWidth:or.quadrantChart?.chartHeight||500,titlePadding:or.quadrantChart?.titlePadding||10,titleFontSize:or.quadrantChart?.titleFontSize||20,quadrantPadding:or.quadrantChart?.quadrantPadding||5,xAxisLabelPadding:or.quadrantChart?.xAxisLabelPadding||5,yAxisLabelPadding:or.quadrantChart?.yAxisLabelPadding||5,xAxisLabelFontSize:or.quadrantChart?.xAxisLabelFontSize||16,yAxisLabelFontSize:or.quadrantChart?.yAxisLabelFontSize||16,quadrantLabelFontSize:or.quadrantChart?.quadrantLabelFontSize||16,quadrantTextTopPadding:or.quadrantChart?.quadrantTextTopPadding||5,pointTextPadding:or.quadrantChart?.pointTextPadding||5,pointLabelFontSize:or.quadrantChart?.pointLabelFontSize||12,pointRadius:or.quadrantChart?.pointRadius||5,xAxisPosition:or.quadrantChart?.xAxisPosition||"top",yAxisPosition:or.quadrantChart?.yAxisPosition||"left",quadrantInternalBorderStrokeWidth:or.quadrantChart?.quadrantInternalBorderStrokeWidth||1,quadrantExternalBorderStrokeWidth:or.quadrantChart?.quadrantExternalBorderStrokeWidth||2}}getDefaultThemeConfig(){return{quadrant1Fill:xs.quadrant1Fill,quadrant2Fill:xs.quadrant2Fill,quadrant3Fill:xs.quadrant3Fill,quadrant4Fill:xs.quadrant4Fill,quadrant1TextFill:xs.quadrant1TextFill,quadrant2TextFill:xs.quadrant2TextFill,quadrant3TextFill:xs.quadrant3TextFill,quadrant4TextFill:xs.quadrant4TextFill,quadrantPointFill:xs.quadrantPointFill,quadrantPointTextFill:xs.quadrantPointTextFill,quadrantXAxisTextFill:xs.quadrantXAxisTextFill,quadrantYAxisTextFill:xs.quadrantYAxisTextFill,quadrantTitleFill:xs.quadrantTitleFill,quadrantInternalBorderStrokeFill:xs.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:xs.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),this.classes=new Map,X.info("clear called")}setData(e){this.data={...this.data,...e}}addPoints(e){this.data.points=[...e,...this.data.points]}addClass(e,r){this.classes.set(e,r)}setConfig(e){X.trace("setConfig called with: ",e),this.config={...this.config,...e}}setThemeConfig(e){X.trace("setThemeConfig called with: ",e),this.themeConfig={...this.themeConfig,...e}}calculateSpace(e,r,n,i){let a=this.config.xAxisLabelPadding*2+this.config.xAxisLabelFontSize,s={top:e==="top"&&r?a:0,bottom:e==="bottom"&&r?a:0},l=this.config.yAxisLabelPadding*2+this.config.yAxisLabelFontSize,u={left:this.config.yAxisPosition==="left"&&n?l:0,right:this.config.yAxisPosition==="right"&&n?l:0},h=this.config.titleFontSize+this.config.titlePadding*2,f={top:i?h:0},d=this.config.quadrantPadding+u.left,p=this.config.quadrantPadding+s.top+f.top,m=this.config.chartWidth-this.config.quadrantPadding*2-u.left-u.right,g=this.config.chartHeight-this.config.quadrantPadding*2-s.top-s.bottom-f.top,y=m/2,v=g/2;return{xAxisSpace:s,yAxisSpace:u,titleSpace:f,quadrantSpace:{quadrantLeft:d,quadrantTop:p,quadrantWidth:m,quadrantHalfWidth:y,quadrantHeight:g,quadrantHalfHeight:v}}}getAxisLabels(e,r,n,i){let{quadrantSpace:a,titleSpace:s}=i,{quadrantHalfHeight:l,quadrantHeight:u,quadrantLeft:h,quadrantHalfWidth:f,quadrantTop:d,quadrantWidth:p}=a,m=!!this.data.xAxisRightText,g=!!this.data.yAxisTopText,y=[];return this.data.xAxisLeftText&&r&&y.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&r&&y.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+f+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&n&&y.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+u-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&n&&y.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+l-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),y}getQuadrants(e){let{quadrantSpace:r}=e,{quadrantHalfHeight:n,quadrantLeft:i,quadrantHalfWidth:a,quadrantTop:s}=r,l=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s,width:a,height:n,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s,width:a,height:n,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant4Fill}];for(let u of l)u.text.x=u.x+u.width/2,this.data.points.length===0?(u.text.y=u.y+u.height/2,u.text.horizontalPos="middle"):(u.text.y=u.y+this.config.quadrantTextTopPadding,u.text.horizontalPos="top");return l}getQuadrantPoints(e){let{quadrantSpace:r}=e,{quadrantHeight:n,quadrantLeft:i,quadrantTop:a,quadrantWidth:s}=r,l=Tl().domain([0,1]).range([i,s+i]),u=Tl().domain([0,1]).range([n+a,a]);return this.data.points.map(f=>{let d=this.classes.get(f.className);return d&&(f={...d,...f}),{x:l(f.x),y:u(f.y),fill:f.color??this.themeConfig.quadrantPointFill,radius:f.radius??this.config.pointRadius,text:{text:f.text,fill:this.themeConfig.quadrantPointTextFill,x:l(f.x),y:u(f.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0},strokeColor:f.strokeColor??this.themeConfig.quadrantPointFill,strokeWidth:f.strokeWidth??"0px"}})}getBorders(e){let r=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:n}=e,{quadrantHalfHeight:i,quadrantHeight:a,quadrantLeft:s,quadrantHalfWidth:l,quadrantTop:u,quadrantWidth:h}=n;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u,x2:s+h+r,y2:u},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s+h,y1:u+r,x2:s+h,y2:u+a-r},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u+a,x2:s+h+r,y2:u+a},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s,y1:u+r,x2:s,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+l,y1:u+r,x2:s+l,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+r,y1:u+i,x2:s+h-r,y2:u+i}]}getTitle(e){if(e)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){let e=this.config.showXAxis&&!!(this.data.xAxisLeftText||this.data.xAxisRightText),r=this.config.showYAxis&&!!(this.data.yAxisTopText||this.data.yAxisBottomText),n=this.config.showTitle&&!!this.data.titleText,i=this.data.points.length>0?"bottom":this.config.xAxisPosition,a=this.calculateSpace(i,e,r,n);return{points:this.getQuadrantPoints(a),quadrants:this.getQuadrants(a),axisLabels:this.getAxisLabels(i,e,r,a),borderLines:this.getBorders(a),title:this.getTitle(n)}}}});function JO(t){return!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(t)}function Mfe(t){return!/^\d+$/.test(t)}function Ife(t){return!/^\d+px$/.test(t)}var Bp,Ofe=N(()=>{"use strict";Bp=class extends Error{static{o(this,"InvalidStyleError")}constructor(e,r,n){super(`value for ${e} ${r} is invalid, please use a valid ${n}`),this.name="InvalidStyleError"}};o(JO,"validateHexCode");o(Mfe,"validateNumber");o(Ife,"validateSizeInPixels")});function eh(t){return wr(t.trim(),YVe)}function XVe(t){wa.setData({quadrant1Text:eh(t.text)})}function jVe(t){wa.setData({quadrant2Text:eh(t.text)})}function KVe(t){wa.setData({quadrant3Text:eh(t.text)})}function QVe(t){wa.setData({quadrant4Text:eh(t.text)})}function ZVe(t){wa.setData({xAxisLeftText:eh(t.text)})}function JVe(t){wa.setData({xAxisRightText:eh(t.text)})}function eUe(t){wa.setData({yAxisTopText:eh(t.text)})}function tUe(t){wa.setData({yAxisBottomText:eh(t.text)})}function eP(t){let e={};for(let r of t){let[n,i]=r.trim().split(/\s*:\s*/);if(n==="radius"){if(Mfe(i))throw new Bp(n,i,"number");e.radius=parseInt(i)}else if(n==="color"){if(JO(i))throw new Bp(n,i,"hex code");e.color=i}else if(n==="stroke-color"){if(JO(i))throw new Bp(n,i,"hex code");e.strokeColor=i}else if(n==="stroke-width"){if(Ife(i))throw new Bp(n,i,"number of pixels (eg. 10px)");e.strokeWidth=i}else throw new Error(`style named ${n} is not supported.`)}return e}function rUe(t,e,r,n,i){let a=eP(i);wa.addPoints([{x:r,y:n,text:eh(t.text),className:e,...a}])}function nUe(t,e){wa.addClass(t,eP(e))}function iUe(t){wa.setConfig({chartWidth:t})}function aUe(t){wa.setConfig({chartHeight:t})}function sUe(){let t=me(),{themeVariables:e,quadrantChart:r}=t;return r&&wa.setConfig(r),wa.setThemeConfig({quadrant1Fill:e.quadrant1Fill,quadrant2Fill:e.quadrant2Fill,quadrant3Fill:e.quadrant3Fill,quadrant4Fill:e.quadrant4Fill,quadrant1TextFill:e.quadrant1TextFill,quadrant2TextFill:e.quadrant2TextFill,quadrant3TextFill:e.quadrant3TextFill,quadrant4TextFill:e.quadrant4TextFill,quadrantPointFill:e.quadrantPointFill,quadrantPointTextFill:e.quadrantPointTextFill,quadrantXAxisTextFill:e.quadrantXAxisTextFill,quadrantYAxisTextFill:e.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:e.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:e.quadrantInternalBorderStrokeFill,quadrantTitleFill:e.quadrantTitleFill}),wa.setData({titleText:Nr()}),wa.build()}var YVe,wa,oUe,Pfe,Bfe=N(()=>{"use strict";Gt();pr();ci();Nfe();Ofe();YVe=me();o(eh,"textSanitizer");wa=new PS;o(XVe,"setQuadrant1Text");o(jVe,"setQuadrant2Text");o(KVe,"setQuadrant3Text");o(QVe,"setQuadrant4Text");o(ZVe,"setXAxisLeftText");o(JVe,"setXAxisRightText");o(eUe,"setYAxisTopText");o(tUe,"setYAxisBottomText");o(eP,"parseStyles");o(rUe,"addPoint");o(nUe,"addClass");o(iUe,"setWidth");o(aUe,"setHeight");o(sUe,"getQuadrantData");oUe=o(function(){wa.clear(),kr()},"clear"),Pfe={setWidth:iUe,setHeight:aUe,setQuadrant1Text:XVe,setQuadrant2Text:jVe,setQuadrant3Text:KVe,setQuadrant4Text:QVe,setXAxisLeftText:ZVe,setXAxisRightText:JVe,setYAxisTopText:eUe,setYAxisBottomText:tUe,parseStyles:eP,addPoint:rUe,addClass:nUe,getQuadrantData:sUe,clear:oUe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var lUe,Ffe,$fe=N(()=>{"use strict";fr();Gt();yt();xi();lUe=o((t,e,r,n)=>{function i(C){return C==="top"?"hanging":"middle"}o(i,"getDominantBaseLine");function a(C){return C==="left"?"start":"middle"}o(a,"getTextAnchor");function s(C){return`translate(${C.x}, ${C.y}) rotate(${C.rotation||0})`}o(s,"getTransformation");let l=me();X.debug(`Rendering quadrant chart +`+t);let u=l.securityLevel,h;u==="sandbox"&&(h=Ge("#i"+e));let d=(u==="sandbox"?Ge(h.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${e}"]`),p=d.append("g").attr("class","main"),m=l.quadrantChart?.chartWidth??500,g=l.quadrantChart?.chartHeight??500;fn(d,g,m,l.quadrantChart?.useMaxWidth??!0),d.attr("viewBox","0 0 "+m+" "+g),n.db.setHeight(g),n.db.setWidth(m);let y=n.db.getQuadrantData(),v=p.append("g").attr("class","quadrants"),x=p.append("g").attr("class","border"),b=p.append("g").attr("class","data-points"),T=p.append("g").attr("class","labels"),S=p.append("g").attr("class","title");y.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",y.title.fill).attr("font-size",y.title.fontSize).attr("dominant-baseline",i(y.title.horizontalPos)).attr("text-anchor",a(y.title.verticalPos)).attr("transform",s(y.title)).text(y.title.text),y.borderLines&&x.selectAll("line").data(y.borderLines).enter().append("line").attr("x1",C=>C.x1).attr("y1",C=>C.y1).attr("x2",C=>C.x2).attr("y2",C=>C.y2).style("stroke",C=>C.strokeFill).style("stroke-width",C=>C.strokeWidth);let w=v.selectAll("g.quadrant").data(y.quadrants).enter().append("g").attr("class","quadrant");w.append("rect").attr("x",C=>C.x).attr("y",C=>C.y).attr("width",C=>C.width).attr("height",C=>C.height).attr("fill",C=>C.fill),w.append("text").attr("x",0).attr("y",0).attr("fill",C=>C.text.fill).attr("font-size",C=>C.text.fontSize).attr("dominant-baseline",C=>i(C.text.horizontalPos)).attr("text-anchor",C=>a(C.text.verticalPos)).attr("transform",C=>s(C.text)).text(C=>C.text.text),T.selectAll("g.label").data(y.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text(C=>C.text).attr("fill",C=>C.fill).attr("font-size",C=>C.fontSize).attr("dominant-baseline",C=>i(C.horizontalPos)).attr("text-anchor",C=>a(C.verticalPos)).attr("transform",C=>s(C));let _=b.selectAll("g.data-point").data(y.points).enter().append("g").attr("class","data-point");_.append("circle").attr("cx",C=>C.x).attr("cy",C=>C.y).attr("r",C=>C.radius).attr("fill",C=>C.fill).attr("stroke",C=>C.strokeColor).attr("stroke-width",C=>C.strokeWidth),_.append("text").attr("x",0).attr("y",0).text(C=>C.text.text).attr("fill",C=>C.text.fill).attr("font-size",C=>C.text.fontSize).attr("dominant-baseline",C=>i(C.text.horizontalPos)).attr("text-anchor",C=>a(C.text.verticalPos)).attr("transform",C=>s(C.text))},"draw"),Ffe={draw:lUe}});var zfe={};ur(zfe,{diagram:()=>cUe});var cUe,Gfe=N(()=>{"use strict";Rfe();Bfe();$fe();cUe={parser:Lfe,db:Pfe,renderer:Ffe,styles:o(()=>"","styles")}});var tP,Hfe,Wfe=N(()=>{"use strict";tP=function(){var t=o(function(I,M,P,B){for(P=P||{},B=I.length;B--;P[I[B]]=M);return P},"o"),e=[1,10,12,14,16,18,19,21,23],r=[2,6],n=[1,3],i=[1,5],a=[1,6],s=[1,7],l=[1,5,10,12,14,16,18,19,21,23,34,35,36],u=[1,25],h=[1,26],f=[1,28],d=[1,29],p=[1,30],m=[1,31],g=[1,32],y=[1,33],v=[1,34],x=[1,35],b=[1,36],T=[1,37],S=[1,43],w=[1,42],E=[1,47],_=[1,50],C=[1,10,12,14,16,18,19,21,23,34,35,36],D=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],O=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],R=[1,64],k={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:o(function(M,P,B,F,z,$,U){var K=$.length-1;switch(z){case 5:F.setOrientation($[K]);break;case 9:F.setDiagramTitle($[K].text.trim());break;case 12:F.setLineData({text:"",type:"text"},$[K]);break;case 13:F.setLineData($[K-1],$[K]);break;case 14:F.setBarData({text:"",type:"text"},$[K]);break;case 15:F.setBarData($[K-1],$[K]);break;case 16:this.$=$[K].trim(),F.setAccTitle(this.$);break;case 17:case 18:this.$=$[K].trim(),F.setAccDescription(this.$);break;case 19:this.$=$[K-1];break;case 20:this.$=[Number($[K-2]),...$[K]];break;case 21:this.$=[Number($[K])];break;case 22:F.setXAxisTitle($[K]);break;case 23:F.setXAxisTitle($[K-1]);break;case 24:F.setXAxisTitle({type:"text",text:""});break;case 25:F.setXAxisBand($[K]);break;case 26:F.setXAxisRangeData(Number($[K-2]),Number($[K]));break;case 27:this.$=$[K-1];break;case 28:this.$=[$[K-2],...$[K]];break;case 29:this.$=[$[K]];break;case 30:F.setYAxisTitle($[K]);break;case 31:F.setYAxisTitle($[K-1]);break;case 32:F.setYAxisTitle({type:"text",text:""});break;case 33:F.setYAxisRangeData(Number($[K-2]),Number($[K]));break;case 37:this.$={text:$[K],type:"text"};break;case 38:this.$={text:$[K],type:"text"};break;case 39:this.$={text:$[K],type:"markdown"};break;case 40:this.$=$[K];break;case 41:this.$=$[K-1]+""+$[K];break}},"anonymous"),table:[t(e,r,{3:1,4:2,7:4,5:n,34:i,35:a,36:s}),{1:[3]},t(e,r,{4:2,7:4,3:8,5:n,34:i,35:a,36:s}),t(e,r,{4:2,7:4,6:9,3:10,5:n,8:[1,11],34:i,35:a,36:s}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(l,[2,34]),t(l,[2,35]),t(l,[2,36]),{1:[2,1]},t(e,r,{4:2,7:4,3:21,5:n,34:i,35:a,36:s}),{1:[2,3]},t(l,[2,5]),t(e,[2,7],{4:22,34:i,35:a,36:s}),{11:23,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:39,13:38,24:S,27:w,29:40,30:41,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:45,15:44,27:E,33:46,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:49,17:48,24:_,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:52,17:51,24:_,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{20:[1,53]},{22:[1,54]},t(C,[2,18]),{1:[2,2]},t(C,[2,8]),t(C,[2,9]),t(D,[2,37],{40:55,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T}),t(D,[2,38]),t(D,[2,39]),t(O,[2,40]),t(O,[2,42]),t(O,[2,43]),t(O,[2,44]),t(O,[2,45]),t(O,[2,46]),t(O,[2,47]),t(O,[2,48]),t(O,[2,49]),t(O,[2,50]),t(O,[2,51]),t(C,[2,10]),t(C,[2,22],{30:41,29:56,24:S,27:w}),t(C,[2,24]),t(C,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},t(C,[2,11]),t(C,[2,30],{33:60,27:E}),t(C,[2,32]),{31:[1,61]},t(C,[2,12]),{17:62,24:_},{25:63,27:R},t(C,[2,14]),{17:65,24:_},t(C,[2,16]),t(C,[2,17]),t(O,[2,41]),t(C,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(C,[2,31]),{27:[1,69]},t(C,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(C,[2,15]),t(C,[2,26]),t(C,[2,27]),{11:59,32:72,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},t(C,[2,33]),t(C,[2,19]),{25:73,27:R},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:o(function(M,P){if(P.recoverable)this.trace(M);else{var B=new Error(M);throw B.hash=P,B}},"parseError"),parse:o(function(M){var P=this,B=[0],F=[],z=[null],$=[],U=this.table,K="",ee=0,Y=0,ce=0,Z=2,ue=1,Q=$.slice.call(arguments,1),j=Object.create(this.lexer),ne={yy:{}};for(var te in this.yy)Object.prototype.hasOwnProperty.call(this.yy,te)&&(ne.yy[te]=this.yy[te]);j.setInput(M,ne.yy),ne.yy.lexer=j,ne.yy.parser=this,typeof j.yylloc>"u"&&(j.yylloc={});var he=j.yylloc;$.push(he);var le=j.options&&j.options.ranges;typeof ne.yy.parseError=="function"?this.parseError=ne.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function J(ie){B.length=B.length-2*ie,z.length=z.length-ie,$.length=$.length-ie}o(J,"popStack");function Se(){var ie;return ie=F.pop()||j.lex()||ue,typeof ie!="number"&&(ie instanceof Array&&(F=ie,ie=F.pop()),ie=P.symbols_[ie]||ie),ie}o(Se,"lex");for(var se,ae,Oe,ye,Be,He,ze={},Le,Ie,xe,q;;){if(Oe=B[B.length-1],this.defaultActions[Oe]?ye=this.defaultActions[Oe]:((se===null||typeof se>"u")&&(se=Se()),ye=U[Oe]&&U[Oe][se]),typeof ye>"u"||!ye.length||!ye[0]){var de="";q=[];for(Le in U[Oe])this.terminals_[Le]&&Le>Z&&q.push("'"+this.terminals_[Le]+"'");j.showPosition?de="Parse error on line "+(ee+1)+`: +`+j.showPosition()+` +Expecting `+q.join(", ")+", got '"+(this.terminals_[se]||se)+"'":de="Parse error on line "+(ee+1)+": Unexpected "+(se==ue?"end of input":"'"+(this.terminals_[se]||se)+"'"),this.parseError(de,{text:j.match,token:this.terminals_[se]||se,line:j.yylineno,loc:he,expected:q})}if(ye[0]instanceof Array&&ye.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Oe+", token: "+se);switch(ye[0]){case 1:B.push(se),z.push(j.yytext),$.push(j.yylloc),B.push(ye[1]),se=null,ae?(se=ae,ae=null):(Y=j.yyleng,K=j.yytext,ee=j.yylineno,he=j.yylloc,ce>0&&ce--);break;case 2:if(Ie=this.productions_[ye[1]][1],ze.$=z[z.length-Ie],ze._$={first_line:$[$.length-(Ie||1)].first_line,last_line:$[$.length-1].last_line,first_column:$[$.length-(Ie||1)].first_column,last_column:$[$.length-1].last_column},le&&(ze._$.range=[$[$.length-(Ie||1)].range[0],$[$.length-1].range[1]]),He=this.performAction.apply(ze,[K,Y,ee,ne.yy,ye[1],z,$].concat(Q)),typeof He<"u")return He;Ie&&(B=B.slice(0,-1*Ie*2),z=z.slice(0,-1*Ie),$=$.slice(0,-1*Ie)),B.push(this.productions_[ye[1]][0]),z.push(ze.$),$.push(ze._$),xe=U[B[B.length-2]][B[B.length-1]],B.push(xe);break;case 3:return!0}}return!0},"parse")},L=function(){var I={EOF:1,parseError:o(function(P,B){if(this.yy.parser)this.yy.parser.parseError(P,B);else throw new Error(P)},"parseError"),setInput:o(function(M,P){return this.yy=P||this.yy||{},this._input=M,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var M=this._input[0];this.yytext+=M,this.yyleng++,this.offset++,this.match+=M,this.matched+=M;var P=M.match(/(?:\r\n?|\n).*/g);return P?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),M},"input"),unput:o(function(M){var P=M.length,B=M.split(/(?:\r\n?|\n)/g);this._input=M+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-P),this.offset-=P;var F=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),B.length-1&&(this.yylineno-=B.length-1);var z=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:B?(B.length===F.length?this.yylloc.first_column:0)+F[F.length-B.length].length-B[0].length:this.yylloc.first_column-P},this.options.ranges&&(this.yylloc.range=[z[0],z[0]+this.yyleng-P]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(M){this.unput(this.match.slice(M))},"less"),pastInput:o(function(){var M=this.matched.substr(0,this.matched.length-this.match.length);return(M.length>20?"...":"")+M.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var M=this.match;return M.length<20&&(M+=this._input.substr(0,20-M.length)),(M.substr(0,20)+(M.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var M=this.pastInput(),P=new Array(M.length+1).join("-");return M+this.upcomingInput()+` +`+P+"^"},"showPosition"),test_match:o(function(M,P){var B,F,z;if(this.options.backtrack_lexer&&(z={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(z.yylloc.range=this.yylloc.range.slice(0))),F=M[0].match(/(?:\r\n?|\n).*/g),F&&(this.yylineno+=F.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:F?F[F.length-1].length-F[F.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+M[0].length},this.yytext+=M[0],this.match+=M[0],this.matches=M,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(M[0].length),this.matched+=M[0],B=this.performAction.call(this,this.yy,this,P,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),B)return B;if(this._backtrack){for(var $ in z)this[$]=z[$];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var M,P,B,F;this._more||(this.yytext="",this.match="");for(var z=this._currentRules(),$=0;$P[0].length)){if(P=B,F=$,this.options.backtrack_lexer){if(M=this.test_match(B,z[$]),M!==!1)return M;if(this._backtrack){P=!1;continue}else return!1}else if(!this.options.flex)break}return P?(M=this.test_match(P,z[F]),M!==!1?M:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var P=this.next();return P||this.lex()},"lex"),begin:o(function(P){this.conditionStack.push(P)},"begin"),popState:o(function(){var P=this.conditionStack.length-1;return P>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(P){return P=this.conditionStack.length-1-Math.abs(P||0),P>=0?this.conditionStack[P]:"INITIAL"},"topState"),pushState:o(function(P){this.begin(P)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(P,B,F,z){var $=z;switch(F){case 0:break;case 1:break;case 2:return this.popState(),34;break;case 3:return this.popState(),34;break;case 4:return 34;case 5:break;case 6:return 10;case 7:return this.pushState("acc_title"),19;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.pushState("acc_descr"),21;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.pushState("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";break;case 17:return this.pushState("axis_data"),"Y_AXIS";break;case 18:return this.pushState("axis_band_data"),24;break;case 19:return 31;case 20:return this.pushState("data"),16;break;case 21:return this.pushState("data"),18;break;case 22:return this.pushState("data_inner"),24;break;case 23:return 27;case 24:return this.popState(),26;break;case 25:this.popState();break;case 26:this.pushState("string");break;case 27:this.popState();break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 43:break;case 44:return 35;case 45:return 36}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};return I}();k.lexer=L;function A(){this.yy={}}return o(A,"Parser"),A.prototype=k,k.Parser=A,new A}();tP.parser=tP;Hfe=tP});function rP(t){return t.type==="bar"}function BS(t){return t.type==="band"}function N1(t){return t.type==="linear"}var FS=N(()=>{"use strict";o(rP,"isBarPlot");o(BS,"isBandAxisData");o(N1,"isLinearAxisData")});var M1,nP=N(()=>{"use strict";ao();M1=class{constructor(e){this.parentGroup=e}static{o(this,"TextDimensionCalculatorWithFont")}getMaxDimension(e,r){if(!this.parentGroup)return{width:e.reduce((a,s)=>Math.max(s.length,a),0)*r,height:r};let n={width:0,height:0},i=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",r);for(let a of e){let s=wQ(i,1,a),l=s?s.width:a.length*r,u=s?s.height:r;n.width=Math.max(n.width,l),n.height=Math.max(n.height,u)}return i.remove(),n}}});var I1,iP=N(()=>{"use strict";I1=class{constructor(e,r,n,i){this.axisConfig=e;this.title=r;this.textDimensionCalculator=n;this.axisThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0};this.axisPosition="left";this.showTitle=!1;this.showLabel=!1;this.showTick=!1;this.showAxisLine=!1;this.outerPadding=0;this.titleTextHeight=0;this.labelTextHeight=0;this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}static{o(this,"BaseAxis")}setRange(e){this.range=e,this.axisPosition==="left"||this.axisPosition==="right"?this.boundingRect.height=e[1]-e[0]:this.boundingRect.width=e[1]-e[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(e){this.axisPosition=e,this.setRange(this.range)}getTickDistance(){let e=this.getRange();return Math.abs(e[0]-e[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(e=>e.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>this.outerPadding*2&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(e){let r=e.height;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.width;this.outerPadding=Math.min(n.width/2,i);let a=n.height+this.axisConfig.labelPadding*2;this.labelTextHeight=n.height,a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width,this.boundingRect.height=e.height-r}calculateSpaceIfDrawnVertical(e){let r=e.width;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.height;this.outerPadding=Math.min(n.height/2,i);let a=n.width+this.axisConfig.labelPadding*2;a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width-r,this.boundingRect.height=e.height}calculateSpace(e){return this.axisPosition==="left"||this.axisPosition==="right"?this.calculateSpaceIfDrawnVertical(e):this.calculateSpaceIfDrawnHorizontally(e),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}getDrawableElementsForLeftAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${r},${this.boundingRect.y} L ${r},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(r),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){let r=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${r},${this.getScaleValue(n)} L ${r-this.axisConfig.tickLength},${this.getScaleValue(n)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForBottomAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r} L ${this.getScaleValue(n)},${r+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForTopAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+this.axisConfig.titlePadding*2:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y;e.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(n)},${r+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElements(){if(this.axisPosition==="left")return this.getDrawableElementsForLeftAxis();if(this.axisPosition==="right")throw Error("Drawing of right axis is not implemented");return this.axisPosition==="bottom"?this.getDrawableElementsForBottomAxis():this.axisPosition==="top"?this.getDrawableElementsForTopAxis():[]}}});var $S,qfe=N(()=>{"use strict";fr();yt();iP();$S=class extends I1{static{o(this,"BandAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.categories=n,this.scale=V0().domain(this.categories).range(this.getRange())}setRange(e){super.setRange(e)}recalculateScale(){this.scale=V0().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),X.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(e){return this.scale(e)??this.getRange()[0]}}});var zS,Yfe=N(()=>{"use strict";fr();iP();zS=class extends I1{static{o(this,"LinearAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.domain=n,this.scale=Tl().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){let e=[...this.domain];this.axisPosition==="left"&&e.reverse(),this.scale=Tl().domain(e).range(this.getRange())}getScaleValue(e){return this.scale(e)}}});function aP(t,e,r,n){let i=new M1(n);return BS(t)?new $S(e,r,t.categories,t.title,i):new zS(e,r,[t.min,t.max],t.title,i)}var Xfe=N(()=>{"use strict";FS();nP();qfe();Yfe();o(aP,"getAxis")});function jfe(t,e,r,n){let i=new M1(n);return new sP(i,t,e,r)}var sP,Kfe=N(()=>{"use strict";nP();sP=class{constructor(e,r,n,i){this.textDimensionCalculator=e;this.chartConfig=r;this.chartData=n;this.chartThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}static{o(this,"ChartTitle")}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){let r=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),n=Math.max(r.width,e.width),i=r.height+2*this.chartConfig.titlePadding;return r.width<=n&&r.height<=i&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=n,this.boundingRect.height=i,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){let e=[];return this.showChartTitle&&e.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),e}};o(jfe,"getChartTitleComponent")});var GS,Qfe=N(()=>{"use strict";fr();GS=class{constructor(e,r,n,i,a){this.plotData=e;this.xAxis=r;this.yAxis=n;this.orientation=i;this.plotIndex=a}static{o(this,"LinePlot")}getDrawableElement(){let e=this.plotData.data.map(n=>[this.xAxis.getScaleValue(n[0]),this.yAxis.getScaleValue(n[1])]),r;return this.orientation==="horizontal"?r=Cl().y(n=>n[0]).x(n=>n[1])(e):r=Cl().x(n=>n[0]).y(n=>n[1])(e),r?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:r,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}});var VS,Zfe=N(()=>{"use strict";VS=class{constructor(e,r,n,i,a,s){this.barData=e;this.boundingRect=r;this.xAxis=n;this.yAxis=i;this.orientation=a;this.plotIndex=s}static{o(this,"BarPlot")}getDrawableElement(){let e=this.barData.data.map(a=>[this.xAxis.getScaleValue(a[0]),this.yAxis.getScaleValue(a[1])]),n=Math.min(this.xAxis.getAxisOuterPadding()*2,this.xAxis.getTickDistance())*(1-.05),i=n/2;return this.orientation==="horizontal"?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:this.boundingRect.x,y:a[0]-i,height:n,width:a[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:a[0]-i,y:a[1],width:n,height:this.boundingRect.y+this.boundingRect.height-a[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}}});function Jfe(t,e,r){return new oP(t,e,r)}var oP,ede=N(()=>{"use strict";Qfe();Zfe();oP=class{constructor(e,r,n){this.chartConfig=e;this.chartData=r;this.chartThemeConfig=n;this.boundingRect={x:0,y:0,width:0,height:0}}static{o(this,"BasePlot")}setAxes(e,r){this.xAxis=e,this.yAxis=r}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){return this.boundingRect.width=e.width,this.boundingRect.height=e.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!(this.xAxis&&this.yAxis))throw Error("Axes must be passed to render Plots");let e=[];for(let[r,n]of this.chartData.plots.entries())switch(n.type){case"line":{let i=new GS(n,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break;case"bar":{let i=new VS(n,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break}return e}};o(Jfe,"getPlotComponent")});var US,tde=N(()=>{"use strict";Xfe();Kfe();ede();FS();US=class{constructor(e,r,n,i){this.chartConfig=e;this.chartData=r;this.componentStore={title:jfe(e,r,n,i),plot:Jfe(e,r,n),xAxis:aP(r.xAxis,e.xAxis,{titleColor:n.xAxisTitleColor,labelColor:n.xAxisLabelColor,tickColor:n.xAxisTickColor,axisLineColor:n.xAxisLineColor},i),yAxis:aP(r.yAxis,e.yAxis,{titleColor:n.yAxisTitleColor,labelColor:n.yAxisLabelColor,tickColor:n.yAxisTickColor,axisLineColor:n.yAxisLineColor},i)}}static{o(this,"Orchestrator")}calculateVerticalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),s=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),l=this.componentStore.plot.calculateSpace({width:a,height:s});e-=l.width,r-=l.height,l=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),i=l.height,r-=l.height,this.componentStore.xAxis.setAxisPosition("bottom"),l=this.componentStore.xAxis.calculateSpace({width:e,height:r}),r-=l.height,this.componentStore.yAxis.setAxisPosition("left"),l=this.componentStore.yAxis.calculateSpace({width:e,height:r}),n=l.width,e-=l.width,e>0&&(a+=e,e=0),r>0&&(s+=r,r=0),this.componentStore.plot.calculateSpace({width:a,height:s}),this.componentStore.plot.setBoundingBoxXY({x:n,y:i}),this.componentStore.xAxis.setRange([n,n+a]),this.componentStore.xAxis.setBoundingBoxXY({x:n,y:i+s}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:i}),this.chartData.plots.some(u=>rP(u))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=0,s=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),l=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),u=this.componentStore.plot.calculateSpace({width:s,height:l});e-=u.width,r-=u.height,u=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),n=u.height,r-=u.height,this.componentStore.xAxis.setAxisPosition("left"),u=this.componentStore.xAxis.calculateSpace({width:e,height:r}),e-=u.width,i=u.width,this.componentStore.yAxis.setAxisPosition("top"),u=this.componentStore.yAxis.calculateSpace({width:e,height:r}),r-=u.height,a=n+u.height,e>0&&(s+=e,e=0),r>0&&(l+=r,r=0),this.componentStore.plot.calculateSpace({width:s,height:l}),this.componentStore.plot.setBoundingBoxXY({x:i,y:a}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:i,y:n}),this.componentStore.xAxis.setRange([a,a+l]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:a}),this.chartData.plots.some(h=>rP(h))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){this.chartConfig.chartOrientation==="horizontal"?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();let e=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(let r of Object.values(this.componentStore))e.push(...r.getDrawableElements());return e}}});var HS,rde=N(()=>{"use strict";tde();HS=class{static{o(this,"XYChartBuilder")}static build(e,r,n,i){return new US(e,r,n,i).getDrawableElement()}}});function ide(){let t=dh(),e=tr();return $n(t.xyChart,e.themeVariables.xyChart)}function ade(){let t=tr();return $n(or.xyChart,t.xyChart)}function sde(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function uP(t){let e=tr();return wr(t.trim(),e)}function dUe(t){nde=t}function pUe(t){t==="horizontal"?Rb.chartOrientation="horizontal":Rb.chartOrientation="vertical"}function mUe(t){cn.xAxis.title=uP(t.text)}function ode(t,e){cn.xAxis={type:"linear",title:cn.xAxis.title,min:t,max:e},WS=!0}function gUe(t){cn.xAxis={type:"band",title:cn.xAxis.title,categories:t.map(e=>uP(e.text))},WS=!0}function yUe(t){cn.yAxis.title=uP(t.text)}function vUe(t,e){cn.yAxis={type:"linear",title:cn.yAxis.title,min:t,max:e},cP=!0}function xUe(t){let e=Math.min(...t),r=Math.max(...t),n=N1(cn.yAxis)?cn.yAxis.min:1/0,i=N1(cn.yAxis)?cn.yAxis.max:-1/0;cn.yAxis={type:"linear",title:cn.yAxis.title,min:Math.min(n,e),max:Math.max(i,r)}}function lde(t){let e=[];if(t.length===0)return e;if(!WS){let r=N1(cn.xAxis)?cn.xAxis.min:1/0,n=N1(cn.xAxis)?cn.xAxis.max:-1/0;ode(Math.min(r,1),Math.max(n,t.length))}if(cP||xUe(t),BS(cn.xAxis)&&(e=cn.xAxis.categories.map((r,n)=>[r,t[n]])),N1(cn.xAxis)){let r=cn.xAxis.min,n=cn.xAxis.max,i=(n-r)/(t.length-1),a=[];for(let s=r;s<=n;s+=i)a.push(`${s}`);e=a.map((s,l)=>[s,t[l]])}return e}function cde(t){return lP[t===0?0:t%lP.length]}function bUe(t,e){let r=lde(e);cn.plots.push({type:"line",strokeFill:cde(Lb),strokeWidth:2,data:r}),Lb++}function TUe(t,e){let r=lde(e);cn.plots.push({type:"bar",fill:cde(Lb),data:r}),Lb++}function wUe(){if(cn.plots.length===0)throw Error("No Plot to render, please provide a plot with some data");return cn.title=Nr(),HS.build(Rb,cn,Nb,nde)}function kUe(){return Nb}function EUe(){return Rb}function SUe(){return cn}var Lb,nde,Rb,Nb,cn,lP,WS,cP,CUe,ude,hde=N(()=>{"use strict";mi();_a();By();er();pr();ci();rde();FS();Lb=0,Rb=ade(),Nb=ide(),cn=sde(),lP=Nb.plotColorPalette.split(",").map(t=>t.trim()),WS=!1,cP=!1;o(ide,"getChartDefaultThemeConfig");o(ade,"getChartDefaultConfig");o(sde,"getChartDefaultData");o(uP,"textSanitizer");o(dUe,"setTmpSVGG");o(pUe,"setOrientation");o(mUe,"setXAxisTitle");o(ode,"setXAxisRangeData");o(gUe,"setXAxisBand");o(yUe,"setYAxisTitle");o(vUe,"setYAxisRangeData");o(xUe,"setYAxisRangeFromPlotData");o(lde,"transformDataWithoutCategory");o(cde,"getPlotColorFromPalette");o(bUe,"setLineData");o(TUe,"setBarData");o(wUe,"getDrawableElem");o(kUe,"getChartThemeConfig");o(EUe,"getChartConfig");o(SUe,"getXYChartData");CUe=o(function(){kr(),Lb=0,Rb=ade(),cn=sde(),Nb=ide(),lP=Nb.plotColorPalette.split(",").map(t=>t.trim()),WS=!1,cP=!1},"clear"),ude={getDrawableElem:wUe,clear:CUe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr,setOrientation:pUe,setXAxisTitle:mUe,setXAxisRangeData:ode,setXAxisBand:gUe,setYAxisTitle:yUe,setYAxisRangeData:vUe,setLineData:bUe,setBarData:TUe,setTmpSVGG:dUe,getChartThemeConfig:kUe,getChartConfig:EUe,getXYChartData:SUe}});var AUe,fde,dde=N(()=>{"use strict";yt();Vl();xi();AUe=o((t,e,r,n)=>{let i=n.db,a=i.getChartThemeConfig(),s=i.getChartConfig(),l=i.getXYChartData().plots[0].data.map(T=>T[1]);function u(T){return T==="top"?"text-before-edge":"middle"}o(u,"getDominantBaseLine");function h(T){return T==="left"?"start":T==="right"?"end":"middle"}o(h,"getTextAnchor");function f(T){return`translate(${T.x}, ${T.y}) rotate(${T.rotation||0})`}o(f,"getTextTransformation"),X.debug(`Rendering xychart chart +`+t);let d=Li(e),p=d.append("g").attr("class","main"),m=p.append("rect").attr("width",s.width).attr("height",s.height).attr("class","background");fn(d,s.height,s.width,!0),d.attr("viewBox",`0 0 ${s.width} ${s.height}`),m.attr("fill",a.backgroundColor),i.setTmpSVGG(d.append("g").attr("class","mermaid-tmp-group"));let g=i.getDrawableElem(),y={};function v(T){let S=p,w="";for(let[E]of T.entries()){let _=p;E>0&&y[w]&&(_=y[w]),w+=T[E],S=y[w],S||(S=y[w]=_.append("g").attr("class",T[E]))}return S}o(v,"getGroup");for(let T of g){if(T.data.length===0)continue;let S=v(T.groupTexts);switch(T.type){case"rect":if(S.selectAll("rect").data(T.data).enter().append("rect").attr("x",w=>w.x).attr("y",w=>w.y).attr("width",w=>w.width).attr("height",w=>w.height).attr("fill",w=>w.fill).attr("stroke",w=>w.strokeFill).attr("stroke-width",w=>w.strokeWidth),s.showDataLabel)if(s.chartOrientation==="horizontal"){let _=function(O,R){let{data:k,label:L}=O;return R*L.length*.7<=k.width-10};var x=_;o(_,"fitsHorizontally");let w=.7,E=T.data.map((O,R)=>({data:O,label:l[R].toString()})).filter(O=>O.data.width>0&&O.data.height>0),C=E.map(O=>{let{data:R}=O,k=R.height*.7;for(;!_(O,k)&&k>0;)k-=1;return k}),D=Math.floor(Math.min(...C));S.selectAll("text").data(E).enter().append("text").attr("x",O=>O.data.x+O.data.width-10).attr("y",O=>O.data.y+O.data.height/2).attr("text-anchor","end").attr("dominant-baseline","middle").attr("fill","black").attr("font-size",`${D}px`).text(O=>O.label)}else{let _=function(O,R,k){let{data:L,label:A}=O,M=R*A.length*.7,P=L.x+L.width/2,B=P-M/2,F=P+M/2,z=B>=L.x&&F<=L.x+L.width,$=L.y+k+R<=L.y+L.height;return z&&$};var b=_;o(_,"fitsInBar");let w=10,E=T.data.map((O,R)=>({data:O,label:l[R].toString()})).filter(O=>O.data.width>0&&O.data.height>0),C=E.map(O=>{let{data:R,label:k}=O,L=R.width/(k.length*.7);for(;!_(O,L,10)&&L>0;)L-=1;return L}),D=Math.floor(Math.min(...C));S.selectAll("text").data(E).enter().append("text").attr("x",O=>O.data.x+O.data.width/2).attr("y",O=>O.data.y+10).attr("text-anchor","middle").attr("dominant-baseline","hanging").attr("fill","black").attr("font-size",`${D}px`).text(O=>O.label)}break;case"text":S.selectAll("text").data(T.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",w=>w.fill).attr("font-size",w=>w.fontSize).attr("dominant-baseline",w=>u(w.verticalPos)).attr("text-anchor",w=>h(w.horizontalPos)).attr("transform",w=>f(w)).text(w=>w.text);break;case"path":S.selectAll("path").data(T.data).enter().append("path").attr("d",w=>w.path).attr("fill",w=>w.fill?w.fill:"none").attr("stroke",w=>w.strokeFill).attr("stroke-width",w=>w.strokeWidth);break}}},"draw"),fde={draw:AUe}});var pde={};ur(pde,{diagram:()=>_Ue});var _Ue,mde=N(()=>{"use strict";Wfe();hde();dde();_Ue={parser:Hfe,db:ude,renderer:fde}});var hP,vde,xde=N(()=>{"use strict";hP=function(){var t=o(function(ie,oe,V,Te){for(V=V||{},Te=ie.length;Te--;V[ie[Te]]=oe);return V},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],s=[1,22],l=[2,7],u=[1,26],h=[1,27],f=[1,28],d=[1,29],p=[1,33],m=[1,34],g=[1,35],y=[1,36],v=[1,37],x=[1,38],b=[1,24],T=[1,31],S=[1,32],w=[1,30],E=[1,39],_=[1,40],C=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],D=[1,61],O=[89,90],R=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],k=[27,29],L=[1,70],A=[1,71],I=[1,72],M=[1,73],P=[1,74],B=[1,75],F=[1,76],z=[1,83],$=[1,80],U=[1,84],K=[1,85],ee=[1,86],Y=[1,87],ce=[1,88],Z=[1,89],ue=[1,90],Q=[1,91],j=[1,92],ne=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],te=[63,64],he=[1,101],le=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],J=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Se=[1,110],se=[1,106],ae=[1,107],Oe=[1,108],ye=[1,109],Be=[1,111],He=[1,116],ze=[1,117],Le=[1,114],Ie=[1,115],xe={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:o(function(oe,V,Te,W,pe,ve,Pe){var _e=ve.length-1;switch(pe){case 4:this.$=ve[_e].trim(),W.setAccTitle(this.$);break;case 5:case 6:this.$=ve[_e].trim(),W.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:W.setDirection("TB");break;case 18:W.setDirection("BT");break;case 19:W.setDirection("RL");break;case 20:W.setDirection("LR");break;case 21:W.addRequirement(ve[_e-3],ve[_e-4]);break;case 22:W.addRequirement(ve[_e-5],ve[_e-6]),W.setClass([ve[_e-5]],ve[_e-3]);break;case 23:W.setNewReqId(ve[_e-2]);break;case 24:W.setNewReqText(ve[_e-2]);break;case 25:W.setNewReqRisk(ve[_e-2]);break;case 26:W.setNewReqVerifyMethod(ve[_e-2]);break;case 29:this.$=W.RequirementType.REQUIREMENT;break;case 30:this.$=W.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=W.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=W.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=W.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=W.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=W.RiskLevel.LOW_RISK;break;case 36:this.$=W.RiskLevel.MED_RISK;break;case 37:this.$=W.RiskLevel.HIGH_RISK;break;case 38:this.$=W.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=W.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=W.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=W.VerifyType.VERIFY_TEST;break;case 42:W.addElement(ve[_e-3]);break;case 43:W.addElement(ve[_e-5]),W.setClass([ve[_e-5]],ve[_e-3]);break;case 44:W.setNewElementType(ve[_e-2]);break;case 45:W.setNewElementDocRef(ve[_e-2]);break;case 48:W.addRelationship(ve[_e-2],ve[_e],ve[_e-4]);break;case 49:W.addRelationship(ve[_e-2],ve[_e-4],ve[_e]);break;case 50:this.$=W.Relationships.CONTAINS;break;case 51:this.$=W.Relationships.COPIES;break;case 52:this.$=W.Relationships.DERIVES;break;case 53:this.$=W.Relationships.SATISFIES;break;case 54:this.$=W.Relationships.VERIFIES;break;case 55:this.$=W.Relationships.REFINES;break;case 56:this.$=W.Relationships.TRACES;break;case 57:this.$=ve[_e-2],W.defineClass(ve[_e-1],ve[_e]);break;case 58:W.setClass(ve[_e-1],ve[_e]);break;case 59:W.setClass([ve[_e-2]],ve[_e]);break;case 60:case 62:this.$=[ve[_e]];break;case 61:case 63:this.$=ve[_e-2].concat([ve[_e]]);break;case 64:this.$=ve[_e-2],W.setCssStyle(ve[_e-1],ve[_e]);break;case 65:this.$=[ve[_e]];break;case 66:ve[_e-2].push(ve[_e]),this.$=ve[_e-2];break;case 68:this.$=ve[_e-1]+ve[_e];break}},"anonymous"),table:[{3:1,4:2,6:e,9:r,11:n,13:i},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:r,11:n,13:i},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(a,[2,6]),{3:12,4:2,6:e,9:r,11:n,13:i},{1:[2,2]},{4:17,5:s,7:13,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},t(a,[2,4]),t(a,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:s,7:42,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:43,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:44,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:45,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:46,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:47,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:48,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:49,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:50,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},t(C,[2,17]),t(C,[2,18]),t(C,[2,19]),t(C,[2,20]),{30:60,33:62,75:D,89:E,90:_},{30:63,33:62,75:D,89:E,90:_},{30:64,33:62,75:D,89:E,90:_},t(O,[2,29]),t(O,[2,30]),t(O,[2,31]),t(O,[2,32]),t(O,[2,33]),t(O,[2,34]),t(R,[2,81]),t(R,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},t(k,[2,79]),t(k,[2,80]),{27:[1,67],29:[1,68]},t(k,[2,85]),t(k,[2,86]),{62:69,65:L,66:A,67:I,68:M,69:P,70:B,71:F},{62:77,65:L,66:A,67:I,68:M,69:P,70:B,71:F},{30:78,33:62,75:D,89:E,90:_},{73:79,75:z,76:$,78:81,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},t(ne,[2,60]),t(ne,[2,62]),{73:93,75:z,76:$,78:81,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},{30:94,33:62,75:D,76:$,89:E,90:_},{5:[1,95]},{30:96,33:62,75:D,89:E,90:_},{5:[1,97]},{30:98,33:62,75:D,89:E,90:_},{63:[1,99]},t(te,[2,50]),t(te,[2,51]),t(te,[2,52]),t(te,[2,53]),t(te,[2,54]),t(te,[2,55]),t(te,[2,56]),{64:[1,100]},t(C,[2,59],{76:$}),t(C,[2,64],{76:he}),{33:103,75:[1,102],89:E,90:_},t(le,[2,65],{79:104,75:z,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j}),t(J,[2,67]),t(J,[2,69]),t(J,[2,70]),t(J,[2,71]),t(J,[2,72]),t(J,[2,73]),t(J,[2,74]),t(J,[2,75]),t(J,[2,76]),t(J,[2,77]),t(J,[2,78]),t(C,[2,57],{76:he}),t(C,[2,58],{76:$}),{5:Se,28:105,31:se,34:ae,36:Oe,38:ye,40:Be},{27:[1,112],76:$},{5:He,40:ze,56:113,57:Le,59:Ie},{27:[1,118],76:$},{33:119,89:E,90:_},{33:120,89:E,90:_},{75:z,78:121,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},t(ne,[2,61]),t(ne,[2,63]),t(J,[2,68]),t(C,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:Se,28:126,31:se,34:ae,36:Oe,38:ye,40:Be},t(C,[2,28]),{5:[1,127]},t(C,[2,42]),{32:[1,128]},{32:[1,129]},{5:He,40:ze,56:130,57:Le,59:Ie},t(C,[2,47]),{5:[1,131]},t(C,[2,48]),t(C,[2,49]),t(le,[2,66],{79:104,75:z,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j}),{33:132,89:E,90:_},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},t(C,[2,27]),{5:Se,28:145,31:se,34:ae,36:Oe,38:ye,40:Be},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},t(C,[2,46]),{5:He,40:ze,56:152,57:Le,59:Ie},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},t(C,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},t(C,[2,43]),{5:Se,28:159,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:160,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:161,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:162,31:se,34:ae,36:Oe,38:ye,40:Be},{5:He,40:ze,56:163,57:Le,59:Ie},{5:He,40:ze,56:164,57:Le,59:Ie},t(C,[2,23]),t(C,[2,24]),t(C,[2,25]),t(C,[2,26]),t(C,[2,44]),t(C,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:o(function(oe,V){if(V.recoverable)this.trace(oe);else{var Te=new Error(oe);throw Te.hash=V,Te}},"parseError"),parse:o(function(oe){var V=this,Te=[0],W=[],pe=[null],ve=[],Pe=this.table,_e="",be=0,Ve=0,De=0,qe=2,at=1,Rt=ve.slice.call(arguments,1),st=Object.create(this.lexer),Ue={yy:{}};for(var ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ct)&&(Ue.yy[ct]=this.yy[ct]);st.setInput(oe,Ue.yy),Ue.yy.lexer=st,Ue.yy.parser=this,typeof st.yylloc>"u"&&(st.yylloc={});var We=st.yylloc;ve.push(We);var ot=st.options&&st.options.ranges;typeof Ue.yy.parseError=="function"?this.parseError=Ue.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Yt(Ir){Te.length=Te.length-2*Ir,pe.length=pe.length-Ir,ve.length=ve.length-Ir}o(Yt,"popStack");function Tt(){var Ir;return Ir=W.pop()||st.lex()||at,typeof Ir!="number"&&(Ir instanceof Array&&(W=Ir,Ir=W.pop()),Ir=V.symbols_[Ir]||Ir),Ir}o(Tt,"lex");for(var Mt,bt,ut,St,ft,vt,nt={},pn,kt,On,tn;;){if(ut=Te[Te.length-1],this.defaultActions[ut]?St=this.defaultActions[ut]:((Mt===null||typeof Mt>"u")&&(Mt=Tt()),St=Pe[ut]&&Pe[ut][Mt]),typeof St>"u"||!St.length||!St[0]){var Mr="";tn=[];for(pn in Pe[ut])this.terminals_[pn]&&pn>qe&&tn.push("'"+this.terminals_[pn]+"'");st.showPosition?Mr="Parse error on line "+(be+1)+`: +`+st.showPosition()+` +Expecting `+tn.join(", ")+", got '"+(this.terminals_[Mt]||Mt)+"'":Mr="Parse error on line "+(be+1)+": Unexpected "+(Mt==at?"end of input":"'"+(this.terminals_[Mt]||Mt)+"'"),this.parseError(Mr,{text:st.match,token:this.terminals_[Mt]||Mt,line:st.yylineno,loc:We,expected:tn})}if(St[0]instanceof Array&&St.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ut+", token: "+Mt);switch(St[0]){case 1:Te.push(Mt),pe.push(st.yytext),ve.push(st.yylloc),Te.push(St[1]),Mt=null,bt?(Mt=bt,bt=null):(Ve=st.yyleng,_e=st.yytext,be=st.yylineno,We=st.yylloc,De>0&&De--);break;case 2:if(kt=this.productions_[St[1]][1],nt.$=pe[pe.length-kt],nt._$={first_line:ve[ve.length-(kt||1)].first_line,last_line:ve[ve.length-1].last_line,first_column:ve[ve.length-(kt||1)].first_column,last_column:ve[ve.length-1].last_column},ot&&(nt._$.range=[ve[ve.length-(kt||1)].range[0],ve[ve.length-1].range[1]]),vt=this.performAction.apply(nt,[_e,Ve,be,Ue.yy,St[1],pe,ve].concat(Rt)),typeof vt<"u")return vt;kt&&(Te=Te.slice(0,-1*kt*2),pe=pe.slice(0,-1*kt),ve=ve.slice(0,-1*kt)),Te.push(this.productions_[St[1]][0]),pe.push(nt.$),ve.push(nt._$),On=Pe[Te[Te.length-2]][Te[Te.length-1]],Te.push(On);break;case 3:return!0}}return!0},"parse")},q=function(){var ie={EOF:1,parseError:o(function(V,Te){if(this.yy.parser)this.yy.parser.parseError(V,Te);else throw new Error(V)},"parseError"),setInput:o(function(oe,V){return this.yy=V||this.yy||{},this._input=oe,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var oe=this._input[0];this.yytext+=oe,this.yyleng++,this.offset++,this.match+=oe,this.matched+=oe;var V=oe.match(/(?:\r\n?|\n).*/g);return V?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),oe},"input"),unput:o(function(oe){var V=oe.length,Te=oe.split(/(?:\r\n?|\n)/g);this._input=oe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-V),this.offset-=V;var W=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Te.length-1&&(this.yylineno-=Te.length-1);var pe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Te?(Te.length===W.length?this.yylloc.first_column:0)+W[W.length-Te.length].length-Te[0].length:this.yylloc.first_column-V},this.options.ranges&&(this.yylloc.range=[pe[0],pe[0]+this.yyleng-V]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(oe){this.unput(this.match.slice(oe))},"less"),pastInput:o(function(){var oe=this.matched.substr(0,this.matched.length-this.match.length);return(oe.length>20?"...":"")+oe.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var oe=this.match;return oe.length<20&&(oe+=this._input.substr(0,20-oe.length)),(oe.substr(0,20)+(oe.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var oe=this.pastInput(),V=new Array(oe.length+1).join("-");return oe+this.upcomingInput()+` +`+V+"^"},"showPosition"),test_match:o(function(oe,V){var Te,W,pe;if(this.options.backtrack_lexer&&(pe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(pe.yylloc.range=this.yylloc.range.slice(0))),W=oe[0].match(/(?:\r\n?|\n).*/g),W&&(this.yylineno+=W.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:W?W[W.length-1].length-W[W.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+oe[0].length},this.yytext+=oe[0],this.match+=oe[0],this.matches=oe,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(oe[0].length),this.matched+=oe[0],Te=this.performAction.call(this,this.yy,this,V,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Te)return Te;if(this._backtrack){for(var ve in pe)this[ve]=pe[ve];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var oe,V,Te,W;this._more||(this.yytext="",this.match="");for(var pe=this._currentRules(),ve=0;veV[0].length)){if(V=Te,W=ve,this.options.backtrack_lexer){if(oe=this.test_match(Te,pe[ve]),oe!==!1)return oe;if(this._backtrack){V=!1;continue}else return!1}else if(!this.options.flex)break}return V?(oe=this.test_match(V,pe[W]),oe!==!1?oe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var V=this.next();return V||this.lex()},"lex"),begin:o(function(V){this.conditionStack.push(V)},"begin"),popState:o(function(){var V=this.conditionStack.length-1;return V>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(V){return V=this.conditionStack.length-1-Math.abs(V||0),V>=0?this.conditionStack[V]:"INITIAL"},"topState"),pushState:o(function(V){this.begin(V)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(V,Te,W,pe){var ve=pe;switch(W){case 0:return"title";case 1:return this.begin("acc_title"),9;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),11;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 21;case 9:return 22;case 10:return 23;case 11:return 24;case 12:return 5;case 13:break;case 14:break;case 15:break;case 16:return 8;case 17:return 6;case 18:return 27;case 19:return 40;case 20:return 29;case 21:return 32;case 22:return 31;case 23:return 34;case 24:return 36;case 25:return 38;case 26:return 41;case 27:return 42;case 28:return 43;case 29:return 44;case 30:return 45;case 31:return 46;case 32:return 47;case 33:return 48;case 34:return 49;case 35:return 50;case 36:return 51;case 37:return 52;case 38:return 53;case 39:return 54;case 40:return 65;case 41:return 66;case 42:return 67;case 43:return 68;case 44:return 69;case 45:return 70;case 46:return 71;case 47:return 57;case 48:return 59;case 49:return this.begin("style"),77;break;case 50:return 75;case 51:return 81;case 52:return 88;case 53:return"PERCENT";case 54:return 86;case 55:return 84;case 56:break;case 57:this.begin("string");break;case 58:this.popState();break;case 59:return this.begin("style"),72;break;case 60:return this.begin("style"),74;break;case 61:return 61;case 62:return 64;case 63:return 63;case 64:this.begin("string");break;case 65:this.popState();break;case 66:return"qString";case 67:return Te.yytext=Te.yytext.trim(),89;break;case 68:return 75;case 69:return 80;case 70:return 76}},"anonymous"),rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::{3})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:style\b)/i,/^(?:\w+)/i,/^(?::)/i,/^(?:;)/i,/^(?:%)/i,/^(?:-)/i,/^(?:#)/i,/^(?: )/i,/^(?:["])/i,/^(?:\n)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^:,\r\n\{\<\>\-\=]*)/i,/^(?:\w+)/i,/^(?:[0-9]+)/i,/^(?:,)/i],conditions:{acc_descr_multiline:{rules:[6,7,68,69,70],inclusive:!1},acc_descr:{rules:[4,68,69,70],inclusive:!1},acc_title:{rules:[2,68,69,70],inclusive:!1},style:{rules:[50,51,52,53,54,55,56,57,58,68,69,70],inclusive:!1},unqString:{rules:[68,69,70],inclusive:!1},token:{rules:[68,69,70],inclusive:!1},string:{rules:[65,66,68,69,70],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,59,60,61,62,63,64,67,68,69,70],inclusive:!0}}};return ie}();xe.lexer=q;function de(){this.yy={}}return o(de,"Parser"),de.prototype=xe,xe.Parser=de,new de}();hP.parser=hP;vde=hP});var qS,bde=N(()=>{"use strict";Gt();yt();ci();qS=class{constructor(){this.relations=[];this.latestRequirement=this.getInitialRequirement();this.requirements=new Map;this.latestElement=this.getInitialElement();this.elements=new Map;this.classes=new Map;this.direction="TB";this.RequirementType={REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"};this.RiskLevel={LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"};this.VerifyType={VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"};this.Relationships={CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"};this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().requirement,"getConfig");this.clear(),this.setDirection=this.setDirection.bind(this),this.addRequirement=this.addRequirement.bind(this),this.setNewReqId=this.setNewReqId.bind(this),this.setNewReqRisk=this.setNewReqRisk.bind(this),this.setNewReqText=this.setNewReqText.bind(this),this.setNewReqVerifyMethod=this.setNewReqVerifyMethod.bind(this),this.addElement=this.addElement.bind(this),this.setNewElementType=this.setNewElementType.bind(this),this.setNewElementDocRef=this.setNewElementDocRef.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setCssStyle=this.setCssStyle.bind(this),this.setClass=this.setClass.bind(this),this.defineClass=this.defineClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"RequirementDB")}getDirection(){return this.direction}setDirection(e){this.direction=e}resetLatestRequirement(){this.latestRequirement=this.getInitialRequirement()}resetLatestElement(){this.latestElement=this.getInitialElement()}getInitialRequirement(){return{requirementId:"",text:"",risk:"",verifyMethod:"",name:"",type:"",cssStyles:[],classes:["default"]}}getInitialElement(){return{name:"",type:"",docRef:"",cssStyles:[],classes:["default"]}}addRequirement(e,r){return this.requirements.has(e)||this.requirements.set(e,{name:e,type:r,requirementId:this.latestRequirement.requirementId,text:this.latestRequirement.text,risk:this.latestRequirement.risk,verifyMethod:this.latestRequirement.verifyMethod,cssStyles:[],classes:["default"]}),this.resetLatestRequirement(),this.requirements.get(e)}getRequirements(){return this.requirements}setNewReqId(e){this.latestRequirement!==void 0&&(this.latestRequirement.requirementId=e)}setNewReqText(e){this.latestRequirement!==void 0&&(this.latestRequirement.text=e)}setNewReqRisk(e){this.latestRequirement!==void 0&&(this.latestRequirement.risk=e)}setNewReqVerifyMethod(e){this.latestRequirement!==void 0&&(this.latestRequirement.verifyMethod=e)}addElement(e){return this.elements.has(e)||(this.elements.set(e,{name:e,type:this.latestElement.type,docRef:this.latestElement.docRef,cssStyles:[],classes:["default"]}),X.info("Added new element: ",e)),this.resetLatestElement(),this.elements.get(e)}getElements(){return this.elements}setNewElementType(e){this.latestElement!==void 0&&(this.latestElement.type=e)}setNewElementDocRef(e){this.latestElement!==void 0&&(this.latestElement.docRef=e)}addRelationship(e,r,n){this.relations.push({type:e,src:r,dst:n})}getRelationships(){return this.relations}clear(){this.relations=[],this.resetLatestRequirement(),this.requirements=new Map,this.resetLatestElement(),this.elements=new Map,this.classes=new Map,kr()}setCssStyle(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(!r||!i)return;for(let a of r)a.includes(",")?i.cssStyles.push(...a.split(",")):i.cssStyles.push(a)}}setClass(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(i)for(let a of r){i.classes.push(a);let s=this.classes.get(a)?.styles;s&&i.cssStyles.push(...s)}}}defineClass(e,r){for(let n of e){let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.requirements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))}),this.elements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))})}}getClasses(){return this.classes}getData(){let e=me(),r=[],n=[];for(let i of this.requirements.values()){let a=i;a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),a.shape="requirementBox",a.look=e.look,r.push(a)}for(let i of this.elements.values()){let a=i;a.shape="requirementBox",a.look=e.look,a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),r.push(a)}for(let i of this.relations){let a=0,s=i.type===this.Relationships.CONTAINS,l={id:`${i.src}-${i.dst}-${a}`,start:this.requirements.get(i.src)?.name??this.elements.get(i.src)?.name,end:this.requirements.get(i.dst)?.name??this.elements.get(i.dst)?.name,label:`<<${i.type}>>`,classes:"relationshipLine",style:["fill:none",s?"":"stroke-dasharray: 10,7"],labelpos:"c",thickness:"normal",type:"normal",pattern:s?"normal":"dashed",arrowTypeStart:s?"requirement_contains":"",arrowTypeEnd:s?"":"requirement_arrow",look:e.look};n.push(l),a++}return{nodes:r,edges:n,other:{},config:e,direction:this.getDirection()}}}});var NUe,Tde,wde=N(()=>{"use strict";NUe=o(t=>` + + marker { + fill: ${t.relationColor}; + stroke: ${t.relationColor}; + } + + marker.cross { + stroke: ${t.lineColor}; + } + + svg { + font-family: ${t.fontFamily}; + font-size: ${t.fontSize}; + } + + .reqBox { + fill: ${t.requirementBackground}; + fill-opacity: 1.0; + stroke: ${t.requirementBorderColor}; + stroke-width: ${t.requirementBorderSize}; + } + + .reqTitle, .reqLabel{ + fill: ${t.requirementTextColor}; + } + .reqLabelBox { + fill: ${t.relationLabelBackground}; + fill-opacity: 1.0; + } + + .req-title-line { + stroke: ${t.requirementBorderColor}; + stroke-width: ${t.requirementBorderSize}; + } + .relationshipLine { + stroke: ${t.relationColor}; + stroke-width: 1; + } + .relationshipLabel { + fill: ${t.relationLabelColor}; + } + .divider { + stroke: ${t.nodeBorder}; + stroke-width: 1; + } + .label { + font-family: ${t.fontFamily}; + color: ${t.nodeTextColor||t.textColor}; + } + .label text,span { + fill: ${t.nodeTextColor||t.textColor}; + color: ${t.nodeTextColor||t.textColor}; + } + .labelBkg { + background-color: ${t.edgeLabelBackground}; + } + +`,"getStyles"),Tde=NUe});var fP={};ur(fP,{draw:()=>MUe});var MUe,kde=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();MUe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing requirement diagram (unified)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.nodeSpacing=a?.nodeSpacing??50,l.rankSpacing=a?.rankSpacing??50,l.markers=["requirement_contains","requirement_arrow"],l.diagramId=e,await Rc(l,u);let h=8;Vt.insertTitle(u,"requirementDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,"requirementDiagram",a?.useMaxWidth??!0)},"draw")});var Ede={};ur(Ede,{diagram:()=>IUe});var IUe,Sde=N(()=>{"use strict";xde();bde();wde();kde();IUe={parser:vde,get db(){return new qS},renderer:fP,styles:Tde}});var dP,_de,Dde=N(()=>{"use strict";dP=function(){var t=o(function(Q,j,ne,te){for(ne=ne||{},te=Q.length;te--;ne[Q[te]]=j);return ne},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,13],u=[1,14],h=[1,16],f=[1,17],d=[1,18],p=[1,24],m=[1,25],g=[1,26],y=[1,27],v=[1,28],x=[1,29],b=[1,30],T=[1,31],S=[1,32],w=[1,33],E=[1,34],_=[1,35],C=[1,36],D=[1,37],O=[1,38],R=[1,39],k=[1,41],L=[1,42],A=[1,43],I=[1,44],M=[1,45],P=[1,46],B=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],F=[4,5,16,50,52,53],z=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],U=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],K=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],ee=[68,69,70],Y=[1,122],ce={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,BIDIRECTIONAL_SOLID_ARROW:74,DOTTED_ARROW:75,BIDIRECTIONAL_DOTTED_ARROW:76,SOLID_CROSS:77,DOTTED_CROSS:78,SOLID_POINT:79,DOTTED_POINT:80,TXT:81,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"BIDIRECTIONAL_SOLID_ARROW",75:"DOTTED_ARROW",76:"BIDIRECTIONAL_DOTTED_ARROW",77:"SOLID_CROSS",78:"DOTTED_CROSS",79:"SOLID_POINT",80:"DOTTED_POINT",81:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:o(function(j,ne,te,he,le,J,Se){var se=J.length-1;switch(le){case 3:return he.apply(J[se]),J[se];break;case 4:case 9:this.$=[];break;case 5:case 10:J[se-1].push(J[se]),this.$=J[se-1];break;case 6:case 7:case 11:case 12:this.$=J[se];break;case 8:case 13:this.$=[];break;case 15:J[se].type="createParticipant",this.$=J[se];break;case 16:J[se-1].unshift({type:"boxStart",boxData:he.parseBoxData(J[se-2])}),J[se-1].push({type:"boxEnd",boxText:J[se-2]}),this.$=J[se-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(J[se-2]),sequenceIndexStep:Number(J[se-1]),sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(J[se-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:he.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:he.LINETYPE.ACTIVE_START,actor:J[se-1].actor};break;case 23:this.$={type:"activeEnd",signalType:he.LINETYPE.ACTIVE_END,actor:J[se-1].actor};break;case 29:he.setDiagramTitle(J[se].substring(6)),this.$=J[se].substring(6);break;case 30:he.setDiagramTitle(J[se].substring(7)),this.$=J[se].substring(7);break;case 31:this.$=J[se].trim(),he.setAccTitle(this.$);break;case 32:case 33:this.$=J[se].trim(),he.setAccDescription(this.$);break;case 34:J[se-1].unshift({type:"loopStart",loopText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.LOOP_START}),J[se-1].push({type:"loopEnd",loopText:J[se-2],signalType:he.LINETYPE.LOOP_END}),this.$=J[se-1];break;case 35:J[se-1].unshift({type:"rectStart",color:he.parseMessage(J[se-2]),signalType:he.LINETYPE.RECT_START}),J[se-1].push({type:"rectEnd",color:he.parseMessage(J[se-2]),signalType:he.LINETYPE.RECT_END}),this.$=J[se-1];break;case 36:J[se-1].unshift({type:"optStart",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.OPT_START}),J[se-1].push({type:"optEnd",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.OPT_END}),this.$=J[se-1];break;case 37:J[se-1].unshift({type:"altStart",altText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.ALT_START}),J[se-1].push({type:"altEnd",signalType:he.LINETYPE.ALT_END}),this.$=J[se-1];break;case 38:J[se-1].unshift({type:"parStart",parText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.PAR_START}),J[se-1].push({type:"parEnd",signalType:he.LINETYPE.PAR_END}),this.$=J[se-1];break;case 39:J[se-1].unshift({type:"parStart",parText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.PAR_OVER_START}),J[se-1].push({type:"parEnd",signalType:he.LINETYPE.PAR_END}),this.$=J[se-1];break;case 40:J[se-1].unshift({type:"criticalStart",criticalText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.CRITICAL_START}),J[se-1].push({type:"criticalEnd",signalType:he.LINETYPE.CRITICAL_END}),this.$=J[se-1];break;case 41:J[se-1].unshift({type:"breakStart",breakText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.BREAK_START}),J[se-1].push({type:"breakEnd",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.BREAK_END}),this.$=J[se-1];break;case 43:this.$=J[se-3].concat([{type:"option",optionText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.CRITICAL_OPTION},J[se]]);break;case 45:this.$=J[se-3].concat([{type:"and",parText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.PAR_AND},J[se]]);break;case 47:this.$=J[se-3].concat([{type:"else",altText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.ALT_ELSE},J[se]]);break;case 48:J[se-3].draw="participant",J[se-3].type="addParticipant",J[se-3].description=he.parseMessage(J[se-1]),this.$=J[se-3];break;case 49:J[se-1].draw="participant",J[se-1].type="addParticipant",this.$=J[se-1];break;case 50:J[se-3].draw="actor",J[se-3].type="addParticipant",J[se-3].description=he.parseMessage(J[se-1]),this.$=J[se-3];break;case 51:J[se-1].draw="actor",J[se-1].type="addParticipant",this.$=J[se-1];break;case 52:J[se-1].type="destroyParticipant",this.$=J[se-1];break;case 53:this.$=[J[se-1],{type:"addNote",placement:J[se-2],actor:J[se-1].actor,text:J[se]}];break;case 54:J[se-2]=[].concat(J[se-1],J[se-1]).slice(0,2),J[se-2][0]=J[se-2][0].actor,J[se-2][1]=J[se-2][1].actor,this.$=[J[se-1],{type:"addNote",placement:he.PLACEMENT.OVER,actor:J[se-2].slice(0,2),text:J[se]}];break;case 55:this.$=[J[se-1],{type:"addLinks",actor:J[se-1].actor,text:J[se]}];break;case 56:this.$=[J[se-1],{type:"addALink",actor:J[se-1].actor,text:J[se]}];break;case 57:this.$=[J[se-1],{type:"addProperties",actor:J[se-1].actor,text:J[se]}];break;case 58:this.$=[J[se-1],{type:"addDetails",actor:J[se-1].actor,text:J[se]}];break;case 61:this.$=[J[se-2],J[se]];break;case 62:this.$=J[se];break;case 63:this.$=he.PLACEMENT.LEFTOF;break;case 64:this.$=he.PLACEMENT.RIGHTOF;break;case 65:this.$=[J[se-4],J[se-1],{type:"addMessage",from:J[se-4].actor,to:J[se-1].actor,signalType:J[se-3],msg:J[se],activate:!0},{type:"activeStart",signalType:he.LINETYPE.ACTIVE_START,actor:J[se-1].actor}];break;case 66:this.$=[J[se-4],J[se-1],{type:"addMessage",from:J[se-4].actor,to:J[se-1].actor,signalType:J[se-3],msg:J[se]},{type:"activeEnd",signalType:he.LINETYPE.ACTIVE_END,actor:J[se-4].actor}];break;case 67:this.$=[J[se-3],J[se-1],{type:"addMessage",from:J[se-3].actor,to:J[se-1].actor,signalType:J[se-2],msg:J[se]}];break;case 68:this.$={type:"addParticipant",actor:J[se]};break;case 69:this.$=he.LINETYPE.SOLID_OPEN;break;case 70:this.$=he.LINETYPE.DOTTED_OPEN;break;case 71:this.$=he.LINETYPE.SOLID;break;case 72:this.$=he.LINETYPE.BIDIRECTIONAL_SOLID;break;case 73:this.$=he.LINETYPE.DOTTED;break;case 74:this.$=he.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 75:this.$=he.LINETYPE.SOLID_CROSS;break;case 76:this.$=he.LINETYPE.DOTTED_CROSS;break;case 77:this.$=he.LINETYPE.SOLID_POINT;break;case 78:this.$=he.LINETYPE.DOTTED_POINT;break;case 79:this.$=he.parseMessage(J[se].trim().substring(1));break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},t(B,[2,5]),{9:47,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},t(B,[2,7]),t(B,[2,8]),t(B,[2,14]),{12:48,50:D,52:O,53:R},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:P},{22:55,70:P},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(B,[2,29]),t(B,[2,30]),{32:[1,61]},{34:[1,62]},t(B,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:P},{22:72,70:P},{22:73,70:P},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82],79:[1,83],80:[1,84]},{55:85,57:[1,86],65:[1,87],66:[1,88]},{22:89,70:P},{22:90,70:P},{22:91,70:P},{22:92,70:P},t([5,51,64,71,72,73,74,75,76,77,78,79,80,81],[2,68]),t(B,[2,6]),t(B,[2,15]),t(F,[2,9],{10:93}),t(B,[2,17]),{5:[1,95],19:[1,94]},{5:[1,96]},t(B,[2,21]),{5:[1,97]},{5:[1,98]},t(B,[2,24]),t(B,[2,25]),t(B,[2,26]),t(B,[2,27]),t(B,[2,28]),t(B,[2,31]),t(B,[2,32]),t(z,i,{7:99}),t(z,i,{7:100}),t(z,i,{7:101}),t($,i,{40:102,7:103}),t(U,i,{42:104,7:105}),t(U,i,{7:105,42:106}),t(K,i,{45:107,7:108}),t(z,i,{7:109}),{5:[1,111],51:[1,110]},{5:[1,113],51:[1,112]},{5:[1,114]},{22:117,68:[1,115],69:[1,116],70:P},t(ee,[2,69]),t(ee,[2,70]),t(ee,[2,71]),t(ee,[2,72]),t(ee,[2,73]),t(ee,[2,74]),t(ee,[2,75]),t(ee,[2,76]),t(ee,[2,77]),t(ee,[2,78]),{22:118,70:P},{22:120,58:119,70:P},{70:[2,63]},{70:[2,64]},{56:121,81:Y},{56:123,81:Y},{56:124,81:Y},{56:125,81:Y},{4:[1,128],5:[1,130],11:127,12:129,16:[1,126],50:D,52:O,53:R},{5:[1,131]},t(B,[2,19]),t(B,[2,20]),t(B,[2,22]),t(B,[2,23]),{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,132],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,133],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,134],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,135]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,46],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,49:[1,136],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,137]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,44],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,48:[1,138],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,139]},{16:[1,140]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,42],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,47:[1,141],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,142],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{15:[1,143]},t(B,[2,49]),{15:[1,144]},t(B,[2,51]),t(B,[2,52]),{22:145,70:P},{22:146,70:P},{56:147,81:Y},{56:148,81:Y},{56:149,81:Y},{64:[1,150],81:[2,62]},{5:[2,55]},{5:[2,79]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(B,[2,16]),t(F,[2,10]),{12:151,50:D,52:O,53:R},t(F,[2,12]),t(F,[2,13]),t(B,[2,18]),t(B,[2,34]),t(B,[2,35]),t(B,[2,36]),t(B,[2,37]),{15:[1,152]},t(B,[2,38]),{15:[1,153]},t(B,[2,39]),t(B,[2,40]),{15:[1,154]},t(B,[2,41]),{5:[1,155]},{5:[1,156]},{56:157,81:Y},{56:158,81:Y},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:159,70:P},t(F,[2,11]),t($,i,{7:103,40:160}),t(U,i,{7:105,42:161}),t(K,i,{7:108,45:162}),t(B,[2,48]),t(B,[2,50]),{5:[2,65]},{5:[2,66]},{81:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],87:[2,63],88:[2,64],121:[2,55],122:[2,79],123:[2,56],124:[2,57],125:[2,58],147:[2,67],148:[2,53],149:[2,54],157:[2,65],158:[2,66],159:[2,61],160:[2,47],161:[2,45],162:[2,43]},parseError:o(function(j,ne){if(ne.recoverable)this.trace(j);else{var te=new Error(j);throw te.hash=ne,te}},"parseError"),parse:o(function(j){var ne=this,te=[0],he=[],le=[null],J=[],Se=this.table,se="",ae=0,Oe=0,ye=0,Be=2,He=1,ze=J.slice.call(arguments,1),Le=Object.create(this.lexer),Ie={yy:{}};for(var xe in this.yy)Object.prototype.hasOwnProperty.call(this.yy,xe)&&(Ie.yy[xe]=this.yy[xe]);Le.setInput(j,Ie.yy),Ie.yy.lexer=Le,Ie.yy.parser=this,typeof Le.yylloc>"u"&&(Le.yylloc={});var q=Le.yylloc;J.push(q);var de=Le.options&&Le.options.ranges;typeof Ie.yy.parseError=="function"?this.parseError=Ie.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ie(Rt){te.length=te.length-2*Rt,le.length=le.length-Rt,J.length=J.length-Rt}o(ie,"popStack");function oe(){var Rt;return Rt=he.pop()||Le.lex()||He,typeof Rt!="number"&&(Rt instanceof Array&&(he=Rt,Rt=he.pop()),Rt=ne.symbols_[Rt]||Rt),Rt}o(oe,"lex");for(var V,Te,W,pe,ve,Pe,_e={},be,Ve,De,qe;;){if(W=te[te.length-1],this.defaultActions[W]?pe=this.defaultActions[W]:((V===null||typeof V>"u")&&(V=oe()),pe=Se[W]&&Se[W][V]),typeof pe>"u"||!pe.length||!pe[0]){var at="";qe=[];for(be in Se[W])this.terminals_[be]&&be>Be&&qe.push("'"+this.terminals_[be]+"'");Le.showPosition?at="Parse error on line "+(ae+1)+`: +`+Le.showPosition()+` +Expecting `+qe.join(", ")+", got '"+(this.terminals_[V]||V)+"'":at="Parse error on line "+(ae+1)+": Unexpected "+(V==He?"end of input":"'"+(this.terminals_[V]||V)+"'"),this.parseError(at,{text:Le.match,token:this.terminals_[V]||V,line:Le.yylineno,loc:q,expected:qe})}if(pe[0]instanceof Array&&pe.length>1)throw new Error("Parse Error: multiple actions possible at state: "+W+", token: "+V);switch(pe[0]){case 1:te.push(V),le.push(Le.yytext),J.push(Le.yylloc),te.push(pe[1]),V=null,Te?(V=Te,Te=null):(Oe=Le.yyleng,se=Le.yytext,ae=Le.yylineno,q=Le.yylloc,ye>0&&ye--);break;case 2:if(Ve=this.productions_[pe[1]][1],_e.$=le[le.length-Ve],_e._$={first_line:J[J.length-(Ve||1)].first_line,last_line:J[J.length-1].last_line,first_column:J[J.length-(Ve||1)].first_column,last_column:J[J.length-1].last_column},de&&(_e._$.range=[J[J.length-(Ve||1)].range[0],J[J.length-1].range[1]]),Pe=this.performAction.apply(_e,[se,Oe,ae,Ie.yy,pe[1],le,J].concat(ze)),typeof Pe<"u")return Pe;Ve&&(te=te.slice(0,-1*Ve*2),le=le.slice(0,-1*Ve),J=J.slice(0,-1*Ve)),te.push(this.productions_[pe[1]][0]),le.push(_e.$),J.push(_e._$),De=Se[te[te.length-2]][te[te.length-1]],te.push(De);break;case 3:return!0}}return!0},"parse")},Z=function(){var Q={EOF:1,parseError:o(function(ne,te){if(this.yy.parser)this.yy.parser.parseError(ne,te);else throw new Error(ne)},"parseError"),setInput:o(function(j,ne){return this.yy=ne||this.yy||{},this._input=j,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var j=this._input[0];this.yytext+=j,this.yyleng++,this.offset++,this.match+=j,this.matched+=j;var ne=j.match(/(?:\r\n?|\n).*/g);return ne?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),j},"input"),unput:o(function(j){var ne=j.length,te=j.split(/(?:\r\n?|\n)/g);this._input=j+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ne),this.offset-=ne;var he=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),te.length-1&&(this.yylineno-=te.length-1);var le=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:te?(te.length===he.length?this.yylloc.first_column:0)+he[he.length-te.length].length-te[0].length:this.yylloc.first_column-ne},this.options.ranges&&(this.yylloc.range=[le[0],le[0]+this.yyleng-ne]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(j){this.unput(this.match.slice(j))},"less"),pastInput:o(function(){var j=this.matched.substr(0,this.matched.length-this.match.length);return(j.length>20?"...":"")+j.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var j=this.match;return j.length<20&&(j+=this._input.substr(0,20-j.length)),(j.substr(0,20)+(j.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var j=this.pastInput(),ne=new Array(j.length+1).join("-");return j+this.upcomingInput()+` +`+ne+"^"},"showPosition"),test_match:o(function(j,ne){var te,he,le;if(this.options.backtrack_lexer&&(le={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(le.yylloc.range=this.yylloc.range.slice(0))),he=j[0].match(/(?:\r\n?|\n).*/g),he&&(this.yylineno+=he.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:he?he[he.length-1].length-he[he.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+j[0].length},this.yytext+=j[0],this.match+=j[0],this.matches=j,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(j[0].length),this.matched+=j[0],te=this.performAction.call(this,this.yy,this,ne,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),te)return te;if(this._backtrack){for(var J in le)this[J]=le[J];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var j,ne,te,he;this._more||(this.yytext="",this.match="");for(var le=this._currentRules(),J=0;Jne[0].length)){if(ne=te,he=J,this.options.backtrack_lexer){if(j=this.test_match(te,le[J]),j!==!1)return j;if(this._backtrack){ne=!1;continue}else return!1}else if(!this.options.flex)break}return ne?(j=this.test_match(ne,le[he]),j!==!1?j:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var ne=this.next();return ne||this.lex()},"lex"),begin:o(function(ne){this.conditionStack.push(ne)},"begin"),popState:o(function(){var ne=this.conditionStack.length-1;return ne>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(ne){return ne=this.conditionStack.length-1-Math.abs(ne||0),ne>=0?this.conditionStack[ne]:"INITIAL"},"topState"),pushState:o(function(ne){this.begin(ne)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(ne,te,he,le){var J=le;switch(he){case 0:return 5;case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;break;case 8:return this.begin("ID"),50;break;case 9:return this.begin("ID"),52;break;case 10:return 13;case 11:return this.begin("ID"),53;break;case 12:return te.yytext=te.yytext.trim(),this.begin("ALIAS"),70;break;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;break;case 14:return this.popState(),this.popState(),5;break;case 15:return this.begin("LINE"),36;break;case 16:return this.begin("LINE"),37;break;case 17:return this.begin("LINE"),38;break;case 18:return this.begin("LINE"),39;break;case 19:return this.begin("LINE"),49;break;case 20:return this.begin("LINE"),41;break;case 21:return this.begin("LINE"),43;break;case 22:return this.begin("LINE"),48;break;case 23:return this.begin("LINE"),44;break;case 24:return this.begin("LINE"),47;break;case 25:return this.begin("LINE"),46;break;case 26:return this.popState(),15;break;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;break;case 37:return this.begin("ID"),23;break;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;break;case 41:return this.popState(),"acc_title_value";break;case 42:return this.begin("acc_descr"),33;break;case 43:return this.popState(),"acc_descr_value";break;case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 51:return 5;case 52:return te.yytext=te.yytext.trim(),70;break;case 53:return 73;case 54:return 74;case 55:return 75;case 56:return 76;case 57:return 71;case 58:return 72;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 80;case 63:return 81;case 64:return 81;case 65:return 68;case 66:return 69;case 67:return 5;case 68:return"INVALID"}},"anonymous"),rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\<->\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\<->\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:<<->>)/i,/^(?:-->>)/i,/^(?:<<-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]*)/i,/^(?::)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],inclusive:!0}}};return Q}();ce.lexer=Z;function ue(){this.yy={}}return o(ue,"Parser"),ue.prototype=ce,ce.Parser=ue,new ue}();dP.parser=dP;_de=dP});var FUe,$Ue,zUe,YS,Lde=N(()=>{"use strict";Gt();yt();SS();pr();ci();FUe={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32,BIDIRECTIONAL_SOLID:33,BIDIRECTIONAL_DOTTED:34},$Ue={FILLED:0,OPEN:1},zUe={LEFTOF:0,RIGHTOF:1,OVER:2},YS=class{constructor(){this.state=new Tf(()=>({prevActor:void 0,actors:new Map,createdActors:new Map,destroyedActors:new Map,boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}));this.setAccTitle=Ar;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getAccTitle=Dr;this.getAccDescription=Rr;this.getDiagramTitle=Nr;this.apply=this.apply.bind(this),this.parseBoxData=this.parseBoxData.bind(this),this.parseMessage=this.parseMessage.bind(this),this.clear(),this.setWrap(me().wrap),this.LINETYPE=FUe,this.ARROWTYPE=$Ue,this.PLACEMENT=zUe}static{o(this,"SequenceDB")}addBox(e){this.state.records.boxes.push({name:e.text,wrap:e.wrap??this.autoWrap(),fill:e.color,actorKeys:[]}),this.state.records.currentBox=this.state.records.boxes.slice(-1)[0]}addActor(e,r,n,i){let a=this.state.records.currentBox,s=this.state.records.actors.get(e);if(s){if(this.state.records.currentBox&&s.box&&this.state.records.currentBox!==s.box)throw new Error(`A same participant should only be defined in one Box: ${s.name} can't be in '${s.box.name}' and in '${this.state.records.currentBox.name}' at the same time.`);if(a=s.box?s.box:this.state.records.currentBox,s.box=a,s&&r===s.name&&n==null)return}if(n?.text==null&&(n={text:r,type:i}),(i==null||n.text==null)&&(n={text:r,type:i}),this.state.records.actors.set(e,{box:a,name:r,description:n.text,wrap:n.wrap??this.autoWrap(),prevActor:this.state.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:i??"participant"}),this.state.records.prevActor){let l=this.state.records.actors.get(this.state.records.prevActor);l&&(l.nextActor=e)}this.state.records.currentBox&&this.state.records.currentBox.actorKeys.push(e),this.state.records.prevActor=e}activationCount(e){let r,n=0;if(!e)return 0;for(r=0;r>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},l}return this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:e,to:r,message:n?.text??"",wrap:n?.wrap??this.autoWrap(),type:i,activate:a}),!0}hasAtLeastOneBox(){return this.state.records.boxes.length>0}hasAtLeastOneBoxWithTitle(){return this.state.records.boxes.some(e=>e.name)}getMessages(){return this.state.records.messages}getBoxes(){return this.state.records.boxes}getActors(){return this.state.records.actors}getCreatedActors(){return this.state.records.createdActors}getDestroyedActors(){return this.state.records.destroyedActors}getActor(e){return this.state.records.actors.get(e)}getActorKeys(){return[...this.state.records.actors.keys()]}enableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!0}disableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!1}showSequenceNumbers(){return this.state.records.sequenceNumbersEnabled}setWrap(e){this.state.records.wrapEnabled=e}extractWrap(e){if(e===void 0)return{};e=e.trim();let r=/^:?wrap:/.exec(e)!==null?!0:/^:?nowrap:/.exec(e)!==null?!1:void 0;return{cleanedText:(r===void 0?e:e.replace(/^:?(?:no)?wrap:/,"")).trim(),wrap:r}}autoWrap(){return this.state.records.wrapEnabled!==void 0?this.state.records.wrapEnabled:me().sequence?.wrap??!1}clear(){this.state.reset(),kr()}parseMessage(e){let r=e.trim(),{wrap:n,cleanedText:i}=this.extractWrap(r),a={text:i,wrap:n};return X.debug(`parseMessage: ${JSON.stringify(a)}`),a}parseBoxData(e){let r=/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(e),n=r?.[1]?r[1].trim():"transparent",i=r?.[2]?r[2].trim():void 0;if(window?.CSS)window.CSS.supports("color",n)||(n="transparent",i=e.trim());else{let l=new Option().style;l.color=n,l.color!==n&&(n="transparent",i=e.trim())}let{wrap:a,cleanedText:s}=this.extractWrap(i);return{text:s?wr(s,me()):void 0,color:n,wrap:a}}addNote(e,r,n){let i={actor:e,placement:r,message:n.text,wrap:n.wrap??this.autoWrap()},a=[].concat(e,e);this.state.records.notes.push(i),this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:a[0],to:a[1],message:n.text,wrap:n.wrap??this.autoWrap(),type:this.LINETYPE.NOTE,placement:r})}addLinks(e,r){let n=this.getActor(e);try{let i=wr(r.text,me());i=i.replace(/=/g,"="),i=i.replace(/&/g,"&");let a=JSON.parse(i);this.insertLinks(n,a)}catch(i){X.error("error while parsing actor link text",i)}}addALink(e,r){let n=this.getActor(e);try{let i={},a=wr(r.text,me()),s=a.indexOf("@");a=a.replace(/=/g,"="),a=a.replace(/&/g,"&");let l=a.slice(0,s-1).trim(),u=a.slice(s+1).trim();i[l]=u,this.insertLinks(n,i)}catch(i){X.error("error while parsing actor link text",i)}}insertLinks(e,r){if(e.links==null)e.links=r;else for(let n in r)e.links[n]=r[n]}addProperties(e,r){let n=this.getActor(e);try{let i=wr(r.text,me()),a=JSON.parse(i);this.insertProperties(n,a)}catch(i){X.error("error while parsing actor properties text",i)}}insertProperties(e,r){if(e.properties==null)e.properties=r;else for(let n in r)e.properties[n]=r[n]}boxEnd(){this.state.records.currentBox=void 0}addDetails(e,r){let n=this.getActor(e),i=document.getElementById(r.text);try{let a=i.innerHTML,s=JSON.parse(a);s.properties&&this.insertProperties(n,s.properties),s.links&&this.insertLinks(n,s.links)}catch(a){X.error("error while parsing actor details text",a)}}getActorProperty(e,r){if(e?.properties!==void 0)return e.properties[r]}apply(e){if(Array.isArray(e))e.forEach(r=>{this.apply(r)});else switch(e.type){case"sequenceIndex":this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:void 0,to:void 0,message:{start:e.sequenceIndex,step:e.sequenceIndexStep,visible:e.sequenceVisible},wrap:!1,type:e.signalType});break;case"addParticipant":this.addActor(e.actor,e.actor,e.description,e.draw);break;case"createParticipant":if(this.state.records.actors.has(e.actor))throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");this.state.records.lastCreated=e.actor,this.addActor(e.actor,e.actor,e.description,e.draw),this.state.records.createdActors.set(e.actor,this.state.records.messages.length);break;case"destroyParticipant":this.state.records.lastDestroyed=e.actor,this.state.records.destroyedActors.set(e.actor,this.state.records.messages.length);break;case"activeStart":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"activeEnd":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"addNote":this.addNote(e.actor,e.placement,e.text);break;case"addLinks":this.addLinks(e.actor,e.text);break;case"addALink":this.addALink(e.actor,e.text);break;case"addProperties":this.addProperties(e.actor,e.text);break;case"addDetails":this.addDetails(e.actor,e.text);break;case"addMessage":if(this.state.records.lastCreated){if(e.to!==this.state.records.lastCreated)throw new Error("The created participant "+this.state.records.lastCreated.name+" does not have an associated creating message after its declaration. Please check the sequence diagram.");this.state.records.lastCreated=void 0}else if(this.state.records.lastDestroyed){if(e.to!==this.state.records.lastDestroyed&&e.from!==this.state.records.lastDestroyed)throw new Error("The destroyed participant "+this.state.records.lastDestroyed.name+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");this.state.records.lastDestroyed=void 0}this.addSignal(e.from,e.to,e.msg,e.signalType,e.activate);break;case"boxStart":this.addBox(e.boxData);break;case"boxEnd":this.boxEnd();break;case"loopStart":this.addSignal(void 0,void 0,e.loopText,e.signalType);break;case"loopEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"rectStart":this.addSignal(void 0,void 0,e.color,e.signalType);break;case"rectEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"optStart":this.addSignal(void 0,void 0,e.optText,e.signalType);break;case"optEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"altStart":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"else":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"altEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"setAccTitle":Ar(e.text);break;case"parStart":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"and":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"parEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"criticalStart":this.addSignal(void 0,void 0,e.criticalText,e.signalType);break;case"option":this.addSignal(void 0,void 0,e.optionText,e.signalType);break;case"criticalEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"breakStart":this.addSignal(void 0,void 0,e.breakText,e.signalType);break;case"breakEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break}}getConfig(){return me().sequence}}});var GUe,Rde,Nde=N(()=>{"use strict";GUe=o(t=>`.actor { + stroke: ${t.actorBorder}; + fill: ${t.actorBkg}; + } + + text.actor > tspan { + fill: ${t.actorTextColor}; + stroke: none; + } + + .actor-line { + stroke: ${t.actorLineColor}; + } + + .messageLine0 { + stroke-width: 1.5; + stroke-dasharray: none; + stroke: ${t.signalColor}; + } + + .messageLine1 { + stroke-width: 1.5; + stroke-dasharray: 2, 2; + stroke: ${t.signalColor}; + } + + #arrowhead path { + fill: ${t.signalColor}; + stroke: ${t.signalColor}; + } + + .sequenceNumber { + fill: ${t.sequenceNumberColor}; + } + + #sequencenumber { + fill: ${t.signalColor}; + } + + #crosshead path { + fill: ${t.signalColor}; + stroke: ${t.signalColor}; + } + + .messageText { + fill: ${t.signalTextColor}; + stroke: none; + } + + .labelBox { + stroke: ${t.labelBoxBorderColor}; + fill: ${t.labelBoxBkgColor}; + } + + .labelText, .labelText > tspan { + fill: ${t.labelTextColor}; + stroke: none; + } + + .loopText, .loopText > tspan { + fill: ${t.loopTextColor}; + stroke: none; + } + + .loopLine { + stroke-width: 2px; + stroke-dasharray: 2, 2; + stroke: ${t.labelBoxBorderColor}; + fill: ${t.labelBoxBorderColor}; + } + + .note { + //stroke: #decc93; + stroke: ${t.noteBorderColor}; + fill: ${t.noteBkgColor}; + } + + .noteText, .noteText > tspan { + fill: ${t.noteTextColor}; + stroke: none; + } + + .activation0 { + fill: ${t.activationBkgColor}; + stroke: ${t.activationBorderColor}; + } + + .activation1 { + fill: ${t.activationBkgColor}; + stroke: ${t.activationBorderColor}; + } + + .activation2 { + fill: ${t.activationBkgColor}; + stroke: ${t.activationBorderColor}; + } + + .actorPopupMenu { + position: absolute; + } + + .actorPopupMenuPanel { + position: absolute; + fill: ${t.actorBkg}; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4)); +} + .actor-man line { + stroke: ${t.actorBorder}; + fill: ${t.actorBkg}; + } + .actor-man circle, line { + stroke: ${t.actorBorder}; + fill: ${t.actorBkg}; + stroke-width: 2px; + } +`,"getStyles"),Rde=GUe});var pP,Sf,Ide,Ode,VUe,Mde,mP,UUe,HUe,Mb,Fp,Pde,Yc,gP,WUe,qUe,YUe,XUe,jUe,KUe,QUe,Bde,ZUe,JUe,eHe,tHe,rHe,nHe,iHe,Fde,aHe,yP,sHe,di,$de=N(()=>{"use strict";pr();t2();er();pP=Aa(Z0(),1);mi();Sf=18*2,Ide="actor-top",Ode="actor-bottom",VUe="actor-box",Mde="actor-man",mP=o(function(t,e){return Nd(t,e)},"drawRect"),UUe=o(function(t,e,r,n,i){if(e.links===void 0||e.links===null||Object.keys(e.links).length===0)return{height:0,width:0};let a=e.links,s=e.actorCnt,l=e.rectData;var u="none";i&&(u="block !important");let h=t.append("g");h.attr("id","actor"+s+"_popup"),h.attr("class","actorPopupMenu"),h.attr("display",u);var f="";l.class!==void 0&&(f=" "+l.class);let d=l.width>r?l.width:r,p=h.append("rect");if(p.attr("class","actorPopupMenuPanel"+f),p.attr("x",l.x),p.attr("y",l.height),p.attr("fill",l.fill),p.attr("stroke",l.stroke),p.attr("width",d),p.attr("height",l.height),p.attr("rx",l.rx),p.attr("ry",l.ry),a!=null){var m=20;for(let v in a){var g=h.append("a"),y=(0,pP.sanitizeUrl)(a[v]);g.attr("xlink:href",y),g.attr("target","_blank"),sHe(n)(v,g,l.x+10,l.height+m,d,20,{class:"actor"},n),m+=30}}return p.attr("height",m),{height:l.height+m,width:d}},"drawPopup"),HUe=o(function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"},"popupMenuToggle"),Mb=o(async function(t,e,r=null){let n=t.append("foreignObject"),i=await Th(e.text,tr()),s=n.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(i).node().getBoundingClientRect();if(n.attr("height",Math.round(s.height)).attr("width",Math.round(s.width)),e.class==="noteText"){let l=t.node().firstChild;l.setAttribute("height",s.height+2*e.textMargin);let u=l.getBBox();n.attr("x",Math.round(u.x+u.width/2-s.width/2)).attr("y",Math.round(u.y+u.height/2-s.height/2))}else if(r){let{startx:l,stopx:u,starty:h}=r;if(l>u){let f=l;l=u,u=f}n.attr("x",Math.round(l+Math.abs(l-u)/2-s.width/2)),e.class==="loopText"?n.attr("y",Math.round(h)):n.attr("y",Math.round(h-s.height))}return[n]},"drawKatex"),Fp=o(function(t,e){let r=0,n=0,i=e.text.split(Ze.lineBreakRegex),[a,s]=zo(e.fontSize),l=[],u=0,h=o(()=>e.y,"yfunc");if(e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0)switch(e.valign){case"top":case"start":h=o(()=>Math.round(e.y+e.textMargin),"yfunc");break;case"middle":case"center":h=o(()=>Math.round(e.y+(r+n+e.textMargin)/2),"yfunc");break;case"bottom":case"end":h=o(()=>Math.round(e.y+(r+n+2*e.textMargin)-e.textMargin),"yfunc");break}if(e.anchor!==void 0&&e.textMargin!==void 0&&e.width!==void 0)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle";break}for(let[f,d]of i.entries()){e.textMargin!==void 0&&e.textMargin===0&&a!==void 0&&(u=f*a);let p=t.append("text");p.attr("x",e.x),p.attr("y",h()),e.anchor!==void 0&&p.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),e.fontFamily!==void 0&&p.style("font-family",e.fontFamily),s!==void 0&&p.style("font-size",s),e.fontWeight!==void 0&&p.style("font-weight",e.fontWeight),e.fill!==void 0&&p.attr("fill",e.fill),e.class!==void 0&&p.attr("class",e.class),e.dy!==void 0?p.attr("dy",e.dy):u!==0&&p.attr("dy",u);let m=d||C9;if(e.tspan){let g=p.append("tspan");g.attr("x",e.x),e.fill!==void 0&&g.attr("fill",e.fill),g.text(m)}else p.text(m);e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0&&(n+=(p._groups||p)[0][0].getBBox().height,r=n),l.push(p)}return l},"drawText"),Pde=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");return n.attr("points",r(e.x,e.y,e.width,e.height,7)),n.attr("class","labelBox"),e.y=e.y+e.height/2,Fp(t,e),n},"drawLabel"),Yc=-1,gP=o((t,e,r,n)=>{t.select&&r.forEach(i=>{let a=e.get(i),s=t.select("#actor"+a.actorCnt);!n.mirrorActors&&a.stopy?s.attr("y2",a.stopy+a.height/2):n.mirrorActors&&s.attr("y2",a.stopy)})},"fixLifeLineHeights"),WUe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+e.height,l=t.append("g").lower();var u=l;n||(Yc++,Object.keys(e.links||{}).length&&!r.forceMenus&&u.attr("onclick",HUe(`actor${Yc}_popup`)).attr("cursor","pointer"),u.append("line").attr("id","actor"+Yc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),u=l.append("g"),e.actorCnt=Yc,e.links!=null&&u.attr("id","root-"+Yc));let h=Al();var f="actor";e.properties?.class?f=e.properties.class:h.fill="#eaeaea",n?f+=` ${Ode}`:f+=` ${Ide}`,h.x=e.x,h.y=i,h.width=e.width,h.height=e.height,h.class=f,h.rx=3,h.ry=3,h.name=e.name;let d=mP(u,h);if(e.rectData=h,e.properties?.icon){let m=e.properties.icon.trim();m.charAt(0)==="@"?KY(u,h.x+h.width-20,h.y+10,m.substr(1)):jY(u,h.x+h.width-20,h.y+10,m)}yP(r,yi(e.description))(e.description,u,h.x,h.y,h.width,h.height,{class:`actor ${VUe}`},r);let p=e.height;if(d.node){let m=d.node().getBBox();e.height=m.height,p=m.height}return p},"drawActorTypeParticipant"),qUe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+80,l=t.append("g").lower();n||(Yc++,l.append("line").attr("id","actor"+Yc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=Yc);let u=t.append("g"),h=Mde;n?h+=` ${Ode}`:h+=` ${Ide}`,u.attr("class",h),u.attr("name",e.name);let f=Al();f.x=e.x,f.y=i,f.fill="#eaeaea",f.width=e.width,f.height=e.height,f.class="actor",f.rx=3,f.ry=3,u.append("line").attr("id","actor-man-torso"+Yc).attr("x1",a).attr("y1",i+25).attr("x2",a).attr("y2",i+45),u.append("line").attr("id","actor-man-arms"+Yc).attr("x1",a-Sf/2).attr("y1",i+33).attr("x2",a+Sf/2).attr("y2",i+33),u.append("line").attr("x1",a-Sf/2).attr("y1",i+60).attr("x2",a).attr("y2",i+45),u.append("line").attr("x1",a).attr("y1",i+45).attr("x2",a+Sf/2-2).attr("y2",i+60);let d=u.append("circle");d.attr("cx",e.x+e.width/2),d.attr("cy",i+10),d.attr("r",15),d.attr("width",e.width),d.attr("height",e.height);let p=u.node().getBBox();return e.height=p.height,yP(r,yi(e.description))(e.description,u,f.x,f.y+35,f.width,f.height,{class:`actor ${Mde}`},r),e.height},"drawActorTypeActor"),YUe=o(async function(t,e,r,n){switch(e.type){case"actor":return await qUe(t,e,r,n);case"participant":return await WUe(t,e,r,n)}},"drawActor"),XUe=o(function(t,e,r){let i=t.append("g");Bde(i,e),e.name&&yP(r)(e.name,i,e.x,e.y+r.boxTextMargin+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},r),i.lower()},"drawBox"),jUe=o(function(t){return t.append("g")},"anchorElement"),KUe=o(function(t,e,r,n,i){let a=Al(),s=e.anchored;a.x=e.startx,a.y=e.starty,a.class="activation"+i%3,a.width=e.stopx-e.startx,a.height=r-e.starty,mP(s,a)},"drawActivation"),QUe=o(async function(t,e,r,n){let{boxMargin:i,boxTextMargin:a,labelBoxHeight:s,labelBoxWidth:l,messageFontFamily:u,messageFontSize:h,messageFontWeight:f}=n,d=t.append("g"),p=o(function(y,v,x,b){return d.append("line").attr("x1",y).attr("y1",v).attr("x2",x).attr("y2",b).attr("class","loopLine")},"drawLoopLine");p(e.startx,e.starty,e.stopx,e.starty),p(e.stopx,e.starty,e.stopx,e.stopy),p(e.startx,e.stopy,e.stopx,e.stopy),p(e.startx,e.starty,e.startx,e.stopy),e.sections!==void 0&&e.sections.forEach(function(y){p(e.startx,y.y,e.stopx,y.y).style("stroke-dasharray","3, 3")});let m=e2();m.text=r,m.x=e.startx,m.y=e.starty,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.anchor="middle",m.valign="middle",m.tspan=!1,m.width=l||50,m.height=s||20,m.textMargin=a,m.class="labelText",Pde(d,m),m=Fde(),m.text=e.title,m.x=e.startx+l/2+(e.stopx-e.startx)/2,m.y=e.starty+i+a,m.anchor="middle",m.valign="middle",m.textMargin=a,m.class="loopText",m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=!0;let g=yi(m.text)?await Mb(d,m,e):Fp(d,m);if(e.sectionTitles!==void 0){for(let[y,v]of Object.entries(e.sectionTitles))if(v.message){m.text=v.message,m.x=e.startx+(e.stopx-e.startx)/2,m.y=e.sections[y].y+i+a,m.class="loopText",m.anchor="middle",m.valign="middle",m.tspan=!1,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=e.wrap,yi(m.text)?(e.starty=e.sections[y].y,await Mb(d,m,e)):Fp(d,m);let x=Math.round(g.map(b=>(b._groups||b)[0][0].getBBox().height).reduce((b,T)=>b+T));e.sections[y].height+=x-(i+a)}}return e.height=Math.round(e.stopy-e.starty),d},"drawLoop"),Bde=o(function(t,e){iT(t,e)},"drawBackgroundRect"),ZUe=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),JUe=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),eHe=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),tHe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto-start-reverse").append("path").attr("d","M -1 0 L 10 5 L 0 10 z")},"insertArrowHead"),rHe=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),nHe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertSequenceNumber"),iHe=o(function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},"insertArrowCrossHead"),Fde=o(function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},"getTextObj"),aHe=o(function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),yP=function(){function t(a,s,l,u,h,f,d){let p=s.append("text").attr("x",l+h/2).attr("y",u+f/2+5).style("text-anchor","middle").text(a);i(p,d)}o(t,"byText");function e(a,s,l,u,h,f,d,p){let{actorFontSize:m,actorFontFamily:g,actorFontWeight:y}=p,[v,x]=zo(m),b=a.split(Ze.lineBreakRegex);for(let T=0;T{let s=$p(Ne),l=a.actorKeys.reduce((f,d)=>f+=t.get(d).width+(t.get(d).margin||0),0);l-=2*Ne.boxTextMargin,a.wrap&&(a.name=Vt.wrapLabel(a.name,l-2*Ne.wrapPadding,s));let u=Vt.calculateTextDimensions(a.name,s);i=Ze.getMax(u.height,i);let h=Ze.getMax(l,u.width+2*Ne.wrapPadding);if(a.margin=Ne.boxTextMargin,la.textMaxHeight=i),Ze.getMax(n,Ne.height)}var Ne,rt,oHe,$p,O1,vP,cHe,uHe,xP,Gde,Vde,XS,zde,fHe,pHe,gHe,yHe,vHe,Ude,Hde=N(()=>{"use strict";fr();$de();yt();pr();pr();t2();Gt();g0();er();xi();Ne={},rt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:o(function(){return Math.max.apply(null,this.actors.length===0?[0]:this.actors.map(t=>t.height||0))+(this.loops.length===0?0:this.loops.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.messages.length===0?0:this.messages.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.notes.length===0?0:this.notes.map(t=>t.height||0).reduce((t,e)=>t+e))},"getHeight"),clear:o(function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},"clear"),addBox:o(function(t){this.boxes.push(t)},"addBox"),addActor:o(function(t){this.actors.push(t)},"addActor"),addLoop:o(function(t){this.loops.push(t)},"addLoop"),addMessage:o(function(t){this.messages.push(t)},"addMessage"),addNote:o(function(t){this.notes.push(t)},"addNote"),lastActor:o(function(){return this.actors[this.actors.length-1]},"lastActor"),lastLoop:o(function(){return this.loops[this.loops.length-1]},"lastLoop"),lastMessage:o(function(){return this.messages[this.messages.length-1]},"lastMessage"),lastNote:o(function(){return this.notes[this.notes.length-1]},"lastNote"),actors:[],boxes:[],loops:[],messages:[],notes:[]},init:o(function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,Vde(me())},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=this,a=0;function s(l){return o(function(h){a++;let f=i.sequenceItems.length-a+1;i.updateVal(h,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopy",n+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopx",r+f*Ne.boxMargin,Math.max),l!=="activation"&&(i.updateVal(h,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopx",r+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopy",n+f*Ne.boxMargin,Math.max))},"updateItemBounds")}o(s,"updateFn"),this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},"updateBounds"),insert:o(function(t,e,r,n){let i=Ze.getMin(t,r),a=Ze.getMax(t,r),s=Ze.getMin(e,n),l=Ze.getMax(e,n);this.updateVal(rt.data,"startx",i,Math.min),this.updateVal(rt.data,"starty",s,Math.min),this.updateVal(rt.data,"stopx",a,Math.max),this.updateVal(rt.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),newActivation:o(function(t,e,r){let n=r.get(t.from),i=XS(t.from).length||0,a=n.x+n.width/2+(i-1)*Ne.activationWidth/2;this.activations.push({startx:a,starty:this.verticalPos+2,stopx:a+Ne.activationWidth,stopy:void 0,actor:t.from,anchored:di.anchorElement(e)})},"newActivation"),endActivation:o(function(t){let e=this.activations.map(function(r){return r.actor}).lastIndexOf(t.from);return this.activations.splice(e,1)[0]},"endActivation"),createLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},"createLoop"),newLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},"newLoop"),endLoop:o(function(){return this.sequenceItems.pop()},"endLoop"),isLoopOverlap:o(function(){return this.sequenceItems.length?this.sequenceItems[this.sequenceItems.length-1].overlap:!1},"isLoopOverlap"),addSectionToLoop:o(function(t){let e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:rt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},"addSectionToLoop"),saveVerticalPos:o(function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},"saveVerticalPos"),resetVerticalPos:o(function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},"resetVerticalPos"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=Ze.getMax(this.data.stopy,this.verticalPos)},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return{bounds:this.data,models:this.models}},"getBounds")},oHe=o(async function(t,e){rt.bumpVerticalPos(Ne.boxMargin),e.height=Ne.boxMargin,e.starty=rt.getVerticalPos();let r=Al();r.x=e.startx,r.y=e.starty,r.width=e.width||Ne.width,r.class="note";let n=t.append("g"),i=di.drawRect(n,r),a=e2();a.x=e.startx,a.y=e.starty,a.width=r.width,a.dy="1em",a.text=e.message,a.class="noteText",a.fontFamily=Ne.noteFontFamily,a.fontSize=Ne.noteFontSize,a.fontWeight=Ne.noteFontWeight,a.anchor=Ne.noteAlign,a.textMargin=Ne.noteMargin,a.valign="center";let s=yi(a.text)?await Mb(n,a):Fp(n,a),l=Math.round(s.map(u=>(u._groups||u)[0][0].getBBox().height).reduce((u,h)=>u+h));i.attr("height",l+2*Ne.noteMargin),e.height+=l+2*Ne.noteMargin,rt.bumpVerticalPos(l+2*Ne.noteMargin),e.stopy=e.starty+l+2*Ne.noteMargin,e.stopx=e.startx+r.width,rt.insert(e.startx,e.starty,e.stopx,e.stopy),rt.models.addNote(e)},"drawNote"),$p=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont"),O1=o(t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),"noteFont"),vP=o(t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}),"actorFont");o(lHe,"boundMessage");cHe=o(async function(t,e,r,n){let{startx:i,stopx:a,starty:s,message:l,type:u,sequenceIndex:h,sequenceVisible:f}=e,d=Vt.calculateTextDimensions(l,$p(Ne)),p=e2();p.x=i,p.y=s+10,p.width=a-i,p.class="messageText",p.dy="1em",p.text=l,p.fontFamily=Ne.messageFontFamily,p.fontSize=Ne.messageFontSize,p.fontWeight=Ne.messageFontWeight,p.anchor=Ne.messageAlign,p.valign="center",p.textMargin=Ne.wrapPadding,p.tspan=!1,yi(p.text)?await Mb(t,p,{startx:i,stopx:a,starty:r}):Fp(t,p);let m=d.width,g;i===a?Ne.rightAngles?g=t.append("path").attr("d",`M ${i},${r} H ${i+Ze.getMax(Ne.width/2,m/2)} V ${r+25} H ${i}`):g=t.append("path").attr("d","M "+i+","+r+" C "+(i+60)+","+(r-10)+" "+(i+60)+","+(r+30)+" "+i+","+(r+20)):(g=t.append("line"),g.attr("x1",i),g.attr("y1",r),g.attr("x2",a),g.attr("y2",r)),u===n.db.LINETYPE.DOTTED||u===n.db.LINETYPE.DOTTED_CROSS||u===n.db.LINETYPE.DOTTED_POINT||u===n.db.LINETYPE.DOTTED_OPEN||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED?(g.style("stroke-dasharray","3, 3"),g.attr("class","messageLine1")):g.attr("class","messageLine0");let y="";Ne.arrowMarkerAbsolute&&(y=mu(!0)),g.attr("stroke-width",2),g.attr("stroke","none"),g.style("fill","none"),(u===n.db.LINETYPE.SOLID||u===n.db.LINETYPE.DOTTED)&&g.attr("marker-end","url("+y+"#arrowhead)"),(u===n.db.LINETYPE.BIDIRECTIONAL_SOLID||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED)&&(g.attr("marker-start","url("+y+"#arrowhead)"),g.attr("marker-end","url("+y+"#arrowhead)")),(u===n.db.LINETYPE.SOLID_POINT||u===n.db.LINETYPE.DOTTED_POINT)&&g.attr("marker-end","url("+y+"#filled-head)"),(u===n.db.LINETYPE.SOLID_CROSS||u===n.db.LINETYPE.DOTTED_CROSS)&&g.attr("marker-end","url("+y+"#crosshead)"),(f||Ne.showSequenceNumbers)&&(g.attr("marker-start","url("+y+"#sequencenumber)"),t.append("text").attr("x",i).attr("y",r+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(h))},"drawMessage"),uHe=o(function(t,e,r,n,i,a,s){let l=0,u=0,h,f=0;for(let d of n){let p=e.get(d),m=p.box;h&&h!=m&&(s||rt.models.addBox(h),u+=Ne.boxMargin+h.margin),m&&m!=h&&(s||(m.x=l+u,m.y=i),u+=m.margin),p.width=p.width||Ne.width,p.height=Ze.getMax(p.height||Ne.height,Ne.height),p.margin=p.margin||Ne.actorMargin,f=Ze.getMax(f,p.height),r.get(p.name)&&(u+=p.width/2),p.x=l+u,p.starty=rt.getVerticalPos(),rt.insert(p.x,i,p.x+p.width,p.height),l+=p.width+u,p.box&&(p.box.width=l+m.margin-p.box.x),u=p.margin,h=p.box,rt.models.addActor(p)}h&&!s&&rt.models.addBox(h),rt.bumpVerticalPos(f)},"addActorRenderingData"),xP=o(async function(t,e,r,n){if(n){let i=0;rt.bumpVerticalPos(Ne.boxMargin*2);for(let a of r){let s=e.get(a);s.stopy||(s.stopy=rt.getVerticalPos());let l=await di.drawActor(t,s,Ne,!0);i=Ze.getMax(i,l)}rt.bumpVerticalPos(i+Ne.boxMargin)}else for(let i of r){let a=e.get(i);await di.drawActor(t,a,Ne,!1)}},"drawActors"),Gde=o(function(t,e,r,n){let i=0,a=0;for(let s of r){let l=e.get(s),u=pHe(l),h=di.drawPopup(t,l,u,Ne,Ne.forceMenus,n);h.height>i&&(i=h.height),h.width+l.x>a&&(a=h.width+l.x)}return{maxHeight:i,maxWidth:a}},"drawActorsPopup"),Vde=o(function(t){Un(Ne,t),t.fontFamily&&(Ne.actorFontFamily=Ne.noteFontFamily=Ne.messageFontFamily=t.fontFamily),t.fontSize&&(Ne.actorFontSize=Ne.noteFontSize=Ne.messageFontSize=t.fontSize),t.fontWeight&&(Ne.actorFontWeight=Ne.noteFontWeight=Ne.messageFontWeight=t.fontWeight)},"setConf"),XS=o(function(t){return rt.activations.filter(function(e){return e.actor===t})},"actorActivations"),zde=o(function(t,e){let r=e.get(t),n=XS(t),i=n.reduce(function(s,l){return Ze.getMin(s,l.startx)},r.x+r.width/2-1),a=n.reduce(function(s,l){return Ze.getMax(s,l.stopx)},r.x+r.width/2+1);return[i,a]},"activationBounds");o(Xc,"adjustLoopHeightForWrap");o(hHe,"adjustCreatedDestroyedData");fHe=o(async function(t,e,r,n){let{securityLevel:i,sequence:a}=me();Ne=a;let s;i==="sandbox"&&(s=Ge("#i"+e));let l=i==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=i==="sandbox"?s.nodes()[0].contentDocument:document;rt.init(),X.debug(n.db);let h=i==="sandbox"?l.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=n.db.getActors(),d=n.db.getCreatedActors(),p=n.db.getDestroyedActors(),m=n.db.getBoxes(),g=n.db.getActorKeys(),y=n.db.getMessages(),v=n.db.getDiagramTitle(),x=n.db.hasAtLeastOneBox(),b=n.db.hasAtLeastOneBoxWithTitle(),T=await dHe(f,y,n);if(Ne.height=await mHe(f,T,m),di.insertComputerIcon(h),di.insertDatabaseIcon(h),di.insertClockIcon(h),x&&(rt.bumpVerticalPos(Ne.boxMargin),b&&rt.bumpVerticalPos(m[0].textMaxHeight)),Ne.hideUnusedParticipants===!0){let B=new Set;y.forEach(F=>{B.add(F.from),B.add(F.to)}),g=g.filter(F=>B.has(F))}uHe(h,f,d,g,0,y,!1);let S=await vHe(y,f,T,n);di.insertArrowHead(h),di.insertArrowCrossHead(h),di.insertArrowFilledHead(h),di.insertSequenceNumber(h);function w(B,F){let z=rt.endActivation(B);z.starty+18>F&&(z.starty=F-6,F+=12),di.drawActivation(h,z,F,Ne,XS(B.from).length),rt.insert(z.startx,F-10,z.stopx,F)}o(w,"activeEnd");let E=1,_=1,C=[],D=[],O=0;for(let B of y){let F,z,$;switch(B.type){case n.db.LINETYPE.NOTE:rt.resetVerticalPos(),z=B.noteModel,await oHe(h,z);break;case n.db.LINETYPE.ACTIVE_START:rt.newActivation(B,h,f);break;case n.db.LINETYPE.ACTIVE_END:w(B,rt.getVerticalPos());break;case n.db.LINETYPE.LOOP_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.LOOP_END:F=rt.endLoop(),await di.drawLoop(h,F,"loop",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.RECT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin,U=>rt.newLoop(void 0,U.message));break;case n.db.LINETYPE.RECT_END:F=rt.endLoop(),D.push(F),rt.models.addLoop(F),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos());break;case n.db.LINETYPE.OPT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.OPT_END:F=rt.endLoop(),await di.drawLoop(h,F,"opt",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.ALT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.ALT_ELSE:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.ALT_END:F=rt.endLoop(),await di.drawLoop(h,F,"alt",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U)),rt.saveVerticalPos();break;case n.db.LINETYPE.PAR_AND:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.PAR_END:F=rt.endLoop(),await di.drawLoop(h,F,"par",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.AUTONUMBER:E=B.message.start||E,_=B.message.step||_,B.message.visible?n.db.enableSequenceNumbers():n.db.disableSequenceNumbers();break;case n.db.LINETYPE.CRITICAL_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.CRITICAL_OPTION:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.CRITICAL_END:F=rt.endLoop(),await di.drawLoop(h,F,"critical",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.BREAK_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.BREAK_END:F=rt.endLoop(),await di.drawLoop(h,F,"break",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;default:try{$=B.msgModel,$.starty=rt.getVerticalPos(),$.sequenceIndex=E,$.sequenceVisible=n.db.showSequenceNumbers();let U=await lHe(h,$);hHe(B,$,U,O,f,d,p),C.push({messageModel:$,lineStartY:U}),rt.models.addMessage($)}catch(U){X.error("error while drawing message",U)}}[n.db.LINETYPE.SOLID_OPEN,n.db.LINETYPE.DOTTED_OPEN,n.db.LINETYPE.SOLID,n.db.LINETYPE.DOTTED,n.db.LINETYPE.SOLID_CROSS,n.db.LINETYPE.DOTTED_CROSS,n.db.LINETYPE.SOLID_POINT,n.db.LINETYPE.DOTTED_POINT,n.db.LINETYPE.BIDIRECTIONAL_SOLID,n.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(B.type)&&(E=E+_),O++}X.debug("createdActors",d),X.debug("destroyedActors",p),await xP(h,f,g,!1);for(let B of C)await cHe(h,B.messageModel,B.lineStartY,n);Ne.mirrorActors&&await xP(h,f,g,!0),D.forEach(B=>di.drawBackgroundRect(h,B)),gP(h,f,g,Ne);for(let B of rt.models.boxes)B.height=rt.getVerticalPos()-B.y,rt.insert(B.x,B.y,B.x+B.width,B.height),B.startx=B.x,B.starty=B.y,B.stopx=B.startx+B.width,B.stopy=B.starty+B.height,B.stroke="rgb(0,0,0, 0.5)",di.drawBox(h,B,Ne);x&&rt.bumpVerticalPos(Ne.boxMargin);let R=Gde(h,f,g,u),{bounds:k}=rt.getBounds();k.startx===void 0&&(k.startx=0),k.starty===void 0&&(k.starty=0),k.stopx===void 0&&(k.stopx=0),k.stopy===void 0&&(k.stopy=0);let L=k.stopy-k.starty;L2,d=o(y=>l?-y:y,"adjustValue");t.from===t.to?h=u:(t.activate&&!f&&(h+=d(Ne.activationWidth/2-1)),[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(h+=d(3)),[r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type)&&(u-=d(3)));let p=[n,i,a,s],m=Math.abs(u-h);t.wrap&&t.message&&(t.message=Vt.wrapLabel(t.message,Ze.getMax(m+2*Ne.wrapPadding,Ne.width),$p(Ne)));let g=Vt.calculateTextDimensions(t.message,$p(Ne));return{width:Ze.getMax(t.wrap?0:g.width+2*Ne.wrapPadding,m+2*Ne.wrapPadding,Ne.width),height:0,startx:u,stopx:h,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,p),toBounds:Math.max.apply(null,p)}},"buildMessageModel"),vHe=o(async function(t,e,r,n){let i={},a=[],s,l,u;for(let h of t){switch(h.type){case n.db.LINETYPE.LOOP_START:case n.db.LINETYPE.ALT_START:case n.db.LINETYPE.OPT_START:case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:case n.db.LINETYPE.CRITICAL_START:case n.db.LINETYPE.BREAK_START:a.push({id:h.id,msg:h.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case n.db.LINETYPE.ALT_ELSE:case n.db.LINETYPE.PAR_AND:case n.db.LINETYPE.CRITICAL_OPTION:h.message&&(s=a.pop(),i[s.id]=s,i[h.id]=s,a.push(s));break;case n.db.LINETYPE.LOOP_END:case n.db.LINETYPE.ALT_END:case n.db.LINETYPE.OPT_END:case n.db.LINETYPE.PAR_END:case n.db.LINETYPE.CRITICAL_END:case n.db.LINETYPE.BREAK_END:s=a.pop(),i[s.id]=s;break;case n.db.LINETYPE.ACTIVE_START:{let d=e.get(h.from?h.from:h.to.actor),p=XS(h.from?h.from:h.to.actor).length,m=d.x+d.width/2+(p-1)*Ne.activationWidth/2,g={startx:m,stopx:m+Ne.activationWidth,actor:h.from,enabled:!0};rt.activations.push(g)}break;case n.db.LINETYPE.ACTIVE_END:{let d=rt.activations.map(p=>p.actor).lastIndexOf(h.from);rt.activations.splice(d,1).splice(0,1)}break}h.placement!==void 0?(l=await gHe(h,e,n),h.noteModel=l,a.forEach(d=>{s=d,s.from=Ze.getMin(s.from,l.startx),s.to=Ze.getMax(s.to,l.startx+l.width),s.width=Ze.getMax(s.width,Math.abs(s.from-s.to))-Ne.labelBoxWidth})):(u=yHe(h,e,n),h.msgModel=u,u.startx&&u.stopx&&a.length>0&&a.forEach(d=>{if(s=d,u.startx===u.stopx){let p=e.get(h.from),m=e.get(h.to);s.from=Ze.getMin(p.x-u.width/2,p.x-p.width/2,s.from),s.to=Ze.getMax(m.x+u.width/2,m.x+p.width/2,s.to),s.width=Ze.getMax(s.width,Math.abs(s.to-s.from))-Ne.labelBoxWidth}else s.from=Ze.getMin(u.startx,s.from),s.to=Ze.getMax(u.stopx,s.to),s.width=Ze.getMax(s.width,u.width)-Ne.labelBoxWidth}))}return rt.activations=[],X.debug("Loop type widths:",i),i},"calculateLoopBounds"),Ude={bounds:rt,drawActors:xP,drawActorsPopup:Gde,setConf:Vde,draw:fHe}});var Wde={};ur(Wde,{diagram:()=>xHe});var xHe,qde=N(()=>{"use strict";Dde();Lde();Nde();Gt();Hde();xHe={parser:_de,get db(){return new YS},renderer:Ude,styles:Rde,init:o(t=>{t.sequence||(t.sequence={}),t.wrap&&(t.sequence.wrap=t.wrap,nv({sequence:{wrap:t.wrap}}))},"init")}});var bP,jS,TP=N(()=>{"use strict";bP=function(){var t=o(function(Ie,xe,q,de){for(q=q||{},de=Ie.length;de--;q[Ie[de]]=xe);return q},"o"),e=[1,18],r=[1,19],n=[1,20],i=[1,41],a=[1,42],s=[1,26],l=[1,24],u=[1,25],h=[1,32],f=[1,33],d=[1,34],p=[1,45],m=[1,35],g=[1,36],y=[1,37],v=[1,38],x=[1,27],b=[1,28],T=[1,29],S=[1,30],w=[1,31],E=[1,44],_=[1,46],C=[1,43],D=[1,47],O=[1,9],R=[1,8,9],k=[1,58],L=[1,59],A=[1,60],I=[1,61],M=[1,62],P=[1,63],B=[1,64],F=[1,8,9,41],z=[1,76],$=[1,8,9,12,13,22,39,41,44,66,67,68,69,70,71,72,77,79],U=[1,8,9,12,13,17,20,22,39,41,44,48,58,66,67,68,69,70,71,72,77,79,84,99,101,102],K=[13,58,84,99,101,102],ee=[13,58,71,72,84,99,101,102],Y=[13,58,66,67,68,69,70,84,99,101,102],ce=[1,98],Z=[1,115],ue=[1,107],Q=[1,113],j=[1,108],ne=[1,109],te=[1,110],he=[1,111],le=[1,112],J=[1,114],Se=[22,58,59,80,84,85,86,87,88,89],se=[1,8,9,39,41,44],ae=[1,8,9,22],Oe=[1,143],ye=[1,8,9,59],Be=[1,8,9,22,58,59,80,84,85,86,87,88,89],He={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,DOT:17,className:18,classLiteralName:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,CLASS:46,ANNOTATION_START:47,ANNOTATION_END:48,MEMBER:49,SEPARATOR:50,relation:51,NOTE_FOR:52,noteText:53,NOTE:54,CLASSDEF:55,classList:56,stylesOpt:57,ALPHA:58,COMMA:59,direction_tb:60,direction_bt:61,direction_rl:62,direction_lr:63,relationType:64,lineType:65,AGGREGATION:66,EXTENSION:67,COMPOSITION:68,DEPENDENCY:69,LOLLIPOP:70,LINE:71,DOTTED_LINE:72,CALLBACK:73,LINK:74,LINK_TARGET:75,CLICK:76,CALLBACK_NAME:77,CALLBACK_ARGS:78,HREF:79,STYLE:80,CSSCLASS:81,style:82,styleComponent:83,NUM:84,COLON:85,UNIT:86,SPACE:87,BRKT:88,PCT:89,commentToken:90,textToken:91,graphCodeTokens:92,textNoTagsToken:93,TAGSTART:94,TAGEND:95,"==":96,"--":97,DEFAULT:98,MINUS:99,keywords:100,UNICODE_TEXT:101,BQUOTE_STR:102,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",17:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"CLASS",47:"ANNOTATION_START",48:"ANNOTATION_END",49:"MEMBER",50:"SEPARATOR",52:"NOTE_FOR",54:"NOTE",55:"CLASSDEF",58:"ALPHA",59:"COMMA",60:"direction_tb",61:"direction_bt",62:"direction_rl",63:"direction_lr",66:"AGGREGATION",67:"EXTENSION",68:"COMPOSITION",69:"DEPENDENCY",70:"LOLLIPOP",71:"LINE",72:"DOTTED_LINE",73:"CALLBACK",74:"LINK",75:"LINK_TARGET",76:"CLICK",77:"CALLBACK_NAME",78:"CALLBACK_ARGS",79:"HREF",80:"STYLE",81:"CSSCLASS",84:"NUM",85:"COLON",86:"UNIT",87:"SPACE",88:"BRKT",89:"PCT",92:"graphCodeTokens",94:"TAGSTART",95:"TAGEND",96:"==",97:"--",98:"DEFAULT",99:"MINUS",100:"keywords",101:"UNICODE_TEXT",102:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,3],[15,2],[18,1],[18,3],[18,1],[18,2],[18,2],[18,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,6],[43,2],[43,3],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[56,1],[56,3],[32,1],[32,1],[32,1],[32,1],[51,3],[51,2],[51,2],[51,1],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[57,1],[57,3],[82,1],[82,2],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[90,1],[90,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[93,1],[93,1],[93,1],[93,1],[16,1],[16,1],[16,1],[16,1],[19,1],[53,1]],performAction:o(function(xe,q,de,ie,oe,V,Te){var W=V.length-1;switch(oe){case 8:this.$=V[W-1];break;case 9:case 12:case 14:this.$=V[W];break;case 10:case 13:this.$=V[W-2]+"."+V[W];break;case 11:case 15:this.$=V[W-1]+V[W];break;case 16:case 17:this.$=V[W-1]+"~"+V[W]+"~";break;case 18:ie.addRelation(V[W]);break;case 19:V[W-1].title=ie.cleanupLabel(V[W]),ie.addRelation(V[W-1]);break;case 30:this.$=V[W].trim(),ie.setAccTitle(this.$);break;case 31:case 32:this.$=V[W].trim(),ie.setAccDescription(this.$);break;case 33:ie.addClassesToNamespace(V[W-3],V[W-1]);break;case 34:ie.addClassesToNamespace(V[W-4],V[W-1]);break;case 35:this.$=V[W],ie.addNamespace(V[W]);break;case 36:this.$=[V[W]];break;case 37:this.$=[V[W-1]];break;case 38:V[W].unshift(V[W-2]),this.$=V[W];break;case 40:ie.setCssClass(V[W-2],V[W]);break;case 41:ie.addMembers(V[W-3],V[W-1]);break;case 42:ie.setCssClass(V[W-5],V[W-3]),ie.addMembers(V[W-5],V[W-1]);break;case 43:this.$=V[W],ie.addClass(V[W]);break;case 44:this.$=V[W-1],ie.addClass(V[W-1]),ie.setClassLabel(V[W-1],V[W]);break;case 45:ie.addAnnotation(V[W],V[W-2]);break;case 46:case 59:this.$=[V[W]];break;case 47:V[W].push(V[W-1]),this.$=V[W];break;case 48:break;case 49:ie.addMember(V[W-1],ie.cleanupLabel(V[W]));break;case 50:break;case 51:break;case 52:this.$={id1:V[W-2],id2:V[W],relation:V[W-1],relationTitle1:"none",relationTitle2:"none"};break;case 53:this.$={id1:V[W-3],id2:V[W],relation:V[W-1],relationTitle1:V[W-2],relationTitle2:"none"};break;case 54:this.$={id1:V[W-3],id2:V[W],relation:V[W-2],relationTitle1:"none",relationTitle2:V[W-1]};break;case 55:this.$={id1:V[W-4],id2:V[W],relation:V[W-2],relationTitle1:V[W-3],relationTitle2:V[W-1]};break;case 56:ie.addNote(V[W],V[W-1]);break;case 57:ie.addNote(V[W]);break;case 58:this.$=V[W-2],ie.defineClass(V[W-1],V[W]);break;case 60:this.$=V[W-2].concat([V[W]]);break;case 61:ie.setDirection("TB");break;case 62:ie.setDirection("BT");break;case 63:ie.setDirection("RL");break;case 64:ie.setDirection("LR");break;case 65:this.$={type1:V[W-2],type2:V[W],lineType:V[W-1]};break;case 66:this.$={type1:"none",type2:V[W],lineType:V[W-1]};break;case 67:this.$={type1:V[W-1],type2:"none",lineType:V[W]};break;case 68:this.$={type1:"none",type2:"none",lineType:V[W]};break;case 69:this.$=ie.relationType.AGGREGATION;break;case 70:this.$=ie.relationType.EXTENSION;break;case 71:this.$=ie.relationType.COMPOSITION;break;case 72:this.$=ie.relationType.DEPENDENCY;break;case 73:this.$=ie.relationType.LOLLIPOP;break;case 74:this.$=ie.lineType.LINE;break;case 75:this.$=ie.lineType.DOTTED_LINE;break;case 76:case 82:this.$=V[W-2],ie.setClickEvent(V[W-1],V[W]);break;case 77:case 83:this.$=V[W-3],ie.setClickEvent(V[W-2],V[W-1]),ie.setTooltip(V[W-2],V[W]);break;case 78:this.$=V[W-2],ie.setLink(V[W-1],V[W]);break;case 79:this.$=V[W-3],ie.setLink(V[W-2],V[W-1],V[W]);break;case 80:this.$=V[W-3],ie.setLink(V[W-2],V[W-1]),ie.setTooltip(V[W-2],V[W]);break;case 81:this.$=V[W-4],ie.setLink(V[W-3],V[W-2],V[W]),ie.setTooltip(V[W-3],V[W-1]);break;case 84:this.$=V[W-3],ie.setClickEvent(V[W-2],V[W-1],V[W]);break;case 85:this.$=V[W-4],ie.setClickEvent(V[W-3],V[W-2],V[W-1]),ie.setTooltip(V[W-3],V[W]);break;case 86:this.$=V[W-3],ie.setLink(V[W-2],V[W]);break;case 87:this.$=V[W-4],ie.setLink(V[W-3],V[W-1],V[W]);break;case 88:this.$=V[W-4],ie.setLink(V[W-3],V[W-1]),ie.setTooltip(V[W-3],V[W]);break;case 89:this.$=V[W-5],ie.setLink(V[W-4],V[W-2],V[W]),ie.setTooltip(V[W-4],V[W-1]);break;case 90:this.$=V[W-2],ie.setCssStyle(V[W-1],V[W]);break;case 91:ie.setCssClass(V[W-1],V[W]);break;case 92:this.$=[V[W]];break;case 93:V[W-2].push(V[W]),this.$=V[W-2];break;case 95:this.$=V[W-1]+V[W];break}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(O,[2,5],{8:[1,48]}),{8:[1,49]},t(R,[2,18],{22:[1,50]}),t(R,[2,20]),t(R,[2,21]),t(R,[2,22]),t(R,[2,23]),t(R,[2,24]),t(R,[2,25]),t(R,[2,26]),t(R,[2,27]),t(R,[2,28]),t(R,[2,29]),{34:[1,51]},{36:[1,52]},t(R,[2,32]),t(R,[2,48],{51:53,64:56,65:57,13:[1,54],22:[1,55],66:k,67:L,68:A,69:I,70:M,71:P,72:B}),{39:[1,65]},t(F,[2,39],{39:[1,67],44:[1,66]}),t(R,[2,50]),t(R,[2,51]),{16:68,58:p,84:E,99:_,101:C},{16:39,18:69,19:40,58:p,84:E,99:_,101:C,102:D},{16:39,18:70,19:40,58:p,84:E,99:_,101:C,102:D},{16:39,18:71,19:40,58:p,84:E,99:_,101:C,102:D},{58:[1,72]},{13:[1,73]},{16:39,18:74,19:40,58:p,84:E,99:_,101:C,102:D},{13:z,53:75},{56:77,58:[1,78]},t(R,[2,61]),t(R,[2,62]),t(R,[2,63]),t(R,[2,64]),t($,[2,12],{16:39,19:40,18:80,17:[1,79],20:[1,81],58:p,84:E,99:_,101:C,102:D}),t($,[2,14],{20:[1,82]}),{15:83,16:84,58:p,84:E,99:_,101:C},{16:39,18:85,19:40,58:p,84:E,99:_,101:C,102:D},t(U,[2,118]),t(U,[2,119]),t(U,[2,120]),t(U,[2,121]),t([1,8,9,12,13,20,22,39,41,44,66,67,68,69,70,71,72,77,79],[2,122]),t(O,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,18:21,38:22,43:23,16:39,19:40,5:86,33:e,35:r,37:n,42:i,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D}),{5:87,10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D},t(R,[2,19]),t(R,[2,30]),t(R,[2,31]),{13:[1,89],16:39,18:88,19:40,58:p,84:E,99:_,101:C,102:D},{51:90,64:56,65:57,66:k,67:L,68:A,69:I,70:M,71:P,72:B},t(R,[2,49]),{65:91,71:P,72:B},t(K,[2,68],{64:92,66:k,67:L,68:A,69:I,70:M}),t(ee,[2,69]),t(ee,[2,70]),t(ee,[2,71]),t(ee,[2,72]),t(ee,[2,73]),t(Y,[2,74]),t(Y,[2,75]),{8:[1,94],24:95,40:93,43:23,46:a},{16:96,58:p,84:E,99:_,101:C},{45:97,49:ce},{48:[1,99]},{13:[1,100]},{13:[1,101]},{77:[1,102],79:[1,103]},{22:Z,57:104,58:ue,80:Q,82:105,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},{58:[1,116]},{13:z,53:117},t(R,[2,57]),t(R,[2,123]),{22:Z,57:118,58:ue,59:[1,119],80:Q,82:105,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},t(Se,[2,59]),{16:39,18:120,19:40,58:p,84:E,99:_,101:C,102:D},t($,[2,15]),t($,[2,16]),t($,[2,17]),{39:[2,35]},{15:122,16:84,17:[1,121],39:[2,9],58:p,84:E,99:_,101:C},t(se,[2,43],{11:123,12:[1,124]}),t(O,[2,7]),{9:[1,125]},t(ae,[2,52]),{16:39,18:126,19:40,58:p,84:E,99:_,101:C,102:D},{13:[1,128],16:39,18:127,19:40,58:p,84:E,99:_,101:C,102:D},t(K,[2,67],{64:129,66:k,67:L,68:A,69:I,70:M}),t(K,[2,66]),{41:[1,130]},{24:95,40:131,43:23,46:a},{8:[1,132],41:[2,36]},t(F,[2,40],{39:[1,133]}),{41:[1,134]},{41:[2,46],45:135,49:ce},{16:39,18:136,19:40,58:p,84:E,99:_,101:C,102:D},t(R,[2,76],{13:[1,137]}),t(R,[2,78],{13:[1,139],75:[1,138]}),t(R,[2,82],{13:[1,140],78:[1,141]}),{13:[1,142]},t(R,[2,90],{59:Oe}),t(ye,[2,92],{83:144,22:Z,58:ue,80:Q,84:j,85:ne,86:te,87:he,88:le,89:J}),t(Be,[2,94]),t(Be,[2,96]),t(Be,[2,97]),t(Be,[2,98]),t(Be,[2,99]),t(Be,[2,100]),t(Be,[2,101]),t(Be,[2,102]),t(Be,[2,103]),t(Be,[2,104]),t(R,[2,91]),t(R,[2,56]),t(R,[2,58],{59:Oe}),{58:[1,145]},t($,[2,13]),{15:146,16:84,58:p,84:E,99:_,101:C},{39:[2,11]},t(se,[2,44]),{13:[1,147]},{1:[2,4]},t(ae,[2,54]),t(ae,[2,53]),{16:39,18:148,19:40,58:p,84:E,99:_,101:C,102:D},t(K,[2,65]),t(R,[2,33]),{41:[1,149]},{24:95,40:150,41:[2,37],43:23,46:a},{45:151,49:ce},t(F,[2,41]),{41:[2,47]},t(R,[2,45]),t(R,[2,77]),t(R,[2,79]),t(R,[2,80],{75:[1,152]}),t(R,[2,83]),t(R,[2,84],{13:[1,153]}),t(R,[2,86],{13:[1,155],75:[1,154]}),{22:Z,58:ue,80:Q,82:156,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},t(Be,[2,95]),t(Se,[2,60]),{39:[2,10]},{14:[1,157]},t(ae,[2,55]),t(R,[2,34]),{41:[2,38]},{41:[1,158]},t(R,[2,81]),t(R,[2,85]),t(R,[2,87]),t(R,[2,88],{75:[1,159]}),t(ye,[2,93],{83:144,22:Z,58:ue,80:Q,84:j,85:ne,86:te,87:he,88:le,89:J}),t(se,[2,8]),t(F,[2,42]),t(R,[2,89])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],83:[2,35],122:[2,11],125:[2,4],135:[2,47],146:[2,10],150:[2,38]},parseError:o(function(xe,q){if(q.recoverable)this.trace(xe);else{var de=new Error(xe);throw de.hash=q,de}},"parseError"),parse:o(function(xe){var q=this,de=[0],ie=[],oe=[null],V=[],Te=this.table,W="",pe=0,ve=0,Pe=0,_e=2,be=1,Ve=V.slice.call(arguments,1),De=Object.create(this.lexer),qe={yy:{}};for(var at in this.yy)Object.prototype.hasOwnProperty.call(this.yy,at)&&(qe.yy[at]=this.yy[at]);De.setInput(xe,qe.yy),qe.yy.lexer=De,qe.yy.parser=this,typeof De.yylloc>"u"&&(De.yylloc={});var Rt=De.yylloc;V.push(Rt);var st=De.options&&De.options.ranges;typeof qe.yy.parseError=="function"?this.parseError=qe.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ue(kt){de.length=de.length-2*kt,oe.length=oe.length-kt,V.length=V.length-kt}o(Ue,"popStack");function ct(){var kt;return kt=ie.pop()||De.lex()||be,typeof kt!="number"&&(kt instanceof Array&&(ie=kt,kt=ie.pop()),kt=q.symbols_[kt]||kt),kt}o(ct,"lex");for(var We,ot,Yt,Tt,Mt,bt,ut={},St,ft,vt,nt;;){if(Yt=de[de.length-1],this.defaultActions[Yt]?Tt=this.defaultActions[Yt]:((We===null||typeof We>"u")&&(We=ct()),Tt=Te[Yt]&&Te[Yt][We]),typeof Tt>"u"||!Tt.length||!Tt[0]){var pn="";nt=[];for(St in Te[Yt])this.terminals_[St]&&St>_e&&nt.push("'"+this.terminals_[St]+"'");De.showPosition?pn="Parse error on line "+(pe+1)+`: +`+De.showPosition()+` +Expecting `+nt.join(", ")+", got '"+(this.terminals_[We]||We)+"'":pn="Parse error on line "+(pe+1)+": Unexpected "+(We==be?"end of input":"'"+(this.terminals_[We]||We)+"'"),this.parseError(pn,{text:De.match,token:this.terminals_[We]||We,line:De.yylineno,loc:Rt,expected:nt})}if(Tt[0]instanceof Array&&Tt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Yt+", token: "+We);switch(Tt[0]){case 1:de.push(We),oe.push(De.yytext),V.push(De.yylloc),de.push(Tt[1]),We=null,ot?(We=ot,ot=null):(ve=De.yyleng,W=De.yytext,pe=De.yylineno,Rt=De.yylloc,Pe>0&&Pe--);break;case 2:if(ft=this.productions_[Tt[1]][1],ut.$=oe[oe.length-ft],ut._$={first_line:V[V.length-(ft||1)].first_line,last_line:V[V.length-1].last_line,first_column:V[V.length-(ft||1)].first_column,last_column:V[V.length-1].last_column},st&&(ut._$.range=[V[V.length-(ft||1)].range[0],V[V.length-1].range[1]]),bt=this.performAction.apply(ut,[W,ve,pe,qe.yy,Tt[1],oe,V].concat(Ve)),typeof bt<"u")return bt;ft&&(de=de.slice(0,-1*ft*2),oe=oe.slice(0,-1*ft),V=V.slice(0,-1*ft)),de.push(this.productions_[Tt[1]][0]),oe.push(ut.$),V.push(ut._$),vt=Te[de[de.length-2]][de[de.length-1]],de.push(vt);break;case 3:return!0}}return!0},"parse")},ze=function(){var Ie={EOF:1,parseError:o(function(q,de){if(this.yy.parser)this.yy.parser.parseError(q,de);else throw new Error(q)},"parseError"),setInput:o(function(xe,q){return this.yy=q||this.yy||{},this._input=xe,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var xe=this._input[0];this.yytext+=xe,this.yyleng++,this.offset++,this.match+=xe,this.matched+=xe;var q=xe.match(/(?:\r\n?|\n).*/g);return q?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),xe},"input"),unput:o(function(xe){var q=xe.length,de=xe.split(/(?:\r\n?|\n)/g);this._input=xe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-q),this.offset-=q;var ie=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),de.length-1&&(this.yylineno-=de.length-1);var oe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:de?(de.length===ie.length?this.yylloc.first_column:0)+ie[ie.length-de.length].length-de[0].length:this.yylloc.first_column-q},this.options.ranges&&(this.yylloc.range=[oe[0],oe[0]+this.yyleng-q]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(xe){this.unput(this.match.slice(xe))},"less"),pastInput:o(function(){var xe=this.matched.substr(0,this.matched.length-this.match.length);return(xe.length>20?"...":"")+xe.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var xe=this.match;return xe.length<20&&(xe+=this._input.substr(0,20-xe.length)),(xe.substr(0,20)+(xe.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var xe=this.pastInput(),q=new Array(xe.length+1).join("-");return xe+this.upcomingInput()+` +`+q+"^"},"showPosition"),test_match:o(function(xe,q){var de,ie,oe;if(this.options.backtrack_lexer&&(oe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(oe.yylloc.range=this.yylloc.range.slice(0))),ie=xe[0].match(/(?:\r\n?|\n).*/g),ie&&(this.yylineno+=ie.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:ie?ie[ie.length-1].length-ie[ie.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+xe[0].length},this.yytext+=xe[0],this.match+=xe[0],this.matches=xe,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(xe[0].length),this.matched+=xe[0],de=this.performAction.call(this,this.yy,this,q,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),de)return de;if(this._backtrack){for(var V in oe)this[V]=oe[V];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var xe,q,de,ie;this._more||(this.yytext="",this.match="");for(var oe=this._currentRules(),V=0;Vq[0].length)){if(q=de,ie=V,this.options.backtrack_lexer){if(xe=this.test_match(de,oe[V]),xe!==!1)return xe;if(this._backtrack){q=!1;continue}else return!1}else if(!this.options.flex)break}return q?(xe=this.test_match(q,oe[ie]),xe!==!1?xe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var q=this.next();return q||this.lex()},"lex"),begin:o(function(q){this.conditionStack.push(q)},"begin"),popState:o(function(){var q=this.conditionStack.length-1;return q>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(q){return q=this.conditionStack.length-1-Math.abs(q||0),q>=0?this.conditionStack[q]:"INITIAL"},"topState"),pushState:o(function(q){this.begin(q)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(q,de,ie,oe){var V=oe;switch(ie){case 0:return 60;case 1:return 61;case 2:return 62;case 3:return 63;case 4:break;case 5:break;case 6:return this.begin("acc_title"),33;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),35;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 8;case 14:break;case 15:return 7;case 16:return 7;case 17:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 19:this.popState();break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 77;case 22:this.popState();break;case 23:return 78;case 24:this.popState();break;case 25:return"STR";case 26:this.begin("string");break;case 27:return 80;case 28:return 55;case 29:return this.begin("namespace"),42;break;case 30:return this.popState(),8;break;case 31:break;case 32:return this.begin("namespace-body"),39;break;case 33:return this.popState(),41;break;case 34:return"EOF_IN_STRUCT";case 35:return 8;case 36:break;case 37:return"EDGE_STATE";case 38:return this.begin("class"),46;break;case 39:return this.popState(),8;break;case 40:break;case 41:return this.popState(),this.popState(),41;break;case 42:return this.begin("class-body"),39;break;case 43:return this.popState(),41;break;case 44:return"EOF_IN_STRUCT";case 45:return"EDGE_STATE";case 46:return"OPEN_IN_STRUCT";case 47:break;case 48:return"MEMBER";case 49:return 81;case 50:return 73;case 51:return 74;case 52:return 76;case 53:return 52;case 54:return 54;case 55:return 47;case 56:return 48;case 57:return 79;case 58:this.popState();break;case 59:return"GENERICTYPE";case 60:this.begin("generic");break;case 61:this.popState();break;case 62:return"BQUOTE_STR";case 63:this.begin("bqstring");break;case 64:return 75;case 65:return 75;case 66:return 75;case 67:return 75;case 68:return 67;case 69:return 67;case 70:return 69;case 71:return 69;case 72:return 68;case 73:return 66;case 74:return 70;case 75:return 71;case 76:return 72;case 77:return 22;case 78:return 44;case 79:return 99;case 80:return 17;case 81:return"PLUS";case 82:return 85;case 83:return 59;case 84:return 88;case 85:return 88;case 86:return 89;case 87:return"EQUALS";case 88:return"EQUALS";case 89:return 58;case 90:return 12;case 91:return 14;case 92:return"PUNCTUATION";case 93:return 84;case 94:return 101;case 95:return 87;case 96:return 87;case 97:return 9}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:classDef\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,33,34,35,36,37,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},namespace:{rules:[26,29,30,31,32,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},"class-body":{rules:[26,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},class:{rules:[26,39,40,41,42,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr:{rules:[9,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_title:{rules:[7,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_args:{rules:[22,23,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_name:{rules:[19,20,21,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},href:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},struct:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},generic:{rules:[26,49,50,51,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},bqstring:{rules:[26,49,50,51,52,53,54,55,56,57,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},string:{rules:[24,25,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,29,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}};return Ie}();He.lexer=ze;function Le(){this.yy={}}return o(Le,"Parser"),Le.prototype=He,He.Parser=Le,new Le}();bP.parser=bP;jS=bP});var jde,Ib,Kde=N(()=>{"use strict";Gt();pr();jde=["#","+","~","-",""],Ib=class{static{o(this,"ClassMember")}constructor(e,r){this.memberType=r,this.visibility="",this.classifier="",this.text="";let n=wr(e,me());this.parseMember(n)}getDisplayDetails(){let e=this.visibility+ic(this.id);this.memberType==="method"&&(e+=`(${ic(this.parameters.trim())})`,this.returnType&&(e+=" : "+ic(this.returnType))),e=e.trim();let r=this.parseClassifier();return{displayText:e,cssStyle:r}}parseMember(e){let r="";if(this.memberType==="method"){let a=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/.exec(e);if(a){let s=a[1]?a[1].trim():"";if(jde.includes(s)&&(this.visibility=s),this.id=a[2],this.parameters=a[3]?a[3].trim():"",r=a[4]?a[4].trim():"",this.returnType=a[5]?a[5].trim():"",r===""){let l=this.returnType.substring(this.returnType.length-1);/[$*]/.exec(l)&&(r=l,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{let i=e.length,a=e.substring(0,1),s=e.substring(i-1);jde.includes(a)&&(this.visibility=a),/[$*]/.exec(s)&&(r=s),this.id=e.substring(this.visibility===""?0:1,r===""?i:i-1)}this.classifier=r,this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim();let n=`${this.visibility?"\\"+this.visibility:""}${ic(this.id)}${this.memberType==="method"?`(${ic(this.parameters)})${this.returnType?" : "+ic(this.returnType):""}`:""}`;this.text=n.replaceAll("<","<").replaceAll(">",">"),this.text.startsWith("\\<")&&(this.text=this.text.replace("\\<","~"))}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}});var KS,Qde,zp,P1,wP=N(()=>{"use strict";fr();yt();Gt();pr();er();ci();Kde();KS="classId-",Qde=0,zp=o(t=>Ze.sanitizeText(t,me()),"sanitizeText"),P1=class{constructor(){this.relations=[];this.classes=new Map;this.styleClasses=new Map;this.notes=[];this.interfaces=[];this.namespaces=new Map;this.namespaceCounter=0;this.functions=[];this.lineType={LINE:0,DOTTED_LINE:1};this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4};this.setupToolTips=o(e=>{let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=this.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.top-14+document.body.scrollTop+"px"),r.html(r.html().replace(/<br\/>/g,"
    ")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})},"setupToolTips");this.direction="TB";this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().class,"getConfig");this.functions.push(this.setupToolTips.bind(this)),this.clear(),this.addRelation=this.addRelation.bind(this),this.addClassesToNamespace=this.addClassesToNamespace.bind(this),this.addNamespace=this.addNamespace.bind(this),this.setCssClass=this.setCssClass.bind(this),this.addMembers=this.addMembers.bind(this),this.addClass=this.addClass.bind(this),this.setClassLabel=this.setClassLabel.bind(this),this.addAnnotation=this.addAnnotation.bind(this),this.addMember=this.addMember.bind(this),this.cleanupLabel=this.cleanupLabel.bind(this),this.addNote=this.addNote.bind(this),this.defineClass=this.defineClass.bind(this),this.setDirection=this.setDirection.bind(this),this.setLink=this.setLink.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.clear=this.clear.bind(this),this.setTooltip=this.setTooltip.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setCssStyle=this.setCssStyle.bind(this)}static{o(this,"ClassDB")}splitClassNameAndType(e){let r=Ze.sanitizeText(e,me()),n="",i=r;if(r.indexOf("~")>0){let a=r.split("~");i=zp(a[0]),n=zp(a[1])}return{className:i,type:n}}setClassLabel(e,r){let n=Ze.sanitizeText(e,me());r&&(r=zp(r));let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).label=r,this.classes.get(i).text=`${r}${this.classes.get(i).type?`<${this.classes.get(i).type}>`:""}`}addClass(e){let r=Ze.sanitizeText(e,me()),{className:n,type:i}=this.splitClassNameAndType(r);if(this.classes.has(n))return;let a=Ze.sanitizeText(n,me());this.classes.set(a,{id:a,type:i,label:a,text:`${a}${i?`<${i}>`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:KS+a+"-"+Qde}),Qde++}addInterface(e,r){let n={id:`interface${this.interfaces.length}`,label:e,classId:r};this.interfaces.push(n)}lookUpDomId(e){let r=Ze.sanitizeText(e,me());if(this.classes.has(r))return this.classes.get(r).domId;throw new Error("Class not found: "+r)}clear(){this.relations=[],this.classes=new Map,this.notes=[],this.interfaces=[],this.functions=[],this.functions.push(this.setupToolTips.bind(this)),this.namespaces=new Map,this.namespaceCounter=0,this.direction="TB",kr()}getClass(e){return this.classes.get(e)}getClasses(){return this.classes}getRelations(){return this.relations}getNotes(){return this.notes}addRelation(e){X.debug("Adding relation: "+JSON.stringify(e));let r=[this.relationType.LOLLIPOP,this.relationType.AGGREGATION,this.relationType.COMPOSITION,this.relationType.DEPENDENCY,this.relationType.EXTENSION];e.relation.type1===this.relationType.LOLLIPOP&&!r.includes(e.relation.type2)?(this.addClass(e.id2),this.addInterface(e.id1,e.id2),e.id1=`interface${this.interfaces.length-1}`):e.relation.type2===this.relationType.LOLLIPOP&&!r.includes(e.relation.type1)?(this.addClass(e.id1),this.addInterface(e.id2,e.id1),e.id2=`interface${this.interfaces.length-1}`):(this.addClass(e.id1),this.addClass(e.id2)),e.id1=this.splitClassNameAndType(e.id1).className,e.id2=this.splitClassNameAndType(e.id2).className,e.relationTitle1=Ze.sanitizeText(e.relationTitle1.trim(),me()),e.relationTitle2=Ze.sanitizeText(e.relationTitle2.trim(),me()),this.relations.push(e)}addAnnotation(e,r){let n=this.splitClassNameAndType(e).className;this.classes.get(n).annotations.push(r)}addMember(e,r){this.addClass(e);let n=this.splitClassNameAndType(e).className,i=this.classes.get(n);if(typeof r=="string"){let a=r.trim();a.startsWith("<<")&&a.endsWith(">>")?i.annotations.push(zp(a.substring(2,a.length-2))):a.indexOf(")")>0?i.methods.push(new Ib(a,"method")):a&&i.members.push(new Ib(a,"attribute"))}}addMembers(e,r){Array.isArray(r)&&(r.reverse(),r.forEach(n=>this.addMember(e,n)))}addNote(e,r){let n={id:`note${this.notes.length}`,class:r,text:e};this.notes.push(n)}cleanupLabel(e){return e.startsWith(":")&&(e=e.substring(1)),zp(e.trim())}setCssClass(e,r){e.split(",").forEach(n=>{let i=n;/\d/.exec(n[0])&&(i=KS+i);let a=this.classes.get(i);a&&(a.cssClasses+=" "+r)})}defineClass(e,r){for(let n of e){let i=this.styleClasses.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.styleClasses.set(n,i)),r&&r.forEach(a=>{if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.classes.forEach(a=>{a.cssClasses.includes(n)&&a.styles.push(...r.flatMap(s=>s.split(",")))})}}setTooltip(e,r){e.split(",").forEach(n=>{r!==void 0&&(this.classes.get(n).tooltip=zp(r))})}getTooltip(e,r){return r&&this.namespaces.has(r)?this.namespaces.get(r).classes.get(e).tooltip:this.classes.get(e).tooltip}setLink(e,r,n){let i=me();e.split(",").forEach(a=>{let s=a;/\d/.exec(a[0])&&(s=KS+s);let l=this.classes.get(s);l&&(l.link=Vt.formatUrl(r,i),i.securityLevel==="sandbox"?l.linkTarget="_top":typeof n=="string"?l.linkTarget=zp(n):l.linkTarget="_blank")}),this.setCssClass(e,"clickable")}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFunc(i,r,n),this.classes.get(i).haveCallback=!0}),this.setCssClass(e,"clickable")}setClickFunc(e,r,n){let i=Ze.sanitizeText(e,me());if(me().securityLevel!=="loose"||r===void 0)return;let s=i;if(this.classes.has(s)){let l=this.lookUpDomId(s),u=[];if(typeof n=="string"){u=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let h=0;h{let h=document.querySelector(`[id="${l}"]`);h!==null&&h.addEventListener("click",()=>{Vt.runFunc(r,...u)},!1)})}}bindFunctions(e){this.functions.forEach(r=>{r(e)})}getDirection(){return this.direction}setDirection(e){this.direction=e}addNamespace(e){this.namespaces.has(e)||(this.namespaces.set(e,{id:e,classes:new Map,children:{},domId:KS+e+"-"+this.namespaceCounter}),this.namespaceCounter++)}getNamespace(e){return this.namespaces.get(e)}getNamespaces(){return this.namespaces}addClassesToNamespace(e,r){if(this.namespaces.has(e))for(let n of r){let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).parent=e,this.namespaces.get(e).classes.set(i,this.classes.get(i))}}setCssStyle(e,r){let n=this.classes.get(e);if(!(!r||!n))for(let i of r)i.includes(",")?n.styles.push(...i.split(",")):n.styles.push(i)}getArrowMarker(e){let r;switch(e){case 0:r="aggregation";break;case 1:r="extension";break;case 2:r="composition";break;case 3:r="dependency";break;case 4:r="lollipop";break;default:r="none"}return r}getData(){let e=[],r=[],n=me();for(let a of this.namespaces.keys()){let s=this.namespaces.get(a);if(s){let l={id:s.id,label:s.id,isGroup:!0,padding:n.class.padding??16,shape:"rect",cssStyles:["fill: none","stroke: black"],look:n.look};e.push(l)}}for(let a of this.classes.keys()){let s=this.classes.get(a);if(s){let l=s;l.parentId=s.parent,l.look=n.look,e.push(l)}}let i=0;for(let a of this.notes){i++;let s={id:a.id,label:a.text,isGroup:!1,shape:"note",padding:n.class.padding??6,cssStyles:["text-align: left","white-space: nowrap",`fill: ${n.themeVariables.noteBkgColor}`,`stroke: ${n.themeVariables.noteBorderColor}`],look:n.look};e.push(s);let l=this.classes.get(a.class)?.id??"";if(l){let u={id:`edgeNote${i}`,start:a.id,end:l,type:"normal",thickness:"normal",classes:"relation",arrowTypeStart:"none",arrowTypeEnd:"none",arrowheadStyle:"",labelStyle:[""],style:["fill: none"],pattern:"dotted",look:n.look};r.push(u)}}for(let a of this.interfaces){let s={id:a.id,label:a.label,isGroup:!1,shape:"rect",cssStyles:["opacity: 0;"],look:n.look};e.push(s)}i=0;for(let a of this.relations){i++;let s={id:Wh(a.id1,a.id2,{prefix:"id",counter:i}),start:a.id1,end:a.id2,type:"normal",label:a.title,labelpos:"c",thickness:"normal",classes:"relation",arrowTypeStart:this.getArrowMarker(a.relation.type1),arrowTypeEnd:this.getArrowMarker(a.relation.type2),startLabelRight:a.relationTitle1==="none"?"":a.relationTitle1,endLabelLeft:a.relationTitle2==="none"?"":a.relationTitle2,arrowheadStyle:"",labelStyle:["display: inline-block"],style:a.style||"",pattern:a.relation.lineType==1?"dashed":"solid",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:this.getDirection()}}}});var kHe,QS,kP=N(()=>{"use strict";Xm();kHe=o(t=>`g.classGroup text { + fill: ${t.nodeBorder||t.classText}; + stroke: none; + font-family: ${t.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${t.classText}; +} +.edgeLabel .label rect { + fill: ${t.mainBkg}; +} +.label text { + fill: ${t.classText}; +} + +.labelBkg { + background: ${t.mainBkg}; +} +.edgeLabel .label span { + background: ${t.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${t.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; +} + +g.classGroup line { + stroke: ${t.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${t.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${t.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${t.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${t.lineColor} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${t.lineColor} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${t.lineColor} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${t.lineColor} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${t.mainBkg} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${t.mainBkg} !important; + stroke: ${t.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; + line-height: initial; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.textColor}; +} + ${Nc()} +`,"getStyles"),QS=kHe});var EHe,SHe,CHe,ZS,EP=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();EHe=o((t,e="TB")=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),SHe=o(function(t,e){return e.db.getClasses()},"getClasses"),CHe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing class diagram (v3)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["aggregation","extension","composition","dependency","lollipop"],l.diagramId=e,await Rc(l,u);let h=8;Vt.insertTitle(u,"classDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,"classDiagram",a?.useMaxWidth??!0)},"draw"),ZS={getClasses:SHe,draw:CHe,getDir:EHe}});var Zde={};ur(Zde,{diagram:()=>AHe});var AHe,Jde=N(()=>{"use strict";TP();wP();kP();EP();AHe={parser:jS,get db(){return new P1},renderer:ZS,styles:QS,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var rpe={};ur(rpe,{diagram:()=>RHe});var RHe,npe=N(()=>{"use strict";TP();wP();kP();EP();RHe={parser:jS,get db(){return new P1},renderer:ZS,styles:QS,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var SP,JS,CP=N(()=>{"use strict";SP=function(){var t=o(function(F,z,$,U){for($=$||{},U=F.length;U--;$[F[U]]=z);return $},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,16],u=[1,17],h=[1,18],f=[1,19],d=[1,33],p=[1,20],m=[1,21],g=[1,22],y=[1,23],v=[1,24],x=[1,26],b=[1,27],T=[1,28],S=[1,29],w=[1,30],E=[1,31],_=[1,32],C=[1,35],D=[1,36],O=[1,37],R=[1,38],k=[1,34],L=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],A=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,39,40,41,45,48,51,52,53,54,57],I=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],M={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"-->":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,CLICK:38,STRING:39,HREF:40,classDef:41,CLASSDEF_ID:42,CLASSDEF_STYLEOPTS:43,DEFAULT:44,style:45,STYLE_IDS:46,STYLEDEF_STYLEOPTS:47,class:48,CLASSENTITY_IDS:49,STYLECLASS:50,direction_tb:51,direction_bt:52,direction_rl:53,direction_lr:54,eol:55,";":56,EDGE_STATE:57,STYLE_SEPARATOR:58,left_of:59,right_of:60,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"-->",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"CLICK",39:"STRING",40:"HREF",41:"classDef",42:"CLASSDEF_ID",43:"CLASSDEF_STYLEOPTS",44:"DEFAULT",45:"style",46:"STYLE_IDS",47:"STYLEDEF_STYLEOPTS",48:"class",49:"CLASSENTITY_IDS",50:"STYLECLASS",51:"direction_tb",52:"direction_bt",53:"direction_rl",54:"direction_lr",56:";",57:"EDGE_STATE",58:"STYLE_SEPARATOR",59:"left_of",60:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[9,5],[9,5],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[55,1],[55,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:o(function(z,$,U,K,ee,Y,ce){var Z=Y.length-1;switch(ee){case 3:return K.setRootDoc(Y[Z]),Y[Z];break;case 4:this.$=[];break;case 5:Y[Z]!="nl"&&(Y[Z-1].push(Y[Z]),this.$=Y[Z-1]);break;case 6:case 7:this.$=Y[Z];break;case 8:this.$="nl";break;case 12:this.$=Y[Z];break;case 13:let ne=Y[Z-1];ne.description=K.trimColon(Y[Z]),this.$=ne;break;case 14:this.$={stmt:"relation",state1:Y[Z-2],state2:Y[Z]};break;case 15:let te=K.trimColon(Y[Z]);this.$={stmt:"relation",state1:Y[Z-3],state2:Y[Z-1],description:te};break;case 19:this.$={stmt:"state",id:Y[Z-3],type:"default",description:"",doc:Y[Z-1]};break;case 20:var ue=Y[Z],Q=Y[Z-2].trim();if(Y[Z].match(":")){var j=Y[Z].split(":");ue=j[0],Q=[Q,j[1]]}this.$={stmt:"state",id:ue,type:"default",description:Q};break;case 21:this.$={stmt:"state",id:Y[Z-3],type:"default",description:Y[Z-5],doc:Y[Z-1]};break;case 22:this.$={stmt:"state",id:Y[Z],type:"fork"};break;case 23:this.$={stmt:"state",id:Y[Z],type:"join"};break;case 24:this.$={stmt:"state",id:Y[Z],type:"choice"};break;case 25:this.$={stmt:"state",id:K.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:Y[Z-1].trim(),note:{position:Y[Z-2].trim(),text:Y[Z].trim()}};break;case 29:this.$=Y[Z].trim(),K.setAccTitle(this.$);break;case 30:case 31:this.$=Y[Z].trim(),K.setAccDescription(this.$);break;case 32:this.$={stmt:"click",id:Y[Z-3],url:Y[Z-2],tooltip:Y[Z-1]};break;case 33:this.$={stmt:"click",id:Y[Z-3],url:Y[Z-1],tooltip:""};break;case 34:case 35:this.$={stmt:"classDef",id:Y[Z-1].trim(),classes:Y[Z].trim()};break;case 36:this.$={stmt:"style",id:Y[Z-1].trim(),styleClass:Y[Z].trim()};break;case 37:this.$={stmt:"applyClass",id:Y[Z-1].trim(),styleClass:Y[Z].trim()};break;case 38:K.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:K.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:K.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:K.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:Y[Z].trim(),type:"default",description:""};break;case 46:this.$={stmt:"state",id:Y[Z-2].trim(),classes:[Y[Z].trim()],type:"default",description:""};break;case 47:this.$={stmt:"state",id:Y[Z-2].trim(),classes:[Y[Z].trim()],type:"default",description:""};break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,5]),{9:39,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,7]),t(L,[2,8]),t(L,[2,9]),t(L,[2,10]),t(L,[2,11]),t(L,[2,12],{14:[1,40],15:[1,41]}),t(L,[2,16]),{18:[1,42]},t(L,[2,18],{20:[1,43]}),{23:[1,44]},t(L,[2,22]),t(L,[2,23]),t(L,[2,24]),t(L,[2,25]),{30:45,31:[1,46],59:[1,47],60:[1,48]},t(L,[2,28]),{34:[1,49]},{36:[1,50]},t(L,[2,31]),{13:51,24:d,57:k},{42:[1,52],44:[1,53]},{46:[1,54]},{49:[1,55]},t(A,[2,44],{58:[1,56]}),t(A,[2,45],{58:[1,57]}),t(L,[2,38]),t(L,[2,39]),t(L,[2,40]),t(L,[2,41]),t(L,[2,6]),t(L,[2,13]),{13:58,24:d,57:k},t(L,[2,17]),t(I,i,{7:59}),{24:[1,60]},{24:[1,61]},{23:[1,62]},{24:[2,48]},{24:[2,49]},t(L,[2,29]),t(L,[2,30]),{39:[1,63],40:[1,64]},{43:[1,65]},{43:[1,66]},{47:[1,67]},{50:[1,68]},{24:[1,69]},{24:[1,70]},t(L,[2,14],{14:[1,71]}),{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,72],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,20],{20:[1,73]}),{31:[1,74]},{24:[1,75]},{39:[1,76]},{39:[1,77]},t(L,[2,34]),t(L,[2,35]),t(L,[2,36]),t(L,[2,37]),t(A,[2,46]),t(A,[2,47]),t(L,[2,15]),t(L,[2,19]),t(I,i,{7:78}),t(L,[2,26]),t(L,[2,27]),{5:[1,79]},{5:[1,80]},{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,81],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,32]),t(L,[2,33]),t(L,[2,21])],defaultActions:{5:[2,1],6:[2,2],47:[2,48],48:[2,49]},parseError:o(function(z,$){if($.recoverable)this.trace(z);else{var U=new Error(z);throw U.hash=$,U}},"parseError"),parse:o(function(z){var $=this,U=[0],K=[],ee=[null],Y=[],ce=this.table,Z="",ue=0,Q=0,j=0,ne=2,te=1,he=Y.slice.call(arguments,1),le=Object.create(this.lexer),J={yy:{}};for(var Se in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Se)&&(J.yy[Se]=this.yy[Se]);le.setInput(z,J.yy),J.yy.lexer=le,J.yy.parser=this,typeof le.yylloc>"u"&&(le.yylloc={});var se=le.yylloc;Y.push(se);var ae=le.options&&le.options.ranges;typeof J.yy.parseError=="function"?this.parseError=J.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Oe(W){U.length=U.length-2*W,ee.length=ee.length-W,Y.length=Y.length-W}o(Oe,"popStack");function ye(){var W;return W=K.pop()||le.lex()||te,typeof W!="number"&&(W instanceof Array&&(K=W,W=K.pop()),W=$.symbols_[W]||W),W}o(ye,"lex");for(var Be,He,ze,Le,Ie,xe,q={},de,ie,oe,V;;){if(ze=U[U.length-1],this.defaultActions[ze]?Le=this.defaultActions[ze]:((Be===null||typeof Be>"u")&&(Be=ye()),Le=ce[ze]&&ce[ze][Be]),typeof Le>"u"||!Le.length||!Le[0]){var Te="";V=[];for(de in ce[ze])this.terminals_[de]&&de>ne&&V.push("'"+this.terminals_[de]+"'");le.showPosition?Te="Parse error on line "+(ue+1)+`: +`+le.showPosition()+` +Expecting `+V.join(", ")+", got '"+(this.terminals_[Be]||Be)+"'":Te="Parse error on line "+(ue+1)+": Unexpected "+(Be==te?"end of input":"'"+(this.terminals_[Be]||Be)+"'"),this.parseError(Te,{text:le.match,token:this.terminals_[Be]||Be,line:le.yylineno,loc:se,expected:V})}if(Le[0]instanceof Array&&Le.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ze+", token: "+Be);switch(Le[0]){case 1:U.push(Be),ee.push(le.yytext),Y.push(le.yylloc),U.push(Le[1]),Be=null,He?(Be=He,He=null):(Q=le.yyleng,Z=le.yytext,ue=le.yylineno,se=le.yylloc,j>0&&j--);break;case 2:if(ie=this.productions_[Le[1]][1],q.$=ee[ee.length-ie],q._$={first_line:Y[Y.length-(ie||1)].first_line,last_line:Y[Y.length-1].last_line,first_column:Y[Y.length-(ie||1)].first_column,last_column:Y[Y.length-1].last_column},ae&&(q._$.range=[Y[Y.length-(ie||1)].range[0],Y[Y.length-1].range[1]]),xe=this.performAction.apply(q,[Z,Q,ue,J.yy,Le[1],ee,Y].concat(he)),typeof xe<"u")return xe;ie&&(U=U.slice(0,-1*ie*2),ee=ee.slice(0,-1*ie),Y=Y.slice(0,-1*ie)),U.push(this.productions_[Le[1]][0]),ee.push(q.$),Y.push(q._$),oe=ce[U[U.length-2]][U[U.length-1]],U.push(oe);break;case 3:return!0}}return!0},"parse")},P=function(){var F={EOF:1,parseError:o(function($,U){if(this.yy.parser)this.yy.parser.parseError($,U);else throw new Error($)},"parseError"),setInput:o(function(z,$){return this.yy=$||this.yy||{},this._input=z,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var z=this._input[0];this.yytext+=z,this.yyleng++,this.offset++,this.match+=z,this.matched+=z;var $=z.match(/(?:\r\n?|\n).*/g);return $?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),z},"input"),unput:o(function(z){var $=z.length,U=z.split(/(?:\r\n?|\n)/g);this._input=z+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-$),this.offset-=$;var K=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),U.length-1&&(this.yylineno-=U.length-1);var ee=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:U?(U.length===K.length?this.yylloc.first_column:0)+K[K.length-U.length].length-U[0].length:this.yylloc.first_column-$},this.options.ranges&&(this.yylloc.range=[ee[0],ee[0]+this.yyleng-$]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(z){this.unput(this.match.slice(z))},"less"),pastInput:o(function(){var z=this.matched.substr(0,this.matched.length-this.match.length);return(z.length>20?"...":"")+z.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var z=this.match;return z.length<20&&(z+=this._input.substr(0,20-z.length)),(z.substr(0,20)+(z.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var z=this.pastInput(),$=new Array(z.length+1).join("-");return z+this.upcomingInput()+` +`+$+"^"},"showPosition"),test_match:o(function(z,$){var U,K,ee;if(this.options.backtrack_lexer&&(ee={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(ee.yylloc.range=this.yylloc.range.slice(0))),K=z[0].match(/(?:\r\n?|\n).*/g),K&&(this.yylineno+=K.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:K?K[K.length-1].length-K[K.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+z[0].length},this.yytext+=z[0],this.match+=z[0],this.matches=z,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(z[0].length),this.matched+=z[0],U=this.performAction.call(this,this.yy,this,$,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),U)return U;if(this._backtrack){for(var Y in ee)this[Y]=ee[Y];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var z,$,U,K;this._more||(this.yytext="",this.match="");for(var ee=this._currentRules(),Y=0;Y$[0].length)){if($=U,K=Y,this.options.backtrack_lexer){if(z=this.test_match(U,ee[Y]),z!==!1)return z;if(this._backtrack){$=!1;continue}else return!1}else if(!this.options.flex)break}return $?(z=this.test_match($,ee[K]),z!==!1?z:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var $=this.next();return $||this.lex()},"lex"),begin:o(function($){this.conditionStack.push($)},"begin"),popState:o(function(){var $=this.conditionStack.length-1;return $>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function($){return $=this.conditionStack.length-1-Math.abs($||0),$>=0?this.conditionStack[$]:"INITIAL"},"topState"),pushState:o(function($){this.begin($)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function($,U,K,ee){var Y=ee;switch(K){case 0:return 38;case 1:return 40;case 2:return 39;case 3:return 44;case 4:return 51;case 5:return 52;case 6:return 53;case 7:return 54;case 8:break;case 9:break;case 10:return 5;case 11:break;case 12:break;case 13:break;case 14:break;case 15:return this.pushState("SCALE"),17;break;case 16:return 18;case 17:this.popState();break;case 18:return this.begin("acc_title"),33;break;case 19:return this.popState(),"acc_title_value";break;case 20:return this.begin("acc_descr"),35;break;case 21:return this.popState(),"acc_descr_value";break;case 22:this.begin("acc_descr_multiline");break;case 23:this.popState();break;case 24:return"acc_descr_multiline_value";case 25:return this.pushState("CLASSDEF"),41;break;case 26:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 27:return this.popState(),this.pushState("CLASSDEFID"),42;break;case 28:return this.popState(),43;break;case 29:return this.pushState("CLASS"),48;break;case 30:return this.popState(),this.pushState("CLASS_STYLE"),49;break;case 31:return this.popState(),50;break;case 32:return this.pushState("STYLE"),45;break;case 33:return this.popState(),this.pushState("STYLEDEF_STYLES"),46;break;case 34:return this.popState(),47;break;case 35:return this.pushState("SCALE"),17;break;case 36:return 18;case 37:this.popState();break;case 38:this.pushState("STATE");break;case 39:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),25;break;case 40:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),26;break;case 41:return this.popState(),U.yytext=U.yytext.slice(0,-10).trim(),27;break;case 42:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),25;break;case 43:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),26;break;case 44:return this.popState(),U.yytext=U.yytext.slice(0,-10).trim(),27;break;case 45:return 51;case 46:return 52;case 47:return 53;case 48:return 54;case 49:this.pushState("STATE_STRING");break;case 50:return this.pushState("STATE_ID"),"AS";break;case 51:return this.popState(),"ID";break;case 52:this.popState();break;case 53:return"STATE_DESCR";case 54:return 19;case 55:this.popState();break;case 56:return this.popState(),this.pushState("struct"),20;break;case 57:break;case 58:return this.popState(),21;break;case 59:break;case 60:return this.begin("NOTE"),29;break;case 61:return this.popState(),this.pushState("NOTE_ID"),59;break;case 62:return this.popState(),this.pushState("NOTE_ID"),60;break;case 63:this.popState(),this.pushState("FLOATING_NOTE");break;case 64:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";break;case 65:break;case 66:return"NOTE_TEXT";case 67:return this.popState(),"ID";break;case 68:return this.popState(),this.pushState("NOTE_TEXT"),24;break;case 69:return this.popState(),U.yytext=U.yytext.substr(2).trim(),31;break;case 70:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),31;break;case 71:return 6;case 72:return 6;case 73:return 16;case 74:return 57;case 75:return 24;case 76:return U.yytext=U.yytext.trim(),14;break;case 77:return 15;case 78:return 28;case 79:return 58;case 80:return 5;case 81:return"INVALID"}},"anonymous"),rules:[/^(?:click\b)/i,/^(?:href\b)/i,/^(?:"[^"]*")/i,/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:style\s+)/i,/^(?:[\w,]+\s+)/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[12,13],inclusive:!1},struct:{rules:[12,13,25,29,32,38,45,46,47,48,57,58,59,60,74,75,76,77,78],inclusive:!1},FLOATING_NOTE_ID:{rules:[67],inclusive:!1},FLOATING_NOTE:{rules:[64,65,66],inclusive:!1},NOTE_TEXT:{rules:[69,70],inclusive:!1},NOTE_ID:{rules:[68],inclusive:!1},NOTE:{rules:[61,62,63],inclusive:!1},STYLEDEF_STYLEOPTS:{rules:[],inclusive:!1},STYLEDEF_STYLES:{rules:[34],inclusive:!1},STYLE_IDS:{rules:[],inclusive:!1},STYLE:{rules:[33],inclusive:!1},CLASS_STYLE:{rules:[31],inclusive:!1},CLASS:{rules:[30],inclusive:!1},CLASSDEFID:{rules:[28],inclusive:!1},CLASSDEF:{rules:[26,27],inclusive:!1},acc_descr_multiline:{rules:[23,24],inclusive:!1},acc_descr:{rules:[21],inclusive:!1},acc_title:{rules:[19],inclusive:!1},SCALE:{rules:[16,17,36,37],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[51],inclusive:!1},STATE_STRING:{rules:[52,53],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[12,13,39,40,41,42,43,44,49,50,54,55,56],inclusive:!1},ID:{rules:[12,13],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,18,20,22,25,29,32,35,38,56,60,71,72,73,74,75,76,77,79,80,81],inclusive:!0}}};return F}();M.lexer=P;function B(){this.yy={}}return o(B,"Parser"),B.prototype=M,M.Parser=B,new B}();SP.parser=SP;JS=SP});var spe,e6,AP,Cf,Gp,Ob,ope,lpe,cpe,Vp,t6,_P,DP,LP,RP,NP,r6,n6,upe,hpe,MP,IP,fpe,dpe,B1,OHe,ppe,OP,PHe,BHe,mpe,gpe,FHe,ype,$He,vpe,PP,BP,xpe,i6,bpe,FP,a6=N(()=>{"use strict";spe="TB",e6="TB",AP="dir",Cf="state",Gp="root",Ob="relation",ope="classDef",lpe="style",cpe="applyClass",Vp="default",t6="divider",_P="fill:none",DP="fill: #333",LP="c",RP="text",NP="normal",r6="rect",n6="rectWithTitle",upe="stateStart",hpe="stateEnd",MP="divider",IP="roundedWithTitle",fpe="note",dpe="noteGroup",B1="statediagram",OHe="state",ppe=`${B1}-${OHe}`,OP="transition",PHe="note",BHe="note-edge",mpe=`${OP} ${BHe}`,gpe=`${B1}-${PHe}`,FHe="cluster",ype=`${B1}-${FHe}`,$He="cluster-alt",vpe=`${B1}-${$He}`,PP="parent",BP="note",xpe="state",i6="----",bpe=`${i6}${BP}`,FP=`${i6}${PP}`});function $P(t="",e=0,r="",n=i6){let i=r!==null&&r.length>0?`${n}${r}`:"";return`${xpe}-${t}${i}-${e}`}function s6(t,e,r){if(!e.id||e.id===""||e.id==="")return;e.cssClasses&&(Array.isArray(e.cssCompiledStyles)||(e.cssCompiledStyles=[]),e.cssClasses.split(" ").forEach(i=>{let a=r.get(i);a&&(e.cssCompiledStyles=[...e.cssCompiledStyles??[],...a.styles])}));let n=t.find(i=>i.id===e.id);n?Object.assign(n,e):t.push(e)}function GHe(t){return t?.classes?.join(" ")??""}function VHe(t){return t?.styles??[]}var o6,Af,zHe,Tpe,F1,wpe,kpe=N(()=>{"use strict";Gt();yt();pr();a6();o6=new Map,Af=0;o($P,"stateDomId");zHe=o((t,e,r,n,i,a,s,l)=>{X.trace("items",e),e.forEach(u=>{switch(u.stmt){case Cf:F1(t,u,r,n,i,a,s,l);break;case Vp:F1(t,u,r,n,i,a,s,l);break;case Ob:{F1(t,u.state1,r,n,i,a,s,l),F1(t,u.state2,r,n,i,a,s,l);let h={id:"edge"+Af,start:u.state1.id,end:u.state2.id,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:_P,labelStyle:"",label:Ze.sanitizeText(u.description??"",me()),arrowheadStyle:DP,labelpos:LP,labelType:RP,thickness:NP,classes:OP,look:s};i.push(h),Af++}break}})},"setupDoc"),Tpe=o((t,e=e6)=>{let r=e;if(t.doc)for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir");o(s6,"insertOrUpdateNode");o(GHe,"getClassesFromDbInfo");o(VHe,"getStylesFromDbInfo");F1=o((t,e,r,n,i,a,s,l)=>{let u=e.id,h=r.get(u),f=GHe(h),d=VHe(h),p=me();if(X.info("dataFetcher parsedItem",e,h,d),u!=="root"){let m=r6;e.start===!0?m=upe:e.start===!1&&(m=hpe),e.type!==Vp&&(m=e.type),o6.get(u)||o6.set(u,{id:u,shape:m,description:Ze.sanitizeText(u,p),cssClasses:`${f} ${ppe}`,cssStyles:d});let g=o6.get(u);e.description&&(Array.isArray(g.description)?(g.shape=n6,g.description.push(e.description)):g.description?.length&&g.description.length>0?(g.shape=n6,g.description===u?g.description=[e.description]:g.description=[g.description,e.description]):(g.shape=r6,g.description=e.description),g.description=Ze.sanitizeTextOrArray(g.description,p)),g.description?.length===1&&g.shape===n6&&(g.type==="group"?g.shape=IP:g.shape=r6),!g.type&&e.doc&&(X.info("Setting cluster for XCX",u,Tpe(e)),g.type="group",g.isGroup=!0,g.dir=Tpe(e),g.shape=e.type===t6?MP:IP,g.cssClasses=`${g.cssClasses} ${ype} ${a?vpe:""}`);let y={labelStyle:"",shape:g.shape,label:g.description,cssClasses:g.cssClasses,cssCompiledStyles:[],cssStyles:g.cssStyles,id:u,dir:g.dir,domId:$P(u,Af),type:g.type,isGroup:g.type==="group",padding:8,rx:10,ry:10,look:s};if(y.shape===MP&&(y.label=""),t&&t.id!=="root"&&(X.trace("Setting node ",u," to be child of its parent ",t.id),y.parentId=t.id),y.centerLabel=!0,e.note){let v={labelStyle:"",shape:fpe,label:e.note.text,cssClasses:gpe,cssStyles:[],cssCompiledStyles:[],id:u+bpe+"-"+Af,domId:$P(u,Af,BP),type:g.type,isGroup:g.type==="group",padding:p.flowchart?.padding,look:s,position:e.note.position},x=u+FP,b={labelStyle:"",shape:dpe,label:e.note.text,cssClasses:g.cssClasses,cssStyles:[],id:u+FP,domId:$P(u,Af,PP),type:"group",isGroup:!0,padding:16,look:s,position:e.note.position};Af++,b.id=x,v.parentId=x,s6(n,b,l),s6(n,v,l),s6(n,y,l);let T=u,S=v.id;e.note.position==="left of"&&(T=v.id,S=u),i.push({id:T+"-"+S,start:T,end:S,arrowhead:"none",arrowTypeEnd:"",style:_P,labelStyle:"",classes:mpe,arrowheadStyle:DP,labelpos:LP,labelType:RP,thickness:NP,look:s})}else s6(n,y,l)}e.doc&&(X.trace("Adding nodes children "),zHe(e,e.doc,r,n,i,!a,s,l))},"dataFetcher"),wpe=o(()=>{o6.clear(),Af=0},"reset")});var zP,UHe,HHe,Epe,GP=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();a6();zP=o((t,e=e6)=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),UHe=o(function(t,e){return e.db.getClasses()},"getClasses"),HHe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing state diagram (v2)",e);let{securityLevel:i,state:a,layout:s}=me();n.db.extract(n.db.getRootDocV2());let l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=s,l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["barb"],l.diagramId=e,await Rc(l,u);let h=8;try{(typeof n.db.getLinks=="function"?n.db.getLinks():new Map).forEach((d,p)=>{let m=typeof p=="string"?p:typeof p?.id=="string"?p.id:"";if(!m){X.warn("\u26A0\uFE0F Invalid or missing stateId from key:",JSON.stringify(p));return}let g=u.node()?.querySelectorAll("g"),y;if(g?.forEach(T=>{T.textContent?.trim()===m&&(y=T)}),!y){X.warn("\u26A0\uFE0F Could not find node matching text:",m);return}let v=y.parentNode;if(!v){X.warn("\u26A0\uFE0F Node has no parent, cannot wrap:",m);return}let x=document.createElementNS("http://www.w3.org/2000/svg","a"),b=d.url.replace(/^"+|"+$/g,"");if(x.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",b),x.setAttribute("target","_blank"),d.tooltip){let T=d.tooltip.replace(/^"+|"+$/g,"");x.setAttribute("title",T)}v.replaceChild(x,y),x.appendChild(y),X.info("\u{1F517} Wrapped node in
    tag for:",m,d.url)})}catch(f){X.error("\u274C Error injecting clickable links:",f)}Vt.insertTitle(u,"statediagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,B1,a?.useMaxWidth??!0)},"draw"),Epe={getClasses:UHe,draw:HHe,getDir:zP}});var bs,Spe,Cpe,l6,tl,c6=N(()=>{"use strict";Gt();yt();er();pr();ci();kpe();GP();a6();bs={START_NODE:"[*]",START_TYPE:"start",END_NODE:"[*]",END_TYPE:"end",COLOR_KEYWORD:"color",FILL_KEYWORD:"fill",BG_FILL:"bgFill",STYLECLASS_SEP:","},Spe=o(()=>new Map,"newClassesList"),Cpe=o(()=>({relations:[],states:new Map,documents:{}}),"newDoc"),l6=o(t=>JSON.parse(JSON.stringify(t)),"clone"),tl=class{constructor(e){this.version=e;this.nodes=[];this.edges=[];this.rootDoc=[];this.classes=Spe();this.documents={root:Cpe()};this.currentDocument=this.documents.root;this.startEndCount=0;this.dividerCnt=0;this.links=new Map;this.getAccTitle=Dr;this.setAccTitle=Ar;this.getAccDescription=Rr;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.clear(),this.setRootDoc=this.setRootDoc.bind(this),this.getDividerId=this.getDividerId.bind(this),this.setDirection=this.setDirection.bind(this),this.trimColon=this.trimColon.bind(this)}static{o(this,"StateDB")}static{this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3}}extract(e){this.clear(!0);for(let i of Array.isArray(e)?e:e.doc)switch(i.stmt){case Cf:this.addState(i.id.trim(),i.type,i.doc,i.description,i.note);break;case Ob:this.addRelation(i.state1,i.state2,i.description);break;case ope:this.addStyleClass(i.id.trim(),i.classes);break;case lpe:this.handleStyleDef(i);break;case cpe:this.setCssClass(i.id.trim(),i.styleClass);break;case"click":this.addLink(i.id,i.url,i.tooltip);break}let r=this.getStates(),n=me();wpe(),F1(void 0,this.getRootDocV2(),r,this.nodes,this.edges,!0,n.look,this.classes);for(let i of this.nodes)if(Array.isArray(i.label)){if(i.description=i.label.slice(1),i.isGroup&&i.description.length>0)throw new Error(`Group nodes can only have label. Remove the additional description for node [${i.id}]`);i.label=i.label[0]}}handleStyleDef(e){let r=e.id.trim().split(","),n=e.styleClass.split(",");for(let i of r){let a=this.getState(i);if(!a){let s=i.trim();this.addState(s),a=this.getState(s)}a&&(a.styles=n.map(s=>s.replace(/;/g,"")?.trim()))}}setRootDoc(e){X.info("Setting root doc",e),this.rootDoc=e,this.version===1?this.extract(e):this.extract(this.getRootDocV2())}docTranslator(e,r,n){if(r.stmt===Ob){this.docTranslator(e,r.state1,!0),this.docTranslator(e,r.state2,!1);return}if(r.stmt===Cf&&(r.id===bs.START_NODE?(r.id=e.id+(n?"_start":"_end"),r.start=n):r.id=r.id.trim()),r.stmt!==Gp&&r.stmt!==Cf||!r.doc)return;let i=[],a=[];for(let s of r.doc)if(s.type===t6){let l=l6(s);l.doc=l6(a),i.push(l),a=[]}else a.push(s);if(i.length>0&&a.length>0){let s={stmt:Cf,id:L9(),type:"divider",doc:l6(a)};i.push(l6(s)),r.doc=i}r.doc.forEach(s=>this.docTranslator(r,s,!0))}getRootDocV2(){return this.docTranslator({id:Gp,stmt:Gp},{id:Gp,stmt:Gp,doc:this.rootDoc},!0),{id:Gp,doc:this.rootDoc}}addState(e,r=Vp,n=void 0,i=void 0,a=void 0,s=void 0,l=void 0,u=void 0){let h=e?.trim();if(!this.currentDocument.states.has(h))X.info("Adding state ",h,i),this.currentDocument.states.set(h,{stmt:Cf,id:h,descriptions:[],type:r,doc:n,note:a,classes:[],styles:[],textStyles:[]});else{let f=this.currentDocument.states.get(h);if(!f)throw new Error(`State not found: ${h}`);f.doc||(f.doc=n),f.type||(f.type=r)}if(i&&(X.info("Setting state description",h,i),(Array.isArray(i)?i:[i]).forEach(d=>this.addDescription(h,d.trim()))),a){let f=this.currentDocument.states.get(h);if(!f)throw new Error(`State not found: ${h}`);f.note=a,f.note.text=Ze.sanitizeText(f.note.text,me())}s&&(X.info("Setting state classes",h,s),(Array.isArray(s)?s:[s]).forEach(d=>this.setCssClass(h,d.trim()))),l&&(X.info("Setting state styles",h,l),(Array.isArray(l)?l:[l]).forEach(d=>this.setStyle(h,d.trim()))),u&&(X.info("Setting state styles",h,l),(Array.isArray(u)?u:[u]).forEach(d=>this.setTextStyle(h,d.trim())))}clear(e){this.nodes=[],this.edges=[],this.documents={root:Cpe()},this.currentDocument=this.documents.root,this.startEndCount=0,this.classes=Spe(),e||(this.links=new Map,kr())}getState(e){return this.currentDocument.states.get(e)}getStates(){return this.currentDocument.states}logDocuments(){X.info("Documents = ",this.documents)}getRelations(){return this.currentDocument.relations}addLink(e,r,n){this.links.set(e,{url:r,tooltip:n}),X.warn("Adding link",e,r,n)}getLinks(){return this.links}startIdIfNeeded(e=""){return e===bs.START_NODE?(this.startEndCount++,`${bs.START_TYPE}${this.startEndCount}`):e}startTypeIfNeeded(e="",r=Vp){return e===bs.START_NODE?bs.START_TYPE:r}endIdIfNeeded(e=""){return e===bs.END_NODE?(this.startEndCount++,`${bs.END_TYPE}${this.startEndCount}`):e}endTypeIfNeeded(e="",r=Vp){return e===bs.END_NODE?bs.END_TYPE:r}addRelationObjs(e,r,n=""){let i=this.startIdIfNeeded(e.id.trim()),a=this.startTypeIfNeeded(e.id.trim(),e.type),s=this.startIdIfNeeded(r.id.trim()),l=this.startTypeIfNeeded(r.id.trim(),r.type);this.addState(i,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),this.addState(s,l,r.doc,r.description,r.note,r.classes,r.styles,r.textStyles),this.currentDocument.relations.push({id1:i,id2:s,relationTitle:Ze.sanitizeText(n,me())})}addRelation(e,r,n){if(typeof e=="object"&&typeof r=="object")this.addRelationObjs(e,r,n);else if(typeof e=="string"&&typeof r=="string"){let i=this.startIdIfNeeded(e.trim()),a=this.startTypeIfNeeded(e),s=this.endIdIfNeeded(r.trim()),l=this.endTypeIfNeeded(r);this.addState(i,a),this.addState(s,l),this.currentDocument.relations.push({id1:i,id2:s,relationTitle:n?Ze.sanitizeText(n,me()):void 0})}}addDescription(e,r){let n=this.currentDocument.states.get(e),i=r.startsWith(":")?r.replace(":","").trim():r;n?.descriptions?.push(Ze.sanitizeText(i,me()))}cleanupLabel(e){return e.startsWith(":")?e.slice(2).trim():e.trim()}getDividerId(){return this.dividerCnt++,`divider-id-${this.dividerCnt}`}addStyleClass(e,r=""){this.classes.has(e)||this.classes.set(e,{id:e,styles:[],textStyles:[]});let n=this.classes.get(e);r&&n&&r.split(bs.STYLECLASS_SEP).forEach(i=>{let a=i.replace(/([^;]*);/,"$1").trim();if(RegExp(bs.COLOR_KEYWORD).exec(i)){let l=a.replace(bs.FILL_KEYWORD,bs.BG_FILL).replace(bs.COLOR_KEYWORD,bs.FILL_KEYWORD);n.textStyles.push(l)}n.styles.push(a)})}getClasses(){return this.classes}setCssClass(e,r){e.split(",").forEach(n=>{let i=this.getState(n);if(!i){let a=n.trim();this.addState(a),i=this.getState(a)}i?.classes?.push(r)})}setStyle(e,r){this.getState(e)?.styles?.push(r)}setTextStyle(e,r){this.getState(e)?.textStyles?.push(r)}getDirectionStatement(){return this.rootDoc.find(e=>e.stmt===AP)}getDirection(){return this.getDirectionStatement()?.value??spe}setDirection(e){let r=this.getDirectionStatement();r?r.value=e:this.rootDoc.unshift({stmt:AP,value:e})}trimColon(e){return e.startsWith(":")?e.slice(1).trim():e.trim()}getData(){let e=me();return{nodes:this.nodes,edges:this.edges,other:{},config:e,direction:zP(this.getRootDocV2())}}getConfig(){return me().state}}});var WHe,u6,VP=N(()=>{"use strict";WHe=o(t=>` +defs #statediagram-barbEnd { + fill: ${t.transitionColor}; + stroke: ${t.transitionColor}; + } +g.stateGroup text { + fill: ${t.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${t.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${t.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; +} + +g.stateGroup line { + stroke: ${t.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${t.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${t.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${t.noteBorderColor}; + fill: ${t.noteBkgColor}; + + text { + fill: ${t.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${t.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${t.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel { + background-color: ${t.edgeLabelBackground}; + p { + background-color: ${t.edgeLabelBackground}; + } + rect { + opacity: 0.5; + background-color: ${t.edgeLabelBackground}; + fill: ${t.edgeLabelBackground}; + } + text-align: center; +} +.edgeLabel .label text { + fill: ${t.transitionLabelColor||t.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${t.transitionLabelColor||t.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${t.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${t.specialStateColor}; + stroke: ${t.specialStateColor}; +} + +.node .fork-join { + fill: ${t.specialStateColor}; + stroke: ${t.specialStateColor}; +} + +.node circle.state-end { + fill: ${t.innerEndBackground}; + stroke: ${t.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${t.compositeBackground||t.background}; + // stroke: ${t.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${t.stateBkg||t.mainBkg}; + stroke: ${t.stateBorder||t.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${t.mainBkg}; + stroke: ${t.stateBorder||t.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${t.lineColor}; +} + +.statediagram-cluster rect { + fill: ${t.compositeTitleBackground}; + stroke: ${t.stateBorder||t.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${t.stateLabelColor}; + // line-height: 1; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${t.stateBorder||t.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${t.compositeBackground||t.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${t.altBackground?t.altBackground:"#efefef"}; +} + +.statediagram-cluster .inner { + rx:0; + ry:0; +} + +.statediagram-state rect.basic { + rx: 5px; + ry: 5px; +} +.statediagram-state rect.divider { + stroke-dasharray: 10,10; + fill: ${t.altBackground?t.altBackground:"#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${t.noteBkgColor}; + stroke: ${t.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${t.noteBkgColor}; + stroke: ${t.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${t.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${t.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${t.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${t.lineColor}; + stroke: ${t.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.textColor}; +} +`,"getStyles"),u6=WHe});var qHe,YHe,XHe,jHe,_pe,KHe,QHe,ZHe,JHe,UP,Ape,Dpe,Lpe=N(()=>{"use strict";fr();c6();er();pr();Gt();yt();qHe=o(t=>t.append("circle").attr("class","start-state").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit).attr("cy",me().state.padding+me().state.sizeUnit),"drawStartState"),YHe=o(t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",me().state.textHeight).attr("class","divider").attr("x2",me().state.textHeight*2).attr("y1",0).attr("y2",0),"drawDivider"),XHe=o((t,e)=>{let r=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+2*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),n=r.node().getBBox();return t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",n.width+2*me().state.padding).attr("height",n.height+2*me().state.padding).attr("rx",me().state.radius),r},"drawSimpleState"),jHe=o((t,e)=>{let r=o(function(p,m,g){let y=p.append("tspan").attr("x",2*me().state.padding).text(m);g||y.attr("dy",me().state.textHeight)},"addTspan"),i=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+1.3*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),a=i.height,s=t.append("text").attr("x",me().state.padding).attr("y",a+me().state.padding*.4+me().state.dividerMargin+me().state.textHeight).attr("class","state-description"),l=!0,u=!0;e.descriptions.forEach(function(p){l||(r(s,p,u),u=!1),l=!1});let h=t.append("line").attr("x1",me().state.padding).attr("y1",me().state.padding+a+me().state.dividerMargin/2).attr("y2",me().state.padding+a+me().state.dividerMargin/2).attr("class","descr-divider"),f=s.node().getBBox(),d=Math.max(f.width,i.width);return h.attr("x2",d+3*me().state.padding),t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",d+2*me().state.padding).attr("height",f.height+a+2*me().state.padding).attr("rx",me().state.radius),t},"drawDescrState"),_pe=o((t,e,r)=>{let n=me().state.padding,i=2*me().state.padding,a=t.node().getBBox(),s=a.width,l=a.x,u=t.append("text").attr("x",0).attr("y",me().state.titleShift).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),f=u.node().getBBox().width+i,d=Math.max(f,s);d===s&&(d=d+i);let p,m=t.node().getBBox();e.doc,p=l-n,f>s&&(p=(s-d)/2+n),Math.abs(l-m.x)s&&(p=l-(f-s)/2);let g=1-me().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",g).attr("class",r?"alt-composit":"composit").attr("width",d).attr("height",m.height+me().state.textHeight+me().state.titleShift+1).attr("rx","0"),u.attr("x",p+n),f<=s&&u.attr("x",l+(d-i)/2-f/2+n),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",me().state.textHeight*3).attr("rx",me().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",m.height+3+2*me().state.textHeight).attr("rx",me().state.radius),t},"addTitleAndBox"),KHe=o(t=>(t.append("circle").attr("class","end-state-outer").attr("r",me().state.sizeUnit+me().state.miniPadding).attr("cx",me().state.padding+me().state.sizeUnit+me().state.miniPadding).attr("cy",me().state.padding+me().state.sizeUnit+me().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit+2).attr("cy",me().state.padding+me().state.sizeUnit+2)),"drawEndState"),QHe=o((t,e)=>{let r=me().state.forkWidth,n=me().state.forkHeight;if(e.parentId){let i=r;r=n,n=i}return t.append("rect").style("stroke","black").style("fill","black").attr("width",r).attr("height",n).attr("x",me().state.padding).attr("y",me().state.padding)},"drawForkJoinState"),ZHe=o((t,e,r,n)=>{let i=0,a=n.append("text");a.style("text-anchor","start"),a.attr("class","noteText");let s=t.replace(/\r\n/g,"
    ");s=s.replace(/\n/g,"
    ");let l=s.split(Ze.lineBreakRegex),u=1.25*me().state.noteMargin;for(let h of l){let f=h.trim();if(f.length>0){let d=a.append("tspan");if(d.text(f),u===0){let p=d.node().getBBox();u+=p.height}i+=u,d.attr("x",e+me().state.noteMargin),d.attr("y",r+i+1.25*me().state.noteMargin)}}return{textWidth:a.node().getBBox().width,textHeight:i}},"_drawLongText"),JHe=o((t,e)=>{e.attr("class","state-note");let r=e.append("rect").attr("x",0).attr("y",me().state.padding),n=e.append("g"),{textWidth:i,textHeight:a}=ZHe(t,0,0,n);return r.attr("height",a+2*me().state.noteMargin),r.attr("width",i+me().state.noteMargin*2),r},"drawNote"),UP=o(function(t,e){let r=e.id,n={id:r,label:e.id,width:0,height:0},i=t.append("g").attr("id",r).attr("class","stateGroup");e.type==="start"&&qHe(i),e.type==="end"&&KHe(i),(e.type==="fork"||e.type==="join")&&QHe(i,e),e.type==="note"&&JHe(e.note.text,i),e.type==="divider"&&YHe(i),e.type==="default"&&e.descriptions.length===0&&XHe(i,e),e.type==="default"&&e.descriptions.length>0&&jHe(i,e);let a=i.node().getBBox();return n.width=a.width+2*me().state.padding,n.height=a.height+2*me().state.padding,n},"drawState"),Ape=0,Dpe=o(function(t,e,r){let n=o(function(u){switch(u){case tl.relationType.AGGREGATION:return"aggregation";case tl.relationType.EXTENSION:return"extension";case tl.relationType.COMPOSITION:return"composition";case tl.relationType.DEPENDENCY:return"dependency"}},"getRelationType");e.points=e.points.filter(u=>!Number.isNaN(u.y));let i=e.points,a=Cl().x(function(u){return u.x}).y(function(u){return u.y}).curve(No),s=t.append("path").attr("d",a(i)).attr("id","edge"+Ape).attr("class","transition"),l="";if(me().state.arrowMarkerAbsolute&&(l=mu(!0)),s.attr("marker-end","url("+l+"#"+n(tl.relationType.DEPENDENCY)+"End)"),r.title!==void 0){let u=t.append("g").attr("class","stateLabel"),{x:h,y:f}=Vt.calcLabelPosition(e.points),d=Ze.getRows(r.title),p=0,m=[],g=0,y=0;for(let b=0;b<=d.length;b++){let T=u.append("text").attr("text-anchor","middle").text(d[b]).attr("x",h).attr("y",f+p),S=T.node().getBBox();g=Math.max(g,S.width),y=Math.min(y,S.x),X.info(S.x,h,f+p),p===0&&(p=T.node().getBBox().height,X.info("Title height",p,f)),m.push(T)}let v=p*d.length;if(d.length>1){let b=(d.length-1)*p*.5;m.forEach((T,S)=>T.attr("y",f+S*p-b)),v=p*d.length}let x=u.node().getBBox();u.insert("rect",":first-child").attr("class","box").attr("x",h-g/2-me().state.padding/2).attr("y",f-v/2-me().state.padding/2-3.5).attr("width",g+me().state.padding).attr("height",v+me().state.padding),X.info(x)}Ape++},"drawEdge")});var go,HP,eWe,tWe,rWe,nWe,Rpe,Npe,Mpe=N(()=>{"use strict";fr();JR();Wo();yt();pr();Lpe();Gt();xi();HP={},eWe=o(function(){},"setConf"),tWe=o(function(t){t.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),rWe=o(function(t,e,r,n){go=me().state;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=i==="sandbox"?a.nodes()[0].contentDocument:document;X.debug("Rendering diagram "+t);let u=s.select(`[id='${e}']`);tWe(u);let h=n.db.getRootDoc();Rpe(h,u,void 0,!1,s,l,n);let f=go.padding,d=u.node().getBBox(),p=d.width+f*2,m=d.height+f*2,g=p*1.75;fn(u,m,g,go.useMaxWidth),u.attr("viewBox",`${d.x-go.padding} ${d.y-go.padding} `+p+" "+m)},"draw"),nWe=o(t=>t?t.length*go.fontSizeFactor:1,"getLabelWidth"),Rpe=o((t,e,r,n,i,a,s)=>{let l=new sn({compound:!0,multigraph:!0}),u,h=!0;for(u=0;u{let w=S.parentElement,E=0,_=0;w&&(w.parentElement&&(E=w.parentElement.getBBox().width),_=parseInt(w.getAttribute("data-x-shift"),10),Number.isNaN(_)&&(_=0)),S.setAttribute("x1",0-_+8),S.setAttribute("x2",E-_-8)})):X.debug("No Node "+b+": "+JSON.stringify(l.node(b)))});let v=y.getBBox();l.edges().forEach(function(b){b!==void 0&&l.edge(b)!==void 0&&(X.debug("Edge "+b.v+" -> "+b.w+": "+JSON.stringify(l.edge(b))),Dpe(e,l.edge(b),l.edge(b).relation))}),v=y.getBBox();let x={id:r||"root",label:r||"root",width:0,height:0};return x.width=v.width+2*go.padding,x.height=v.height+2*go.padding,X.debug("Doc rendered",x,l),x},"renderDoc"),Npe={setConf:eWe,draw:rWe}});var Ipe={};ur(Ipe,{diagram:()=>iWe});var iWe,Ope=N(()=>{"use strict";CP();c6();VP();Mpe();iWe={parser:JS,get db(){return new tl(1)},renderer:Npe,styles:u6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var Fpe={};ur(Fpe,{diagram:()=>lWe});var lWe,$pe=N(()=>{"use strict";CP();c6();VP();GP();lWe={parser:JS,get db(){return new tl(2)},renderer:Epe,styles:u6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var WP,Vpe,Upe=N(()=>{"use strict";WP=function(){var t=o(function(d,p,m,g){for(m=m||{},g=d.length;g--;m[d[g]]=p);return m},"o"),e=[6,8,10,11,12,14,16,17,18],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,14],u={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:o(function(p,m,g,y,v,x,b){var T=x.length-1;switch(v){case 1:return x[T-1];case 2:this.$=[];break;case 3:x[T-1].push(x[T]),this.$=x[T-1];break;case 4:case 5:this.$=x[T];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(x[T].substr(6)),this.$=x[T].substr(6);break;case 9:this.$=x[T].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=x[T].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(x[T].substr(8)),this.$=x[T].substr(8);break;case 13:y.addTask(x[T-1],x[T]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:o(function(p,m){if(m.recoverable)this.trace(p);else{var g=new Error(p);throw g.hash=m,g}},"parseError"),parse:o(function(p){var m=this,g=[0],y=[],v=[null],x=[],b=this.table,T="",S=0,w=0,E=0,_=2,C=1,D=x.slice.call(arguments,1),O=Object.create(this.lexer),R={yy:{}};for(var k in this.yy)Object.prototype.hasOwnProperty.call(this.yy,k)&&(R.yy[k]=this.yy[k]);O.setInput(p,R.yy),R.yy.lexer=O,R.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var L=O.yylloc;x.push(L);var A=O.options&&O.options.ranges;typeof R.yy.parseError=="function"?this.parseError=R.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function I(Q){g.length=g.length-2*Q,v.length=v.length-Q,x.length=x.length-Q}o(I,"popStack");function M(){var Q;return Q=y.pop()||O.lex()||C,typeof Q!="number"&&(Q instanceof Array&&(y=Q,Q=y.pop()),Q=m.symbols_[Q]||Q),Q}o(M,"lex");for(var P,B,F,z,$,U,K={},ee,Y,ce,Z;;){if(F=g[g.length-1],this.defaultActions[F]?z=this.defaultActions[F]:((P===null||typeof P>"u")&&(P=M()),z=b[F]&&b[F][P]),typeof z>"u"||!z.length||!z[0]){var ue="";Z=[];for(ee in b[F])this.terminals_[ee]&&ee>_&&Z.push("'"+this.terminals_[ee]+"'");O.showPosition?ue="Parse error on line "+(S+1)+`: +`+O.showPosition()+` +Expecting `+Z.join(", ")+", got '"+(this.terminals_[P]||P)+"'":ue="Parse error on line "+(S+1)+": Unexpected "+(P==C?"end of input":"'"+(this.terminals_[P]||P)+"'"),this.parseError(ue,{text:O.match,token:this.terminals_[P]||P,line:O.yylineno,loc:L,expected:Z})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+F+", token: "+P);switch(z[0]){case 1:g.push(P),v.push(O.yytext),x.push(O.yylloc),g.push(z[1]),P=null,B?(P=B,B=null):(w=O.yyleng,T=O.yytext,S=O.yylineno,L=O.yylloc,E>0&&E--);break;case 2:if(Y=this.productions_[z[1]][1],K.$=v[v.length-Y],K._$={first_line:x[x.length-(Y||1)].first_line,last_line:x[x.length-1].last_line,first_column:x[x.length-(Y||1)].first_column,last_column:x[x.length-1].last_column},A&&(K._$.range=[x[x.length-(Y||1)].range[0],x[x.length-1].range[1]]),U=this.performAction.apply(K,[T,w,S,R.yy,z[1],v,x].concat(D)),typeof U<"u")return U;Y&&(g=g.slice(0,-1*Y*2),v=v.slice(0,-1*Y),x=x.slice(0,-1*Y)),g.push(this.productions_[z[1]][0]),v.push(K.$),x.push(K._$),ce=b[g[g.length-2]][g[g.length-1]],g.push(ce);break;case 3:return!0}}return!0},"parse")},h=function(){var d={EOF:1,parseError:o(function(m,g){if(this.yy.parser)this.yy.parser.parseError(m,g);else throw new Error(m)},"parseError"),setInput:o(function(p,m){return this.yy=m||this.yy||{},this._input=p,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var p=this._input[0];this.yytext+=p,this.yyleng++,this.offset++,this.match+=p,this.matched+=p;var m=p.match(/(?:\r\n?|\n).*/g);return m?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),p},"input"),unput:o(function(p){var m=p.length,g=p.split(/(?:\r\n?|\n)/g);this._input=p+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-m),this.offset-=m;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var v=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===y.length?this.yylloc.first_column:0)+y[y.length-g.length].length-g[0].length:this.yylloc.first_column-m},this.options.ranges&&(this.yylloc.range=[v[0],v[0]+this.yyleng-m]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(p){this.unput(this.match.slice(p))},"less"),pastInput:o(function(){var p=this.matched.substr(0,this.matched.length-this.match.length);return(p.length>20?"...":"")+p.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var p=this.match;return p.length<20&&(p+=this._input.substr(0,20-p.length)),(p.substr(0,20)+(p.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var p=this.pastInput(),m=new Array(p.length+1).join("-");return p+this.upcomingInput()+` +`+m+"^"},"showPosition"),test_match:o(function(p,m){var g,y,v;if(this.options.backtrack_lexer&&(v={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(v.yylloc.range=this.yylloc.range.slice(0))),y=p[0].match(/(?:\r\n?|\n).*/g),y&&(this.yylineno+=y.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:y?y[y.length-1].length-y[y.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+p[0].length},this.yytext+=p[0],this.match+=p[0],this.matches=p,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(p[0].length),this.matched+=p[0],g=this.performAction.call(this,this.yy,this,m,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),g)return g;if(this._backtrack){for(var x in v)this[x]=v[x];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var p,m,g,y;this._more||(this.yytext="",this.match="");for(var v=this._currentRules(),x=0;xm[0].length)){if(m=g,y=x,this.options.backtrack_lexer){if(p=this.test_match(g,v[x]),p!==!1)return p;if(this._backtrack){m=!1;continue}else return!1}else if(!this.options.flex)break}return m?(p=this.test_match(m,v[y]),p!==!1?p:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var m=this.next();return m||this.lex()},"lex"),begin:o(function(m){this.conditionStack.push(m)},"begin"),popState:o(function(){var m=this.conditionStack.length-1;return m>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(m){return m=this.conditionStack.length-1-Math.abs(m||0),m>=0?this.conditionStack[m]:"INITIAL"},"topState"),pushState:o(function(m){this.begin(m)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(m,g,y,v){var x=v;switch(y){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};return d}();u.lexer=h;function f(){this.yy={}}return o(f,"Parser"),f.prototype=u,u.Parser=f,new f}();WP.parser=WP;Vpe=WP});var $1,qP,Pb,Bb,fWe,dWe,pWe,mWe,gWe,yWe,vWe,Hpe,xWe,YP,Wpe=N(()=>{"use strict";Gt();ci();$1="",qP=[],Pb=[],Bb=[],fWe=o(function(){qP.length=0,Pb.length=0,$1="",Bb.length=0,kr()},"clear"),dWe=o(function(t){$1=t,qP.push(t)},"addSection"),pWe=o(function(){return qP},"getSections"),mWe=o(function(){let t=Hpe(),e=100,r=0;for(;!t&&r{r.people&&t.push(...r.people)}),[...new Set(t)].sort()},"updateActors"),yWe=o(function(t,e){let r=e.substr(1).split(":"),n=0,i=[];r.length===1?(n=Number(r[0]),i=[]):(n=Number(r[0]),i=r[1].split(","));let a=i.map(l=>l.trim()),s={section:$1,type:$1,people:a,task:t,score:n};Bb.push(s)},"addTask"),vWe=o(function(t){let e={section:$1,type:$1,description:t,task:t,classes:[]};Pb.push(e)},"addTaskOrg"),Hpe=o(function(){let t=o(function(r){return Bb[r].processed},"compileTask"),e=!0;for(let[r,n]of Bb.entries())t(r),e=e&&n.processed;return e},"compileTasks"),xWe=o(function(){return gWe()},"getActors"),YP={getConfig:o(()=>me().journey,"getConfig"),clear:fWe,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,addSection:dWe,getSections:pWe,getTasks:mWe,addTask:yWe,addTaskOrg:vWe,getActors:xWe}});var bWe,qpe,Ype=N(()=>{"use strict";Xm();bWe=o(t=>`.label { + font-family: ${t.fontFamily}; + color: ${t.textColor}; + } + .mouth { + stroke: #666; + } + + line { + stroke: ${t.textColor} + } + + .legend { + fill: ${t.textColor}; + font-family: ${t.fontFamily}; + } + + .label text { + fill: #333; + } + .label { + color: ${t.textColor} + } + + .face { + ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"}; + stroke: #999; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${t.arrowheadColor}; + } + + .edgePath .path { + stroke: ${t.lineColor}; + stroke-width: 1.5px; + } + + .flowchart-link { + stroke: ${t.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${t.edgeLabelBackground}; + rect { + opacity: 0.5; + } + text-align: center; + } + + .cluster rect { + } + + .cluster text { + fill: ${t.titleColor}; + } + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${t.fontFamily}; + font-size: 12px; + background: ${t.tertiaryColor}; + border: 1px solid ${t.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .task-type-0, .section-type-0 { + ${t.fillType0?`fill: ${t.fillType0}`:""}; + } + .task-type-1, .section-type-1 { + ${t.fillType0?`fill: ${t.fillType1}`:""}; + } + .task-type-2, .section-type-2 { + ${t.fillType0?`fill: ${t.fillType2}`:""}; + } + .task-type-3, .section-type-3 { + ${t.fillType0?`fill: ${t.fillType3}`:""}; + } + .task-type-4, .section-type-4 { + ${t.fillType0?`fill: ${t.fillType4}`:""}; + } + .task-type-5, .section-type-5 { + ${t.fillType0?`fill: ${t.fillType5}`:""}; + } + .task-type-6, .section-type-6 { + ${t.fillType0?`fill: ${t.fillType6}`:""}; + } + .task-type-7, .section-type-7 { + ${t.fillType0?`fill: ${t.fillType7}`:""}; + } + + .actor-0 { + ${t.actor0?`fill: ${t.actor0}`:""}; + } + .actor-1 { + ${t.actor1?`fill: ${t.actor1}`:""}; + } + .actor-2 { + ${t.actor2?`fill: ${t.actor2}`:""}; + } + .actor-3 { + ${t.actor3?`fill: ${t.actor3}`:""}; + } + .actor-4 { + ${t.actor4?`fill: ${t.actor4}`:""}; + } + .actor-5 { + ${t.actor5?`fill: ${t.actor5}`:""}; + } + ${Nc()} +`,"getStyles"),qpe=bWe});var XP,TWe,jpe,Kpe,wWe,kWe,Xpe,EWe,SWe,Qpe,CWe,z1,Zpe=N(()=>{"use strict";fr();t2();XP=o(function(t,e){return Nd(t,e)},"drawRect"),TWe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=Sl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=Sl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),jpe=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),Kpe=o(function(t,e){return XY(t,e)},"drawText"),wWe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,Kpe(t,e)},"drawLabel"),kWe=o(function(t,e,r){let n=t.append("g"),i=Al();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width*e.taskCount+r.diagramMarginX*(e.taskCount-1),i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,XP(n,i),Qpe(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),Xpe=-1,EWe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");Xpe++;let a=300+5*30;i.append("line").attr("id","task"+Xpe).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),TWe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=Al();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,XP(i,s);let l=e.x+14;e.people.forEach(u=>{let h=e.actors[u].color,f={cx:l,cy:e.y,r:7,fill:h,stroke:"#000",title:u,pos:e.actors[u].position};jpe(i,f),l+=10}),Qpe(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),SWe=o(function(t,e){iT(t,e)},"drawBackgroundRect"),Qpe=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(//gi);for(let v=0;v{let a=th[i].color,s={cx:20,cy:n,r:7,fill:a,stroke:"#000",pos:th[i].position};z1.drawCircle(t,s);let l=t.append("text").attr("visibility","hidden").text(i),u=l.node().getBoundingClientRect().width;l.remove();let h=[];if(u<=r)h=[i];else{let f=i.split(" "),d="";l=t.append("text").attr("visibility","hidden"),f.forEach(p=>{let m=d?`${d} ${p}`:p;if(l.text(m),l.node().getBoundingClientRect().width>r){if(d&&h.push(d),d=p,l.text(p),l.node().getBoundingClientRect().width>r){let y="";for(let v of p)y+=v,l.text(y+"-"),l.node().getBoundingClientRect().width>r&&(h.push(y.slice(0,-1)+"-"),y=v);d=y}}else d=m}),d&&h.push(d),l.remove()}h.forEach((f,d)=>{let p={x:40,y:n+7+d*20,fill:"#666",text:f,textMargin:e.boxTextMargin??5},g=z1.drawText(t,p).node().getBoundingClientRect().width;g>h6&&g>e.leftMargin-g&&(h6=g)}),n+=Math.max(20,h.length*20)})}var AWe,th,h6,Ul,_f,DWe,rl,jP,Jpe,LWe,KP,e0e=N(()=>{"use strict";fr();Zpe();Gt();xi();AWe=o(function(t){Object.keys(t).forEach(function(r){Ul[r]=t[r]})},"setConf"),th={},h6=0;o(_We,"drawActorLegend");Ul=me().journey,_f=0,DWe=o(function(t,e,r,n){let i=me(),a=i.journey.titleColor,s=i.journey.titleFontSize,l=i.journey.titleFontFamily,u=i.securityLevel,h;u==="sandbox"&&(h=Ge("#i"+e));let f=u==="sandbox"?Ge(h.nodes()[0].contentDocument.body):Ge("body");rl.init();let d=f.select("#"+e);z1.initGraphics(d);let p=n.db.getTasks(),m=n.db.getDiagramTitle(),g=n.db.getActors();for(let S in th)delete th[S];let y=0;g.forEach(S=>{th[S]={color:Ul.actorColours[y%Ul.actorColours.length],position:y},y++}),_We(d),_f=Ul.leftMargin+h6,rl.insert(0,0,_f,Object.keys(th).length*50),LWe(d,p,0);let v=rl.getBounds();m&&d.append("text").text(m).attr("x",_f).attr("font-size",s).attr("font-weight","bold").attr("y",25).attr("fill",a).attr("font-family",l);let x=v.stopy-v.starty+2*Ul.diagramMarginY,b=_f+v.stopx+2*Ul.diagramMarginX;fn(d,x,b,Ul.useMaxWidth),d.append("line").attr("x1",_f).attr("y1",Ul.height*4).attr("x2",b-_f-4).attr("y2",Ul.height*4).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");let T=m?70:0;d.attr("viewBox",`${v.startx} -25 ${b} ${x+T}`),d.attr("preserveAspectRatio","xMinYMin meet"),d.attr("height",x+T+25)},"draw"),rl={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:o(function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=me().journey,a=this,s=0;function l(u){return o(function(f){s++;let d=a.sequenceItems.length-s+1;a.updateVal(f,"starty",e-d*i.boxMargin,Math.min),a.updateVal(f,"stopy",n+d*i.boxMargin,Math.max),a.updateVal(rl.data,"startx",t-d*i.boxMargin,Math.min),a.updateVal(rl.data,"stopx",r+d*i.boxMargin,Math.max),u!=="activation"&&(a.updateVal(f,"startx",t-d*i.boxMargin,Math.min),a.updateVal(f,"stopx",r+d*i.boxMargin,Math.max),a.updateVal(rl.data,"starty",e-d*i.boxMargin,Math.min),a.updateVal(rl.data,"stopy",n+d*i.boxMargin,Math.max))},"updateItemBounds")}o(l,"updateFn"),this.sequenceItems.forEach(l())},"updateBounds"),insert:o(function(t,e,r,n){let i=Math.min(t,r),a=Math.max(t,r),s=Math.min(e,n),l=Math.max(e,n);this.updateVal(rl.data,"startx",i,Math.min),this.updateVal(rl.data,"starty",s,Math.min),this.updateVal(rl.data,"stopx",a,Math.max),this.updateVal(rl.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return this.data},"getBounds")},jP=Ul.sectionFills,Jpe=Ul.sectionColours,LWe=o(function(t,e,r){let n=me().journey,i="",a=n.height*2+n.diagramMarginY,s=r+a,l=0,u="#CCC",h="black",f=0;for(let[d,p]of e.entries()){if(i!==p.section){u=jP[l%jP.length],f=l%jP.length,h=Jpe[l%Jpe.length];let g=0,y=p.section;for(let x=d;x(th[y]&&(g[y]=th[y]),g),{});p.x=d*n.taskMargin+d*n.width+_f,p.y=s,p.width=n.diagramMarginX,p.height=n.diagramMarginY,p.colour=h,p.fill=u,p.num=f,p.actors=m,z1.drawTask(t,p,n),rl.insert(p.x,p.y,p.x+p.width+n.taskMargin,300+5*30)}},"drawTasks"),KP={setConf:AWe,draw:DWe}});var t0e={};ur(t0e,{diagram:()=>RWe});var RWe,r0e=N(()=>{"use strict";Upe();Wpe();Ype();e0e();RWe={parser:Vpe,db:YP,renderer:KP,styles:qpe,init:o(t=>{KP.setConf(t.journey),YP.clear()},"init")}});var ZP,c0e,u0e=N(()=>{"use strict";ZP=function(){var t=o(function(p,m,g,y){for(g=g||{},y=p.length;y--;g[p[y]]=m);return g},"o"),e=[6,8,10,11,12,14,16,17,20,21],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,16],u=[1,17],h={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:o(function(m,g,y,v,x,b,T){var S=b.length-1;switch(x){case 1:return b[S-1];case 2:this.$=[];break;case 3:b[S-1].push(b[S]),this.$=b[S-1];break;case 4:case 5:this.$=b[S];break;case 6:case 7:this.$=[];break;case 8:v.getCommonDb().setDiagramTitle(b[S].substr(6)),this.$=b[S].substr(6);break;case 9:this.$=b[S].trim(),v.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=b[S].trim(),v.getCommonDb().setAccDescription(this.$);break;case 12:v.addSection(b[S].substr(8)),this.$=b[S].substr(8);break;case 15:v.addTask(b[S],0,""),this.$=b[S];break;case 16:v.addEvent(b[S].substr(2)),this.$=b[S];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:o(function(m,g){if(g.recoverable)this.trace(m);else{var y=new Error(m);throw y.hash=g,y}},"parseError"),parse:o(function(m){var g=this,y=[0],v=[],x=[null],b=[],T=this.table,S="",w=0,E=0,_=0,C=2,D=1,O=b.slice.call(arguments,1),R=Object.create(this.lexer),k={yy:{}};for(var L in this.yy)Object.prototype.hasOwnProperty.call(this.yy,L)&&(k.yy[L]=this.yy[L]);R.setInput(m,k.yy),k.yy.lexer=R,k.yy.parser=this,typeof R.yylloc>"u"&&(R.yylloc={});var A=R.yylloc;b.push(A);var I=R.options&&R.options.ranges;typeof k.yy.parseError=="function"?this.parseError=k.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function M(j){y.length=y.length-2*j,x.length=x.length-j,b.length=b.length-j}o(M,"popStack");function P(){var j;return j=v.pop()||R.lex()||D,typeof j!="number"&&(j instanceof Array&&(v=j,j=v.pop()),j=g.symbols_[j]||j),j}o(P,"lex");for(var B,F,z,$,U,K,ee={},Y,ce,Z,ue;;){if(z=y[y.length-1],this.defaultActions[z]?$=this.defaultActions[z]:((B===null||typeof B>"u")&&(B=P()),$=T[z]&&T[z][B]),typeof $>"u"||!$.length||!$[0]){var Q="";ue=[];for(Y in T[z])this.terminals_[Y]&&Y>C&&ue.push("'"+this.terminals_[Y]+"'");R.showPosition?Q="Parse error on line "+(w+1)+`: +`+R.showPosition()+` +Expecting `+ue.join(", ")+", got '"+(this.terminals_[B]||B)+"'":Q="Parse error on line "+(w+1)+": Unexpected "+(B==D?"end of input":"'"+(this.terminals_[B]||B)+"'"),this.parseError(Q,{text:R.match,token:this.terminals_[B]||B,line:R.yylineno,loc:A,expected:ue})}if($[0]instanceof Array&&$.length>1)throw new Error("Parse Error: multiple actions possible at state: "+z+", token: "+B);switch($[0]){case 1:y.push(B),x.push(R.yytext),b.push(R.yylloc),y.push($[1]),B=null,F?(B=F,F=null):(E=R.yyleng,S=R.yytext,w=R.yylineno,A=R.yylloc,_>0&&_--);break;case 2:if(ce=this.productions_[$[1]][1],ee.$=x[x.length-ce],ee._$={first_line:b[b.length-(ce||1)].first_line,last_line:b[b.length-1].last_line,first_column:b[b.length-(ce||1)].first_column,last_column:b[b.length-1].last_column},I&&(ee._$.range=[b[b.length-(ce||1)].range[0],b[b.length-1].range[1]]),K=this.performAction.apply(ee,[S,E,w,k.yy,$[1],x,b].concat(O)),typeof K<"u")return K;ce&&(y=y.slice(0,-1*ce*2),x=x.slice(0,-1*ce),b=b.slice(0,-1*ce)),y.push(this.productions_[$[1]][0]),x.push(ee.$),b.push(ee._$),Z=T[y[y.length-2]][y[y.length-1]],y.push(Z);break;case 3:return!0}}return!0},"parse")},f=function(){var p={EOF:1,parseError:o(function(g,y){if(this.yy.parser)this.yy.parser.parseError(g,y);else throw new Error(g)},"parseError"),setInput:o(function(m,g){return this.yy=g||this.yy||{},this._input=m,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var m=this._input[0];this.yytext+=m,this.yyleng++,this.offset++,this.match+=m,this.matched+=m;var g=m.match(/(?:\r\n?|\n).*/g);return g?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),m},"input"),unput:o(function(m){var g=m.length,y=m.split(/(?:\r\n?|\n)/g);this._input=m+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-g),this.offset-=g;var v=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),y.length-1&&(this.yylineno-=y.length-1);var x=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:y?(y.length===v.length?this.yylloc.first_column:0)+v[v.length-y.length].length-y[0].length:this.yylloc.first_column-g},this.options.ranges&&(this.yylloc.range=[x[0],x[0]+this.yyleng-g]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(m){this.unput(this.match.slice(m))},"less"),pastInput:o(function(){var m=this.matched.substr(0,this.matched.length-this.match.length);return(m.length>20?"...":"")+m.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var m=this.match;return m.length<20&&(m+=this._input.substr(0,20-m.length)),(m.substr(0,20)+(m.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var m=this.pastInput(),g=new Array(m.length+1).join("-");return m+this.upcomingInput()+` +`+g+"^"},"showPosition"),test_match:o(function(m,g){var y,v,x;if(this.options.backtrack_lexer&&(x={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(x.yylloc.range=this.yylloc.range.slice(0))),v=m[0].match(/(?:\r\n?|\n).*/g),v&&(this.yylineno+=v.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:v?v[v.length-1].length-v[v.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+m[0].length},this.yytext+=m[0],this.match+=m[0],this.matches=m,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(m[0].length),this.matched+=m[0],y=this.performAction.call(this,this.yy,this,g,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),y)return y;if(this._backtrack){for(var b in x)this[b]=x[b];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var m,g,y,v;this._more||(this.yytext="",this.match="");for(var x=this._currentRules(),b=0;bg[0].length)){if(g=y,v=b,this.options.backtrack_lexer){if(m=this.test_match(y,x[b]),m!==!1)return m;if(this._backtrack){g=!1;continue}else return!1}else if(!this.options.flex)break}return g?(m=this.test_match(g,x[v]),m!==!1?m:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var g=this.next();return g||this.lex()},"lex"),begin:o(function(g){this.conditionStack.push(g)},"begin"),popState:o(function(){var g=this.conditionStack.length-1;return g>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(g){return g=this.conditionStack.length-1-Math.abs(g||0),g>=0?this.conditionStack[g]:"INITIAL"},"topState"),pushState:o(function(g){this.begin(g)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(g,y,v,x){var b=x;switch(v){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^:\n]+)/i,/^(?::\s(?:[^:\n]|:(?!\s))+)/i,/^(?:[^#:\n]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};return p}();h.lexer=f;function d(){this.yy={}}return o(d,"Parser"),d.prototype=h,h.Parser=d,new d}();ZP.parser=ZP;c0e=ZP});var eB={};ur(eB,{addEvent:()=>x0e,addSection:()=>m0e,addTask:()=>v0e,addTaskOrg:()=>b0e,clear:()=>p0e,default:()=>zWe,getCommonDb:()=>d0e,getSections:()=>g0e,getTasks:()=>y0e});var G1,f0e,JP,f6,V1,d0e,p0e,m0e,g0e,y0e,v0e,x0e,b0e,h0e,zWe,T0e=N(()=>{"use strict";ci();G1="",f0e=0,JP=[],f6=[],V1=[],d0e=o(()=>rv,"getCommonDb"),p0e=o(function(){JP.length=0,f6.length=0,G1="",V1.length=0,kr()},"clear"),m0e=o(function(t){G1=t,JP.push(t)},"addSection"),g0e=o(function(){return JP},"getSections"),y0e=o(function(){let t=h0e(),e=100,r=0;for(;!t&&rr.id===f0e-1).events.push(t)},"addEvent"),b0e=o(function(t){let e={section:G1,type:G1,description:t,task:t,classes:[]};f6.push(e)},"addTaskOrg"),h0e=o(function(){let t=o(function(r){return V1[r].processed},"compileTask"),e=!0;for(let[r,n]of V1.entries())t(r),e=e&&n.processed;return e},"compileTasks"),zWe={clear:p0e,getCommonDb:d0e,addSection:m0e,getSections:g0e,getTasks:y0e,addTask:v0e,addTaskOrg:b0e,addEvent:x0e}});function S0e(t,e){t.each(function(){var r=Ge(this),n=r.text().split(/(\s+|
    )/).reverse(),i,a=[],s=1.1,l=r.attr("y"),u=parseFloat(r.attr("dy")),h=r.text(null).append("tspan").attr("x",0).attr("y",l).attr("dy",u+"em");for(let f=0;fe||i==="
    ")&&(a.pop(),h.text(a.join(" ").trim()),i==="
    "?a=[""]:a=[i],h=r.append("tspan").attr("x",0).attr("y",l).attr("dy",s+"em").text(i))})}var GWe,d6,VWe,UWe,k0e,HWe,WWe,w0e,qWe,YWe,XWe,tB,E0e,jWe,KWe,QWe,ZWe,Df,C0e=N(()=>{"use strict";fr();GWe=12,d6=o(function(t,e){let r=t.append("rect");return r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),r.attr("rx",e.rx),r.attr("ry",e.ry),e.class!==void 0&&r.attr("class",e.class),r},"drawRect"),VWe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=Sl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=Sl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),UWe=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),k0e=o(function(t,e){let r=e.text.replace(//gi," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class!==void 0&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),HWe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,k0e(t,e)},"drawLabel"),WWe=o(function(t,e,r){let n=t.append("g"),i=tB();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width,i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,d6(n,i),E0e(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),w0e=-1,qWe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");w0e++;let a=300+5*30;i.append("line").attr("id","task"+w0e).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),VWe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=tB();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,d6(i,s),E0e(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),YWe=o(function(t,e){d6(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()},"drawBackgroundRect"),XWe=o(function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}},"getTextObj"),tB=o(function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),E0e=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(//gi);for(let v=0;v{"use strict";fr();C0e();yt();Gt();xi();JWe=o(function(t,e,r,n){let i=me(),a=i.timeline?.leftMargin??50;X.debug("timeline",n.db);let s=i.securityLevel,l;s==="sandbox"&&(l=Ge("#i"+e));let h=(s==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body")).select("#"+e);h.append("g");let f=n.db.getTasks(),d=n.db.getCommonDb().getDiagramTitle();X.debug("task",f),Df.initGraphics(h);let p=n.db.getSections();X.debug("sections",p);let m=0,g=0,y=0,v=0,x=50+a,b=50;v=50;let T=0,S=!0;p.forEach(function(D){let O={number:T,descr:D,section:T,width:150,padding:20,maxHeight:m},R=Df.getVirtualNodeHeight(h,O,i);X.debug("sectionHeight before draw",R),m=Math.max(m,R+20)});let w=0,E=0;X.debug("tasks.length",f.length);for(let[D,O]of f.entries()){let R={number:D,descr:O,section:O.section,width:150,padding:20,maxHeight:g},k=Df.getVirtualNodeHeight(h,R,i);X.debug("taskHeight before draw",k),g=Math.max(g,k+20),w=Math.max(w,O.events.length);let L=0;for(let A of O.events){let I={descr:A,section:O.section,number:O.section,width:150,padding:20,maxHeight:50};L+=Df.getVirtualNodeHeight(h,I,i)}O.events.length>0&&(L+=(O.events.length-1)*10),E=Math.max(E,L)}X.debug("maxSectionHeight before draw",m),X.debug("maxTaskHeight before draw",g),p&&p.length>0?p.forEach(D=>{let O=f.filter(A=>A.section===D),R={number:T,descr:D,section:T,width:200*Math.max(O.length,1)-50,padding:20,maxHeight:m};X.debug("sectionNode",R);let k=h.append("g"),L=Df.drawNode(k,R,T,i);X.debug("sectionNode output",L),k.attr("transform",`translate(${x}, ${v})`),b+=m+50,O.length>0&&A0e(h,O,T,x,b,g,i,w,E,m,!1),x+=200*Math.max(O.length,1),b=v,T++}):(S=!1,A0e(h,f,T,x,b,g,i,w,E,m,!0));let _=h.node().getBBox();X.debug("bounds",_),d&&h.append("text").text(d).attr("x",_.width/2-a).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),y=S?m+g+150:g+100,h.append("g").attr("class","lineWrapper").append("line").attr("x1",a).attr("y1",y).attr("x2",_.width+3*a).attr("y2",y).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),Lo(void 0,h,i.timeline?.padding??50,i.timeline?.useMaxWidth??!1)},"draw"),A0e=o(function(t,e,r,n,i,a,s,l,u,h,f){for(let d of e){let p={descr:d.task,section:r,number:r,width:150,padding:20,maxHeight:a};X.debug("taskNode",p);let m=t.append("g").attr("class","taskWrapper"),y=Df.drawNode(m,p,r,s).height;if(X.debug("taskHeight after draw",y),m.attr("transform",`translate(${n}, ${i})`),a=Math.max(a,y),d.events){let v=t.append("g").attr("class","lineWrapper"),x=a;i+=100,x=x+eqe(t,d.events,r,n,i,s),i-=100,v.append("line").attr("x1",n+190/2).attr("y1",i+a).attr("x2",n+190/2).attr("y2",i+a+100+u+100).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}n=n+200,f&&!s.timeline?.disableMulticolor&&r++}i=i-10},"drawTasks"),eqe=o(function(t,e,r,n,i,a){let s=0,l=i;i=i+100;for(let u of e){let h={descr:u,section:r,number:r,width:150,padding:20,maxHeight:50};X.debug("eventNode",h);let f=t.append("g").attr("class","eventWrapper"),p=Df.drawNode(f,h,r,a).height;s=s+p,f.attr("transform",`translate(${n}, ${i})`),i=i+10+p}return i=l,s},"drawEvents"),_0e={setConf:o(()=>{},"setConf"),draw:JWe}});var tqe,rqe,L0e,R0e=N(()=>{"use strict";Ks();tqe=o(t=>{let e="";for(let r=0;r` + .edge { + stroke-width: 3; + } + ${tqe(t)} + .section-root rect, .section-root path, .section-root circle { + fill: ${t.git0}; + } + .section-root text { + fill: ${t.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .eventWrapper { + filter: brightness(120%); + } +`,"getStyles"),L0e=rqe});var N0e={};ur(N0e,{diagram:()=>nqe});var nqe,M0e=N(()=>{"use strict";u0e();T0e();D0e();R0e();nqe={db:eB,renderer:_0e,parser:c0e,styles:L0e}});var rB,P0e,B0e=N(()=>{"use strict";rB=function(){var t=o(function(S,w,E,_){for(E=E||{},_=S.length;_--;E[S[_]]=w);return E},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,6,13,15,16,19,22],g=[1,33],y=[1,34],v=[1,6,7,11,13,15,16,19,22],x={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:o(function(w,E,_,C,D,O,R){var k=O.length-1;switch(D){case 6:case 7:return C;case 8:C.getLogger().trace("Stop NL ");break;case 9:C.getLogger().trace("Stop EOF ");break;case 11:C.getLogger().trace("Stop NL2 ");break;case 12:C.getLogger().trace("Stop EOF2 ");break;case 15:C.getLogger().info("Node: ",O[k].id),C.addNode(O[k-1].length,O[k].id,O[k].descr,O[k].type);break;case 16:C.getLogger().trace("Icon: ",O[k]),C.decorateNode({icon:O[k]});break;case 17:case 21:C.decorateNode({class:O[k]});break;case 18:C.getLogger().trace("SPACELIST");break;case 19:C.getLogger().trace("Node: ",O[k].id),C.addNode(0,O[k].id,O[k].descr,O[k].type);break;case 20:C.decorateNode({icon:O[k]});break;case 25:C.getLogger().trace("node found ..",O[k-2]),this.$={id:O[k-1],descr:O[k-1],type:C.getType(O[k-2],O[k])};break;case 26:this.$={id:O[k],descr:O[k],type:C.nodeType.DEFAULT};break;case 27:C.getLogger().trace("node found ..",O[k-3]),this.$={id:O[k-3],descr:O[k-1],type:C.getType(O[k-2],O[k])};break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:r,9:22,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:h,7:f,10:23,11:d},t(p,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:s,22:l}),t(p,[2,18]),t(p,[2,19]),t(p,[2,20]),t(p,[2,21]),t(p,[2,23]),t(p,[2,24]),t(p,[2,26],{19:[1,30]}),{20:[1,31]},{6:h,7:f,10:32,11:d},{1:[2,7],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(m,[2,14],{7:g,11:y}),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(p,[2,15]),t(p,[2,16]),t(p,[2,17]),{20:[1,35]},{21:[1,36]},t(m,[2,13],{7:g,11:y}),t(v,[2,11]),t(v,[2,12]),{21:[1,37]},t(p,[2,25]),t(p,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(w,E){if(E.recoverable)this.trace(w);else{var _=new Error(w);throw _.hash=E,_}},"parseError"),parse:o(function(w){var E=this,_=[0],C=[],D=[null],O=[],R=this.table,k="",L=0,A=0,I=0,M=2,P=1,B=O.slice.call(arguments,1),F=Object.create(this.lexer),z={yy:{}};for(var $ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,$)&&(z.yy[$]=this.yy[$]);F.setInput(w,z.yy),z.yy.lexer=F,z.yy.parser=this,typeof F.yylloc>"u"&&(F.yylloc={});var U=F.yylloc;O.push(U);var K=F.options&&F.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ee(ae){_.length=_.length-2*ae,D.length=D.length-ae,O.length=O.length-ae}o(ee,"popStack");function Y(){var ae;return ae=C.pop()||F.lex()||P,typeof ae!="number"&&(ae instanceof Array&&(C=ae,ae=C.pop()),ae=E.symbols_[ae]||ae),ae}o(Y,"lex");for(var ce,Z,ue,Q,j,ne,te={},he,le,J,Se;;){if(ue=_[_.length-1],this.defaultActions[ue]?Q=this.defaultActions[ue]:((ce===null||typeof ce>"u")&&(ce=Y()),Q=R[ue]&&R[ue][ce]),typeof Q>"u"||!Q.length||!Q[0]){var se="";Se=[];for(he in R[ue])this.terminals_[he]&&he>M&&Se.push("'"+this.terminals_[he]+"'");F.showPosition?se="Parse error on line "+(L+1)+`: +`+F.showPosition()+` +Expecting `+Se.join(", ")+", got '"+(this.terminals_[ce]||ce)+"'":se="Parse error on line "+(L+1)+": Unexpected "+(ce==P?"end of input":"'"+(this.terminals_[ce]||ce)+"'"),this.parseError(se,{text:F.match,token:this.terminals_[ce]||ce,line:F.yylineno,loc:U,expected:Se})}if(Q[0]instanceof Array&&Q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ue+", token: "+ce);switch(Q[0]){case 1:_.push(ce),D.push(F.yytext),O.push(F.yylloc),_.push(Q[1]),ce=null,Z?(ce=Z,Z=null):(A=F.yyleng,k=F.yytext,L=F.yylineno,U=F.yylloc,I>0&&I--);break;case 2:if(le=this.productions_[Q[1]][1],te.$=D[D.length-le],te._$={first_line:O[O.length-(le||1)].first_line,last_line:O[O.length-1].last_line,first_column:O[O.length-(le||1)].first_column,last_column:O[O.length-1].last_column},K&&(te._$.range=[O[O.length-(le||1)].range[0],O[O.length-1].range[1]]),ne=this.performAction.apply(te,[k,A,L,z.yy,Q[1],D,O].concat(B)),typeof ne<"u")return ne;le&&(_=_.slice(0,-1*le*2),D=D.slice(0,-1*le),O=O.slice(0,-1*le)),_.push(this.productions_[Q[1]][0]),D.push(te.$),O.push(te._$),J=R[_[_.length-2]][_[_.length-1]],_.push(J);break;case 3:return!0}}return!0},"parse")},b=function(){var S={EOF:1,parseError:o(function(E,_){if(this.yy.parser)this.yy.parser.parseError(E,_);else throw new Error(E)},"parseError"),setInput:o(function(w,E){return this.yy=E||this.yy||{},this._input=w,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var w=this._input[0];this.yytext+=w,this.yyleng++,this.offset++,this.match+=w,this.matched+=w;var E=w.match(/(?:\r\n?|\n).*/g);return E?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),w},"input"),unput:o(function(w){var E=w.length,_=w.split(/(?:\r\n?|\n)/g);this._input=w+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-E),this.offset-=E;var C=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),_.length-1&&(this.yylineno-=_.length-1);var D=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:_?(_.length===C.length?this.yylloc.first_column:0)+C[C.length-_.length].length-_[0].length:this.yylloc.first_column-E},this.options.ranges&&(this.yylloc.range=[D[0],D[0]+this.yyleng-E]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(w){this.unput(this.match.slice(w))},"less"),pastInput:o(function(){var w=this.matched.substr(0,this.matched.length-this.match.length);return(w.length>20?"...":"")+w.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var w=this.match;return w.length<20&&(w+=this._input.substr(0,20-w.length)),(w.substr(0,20)+(w.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var w=this.pastInput(),E=new Array(w.length+1).join("-");return w+this.upcomingInput()+` +`+E+"^"},"showPosition"),test_match:o(function(w,E){var _,C,D;if(this.options.backtrack_lexer&&(D={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(D.yylloc.range=this.yylloc.range.slice(0))),C=w[0].match(/(?:\r\n?|\n).*/g),C&&(this.yylineno+=C.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:C?C[C.length-1].length-C[C.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+w[0].length},this.yytext+=w[0],this.match+=w[0],this.matches=w,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(w[0].length),this.matched+=w[0],_=this.performAction.call(this,this.yy,this,E,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),_)return _;if(this._backtrack){for(var O in D)this[O]=D[O];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var w,E,_,C;this._more||(this.yytext="",this.match="");for(var D=this._currentRules(),O=0;OE[0].length)){if(E=_,C=O,this.options.backtrack_lexer){if(w=this.test_match(_,D[O]),w!==!1)return w;if(this._backtrack){E=!1;continue}else return!1}else if(!this.options.flex)break}return E?(w=this.test_match(E,D[C]),w!==!1?w:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var E=this.next();return E||this.lex()},"lex"),begin:o(function(E){this.conditionStack.push(E)},"begin"),popState:o(function(){var E=this.conditionStack.length-1;return E>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(E){return E=this.conditionStack.length-1-Math.abs(E||0),E>=0?this.conditionStack[E]:"INITIAL"},"topState"),pushState:o(function(E){this.begin(E)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(E,_,C,D){var O=D;switch(C){case 0:return E.getLogger().trace("Found comment",_.yytext),6;break;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;break;case 4:this.popState();break;case 5:E.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return E.getLogger().trace("SPACELINE"),6;break;case 7:return 7;case 8:return 15;case 9:E.getLogger().trace("end icon"),this.popState();break;case 10:return E.getLogger().trace("Exploding node"),this.begin("NODE"),19;break;case 11:return E.getLogger().trace("Cloud"),this.begin("NODE"),19;break;case 12:return E.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;break;case 13:return E.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;break;case 14:return this.begin("NODE"),19;break;case 15:return this.begin("NODE"),19;break;case 16:return this.begin("NODE"),19;break;case 17:return this.begin("NODE"),19;break;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 23:this.popState();break;case 24:E.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return E.getLogger().trace("description:",_.yytext),"NODE_DESCR";break;case 26:this.popState();break;case 27:return this.popState(),E.getLogger().trace("node end ))"),"NODE_DEND";break;case 28:return this.popState(),E.getLogger().trace("node end )"),"NODE_DEND";break;case 29:return this.popState(),E.getLogger().trace("node end ...",_.yytext),"NODE_DEND";break;case 30:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 31:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 32:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 33:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 34:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 35:return E.getLogger().trace("Long description:",_.yytext),20;break;case 36:return E.getLogger().trace("Long description:",_.yytext),20;break}},"anonymous"),rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};return S}();x.lexer=b;function T(){this.yy={}}return o(T,"Parser"),T.prototype=x,x.Parser=T,new T}();rB.parser=rB;P0e=rB});var oqe,p6,F0e=N(()=>{"use strict";Gt();pr();yt();_a();oqe={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},p6=class{constructor(){this.nodes=[];this.count=0;this.elements={};this.getLogger=this.getLogger.bind(this),this.nodeType=oqe,this.clear(),this.getType=this.getType.bind(this),this.getMindmap=this.getMindmap.bind(this),this.getElementById=this.getElementById.bind(this),this.getParent=this.getParent.bind(this),this.getMindmap=this.getMindmap.bind(this),this.addNode=this.addNode.bind(this),this.decorateNode=this.decorateNode.bind(this)}static{o(this,"MindmapDB")}clear(){this.nodes=[],this.count=0,this.elements={}}getParent(e){for(let r=this.nodes.length-1;r>=0;r--)if(this.nodes[r].level0?this.nodes[0]:null}addNode(e,r,n,i){X.info("addNode",e,r,n,i);let a=me(),s=a.mindmap?.padding??or.mindmap.padding;switch(i){case this.nodeType.ROUNDED_RECT:case this.nodeType.RECT:case this.nodeType.HEXAGON:s*=2;break}let l={id:this.count++,nodeId:wr(r,a),level:e,descr:wr(n,a),type:i,children:[],width:a.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:s},u=this.getParent(e);if(u)u.children.push(l),this.nodes.push(l);else if(this.nodes.length===0)this.nodes.push(l);else throw new Error(`There can be only one root. No parent could be found for ("${l.descr}")`)}getType(e,r){switch(X.debug("In get type",e,r),e){case"[":return this.nodeType.RECT;case"(":return r===")"?this.nodeType.ROUNDED_RECT:this.nodeType.CLOUD;case"((":return this.nodeType.CIRCLE;case")":return this.nodeType.CLOUD;case"))":return this.nodeType.BANG;case"{{":return this.nodeType.HEXAGON;default:return this.nodeType.DEFAULT}}setElementForId(e,r){this.elements[e]=r}getElementById(e){return this.elements[e]}decorateNode(e){if(!e)return;let r=me(),n=this.nodes[this.nodes.length-1];e.icon&&(n.icon=wr(e.icon,r)),e.class&&(n.class=wr(e.class,r))}type2Str(e){switch(e){case this.nodeType.DEFAULT:return"no-border";case this.nodeType.RECT:return"rect";case this.nodeType.ROUNDED_RECT:return"rounded-rect";case this.nodeType.CIRCLE:return"circle";case this.nodeType.CLOUD:return"cloud";case this.nodeType.BANG:return"bang";case this.nodeType.HEXAGON:return"hexgon";default:return"no-border"}}getLogger(){return X}}});function qi(t){"@babel/helpers - typeof";return qi=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},qi(t)}function Vf(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function $0e(t,e){for(var r=0;rt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[n++]}},"n"),e:o(function(u){throw u},"e"),f:i}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var a=!0,s=!1,l;return{s:o(function(){r=r.call(t)},"s"),n:o(function(){var u=r.next();return a=u.done,u},"n"),e:o(function(u){s=!0,l=u},"e"),f:o(function(){try{!a&&r.return!=null&&r.return()}finally{if(s)throw l}},"f")}}function Pqe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}function Bqe(t,e){return e={exports:{}},t(e,e.exports),e.exports}function Hqe(t){for(var e=t.length;e--&&Uqe.test(t.charAt(e)););return e}function Yqe(t){return t&&t.slice(0,Wqe(t)+1).replace(qqe,"")}function Zqe(t){var e=Kqe.call(t,Fb),r=t[Fb];try{t[Fb]=void 0;var n=!0}catch{}var i=Qqe.call(t);return n&&(e?t[Fb]=r:delete t[Fb]),i}function rYe(t){return tYe.call(t)}function sYe(t){return t==null?t===void 0?aYe:iYe:V0e&&V0e in Object(t)?Jqe(t):nYe(t)}function oYe(t){return t!=null&&typeof t=="object"}function uYe(t){return typeof t=="symbol"||lYe(t)&&mge(t)==cYe}function mYe(t){if(typeof t=="number")return t;if(d4(t))return U0e;if(Kp(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=Kp(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=Xqe(t);var r=fYe.test(t);return r||dYe.test(t)?pYe(t.slice(2),r?2:8):hYe.test(t)?U0e:+t}function xYe(t,e,r){var n,i,a,s,l,u,h=0,f=!1,d=!1,p=!0;if(typeof t!="function")throw new TypeError(gYe);e=H0e(e)||0,Kp(r)&&(f=!!r.leading,d="maxWait"in r,a=d?yYe(H0e(r.maxWait)||0,e):a,p="trailing"in r?!!r.trailing:p);function m(E){var _=n,C=i;return n=i=void 0,h=E,s=t.apply(C,_),s}o(m,"invokeFunc");function g(E){return h=E,l=setTimeout(x,e),f?m(E):s}o(g,"leadingEdge");function y(E){var _=E-u,C=E-h,D=e-_;return d?vYe(D,a-C):D}o(y,"remainingWait");function v(E){var _=E-u,C=E-h;return u===void 0||_>=e||_<0||d&&C>=a}o(v,"shouldInvoke");function x(){var E=nB();if(v(E))return b(E);l=setTimeout(x,y(E))}o(x,"timerExpired");function b(E){return l=void 0,p&&n?m(E):(n=i=void 0,s)}o(b,"trailingEdge");function T(){l!==void 0&&clearTimeout(l),h=0,n=u=i=l=void 0}o(T,"cancel");function S(){return l===void 0?s:b(nB())}o(S,"flush");function w(){var E=nB(),_=v(E);if(n=arguments,i=this,u=E,_){if(l===void 0)return g(u);if(d)return clearTimeout(l),l=setTimeout(x,e),m(u)}return l===void 0&&(l=setTimeout(x,e)),s}return o(w,"debounced"),w.cancel=T,w.flush=S,w}function eC(t,e,r,n,i,a){var s;return li(t)?s=t:s=ny[t]||ny.euclidean,e===0&&li(t)?s(i,a):s(e,r,n,i,a)}function hje(t,e){if(tC(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||d4(t)?!0:uje.test(t)||!cje.test(t)||e!=null&&t in Object(e)}function yje(t){if(!Kp(t))return!1;var e=mge(t);return e==pje||e==mje||e==dje||e==gje}function bje(t){return!!ume&&ume in t}function Eje(t){if(t!=null){try{return kje.call(t)}catch{}try{return t+""}catch{}}return""}function Mje(t){if(!Kp(t)||Tje(t))return!1;var e=vje(t)?Nje:Aje;return e.test(Sje(t))}function Oje(t,e){return t?.[e]}function Bje(t,e){var r=Pje(t,e);return Ije(r)?r:void 0}function $je(){this.__data__=s4?s4(null):{},this.size=0}function Gje(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}function qje(t){var e=this.__data__;if(s4){var r=e[t];return r===Uje?void 0:r}return Wje.call(e,t)?e[t]:void 0}function Kje(t){var e=this.__data__;return s4?e[t]!==void 0:jje.call(e,t)}function Jje(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=s4&&e===void 0?Zje:e,this}function oy(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1}function dKe(t,e){var r=this.__data__,n=rC(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}function ly(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1&&t%1==0&&t0;){var f=i.shift();e(f),a.add(f.id()),l&&n(i,a,f)}return t}function Xge(t,e,r){if(r.isParent())for(var n=r._private.children,i=0;i0&&arguments[0]!==void 0?arguments[0]:QQe,e=arguments.length>1?arguments[1]:void 0,r=0;r0?k=A:R=A;while(Math.abs(L)>s&&++I=a?b(O,I):M===0?I:S(O,R,R+h)}o(w,"getTForX");var E=!1;function _(){E=!0,(t!==e||r!==n)&&T()}o(_,"precompute");var C=o(function(R){return E||_(),t===e&&r===n?R:R===0?0:R===1?1:v(w(R),e,n)},"f");C.getControlPoints=function(){return[{x:t,y:e},{x:r,y:n}]};var D="generateBezier("+[t,e,r,n]+")";return C.toString=function(){return D},C}function Dme(t,e,r,n,i){if(n===1||e===r)return r;var a=i(e,r,n);return t==null||((t.roundValue||t.color)&&(a=Math.round(a)),t.min!==void 0&&(a=Math.max(a,t.min)),t.max!==void 0&&(a=Math.min(a,t.max))),a}function Lme(t,e){return t.pfValue!=null||t.value!=null?t.pfValue!=null&&(e==null||e.type.units!=="%")?t.pfValue:t.value:t}function W1(t,e,r,n,i){var a=i!=null?i.type:null;r<0?r=0:r>1&&(r=1);var s=Lme(t,i),l=Lme(e,i);if(_t(s)&&_t(l))return Dme(a,s,l,r,n);if(En(s)&&En(l)){for(var u=[],h=0;h0?(m==="spring"&&g.push(s.duration),s.easingImpl=M6[m].apply(null,g)):s.easingImpl=M6[m]}var y=s.easingImpl,v;if(s.duration===0?v=1:v=(r-u)/s.duration,s.applying&&(v=s.progress),v<0?v=0:v>1&&(v=1),s.delay==null){var x=s.startPosition,b=s.position;if(b&&i&&!t.locked()){var T={};Vb(x.x,b.x)&&(T.x=W1(x.x,b.x,v,y)),Vb(x.y,b.y)&&(T.y=W1(x.y,b.y,v,y)),t.position(T)}var S=s.startPan,w=s.pan,E=a.pan,_=w!=null&&n;_&&(Vb(S.x,w.x)&&(E.x=W1(S.x,w.x,v,y)),Vb(S.y,w.y)&&(E.y=W1(S.y,w.y,v,y)),t.emit("pan"));var C=s.startZoom,D=s.zoom,O=D!=null&&n;O&&(Vb(C,D)&&(a.zoom=i4(a.minZoom,W1(C,D,v,y),a.maxZoom)),t.emit("zoom")),(_||O)&&t.emit("viewport");var R=s.style;if(R&&R.length>0&&i){for(var k=0;k=0;_--){var C=E[_];C()}E.splice(0,E.length)},"callbacks"),b=m.length-1;b>=0;b--){var T=m[b],S=T._private;if(S.stopped){m.splice(b,1),S.hooked=!1,S.playing=!1,S.started=!1,x(S.frames);continue}!S.playing&&!S.applying||(S.playing&&S.applying&&(S.applying=!1),S.started||hZe(f,T,t),uZe(f,T,t,d),S.applying&&(S.applying=!1),x(S.frames),S.step!=null&&S.step(t),T.completed()&&(m.splice(b,1),S.hooked=!1,S.playing=!1,S.started=!1,x(S.completes)),y=!0)}return!d&&m.length===0&&g.length===0&&n.push(f),y}o(i,"stepOne");for(var a=!1,s=0;s0?e.notify("draw",r):e.notify("draw")),r.unmerge(n),e.emit("step")}function h1e(t){this.options=ir({},xZe,bZe,t)}function f1e(t){this.options=ir({},TZe,t)}function d1e(t){this.options=ir({},wZe,t)}function uC(t){this.options=ir({},kZe,t),this.options.layout=this;var e=this.options.eles.nodes(),r=this.options.eles.edges(),n=r.filter(function(i){var a=i.source().data("id"),s=i.target().data("id"),l=e.some(function(h){return h.data("id")===a}),u=e.some(function(h){return h.data("id")===s});return!l||!u});this.options.eles=this.options.eles.not(n)}function m1e(t){this.options=ir({},zZe,t)}function eF(t){this.options=ir({},GZe,t)}function g1e(t){this.options=ir({},VZe,t)}function y1e(t){this.options=ir({},UZe,t)}function v1e(t){this.options=t,this.notifications=0}function T1e(t,e){e.radius===0?t.lineTo(e.cx,e.cy):t.arc(e.cx,e.cy,e.radius,e.startAngle,e.endAngle,e.counterClockwise)}function rF(t,e,r,n){var i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0;return n===0||e.radius===0?{cx:e.x,cy:e.y,radius:0,startX:e.x,startY:e.y,stopX:e.x,stopY:e.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(qZe(t,e,r,n,i),{cx:_B,cy:DB,radius:Yp,startX:x1e,startY:b1e,stopX:LB,stopY:RB,startAngle:Kc.ang+Math.PI/2*Xp,endAngle:nl.ang-Math.PI/2*Xp,counterClockwise:P6})}function w1e(t){var e=[];if(t!=null){for(var r=0;r5&&arguments[5]!==void 0?arguments[5]:5,s=arguments.length>6?arguments[6]:void 0;t.beginPath(),t.moveTo(e+a,r),t.lineTo(e+n-a,r),t.quadraticCurveTo(e+n,r,e+n,r+a),t.lineTo(e+n,r+i-a),t.quadraticCurveTo(e+n,r+i,e+n-a,r+i),t.lineTo(e+a,r+i),t.quadraticCurveTo(e,r+i,e,r+i-a),t.lineTo(e,r+a),t.quadraticCurveTo(e,r,e+a,r),t.closePath(),s?t.stroke():t.fill()}function Kme(t,e,r){var n=t.createShader(e);if(t.shaderSource(n,r),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(n));return n}function MJe(t,e,r){var n=Kme(t,t.VERTEX_SHADER,e),i=Kme(t,t.FRAGMENT_SHADER,r),a=t.createProgram();if(t.attachShader(a,n),t.attachShader(a,i),t.linkProgram(a),!t.getProgramParameter(a,t.LINK_STATUS))throw new Error("Could not initialize shaders");return a}function IJe(t,e,r){r===void 0&&(r=e);var n=t.makeOffscreenCanvas(e,r),i=n.context=n.getContext("2d");return n.clear=function(){return i.clearRect(0,0,n.width,n.height)},n.clear(),n}function aF(t){var e=t.pixelRatio,r=t.cy.zoom(),n=t.cy.pan();return{zoom:r*e,pan:{x:n.x*e,y:n.y*e}}}function gB(t,e,r,n,i){var a=n*r+e.x,s=i*r+e.y;return s=Math.round(t.canvasHeight-s),[a,s]}function A6(t,e,r){var n=t[0]/255,i=t[1]/255,a=t[2]/255,s=e,l=r||new Array(4);return l[0]=n*s,l[1]=i*s,l[2]=a*s,l[3]=s,l}function _6(t,e){var r=e||new Array(4);return r[0]=(t>>0&255)/255,r[1]=(t>>8&255)/255,r[2]=(t>>16&255)/255,r[3]=(t>>24&255)/255,r}function OJe(t){return t[0]+(t[1]<<8)+(t[2]<<16)+(t[3]<<24)}function PJe(t,e){var r=t.createTexture();return r.buffer=function(n){t.bindTexture(t.TEXTURE_2D,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR_MIPMAP_NEAREST),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n),t.generateMipmap(t.TEXTURE_2D),t.bindTexture(t.TEXTURE_2D,null)},r.deleteTexture=function(){t.deleteTexture(r)},r}function O1e(t,e){switch(e){case"float":return[1,t.FLOAT,4];case"vec2":return[2,t.FLOAT,4];case"vec3":return[3,t.FLOAT,4];case"vec4":return[4,t.FLOAT,4];case"int":return[1,t.INT,4];case"ivec2":return[2,t.INT,4]}}function P1e(t,e,r){switch(e){case t.FLOAT:return new Float32Array(r);case t.INT:return new Int32Array(r)}}function BJe(t,e,r,n,i,a){switch(e){case t.FLOAT:return new Float32Array(r.buffer,a*n,i);case t.INT:return new Int32Array(r.buffer,a*n,i)}}function FJe(t,e,r,n){var i=O1e(t,e),a=Ri(i,2),s=a[0],l=a[1],u=P1e(t,l,n),h=t.createBuffer();return t.bindBuffer(t.ARRAY_BUFFER,h),t.bufferData(t.ARRAY_BUFFER,u,t.STATIC_DRAW),l===t.FLOAT?t.vertexAttribPointer(r,s,l,!1,0,0):l===t.INT&&t.vertexAttribIPointer(r,s,l,0,0),t.enableVertexAttribArray(r),t.bindBuffer(t.ARRAY_BUFFER,null),h}function yo(t,e,r,n){var i=O1e(t,r),a=Ri(i,3),s=a[0],l=a[1],u=a[2],h=P1e(t,l,e*s),f=s*u,d=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,d),t.bufferData(t.ARRAY_BUFFER,e*f,t.DYNAMIC_DRAW),t.enableVertexAttribArray(n),l===t.FLOAT?t.vertexAttribPointer(n,s,l,!1,f,0):l===t.INT&&t.vertexAttribIPointer(n,s,l,f,0),t.vertexAttribDivisor(n,1),t.bindBuffer(t.ARRAY_BUFFER,null);for(var p=new Array(e),m=0;mL1e?(KJe(t),e.call(t,a)):(QJe(t),G1e(t,a,Jb.SCREEN)))}}{var r=t.matchCanvasSize;t.matchCanvasSize=function(a){r.call(t,a),t.pickingFrameBuffer.setFramebufferAttachmentSizes(t.canvasWidth,t.canvasHeight),t.pickingFrameBuffer.needsDraw=!0}}t.findNearestElements=function(a,s,l,u){return net(t,a,s)};{var n=t.invalidateCachedZSortedEles;t.invalidateCachedZSortedEles=function(){n.call(t),t.pickingFrameBuffer.needsDraw=!0}}{var i=t.notify;t.notify=function(a,s){i.call(t,a,s),a==="viewport"||a==="bounds"?t.pickingFrameBuffer.needsDraw=!0:a==="background"&&t.eleDrawing.invalidate(s,{type:"node-body"})}}}function KJe(t){var e=t.data.contexts[t.WEBGL];e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}function QJe(t){var e=o(function(n){n.save(),n.setTransform(1,0,0,1,0,0),n.clearRect(0,0,t.canvasWidth,t.canvasHeight),n.restore()},"clear");e(t.data.contexts[t.NODE]),e(t.data.contexts[t.DRAG])}function ZJe(t){var e=t.canvasWidth,r=t.canvasHeight,n=aF(t),i=n.pan,a=n.zoom,s=Zb();j6(s,s,[i.x,i.y]),sF(s,s,[a,a]);var l=Zb();GJe(l,e,r);var u=Zb();return zJe(u,l,s),u}function z1e(t,e){var r=t.canvasWidth,n=t.canvasHeight,i=aF(t),a=i.pan,s=i.zoom;e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,r,n),e.translate(a.x,a.y),e.scale(s,s)}function JJe(t,e){t.drawSelectionRectangle(e,function(r){return z1e(t,r)})}function eet(t){var e=t.data.contexts[t.NODE];e.save(),z1e(t,e),e.strokeStyle="rgba(0, 0, 0, 0.3)",e.beginPath(),e.moveTo(-1e3,0),e.lineTo(1e3,0),e.stroke(),e.beginPath(),e.moveTo(0,-1e3),e.lineTo(0,1e3),e.stroke(),e.restore()}function tet(t){var e=o(function(i,a,s){for(var l=i.atlasManager.getRenderTypeOpts(a),u=t.data.contexts[t.NODE],h=.125,f=l.atlasCollection.atlases,d=0;d=0&&k.add(I)}return k}function net(t,e,r){var n=ret(t,e,r),i=t.getCachedZSortedEles(),a,s,l=vo(n),u;try{for(l.s();!(u=l.n()).done;){var h=u.value,f=i[h];if(!a&&f.isNode()&&(a=f),!s&&f.isEdge()&&(s=f),a&&s)break}}catch(d){l.e(d)}finally{l.f()}return[a,s].filter(Boolean)}function G1e(t,e,r){var n,i;t.webglDebug&&(i=[],n=performance.now());var a=t.eleDrawing,s=0;if(r.screen&&t.data.canvasNeedsRedraw[t.SELECT_BOX]&&JJe(t,e),t.data.canvasNeedsRedraw[t.NODE]||r.picking){var l=o(function(k,L){L+=1,k.isNode()?(a.drawTexture(k,L,"node-underlay"),a.drawTexture(k,L,"node-body"),a.drawTexture(k,L,"node-label"),a.drawTexture(k,L,"node-overlay")):(a.drawEdgeLine(k,L),a.drawEdgeArrow(k,L,"source"),a.drawEdgeArrow(k,L,"target"),a.drawTexture(k,L,"edge-label"))},"draw"),u=t.data.contexts[t.WEBGL];r.screen?(u.clearColor(0,0,0,0),u.enable(u.BLEND),u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA)):u.disable(u.BLEND),u.clear(u.COLOR_BUFFER_BIT|u.DEPTH_BUFFER_BIT),u.viewport(0,0,u.canvas.width,u.canvas.height);var h=ZJe(t),f=t.getCachedZSortedEles();if(s=f.length,a.startFrame(h,i,r),r.screen){for(var d=0;d{"use strict";o(qi,"_typeof");o(Vf,"_classCallCheck");o($0e,"_defineProperties");o(Uf,"_createClass");o(ige,"_defineProperty$1");o(Ri,"_slicedToArray");o(age,"_toConsumableArray");o(lqe,"_arrayWithoutHoles");o(cqe,"_arrayWithHoles");o(uqe,"_iterableToArray");o(hqe,"_iterableToArrayLimit");o(PB,"_unsupportedIterableToArray");o(xB,"_arrayLikeToArray");o(fqe,"_nonIterableSpread");o(dqe,"_nonIterableRest");o(vo,"_createForOfIteratorHelper");Hi=typeof window>"u"?null:window,z0e=Hi?Hi.navigator:null;Hi&&Hi.document;pqe=qi(""),sge=qi({}),mqe=qi(function(){}),gqe=typeof HTMLElement>"u"?"undefined":qi(HTMLElement),h4=o(function(e){return e&&e.instanceString&&li(e.instanceString)?e.instanceString():null},"instanceStr"),Zt=o(function(e){return e!=null&&qi(e)==pqe},"string"),li=o(function(e){return e!=null&&qi(e)===mqe},"fn"),En=o(function(e){return!xo(e)&&(Array.isArray?Array.isArray(e):e!=null&&e instanceof Array)},"array"),Ur=o(function(e){return e!=null&&qi(e)===sge&&!En(e)&&e.constructor===Object},"plainObject"),yqe=o(function(e){return e!=null&&qi(e)===sge},"object"),_t=o(function(e){return e!=null&&qi(e)===qi(1)&&!isNaN(e)},"number"),vqe=o(function(e){return _t(e)&&Math.floor(e)===e},"integer"),F6=o(function(e){if(gqe!=="undefined")return e!=null&&e instanceof HTMLElement},"htmlElement"),xo=o(function(e){return f4(e)||oge(e)},"elementOrCollection"),f4=o(function(e){return h4(e)==="collection"&&e._private.single},"element"),oge=o(function(e){return h4(e)==="collection"&&!e._private.single},"collection"),BB=o(function(e){return h4(e)==="core"},"core"),lge=o(function(e){return h4(e)==="stylesheet"},"stylesheet"),xqe=o(function(e){return h4(e)==="event"},"event"),Pf=o(function(e){return e==null?!0:!!(e===""||e.match(/^\s+$/))},"emptyString"),bqe=o(function(e){return typeof HTMLElement>"u"?!1:e instanceof HTMLElement},"domElement"),Tqe=o(function(e){return Ur(e)&&_t(e.x1)&&_t(e.x2)&&_t(e.y1)&&_t(e.y2)},"boundingBox"),wqe=o(function(e){return yqe(e)&&li(e.then)},"promise"),kqe=o(function(){return z0e&&z0e.userAgent.match(/msie|trident|edge/i)},"ms"),e4=o(function(e,r){r||(r=o(function(){if(arguments.length===1)return arguments[0];if(arguments.length===0)return"undefined";for(var a=[],s=0;sr?1:0},"ascending"),Lqe=o(function(e,r){return-1*uge(e,r)},"descending"),ir=Object.assign!=null?Object.assign.bind(Object):function(t){for(var e=arguments,r=1;r1&&(v-=1),v<1/6?g+(y-g)*6*v:v<1/2?y:v<2/3?g+(y-g)*(2/3-v)*6:g}o(f,"hue2rgb");var d=new RegExp("^"+Cqe+"$").exec(e);if(d){if(n=parseInt(d[1]),n<0?n=(360- -1*n%360)%360:n>360&&(n=n%360),n/=360,i=parseFloat(d[2]),i<0||i>100||(i=i/100,a=parseFloat(d[3]),a<0||a>100)||(a=a/100,s=d[4],s!==void 0&&(s=parseFloat(s),s<0||s>1)))return;if(i===0)l=u=h=Math.round(a*255);else{var p=a<.5?a*(1+i):a+i-a*i,m=2*a-p;l=Math.round(255*f(m,p,n+1/3)),u=Math.round(255*f(m,p,n)),h=Math.round(255*f(m,p,n-1/3))}r=[l,u,h,s]}return r},"hsl2tuple"),Mqe=o(function(e){var r,n=new RegExp("^"+Eqe+"$").exec(e);if(n){r=[];for(var i=[],a=1;a<=3;a++){var s=n[a];if(s[s.length-1]==="%"&&(i[a]=!0),s=parseFloat(s),i[a]&&(s=s/100*255),s<0||s>255)return;r.push(Math.floor(s))}var l=i[1]||i[2]||i[3],u=i[1]&&i[2]&&i[3];if(l&&!u)return;var h=n[4];if(h!==void 0){if(h=parseFloat(h),h<0||h>1)return;r.push(h)}}return r},"rgb2tuple"),Iqe=o(function(e){return Oqe[e.toLowerCase()]},"colorname2tuple"),hge=o(function(e){return(En(e)?e:null)||Iqe(e)||Rqe(e)||Mqe(e)||Nqe(e)},"color2tuple"),Oqe={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},fge=o(function(e){for(var r=e.map,n=e.keys,i=n.length,a=0;a1&&arguments[1]!==void 0?arguments[1]:X1,n=r,i;i=e.next(),!i.done;)n=n*yge+i.value|0;return n},"hashIterableInts"),t4=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:X1;return r*yge+e|0},"hashInt"),r4=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:qb;return(r<<5)+r+e|0},"hashIntAlt"),TYe=o(function(e,r){return e*2097152+r},"combineHashes"),Lf=o(function(e){return e[0]*2097152+e[1]},"combineHashesArray"),m6=o(function(e,r){return[t4(e[0],r[0]),r4(e[1],r[1])]},"hashArrays"),wYe=o(function(e,r){var n={value:0,done:!1},i=0,a=e.length,s={next:o(function(){return i=0&&!(e[i]===r&&(e.splice(i,1),n));i--);},"removeFromArray"),GB=o(function(e){e.splice(0,e.length)},"clearArray"),DYe=o(function(e,r){for(var n=0;n"u"?"undefined":qi(Set))!==RYe?Set:NYe,Z6=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(e===void 0||r===void 0||!BB(e)){oi("An element must have a core reference and parameters set");return}var i=r.group;if(i==null&&(r.data&&r.data.source!=null&&r.data.target!=null?i="edges":i="nodes"),i!=="nodes"&&i!=="edges"){oi("An element must be of type `nodes` or `edges`; you specified `"+i+"`");return}this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:r.data||{},position:r.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:i,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!r.selected,selectable:r.selectable===void 0?!0:!!r.selectable,locked:!!r.locked,grabbed:!1,grabbable:r.grabbable===void 0?!0:!!r.grabbable,pannable:r.pannable===void 0?i==="edges":!!r.pannable,active:!1,classes:new ay,animation:{current:[],queue:[]},rscratch:{},scratch:r.scratch||{},edges:[],children:[],parent:r.parent&&r.parent.isNode()?r.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(a.position.x==null&&(a.position.x=0),a.position.y==null&&(a.position.y=0),r.renderedPosition){var s=r.renderedPosition,l=e.pan(),u=e.zoom();a.position={x:(s.x-l.x)/u,y:(s.y-l.y)/u}}var h=[];En(r.classes)?h=r.classes:Zt(r.classes)&&(h=r.classes.split(/\s+/));for(var f=0,d=h.length;fb?1:0},"defaultCmp"),f=o(function(x,b,T,S,w){var E;if(T==null&&(T=0),w==null&&(w=n),T<0)throw new Error("lo must be non-negative");for(S==null&&(S=x.length);TO;0<=O?D++:D--)C.push(D);return C}.apply(this).reverse(),_=[],S=0,w=E.length;SR;0<=R?++C:--C)k.push(s(x,T));return k},"nsmallest"),y=o(function(x,b,T,S){var w,E,_;for(S==null&&(S=n),w=x[T];T>b;){if(_=T-1>>1,E=x[_],S(w,E)<0){x[T]=E,T=_;continue}break}return x[T]=w},"_siftdown"),v=o(function(x,b,T){var S,w,E,_,C;for(T==null&&(T=n),w=x.length,C=b,E=x[b],S=2*b+1;S0;){var E=b.pop(),_=v(E),C=E.id();if(p[C]=_,_!==1/0)for(var D=E.neighborhood().intersect(g),O=0;O0)for(B.unshift(P);d[z];){var $=d[z];B.unshift($.edge),B.unshift($.node),F=$.node,z=F.id()}return l.spawn(B)},"pathTo")}},"dijkstra")},PYe={kruskal:o(function(e){e=e||function(T){return 1};for(var r=this.byGroup(),n=r.nodes,i=r.edges,a=n.length,s=new Array(a),l=n,u=o(function(S){for(var w=0;w0;){if(w(),_++,S===f){for(var C=[],D=a,O=f,R=x[O];C.unshift(D),R!=null&&C.unshift(R),D=v[O],D!=null;)O=D.id(),R=x[O];return{found:!0,distance:d[S],path:this.spawn(C),steps:_}}m[S]=!0;for(var k=T._private.edges,L=0;LR&&(g[O]=R,b[O]=D,T[O]=w),!a){var k=D*f+C;!a&&g[k]>R&&(g[k]=R,b[k]=C,T[k]=w)}}}for(var L=0;L1&&arguments[1]!==void 0?arguments[1]:s,ye=T(ae),Be=[],He=ye;;){if(He==null)return r.spawn();var ze=b(He),Le=ze.edge,Ie=ze.pred;if(Be.unshift(He[0]),He.same(Oe)&&Be.length>0)break;Le!=null&&Be.unshift(Le),He=Ie}return u.spawn(Be)},"pathTo"),E=0;E=0;f--){var d=h[f],p=d[1],m=d[2];(r[p]===l&&r[m]===u||r[p]===u&&r[m]===l)&&h.splice(f,1)}for(var g=0;gi;){var a=Math.floor(Math.random()*r.length);r=HYe(a,e,r),n--}return r},"contractUntil"),WYe={kargerStein:o(function(){var e=this,r=this.byGroup(),n=r.nodes,i=r.edges;i.unmergeBy(function(B){return B.isLoop()});var a=n.length,s=i.length,l=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),u=Math.floor(a/UYe);if(a<2){oi("At least 2 nodes are required for Karger-Stein algorithm");return}for(var h=[],f=0;f1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=1/0,a=r;a1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=-1/0,a=r;a1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=0,a=0,s=r;s1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,a=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;i?e=e.slice(r,n):(n0&&e.splice(0,r));for(var l=0,u=e.length-1;u>=0;u--){var h=e[u];s?isFinite(h)||(e[u]=-1/0,l++):e.splice(u,1)}a&&e.sort(function(p,m){return p-m});var f=e.length,d=Math.floor(f/2);return f%2!==0?e[d+1+l]:(e[d-1+l]+e[d+l])/2},"median"),QYe=o(function(e){return Math.PI*e/180},"deg2rad"),g6=o(function(e,r){return Math.atan2(r,e)-Math.PI/2},"getAngleFromDisp"),VB=Math.log2||function(t){return Math.log(t)/Math.log(2)},Sge=o(function(e){return e>0?1:e<0?-1:0},"signum"),Qp=o(function(e,r){return Math.sqrt(Wp(e,r))},"dist"),Wp=o(function(e,r){var n=r.x-e.x,i=r.y-e.y;return n*n+i*i},"sqdist"),ZYe=o(function(e){for(var r=e.length,n=0,i=0;i=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(e.w!=null&&e.h!=null&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},"makeBoundingBox"),eXe=o(function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},"copyBoundingBox"),tXe=o(function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},"clearBoundingBox"),rXe=o(function(e,r,n){return{x1:e.x1+r,x2:e.x2+r,y1:e.y1+n,y2:e.y2+n,w:e.w,h:e.h}},"shiftBoundingBox"),Cge=o(function(e,r){e.x1=Math.min(e.x1,r.x1),e.x2=Math.max(e.x2,r.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,r.y1),e.y2=Math.max(e.y2,r.y2),e.h=e.y2-e.y1},"updateBoundingBox"),nXe=o(function(e,r,n){e.x1=Math.min(e.x1,r),e.x2=Math.max(e.x2,r),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},"expandBoundingBoxByPoint"),D6=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return e.x1-=r,e.x2+=r,e.y1-=r,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBox"),L6=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[0],n,i,a,s;if(r.length===1)n=i=a=s=r[0];else if(r.length===2)n=a=r[0],s=i=r[1];else if(r.length===4){var l=Ri(r,4);n=l[0],i=l[1],a=l[2],s=l[3]}return e.x1-=s,e.x2+=i,e.y1-=n,e.y2+=a,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBoxSides"),X0e=o(function(e,r){e.x1=r.x1,e.y1=r.y1,e.x2=r.x2,e.y2=r.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},"assignBoundingBox"),UB=o(function(e,r){return!(e.x1>r.x2||r.x1>e.x2||e.x2r.y2||r.y1>e.y2)},"boundingBoxesIntersect"),ry=o(function(e,r,n){return e.x1<=r&&r<=e.x2&&e.y1<=n&&n<=e.y2},"inBoundingBox"),iXe=o(function(e,r){return ry(e,r.x,r.y)},"pointInBoundingBox"),Age=o(function(e,r){return ry(e,r.x1,r.y1)&&ry(e,r.x2,r.y2)},"boundingBoxInBoundingBox"),_ge=o(function(e,r,n,i,a,s,l){var u=arguments.length>7&&arguments[7]!==void 0?arguments[7]:"auto",h=u==="auto"?Zp(a,s):u,f=a/2,d=s/2;h=Math.min(h,f,d);var p=h!==f,m=h!==d,g;if(p){var y=n-f+h-l,v=i-d-l,x=n+f-h+l,b=v;if(g=Mf(e,r,n,i,y,v,x,b,!1),g.length>0)return g}if(m){var T=n+f+l,S=i-d+h-l,w=T,E=i+d-h+l;if(g=Mf(e,r,n,i,T,S,w,E,!1),g.length>0)return g}if(p){var _=n-f+h-l,C=i+d+l,D=n+f-h+l,O=C;if(g=Mf(e,r,n,i,_,C,D,O,!1),g.length>0)return g}if(m){var R=n-f-l,k=i-d+h-l,L=R,A=i+d-h+l;if(g=Mf(e,r,n,i,R,k,L,A,!1),g.length>0)return g}var I;{var M=n-f+h,P=i-d+h;if(I=Yb(e,r,n,i,M,P,h+l),I.length>0&&I[0]<=M&&I[1]<=P)return[I[0],I[1]]}{var B=n+f-h,F=i-d+h;if(I=Yb(e,r,n,i,B,F,h+l),I.length>0&&I[0]>=B&&I[1]<=F)return[I[0],I[1]]}{var z=n+f-h,$=i+d-h;if(I=Yb(e,r,n,i,z,$,h+l),I.length>0&&I[0]>=z&&I[1]>=$)return[I[0],I[1]]}{var U=n-f+h,K=i+d-h;if(I=Yb(e,r,n,i,U,K,h+l),I.length>0&&I[0]<=U&&I[1]>=K)return[I[0],I[1]]}return[]},"roundRectangleIntersectLine"),aXe=o(function(e,r,n,i,a,s,l){var u=l,h=Math.min(n,a),f=Math.max(n,a),d=Math.min(i,s),p=Math.max(i,s);return h-u<=e&&e<=f+u&&d-u<=r&&r<=p+u},"inLineVicinity"),sXe=o(function(e,r,n,i,a,s,l,u,h){var f={x1:Math.min(n,l,a)-h,x2:Math.max(n,l,a)+h,y1:Math.min(i,u,s)-h,y2:Math.max(i,u,s)+h};return!(ef.x2||rf.y2)},"inBezierVicinity"),oXe=o(function(e,r,n,i){n-=i;var a=r*r-4*e*n;if(a<0)return[];var s=Math.sqrt(a),l=2*e,u=(-r+s)/l,h=(-r-s)/l;return[u,h]},"solveQuadratic"),lXe=o(function(e,r,n,i,a){var s=1e-5;e===0&&(e=s),r/=e,n/=e,i/=e;var l,u,h,f,d,p,m,g;if(u=(3*n-r*r)/9,h=-(27*i)+r*(9*n-2*(r*r)),h/=54,l=u*u*u+h*h,a[1]=0,m=r/3,l>0){d=h+Math.sqrt(l),d=d<0?-Math.pow(-d,1/3):Math.pow(d,1/3),p=h-Math.sqrt(l),p=p<0?-Math.pow(-p,1/3):Math.pow(p,1/3),a[0]=-m+d+p,m+=(d+p)/2,a[4]=a[2]=-m,m=Math.sqrt(3)*(-p+d)/2,a[3]=m,a[5]=-m;return}if(a[5]=a[3]=0,l===0){g=h<0?-Math.pow(-h,1/3):Math.pow(h,1/3),a[0]=-m+2*g,a[4]=a[2]=-(g+m);return}u=-u,f=u*u*u,f=Math.acos(h/Math.sqrt(f)),g=2*Math.sqrt(u),a[0]=-m+g*Math.cos(f/3),a[2]=-m+g*Math.cos((f+2*Math.PI)/3),a[4]=-m+g*Math.cos((f+4*Math.PI)/3)},"solveCubic"),cXe=o(function(e,r,n,i,a,s,l,u){var h=1*n*n-4*n*a+2*n*l+4*a*a-4*a*l+l*l+i*i-4*i*s+2*i*u+4*s*s-4*s*u+u*u,f=1*9*n*a-3*n*n-3*n*l-6*a*a+3*a*l+9*i*s-3*i*i-3*i*u-6*s*s+3*s*u,d=1*3*n*n-6*n*a+n*l-n*e+2*a*a+2*a*e-l*e+3*i*i-6*i*s+i*u-i*r+2*s*s+2*s*r-u*r,p=1*n*a-n*n+n*e-a*e+i*s-i*i+i*r-s*r,m=[];lXe(h,f,d,p,m);for(var g=1e-7,y=[],v=0;v<6;v+=2)Math.abs(m[v+1])=0&&m[v]<=1&&y.push(m[v]);y.push(1),y.push(0);for(var x=-1,b,T,S,w=0;w=0?Sh?(e-a)*(e-a)+(r-s)*(r-s):f-p},"sqdistToFiniteLine"),qs=o(function(e,r,n){for(var i,a,s,l,u,h=0,f=0;f=e&&e>=s||i<=e&&e<=s)u=(e-i)/(s-i)*(l-a)+a,u>r&&h++;else continue;return h%2!==0},"pointInsidePolygonPoints"),ih=o(function(e,r,n,i,a,s,l,u,h){var f=new Array(n.length),d;u[0]!=null?(d=Math.atan(u[1]/u[0]),u[0]<0?d=d+Math.PI/2:d=-d-Math.PI/2):d=u;for(var p=Math.cos(-d),m=Math.sin(-d),g=0;g0){var v=V6(f,-h);y=G6(v)}else y=f;return qs(e,r,y)},"pointInsidePolygon"),hXe=o(function(e,r,n,i,a,s,l,u){for(var h=new Array(n.length*2),f=0;f=0&&v<=1&&b.push(v),x>=0&&x<=1&&b.push(x),b.length===0)return[];var T=b[0]*u[0]+e,S=b[0]*u[1]+r;if(b.length>1){if(b[0]==b[1])return[T,S];var w=b[1]*u[0]+e,E=b[1]*u[1]+r;return[T,S,w,E]}else return[T,S]},"intersectLineCircle"),sB=o(function(e,r,n){return r<=e&&e<=n||n<=e&&e<=r?e:e<=r&&r<=n||n<=r&&r<=e?r:n},"midOfThree"),Mf=o(function(e,r,n,i,a,s,l,u,h){var f=e-a,d=n-e,p=l-a,m=r-s,g=i-r,y=u-s,v=p*m-y*f,x=d*m-g*f,b=y*d-p*g;if(b!==0){var T=v/b,S=x/b,w=.001,E=0-w,_=1+w;return E<=T&&T<=_&&E<=S&&S<=_?[e+T*d,r+T*g]:h?[e+T*d,r+T*g]:[]}else return v===0||x===0?sB(e,n,l)===l?[l,u]:sB(e,n,a)===a?[a,s]:sB(a,l,n)===n?[n,i]:[]:[]},"finiteLinesIntersect"),a4=o(function(e,r,n,i,a,s,l,u){var h=[],f,d=new Array(n.length),p=!0;s==null&&(p=!1);var m;if(p){for(var g=0;g0){var y=V6(d,-u);m=G6(y)}else m=d}else m=n;for(var v,x,b,T,S=0;S2){for(var g=[f[0],f[1]],y=Math.pow(g[0]-e,2)+Math.pow(g[1]-r,2),v=1;vf&&(f=S)},"set"),get:o(function(T){return h[T]},"get")},p=0;p0?M=I.edgesTo(A)[0]:M=A.edgesTo(I)[0];var P=i(M);A=A.id(),C[A]>C[k]+P&&(C[A]=C[k]+P,D.nodes.indexOf(A)<0?D.push(A):D.updateItem(A),_[A]=0,E[A]=[]),C[A]==C[k]+P&&(_[A]=_[A]+_[k],E[A].push(k))}else for(var B=0;B0;){for(var U=w.pop(),K=0;K0&&l.push(n[u]);l.length!==0&&a.push(i.collection(l))}return a},"assign"),AXe=o(function(e,r){for(var n=0;n5&&arguments[5]!==void 0?arguments[5]:LXe,l=i,u,h,f=0;f=2?$b(e,r,n,0,J0e,RXe):$b(e,r,n,0,Z0e)},"euclidean"),squaredEuclidean:o(function(e,r,n){return $b(e,r,n,0,J0e)},"squaredEuclidean"),manhattan:o(function(e,r,n){return $b(e,r,n,0,Z0e)},"manhattan"),max:o(function(e,r,n){return $b(e,r,n,-1/0,NXe)},"max")};ny["squared-euclidean"]=ny.squaredEuclidean;ny.squaredeuclidean=ny.squaredEuclidean;o(eC,"clusteringDistance");MXe=oa({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),WB=o(function(e){return MXe(e)},"setOptions"),U6=o(function(e,r,n,i,a){var s=a!=="kMedoids",l=s?function(d){return n[d]}:function(d){return i[d](n)},u=o(function(p){return i[p](r)},"getQ"),h=n,f=r;return eC(e,i.length,l,u,h,f)},"getDist"),oB=o(function(e,r,n){for(var i=n.length,a=new Array(i),s=new Array(i),l=new Array(r),u=null,h=0;hn)return!1}return!0},"haveMatricesConverged"),PXe=o(function(e,r,n){for(var i=0;il&&(l=r[h][f],u=f);a[u].push(e[h])}for(var d=0;d=a.threshold||a.mode==="dendrogram"&&e.length===1)return!1;var g=r[s],y=r[i[s]],v;a.mode==="dendrogram"?v={left:g,right:y,key:g.key}:v={value:g.value.concat(y.value),key:g.key},e[g.index]=v,e.splice(y.index,1),r[g.key]=v;for(var x=0;xn[y.key][b.key]&&(u=n[y.key][b.key])):a.linkage==="max"?(u=n[g.key][b.key],n[g.key][b.key]0&&i.push(a);return i},"findExemplars"),ame=o(function(e,r,n){for(var i=[],a=0;al&&(s=h,l=r[a*e+h])}s>0&&i.push(s)}for(var f=0;fh&&(u=f,h=d)}n[a]=s[u]}return i=ame(e,r,n),i},"assign"),sme=o(function(e){for(var r=this.cy(),n=this.nodes(),i=KXe(e),a={},s=0;s=R?(k=R,R=A,L=I):A>k&&(k=A);for(var M=0;M0?1:0;_[D%i.minIterations*l+U]=K,$+=K}if($>0&&(D>=i.minIterations-1||D==i.maxIterations-1)){for(var ee=0,Y=0;Y1||E>1)&&(l=!0),d[T]=[],b.outgoers().forEach(function(C){C.isEdge()&&d[T].push(C.id())})}else p[T]=[void 0,b.target().id()]}):s.forEach(function(b){var T=b.id();if(b.isNode()){var S=b.degree(!0);S%2&&(u?h?l=!0:h=T:u=T),d[T]=[],b.connectedEdges().forEach(function(w){return d[T].push(w.id())})}else p[T]=[b.source().id(),b.target().id()]});var m={found:!1,trail:void 0};if(l)return m;if(h&&u)if(a){if(f&&h!=f)return m;f=h}else{if(f&&h!=f&&u!=f)return m;f||(f=h)}else f||(f=s[0].id());var g=o(function(T){for(var S=T,w=[T],E,_,C;d[S].length;)E=d[S].shift(),_=p[E][0],C=p[E][1],S!=C?(d[C]=d[C].filter(function(D){return D!=E}),S=C):!a&&S!=_&&(d[_]=d[_].filter(function(D){return D!=E}),S=_),w.unshift(E),w.unshift(S);return w},"walk"),y=[],v=[];for(v=g(f);v.length!=1;)d[v[0]].length==0?(y.unshift(s.getElementById(v.shift())),y.unshift(s.getElementById(v.shift()))):v=g(v.shift()).concat(v);y.unshift(s.getElementById(v.shift()));for(var x in d)if(d[x].length)return m;return m.found=!0,m.trail=this.spawn(y,!0),m},"hierholzer")},x6=o(function(){var e=this,r={},n=0,i=0,a=[],s=[],l={},u=o(function(p,m){for(var g=s.length-1,y=[],v=e.spawn();s[g].x!=p||s[g].y!=m;)y.push(s.pop().edge),g--;y.push(s.pop().edge),y.forEach(function(x){var b=x.connectedNodes().intersection(e);v.merge(x),b.forEach(function(T){var S=T.id(),w=T.connectedEdges().intersection(e);v.merge(T),r[S].cutVertex?v.merge(w.filter(function(E){return E.isLoop()})):v.merge(w)})}),a.push(v)},"buildComponent"),h=o(function d(p,m,g){p===g&&(i+=1),r[m]={id:n,low:n++,cutVertex:!1};var y=e.getElementById(m).connectedEdges().intersection(e);if(y.size()===0)a.push(e.spawn(e.getElementById(m)));else{var v,x,b,T;y.forEach(function(S){v=S.source().id(),x=S.target().id(),b=v===m?x:v,b!==g&&(T=S.id(),l[T]||(l[T]=!0,s.push({x:m,y:b,edge:S})),b in r?r[m].low=Math.min(r[m].low,r[b].id):(d(p,b,m),r[m].low=Math.min(r[m].low,r[b].low),r[m].id<=r[b].low&&(r[m].cutVertex=!0,u(m,b))))})}},"biconnectedSearch");e.forEach(function(d){if(d.isNode()){var p=d.id();p in r||(i=0,h(p,p),r[p].cutVertex=i>1)}});var f=Object.keys(r).filter(function(d){return r[d].cutVertex}).map(function(d){return e.getElementById(d)});return{cut:e.spawn(f),components:a}},"hopcroftTarjanBiconnected"),ije={hopcroftTarjanBiconnected:x6,htbc:x6,htb:x6,hopcroftTarjanBiconnectedComponents:x6},b6=o(function(){var e=this,r={},n=0,i=[],a=[],s=e.spawn(e),l=o(function u(h){a.push(h),r[h]={index:n,low:n++,explored:!1};var f=e.getElementById(h).connectedEdges().intersection(e);if(f.forEach(function(y){var v=y.target().id();v!==h&&(v in r||u(v),r[v].explored||(r[h].low=Math.min(r[h].low,r[v].low)))}),r[h].index===r[h].low){for(var d=e.spawn();;){var p=a.pop();if(d.merge(e.getElementById(p)),r[p].low=r[h].index,r[p].explored=!0,p===h)break}var m=d.edgesWith(d),g=d.merge(m);i.push(g),s=s.difference(g)}},"stronglyConnectedSearch");return e.forEach(function(u){if(u.isNode()){var h=u.id();h in r||l(h)}}),{cut:s,components:i}},"tarjanStronglyConnected"),aje={tarjanStronglyConnected:b6,tsc:b6,tscc:b6,tarjanStronglyConnectedComponents:b6},Oge={};[n4,OYe,PYe,FYe,zYe,VYe,WYe,gXe,Z1,J1,wB,DXe,VXe,XXe,tje,nje,ije,aje].forEach(function(t){ir(Oge,t)});Pge=0,Bge=1,Fge=2,ah=o(function t(e){if(!(this instanceof t))return new t(e);this.id="Thenable/1.0.7",this.state=Pge,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},typeof e=="function"&&e.call(this,this.fulfill.bind(this),this.reject.bind(this))},"api");ah.prototype={fulfill:o(function(e){return ome(this,Bge,"fulfillValue",e)},"fulfill"),reject:o(function(e){return ome(this,Fge,"rejectReason",e)},"reject"),then:o(function(e,r){var n=this,i=new ah;return n.onFulfilled.push(cme(e,i,"fulfill")),n.onRejected.push(cme(r,i,"reject")),$ge(n),i.proxy},"then")};ome=o(function(e,r,n,i){return e.state===Pge&&(e.state=r,e[n]=i,$ge(e)),e},"deliver"),$ge=o(function(e){e.state===Bge?lme(e,"onFulfilled",e.fulfillValue):e.state===Fge&&lme(e,"onRejected",e.rejectReason)},"execute"),lme=o(function(e,r,n){if(e[r].length!==0){var i=e[r];e[r]=[];var a=o(function(){for(var l=0;l0},"animatedImpl")},"animated"),clearQueue:o(function(){return o(function(){var r=this,n=r.length!==void 0,i=n?r:[r],a=this._private.cy||this;if(!a.styleEnabled())return this;for(var s=0;s0&&this.spawn(i).updateStyle().emit("class"),r},"classes"),addClass:o(function(e){return this.toggleClass(e,!0)},"addClass"),hasClass:o(function(e){var r=this[0];return r!=null&&r._private.classes.has(e)},"hasClass"),toggleClass:o(function(e,r){En(e)||(e=e.match(/\S+/g)||[]);for(var n=this,i=r===void 0,a=[],s=0,l=n.length;s0&&this.spawn(a).updateStyle().emit("class"),n},"toggleClass"),removeClass:o(function(e){return this.toggleClass(e,!1)},"removeClass"),flashClass:o(function(e,r){var n=this;if(r==null)r=250;else if(r===0)return n;return n.addClass(e),setTimeout(function(){n.removeClass(e)},r),n},"flashClass")};R6.className=R6.classNames=R6.classes;Vr={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:`"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'`,number:Wi,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Vr.variable="(?:[\\w-.]|(?:\\\\"+Vr.metaChar+"))+";Vr.className="(?:[\\w-]|(?:\\\\"+Vr.metaChar+"))+";Vr.value=Vr.string+"|"+Vr.number;Vr.id=Vr.variable;(function(){var t,e,r;for(t=Vr.comparatorOp.split("|"),r=0;r=0)&&e!=="="&&(Vr.comparatorOp+="|\\!"+e)})();gn=o(function(){return{checks:[]}},"newQuery"),$t={GROUP:0,COLLECTION:1,FILTER:2,DATA_COMPARE:3,DATA_EXIST:4,DATA_BOOL:5,META_COMPARE:6,STATE:7,ID:8,CLASS:9,UNDIRECTED_EDGE:10,DIRECTED_EDGE:11,NODE_SOURCE:12,NODE_TARGET:13,NODE_NEIGHBOR:14,CHILD:15,DESCENDANT:16,PARENT:17,ANCESTOR:18,COMPOUND_SPLIT:19,TRUE:20},EB=[{selector:":selected",matches:o(function(e){return e.selected()},"matches")},{selector:":unselected",matches:o(function(e){return!e.selected()},"matches")},{selector:":selectable",matches:o(function(e){return e.selectable()},"matches")},{selector:":unselectable",matches:o(function(e){return!e.selectable()},"matches")},{selector:":locked",matches:o(function(e){return e.locked()},"matches")},{selector:":unlocked",matches:o(function(e){return!e.locked()},"matches")},{selector:":visible",matches:o(function(e){return e.visible()},"matches")},{selector:":hidden",matches:o(function(e){return!e.visible()},"matches")},{selector:":transparent",matches:o(function(e){return e.transparent()},"matches")},{selector:":grabbed",matches:o(function(e){return e.grabbed()},"matches")},{selector:":free",matches:o(function(e){return!e.grabbed()},"matches")},{selector:":removed",matches:o(function(e){return e.removed()},"matches")},{selector:":inside",matches:o(function(e){return!e.removed()},"matches")},{selector:":grabbable",matches:o(function(e){return e.grabbable()},"matches")},{selector:":ungrabbable",matches:o(function(e){return!e.grabbable()},"matches")},{selector:":animated",matches:o(function(e){return e.animated()},"matches")},{selector:":unanimated",matches:o(function(e){return!e.animated()},"matches")},{selector:":parent",matches:o(function(e){return e.isParent()},"matches")},{selector:":childless",matches:o(function(e){return e.isChildless()},"matches")},{selector:":child",matches:o(function(e){return e.isChild()},"matches")},{selector:":orphan",matches:o(function(e){return e.isOrphan()},"matches")},{selector:":nonorphan",matches:o(function(e){return e.isChild()},"matches")},{selector:":compound",matches:o(function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()},"matches")},{selector:":loop",matches:o(function(e){return e.isLoop()},"matches")},{selector:":simple",matches:o(function(e){return e.isSimple()},"matches")},{selector:":active",matches:o(function(e){return e.active()},"matches")},{selector:":inactive",matches:o(function(e){return!e.active()},"matches")},{selector:":backgrounding",matches:o(function(e){return e.backgrounding()},"matches")},{selector:":nonbackgrounding",matches:o(function(e){return!e.backgrounding()},"matches")}].sort(function(t,e){return Lqe(t.selector,e.selector)}),vQe=function(){for(var t={},e,r=0;r0&&f.edgeCount>0)return hn("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(f.edgeCount>1)return hn("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;f.edgeCount===1&&hn("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},"parse"),EQe=o(function(){if(this.toStringCache!=null)return this.toStringCache;for(var e=o(function(f){return f??""},"clean"),r=o(function(f){return Zt(f)?'"'+f+'"':e(f)},"cleanVal"),n=o(function(f){return" "+f+" "},"space"),i=o(function(f,d){var p=f.type,m=f.value;switch(p){case $t.GROUP:{var g=e(m);return g.substring(0,g.length-1)}case $t.DATA_COMPARE:{var y=f.field,v=f.operator;return"["+y+n(e(v))+r(m)+"]"}case $t.DATA_BOOL:{var x=f.operator,b=f.field;return"["+e(x)+b+"]"}case $t.DATA_EXIST:{var T=f.field;return"["+T+"]"}case $t.META_COMPARE:{var S=f.operator,w=f.field;return"[["+w+n(e(S))+r(m)+"]]"}case $t.STATE:return m;case $t.ID:return"#"+m;case $t.CLASS:return"."+m;case $t.PARENT:case $t.CHILD:return a(f.parent,d)+n(">")+a(f.child,d);case $t.ANCESTOR:case $t.DESCENDANT:return a(f.ancestor,d)+" "+a(f.descendant,d);case $t.COMPOUND_SPLIT:{var E=a(f.left,d),_=a(f.subject,d),C=a(f.right,d);return E+(E.length>0?" ":"")+_+C}case $t.TRUE:return""}},"checkToString"),a=o(function(f,d){return f.checks.reduce(function(p,m,g){return p+(d===f&&g===0?"$":"")+i(m,d)},"")},"queryToString"),s="",l=0;l1&&l=0&&(r=r.replace("!",""),d=!0),r.indexOf("@")>=0&&(r=r.replace("@",""),f=!0),(a||l||f)&&(u=!a&&!s?"":""+e,h=""+n),f&&(e=u=u.toLowerCase(),n=h=h.toLowerCase()),r){case"*=":i=u.indexOf(h)>=0;break;case"$=":i=u.indexOf(h,u.length-h.length)>=0;break;case"^=":i=u.indexOf(h)===0;break;case"=":i=e===n;break;case">":p=!0,i=e>n;break;case">=":p=!0,i=e>=n;break;case"<":p=!0,i=e1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,Xge)};o(jge,"addParent");iy.forEachUp=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,jge)};o(NQe,"addParentAndChildren");iy.forEachUpAndDown=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,NQe)};iy.ancestors=iy.parents;o4=Kge={data:un.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:un.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:un.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:un.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:un.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:un.removeData({field:"rscratch",triggerEvent:!1}),id:o(function(){var e=this[0];if(e)return e._private.data.id},"id")};o4.attr=o4.data;o4.removeAttr=o4.removeData;MQe=Kge,iC={};o(cB,"defineDegreeFunction");ir(iC,{degree:cB(function(t,e){return e.source().same(e.target())?2:1}),indegree:cB(function(t,e){return e.target().same(t)?1:0}),outdegree:cB(function(t,e){return e.source().same(t)?1:0})});o(H1,"defineDegreeBoundsFunction");ir(iC,{minDegree:H1("degree",function(t,e){return te}),minIndegree:H1("indegree",function(t,e){return te}),minOutdegree:H1("outdegree",function(t,e){return te})});ir(iC,{totalDegree:o(function(e){for(var r=0,n=this.nodes(),i=0;i0,p=d;d&&(f=f[0]);var m=p?f.position():{x:0,y:0};r!==void 0?h.position(e,r+m[e]):a!==void 0&&h.position({x:a.x+m.x,y:a.y+m.y})}else{var g=n.position(),y=l?n.parent():null,v=y&&y.length>0,x=v;v&&(y=y[0]);var b=x?y.position():{x:0,y:0};return a={x:g.x-b.x,y:g.y-b.y},e===void 0?a:a[e]}else if(!s)return;return this},"relativePosition")};ql.modelPosition=ql.point=ql.position;ql.modelPositions=ql.points=ql.positions;ql.renderedPoint=ql.renderedPosition;ql.relativePoint=ql.relativePosition;IQe=Qge;ey=Hf={};Hf.renderedBoundingBox=function(t){var e=this.boundingBox(t),r=this.cy(),n=r.zoom(),i=r.pan(),a=e.x1*n+i.x,s=e.x2*n+i.x,l=e.y1*n+i.y,u=e.y2*n+i.y;return{x1:a,x2:s,y1:l,y2:u,w:s-a,h:u-l}};Hf.dirtyCompoundBoundsCache=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();return!e.styleEnabled()||!e.hasCompoundNodes()?this:(this.forEachUp(function(r){if(r.isParent()){var n=r._private;n.compoundBoundsClean=!1,n.bbCache=null,t||r.emitAndNotify("bounds")}}),this)};Hf.updateCompoundBounds=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();if(!e.styleEnabled()||!e.hasCompoundNodes())return this;if(!t&&e.batching())return this;function r(s){if(!s.isParent())return;var l=s._private,u=s.children(),h=s.pstyle("compound-sizing-wrt-labels").value==="include",f={width:{val:s.pstyle("min-width").pfValue,left:s.pstyle("min-width-bias-left"),right:s.pstyle("min-width-bias-right")},height:{val:s.pstyle("min-height").pfValue,top:s.pstyle("min-height-bias-top"),bottom:s.pstyle("min-height-bias-bottom")}},d=u.boundingBox({includeLabels:h,includeOverlays:!1,useCache:!1}),p=l.position;(d.w===0||d.h===0)&&(d={w:s.pstyle("width").pfValue,h:s.pstyle("height").pfValue},d.x1=p.x-d.w/2,d.x2=p.x+d.w/2,d.y1=p.y-d.h/2,d.y2=p.y+d.h/2);function m(D,O,R){var k=0,L=0,A=O+R;return D>0&&A>0&&(k=O/A*D,L=R/A*D),{biasDiff:k,biasComplementDiff:L}}o(m,"computeBiasValues");function g(D,O,R,k){if(R.units==="%")switch(k){case"width":return D>0?R.pfValue*D:0;case"height":return O>0?R.pfValue*O:0;case"average":return D>0&&O>0?R.pfValue*(D+O)/2:0;case"min":return D>0&&O>0?D>O?R.pfValue*O:R.pfValue*D:0;case"max":return D>0&&O>0?D>O?R.pfValue*D:R.pfValue*O:0;default:return 0}else return R.units==="px"?R.pfValue:0}o(g,"computePaddingValues");var y=f.width.left.value;f.width.left.units==="px"&&f.width.val>0&&(y=y*100/f.width.val);var v=f.width.right.value;f.width.right.units==="px"&&f.width.val>0&&(v=v*100/f.width.val);var x=f.height.top.value;f.height.top.units==="px"&&f.height.val>0&&(x=x*100/f.height.val);var b=f.height.bottom.value;f.height.bottom.units==="px"&&f.height.val>0&&(b=b*100/f.height.val);var T=m(f.width.val-d.w,y,v),S=T.biasDiff,w=T.biasComplementDiff,E=m(f.height.val-d.h,x,b),_=E.biasDiff,C=E.biasComplementDiff;l.autoPadding=g(d.w,d.h,s.pstyle("padding"),s.pstyle("padding-relative-to").value),l.autoWidth=Math.max(d.w,f.width.val),p.x=(-S+d.x1+d.x2+w)/2,l.autoHeight=Math.max(d.h,f.height.val),p.y=(-_+d.y1+d.y2+C)/2}o(r,"update");for(var n=0;ne.x2?i:e.x2,e.y1=ne.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},"updateBounds"),qp=o(function(e,r){return r==null?e:Hl(e,r.x1,r.y1,r.x2,r.y2)},"updateBoundsFromBox"),zb=o(function(e,r,n){return Wl(e,r,n)},"prefixedProperty"),T6=o(function(e,r,n){if(!r.cy().headless()){var i=r._private,a=i.rstyle,s=a.arrowWidth/2,l=r.pstyle(n+"-arrow-shape").value,u,h;if(l!=="none"){n==="source"?(u=a.srcX,h=a.srcY):n==="target"?(u=a.tgtX,h=a.tgtY):(u=a.midX,h=a.midY);var f=i.arrowBounds=i.arrowBounds||{},d=f[n]=f[n]||{};d.x1=u-s,d.y1=h-s,d.x2=u+s,d.y2=h+s,d.w=d.x2-d.x1,d.h=d.y2-d.y1,D6(d,1),Hl(e,d.x1,d.y1,d.x2,d.y2)}}},"updateBoundsFromArrow"),uB=o(function(e,r,n){if(!r.cy().headless()){var i;n?i=n+"-":i="";var a=r._private,s=a.rstyle,l=r.pstyle(i+"label").strValue;if(l){var u=r.pstyle("text-halign"),h=r.pstyle("text-valign"),f=zb(s,"labelWidth",n),d=zb(s,"labelHeight",n),p=zb(s,"labelX",n),m=zb(s,"labelY",n),g=r.pstyle(i+"text-margin-x").pfValue,y=r.pstyle(i+"text-margin-y").pfValue,v=r.isEdge(),x=r.pstyle(i+"text-rotation"),b=r.pstyle("text-outline-width").pfValue,T=r.pstyle("text-border-width").pfValue,S=T/2,w=r.pstyle("text-background-padding").pfValue,E=2,_=d,C=f,D=C/2,O=_/2,R,k,L,A;if(v)R=p-D,k=p+D,L=m-O,A=m+O;else{switch(u.value){case"left":R=p-C,k=p;break;case"center":R=p-D,k=p+D;break;case"right":R=p,k=p+C;break}switch(h.value){case"top":L=m-_,A=m;break;case"center":L=m-O,A=m+O;break;case"bottom":L=m,A=m+_;break}}var I=g-Math.max(b,S)-w-E,M=g+Math.max(b,S)+w+E,P=y-Math.max(b,S)-w-E,B=y+Math.max(b,S)+w+E;R+=I,k+=M,L+=P,A+=B;var F=n||"main",z=a.labelBounds,$=z[F]=z[F]||{};$.x1=R,$.y1=L,$.x2=k,$.y2=A,$.w=k-R,$.h=A-L,$.leftPad=I,$.rightPad=M,$.topPad=P,$.botPad=B;var U=v&&x.strValue==="autorotate",K=x.pfValue!=null&&x.pfValue!==0;if(U||K){var ee=U?zb(a.rstyle,"labelAngle",n):x.pfValue,Y=Math.cos(ee),ce=Math.sin(ee),Z=(R+k)/2,ue=(L+A)/2;if(!v){switch(u.value){case"left":Z=k;break;case"right":Z=R;break}switch(h.value){case"top":ue=A;break;case"bottom":ue=L;break}}var Q=o(function(se,ae){return se=se-Z,ae=ae-ue,{x:se*Y-ae*ce+Z,y:se*ce+ae*Y+ue}},"rotate"),j=Q(R,L),ne=Q(R,A),te=Q(k,L),he=Q(k,A);R=Math.min(j.x,ne.x,te.x,he.x),k=Math.max(j.x,ne.x,te.x,he.x),L=Math.min(j.y,ne.y,te.y,he.y),A=Math.max(j.y,ne.y,te.y,he.y)}var le=F+"Rot",J=z[le]=z[le]||{};J.x1=R,J.y1=L,J.x2=k,J.y2=A,J.w=k-R,J.h=A-L,Hl(e,R,L,k,A),Hl(a.labelBounds.all,R,L,k,A)}return e}},"updateBoundsFromLabel"),OQe=o(function(e,r){if(!r.cy().headless()){var n=r.pstyle("outline-opacity").value,i=r.pstyle("outline-width").value;if(n>0&&i>0){var a=r.pstyle("outline-offset").value,s=r.pstyle("shape").value,l=i+a,u=(e.w+l*2)/e.w,h=(e.h+l*2)/e.h,f=0,d=0;["diamond","pentagon","round-triangle"].includes(s)?(u=(e.w+l*2.4)/e.w,d=-l/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(s)?u=(e.w+l*2.4)/e.w:s==="star"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.6)/e.h,d=-l/3.8):s==="triangle"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.4)/e.h,d=-l/1.4):s==="vee"&&(u=(e.w+l*4.4)/e.w,h=(e.h+l*3.8)/e.h,d=-l*.5);var p=e.h*h-e.h,m=e.w*u-e.w;if(L6(e,[Math.ceil(p/2),Math.ceil(m/2)]),f!=0||d!==0){var g=rXe(e,f,d);Cge(e,g)}}}},"updateBoundsFromOutline"),PQe=o(function(e,r){var n=e._private.cy,i=n.styleEnabled(),a=n.headless(),s=Ys(),l=e._private,u=e.isNode(),h=e.isEdge(),f,d,p,m,g,y,v=l.rstyle,x=u&&i?e.pstyle("bounds-expansion").pfValue:[0],b=o(function(Se){return Se.pstyle("display").value!=="none"},"isDisplayed"),T=!i||b(e)&&(!h||b(e.source())&&b(e.target()));if(T){var S=0,w=0;i&&r.includeOverlays&&(S=e.pstyle("overlay-opacity").value,S!==0&&(w=e.pstyle("overlay-padding").value));var E=0,_=0;i&&r.includeUnderlays&&(E=e.pstyle("underlay-opacity").value,E!==0&&(_=e.pstyle("underlay-padding").value));var C=Math.max(w,_),D=0,O=0;if(i&&(D=e.pstyle("width").pfValue,O=D/2),u&&r.includeNodes){var R=e.position();g=R.x,y=R.y;var k=e.outerWidth(),L=k/2,A=e.outerHeight(),I=A/2;f=g-L,d=g+L,p=y-I,m=y+I,Hl(s,f,p,d,m),i&&r.includeOutlines&&OQe(s,e)}else if(h&&r.includeEdges)if(i&&!a){var M=e.pstyle("curve-style").strValue;if(f=Math.min(v.srcX,v.midX,v.tgtX),d=Math.max(v.srcX,v.midX,v.tgtX),p=Math.min(v.srcY,v.midY,v.tgtY),m=Math.max(v.srcY,v.midY,v.tgtY),f-=O,d+=O,p-=O,m+=O,Hl(s,f,p,d,m),M==="haystack"){var P=v.haystackPts;if(P&&P.length===2){if(f=P[0].x,p=P[0].y,d=P[1].x,m=P[1].y,f>d){var B=f;f=d,d=B}if(p>m){var F=p;p=m,m=F}Hl(s,f-O,p-O,d+O,m+O)}}else if(M==="bezier"||M==="unbundled-bezier"||M.endsWith("segments")||M.endsWith("taxi")){var z;switch(M){case"bezier":case"unbundled-bezier":z=v.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":z=v.linePts;break}if(z!=null)for(var $=0;$d){var Z=f;f=d,d=Z}if(p>m){var ue=p;p=m,m=ue}f-=O,d+=O,p-=O,m+=O,Hl(s,f,p,d,m)}if(i&&r.includeEdges&&h&&(T6(s,e,"mid-source"),T6(s,e,"mid-target"),T6(s,e,"source"),T6(s,e,"target")),i){var Q=e.pstyle("ghost").value==="yes";if(Q){var j=e.pstyle("ghost-offset-x").pfValue,ne=e.pstyle("ghost-offset-y").pfValue;Hl(s,s.x1+j,s.y1+ne,s.x2+j,s.y2+ne)}}var te=l.bodyBounds=l.bodyBounds||{};X0e(te,s),L6(te,x),D6(te,1),i&&(f=s.x1,d=s.x2,p=s.y1,m=s.y2,Hl(s,f-C,p-C,d+C,m+C));var he=l.overlayBounds=l.overlayBounds||{};X0e(he,s),L6(he,x),D6(he,1);var le=l.labelBounds=l.labelBounds||{};le.all!=null?tXe(le.all):le.all=Ys(),i&&r.includeLabels&&(r.includeMainLabels&&uB(s,e,null),h&&(r.includeSourceLabels&&uB(s,e,"source"),r.includeTargetLabels&&uB(s,e,"target")))}return s.x1=il(s.x1),s.y1=il(s.y1),s.x2=il(s.x2),s.y2=il(s.y2),s.w=il(s.x2-s.x1),s.h=il(s.y2-s.y1),s.w>0&&s.h>0&&T&&(L6(s,x),D6(s,1)),s},"boundingBoxImpl"),Jge=o(function(e){var r=0,n=o(function(s){return(s?1:0)<=0;l--)s(l);return this};Gf.removeAllListeners=function(){return this.removeListener("*")};Gf.emit=Gf.trigger=function(t,e,r){var n=this.listeners,i=n.length;return this.emitting++,En(e)||(e=[e]),ZQe(this,function(a,s){r!=null&&(n=[{event:s.event,type:s.type,namespace:s.namespace,callback:r}],i=n.length);for(var l=o(function(f){var d=n[f];if(d.type===s.type&&(!d.namespace||d.namespace===s.namespace||d.namespace===KQe)&&a.eventMatches(a.context,d,s)){var p=[s];e!=null&&DYe(p,e),a.beforeEmit(a.context,d,s),d.conf&&d.conf.one&&(a.listeners=a.listeners.filter(function(y){return y!==d}));var m=a.callbackContext(a.context,d,s),g=d.callback.apply(m,p);a.afterEmit(a.context,d,s),g===!1&&(s.stopPropagation(),s.preventDefault())}},"_loop2"),u=0;u1&&!s){var l=this.length-1,u=this[l],h=u._private.data.id;this[l]=void 0,this[e]=u,a.set(h,{ele:u,index:e})}return this.length--,this},"unmergeAt"),unmergeOne:o(function(e){e=e[0];var r=this._private,n=e._private.data.id,i=r.map,a=i.get(n);if(!a)return this;var s=a.index;return this.unmergeAt(s),this},"unmergeOne"),unmerge:o(function(e){var r=this._private.cy;if(!e)return this;if(e&&Zt(e)){var n=e;e=r.mutableElements().filter(n)}for(var i=0;i=0;r--){var n=this[r];e(n)&&this.unmergeAt(r)}return this},"unmergeBy"),map:o(function(e,r){for(var n=[],i=this,a=0;an&&(n=u,i=l)}return{value:n,ele:i}},"max"),min:o(function(e,r){for(var n=1/0,i,a=this,s=0;s=0&&a"u"?"undefined":qi(Symbol))!=e&&qi(Symbol.iterator)!=e;r&&(H6[Symbol.iterator]=function(){var n=this,i={value:void 0,done:!1},a=0,s=this.length;return ige({next:o(function(){return a1&&arguments[1]!==void 0?arguments[1]:!0,n=this[0],i=n.cy();if(i.styleEnabled()&&n){n._private.styleDirty&&(n._private.styleDirty=!1,i.style().apply(n));var a=n._private.style[e];return a??(r?i.style().getDefaultProperty(e):null)}},"parsedStyle"),numericStyle:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r){var n=r.pstyle(e);return n.pfValue!==void 0?n.pfValue:n.value}},"numericStyle"),numericStyleUnits:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r)return r.pstyle(e).units},"numericStyleUnits"),renderedStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=this[0];if(n)return r.style().getRenderedStyle(n,e)},"renderedStyle"),style:o(function(e,r){var n=this.cy();if(!n.styleEnabled())return this;var i=!1,a=n.style();if(Ur(e)){var s=e;a.applyBypass(this,s,i),this.emitAndNotify("style")}else if(Zt(e))if(r===void 0){var l=this[0];return l?a.getStylePropertyValue(l,e):void 0}else a.applyBypass(this,e,r,i),this.emitAndNotify("style");else if(e===void 0){var u=this[0];return u?a.getRawStyle(u):void 0}return this},"style"),removeStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=!1,i=r.style(),a=this;if(e===void 0)for(var s=0;s0&&e.push(f[0]),e.push(l[0])}return this.spawn(e,!0).filter(t)},"neighborhood"),closedNeighborhood:o(function(e){return this.neighborhood().add(this).filter(e)},"closedNeighborhood"),openNeighborhood:o(function(e){return this.neighborhood(e)},"openNeighborhood")});Ha.neighbourhood=Ha.neighborhood;Ha.closedNeighbourhood=Ha.closedNeighborhood;Ha.openNeighbourhood=Ha.openNeighborhood;ir(Ha,{source:al(o(function(e){var r=this[0],n;return r&&(n=r._private.source||r.cy().collection()),n&&e?n.filter(e):n},"sourceImpl"),"source"),target:al(o(function(e){var r=this[0],n;return r&&(n=r._private.target||r.cy().collection()),n&&e?n.filter(e):n},"targetImpl"),"target"),sources:Cme({attr:"source"}),targets:Cme({attr:"target"})});o(Cme,"defineSourceFunction");ir(Ha,{edgesWith:al(Ame(),"edgesWith"),edgesTo:al(Ame({thisIsSrc:!0}),"edgesTo")});o(Ame,"defineEdgesWithFunction");ir(Ha,{connectedEdges:al(function(t){for(var e=[],r=this,n=0;n0);return s},"components"),component:o(function(){var e=this[0];return e.cy().mutableElements().components(e)[0]},"component")});Ha.componentsOf=Ha.components;Sa=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(e===void 0){oi("A collection must have a reference to the core");return}var a=new Zc,s=!1;if(!r)r=[];else if(r.length>0&&Ur(r[0])&&!f4(r[0])){s=!0;for(var l=[],u=new ay,h=0,f=r.length;h0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=r.cy(),i=n._private,a=[],s=[],l,u=0,h=r.length;u0){for(var F=l.length===r.length?r:new Sa(n,l),z=0;z0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=[],i={},a=r._private.cy;function s(A){for(var I=A._private.edges,M=0;M0&&(t?R.emitAndNotify("remove"):e&&R.emit("remove"));for(var k=0;kf&&Math.abs(g.v)>f;);return p?function(y){return u[y*(u.length-1)|0]}:h},"springRK4Factory")}(),Nn=o(function(e,r,n,i){var a=lZe(e,r,n,i);return function(s,l,u){return s+(l-s)*a(u)}},"cubicBezier"),M6={linear:o(function(e,r,n){return e+(r-e)*n},"linear"),ease:Nn(.25,.1,.25,1),"ease-in":Nn(.42,0,1,1),"ease-out":Nn(0,0,.58,1),"ease-in-out":Nn(.42,0,.58,1),"ease-in-sine":Nn(.47,0,.745,.715),"ease-out-sine":Nn(.39,.575,.565,1),"ease-in-out-sine":Nn(.445,.05,.55,.95),"ease-in-quad":Nn(.55,.085,.68,.53),"ease-out-quad":Nn(.25,.46,.45,.94),"ease-in-out-quad":Nn(.455,.03,.515,.955),"ease-in-cubic":Nn(.55,.055,.675,.19),"ease-out-cubic":Nn(.215,.61,.355,1),"ease-in-out-cubic":Nn(.645,.045,.355,1),"ease-in-quart":Nn(.895,.03,.685,.22),"ease-out-quart":Nn(.165,.84,.44,1),"ease-in-out-quart":Nn(.77,0,.175,1),"ease-in-quint":Nn(.755,.05,.855,.06),"ease-out-quint":Nn(.23,1,.32,1),"ease-in-out-quint":Nn(.86,0,.07,1),"ease-in-expo":Nn(.95,.05,.795,.035),"ease-out-expo":Nn(.19,1,.22,1),"ease-in-out-expo":Nn(1,0,0,1),"ease-in-circ":Nn(.6,.04,.98,.335),"ease-out-circ":Nn(.075,.82,.165,1),"ease-in-out-circ":Nn(.785,.135,.15,.86),spring:o(function(e,r,n){if(n===0)return M6.linear;var i=cZe(e,r,n);return function(a,s,l){return a+(s-a)*i(l)}},"spring"),"cubic-bezier":Nn};o(Dme,"getEasedValue");o(Lme,"getValue");o(W1,"ease");o(uZe,"step$1");o(Vb,"valid");o(hZe,"startAnimation");o(Rme,"stepAll");fZe={animate:un.animate(),animation:un.animation(),animated:un.animated(),clearQueue:un.clearQueue(),delay:un.delay(),delayAnimation:un.delayAnimation(),stop:un.stop(),addToAnimationPool:o(function(e){var r=this;r.styleEnabled()&&r._private.aniEles.merge(e)},"addToAnimationPool"),stopAnimationLoop:o(function(){this._private.animationsRunning=!1},"stopAnimationLoop"),startAnimationLoop:o(function(){var e=this;if(e._private.animationsRunning=!0,!e.styleEnabled())return;function r(){e._private.animationsRunning&&$6(o(function(a){Rme(a,e),r()},"animationStep"))}o(r,"headlessStep");var n=e.renderer();n&&n.beforeRender?n.beforeRender(o(function(a,s){Rme(s,e)},"rendererAnimationStep"),n.beforeRenderPriorities.animations):r()},"startAnimationLoop")},dZe={qualifierCompare:o(function(e,r){return e==null||r==null?e==null&&r==null:e.sameText(r)},"qualifierCompare"),eventMatches:o(function(e,r,n){var i=r.qualifier;return i!=null?e!==n.target&&f4(n.target)&&i.matches(n.target):!0},"eventMatches"),addEventFields:o(function(e,r){r.cy=e,r.target=e},"addEventFields"),callbackContext:o(function(e,r,n){return r.qualifier!=null?n.target:e},"callbackContext")},E6=o(function(e){return Zt(e)?new $f(e):e},"argSelector"),u1e={createEmitter:o(function(){var e=this._private;return e.emitter||(e.emitter=new aC(dZe,this)),this},"createEmitter"),emitter:o(function(){return this._private.emitter},"emitter"),on:o(function(e,r,n){return this.emitter().on(e,E6(r),n),this},"on"),removeListener:o(function(e,r,n){return this.emitter().removeListener(e,E6(r),n),this},"removeListener"),removeAllListeners:o(function(){return this.emitter().removeAllListeners(),this},"removeAllListeners"),one:o(function(e,r,n){return this.emitter().one(e,E6(r),n),this},"one"),once:o(function(e,r,n){return this.emitter().one(e,E6(r),n),this},"once"),emit:o(function(e,r){return this.emitter().emit(e,r),this},"emit"),emitAndNotify:o(function(e,r){return this.emit(e),this.notify(e,r),this},"emitAndNotify")};un.eventAliasesOn(u1e);CB={png:o(function(e){var r=this._private.renderer;return e=e||{},r.png(e)},"png"),jpg:o(function(e){var r=this._private.renderer;return e=e||{},e.bg=e.bg||"#fff",r.jpg(e)},"jpg")};CB.jpeg=CB.jpg;I6={layout:o(function(e){var r=this;if(e==null){oi("Layout options must be specified to make a layout");return}if(e.name==null){oi("A `name` must be specified to make a layout");return}var n=e.name,i=r.extension("layout",n);if(i==null){oi("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?");return}var a;Zt(e.eles)?a=r.$(e.eles):a=e.eles!=null?e.eles:r.$();var s=new i(ir({},e,{cy:r,eles:a}));return s},"layout")};I6.createLayout=I6.makeLayout=I6.layout;pZe={notify:o(function(e,r){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var i=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();r!=null&&i.merge(r);return}if(n.notificationsEnabled){var a=this.renderer();this.destroyed()||!a||a.notify(e,r)}},"notify"),notifications:o(function(e){var r=this._private;return e===void 0?r.notificationsEnabled:(r.notificationsEnabled=!!e,this)},"notifications"),noNotifications:o(function(e){this.notifications(!1),e(),this.notifications(!0)},"noNotifications"),batching:o(function(){return this._private.batchCount>0},"batching"),startBatch:o(function(){var e=this._private;return e.batchCount==null&&(e.batchCount=0),e.batchCount===0&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},"startBatch"),endBatch:o(function(){var e=this._private;if(e.batchCount===0)return this;if(e.batchCount--,e.batchCount===0){e.batchStyleEles.updateStyle();var r=this.renderer();Object.keys(e.batchNotifications).forEach(function(n){var i=e.batchNotifications[n];i.empty()?r.notify(n):r.notify(n,i)})}return this},"endBatch"),batch:o(function(e){return this.startBatch(),e(),this.endBatch(),this},"batch"),batchData:o(function(e){var r=this;return this.batch(function(){for(var n=Object.keys(e),i=0;i0;)r.removeChild(r.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach(function(n){var i=n._private;i.rscratch={},i.rstyle={},i.animation.current=[],i.animation.queue=[]})},"destroyRenderer"),onRender:o(function(e){return this.on("render",e)},"onRender"),offRender:o(function(e){return this.off("render",e)},"offRender")};AB.invalidateDimensions=AB.resize;O6={collection:o(function(e,r){return Zt(e)?this.$(e):xo(e)?e.collection():En(e)?(r||(r={}),new Sa(this,e,r.unique,r.removed)):new Sa(this)},"collection"),nodes:o(function(e){var r=this.$(function(n){return n.isNode()});return e?r.filter(e):r},"nodes"),edges:o(function(e){var r=this.$(function(n){return n.isEdge()});return e?r.filter(e):r},"edges"),$:o(function(e){var r=this._private.elements;return e?r.filter(e):r.spawnSelf()},"$"),mutableElements:o(function(){return this._private.elements},"mutableElements")};O6.elements=O6.filter=O6.$;qa={},Kb="t",gZe="f";qa.apply=function(t){for(var e=this,r=e._private,n=r.cy,i=n.collection(),a=0;a0;if(p||d&&m){var g=void 0;p&&m||p?g=h.properties:m&&(g=h.mappedProperties);for(var y=0;y1&&(S=1),l.color){var E=n.valueMin[0],_=n.valueMax[0],C=n.valueMin[1],D=n.valueMax[1],O=n.valueMin[2],R=n.valueMax[2],k=n.valueMin[3]==null?1:n.valueMin[3],L=n.valueMax[3]==null?1:n.valueMax[3],A=[Math.round(E+(_-E)*S),Math.round(C+(D-C)*S),Math.round(O+(R-O)*S),Math.round(k+(L-k)*S)];a={bypass:n.bypass,name:n.name,value:A,strValue:"rgb("+A[0]+", "+A[1]+", "+A[2]+")"}}else if(l.number){var I=n.valueMin+(n.valueMax-n.valueMin)*S;a=this.parse(n.name,I,n.bypass,p)}else return!1;if(!a)return y(),!1;a.mapping=n,n=a;break}case s.data:{for(var M=n.field.split("."),P=d.data,B=0;B0&&a>0){for(var l={},u=!1,h=0;h0?t.delayAnimation(s).play().promise().then(T):T()}).then(function(){return t.animation({style:l,duration:a,easing:t.pstyle("transition-timing-function").value,queue:!1}).play().promise()}).then(function(){r.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1})}else n.transitioning&&(this.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1)};qa.checkTrigger=function(t,e,r,n,i,a){var s=this.properties[e],l=i(s);l!=null&&l(r,n)&&a(s)};qa.checkZOrderTrigger=function(t,e,r,n){var i=this;this.checkTrigger(t,e,r,n,function(a){return a.triggersZOrder},function(){i._private.cy.notify("zorder",t)})};qa.checkBoundsTrigger=function(t,e,r,n){this.checkTrigger(t,e,r,n,function(i){return i.triggersBounds},function(i){t.dirtyCompoundBoundsCache(),t.dirtyBoundingBoxCache(),i.triggersBoundsOfParallelBeziers&&e==="curve-style"&&(r==="bezier"||n==="bezier")&&t.parallelEdges().forEach(function(a){a.dirtyBoundingBoxCache()}),i.triggersBoundsOfConnectedEdges&&e==="display"&&(r==="none"||n==="none")&&t.connectedEdges().forEach(function(a){a.dirtyBoundingBoxCache()})})};qa.checkTriggers=function(t,e,r,n){t.dirtyStyleCache(),this.checkZOrderTrigger(t,e,r,n),this.checkBoundsTrigger(t,e,r,n)};y4={};y4.applyBypass=function(t,e,r,n){var i=this,a=[],s=!0;if(e==="*"||e==="**"){if(r!==void 0)for(var l=0;li.length?n=n.substr(i.length):n=""}o(l,"removeSelAndBlockFromRemaining");function u(){a.length>s.length?a=a.substr(s.length):a=""}for(o(u,"removePropAndValFromRem");;){var h=n.match(/^\s*$/);if(h)break;var f=n.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!f){hn("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+n);break}i=f[0];var d=f[1];if(d!=="core"){var p=new $f(d);if(p.invalid){hn("Skipping parsing of block: Invalid selector found in string stylesheet: "+d),l();continue}}var m=f[2],g=!1;a=m;for(var y=[];;){var v=a.match(/^\s*$/);if(v)break;var x=a.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!x){hn("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+m),g=!0;break}s=x[0];var b=x[1],T=x[2],S=e.properties[b];if(!S){hn("Skipping property: Invalid property name in: "+s),u();continue}var w=r.parse(b,T);if(!w){hn("Skipping property: Invalid property definition in: "+s),u();continue}y.push({name:b,val:T}),u()}if(g){l();break}r.selector(d);for(var E=0;E=7&&e[0]==="d"&&(f=new RegExp(l.data.regex).exec(e))){if(r)return!1;var p=l.data;return{name:t,value:f,strValue:""+e,mapped:p,field:f[1],bypass:r}}else if(e.length>=10&&e[0]==="m"&&(d=new RegExp(l.mapData.regex).exec(e))){if(r||h.multiple)return!1;var m=l.mapData;if(!(h.color||h.number))return!1;var g=this.parse(t,d[4]);if(!g||g.mapped)return!1;var y=this.parse(t,d[5]);if(!y||y.mapped)return!1;if(g.pfValue===y.pfValue||g.strValue===y.strValue)return hn("`"+t+": "+e+"` is not a valid mapper because the output range is zero; converting to `"+t+": "+g.strValue+"`"),this.parse(t,g.strValue);if(h.color){var v=g.value,x=y.value,b=v[0]===x[0]&&v[1]===x[1]&&v[2]===x[2]&&(v[3]===x[3]||(v[3]==null||v[3]===1)&&(x[3]==null||x[3]===1));if(b)return!1}return{name:t,value:d,strValue:""+e,mapped:m,field:d[1],fieldMin:parseFloat(d[2]),fieldMax:parseFloat(d[3]),valueMin:g.value,valueMax:y.value,bypass:r}}}if(h.multiple&&n!=="multiple"){var T;if(u?T=e.split(/\s+/):En(e)?T=e:T=[e],h.evenMultiple&&T.length%2!==0)return null;for(var S=[],w=[],E=[],_="",C=!1,D=0;D0?" ":"")+O.strValue}return h.validate&&!h.validate(S,w)?null:h.singleEnum&&C?S.length===1&&Zt(S[0])?{name:t,value:S[0],strValue:S[0],bypass:r}:null:{name:t,value:S,pfValue:E,strValue:_,bypass:r,units:w}}var R=o(function(){for(var Q=0;Qh.max||h.strictMax&&e===h.max))return null;var M={name:t,value:e,strValue:""+e+(k||""),units:k,bypass:r};return h.unitless||k!=="px"&&k!=="em"?M.pfValue=e:M.pfValue=k==="px"||!k?e:this.getEmSizeInPixels()*e,(k==="ms"||k==="s")&&(M.pfValue=k==="ms"?e:1e3*e),(k==="deg"||k==="rad")&&(M.pfValue=k==="rad"?e:QYe(e)),k==="%"&&(M.pfValue=e/100),M}else if(h.propList){var P=[],B=""+e;if(B!=="none"){for(var F=B.split(/\s*,\s*|\s+/),z=0;z0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0){u=Math.min((s-2*r)/n.w,(l-2*r)/n.h),u=u>this._private.maxZoom?this._private.maxZoom:u,u=u=n.minZoom&&(n.maxZoom=r),this},"zoomRange"),minZoom:o(function(e){return e===void 0?this._private.minZoom:this.zoomRange({min:e})},"minZoom"),maxZoom:o(function(e){return e===void 0?this._private.maxZoom:this.zoomRange({max:e})},"maxZoom"),getZoomedViewport:o(function(e){var r=this._private,n=r.pan,i=r.zoom,a,s,l=!1;if(r.zoomingEnabled||(l=!0),_t(e)?s=e:Ur(e)&&(s=e.level,e.position!=null?a=J6(e.position,i,n):e.renderedPosition!=null&&(a=e.renderedPosition),a!=null&&!r.panningEnabled&&(l=!0)),s=s>r.maxZoom?r.maxZoom:s,s=sr.maxZoom||!r.zoomingEnabled?s=!0:(r.zoom=u,a.push("zoom"))}if(i&&(!s||!e.cancelOnFailedZoom)&&r.panningEnabled){var h=e.pan;_t(h.x)&&(r.pan.x=h.x,l=!1),_t(h.y)&&(r.pan.y=h.y,l=!1),l||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},"viewport"),center:o(function(e){var r=this.getCenterPan(e);return r&&(this._private.pan=r,this.emit("pan viewport"),this.notify("viewport")),this},"center"),getCenterPan:o(function(e,r){if(this._private.panningEnabled){if(Zt(e)){var n=e;e=this.mutableElements().filter(n)}else xo(e)||(e=this.mutableElements());if(e.length!==0){var i=e.boundingBox(),a=this.width(),s=this.height();r=r===void 0?this._private.zoom:r;var l={x:(a-r*(i.x1+i.x2))/2,y:(s-r*(i.y1+i.y2))/2};return l}}},"getCenterPan"),reset:o(function(){return!this._private.panningEnabled||!this._private.zoomingEnabled?this:(this.viewport({pan:{x:0,y:0},zoom:1}),this)},"reset"),invalidateSize:o(function(){this._private.sizeCache=null},"invalidateSize"),size:o(function(){var e=this._private,r=e.container,n=this;return e.sizeCache=e.sizeCache||(r?function(){var i=n.window().getComputedStyle(r),a=o(function(l){return parseFloat(i.getPropertyValue(l))},"val");return{width:r.clientWidth-a("padding-left")-a("padding-right"),height:r.clientHeight-a("padding-top")-a("padding-bottom")}}():{width:1,height:1})},"size"),width:o(function(){return this.size().width},"width"),height:o(function(){return this.size().height},"height"),extent:o(function(){var e=this._private.pan,r=this._private.zoom,n=this.renderedExtent(),i={x1:(n.x1-e.x)/r,x2:(n.x2-e.x)/r,y1:(n.y1-e.y)/r,y2:(n.y2-e.y)/r};return i.w=i.x2-i.x1,i.h=i.y2-i.y1,i},"extent"),renderedExtent:o(function(){var e=this.width(),r=this.height();return{x1:0,y1:0,x2:e,y2:r,w:e,h:r}},"renderedExtent"),multiClickDebounceTime:o(function(e){if(e)this._private.multiClickDebounceTime=e;else return this._private.multiClickDebounceTime;return this},"multiClickDebounceTime")};e0.centre=e0.center;e0.autolockNodes=e0.autolock;e0.autoungrabifyNodes=e0.autoungrabify;c4={data:un.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:un.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:un.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:un.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};c4.attr=c4.data;c4.removeAttr=c4.removeData;u4=o(function(e){var r=this;e=ir({},e);var n=e.container;n&&!F6(n)&&F6(n[0])&&(n=n[0]);var i=n?n._cyreg:null;i=i||{},i&&i.cy&&(i.cy.destroy(),i={});var a=i.readies=i.readies||[];n&&(n._cyreg=i),i.cy=r;var s=Hi!==void 0&&n!==void 0&&!e.headless,l=e;l.layout=ir({name:s?"grid":"null"},l.layout),l.renderer=ir({name:s?"canvas":"null"},l.renderer);var u=o(function(g,y,v){return y!==void 0?y:v!==void 0?v:g},"defVal"),h=this._private={container:n,ready:!1,options:l,elements:new Sa(this),listeners:[],aniEles:new Sa(this),data:l.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:u(!0,l.zoomingEnabled),userZoomingEnabled:u(!0,l.userZoomingEnabled),panningEnabled:u(!0,l.panningEnabled),userPanningEnabled:u(!0,l.userPanningEnabled),boxSelectionEnabled:u(!0,l.boxSelectionEnabled),autolock:u(!1,l.autolock,l.autolockNodes),autoungrabify:u(!1,l.autoungrabify,l.autoungrabifyNodes),autounselectify:u(!1,l.autounselectify),styleEnabled:l.styleEnabled===void 0?s:l.styleEnabled,zoom:_t(l.zoom)?l.zoom:1,pan:{x:Ur(l.pan)&&_t(l.pan.x)?l.pan.x:0,y:Ur(l.pan)&&_t(l.pan.y)?l.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:u(250,l.multiClickDebounceTime)};this.createEmitter(),this.selectionType(l.selectionType),this.zoomRange({min:l.minZoom,max:l.maxZoom});var f=o(function(g,y){var v=g.some(wqe);if(v)return sy.all(g).then(y);y(g)},"loadExtData");h.styleEnabled&&r.setStyle([]);var d=ir({},l,l.renderer);r.initRenderer(d);var p=o(function(g,y,v){r.notifications(!1);var x=r.mutableElements();x.length>0&&x.remove(),g!=null&&(Ur(g)||En(g))&&r.add(g),r.one("layoutready",function(T){r.notifications(!0),r.emit(T),r.one("load",y),r.emitAndNotify("load")}).one("layoutstop",function(){r.one("done",v),r.emit("done")});var b=ir({},r._private.options.layout);b.eles=r.elements(),r.layout(b).run()},"setElesAndLayout");f([l.style,l.elements],function(m){var g=m[0],y=m[1];h.styleEnabled&&r.style().append(g),p(y,function(){r.startAnimationLoop(),h.ready=!0,li(l.ready)&&r.on("ready",l.ready);for(var v=0;v0,l=!!t.boundingBox,u=e.extent(),h=Ys(l?t.boundingBox:{x1:u.x1,y1:u.y1,w:u.w,h:u.h}),f;if(xo(t.roots))f=t.roots;else if(En(t.roots)){for(var d=[],p=0;p0;){var I=A(),M=O(I,k);if(M)I.outgoers().filter(function(ae){return ae.isNode()&&r.has(ae)}).forEach(L);else if(M===null){hn("Detected double maximal shift for node `"+I.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}var P=0;if(t.avoidOverlap)for(var B=0;B0&&b[0].length<=3?ze/2:0),Ie=2*Math.PI/b[Be].length*He;return Be===0&&b[0].length===1&&(Le=1),{x:he.x+Le*Math.cos(Ie),y:he.y+Le*Math.sin(Ie)}}else{var xe=b[Be].length,q=Math.max(xe===1?0:l?(h.w-t.padding*2-le.w)/((t.grid?Se:xe)-1):(h.w-t.padding*2-le.w)/((t.grid?Se:xe)+1),P),de={x:he.x+(He+1-(xe+1)/2)*q,y:he.y+(Be+1-(ce+1)/2)*J};return de}},"getPosition");return r.nodes().layoutPositions(this,t,se),this};TZe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(f1e,"CircleLayout");f1e.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,a=n.nodes().not(":parent");e.sort&&(a=a.sort(e.sort));for(var s=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=e.sweep===void 0?2*Math.PI-2*Math.PI/a.length:e.sweep,h=u/Math.max(1,a.length-1),f,d=0,p=0;p1&&e.avoidOverlap){d*=1.75;var x=Math.cos(h)-Math.cos(0),b=Math.sin(h)-Math.sin(0),T=Math.sqrt(d*d/(x*x+b*b));f=Math.max(T,f)}var S=o(function(E,_){var C=e.startAngle+_*h*(i?1:-1),D=f*Math.cos(C),O=f*Math.sin(C),R={x:l.x+D,y:l.y+O};return R},"getPos");return n.nodes().layoutPositions(this,e,S),this};wZe={fit:!0,padding:30,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:o(function(e){return e.degree()},"concentric"),levelWidth:o(function(e){return e.maxDegree()/4},"levelWidth"),animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(d1e,"ConcentricLayout");d1e.prototype.run=function(){for(var t=this.options,e=t,r=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,n=t.cy,i=e.eles,a=i.nodes().not(":parent"),s=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=[],h=0,f=0;f0){var w=Math.abs(b[0].value-S.value);w>=v&&(b=[],x.push(b))}b.push(S)}var E=h+e.minNodeSpacing;if(!e.avoidOverlap){var _=x.length>0&&x[0].length>1,C=Math.min(s.w,s.h)/2-E,D=C/(x.length+_?1:0);E=Math.min(E,D)}for(var O=0,R=0;R1&&e.avoidOverlap){var I=Math.cos(A)-Math.cos(0),M=Math.sin(A)-Math.sin(0),P=Math.sqrt(E*E/(I*I+M*M));O=Math.max(P,O)}k.r=O,O+=E}if(e.equidistant){for(var B=0,F=0,z=0;z=t.numIter||(LZe(n,t),n.temperature=n.temperature*t.coolingFactor,n.temperature=t.animationThreshold&&a(),$6(d)}},"frame");f()}else{for(;h;)h=s(u),u++;Ime(n,t),l()}return this};uC.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this};uC.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};EZe=o(function(e,r,n){for(var i=n.eles.edges(),a=n.eles.nodes(),s=Ys(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),l={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:i.size(),temperature:n.initialTemp,clientWidth:s.w,clientHeight:s.h,boundingBox:s},u=n.eles.components(),h={},f=0;f0){l.graphSet.push(C);for(var f=0;fi.count?0:i.graph},"findLCA"),CZe=o(function t(e,r,n,i){var a=i.graphSet[n];if(-10)var d=i.nodeOverlap*f,p=Math.sqrt(l*l+u*u),m=d*l/p,g=d*u/p;else var y=q6(e,l,u),v=q6(r,-1*l,-1*u),x=v.x-y.x,b=v.y-y.y,T=x*x+b*b,p=Math.sqrt(T),d=(e.nodeRepulsion+r.nodeRepulsion)/T,m=d*x/p,g=d*b/p;e.isLocked||(e.offsetX-=m,e.offsetY-=g),r.isLocked||(r.offsetX+=m,r.offsetY+=g)}},"nodeRepulsion"),MZe=o(function(e,r,n,i){if(n>0)var a=e.maxX-r.minX;else var a=r.maxX-e.minX;if(i>0)var s=e.maxY-r.minY;else var s=r.maxY-e.minY;return a>=0&&s>=0?Math.sqrt(a*a+s*s):0},"nodesOverlap"),q6=o(function(e,r,n){var i=e.positionX,a=e.positionY,s=e.height||1,l=e.width||1,u=n/r,h=s/l,f={};return r===0&&0n?(f.x=i,f.y=a+s/2,f):0r&&-1*h<=u&&u<=h?(f.x=i-l/2,f.y=a-l*n/2/r,f):0=h)?(f.x=i+s*r/2/n,f.y=a+s/2,f):(0>n&&(u<=-1*h||u>=h)&&(f.x=i-s*r/2/n,f.y=a-s/2),f)},"findClippingPoint"),IZe=o(function(e,r){for(var n=0;nn){var v=r.gravity*m/y,x=r.gravity*g/y;p.offsetX+=v,p.offsetY+=x}}}}},"calculateGravityForces"),PZe=o(function(e,r){var n=[],i=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;i<=a;){var s=n[i++],l=e.idToIndex[s],u=e.layoutNodes[l],h=u.children;if(0n)var a={x:n*e/i,y:n*r/i};else var a={x:e,y:r};return a},"limitForce"),$Ze=o(function t(e,r){var n=e.parentId;if(n!=null){var i=r.layoutNodes[r.idToIndex[n]],a=!1;if((i.maxX==null||e.maxX+i.padRight>i.maxX)&&(i.maxX=e.maxX+i.padRight,a=!0),(i.minX==null||e.minX-i.padLefti.maxY)&&(i.maxY=e.maxY+i.padBottom,a=!0),(i.minY==null||e.minY-i.padTopx&&(g+=v+r.componentSpacing,m=0,y=0,v=0)}}},"separateComponents"),zZe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:o(function(e){},"position"),sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(m1e,"GridLayout");m1e.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=n.nodes().not(":parent");e.sort&&(i=i.sort(e.sort));var a=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(a.h===0||a.w===0)n.nodes().layoutPositions(this,e,function(K){return{x:a.x1,y:a.y1}});else{var s=i.size(),l=Math.sqrt(s*a.h/a.w),u=Math.round(l),h=Math.round(a.w/a.h*l),f=o(function(ee){if(ee==null)return Math.min(u,h);var Y=Math.min(u,h);Y==u?u=ee:h=ee},"small"),d=o(function(ee){if(ee==null)return Math.max(u,h);var Y=Math.max(u,h);Y==u?u=ee:h=ee},"large"),p=e.rows,m=e.cols!=null?e.cols:e.columns;if(p!=null&&m!=null)u=p,h=m;else if(p!=null&&m==null)u=p,h=Math.ceil(s/u);else if(p==null&&m!=null)h=m,u=Math.ceil(s/h);else if(h*u>s){var g=f(),y=d();(g-1)*y>=s?f(g-1):(y-1)*g>=s&&d(y-1)}else for(;h*u=s?d(x+1):f(v+1)}var b=a.w/h,T=a.h/u;if(e.condense&&(b=0,T=0),e.avoidOverlap)for(var S=0;S=h&&(I=0,A++)},"moveToNextCell"),P={},B=0;B(I=uXe(t,e,M[P],M[P+1],M[P+2],M[P+3])))return v(_,I),!0}else if(D.edgeType==="bezier"||D.edgeType==="multibezier"||D.edgeType==="self"||D.edgeType==="compound"){for(var M=D.allpts,P=0;P+5(I=cXe(t,e,M[P],M[P+1],M[P+2],M[P+3],M[P+4],M[P+5])))return v(_,I),!0}for(var B=B||C.source,F=F||C.target,z=i.getArrowWidth(O,R),$=[{name:"source",x:D.arrowStartX,y:D.arrowStartY,angle:D.srcArrowAngle},{name:"target",x:D.arrowEndX,y:D.arrowEndY,angle:D.tgtArrowAngle},{name:"mid-source",x:D.midX,y:D.midY,angle:D.midsrcArrowAngle},{name:"mid-target",x:D.midX,y:D.midY,angle:D.midtgtArrowAngle}],P=0;P<$.length;P++){var U=$[P],K=a.arrowShapes[_.pstyle(U.name+"-arrow-shape").value],ee=_.pstyle("width").pfValue;if(K.roughCollide(t,e,z,U.angle,{x:U.x,y:U.y},ee,f)&&K.collide(t,e,z,U.angle,{x:U.x,y:U.y},ee,f))return v(_),!0}h&&l.length>0&&(x(B),x(F))}o(b,"checkEdge");function T(_,C,D){return Wl(_,C,D)}o(T,"preprop");function S(_,C){var D=_._private,O=p,R;C?R=C+"-":R="",_.boundingBox();var k=D.labelBounds[C||"main"],L=_.pstyle(R+"label").value,A=_.pstyle("text-events").strValue==="yes";if(!(!A||!L)){var I=T(D.rscratch,"labelX",C),M=T(D.rscratch,"labelY",C),P=T(D.rscratch,"labelAngle",C),B=_.pstyle(R+"text-margin-x").pfValue,F=_.pstyle(R+"text-margin-y").pfValue,z=k.x1-O-B,$=k.x2+O-B,U=k.y1-O-F,K=k.y2+O-F;if(P){var ee=Math.cos(P),Y=Math.sin(P),ce=o(function(he,le){return he=he-I,le=le-M,{x:he*ee-le*Y+I,y:he*Y+le*ee+M}},"rotate"),Z=ce(z,U),ue=ce(z,K),Q=ce($,U),j=ce($,K),ne=[Z.x+B,Z.y+F,Q.x+B,Q.y+F,j.x+B,j.y+F,ue.x+B,ue.y+F];if(qs(t,e,ne))return v(_),!0}else if(ry(k,t,e))return v(_),!0}}o(S,"checkLabel");for(var w=s.length-1;w>=0;w--){var E=s[w];E.isNode()?x(E)||S(E):b(E)||S(E)||S(E,"source")||S(E,"target")}return l};r0.getAllInBox=function(t,e,r,n){var i=this.getCachedZSortedEles().interactive,a=[],s=Math.min(t,r),l=Math.max(t,r),u=Math.min(e,n),h=Math.max(e,n);t=s,r=l,e=u,n=h;for(var f=Ys({x1:t,y1:e,x2:r,y2:n}),d=0;d0?-(Math.PI-e.ang):Math.PI+e.ang},"invertVec"),qZe=o(function(e,r,n,i,a){if(e!==$me?zme(r,e,Kc):WZe(nl,Kc),zme(r,n,nl),Bme=Kc.nx*nl.ny-Kc.ny*nl.nx,Fme=Kc.nx*nl.nx-Kc.ny*-nl.ny,rh=Math.asin(Math.max(-1,Math.min(1,Bme))),Math.abs(rh)<1e-6){_B=r.x,DB=r.y,Yp=Y1=0;return}Xp=1,P6=!1,Fme<0?rh<0?rh=Math.PI+rh:(rh=Math.PI-rh,Xp=-1,P6=!0):rh>0&&(Xp=-1,P6=!0),r.radius!==void 0?Y1=r.radius:Y1=i,Up=rh/2,S6=Math.min(Kc.len/2,nl.len/2),a?(jc=Math.abs(Math.cos(Up)*Y1/Math.sin(Up)),jc>S6?(jc=S6,Yp=Math.abs(jc*Math.sin(Up)/Math.cos(Up))):Yp=Y1):(jc=Math.min(S6,Y1),Yp=Math.abs(jc*Math.sin(Up)/Math.cos(Up))),LB=r.x+nl.nx*jc,RB=r.y+nl.ny*jc,_B=LB-nl.ny*Yp*Xp,DB=RB+nl.nx*Yp*Xp,x1e=r.x+Kc.nx*jc,b1e=r.y+Kc.ny*jc,$me=r},"calcCornerArc");o(T1e,"drawPreparedRoundCorner");o(rF,"getRoundCorner");Ya={};Ya.findMidptPtsEtc=function(t,e){var r=e.posPts,n=e.intersectionPts,i=e.vectorNormInverse,a,s=t.pstyle("source-endpoint"),l=t.pstyle("target-endpoint"),u=s.units!=null&&l.units!=null,h=o(function(w,E,_,C){var D=C-E,O=_-w,R=Math.sqrt(O*O+D*D);return{x:-D/R,y:O/R}},"recalcVectorNormInverse"),f=t.pstyle("edge-distances").value;switch(f){case"node-position":a=r;break;case"intersection":a=n;break;case"endpoints":{if(u){var d=this.manualEndptToPx(t.source()[0],s),p=Ri(d,2),m=p[0],g=p[1],y=this.manualEndptToPx(t.target()[0],l),v=Ri(y,2),x=v[0],b=v[1],T={x1:m,y1:g,x2:x,y2:b};i=h(m,g,x,b),a=T}else hn("Edge ".concat(t.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),a=n;break}}return{midptPts:a,vectorNormInverse:i}};Ya.findHaystackPoints=function(t){for(var e=0;e0?Math.max(W-pe,0):Math.min(W+pe,0)},"subDWH"),L=k(O,C),A=k(R,D),I=!1;b===h?x=Math.abs(L)>Math.abs(A)?i:n:b===u||b===l?(x=n,I=!0):(b===a||b===s)&&(x=i,I=!0);var M=x===n,P=M?A:L,B=M?R:O,F=Sge(B),z=!1;!(I&&(S||E))&&(b===l&&B<0||b===u&&B>0||b===a&&B>0||b===s&&B<0)&&(F*=-1,P=F*Math.abs(P),z=!0);var $;if(S){var U=w<0?1+w:w;$=U*P}else{var K=w<0?P:0;$=K+w*F}var ee=o(function(W){return Math.abs(W)<_||Math.abs(W)>=Math.abs(P)},"getIsTooClose"),Y=ee($),ce=ee(Math.abs(P)-Math.abs($)),Z=Y||ce;if(Z&&!z)if(M){var ue=Math.abs(B)<=p/2,Q=Math.abs(O)<=m/2;if(ue){var j=(f.x1+f.x2)/2,ne=f.y1,te=f.y2;r.segpts=[j,ne,j,te]}else if(Q){var he=(f.y1+f.y2)/2,le=f.x1,J=f.x2;r.segpts=[le,he,J,he]}else r.segpts=[f.x1,f.y2]}else{var Se=Math.abs(B)<=d/2,se=Math.abs(R)<=g/2;if(Se){var ae=(f.y1+f.y2)/2,Oe=f.x1,ye=f.x2;r.segpts=[Oe,ae,ye,ae]}else if(se){var Be=(f.x1+f.x2)/2,He=f.y1,ze=f.y2;r.segpts=[Be,He,Be,ze]}else r.segpts=[f.x2,f.y1]}else if(M){var Le=f.y1+$+(v?p/2*F:0),Ie=f.x1,xe=f.x2;r.segpts=[Ie,Le,xe,Le]}else{var q=f.x1+$+(v?d/2*F:0),de=f.y1,ie=f.y2;r.segpts=[q,de,q,ie]}if(r.isRound){var oe=t.pstyle("taxi-radius").value,V=t.pstyle("radius-type").value[0]==="arc-radius";r.radii=new Array(r.segpts.length/2).fill(oe),r.isArcRadius=new Array(r.segpts.length/2).fill(V)}};Ya.tryToCorrectInvalidPoints=function(t,e){var r=t._private.rscratch;if(r.edgeType==="bezier"){var n=e.srcPos,i=e.tgtPos,a=e.srcW,s=e.srcH,l=e.tgtW,u=e.tgtH,h=e.srcShape,f=e.tgtShape,d=e.srcCornerRadius,p=e.tgtCornerRadius,m=e.srcRs,g=e.tgtRs,y=!_t(r.startX)||!_t(r.startY),v=!_t(r.arrowStartX)||!_t(r.arrowStartY),x=!_t(r.endX)||!_t(r.endY),b=!_t(r.arrowEndX)||!_t(r.arrowEndY),T=3,S=this.getArrowWidth(t.pstyle("width").pfValue,t.pstyle("arrow-scale").value)*this.arrowShapeWidth,w=T*S,E=Qp({x:r.ctrlpts[0],y:r.ctrlpts[1]},{x:r.startX,y:r.startY}),_=EA.poolIndex()){var I=L;L=A,A=I}var M=D.srcPos=L.position(),P=D.tgtPos=A.position(),B=D.srcW=L.outerWidth(),F=D.srcH=L.outerHeight(),z=D.tgtW=A.outerWidth(),$=D.tgtH=A.outerHeight(),U=D.srcShape=r.nodeShapes[e.getNodeShape(L)],K=D.tgtShape=r.nodeShapes[e.getNodeShape(A)],ee=D.srcCornerRadius=L.pstyle("corner-radius").value==="auto"?"auto":L.pstyle("corner-radius").pfValue,Y=D.tgtCornerRadius=A.pstyle("corner-radius").value==="auto"?"auto":A.pstyle("corner-radius").pfValue,ce=D.tgtRs=A._private.rscratch,Z=D.srcRs=L._private.rscratch;D.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var ue=0;ue0){var te=a,he=Wp(te,j1(r)),le=Wp(te,j1(ne)),J=he;if(le2){var Se=Wp(te,{x:ne[2],y:ne[3]});Se0){var ie=s,oe=Wp(ie,j1(r)),V=Wp(ie,j1(de)),Te=oe;if(V2){var W=Wp(ie,{x:de[2],y:de[3]});W=g||_){v={cp:S,segment:E};break}}if(v)break}var C=v.cp,D=v.segment,O=(g-x)/D.length,R=D.t1-D.t0,k=m?D.t0+R*O:D.t1-R*O;k=i4(0,k,1),e=Q1(C.p0,C.p1,C.p2,k),p=XZe(C.p0,C.p1,C.p2,k);break}case"straight":case"segments":case"haystack":{for(var L=0,A,I,M,P,B=n.allpts.length,F=0;F+3=g));F+=2);var z=g-I,$=z/A;$=i4(0,$,1),e=JYe(M,P,$),p=E1e(M,P);break}}s("labelX",d,e.x),s("labelY",d,e.y),s("labelAutoAngle",d,p)}},"calculateEndProjection");h("source"),h("target"),this.applyLabelDimensions(t)}};eu.applyLabelDimensions=function(t){this.applyPrefixedLabelDimensions(t),t.isEdge()&&(this.applyPrefixedLabelDimensions(t,"source"),this.applyPrefixedLabelDimensions(t,"target"))};eu.applyPrefixedLabelDimensions=function(t,e){var r=t._private,n=this.getLabelText(t,e),i=this.calculateLabelDimensions(t,n),a=t.pstyle("line-height").pfValue,s=t.pstyle("text-wrap").strValue,l=Wl(r.rscratch,"labelWrapCachedLines",e)||[],u=s!=="wrap"?1:Math.max(l.length,1),h=i.height/u,f=h*a,d=i.width,p=i.height+(u-1)*(a-1)*h;Nf(r.rstyle,"labelWidth",e,d),Nf(r.rscratch,"labelWidth",e,d),Nf(r.rstyle,"labelHeight",e,p),Nf(r.rscratch,"labelHeight",e,p),Nf(r.rscratch,"labelLineHeight",e,f)};eu.getLabelText=function(t,e){var r=t._private,n=e?e+"-":"",i=t.pstyle(n+"label").strValue,a=t.pstyle("text-transform").value,s=o(function(K,ee){return ee?(Nf(r.rscratch,K,e,ee),ee):Wl(r.rscratch,K,e)},"rscratch");if(!i)return"";a=="none"||(a=="uppercase"?i=i.toUpperCase():a=="lowercase"&&(i=i.toLowerCase()));var l=t.pstyle("text-wrap").value;if(l==="wrap"){var u=s("labelKey");if(u!=null&&s("labelWrapKey")===u)return s("labelWrapCachedText");for(var h="\u200B",f=i.split(` +`),d=t.pstyle("text-max-width").pfValue,p=t.pstyle("text-overflow-wrap").value,m=p==="anywhere",g=[],y=/[\s\u200b]+|$/g,v=0;vd){var w=x.matchAll(y),E="",_=0,C=vo(w),D;try{for(C.s();!(D=C.n()).done;){var O=D.value,R=O[0],k=x.substring(_,O.index);_=O.index+R.length;var L=E.length===0?k:E+k+R,A=this.calculateLabelDimensions(t,L),I=A.width;I<=d?E+=k+R:(E&&g.push(E),E=k+R)}}catch(U){C.e(U)}finally{C.f()}E.match(/^[\s\u200b]+$/)||g.push(E)}else g.push(x)}s("labelWrapCachedLines",g),i=s("labelWrapCachedText",g.join(` +`)),s("labelWrapKey",u)}else if(l==="ellipsis"){var M=t.pstyle("text-max-width").pfValue,P="",B="\u2026",F=!1;if(this.calculateLabelDimensions(t,i).widthM)break;P+=i[z],z===i.length-1&&(F=!0)}return F||(P+=B),P}return i};eu.getLabelJustification=function(t){var e=t.pstyle("text-justification").strValue,r=t.pstyle("text-halign").strValue;if(e==="auto")if(t.isNode())switch(r){case"left":return"right";case"right":return"left";default:return"center"}else return"center";else return e};eu.calculateLabelDimensions=function(t,e){var r=this,n=r.cy.window(),i=n.document,a=Bf(e,t._private.labelDimsKey),s=r.labelDimCache||(r.labelDimCache=[]),l=s[a];if(l!=null)return l;var u=0,h=t.pstyle("font-style").strValue,f=t.pstyle("font-size").pfValue,d=t.pstyle("font-family").strValue,p=t.pstyle("font-weight").strValue,m=this.labelCalcCanvas,g=this.labelCalcCanvasContext;if(!m){m=this.labelCalcCanvas=i.createElement("canvas"),g=this.labelCalcCanvasContext=m.getContext("2d");var y=m.style;y.position="absolute",y.left="-9999px",y.top="-9999px",y.zIndex="-1",y.visibility="hidden",y.pointerEvents="none"}g.font="".concat(h," ").concat(p," ").concat(f,"px ").concat(d);for(var v=0,x=0,b=e.split(` +`),T=0;T1&&arguments[1]!==void 0?arguments[1]:!0;if(e.merge(s),l)for(var u=0;u=t.desktopTapThreshold2}var ot=a(q);at&&(t.hoverData.tapholdCancelled=!0);var Yt=o(function(){var kt=t.hoverData.dragDelta=t.hoverData.dragDelta||[];kt.length===0?(kt.push(De[0]),kt.push(De[1])):(kt[0]+=De[0],kt[1]+=De[1])},"updateDragDelta");ie=!0,i(_e,["mousemove","vmousemove","tapdrag"],q,{x:W[0],y:W[1]});var Tt=o(function(){t.data.bgActivePosistion=void 0,t.hoverData.selecting||oe.emit({originalEvent:q,type:"boxstart",position:{x:W[0],y:W[1]}}),Pe[4]=1,t.hoverData.selecting=!0,t.redrawHint("select",!0),t.redraw()},"goIntoBoxMode");if(t.hoverData.which===3){if(at){var Mt={originalEvent:q,type:"cxtdrag",position:{x:W[0],y:W[1]}};Ve?Ve.emit(Mt):oe.emit(Mt),t.hoverData.cxtDragged=!0,(!t.hoverData.cxtOver||_e!==t.hoverData.cxtOver)&&(t.hoverData.cxtOver&&t.hoverData.cxtOver.emit({originalEvent:q,type:"cxtdragout",position:{x:W[0],y:W[1]}}),t.hoverData.cxtOver=_e,_e&&_e.emit({originalEvent:q,type:"cxtdragover",position:{x:W[0],y:W[1]}}))}}else if(t.hoverData.dragging){if(ie=!0,oe.panningEnabled()&&oe.userPanningEnabled()){var bt;if(t.hoverData.justStartedPan){var ut=t.hoverData.mdownPos;bt={x:(W[0]-ut[0])*V,y:(W[1]-ut[1])*V},t.hoverData.justStartedPan=!1}else bt={x:De[0]*V,y:De[1]*V};oe.panBy(bt),oe.emit("dragpan"),t.hoverData.dragged=!0}W=t.projectIntoViewport(q.clientX,q.clientY)}else if(Pe[4]==1&&(Ve==null||Ve.pannable())){if(at){if(!t.hoverData.dragging&&oe.boxSelectionEnabled()&&(ot||!oe.panningEnabled()||!oe.userPanningEnabled()))Tt();else if(!t.hoverData.selecting&&oe.panningEnabled()&&oe.userPanningEnabled()){var St=s(Ve,t.hoverData.downs);St&&(t.hoverData.dragging=!0,t.hoverData.justStartedPan=!0,Pe[4]=0,t.data.bgActivePosistion=j1(pe),t.redrawHint("select",!0),t.redraw())}Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate()}}else{if(Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate(),(!Ve||!Ve.grabbed())&&_e!=be&&(be&&i(be,["mouseout","tapdragout"],q,{x:W[0],y:W[1]}),_e&&i(_e,["mouseover","tapdragover"],q,{x:W[0],y:W[1]}),t.hoverData.last=_e),Ve)if(at){if(oe.boxSelectionEnabled()&&ot)Ve&&Ve.grabbed()&&(x(qe),Ve.emit("freeon"),qe.emit("free"),t.dragData.didDrag&&(Ve.emit("dragfreeon"),qe.emit("dragfree"))),Tt();else if(Ve&&Ve.grabbed()&&t.nodeIsDraggable(Ve)){var ft=!t.dragData.didDrag;ft&&t.redrawHint("eles",!0),t.dragData.didDrag=!0,t.hoverData.draggingEles||y(qe,{inDragLayer:!0});var vt={x:0,y:0};if(_t(De[0])&&_t(De[1])&&(vt.x+=De[0],vt.y+=De[1],ft)){var nt=t.hoverData.dragDelta;nt&&_t(nt[0])&&_t(nt[1])&&(vt.x+=nt[0],vt.y+=nt[1])}t.hoverData.draggingEles=!0,qe.silentShift(vt).emit("position drag"),t.redrawHint("drag",!0),t.redraw()}}else Yt();ie=!0}if(Pe[2]=W[0],Pe[3]=W[1],ie)return q.stopPropagation&&q.stopPropagation(),q.preventDefault&&q.preventDefault(),!1}},"mousemoveHandler"),!1);var k,L,A;t.registerBinding(e,"mouseup",o(function(q){if(!(t.hoverData.which===1&&q.which!==1&&t.hoverData.capture)){var de=t.hoverData.capture;if(de){t.hoverData.capture=!1;var ie=t.cy,oe=t.projectIntoViewport(q.clientX,q.clientY),V=t.selection,Te=t.findNearestElement(oe[0],oe[1],!0,!1),W=t.dragData.possibleDragElements,pe=t.hoverData.down,ve=a(q);if(t.data.bgActivePosistion&&(t.redrawHint("select",!0),t.redraw()),t.hoverData.tapholdCancelled=!0,t.data.bgActivePosistion=void 0,pe&&pe.unactivate(),t.hoverData.which===3){var Pe={originalEvent:q,type:"cxttapend",position:{x:oe[0],y:oe[1]}};if(pe?pe.emit(Pe):ie.emit(Pe),!t.hoverData.cxtDragged){var _e={originalEvent:q,type:"cxttap",position:{x:oe[0],y:oe[1]}};pe?pe.emit(_e):ie.emit(_e)}t.hoverData.cxtDragged=!1,t.hoverData.which=null}else if(t.hoverData.which===1){if(i(Te,["mouseup","tapend","vmouseup"],q,{x:oe[0],y:oe[1]}),!t.dragData.didDrag&&!t.hoverData.dragged&&!t.hoverData.selecting&&!t.hoverData.isOverThresholdDrag&&(i(pe,["click","tap","vclick"],q,{x:oe[0],y:oe[1]}),L=!1,q.timeStamp-A<=ie.multiClickDebounceTime()?(k&&clearTimeout(k),L=!0,A=null,i(pe,["dblclick","dbltap","vdblclick"],q,{x:oe[0],y:oe[1]})):(k=setTimeout(function(){L||i(pe,["oneclick","onetap","voneclick"],q,{x:oe[0],y:oe[1]})},ie.multiClickDebounceTime()),A=q.timeStamp)),pe==null&&!t.dragData.didDrag&&!t.hoverData.selecting&&!t.hoverData.dragged&&!a(q)&&(ie.$(r).unselect(["tapunselect"]),W.length>0&&t.redrawHint("eles",!0),t.dragData.possibleDragElements=W=ie.collection()),Te==pe&&!t.dragData.didDrag&&!t.hoverData.selecting&&Te!=null&&Te._private.selectable&&(t.hoverData.dragging||(ie.selectionType()==="additive"||ve?Te.selected()?Te.unselect(["tapunselect"]):Te.select(["tapselect"]):ve||(ie.$(r).unmerge(Te).unselect(["tapunselect"]),Te.select(["tapselect"]))),t.redrawHint("eles",!0)),t.hoverData.selecting){var be=ie.collection(t.getAllInBox(V[0],V[1],V[2],V[3]));t.redrawHint("select",!0),be.length>0&&t.redrawHint("eles",!0),ie.emit({type:"boxend",originalEvent:q,position:{x:oe[0],y:oe[1]}});var Ve=o(function(at){return at.selectable()&&!at.selected()},"eleWouldBeSelected");ie.selectionType()==="additive"||ve||ie.$(r).unmerge(be).unselect(),be.emit("box").stdFilter(Ve).select().emit("boxselect"),t.redraw()}if(t.hoverData.dragging&&(t.hoverData.dragging=!1,t.redrawHint("select",!0),t.redrawHint("eles",!0),t.redraw()),!V[4]){t.redrawHint("drag",!0),t.redrawHint("eles",!0);var De=pe&&pe.grabbed();x(W),De&&(pe.emit("freeon"),W.emit("free"),t.dragData.didDrag&&(pe.emit("dragfreeon"),W.emit("dragfree")))}}V[4]=0,t.hoverData.down=null,t.hoverData.cxtStarted=!1,t.hoverData.draggingEles=!1,t.hoverData.selecting=!1,t.hoverData.isOverThresholdDrag=!1,t.dragData.didDrag=!1,t.hoverData.dragged=!1,t.hoverData.dragDelta=[],t.hoverData.mdownPos=null,t.hoverData.mdownGPos=null,t.hoverData.which=null}}},"mouseupHandler"),!1);var I=o(function(q){if(!t.scrollingPage){var de=t.cy,ie=de.zoom(),oe=de.pan(),V=t.projectIntoViewport(q.clientX,q.clientY),Te=[V[0]*ie+oe.x,V[1]*ie+oe.y];if(t.hoverData.draggingEles||t.hoverData.dragging||t.hoverData.cxtStarted||D()){q.preventDefault();return}if(de.panningEnabled()&&de.userPanningEnabled()&&de.zoomingEnabled()&&de.userZoomingEnabled()){q.preventDefault(),t.data.wheelZooming=!0,clearTimeout(t.data.wheelTimeout),t.data.wheelTimeout=setTimeout(function(){t.data.wheelZooming=!1,t.redrawHint("eles",!0),t.redraw()},150);var W;q.deltaY!=null?W=q.deltaY/-250:q.wheelDeltaY!=null?W=q.wheelDeltaY/1e3:W=q.wheelDelta/1e3,W=W*t.wheelSensitivity;var pe=q.deltaMode===1;pe&&(W*=33);var ve=de.zoom()*Math.pow(10,W);q.type==="gesturechange"&&(ve=t.gestureStartZoom*q.scale),de.zoom({level:ve,renderedPosition:{x:Te[0],y:Te[1]}}),de.emit(q.type==="gesturechange"?"pinchzoom":"scrollzoom")}}},"wheelHandler");t.registerBinding(t.container,"wheel",I,!0),t.registerBinding(e,"scroll",o(function(q){t.scrollingPage=!0,clearTimeout(t.scrollingPageTimeout),t.scrollingPageTimeout=setTimeout(function(){t.scrollingPage=!1},250)},"scrollHandler"),!0),t.registerBinding(t.container,"gesturestart",o(function(q){t.gestureStartZoom=t.cy.zoom(),t.hasTouchStarted||q.preventDefault()},"gestureStartHandler"),!0),t.registerBinding(t.container,"gesturechange",function(xe){t.hasTouchStarted||I(xe)},!0),t.registerBinding(t.container,"mouseout",o(function(q){var de=t.projectIntoViewport(q.clientX,q.clientY);t.cy.emit({originalEvent:q,type:"mouseout",position:{x:de[0],y:de[1]}})},"mouseOutHandler"),!1),t.registerBinding(t.container,"mouseover",o(function(q){var de=t.projectIntoViewport(q.clientX,q.clientY);t.cy.emit({originalEvent:q,type:"mouseover",position:{x:de[0],y:de[1]}})},"mouseOverHandler"),!1);var M,P,B,F,z,$,U,K,ee,Y,ce,Z,ue,Q=o(function(q,de,ie,oe){return Math.sqrt((ie-q)*(ie-q)+(oe-de)*(oe-de))},"distance"),j=o(function(q,de,ie,oe){return(ie-q)*(ie-q)+(oe-de)*(oe-de)},"distanceSq"),ne;t.registerBinding(t.container,"touchstart",ne=o(function(q){if(t.hasTouchStarted=!0,!!O(q)){T(),t.touchData.capture=!0,t.data.bgActivePosistion=void 0;var de=t.cy,ie=t.touchData.now,oe=t.touchData.earlier;if(q.touches[0]){var V=t.projectIntoViewport(q.touches[0].clientX,q.touches[0].clientY);ie[0]=V[0],ie[1]=V[1]}if(q.touches[1]){var V=t.projectIntoViewport(q.touches[1].clientX,q.touches[1].clientY);ie[2]=V[0],ie[3]=V[1]}if(q.touches[2]){var V=t.projectIntoViewport(q.touches[2].clientX,q.touches[2].clientY);ie[4]=V[0],ie[5]=V[1]}if(q.touches[1]){t.touchData.singleTouchMoved=!0,x(t.dragData.touchDragEles);var Te=t.findContainerClientCoords();ee=Te[0],Y=Te[1],ce=Te[2],Z=Te[3],M=q.touches[0].clientX-ee,P=q.touches[0].clientY-Y,B=q.touches[1].clientX-ee,F=q.touches[1].clientY-Y,ue=0<=M&&M<=ce&&0<=B&&B<=ce&&0<=P&&P<=Z&&0<=F&&F<=Z;var W=de.pan(),pe=de.zoom();z=Q(M,P,B,F),$=j(M,P,B,F),U=[(M+B)/2,(P+F)/2],K=[(U[0]-W.x)/pe,(U[1]-W.y)/pe];var ve=200,Pe=ve*ve;if($=1){for(var st=t.touchData.startPosition=[null,null,null,null,null,null],Ue=0;Ue=t.touchTapThreshold2}if(de&&t.touchData.cxt){q.preventDefault();var st=q.touches[0].clientX-ee,Ue=q.touches[0].clientY-Y,ct=q.touches[1].clientX-ee,We=q.touches[1].clientY-Y,ot=j(st,Ue,ct,We),Yt=ot/$,Tt=150,Mt=Tt*Tt,bt=1.5,ut=bt*bt;if(Yt>=ut||ot>=Mt){t.touchData.cxt=!1,t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var St={originalEvent:q,type:"cxttapend",position:{x:V[0],y:V[1]}};t.touchData.start?(t.touchData.start.unactivate().emit(St),t.touchData.start=null):oe.emit(St)}}if(de&&t.touchData.cxt){var St={originalEvent:q,type:"cxtdrag",position:{x:V[0],y:V[1]}};t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.touchData.start?t.touchData.start.emit(St):oe.emit(St),t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxtDragged=!0;var ft=t.findNearestElement(V[0],V[1],!0,!0);(!t.touchData.cxtOver||ft!==t.touchData.cxtOver)&&(t.touchData.cxtOver&&t.touchData.cxtOver.emit({originalEvent:q,type:"cxtdragout",position:{x:V[0],y:V[1]}}),t.touchData.cxtOver=ft,ft&&ft.emit({originalEvent:q,type:"cxtdragover",position:{x:V[0],y:V[1]}}))}else if(de&&q.touches[2]&&oe.boxSelectionEnabled())q.preventDefault(),t.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,t.touchData.selecting||oe.emit({originalEvent:q,type:"boxstart",position:{x:V[0],y:V[1]}}),t.touchData.selecting=!0,t.touchData.didSelect=!0,ie[4]=1,!ie||ie.length===0||ie[0]===void 0?(ie[0]=(V[0]+V[2]+V[4])/3,ie[1]=(V[1]+V[3]+V[5])/3,ie[2]=(V[0]+V[2]+V[4])/3+1,ie[3]=(V[1]+V[3]+V[5])/3+1):(ie[2]=(V[0]+V[2]+V[4])/3,ie[3]=(V[1]+V[3]+V[5])/3),t.redrawHint("select",!0),t.redraw();else if(de&&q.touches[1]&&!t.touchData.didSelect&&oe.zoomingEnabled()&&oe.panningEnabled()&&oe.userZoomingEnabled()&&oe.userPanningEnabled()){q.preventDefault(),t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var vt=t.dragData.touchDragEles;if(vt){t.redrawHint("drag",!0);for(var nt=0;nt0&&!t.hoverData.draggingEles&&!t.swipePanning&&t.data.bgActivePosistion!=null&&(t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.redraw())}},"touchmoveHandler"),!1);var he;t.registerBinding(e,"touchcancel",he=o(function(q){var de=t.touchData.start;t.touchData.capture=!1,de&&de.unactivate()},"touchcancelHandler"));var le,J,Se,se;if(t.registerBinding(e,"touchend",le=o(function(q){var de=t.touchData.start,ie=t.touchData.capture;if(ie)q.touches.length===0&&(t.touchData.capture=!1),q.preventDefault();else return;var oe=t.selection;t.swipePanning=!1,t.hoverData.draggingEles=!1;var V=t.cy,Te=V.zoom(),W=t.touchData.now,pe=t.touchData.earlier;if(q.touches[0]){var ve=t.projectIntoViewport(q.touches[0].clientX,q.touches[0].clientY);W[0]=ve[0],W[1]=ve[1]}if(q.touches[1]){var ve=t.projectIntoViewport(q.touches[1].clientX,q.touches[1].clientY);W[2]=ve[0],W[3]=ve[1]}if(q.touches[2]){var ve=t.projectIntoViewport(q.touches[2].clientX,q.touches[2].clientY);W[4]=ve[0],W[5]=ve[1]}de&&de.unactivate();var Pe;if(t.touchData.cxt){if(Pe={originalEvent:q,type:"cxttapend",position:{x:W[0],y:W[1]}},de?de.emit(Pe):V.emit(Pe),!t.touchData.cxtDragged){var _e={originalEvent:q,type:"cxttap",position:{x:W[0],y:W[1]}};de?de.emit(_e):V.emit(_e)}t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxt=!1,t.touchData.start=null,t.redraw();return}if(!q.touches[2]&&V.boxSelectionEnabled()&&t.touchData.selecting){t.touchData.selecting=!1;var be=V.collection(t.getAllInBox(oe[0],oe[1],oe[2],oe[3]));oe[0]=void 0,oe[1]=void 0,oe[2]=void 0,oe[3]=void 0,oe[4]=0,t.redrawHint("select",!0),V.emit({type:"boxend",originalEvent:q,position:{x:W[0],y:W[1]}});var Ve=o(function(Mt){return Mt.selectable()&&!Mt.selected()},"eleWouldBeSelected");be.emit("box").stdFilter(Ve).select().emit("boxselect"),be.nonempty()&&t.redrawHint("eles",!0),t.redraw()}if(de?.unactivate(),q.touches[2])t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);else if(!q.touches[1]){if(!q.touches[0]){if(!q.touches[0]){t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var De=t.dragData.touchDragEles;if(de!=null){var qe=de._private.grabbed;x(De),t.redrawHint("drag",!0),t.redrawHint("eles",!0),qe&&(de.emit("freeon"),De.emit("free"),t.dragData.didDrag&&(de.emit("dragfreeon"),De.emit("dragfree"))),i(de,["touchend","tapend","vmouseup","tapdragout"],q,{x:W[0],y:W[1]}),de.unactivate(),t.touchData.start=null}else{var at=t.findNearestElement(W[0],W[1],!0,!0);i(at,["touchend","tapend","vmouseup","tapdragout"],q,{x:W[0],y:W[1]})}var Rt=t.touchData.startPosition[0]-W[0],st=Rt*Rt,Ue=t.touchData.startPosition[1]-W[1],ct=Ue*Ue,We=st+ct,ot=We*Te*Te;t.touchData.singleTouchMoved||(de||V.$(":selected").unselect(["tapunselect"]),i(de,["tap","vclick"],q,{x:W[0],y:W[1]}),J=!1,q.timeStamp-se<=V.multiClickDebounceTime()?(Se&&clearTimeout(Se),J=!0,se=null,i(de,["dbltap","vdblclick"],q,{x:W[0],y:W[1]})):(Se=setTimeout(function(){J||i(de,["onetap","voneclick"],q,{x:W[0],y:W[1]})},V.multiClickDebounceTime()),se=q.timeStamp)),de!=null&&!t.dragData.didDrag&&de._private.selectable&&ot"u"){var ae=[],Oe=o(function(q){return{clientX:q.clientX,clientY:q.clientY,force:1,identifier:q.pointerId,pageX:q.pageX,pageY:q.pageY,radiusX:q.width/2,radiusY:q.height/2,screenX:q.screenX,screenY:q.screenY,target:q.target}},"makeTouch"),ye=o(function(q){return{event:q,touch:Oe(q)}},"makePointer"),Be=o(function(q){ae.push(ye(q))},"addPointer"),He=o(function(q){for(var de=0;de0)return U[0]}return null},"getCurveT"),g=Object.keys(p),y=0;y0?m:_ge(a,s,e,r,n,i,l,u)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){u=u==="auto"?Zp(i,a):u;var h=2*u;if(ih(e,r,this.points,s,l,i,a-h,[0,-1],n)||ih(e,r,this.points,s,l,i-h,a,[0,-1],n))return!0;var f=i/2+2*n,d=a/2+2*n,p=[s-f,l-d,s-f,l,s+f,l,s+f,l-d];return!!(qs(e,r,p)||jp(e,r,h,h,s+i/2-u,l+a/2-u,n)||jp(e,r,h,h,s-i/2+u,l+a/2-u,n))},"checkPoint")}};sh.registerNodeShapes=function(){var t=this.nodeShapes={},e=this;this.generateEllipse(),this.generatePolygon("triangle",Ts(3,0)),this.generateRoundPolygon("round-triangle",Ts(3,0)),this.generatePolygon("rectangle",Ts(4,0)),t.square=t.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();{var r=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",r),this.generateRoundPolygon("round-diamond",r)}this.generatePolygon("pentagon",Ts(5,0)),this.generateRoundPolygon("round-pentagon",Ts(5,0)),this.generatePolygon("hexagon",Ts(6,0)),this.generateRoundPolygon("round-hexagon",Ts(6,0)),this.generatePolygon("heptagon",Ts(7,0)),this.generateRoundPolygon("round-heptagon",Ts(7,0)),this.generatePolygon("octagon",Ts(8,0)),this.generateRoundPolygon("round-octagon",Ts(8,0));var n=new Array(20);{var i=bB(5,0),a=bB(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;l=e.deqFastCost*S)break}else if(h){if(b>=e.deqCost*m||b>=e.deqAvgCost*p)break}else if(T>=e.deqNoDrawCost*dB)break;var w=e.deq(n,v,y);if(w.length>0)for(var E=0;E0&&(e.onDeqd(n,g),!h&&e.shouldRedraw(n,g,v,y)&&a())},"dequeue"),l=e.priority||zB;i.beforeRender(s,l(n))}},"setupDequeueingImpl")},"setupDequeueing")},KZe=function(){function t(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:z6;Vf(this,t),this.idsByKey=new Zc,this.keyForId=new Zc,this.cachesByLvl=new Zc,this.lvls=[],this.getKey=e,this.doesEleInvalidateKey=r}return o(t,"ElementTextureCacheLookup"),Uf(t,[{key:"getIdsFor",value:o(function(r){r==null&&oi("Can not get id list for null key");var n=this.idsByKey,i=this.idsByKey.get(r);return i||(i=new ay,n.set(r,i)),i},"getIdsFor")},{key:"addIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).add(n)},"addIdForKey")},{key:"deleteIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).delete(n)},"deleteIdForKey")},{key:"getNumberOfIdsForKey",value:o(function(r){return r==null?0:this.getIdsFor(r).size},"getNumberOfIdsForKey")},{key:"updateKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);this.deleteIdForKey(i,n),this.addIdForKey(a,n),this.keyForId.set(n,a)},"updateKeyMappingFor")},{key:"deleteKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteIdForKey(i,n),this.keyForId.delete(n)},"deleteKeyMappingFor")},{key:"keyHasChangedFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);return i!==a},"keyHasChangedFor")},{key:"isInvalid",value:o(function(r){return this.keyHasChangedFor(r)||this.doesEleInvalidateKey(r)},"isInvalid")},{key:"getCachesAt",value:o(function(r){var n=this.cachesByLvl,i=this.lvls,a=n.get(r);return a||(a=new Zc,n.set(r,a),i.push(r)),a},"getCachesAt")},{key:"getCache",value:o(function(r,n){return this.getCachesAt(n).get(r)},"getCache")},{key:"get",value:o(function(r,n){var i=this.getKey(r),a=this.getCache(i,n);return a!=null&&this.updateKeyMappingFor(r),a},"get")},{key:"getForCachedKey",value:o(function(r,n){var i=this.keyForId.get(r.id()),a=this.getCache(i,n);return a},"getForCachedKey")},{key:"hasCache",value:o(function(r,n){return this.getCachesAt(n).has(r)},"hasCache")},{key:"has",value:o(function(r,n){var i=this.getKey(r);return this.hasCache(i,n)},"has")},{key:"setCache",value:o(function(r,n,i){i.key=r,this.getCachesAt(n).set(r,i)},"setCache")},{key:"set",value:o(function(r,n,i){var a=this.getKey(r);this.setCache(a,n,i),this.updateKeyMappingFor(r)},"set")},{key:"deleteCache",value:o(function(r,n){this.getCachesAt(n).delete(r)},"deleteCache")},{key:"delete",value:o(function(r,n){var i=this.getKey(r);this.deleteCache(i,n)},"_delete")},{key:"invalidateKey",value:o(function(r){var n=this;this.lvls.forEach(function(i){return n.deleteCache(r,i)})},"invalidateKey")},{key:"invalidate",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteKeyMappingFor(r);var a=this.doesEleInvalidateKey(r);return a&&this.invalidateKey(i),a||this.getNumberOfIdsForKey(i)===0},"invalidate")}]),t}(),Hme=25,C6=50,B6=-4,NB=3,L1e=7.99,QZe=8,ZZe=1024,JZe=1024,eJe=1024,tJe=.2,rJe=.8,nJe=10,iJe=.15,aJe=.1,sJe=.9,oJe=.9,lJe=100,cJe=1,K1={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},uJe=oa({getKey:null,doesEleInvalidateKey:z6,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:bge,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),jb=o(function(e,r){var n=this;n.renderer=e,n.onDequeues=[];var i=uJe(r);ir(n,i),n.lookup=new KZe(i.getKey,i.doesEleInvalidateKey),n.setupDequeueing()},"ElementTextureCache"),Yi=jb.prototype;Yi.reasons=K1;Yi.getTextureQueue=function(t){var e=this;return e.eleImgCaches=e.eleImgCaches||{},e.eleImgCaches[t]=e.eleImgCaches[t]||[]};Yi.getRetiredTextureQueue=function(t){var e=this,r=e.eleImgCaches.retired=e.eleImgCaches.retired||{},n=r[t]=r[t]||[];return n};Yi.getElementQueue=function(){var t=this,e=t.eleCacheQueue=t.eleCacheQueue||new m4(function(r,n){return n.reqs-r.reqs});return e};Yi.getElementKeyToQueue=function(){var t=this,e=t.eleKeyToCacheQueue=t.eleKeyToCacheQueue||{};return e};Yi.getElement=function(t,e,r,n,i){var a=this,s=this.renderer,l=s.cy.zoom(),u=this.lookup;if(!e||e.w===0||e.h===0||isNaN(e.w)||isNaN(e.h)||!t.visible()||t.removed()||!a.allowEdgeTxrCaching&&t.isEdge()||!a.allowParentTxrCaching&&t.isParent())return null;if(n==null&&(n=Math.ceil(VB(l*r))),n=L1e||n>NB)return null;var h=Math.pow(2,n),f=e.h*h,d=e.w*h,p=s.eleTextBiggerThanMin(t,h);if(!this.isVisible(t,p))return null;var m=u.get(t,n);if(m&&m.invalidated&&(m.invalidated=!1,m.texture.invalidatedWidth-=m.width),m)return m;var g;if(f<=Hme?g=Hme:f<=C6?g=C6:g=Math.ceil(f/C6)*C6,f>eJe||d>JZe)return null;var y=a.getTextureQueue(g),v=y[y.length-2],x=o(function(){return a.recycleTexture(g,d)||a.addTexture(g,d)},"addNewTxr");v||(v=y[y.length-1]),v||(v=x()),v.width-v.usedWidthn;R--)D=a.getElement(t,e,r,R,K1.downscale);O()}else return a.queueElement(t,E.level-1),E;else{var k;if(!T&&!S&&!w)for(var L=n-1;L>=B6;L--){var A=u.get(t,L);if(A){k=A;break}}if(b(k))return a.queueElement(t,n),k;v.context.translate(v.usedWidth,0),v.context.scale(h,h),this.drawElement(v.context,t,e,p,!1),v.context.scale(1/h,1/h),v.context.translate(-v.usedWidth,0)}return m={x:v.usedWidth,texture:v,level:n,scale:h,width:d,height:f,scaledLabelShown:p},v.usedWidth+=Math.ceil(d+QZe),v.eleCaches.push(m),u.set(t,n,m),a.checkTextureFullness(v),m};Yi.invalidateElements=function(t){for(var e=0;e=tJe*t.width&&this.retireTexture(t)};Yi.checkTextureFullness=function(t){var e=this,r=e.getTextureQueue(t.height);t.usedWidth/t.width>rJe&&t.fullnessChecks>=nJe?Ff(r,t):t.fullnessChecks++};Yi.retireTexture=function(t){var e=this,r=t.height,n=e.getTextureQueue(r),i=this.lookup;Ff(n,t),t.retired=!0;for(var a=t.eleCaches,s=0;s=e)return s.retired=!1,s.usedWidth=0,s.invalidatedWidth=0,s.fullnessChecks=0,GB(s.eleCaches),s.context.setTransform(1,0,0,1,0,0),s.context.clearRect(0,0,s.width,s.height),Ff(i,s),n.push(s),s}};Yi.queueElement=function(t,e){var r=this,n=r.getElementQueue(),i=r.getElementKeyToQueue(),a=this.getKey(t),s=i[a];if(s)s.level=Math.max(s.level,e),s.eles.merge(t),s.reqs++,n.updateItem(s);else{var l={eles:t.spawn().merge(t),level:e,reqs:1,key:a};n.push(l),i[a]=l}};Yi.dequeue=function(t){for(var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=[],a=e.lookup,s=0;s0;s++){var l=r.pop(),u=l.key,h=l.eles[0],f=a.hasCache(h,l.level);if(n[u]=null,f)continue;i.push(l);var d=e.getBoundingBox(h);e.getElement(h,d,t,l.level,K1.dequeue)}return i};Yi.removeFromQueue=function(t){var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=this.getKey(t),a=n[i];a!=null&&(a.eles.length===1?(a.reqs=$B,r.updateItem(a),r.pop(),n[i]=null):a.eles.unmerge(t))};Yi.onDequeue=function(t){this.onDequeues.push(t)};Yi.offDequeue=function(t){Ff(this.onDequeues,t)};Yi.setupDequeueing=D1e.setupDequeueing({deqRedrawThreshold:lJe,deqCost:iJe,deqAvgCost:aJe,deqNoDrawCost:sJe,deqFastCost:oJe,deq:o(function(e,r,n){return e.dequeue(r,n)},"deq"),onDeqd:o(function(e,r){for(var n=0;n=fJe||r>X6)return null}n.validateLayersElesOrdering(r,t);var u=n.layersByLevel,h=Math.pow(2,r),f=u[r]=u[r]||[],d,p=n.levelIsComplete(r,t),m,g=o(function(){var O=o(function(I){if(n.validateLayersElesOrdering(I,t),n.levelIsComplete(I,t))return m=u[I],!0},"canUseAsTmpLvl"),R=o(function(I){if(!m)for(var M=r+I;Qb<=M&&M<=X6&&!O(M);M+=I);},"checkLvls");R(1),R(-1);for(var k=f.length-1;k>=0;k--){var L=f[k];L.invalid&&Ff(f,L)}},"checkTempLevels");if(!p)g();else return f;var y=o(function(){if(!d){d=Ys();for(var O=0;Oqme||L>qme)return null;var A=k*L;if(A>bJe)return null;var I=n.makeLayer(d,r);if(R!=null){var M=f.indexOf(R)+1;f.splice(M,0,I)}else(O.insert===void 0||O.insert)&&f.unshift(I);return I},"makeLayer");if(n.skipping&&!l)return null;for(var x=null,b=t.length/hJe,T=!l,S=0;S=b||!Age(x.bb,w.boundingBox()))&&(x=v({insert:!0,after:x}),!x))return null;m||T?n.queueLayer(x,w):n.drawEleInLayer(x,w,r,e),x.eles.push(w),_[r]=x}return m||(T?null:f)};Ca.getEleLevelForLayerLevel=function(t,e){return t};Ca.drawEleInLayer=function(t,e,r,n){var i=this,a=this.renderer,s=t.context,l=e.boundingBox();l.w===0||l.h===0||!e.visible()||(r=i.getEleLevelForLayerLevel(r,n),a.setImgSmoothing(s,!1),a.drawCachedElement(s,e,null,null,r,TJe),a.setImgSmoothing(s,!0))};Ca.levelIsComplete=function(t,e){var r=this,n=r.layersByLevel[t];if(!n||n.length===0)return!1;for(var i=0,a=0;a0||s.invalid)return!1;i+=s.eles.length}return i===e.length};Ca.validateLayersElesOrdering=function(t,e){var r=this.layersByLevel[t];if(r)for(var n=0;n0){e=!0;break}}return e};Ca.invalidateElements=function(t){var e=this;t.length!==0&&(e.lastInvalidationTime=nh(),!(t.length===0||!e.haveLayers())&&e.updateElementsInLayers(t,o(function(n,i,a){e.invalidateLayer(n)},"invalAssocLayers")))};Ca.invalidateLayer=function(t){if(this.lastInvalidationTime=nh(),!t.invalid){var e=t.level,r=t.eles,n=this.layersByLevel[e];Ff(n,t),t.elesQueue=[],t.invalid=!0,t.replacement&&(t.replacement.invalid=!0);for(var i=0;i3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l=e._private.rscratch;if(!(a&&!e.visible())&&!(l.badLine||l.allpts==null||isNaN(l.allpts[0]))){var u;r&&(u=r,t.translate(-u.x1,-u.y1));var h=a?e.pstyle("opacity").value:1,f=a?e.pstyle("line-opacity").value:1,d=e.pstyle("curve-style").value,p=e.pstyle("line-style").value,m=e.pstyle("width").pfValue,g=e.pstyle("line-cap").value,y=e.pstyle("line-outline-width").value,v=e.pstyle("line-outline-color").value,x=h*f,b=h*f,T=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;d==="straight-triangle"?(s.eleStrokeStyle(t,e,I),s.drawEdgeTrianglePath(e,t,l.allpts)):(t.lineWidth=m,t.lineCap=g,s.eleStrokeStyle(t,e,I),s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLine"),S=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;if(t.lineWidth=m+y,t.lineCap=g,y>0)s.colorStrokeStyle(t,v[0],v[1],v[2],I);else{t.lineCap="butt";return}d==="straight-triangle"?s.drawEdgeTrianglePath(e,t,l.allpts):(s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLineOutline"),w=o(function(){i&&s.drawEdgeOverlay(t,e)},"drawOverlay"),E=o(function(){i&&s.drawEdgeUnderlay(t,e)},"drawUnderlay"),_=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:b;s.drawArrowheads(t,e,I)},"drawArrows"),C=o(function(){s.drawElementText(t,e,null,n)},"drawText");t.lineJoin="round";var D=e.pstyle("ghost").value==="yes";if(D){var O=e.pstyle("ghost-offset-x").pfValue,R=e.pstyle("ghost-offset-y").pfValue,k=e.pstyle("ghost-opacity").value,L=x*k;t.translate(O,R),T(L),_(L),t.translate(-O,-R)}else S();E(),T(),_(),w(),C(),r&&t.translate(u.x1,u.y1)}};M1e=o(function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(r,n){if(n.visible()){var i=n.pstyle("".concat(e,"-opacity")).value;if(i!==0){var a=this,s=a.usePaths(),l=n._private.rscratch,u=n.pstyle("".concat(e,"-padding")).pfValue,h=2*u,f=n.pstyle("".concat(e,"-color")).value;r.lineWidth=h,l.edgeType==="self"&&!s?r.lineCap="butt":r.lineCap="round",a.colorStrokeStyle(r,f[0],f[1],f[2],i),a.drawEdgePath(n,r,l.allpts,"solid")}}}},"drawEdgeOverlayUnderlay");oh.drawEdgeOverlay=M1e("overlay");oh.drawEdgeUnderlay=M1e("underlay");oh.drawEdgePath=function(t,e,r,n){var i=t._private.rscratch,a=e,s,l=!1,u=this.usePaths(),h=t.pstyle("line-dash-pattern").pfValue,f=t.pstyle("line-dash-offset").pfValue;if(u){var d=r.join("$"),p=i.pathCacheKey&&i.pathCacheKey===d;p?(s=e=i.pathCache,l=!0):(s=e=new Path2D,i.pathCacheKey=d,i.pathCache=s)}if(a.setLineDash)switch(n){case"dotted":a.setLineDash([1,1]);break;case"dashed":a.setLineDash(h),a.lineDashOffset=f;break;case"solid":a.setLineDash([]);break}if(!l&&!i.badLine)switch(e.beginPath&&e.beginPath(),e.moveTo(r[0],r[1]),i.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var m=2;m+35&&arguments[5]!==void 0?arguments[5]:!0,s=this;if(n==null){if(a&&!s.eleTextBiggerThanMin(e))return}else if(n===!1)return;if(e.isNode()){var l=e.pstyle("label");if(!l||!l.value)return;var u=s.getLabelJustification(e);t.textAlign=u,t.textBaseline="bottom"}else{var h=e.element()._private.rscratch.badLine,f=e.pstyle("label"),d=e.pstyle("source-label"),p=e.pstyle("target-label");if(h||(!f||!f.value)&&(!d||!d.value)&&(!p||!p.value))return;t.textAlign="center",t.textBaseline="bottom"}var m=!r,g;r&&(g=r,t.translate(-g.x1,-g.y1)),i==null?(s.drawText(t,e,null,m,a),e.isEdge()&&(s.drawText(t,e,"source",m,a),s.drawText(t,e,"target",m,a))):s.drawText(t,e,i,m,a),r&&t.translate(g.x1,g.y1)};n0.getFontCache=function(t){var e;this.fontCaches=this.fontCaches||[];for(var r=0;r2&&arguments[2]!==void 0?arguments[2]:!0,n=e.pstyle("font-style").strValue,i=e.pstyle("font-size").pfValue+"px",a=e.pstyle("font-family").strValue,s=e.pstyle("font-weight").strValue,l=r?e.effectiveOpacity()*e.pstyle("text-opacity").value:1,u=e.pstyle("text-outline-opacity").value*l,h=e.pstyle("color").value,f=e.pstyle("text-outline-color").value;t.font=n+" "+s+" "+i+" "+a,t.lineJoin="round",this.colorFillStyle(t,h[0],h[1],h[2],l),this.colorStrokeStyle(t,f[0],f[1],f[2],u)};o(mB,"roundRect");n0.getTextAngle=function(t,e){var r,n=t._private,i=n.rscratch,a=e?e+"-":"",s=t.pstyle(a+"text-rotation");if(s.strValue==="autorotate"){var l=Wl(i,"labelAngle",e);r=t.isEdge()?l:0}else s.strValue==="none"?r=0:r=s.pfValue;return r};n0.drawText=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=e._private,s=a.rscratch,l=i?e.effectiveOpacity():1;if(!(i&&(l===0||e.pstyle("text-opacity").value===0))){r==="main"&&(r=null);var u=Wl(s,"labelX",r),h=Wl(s,"labelY",r),f,d,p=this.getLabelText(e,r);if(p!=null&&p!==""&&!isNaN(u)&&!isNaN(h)){this.setupTextStyle(t,e,i);var m=r?r+"-":"",g=Wl(s,"labelWidth",r),y=Wl(s,"labelHeight",r),v=e.pstyle(m+"text-margin-x").pfValue,x=e.pstyle(m+"text-margin-y").pfValue,b=e.isEdge(),T=e.pstyle("text-halign").value,S=e.pstyle("text-valign").value;b&&(T="center",S="center"),u+=v,h+=x;var w;switch(n?w=this.getTextAngle(e,r):w=0,w!==0&&(f=u,d=h,t.translate(f,d),t.rotate(w),u=0,h=0),S){case"top":break;case"center":h+=y/2;break;case"bottom":h+=y;break}var E=e.pstyle("text-background-opacity").value,_=e.pstyle("text-border-opacity").value,C=e.pstyle("text-border-width").pfValue,D=e.pstyle("text-background-padding").pfValue,O=e.pstyle("text-background-shape").strValue,R=O.indexOf("round")===0,k=2;if(E>0||C>0&&_>0){var L=u-D;switch(T){case"left":L-=g;break;case"center":L-=g/2;break}var A=h-y-D,I=g+2*D,M=y+2*D;if(E>0){var P=t.fillStyle,B=e.pstyle("text-background-color").value;t.fillStyle="rgba("+B[0]+","+B[1]+","+B[2]+","+E*l+")",R?mB(t,L,A,I,M,k):t.fillRect(L,A,I,M),t.fillStyle=P}if(C>0&&_>0){var F=t.strokeStyle,z=t.lineWidth,$=e.pstyle("text-border-color").value,U=e.pstyle("text-border-style").value;if(t.strokeStyle="rgba("+$[0]+","+$[1]+","+$[2]+","+_*l+")",t.lineWidth=C,t.setLineDash)switch(U){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"double":t.lineWidth=C/4,t.setLineDash([]);break;case"solid":t.setLineDash([]);break}if(R?mB(t,L,A,I,M,k,"stroke"):t.strokeRect(L,A,I,M),U==="double"){var K=C/2;R?mB(t,L+K,A+K,I-K*2,M-K*2,k,"stroke"):t.strokeRect(L+K,A+K,I-K*2,M-K*2)}t.setLineDash&&t.setLineDash([]),t.lineWidth=z,t.strokeStyle=F}}var ee=2*e.pstyle("text-outline-width").pfValue;if(ee>0&&(t.lineWidth=ee),e.pstyle("text-wrap").value==="wrap"){var Y=Wl(s,"labelWrapCachedLines",r),ce=Wl(s,"labelLineHeight",r),Z=g/2,ue=this.getLabelJustification(e);switch(ue==="auto"||(T==="left"?ue==="left"?u+=-g:ue==="center"&&(u+=-Z):T==="center"?ue==="left"?u+=-Z:ue==="right"&&(u+=Z):T==="right"&&(ue==="center"?u+=Z:ue==="right"&&(u+=g))),S){case"top":h-=(Y.length-1)*ce;break;case"center":case"bottom":h-=(Y.length-1)*ce;break}for(var Q=0;Q0&&t.strokeText(Y[Q],u,h),t.fillText(Y[Q],u,h),h+=ce}else ee>0&&t.strokeText(p,u,h),t.fillText(p,u,h);w!==0&&(t.rotate(-w),t.translate(-f,-d))}}};py={};py.drawNode=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l,u,h=e._private,f=h.rscratch,d=e.position();if(!(!_t(d.x)||!_t(d.y))&&!(a&&!e.visible())){var p=a?e.effectiveOpacity():1,m=s.usePaths(),g,y=!1,v=e.padding();l=e.width()+2*v,u=e.height()+2*v;var x;r&&(x=r,t.translate(-x.x1,-x.y1));for(var b=e.pstyle("background-image"),T=b.value,S=new Array(T.length),w=new Array(T.length),E=0,_=0;_0&&arguments[0]!==void 0?arguments[0]:L;s.eleFillStyle(t,e,oe)},"setupShapeColor"),Q=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:$;s.colorStrokeStyle(t,A[0],A[1],A[2],oe)},"setupBorderColor"),j=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Y;s.colorStrokeStyle(t,K[0],K[1],K[2],oe)},"setupOutlineColor"),ne=o(function(oe,V,Te,W){var pe=s.nodePathCache=s.nodePathCache||[],ve=xge(Te==="polygon"?Te+","+W.join(","):Te,""+V,""+oe,""+Z),Pe=pe[ve],_e,be=!1;return Pe!=null?(_e=Pe,be=!0,f.pathCache=_e):(_e=new Path2D,pe[ve]=f.pathCache=_e),{path:_e,cacheHit:be}},"getPath"),te=e.pstyle("shape").strValue,he=e.pstyle("shape-polygon-points").pfValue;if(m){t.translate(d.x,d.y);var le=ne(l,u,te,he);g=le.path,y=le.cacheHit}var J=o(function(){if(!y){var oe=d;m&&(oe={x:0,y:0}),s.nodeShapes[s.getNodeShape(e)].draw(g||t,oe.x,oe.y,l,u,Z,f)}m?t.fill(g):t.fill()},"drawShape"),Se=o(function(){for(var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,Te=h.backgrounding,W=0,pe=0;pe0&&arguments[0]!==void 0?arguments[0]:!1,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:p;s.hasPie(e)&&(s.drawPie(t,e,V),oe&&(m||s.nodeShapes[s.getNodeShape(e)].draw(t,d.x,d.y,l,u,Z,f)))},"drawPie"),ae=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=(R>0?R:-R)*oe,Te=R>0?0:255;R!==0&&(s.colorFillStyle(t,Te,Te,Te,V),m?t.fill(g):t.fill())},"darken"),Oe=o(function(){if(k>0){if(t.lineWidth=k,t.lineCap=P,t.lineJoin=M,t.setLineDash)switch(I){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash(F),t.lineDashOffset=z;break;case"solid":case"double":t.setLineDash([]);break}if(B!=="center"){if(t.save(),t.lineWidth*=2,B==="inside")m?t.clip(g):t.clip();else{var oe=new Path2D;oe.rect(-l/2-k,-u/2-k,l+2*k,u+2*k),oe.addPath(g),t.clip(oe,"evenodd")}m?t.stroke(g):t.stroke(),t.restore()}else m?t.stroke(g):t.stroke();if(I==="double"){t.lineWidth=k/3;var V=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",m?t.stroke(g):t.stroke(),t.globalCompositeOperation=V}t.setLineDash&&t.setLineDash([])}},"drawBorder"),ye=o(function(){if(U>0){if(t.lineWidth=U,t.lineCap="butt",t.setLineDash)switch(ee){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"solid":case"double":t.setLineDash([]);break}var oe=d;m&&(oe={x:0,y:0});var V=s.getNodeShape(e),Te=k;B==="inside"&&(Te=0),B==="outside"&&(Te*=2);var W=(l+Te+(U+ce))/l,pe=(u+Te+(U+ce))/u,ve=l*W,Pe=u*pe,_e=s.nodeShapes[V].points,be;if(m){var Ve=ne(ve,Pe,V,_e);be=Ve.path}if(V==="ellipse")s.drawEllipsePath(be||t,oe.x,oe.y,ve,Pe);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(V)){var De=0,qe=0,at=0;V==="round-diamond"?De=(Te+ce+U)*1.4:V==="round-heptagon"?(De=(Te+ce+U)*1.075,at=-(Te/2+ce+U)/35):V==="round-hexagon"?De=(Te+ce+U)*1.12:V==="round-pentagon"?(De=(Te+ce+U)*1.13,at=-(Te/2+ce+U)/15):V==="round-tag"?(De=(Te+ce+U)*1.12,qe=(Te/2+U+ce)*.07):V==="round-triangle"&&(De=(Te+ce+U)*(Math.PI/2),at=-(Te+ce/2+U)/Math.PI),De!==0&&(W=(l+De)/l,ve=l*W,["round-hexagon","round-tag"].includes(V)||(pe=(u+De)/u,Pe=u*pe)),Z=Z==="auto"?Lge(ve,Pe):Z;for(var Rt=ve/2,st=Pe/2,Ue=Z+(Te+U+ce)/2,ct=new Array(_e.length/2),We=new Array(_e.length/2),ot=0;ot<_e.length/2;ot++)ct[ot]={x:oe.x+qe+Rt*_e[ot*2],y:oe.y+at+st*_e[ot*2+1]};var Yt,Tt,Mt,bt,ut=ct.length;for(Tt=ct[ut-1],Yt=0;Yt0){if(i=i||n.position(),a==null||s==null){var m=n.padding();a=n.width()+2*m,s=n.height()+2*m}l.colorFillStyle(r,f[0],f[1],f[2],h),l.nodeShapes[d].draw(r,i.x,i.y,a+u*2,s+u*2,p),r.fill()}}}},"drawNodeOverlayUnderlay");py.drawNodeOverlay=I1e("overlay");py.drawNodeUnderlay=I1e("underlay");py.hasPie=function(t){return t=t[0],t._private.hasPie};py.drawPie=function(t,e,r,n){e=e[0],n=n||e.position();var i=e.cy().style(),a=e.pstyle("pie-size"),s=n.x,l=n.y,u=e.width(),h=e.height(),f=Math.min(u,h)/2,d=0,p=this.usePaths();p&&(s=0,l=0),a.units==="%"?f=f*a.pfValue:a.pfValue!==void 0&&(f=a.pfValue/2);for(var m=1;m<=i.pieBackgroundN;m++){var g=e.pstyle("pie-"+m+"-background-size").value,y=e.pstyle("pie-"+m+"-background-color").value,v=e.pstyle("pie-"+m+"-background-opacity").value*r,x=g/100;x+d>1&&(x=1-d);var b=1.5*Math.PI+2*Math.PI*d,T=2*Math.PI*x,S=b+T;g===0||d>=1||d+x>1||(t.beginPath(),t.moveTo(s,l),t.arc(s,l,f,b,S),t.closePath(),this.colorFillStyle(t,y[0],y[1],y[2],v),t.fill(),d+=x)}};ws={},NJe=100;ws.getPixelRatio=function(){var t=this.data.contexts[0];if(this.forcedPixelRatio!=null)return this.forcedPixelRatio;var e=this.cy.window(),r=t.backingStorePixelRatio||t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return(e.devicePixelRatio||1)/r};ws.paintCache=function(t){for(var e=this.paintCaches=this.paintCaches||[],r=!0,n,i=0;ie.minMbLowQualFrames&&(e.motionBlurPxRatio=e.mbPxRBlurry)),e.clearingMotionBlur&&(e.motionBlurPxRatio=1),e.textureDrawLastFrame&&!d&&(f[e.NODE]=!0,f[e.SELECT_BOX]=!0);var b=r.style(),T=r.zoom(),S=s!==void 0?s:T,w=r.pan(),E={x:w.x,y:w.y},_={zoom:T,pan:{x:w.x,y:w.y}},C=e.prevViewport,D=C===void 0||_.zoom!==C.zoom||_.pan.x!==C.pan.x||_.pan.y!==C.pan.y;!D&&!(y&&!g)&&(e.motionBlurPxRatio=1),l&&(E=l),S*=u,E.x*=u,E.y*=u;var O=e.getCachedZSortedEles();function R(Q,j,ne,te,he){var le=Q.globalCompositeOperation;Q.globalCompositeOperation="destination-out",e.colorFillStyle(Q,255,255,255,e.motionBlurTransparency),Q.fillRect(j,ne,te,he),Q.globalCompositeOperation=le}o(R,"mbclear");function k(Q,j){var ne,te,he,le;!e.clearingMotionBlur&&(Q===h.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]||Q===h.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG])?(ne={x:w.x*m,y:w.y*m},te=T*m,he=e.canvasWidth*m,le=e.canvasHeight*m):(ne=E,te=S,he=e.canvasWidth,le=e.canvasHeight),Q.setTransform(1,0,0,1,0,0),j==="motionBlur"?R(Q,0,0,he,le):!n&&(j===void 0||j)&&Q.clearRect(0,0,he,le),i||(Q.translate(ne.x,ne.y),Q.scale(te,te)),l&&Q.translate(l.x,l.y),s&&Q.scale(s,s)}if(o(k,"setContextTransform"),d||(e.textureDrawLastFrame=!1),d){if(e.textureDrawLastFrame=!0,!e.textureCache){e.textureCache={},e.textureCache.bb=r.mutableElements().boundingBox(),e.textureCache.texture=e.data.bufferCanvases[e.TEXTURE_BUFFER];var L=e.data.bufferContexts[e.TEXTURE_BUFFER];L.setTransform(1,0,0,1,0,0),L.clearRect(0,0,e.canvasWidth*e.textureMult,e.canvasHeight*e.textureMult),e.render({forcedContext:L,drawOnlyNodeLayer:!0,forcedPxRatio:u*e.textureMult});var _=e.textureCache.viewport={zoom:r.zoom(),pan:r.pan(),width:e.canvasWidth,height:e.canvasHeight};_.mpan={x:(0-_.pan.x)/_.zoom,y:(0-_.pan.y)/_.zoom}}f[e.DRAG]=!1,f[e.NODE]=!1;var A=h.contexts[e.NODE],I=e.textureCache.texture,_=e.textureCache.viewport;A.setTransform(1,0,0,1,0,0),p?R(A,0,0,_.width,_.height):A.clearRect(0,0,_.width,_.height);var M=b.core("outside-texture-bg-color").value,P=b.core("outside-texture-bg-opacity").value;e.colorFillStyle(A,M[0],M[1],M[2],P),A.fillRect(0,0,_.width,_.height);var T=r.zoom();k(A,!1),A.clearRect(_.mpan.x,_.mpan.y,_.width/_.zoom/u,_.height/_.zoom/u),A.drawImage(I,_.mpan.x,_.mpan.y,_.width/_.zoom/u,_.height/_.zoom/u)}else e.textureOnViewport&&!n&&(e.textureCache=null);var B=r.extent(),F=e.pinching||e.hoverData.dragging||e.swipePanning||e.data.wheelZooming||e.hoverData.draggingEles||e.cy.animated(),z=e.hideEdgesOnViewport&&F,$=[];if($[e.NODE]=!f[e.NODE]&&p&&!e.clearedForMotionBlur[e.NODE]||e.clearingMotionBlur,$[e.NODE]&&(e.clearedForMotionBlur[e.NODE]=!0),$[e.DRAG]=!f[e.DRAG]&&p&&!e.clearedForMotionBlur[e.DRAG]||e.clearingMotionBlur,$[e.DRAG]&&(e.clearedForMotionBlur[e.DRAG]=!0),f[e.NODE]||i||a||$[e.NODE]){var U=p&&!$[e.NODE]&&m!==1,A=n||(U?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]:h.contexts[e.NODE]),K=p&&!U?"motionBlur":void 0;k(A,K),z?e.drawCachedNodes(A,O.nondrag,u,B):e.drawLayeredElements(A,O.nondrag,u,B),e.debug&&e.drawDebugPoints(A,O.nondrag),!i&&!p&&(f[e.NODE]=!1)}if(!a&&(f[e.DRAG]||i||$[e.DRAG])){var U=p&&!$[e.DRAG]&&m!==1,A=n||(U?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG]:h.contexts[e.DRAG]);k(A,p&&!U?"motionBlur":void 0),z?e.drawCachedNodes(A,O.drag,u,B):e.drawCachedElements(A,O.drag,u,B),e.debug&&e.drawDebugPoints(A,O.drag),!i&&!p&&(f[e.DRAG]=!1)}if(this.drawSelectionRectangle(t,k),p&&m!==1){var ee=h.contexts[e.NODE],Y=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_NODE],ce=h.contexts[e.DRAG],Z=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_DRAG],ue=o(function(j,ne,te){j.setTransform(1,0,0,1,0,0),te||!x?j.clearRect(0,0,e.canvasWidth,e.canvasHeight):R(j,0,0,e.canvasWidth,e.canvasHeight);var he=m;j.drawImage(ne,0,0,e.canvasWidth*he,e.canvasHeight*he,0,0,e.canvasWidth,e.canvasHeight)},"drawMotionBlur");(f[e.NODE]||$[e.NODE])&&(ue(ee,Y,$[e.NODE]),f[e.NODE]=!1),(f[e.DRAG]||$[e.DRAG])&&(ue(ce,Z,$[e.DRAG]),f[e.DRAG]=!1)}e.prevViewport=_,e.clearingMotionBlur&&(e.clearingMotionBlur=!1,e.motionBlurCleared=!0,e.motionBlur=!0),p&&(e.motionBlurTimeout=setTimeout(function(){e.motionBlurTimeout=null,e.clearedForMotionBlur[e.NODE]=!1,e.clearedForMotionBlur[e.DRAG]=!1,e.motionBlur=!1,e.clearingMotionBlur=!d,e.mbFrames=0,f[e.NODE]=!0,f[e.DRAG]=!0,e.redraw()},NJe)),n||r.emit("render")};ws.drawSelectionRectangle=function(t,e){var r=this,n=r.cy,i=r.data,a=n.style(),s=t.drawOnlyNodeLayer,l=t.drawAllLayers,u=i.canvasNeedsRedraw,h=t.forcedContext;if(r.showFps||!s&&u[r.SELECT_BOX]&&!l){var f=h||i.contexts[r.SELECT_BOX];if(e(f),r.selection[4]==1&&(r.hoverData.selecting||r.touchData.selecting)){var d=r.cy.zoom(),p=a.core("selection-box-border-width").value/d;f.lineWidth=p,f.fillStyle="rgba("+a.core("selection-box-color").value[0]+","+a.core("selection-box-color").value[1]+","+a.core("selection-box-color").value[2]+","+a.core("selection-box-opacity").value+")",f.fillRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]),p>0&&(f.strokeStyle="rgba("+a.core("selection-box-border-color").value[0]+","+a.core("selection-box-border-color").value[1]+","+a.core("selection-box-border-color").value[2]+","+a.core("selection-box-opacity").value+")",f.strokeRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]))}if(i.bgActivePosistion&&!r.hoverData.selecting){var d=r.cy.zoom(),m=i.bgActivePosistion;f.fillStyle="rgba("+a.core("active-bg-color").value[0]+","+a.core("active-bg-color").value[1]+","+a.core("active-bg-color").value[2]+","+a.core("active-bg-opacity").value+")",f.beginPath(),f.arc(m.x,m.y,a.core("active-bg-size").pfValue/d,0,2*Math.PI),f.fill()}var g=r.lastRedrawTime;if(r.showFps&&g){g=Math.round(g);var y=Math.round(1e3/g),v="1 frame = "+g+" ms = "+y+" fps";if(f.setTransform(1,0,0,1,0,0),f.fillStyle="rgba(255, 0, 0, 0.75)",f.strokeStyle="rgba(255, 0, 0, 0.75)",f.font="30px Arial",!Ub){var x=f.measureText(v);Ub=x.actualBoundingBoxAscent}f.fillText(v,0,Ub);var b=60;f.strokeRect(0,Ub+10,250,20),f.fillRect(0,Ub+10,250*Math.min(y/b,1),20)}l||(u[r.SELECT_BOX]=!1)}};o(Kme,"compileShader");o(MJe,"createProgram");o(IJe,"createTextureCanvas");o(aF,"getEffectivePanZoom");o(gB,"modelToRenderedPosition");o(A6,"toWebGLColor");o(_6,"indexToVec4");o(OJe,"vec4ToIndex");o(PJe,"createTexture");o(O1e,"getTypeInfo");o(P1e,"createTypedArray");o(BJe,"createTypedArrayView");o(FJe,"createBufferStaticDraw");o(yo,"createBufferDynamicDraw");o($Je,"createPickingFrameBuffer");Qme=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});o(Zb,"create");o(B1e,"identity");o(zJe,"multiply");o(j6,"translate");o(F1e,"rotate");o(sF,"scale");o(GJe,"projection");Jb={SCREEN:{name:"screen",screen:!0},PICKING:{name:"picking",picking:!0}},Hb=oa({getKey:null,drawElement:null,getBoundingBox:null,getRotation:null,getRotationPoint:null,getRotationOffset:null,isVisible:null,getPadding:null}),VJe=function(){function t(e,r){Vf(this,t),this.debugID=Math.floor(Math.random()*1e4),this.r=e,this.atlasSize=r.webglTexSize,this.rows=r.webglTexRows,this.enableWrapping=r.enableWrapping,this.texHeight=Math.floor(this.atlasSize/this.rows),this.maxTexWidth=this.atlasSize,this.texture=null,this.canvas=null,this.needsBuffer=!0,this.freePointer={x:0,row:0},this.keyToLocation=new Map,this.canvas=r.createTextureCanvas(e,this.atlasSize,this.atlasSize),this.scratch=r.createTextureCanvas(e,this.atlasSize,this.texHeight,"scratch")}return o(t,"Atlas"),Uf(t,[{key:"getKeys",value:o(function(){return new Set(this.keyToLocation.keys())},"getKeys")},{key:"getScale",value:o(function(r){var n=r.w,i=r.h,a=this.texHeight,s=this.maxTexWidth,l=a/i,u=n*l,h=i*l;return u>s&&(l=s/n,u=n*l,h=i*l),{scale:l,texW:u,texH:h}},"getScale")},{key:"draw",value:o(function(r,n,i){var a=this,s=this.atlasSize,l=this.rows,u=this.texHeight,h=this.getScale(n),f=h.scale,d=h.texW,p=h.texH,m=[null,null],g=o(function(T,S){if(i&&S){var w=S.context,E=T.x,_=T.row,C=E,D=u*_;w.save(),w.translate(C,D),w.scale(f,f),i(w,n),w.restore()}},"drawAt"),y=o(function(){g(a.freePointer,a.canvas),m[0]={x:a.freePointer.x,y:a.freePointer.row*u,w:d,h:p},m[1]={x:a.freePointer.x+d,y:a.freePointer.row*u,w:0,h:p},a.freePointer.x+=d,a.freePointer.x==s&&(a.freePointer.x=0,a.freePointer.row++)},"drawNormal"),v=o(function(){var T=a.scratch,S=a.canvas;T.clear(),g({x:0,row:0},T);var w=s-a.freePointer.x,E=d-w,_=u;{var C=a.freePointer.x,D=a.freePointer.row*u,O=w;S.context.drawImage(T,0,0,O,_,C,D,O,_),m[0]={x:C,y:D,w:O,h:p}}{var R=w,k=(a.freePointer.row+1)*u,L=E;S&&S.context.drawImage(T,R,0,L,_,0,k,L,_),m[1]={x:0,y:k,w:L,h:p}}a.freePointer.x=E,a.freePointer.row++},"drawWrapped"),x=o(function(){a.freePointer.x=0,a.freePointer.row++},"moveToStartOfNextRow");if(this.freePointer.x+d<=s)y();else{if(this.freePointer.row>=l-1)return!1;this.freePointer.x===s?(x(),y()):this.enableWrapping?v():(x(),y())}return this.keyToLocation.set(r,m),this.needsBuffer=!0,m},"draw")},{key:"getOffsets",value:o(function(r){return this.keyToLocation.get(r)},"getOffsets")},{key:"isEmpty",value:o(function(){return this.freePointer.x===0&&this.freePointer.row===0},"isEmpty")},{key:"canFit",value:o(function(r){var n=this.atlasSize,i=this.rows,a=this.getScale(r),s=a.texW;return this.freePointer.x+s>n?this.freePointer.row1&&arguments[1]!==void 0?arguments[1]:{},i=n.forceRedraw,a=i===void 0?!1:i,s=n.filterEle,l=s===void 0?function(){return!0}:s,u=n.filterType,h=u===void 0?function(){return!0}:u,f=!1,d=vo(r),p;try{for(d.s();!(p=d.n()).done;){var m=p.value;if(l(m)){var g=m.id(),y=vo(this.getRenderTypes()),v;try{for(y.s();!(v=y.n()).done;){var x=v.value;if(h(x.type)){var b=x.getKey(m);a?(x.atlasCollection.deleteKey(g,b),x.atlasCollection.styleKeyNeedsRedraw.add(b),f=!0):f|=x.atlasCollection.checkKeyIsInvalid(g,b)}}}catch(T){y.e(T)}finally{y.f()}}}}catch(T){d.e(T)}finally{d.f()}return f},"invalidate")},{key:"gc",value:o(function(){var r=vo(this.getRenderTypes()),n;try{for(r.s();!(n=r.n()).done;){var i=n.value;i.atlasCollection.gc()}}catch(a){r.e(a)}finally{r.f()}},"gc")},{key:"isRenderable",value:o(function(r,n){var i=this.getRenderTypeOpts(n);return i&&i.isVisible(r)},"isRenderable")},{key:"startBatch",value:o(function(){this.batchAtlases=[]},"startBatch")},{key:"getAtlasCount",value:o(function(){return this.batchAtlases.length},"getAtlasCount")},{key:"getAtlases",value:o(function(){return this.batchAtlases},"getAtlases")},{key:"getOrCreateAtlas",value:o(function(r,n,i){var a=this.renderTypes.get(i),s=a.getKey(r),l=r.id();return a.atlasCollection.draw(l,s,n,function(u){a.drawElement(u,r,n,!0,!0)})},"getOrCreateAtlas")},{key:"getAtlasIndexForBatch",value:o(function(r){var n=this.batchAtlases.indexOf(r);if(n<0){if(this.batchAtlases.length===this.maxAtlasesPerBatch)return;this.batchAtlases.push(r),n=this.batchAtlases.length-1}return n},"getAtlasIndexForBatch")},{key:"getIndexArray",value:o(function(){return Array.from({length:this.maxAtlases},function(r,n){return n})},"getIndexArray")},{key:"getAtlasInfo",value:o(function(r,n){var i=this.renderTypes.get(n),a=i.getBoundingBox(r),s=this.getOrCreateAtlas(r,a,n),l=this.getAtlasIndexForBatch(s);if(l!==void 0){var u=i.getKey(r),h=s.getOffsets(u),f=Ri(h,2),d=f[0],p=f[1];return{atlasID:l,tex:d,tex1:d,tex2:p,bb:a,type:n,styleKey:u}}},"getAtlasInfo")},{key:"canAddToCurrentBatch",value:o(function(r,n){if(this.batchAtlases.length===this.maxAtlasesPerBatch){var i=this.renderTypes.get(n),a=i.getKey(r),s=i.atlasCollection.getAtlas(a);return s&&this.batchAtlases.includes(s)}return!0},"canAddToCurrentBatch")},{key:"setTransformMatrix",value:o(function(r,n,i){var a=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,s=n.bb,l=n.type,u=n.tex1,h=n.tex2,f=this.getRenderTypeOpts(l),d=f.getPadding?f.getPadding(i):0,p=u.w/(u.w+h.w);a||(p=1-p);var m=this.getAdjustedBB(s,d,a,p),g,y;B1e(r);var v=f.getRotation?f.getRotation(i):0;if(v!==0){var x=f.getRotationPoint(i),b=x.x,T=x.y;j6(r,r,[b,T]),F1e(r,r,v);var S=f.getRotationOffset(i);g=S.x+m.xOffset,y=S.y}else g=m.x1,y=m.y1;j6(r,r,[g,y]),sF(r,r,[m.w,m.h])},"setTransformMatrix")},{key:"getTransformMatrix",value:o(function(r,n){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,a=Zb();return this.setTransformMatrix(a,r,n,i),a},"getTransformMatrix")},{key:"getAdjustedBB",value:o(function(r,n,i,a){var s=r.x1,l=r.y1,u=r.w,h=r.h;n&&(s-=n,l-=n,u+=2*n,h+=2*n);var f=0,d=u*a;return i&&a<1?u=d:!i&&a<1&&(f=u-d,s+=f,u=d),{x1:s,y1:l,w:u,h,xOffset:f}},"getAdjustedBB")},{key:"getDebugInfo",value:o(function(){var r=[],n=vo(this.renderTypes),i;try{for(n.s();!(i=n.n()).done;){var a=Ri(i.value,2),s=a[0],l=a[1],u=l.atlasCollection.getCounts(),h=u.keyCount,f=u.atlasCount;r.push({type:s,keyCount:h,atlasCount:f})}}catch(d){n.e(d)}finally{n.f()}return r},"getDebugInfo")}]),t}(),yB=0,Zme=1,Jme=2,vB=3,qJe=function(){function t(e,r,n){Vf(this,t),this.r=e,this.gl=r,this.maxInstances=n.webglBatchSize,this.maxAtlases=n.webglTexPerBatch,this.atlasSize=n.webglTexSize,this.bgColor=n.bgColor,n.enableWrapping=!0,n.createTextureCanvas=IJe,this.atlasManager=new WJe(e,n),this.program=this.createShaderProgram(Jb.SCREEN),this.pickingProgram=this.createShaderProgram(Jb.PICKING),this.vao=this.createVAO(),this.debugInfo=[]}return o(t,"ElementDrawingWebGL"),Uf(t,[{key:"addTextureRenderType",value:o(function(r,n){this.atlasManager.addRenderType(r,n)},"addTextureRenderType")},{key:"invalidate",value:o(function(r){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=n.type,a=this.atlasManager;return i?a.invalidate(r,{filterType:o(function(l){return l===i},"filterType"),forceRedraw:!0}):a.invalidate(r)},"invalidate")},{key:"gc",value:o(function(){this.atlasManager.gc()},"gc")},{key:"createShaderProgram",value:o(function(r){var n=this.gl,i=`#version 300 es + precision highp float; + + uniform mat3 uPanZoomMatrix; + uniform int uAtlasSize; + + // instanced + in vec2 aPosition; + + // what are we rendering? + in int aVertType; + + // for picking + in vec4 aIndex; + + // For textures + in int aAtlasId; // which shader unit/atlas to use + in vec4 aTex1; // x/y/w/h of texture in atlas + in vec4 aTex2; + + // for any transforms that are needed + in vec4 aScaleRotate1; // vectors use fewer attributes than matrices + in vec2 aTranslate1; + in vec4 aScaleRotate2; + in vec2 aTranslate2; + + // for edges + in vec4 aPointAPointB; + in vec4 aPointCPointD; + in float aLineWidth; + in vec4 aEdgeColor; + + out vec2 vTexCoord; + out vec4 vEdgeColor; + flat out int vAtlasId; + flat out vec4 vIndex; + flat out int vVertType; + + void main(void) { + int vid = gl_VertexID; + vec2 position = aPosition; + + if(aVertType == `.concat(yB,`) { + float texX; + float texY; + float texW; + float texH; + mat3 texMatrix; + + int vid = gl_VertexID; + if(vid <= 5) { + texX = aTex1.x; + texY = aTex1.y; + texW = aTex1.z; + texH = aTex1.w; + texMatrix = mat3( + vec3(aScaleRotate1.xy, 0.0), + vec3(aScaleRotate2.zw, 0.0), + vec3(aTranslate1, 1.0) + ); + } else { + texX = aTex2.x; + texY = aTex2.y; + texW = aTex2.z; + texH = aTex2.w; + texMatrix = mat3( + vec3(aScaleRotate2.xy, 0.0), + vec3(aScaleRotate2.zw, 0.0), + vec3(aTranslate2, 1.0) + ); + } + + if(vid == 1 || vid == 2 || vid == 4 || vid == 7 || vid == 8 || vid == 10) { + texX += texW; + } + if(vid == 2 || vid == 4 || vid == 5 || vid == 8 || vid == 10 || vid == 11) { + texY += texH; + } + + float d = float(uAtlasSize); + vTexCoord = vec2(texX / d, texY / d); // tex coords must be between 0 and 1 + + gl_Position = vec4(uPanZoomMatrix * texMatrix * vec3(position, 1.0), 1.0); + } + else if(aVertType == `).concat(Zme,` && vid < 6) { + vec2 source = aPointAPointB.xy; + vec2 target = aPointAPointB.zw; + + // adjust the geometry so that the line is centered on the edge + position.y = position.y - 0.5; + + vec2 xBasis = target - source; + vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); + vec2 point = source + xBasis * position.x + yBasis * aLineWidth * position.y; + + gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0); + vEdgeColor = aEdgeColor; + } + else if(aVertType == `).concat(Jme,` && vid < 6) { + vec2 pointA = aPointAPointB.xy; + vec2 pointB = aPointAPointB.zw; + vec2 pointC = aPointCPointD.xy; + vec2 pointD = aPointCPointD.zw; + + // adjust the geometry so that the line is centered on the edge + position.y = position.y - 0.5; + + vec2 p0 = pointA; + vec2 p1 = pointB; + vec2 p2 = pointC; + vec2 pos = position; + if(position.x == 1.0) { + p0 = pointD; + p1 = pointC; + p2 = pointB; + pos = vec2(0.0, -position.y); + } + + vec2 p01 = p1 - p0; + vec2 p12 = p2 - p1; + vec2 p21 = p1 - p2; + + // Find the normal vector. + vec2 tangent = normalize(normalize(p12) + normalize(p01)); + vec2 normal = vec2(-tangent.y, tangent.x); + + // Find the vector perpendicular to p0 -> p1. + vec2 p01Norm = normalize(vec2(-p01.y, p01.x)); + + // Determine the bend direction. + float sigma = sign(dot(p01 + p21, normal)); + float width = aLineWidth; + + if(sign(pos.y) == -sigma) { + // This is an intersecting vertex. Adjust the position so that there's no overlap. + vec2 point = 0.5 * width * normal * -sigma / dot(normal, p01Norm); + gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0); + } else { + // This is a non-intersecting vertex. Treat it like a mitre join. + vec2 point = 0.5 * width * normal * sigma * dot(normal, p01Norm); + gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0); + } + + vEdgeColor = aEdgeColor; + } + else if(aVertType == `).concat(vB,` && vid < 3) { + // massage the first triangle into an edge arrow + if(vid == 0) + position = vec2(-0.15, -0.3); + if(vid == 1) + position = vec2( 0.0, 0.0); + if(vid == 2) + position = vec2( 0.15, -0.3); + + mat3 transform = mat3( + vec3(aScaleRotate1.xy, 0.0), + vec3(aScaleRotate1.zw, 0.0), + vec3(aTranslate1, 1.0) + ); + gl_Position = vec4(uPanZoomMatrix * transform * vec3(position, 1.0), 1.0); + vEdgeColor = aEdgeColor; + } else { + gl_Position = vec4(2.0, 0.0, 0.0, 1.0); // discard vertex by putting it outside webgl clip space + } + + vAtlasId = aAtlasId; + vIndex = aIndex; + vVertType = aVertType; + } + `),a=this.atlasManager.getIndexArray(),s=`#version 300 es + precision highp float; + + // define texture unit for each node in the batch + `.concat(a.map(function(h){return"uniform sampler2D uTexture".concat(h,";")}).join(` + `),` + + uniform vec4 uBGColor; + + in vec2 vTexCoord; + in vec4 vEdgeColor; + flat in int vAtlasId; + flat in vec4 vIndex; + flat in int vVertType; + + out vec4 outColor; + + void main(void) { + if(vVertType == `).concat(yB,`) { + `).concat(a.map(function(h){return"if(vAtlasId == ".concat(h,") outColor = texture(uTexture").concat(h,", vTexCoord);")}).join(` + else `),` + } else if(vVertType == `).concat(vB,`) { + // blend arrow color with background (using premultiplied alpha) + outColor.rgb = vEdgeColor.rgb + (uBGColor.rgb * (1.0 - vEdgeColor.a)); + outColor.a = 1.0; // make opaque, masks out line under arrow + } else { + outColor = vEdgeColor; + } + + `).concat(r.picking?`if(outColor.a == 0.0) discard; + else outColor = vIndex;`:"",` + } + `),l=MJe(n,i,s);l.aPosition=n.getAttribLocation(l,"aPosition"),l.aIndex=n.getAttribLocation(l,"aIndex"),l.aVertType=n.getAttribLocation(l,"aVertType"),l.aAtlasId=n.getAttribLocation(l,"aAtlasId"),l.aTex1=n.getAttribLocation(l,"aTex1"),l.aTex2=n.getAttribLocation(l,"aTex2"),l.aScaleRotate1=n.getAttribLocation(l,"aScaleRotate1"),l.aTranslate1=n.getAttribLocation(l,"aTranslate1"),l.aScaleRotate2=n.getAttribLocation(l,"aScaleRotate2"),l.aTranslate2=n.getAttribLocation(l,"aTranslate2"),l.aPointAPointB=n.getAttribLocation(l,"aPointAPointB"),l.aPointCPointD=n.getAttribLocation(l,"aPointCPointD"),l.aLineWidth=n.getAttribLocation(l,"aLineWidth"),l.aEdgeColor=n.getAttribLocation(l,"aEdgeColor"),l.uPanZoomMatrix=n.getUniformLocation(l,"uPanZoomMatrix"),l.uAtlasSize=n.getUniformLocation(l,"uAtlasSize"),l.uBGColor=n.getUniformLocation(l,"uBGColor"),l.uTextures=[];for(var u=0;u2&&arguments[2]!==void 0?arguments[2]:Jb.SCREEN;this.panZoomMatrix=r,this.debugInfo=n,this.renderTarget=i,this.startBatch()},"startFrame")},{key:"startBatch",value:o(function(){this.instanceCount=0,this.atlasManager.startBatch()},"startBatch")},{key:"endFrame",value:o(function(){this.endBatch()},"endFrame")},{key:"getTempMatrix",value:o(function(){return this.tempMatrix=this.tempMatrix||Zb()},"getTempMatrix")},{key:"drawTexture",value:o(function(r,n,i){var a=this.atlasManager;if(a.isRenderable(r,i)){a.canAddToCurrentBatch(r,i)||this.endBatch();var s=this.instanceCount;this.vertTypeBuffer.getView(s)[0]=yB;var l=this.indexBuffer.getView(s);_6(n,l);var u=a.getAtlasInfo(r,i,u),h=u.atlasID,f=u.tex1,d=u.tex2,p=this.atlasIdBuffer.getView(s);p[0]=h;var m=this.tex1Buffer.getView(s);m[0]=f.x,m[1]=f.y,m[2]=f.w,m[3]=f.h;var g=this.tex2Buffer.getView(s);g[0]=d.x,g[1]=d.y,g[2]=d.w,g[3]=d.h;for(var y=this.getTempMatrix(),v=0,x=[1,2];v=this.maxInstances&&this.endBatch()}},"drawTexture")},{key:"drawEdgeArrow",value:o(function(r,n,i){var a=r._private.rscratch,s,l,u;if(i==="source"?(s=a.arrowStartX,l=a.arrowStartY,u=a.srcArrowAngle):(s=a.arrowEndX,l=a.arrowEndY,u=a.tgtArrowAngle),!(isNaN(s)||s==null||isNaN(l)||l==null||isNaN(u)||u==null)){var h=r.pstyle(i+"-arrow-shape").value;if(h!=="none"){var f=r.pstyle(i+"-arrow-color").value,d=r.pstyle("opacity").value,p=r.pstyle("line-opacity").value,m=d*p,g=r.pstyle("width").pfValue,y=r.pstyle("arrow-scale").value,v=this.r.getArrowWidth(g,y),x=this.getTempMatrix();B1e(x),j6(x,x,[s,l]),sF(x,x,[v,v]),F1e(x,x,u);var b=this.instanceCount;this.vertTypeBuffer.getView(b)[0]=vB;var T=this.indexBuffer.getView(b);_6(n,T);var S=this.edgeColorBuffer.getView(b);A6(f,m,S);var w=this.scaleRotate1Buffer.getView(b);w[0]=x[0],w[1]=x[1],w[2]=x[3],w[3]=x[4];var E=this.translate1Buffer.getView(b);E[0]=x[6],E[1]=x[7],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}},"drawEdgeArrow")},{key:"drawEdgeLine",value:o(function(r,n){var i=r.pstyle("opacity").value,a=r.pstyle("line-opacity").value,s=r.pstyle("width").pfValue,l=r.pstyle("line-color").value,u=i*a,h=this.getEdgePoints(r);if(h.length/2+this.instanceCount>this.maxInstances&&this.endBatch(),h.length==4){var f=this.instanceCount;this.vertTypeBuffer.getView(f)[0]=Zme;var d=this.indexBuffer.getView(f);_6(n,d);var p=this.edgeColorBuffer.getView(f);A6(l,u,p);var m=this.lineWidthBuffer.getView(f);m[0]=s;var g=this.pointAPointBBuffer.getView(f);g[0]=h[0],g[1]=h[1],g[2]=h[2],g[3]=h[3],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}else for(var y=0;y=this.maxInstances&&this.endBatch()}},"drawEdgeLine")},{key:"getEdgePoints",value:o(function(r){var n=r._private.rscratch,i=n.allpts;if(i.length==4)return i;var a=this.getNumSegments(r);return this.getCurveSegmentPoints(i,a)},"getEdgePoints")},{key:"getNumSegments",value:o(function(r){var n=15;return Math.min(Math.max(n,5),this.maxInstances)},"getNumSegments")},{key:"getCurveSegmentPoints",value:o(function(r,n){if(r.length==4)return r;for(var i=Array((n+1)*2),a=0;a<=n;a++)if(a==0)i[0]=r[0],i[1]=r[1];else if(a==n)i[a*2]=r[r.length-2],i[a*2+1]=r[r.length-1];else{var s=a/n;this.setCurvePoint(r,s,i,a*2)}return i},"getCurveSegmentPoints")},{key:"setCurvePoint",value:o(function(r,n,i,a){if(r.length<=2)i[a]=r[0],i[a+1]=r[1];else{for(var s=Array(r.length-2),l=0;l0},"isVisible")},{key:"getStyle",value:o(function(r,n){var i=n.pstyle("".concat(r,"-opacity")).value,a=n.pstyle("".concat(r,"-color")).value,s=n.pstyle("".concat(r,"-shape")).value;return{opacity:i,color:a,shape:s}},"getStyle")},{key:"getPadding",value:o(function(r,n){return n.pstyle("".concat(r,"-padding")).pfValue},"getPadding")},{key:"draw",value:o(function(r,n,i,a){if(this.isVisible(r,i)){var s=this.r,l=a.w,u=a.h,h=l/2,f=u/2,d=this.getStyle(r,i),p=d.shape,m=d.color,g=d.opacity;n.save(),n.fillStyle=ege(m,g),p==="round-rectangle"||p==="roundrectangle"?s.drawRoundRectanglePath(n,h,f,l,u,"auto"):p==="ellipse"&&s.drawEllipsePath(n,h,f,l,u),n.fill(),n.restore()}},"draw")}]),t}();o(XJe,"getBGColor");$1e={};$1e.initWebgl=function(t,e){var r=this,n=r.data.contexts[r.WEBGL],i=t.cy.container();t.bgColor=XJe(i),t.webglTexSize=Math.min(t.webglTexSize,n.getParameter(n.MAX_TEXTURE_SIZE)),t.webglTexRows=Math.min(t.webglTexRows,54),t.webglBatchSize=Math.min(t.webglBatchSize,16384),t.webglTexPerBatch=Math.min(t.webglTexPerBatch,n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),r.webglDebug=t.webglDebug,r.webglDebugShowAtlases=t.webglDebugShowAtlases,console.log("max texture units",n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),console.log("max texture size",n.getParameter(n.MAX_TEXTURE_SIZE)),console.log("webgl options",t),r.pickingFrameBuffer=$Je(n),r.pickingFrameBuffer.needsDraw=!0;var a=o(function(f){return r.getTextAngle(f,null)},"getLabelRotation"),s=o(function(f){var d=f.pstyle("label");return d&&d.value},"isLabelVisible");r.eleDrawing=new qJe(r,n,t);var l=new YJe(r);r.eleDrawing.addTextureRenderType("node-body",Hb({getKey:e.getStyleKey,getBoundingBox:e.getElementBox,drawElement:e.drawElement,isVisible:o(function(f){return f.visible()},"isVisible")})),r.eleDrawing.addTextureRenderType("node-label",Hb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s})),r.eleDrawing.addTextureRenderType("node-overlay",Hb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("overlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("overlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("overlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("overlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("node-underlay",Hb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("underlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("underlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("underlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("underlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("edge-label",Hb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s}));var u=p4(function(){console.log("garbage collect flag set"),r.data.gc=!0},1e4);r.onUpdateEleCalcs(function(h,f){var d=!1;f&&f.length>0&&(d|=r.eleDrawing.invalidate(f)),d&&u()}),jJe(r)};o(jJe,"overrideCanvasRendererFunctions");o(KJe,"clearWebgl");o(QJe,"clearCanvas");o(ZJe,"createPanZoomMatrix");o(z1e,"setContextTransform");o(JJe,"drawSelectionRectangle");o(eet,"drawAxes");o(tet,"drawAtlases");o(ret,"getPickingIndexes");o(net,"findNearestElementsWebgl");o(G1e,"renderWebgl");Wf={};Wf.drawPolygonPath=function(t,e,r,n,i,a){var s=n/2,l=i/2;t.beginPath&&t.beginPath(),t.moveTo(e+s*a[0],r+l*a[1]);for(var u=1;u0&&s>0){m.clearRect(0,0,a,s),m.globalCompositeOperation="source-over";var g=this.getCachedZSortedEles();if(t.full)m.translate(-n.x1*h,-n.y1*h),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(n.x1*h,n.y1*h);else{var y=e.pan(),v={x:y.x*h,y:y.y*h};h*=e.zoom(),m.translate(v.x,v.y),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(-v.x,-v.y)}t.bg&&(m.globalCompositeOperation="destination-over",m.fillStyle=t.bg,m.rect(0,0,a,s),m.fill())}return p};o(iet,"b64ToBlob");o(nge,"b64UriToB64");o(U1e,"output");b4.png=function(t){return U1e(t,this.bufferCanvasImage(t),"image/png")};b4.jpg=function(t){return U1e(t,this.bufferCanvasImage(t),"image/jpeg")};H1e={};H1e.nodeShapeImpl=function(t,e,r,n,i,a,s,l){switch(t){case"ellipse":return this.drawEllipsePath(e,r,n,i,a);case"polygon":return this.drawPolygonPath(e,r,n,i,a,s);case"round-polygon":return this.drawRoundPolygonPath(e,r,n,i,a,s,l);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(e,r,n,i,a,l);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(e,r,n,i,a,s,l);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(e,r,n,i,a,l);case"barrel":return this.drawBarrelPath(e,r,n,i,a)}};aet=W1e,Sr=W1e.prototype;Sr.CANVAS_LAYERS=3;Sr.SELECT_BOX=0;Sr.DRAG=1;Sr.NODE=2;Sr.WEBGL=3;Sr.CANVAS_TYPES=["2d","2d","2d","webgl2"];Sr.BUFFER_COUNT=3;Sr.TEXTURE_BUFFER=0;Sr.MOTIONBLUR_BUFFER_NODE=1;Sr.MOTIONBLUR_BUFFER_DRAG=2;o(W1e,"CanvasRenderer");Sr.redrawHint=function(t,e){var r=this;switch(t){case"eles":r.data.canvasNeedsRedraw[Sr.NODE]=e;break;case"drag":r.data.canvasNeedsRedraw[Sr.DRAG]=e;break;case"select":r.data.canvasNeedsRedraw[Sr.SELECT_BOX]=e;break;case"gc":r.data.gc=!0;break}};set=typeof Path2D<"u";Sr.path2dEnabled=function(t){if(t===void 0)return this.pathsEnabled;this.pathsEnabled=!!t};Sr.usePaths=function(){return set&&this.pathsEnabled};Sr.setImgSmoothing=function(t,e){t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled=e:(t.webkitImageSmoothingEnabled=e,t.mozImageSmoothingEnabled=e,t.msImageSmoothingEnabled=e)};Sr.getImgSmoothing=function(t){return t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled:t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled};Sr.makeOffscreenCanvas=function(t,e){var r;if((typeof OffscreenCanvas>"u"?"undefined":qi(OffscreenCanvas))!=="undefined")r=new OffscreenCanvas(t,e);else{var n=this.cy.window(),i=n.document;r=i.createElement("canvas"),r.width=t,r.height=e}return r};[N1e,tu,oh,iF,n0,py,ws,$1e,Wf,b4,H1e].forEach(function(t){ir(Sr,t)});oet=[{name:"null",impl:v1e},{name:"base",impl:_1e},{name:"canvas",impl:aet}],cet=[{type:"layout",extensions:HZe},{type:"renderer",extensions:oet}],q1e={},Y1e={};o(X1e,"setExtension");o(j1e,"getExtension");o(uet,"setModule");o(het,"getModule");OB=o(function(){if(arguments.length===2)return j1e.apply(null,arguments);if(arguments.length===3)return X1e.apply(null,arguments);if(arguments.length===4)return het.apply(null,arguments);if(arguments.length===5)return uet.apply(null,arguments);oi("Invalid extension access syntax")},"extension");u4.prototype.extension=OB;cet.forEach(function(t){t.extensions.forEach(function(e){X1e(t.type,e.name,e.impl)})});K1e=o(function t(){if(!(this instanceof t))return new t;this.length=0},"Stylesheet"),t0=K1e.prototype;t0.instanceString=function(){return"stylesheet"};t0.selector=function(t){var e=this.length++;return this[e]={selector:t,properties:[]},this};t0.css=function(t,e){var r=this.length-1;if(Zt(t))this[r].properties.push({name:t,value:e});else if(Ur(t))for(var n=t,i=Object.keys(n),a=0;a{"use strict";o(function(e,r){typeof T4=="object"&&typeof lF=="object"?lF.exports=r():typeof define=="function"&&define.amd?define([],r):typeof T4=="object"?T4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(T4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=26)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(4);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;yp&&(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)),this.labelHeight>m&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-m)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-m),this.setHeight(this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(6),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,T=0;T-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(w,1),x.target!=x.source&&x.target.edges.splice(E,1);var S=x.source.owner.getEdges().indexOf(x);if(S==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(S,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,T=this.getNodes(),S=T.length,w=0;wv&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(T[0].getParent().paddingLeft!=null?b=T[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,T,S,w,E,_,C=this.nodes,D=C.length,O=0;OT&&(y=T),vw&&(x=w),bT&&(y=T),vw&&(x=w),b=this.nodes.length){var D=0;v.forEach(function(O){O.owner==g&&D++}),D==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(5),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]d)return l[0]=u,l[1]=m,l[2]=f,l[3]=C,!1;if(hf)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(uf?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):A===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-I===M?f>u?(l[2]=_,l[3]=C,L=!0):(l[2]=E,l[3]=w,L=!0):I===M&&(f>u?(l[2]=S,l[3]=w,L=!0):(l[2]=D,l[3]=C,L=!0)),k&&L)return!1;if(u>f?h>d?(P=this.getCardinalDirection(A,M,4),B=this.getCardinalDirection(I,M,2)):(P=this.getCardinalDirection(-A,M,3),B=this.getCardinalDirection(-I,M,1)):h>d?(P=this.getCardinalDirection(-A,M,1),B=this.getCardinalDirection(-I,M,3)):(P=this.getCardinalDirection(A,M,2),B=this.getCardinalDirection(I,M,4)),!k)switch(P){case 1:z=m,F=u+-T/M,l[0]=F,l[1]=z;break;case 2:F=x,z=h+b*M,l[0]=F,l[1]=z;break;case 3:z=v,F=u+T/M,l[0]=F,l[1]=z;break;case 4:F=y,z=h+-b*M,l[0]=F,l[1]=z;break}if(!L)switch(B){case 1:U=w,$=f+-R/M,l[2]=$,l[3]=U;break;case 2:$=D,U=d+O*M,l[2]=$,l[3]=U;break;case 3:U=C,$=f+R/M,l[2]=$,l[3]=U;break;case 4:$=_,U=d+-O*M,l[2]=$,l[3]=U;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,T=void 0,S=void 0,w=void 0,E=void 0,_=void 0,C=void 0,D=void 0;return T=p-f,w=h-d,_=d*f-h*p,S=v-g,E=m-y,C=y*g-m*v,D=T*E-S*w,D===0?null:(x=(w*C-E*_)/D,b=(S*_-T*C)/D,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g0&&g;){for(T.push(w[0]);T.length>0&&g;){var E=T[0];T.splice(0,1),b.add(E);for(var _=E.getEdges(),x=0;x<_.length;x++){var C=_[x].getOtherEnd(E);if(S.get(E)!=C)if(!b.has(C))T.push(C),S.set(C,E);else{g=!1;break}}}if(!g)m=[];else{var D=[].concat(n(b));m.push(D);for(var x=0;x-1&&w.splice(R,1)}b=new Set,S=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x0){for(var v=this.edgeToDummyNodes.get(y),x=0;x=0&&g.splice(C,1);var D=S.getNeighborsList();D.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),A=L-1;A==1&&E.push(k),v.set(k,A)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(4);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);pa.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;mT||b>T)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(T=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>T||b>T)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement=x.length||T>=x[0].length)){for(var S=0;Sh},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l{"use strict";o(function(e,r){typeof w4=="object"&&typeof uF=="object"?uF.exports=r(cF()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof w4=="object"?w4.coseBase=r(cF()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(w4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=7)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).FDLayoutConstants;function a(){}o(a,"CoSEConstants");for(var s in i)a[s]=i[s];a.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,a.DEFAULT_RADIAL_SEPARATION=i.DEFAULT_EDGE_LENGTH,a.DEFAULT_COMPONENT_SEPERATION=60,a.TILE=!0,a.TILING_PADDING_VERTICAL=10,a.TILING_PADDING_HORIZONTAL=10,a.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutEdge;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEEdge"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraph;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEGraph"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraphManager;function a(l){i.call(this,l)}o(a,"CoSEGraphManager"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutNode,a=n(0).IMath;function s(u,h,f,d){i.call(this,u,h,f,d)}o(s,"CoSENode"),s.prototype=Object.create(i.prototype);for(var l in i)s[l]=i[l];s.prototype.move=function(){var u=this.graphManager.getLayout();this.displacementX=u.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=u.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementX=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementX)),Math.abs(this.displacementY)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementY=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementY)),this.child==null?this.moveBy(this.displacementX,this.displacementY):this.child.getNodes().length==0?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),u.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},s.prototype.propogateDisplacementToChildren=function(u,h){for(var f=this.getChild().getNodes(),d,p=0;p0)this.positionNodesRadially(w);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),_=this.nodesWithGravity.filter(function(C){return E.has(C)});this.graphManager.setAllNodesToApplyGravitation(_),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},T.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%f.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var w=new Set(this.getAllNodes()),E=this.nodesWithGravity.filter(function(D){return w.has(D)});this.graphManager.setAllNodesToApplyGravitation(E),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var _=!this.isTreeGrowing&&!this.isGrowthFinished,C=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(_,C),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},T.prototype.getPositionsData=function(){for(var w=this.graphManager.getAllNodes(),E={},_=0;_1){var k;for(k=0;kC&&(C=Math.floor(R.y)),O=Math.floor(R.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new m(d.WORLD_CENTER_X-R.x/2,d.WORLD_CENTER_Y-R.y/2))},T.radialLayout=function(w,E,_){var C=Math.max(this.maxDiagonalInTree(w),h.DEFAULT_RADIAL_SEPARATION);T.branchRadialLayout(E,null,0,359,0,C);var D=x.calculateBounds(w),O=new b;O.setDeviceOrgX(D.getMinX()),O.setDeviceOrgY(D.getMinY()),O.setWorldOrgX(_.x),O.setWorldOrgY(_.y);for(var R=0;R1;){var K=U[0];U.splice(0,1);var ee=P.indexOf(K);ee>=0&&P.splice(ee,1),z--,B--}E!=null?$=(P.indexOf(U[0])+1)%z:$=0;for(var Y=Math.abs(C-_)/B,ce=$;F!=B;ce=++ce%z){var Z=P[ce].getOtherEnd(w);if(Z!=E){var ue=(_+F*Y)%360,Q=(ue+Y)%360;T.branchRadialLayout(Z,w,ue,Q,D+O,O),F++}}},T.maxDiagonalInTree=function(w){for(var E=y.MIN_VALUE,_=0;_E&&(E=D)}return E},T.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},T.prototype.groupZeroDegreeMembers=function(){var w=this,E={};this.memberGroups={},this.idToDummyNode={};for(var _=[],C=this.graphManager.getAllNodes(),D=0;D"u"&&(E[k]=[]),E[k]=E[k].concat(O)}Object.keys(E).forEach(function(L){if(E[L].length>1){var A="DummyCompound_"+L;w.memberGroups[A]=E[L];var I=E[L][0].getParent(),M=new l(w.graphManager);M.id=A,M.paddingLeft=I.paddingLeft||0,M.paddingRight=I.paddingRight||0,M.paddingBottom=I.paddingBottom||0,M.paddingTop=I.paddingTop||0,w.idToDummyNode[A]=M;var P=w.getGraphManager().add(w.newGraph(),M),B=I.getChild();B.add(M);for(var F=0;F=0;w--){var E=this.compoundOrder[w],_=E.id,C=E.paddingLeft,D=E.paddingTop;this.adjustLocations(this.tiledMemberPack[_],E.rect.x,E.rect.y,C,D)}},T.prototype.repopulateZeroDegreeMembers=function(){var w=this,E=this.tiledZeroDegreePack;Object.keys(E).forEach(function(_){var C=w.idToDummyNode[_],D=C.paddingLeft,O=C.paddingTop;w.adjustLocations(E[_],C.rect.x,C.rect.y,D,O)})},T.prototype.getToBeTiled=function(w){var E=w.id;if(this.toBeTiled[E]!=null)return this.toBeTiled[E];var _=w.getChild();if(_==null)return this.toBeTiled[E]=!1,!1;for(var C=_.getNodes(),D=0;D0)return this.toBeTiled[E]=!1,!1;if(O.getChild()==null){this.toBeTiled[O.id]=!1;continue}if(!this.getToBeTiled(O))return this.toBeTiled[E]=!1,!1}return this.toBeTiled[E]=!0,!0},T.prototype.getNodeDegree=function(w){for(var E=w.id,_=w.getEdges(),C=0,D=0;D<_.length;D++){var O=_[D];O.getSource().id!==O.getTarget().id&&(C=C+1)}return C},T.prototype.getNodeDegreeWithChildren=function(w){var E=this.getNodeDegree(w);if(w.getChild()==null)return E;for(var _=w.getChild().getNodes(),C=0;C<_.length;C++){var D=_[C];E+=this.getNodeDegreeWithChildren(D)}return E},T.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},T.prototype.fillCompexOrderByDFS=function(w){for(var E=0;EL&&(L=I.rect.height)}_+=L+w.verticalPadding}},T.prototype.tileCompoundMembers=function(w,E){var _=this;this.tiledMemberPack=[],Object.keys(w).forEach(function(C){var D=E[C];_.tiledMemberPack[C]=_.tileNodes(w[C],D.paddingLeft+D.paddingRight),D.rect.width=_.tiledMemberPack[C].width,D.rect.height=_.tiledMemberPack[C].height})},T.prototype.tileNodes=function(w,E){var _=h.TILING_PADDING_VERTICAL,C=h.TILING_PADDING_HORIZONTAL,D={rows:[],rowWidth:[],rowHeight:[],width:0,height:E,verticalPadding:_,horizontalPadding:C};w.sort(function(k,L){return k.rect.width*k.rect.height>L.rect.width*L.rect.height?-1:k.rect.width*k.rect.height0&&(R+=w.horizontalPadding),w.rowWidth[_]=R,w.width0&&(k+=w.verticalPadding);var L=0;k>w.rowHeight[_]&&(L=w.rowHeight[_],w.rowHeight[_]=k,L=w.rowHeight[_]-L),w.height+=L,w.rows[_].push(E)},T.prototype.getShortestRowIndex=function(w){for(var E=-1,_=Number.MAX_VALUE,C=0;C_&&(E=C,_=w.rowWidth[C]);return E},T.prototype.canAddHorizontal=function(w,E,_){var C=this.getShortestRowIndex(w);if(C<0)return!0;var D=w.rowWidth[C];if(D+w.horizontalPadding+E<=w.width)return!0;var O=0;w.rowHeight[C]<_&&C>0&&(O=_+w.verticalPadding-w.rowHeight[C]);var R;w.width-D>=E+w.horizontalPadding?R=(w.height+O)/(D+E+w.horizontalPadding):R=(w.height+O)/w.width,O=_+w.verticalPadding;var k;return w.widthO&&E!=_){C.splice(-1,1),w.rows[_].push(D),w.rowWidth[E]=w.rowWidth[E]-O,w.rowWidth[_]=w.rowWidth[_]+O,w.width=w.rowWidth[instance.getLongestRowIndex(w)];for(var R=Number.MIN_VALUE,k=0;kR&&(R=C[k].height);E>0&&(R+=w.verticalPadding);var L=w.rowHeight[E]+w.rowHeight[_];w.rowHeight[E]=R,w.rowHeight[_]0)for(var B=D;B<=O;B++)P[0]+=this.grid[B][R-1].length+this.grid[B][R].length-1;if(O0)for(var B=R;B<=k;B++)P[3]+=this.grid[D-1][B].length+this.grid[D][B].length-1;for(var F=y.MAX_VALUE,z,$,U=0;U{"use strict";o(function(e,r){typeof k4=="object"&&typeof fF=="object"?fF.exports=r(hF()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof k4=="object"?k4.cytoscapeCoseBilkent=r(hF()):e.cytoscapeCoseBilkent=r(e.coseBase)},"webpackUniversalModuleDefinition")(k4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=1)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).layoutBase.LayoutConstants,a=n(0).layoutBase.FDLayoutConstants,s=n(0).CoSEConstants,l=n(0).CoSELayout,u=n(0).CoSENode,h=n(0).layoutBase.PointD,f=n(0).layoutBase.DimensionD,d={ready:o(function(){},"ready"),stop:o(function(){},"stop"),quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function p(v,x){var b={};for(var T in v)b[T]=v[T];for(var T in x)b[T]=x[T];return b}o(p,"extend");function m(v){this.options=p(d,v),g(this.options)}o(m,"_CoSELayout");var g=o(function(x){x.nodeRepulsion!=null&&(s.DEFAULT_REPULSION_STRENGTH=a.DEFAULT_REPULSION_STRENGTH=x.nodeRepulsion),x.idealEdgeLength!=null&&(s.DEFAULT_EDGE_LENGTH=a.DEFAULT_EDGE_LENGTH=x.idealEdgeLength),x.edgeElasticity!=null&&(s.DEFAULT_SPRING_STRENGTH=a.DEFAULT_SPRING_STRENGTH=x.edgeElasticity),x.nestingFactor!=null&&(s.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=x.nestingFactor),x.gravity!=null&&(s.DEFAULT_GRAVITY_STRENGTH=a.DEFAULT_GRAVITY_STRENGTH=x.gravity),x.numIter!=null&&(s.MAX_ITERATIONS=a.MAX_ITERATIONS=x.numIter),x.gravityRange!=null&&(s.DEFAULT_GRAVITY_RANGE_FACTOR=a.DEFAULT_GRAVITY_RANGE_FACTOR=x.gravityRange),x.gravityCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_STRENGTH=a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=x.gravityCompound),x.gravityRangeCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=x.gravityRangeCompound),x.initialEnergyOnIncremental!=null&&(s.DEFAULT_COOLING_FACTOR_INCREMENTAL=a.DEFAULT_COOLING_FACTOR_INCREMENTAL=x.initialEnergyOnIncremental),x.quality=="draft"?i.QUALITY=0:x.quality=="proof"?i.QUALITY=2:i.QUALITY=1,s.NODE_DIMENSIONS_INCLUDE_LABELS=a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=x.nodeDimensionsIncludeLabels,s.DEFAULT_INCREMENTAL=a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=!x.randomize,s.ANIMATE=a.ANIMATE=i.ANIMATE=x.animate,s.TILE=x.tile,s.TILING_PADDING_VERTICAL=typeof x.tilingPaddingVertical=="function"?x.tilingPaddingVertical.call():x.tilingPaddingVertical,s.TILING_PADDING_HORIZONTAL=typeof x.tilingPaddingHorizontal=="function"?x.tilingPaddingHorizontal.call():x.tilingPaddingHorizontal},"getUserOptions");m.prototype.run=function(){var v,x,b=this.options,T=this.idToLNode={},S=this.layout=new l,w=this;w.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var E=S.newGraphManager();this.gm=E;var _=this.options.eles.nodes(),C=this.options.eles.edges();this.root=E.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(_),S);for(var D=0;D0){var k;k=b.getGraphManager().add(b.newGraph(),_),this.processChildrenList(k,E,b)}}},m.prototype.stop=function(){return this.stopped=!0,this};var y=o(function(x){x("layout","cose-bilkent",m)},"register");typeof cytoscape<"u"&&y(cytoscape),e.exports=y}])})});function xet(t,e,r,n,i){return t.insert("polygon",":first-child").attr("points",n.map(function(a){return a.x+","+a.y}).join(" ")).attr("transform","translate("+(i.width-e)/2+", "+r+")")}var det,pet,met,get,yet,vet,bet,Tet,Z1e,J1e,eye=N(()=>{"use strict";ao();er();det=12,pet=o(function(t,e,r,n){e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 ${r.height-5} v${-r.height+2*5} q0,-5 5,-5 h${r.width-2*5} q5,0 5,5 v${r.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",r.height).attr("x2",r.width).attr("y2",r.height)},"defaultBkg"),met=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("width",r.width)},"rectBkg"),get=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n,s=.25*n,l=.35*n,u=.2*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 0 0,1 ${n*.25},${-1*n*.1} + a${l},${l} 1 0,1 ${n*.4},${-1*n*.1} + a${s},${s} 1 0,1 ${n*.35},${1*n*.2} + + a${a},${a} 1 0,1 ${n*.15},${1*i*.35} + a${u},${u} 1 0,1 ${-1*n*.15},${1*i*.65} + + a${s},${a} 1 0,1 ${-1*n*.25},${n*.15} + a${l},${l} 1 0,1 ${-1*n*.5},0 + a${a},${a} 1 0,1 ${-1*n*.25},${-1*n*.15} + + a${a},${a} 1 0,1 ${-1*n*.1},${-1*i*.35} + a${u},${u} 1 0,1 ${n*.1},${-1*i*.65} + + H0 V0 Z`)},"cloudBkg"),yet=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 1 0,0 ${n*.25},${-1*i*.1} + a${a},${a} 1 0,0 ${n*.25},0 + a${a},${a} 1 0,0 ${n*.25},0 + a${a},${a} 1 0,0 ${n*.25},${1*i*.1} + + a${a},${a} 1 0,0 ${n*.15},${1*i*.33} + a${a*.8},${a*.8} 1 0,0 0,${1*i*.34} + a${a},${a} 1 0,0 ${-1*n*.15},${1*i*.33} + + a${a},${a} 1 0,0 ${-1*n*.25},${i*.15} + a${a},${a} 1 0,0 ${-1*n*.25},0 + a${a},${a} 1 0,0 ${-1*n*.25},0 + a${a},${a} 1 0,0 ${-1*n*.25},${-1*i*.15} + + a${a},${a} 1 0,0 ${-1*n*.1},${-1*i*.33} + a${a*.8},${a*.8} 1 0,0 0,${-1*i*.34} + a${a},${a} 1 0,0 ${n*.1},${-1*i*.33} + + H0 V0 Z`)},"bangBkg"),vet=o(function(t,e,r){e.append("circle").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("r",r.width/2)},"circleBkg");o(xet,"insertPolygonShape");bet=o(function(t,e,r){let n=r.height,a=n/4,s=r.width-r.padding+2*a,l=[{x:a,y:0},{x:s-a,y:0},{x:s,y:-n/2},{x:s-a,y:-n},{x:a,y:-n},{x:0,y:-n/2}];xet(e,s,n,l,r)},"hexagonBkg"),Tet=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("rx",r.padding).attr("ry",r.padding).attr("width",r.width)},"roundedRectBkg"),Z1e=o(async function(t,e,r,n,i){let a=i.htmlLabels,s=n%(det-1),l=e.append("g");r.section=s;let u="section-"+s;s<0&&(u+=" section-root"),l.attr("class",(r.class?r.class+" ":"")+"mindmap-node "+u);let h=l.append("g"),f=l.append("g"),d=r.descr.replace(/()/g,` +`);await qn(f,d,{useHtmlLabels:a,width:r.width,classes:"mindmap-node-label"},i),a||f.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");let p=f.node().getBBox(),[m]=zo(i.fontSize);if(r.height=p.height+m*1.1*.5+r.padding,r.width=p.width+2*r.padding,r.icon)if(r.type===t.nodeType.CIRCLE)r.height+=50,r.width+=50,l.append("foreignObject").attr("height","50px").attr("width",r.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+r.width/2+", "+(r.height/2-1.5*r.padding)+")");else{r.width+=50;let g=r.height;r.height=Math.max(g,60);let y=Math.abs(r.height-g);l.append("foreignObject").attr("width","60px").attr("height",r.height).attr("style","text-align: center;margin-top:"+y/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+(25+r.width/2)+", "+(y/2+r.padding/2)+")")}else if(a){let g=(r.width-p.width)/2,y=(r.height-p.height)/2;f.attr("transform","translate("+g+", "+y+")")}else{let g=r.width/2,y=r.padding/2;f.attr("transform","translate("+g+", "+y+")")}switch(r.type){case t.nodeType.DEFAULT:pet(t,h,r,s);break;case t.nodeType.ROUNDED_RECT:Tet(t,h,r,s);break;case t.nodeType.RECT:met(t,h,r,s);break;case t.nodeType.CIRCLE:h.attr("transform","translate("+r.width/2+", "+ +r.height/2+")"),vet(t,h,r,s);break;case t.nodeType.CLOUD:get(t,h,r,s);break;case t.nodeType.BANG:yet(t,h,r,s);break;case t.nodeType.HEXAGON:bet(t,h,r,s);break}return t.setElementForId(r.id,l),r.height},"drawNode"),J1e=o(function(t,e){let r=t.getElementById(e.id),n=e.x||0,i=e.y||0;r.attr("transform","translate("+n+","+i+")")},"positionNode")});async function rye(t,e,r,n,i){await Z1e(t,e,r,n,i),r.children&&await Promise.all(r.children.map((a,s)=>rye(t,e,a,n<0?s:n,i)))}function wet(t,e){e.edges().map((r,n)=>{let i=r.data();if(r[0]._private.bodyBounds){let a=r[0]._private.rscratch;X.trace("Edge: ",n,i),t.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}})}function nye(t,e,r,n){e.add({group:"nodes",data:{id:t.id.toString(),labelText:t.descr,height:t.height,width:t.width,level:n,nodeId:t.id,padding:t.padding,type:t.type},position:{x:t.x,y:t.y}}),t.children&&t.children.forEach(i=>{nye(i,e,r,n+1),e.add({group:"edges",data:{id:`${t.id}_${i.id}`,source:t.id,target:i.id,depth:n,section:i.section}})})}function ket(t,e){return new Promise(r=>{let n=Ge("body").append("div").attr("id","cy").attr("style","display:none"),i=sl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});n.remove(),nye(t,i,e,0),i.nodes().forEach(function(a){a.layoutDimensions=()=>{let s=a.data();return{w:s.width,h:s.height}}}),i.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),i.ready(a=>{X.info("Ready",a),r(i)})})}function Eet(t,e){e.nodes().map((r,n)=>{let i=r.data();i.x=r.position().x,i.y=r.position().y,J1e(t,i);let a=t.getElementById(i.nodeId);X.info("id:",n,"Position: (",r.position().x,", ",r.position().y,")",i),a.attr("transform",`translate(${r.position().x-i.width/2}, ${r.position().y-i.height/2})`),a.attr("attr",`apa-${n})`)})}var tye,Cet,iye,aye=N(()=>{"use strict";oF();tye=Aa(Q1e(),1);fr();Gt();yt();Vl();xi();eye();_a();sl.use(tye.default);o(rye,"drawNodes");o(wet,"drawEdges");o(nye,"addNodes");o(ket,"layoutMindmap");o(Eet,"positionNodes");Cet=o(async(t,e,r,n)=>{X.debug(`Rendering mindmap diagram +`+t);let i=n.db,a=i.getMindmap();if(!a)return;let s=me();s.htmlLabels=!1;let l=Li(e),u=l.append("g");u.attr("class","mindmap-edges");let h=l.append("g");h.attr("class","mindmap-nodes"),await rye(i,h,a,-1,s);let f=await ket(a,s);wet(u,f),Eet(i,f),Lo(void 0,l,s.mindmap?.padding??or.mindmap.padding,s.mindmap?.useMaxWidth??or.mindmap.useMaxWidth)},"draw"),iye={draw:Cet}});var Aet,_et,sye,oye=N(()=>{"use strict";Ks();Aet=o(t=>{let e="";for(let r=0;r` + .edge { + stroke-width: 3; + } + ${Aet(t)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${t.git0}; + } + .section-root text { + fill: ${t.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .mindmap-node-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } +`,"getStyles"),sye=_et});var lye={};ur(lye,{diagram:()=>Det});var Det,cye=N(()=>{"use strict";B0e();F0e();aye();oye();Det={get db(){return new p6},renderer:iye,parser:P0e,styles:sye}});var dF,fye,dye=N(()=>{"use strict";dF=function(){var t=o(function(_,C,D,O){for(D=D||{},O=_.length;O--;D[_[O]]=C);return D},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,31],g=[6,7,11,24],y=[1,6,13,16,17,20,23],v=[1,35],x=[1,36],b=[1,6,7,11,13,16,17,20,23],T=[1,38],S={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:o(function(C,D,O,R,k,L,A){var I=L.length-1;switch(k){case 6:case 7:return R;case 8:R.getLogger().trace("Stop NL ");break;case 9:R.getLogger().trace("Stop EOF ");break;case 11:R.getLogger().trace("Stop NL2 ");break;case 12:R.getLogger().trace("Stop EOF2 ");break;case 15:R.getLogger().info("Node: ",L[I-1].id),R.addNode(L[I-2].length,L[I-1].id,L[I-1].descr,L[I-1].type,L[I]);break;case 16:R.getLogger().info("Node: ",L[I].id),R.addNode(L[I-1].length,L[I].id,L[I].descr,L[I].type);break;case 17:R.getLogger().trace("Icon: ",L[I]),R.decorateNode({icon:L[I]});break;case 18:case 23:R.decorateNode({class:L[I]});break;case 19:R.getLogger().trace("SPACELIST");break;case 20:R.getLogger().trace("Node: ",L[I-1].id),R.addNode(0,L[I-1].id,L[I-1].descr,L[I-1].type,L[I]);break;case 21:R.getLogger().trace("Node: ",L[I].id),R.addNode(0,L[I].id,L[I].descr,L[I].type);break;case 22:R.decorateNode({icon:L[I]});break;case 27:R.getLogger().trace("node found ..",L[I-2]),this.$={id:L[I-1],descr:L[I-1],type:R.getType(L[I-2],L[I])};break;case 28:this.$={id:L[I],descr:L[I],type:0};break;case 29:R.getLogger().trace("node found ..",L[I-3]),this.$={id:L[I-3],descr:L[I-1],type:R.getType(L[I-2],L[I])};break;case 30:this.$=L[I-1]+L[I];break;case 31:this.$=L[I];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:r,9:22,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:h,7:f,10:23,11:d},t(p,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:s,23:l}),t(p,[2,19]),t(p,[2,21],{15:30,24:m}),t(p,[2,22]),t(p,[2,23]),t(g,[2,25]),t(g,[2,26]),t(g,[2,28],{20:[1,32]}),{21:[1,33]},{6:h,7:f,10:34,11:d},{1:[2,7],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(y,[2,14],{7:v,11:x}),t(b,[2,8]),t(b,[2,9]),t(b,[2,10]),t(p,[2,16],{15:37,24:m}),t(p,[2,17]),t(p,[2,18]),t(p,[2,20],{24:T}),t(g,[2,31]),{21:[1,39]},{22:[1,40]},t(y,[2,13],{7:v,11:x}),t(b,[2,11]),t(b,[2,12]),t(p,[2,15],{24:T}),t(g,[2,30]),{22:[1,41]},t(g,[2,27]),t(g,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(C,D){if(D.recoverable)this.trace(C);else{var O=new Error(C);throw O.hash=D,O}},"parseError"),parse:o(function(C){var D=this,O=[0],R=[],k=[null],L=[],A=this.table,I="",M=0,P=0,B=0,F=2,z=1,$=L.slice.call(arguments,1),U=Object.create(this.lexer),K={yy:{}};for(var ee in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ee)&&(K.yy[ee]=this.yy[ee]);U.setInput(C,K.yy),K.yy.lexer=U,K.yy.parser=this,typeof U.yylloc>"u"&&(U.yylloc={});var Y=U.yylloc;L.push(Y);var ce=U.options&&U.options.ranges;typeof K.yy.parseError=="function"?this.parseError=K.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Z(Be){O.length=O.length-2*Be,k.length=k.length-Be,L.length=L.length-Be}o(Z,"popStack");function ue(){var Be;return Be=R.pop()||U.lex()||z,typeof Be!="number"&&(Be instanceof Array&&(R=Be,Be=R.pop()),Be=D.symbols_[Be]||Be),Be}o(ue,"lex");for(var Q,j,ne,te,he,le,J={},Se,se,ae,Oe;;){if(ne=O[O.length-1],this.defaultActions[ne]?te=this.defaultActions[ne]:((Q===null||typeof Q>"u")&&(Q=ue()),te=A[ne]&&A[ne][Q]),typeof te>"u"||!te.length||!te[0]){var ye="";Oe=[];for(Se in A[ne])this.terminals_[Se]&&Se>F&&Oe.push("'"+this.terminals_[Se]+"'");U.showPosition?ye="Parse error on line "+(M+1)+`: +`+U.showPosition()+` +Expecting `+Oe.join(", ")+", got '"+(this.terminals_[Q]||Q)+"'":ye="Parse error on line "+(M+1)+": Unexpected "+(Q==z?"end of input":"'"+(this.terminals_[Q]||Q)+"'"),this.parseError(ye,{text:U.match,token:this.terminals_[Q]||Q,line:U.yylineno,loc:Y,expected:Oe})}if(te[0]instanceof Array&&te.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ne+", token: "+Q);switch(te[0]){case 1:O.push(Q),k.push(U.yytext),L.push(U.yylloc),O.push(te[1]),Q=null,j?(Q=j,j=null):(P=U.yyleng,I=U.yytext,M=U.yylineno,Y=U.yylloc,B>0&&B--);break;case 2:if(se=this.productions_[te[1]][1],J.$=k[k.length-se],J._$={first_line:L[L.length-(se||1)].first_line,last_line:L[L.length-1].last_line,first_column:L[L.length-(se||1)].first_column,last_column:L[L.length-1].last_column},ce&&(J._$.range=[L[L.length-(se||1)].range[0],L[L.length-1].range[1]]),le=this.performAction.apply(J,[I,P,M,K.yy,te[1],k,L].concat($)),typeof le<"u")return le;se&&(O=O.slice(0,-1*se*2),k=k.slice(0,-1*se),L=L.slice(0,-1*se)),O.push(this.productions_[te[1]][0]),k.push(J.$),L.push(J._$),ae=A[O[O.length-2]][O[O.length-1]],O.push(ae);break;case 3:return!0}}return!0},"parse")},w=function(){var _={EOF:1,parseError:o(function(D,O){if(this.yy.parser)this.yy.parser.parseError(D,O);else throw new Error(D)},"parseError"),setInput:o(function(C,D){return this.yy=D||this.yy||{},this._input=C,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var C=this._input[0];this.yytext+=C,this.yyleng++,this.offset++,this.match+=C,this.matched+=C;var D=C.match(/(?:\r\n?|\n).*/g);return D?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),C},"input"),unput:o(function(C){var D=C.length,O=C.split(/(?:\r\n?|\n)/g);this._input=C+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-D),this.offset-=D;var R=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),O.length-1&&(this.yylineno-=O.length-1);var k=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:O?(O.length===R.length?this.yylloc.first_column:0)+R[R.length-O.length].length-O[0].length:this.yylloc.first_column-D},this.options.ranges&&(this.yylloc.range=[k[0],k[0]+this.yyleng-D]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(C){this.unput(this.match.slice(C))},"less"),pastInput:o(function(){var C=this.matched.substr(0,this.matched.length-this.match.length);return(C.length>20?"...":"")+C.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var C=this.match;return C.length<20&&(C+=this._input.substr(0,20-C.length)),(C.substr(0,20)+(C.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var C=this.pastInput(),D=new Array(C.length+1).join("-");return C+this.upcomingInput()+` +`+D+"^"},"showPosition"),test_match:o(function(C,D){var O,R,k;if(this.options.backtrack_lexer&&(k={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(k.yylloc.range=this.yylloc.range.slice(0))),R=C[0].match(/(?:\r\n?|\n).*/g),R&&(this.yylineno+=R.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:R?R[R.length-1].length-R[R.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+C[0].length},this.yytext+=C[0],this.match+=C[0],this.matches=C,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(C[0].length),this.matched+=C[0],O=this.performAction.call(this,this.yy,this,D,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),O)return O;if(this._backtrack){for(var L in k)this[L]=k[L];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var C,D,O,R;this._more||(this.yytext="",this.match="");for(var k=this._currentRules(),L=0;LD[0].length)){if(D=O,R=L,this.options.backtrack_lexer){if(C=this.test_match(O,k[L]),C!==!1)return C;if(this._backtrack){D=!1;continue}else return!1}else if(!this.options.flex)break}return D?(C=this.test_match(D,k[R]),C!==!1?C:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var D=this.next();return D||this.lex()},"lex"),begin:o(function(D){this.conditionStack.push(D)},"begin"),popState:o(function(){var D=this.conditionStack.length-1;return D>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(D){return D=this.conditionStack.length-1-Math.abs(D||0),D>=0?this.conditionStack[D]:"INITIAL"},"topState"),pushState:o(function(D){this.begin(D)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(D,O,R,k){var L=k;switch(R){case 0:return this.pushState("shapeData"),O.yytext="",24;break;case 1:return this.pushState("shapeDataStr"),24;break;case 2:return this.popState(),24;break;case 3:let A=/\n\s*/g;return O.yytext=O.yytext.replace(A,"
    "),24;break;case 4:return 24;case 5:this.popState();break;case 6:return D.getLogger().trace("Found comment",O.yytext),6;break;case 7:return 8;case 8:this.begin("CLASS");break;case 9:return this.popState(),17;break;case 10:this.popState();break;case 11:D.getLogger().trace("Begin icon"),this.begin("ICON");break;case 12:return D.getLogger().trace("SPACELINE"),6;break;case 13:return 7;case 14:return 16;case 15:D.getLogger().trace("end icon"),this.popState();break;case 16:return D.getLogger().trace("Exploding node"),this.begin("NODE"),20;break;case 17:return D.getLogger().trace("Cloud"),this.begin("NODE"),20;break;case 18:return D.getLogger().trace("Explosion Bang"),this.begin("NODE"),20;break;case 19:return D.getLogger().trace("Cloud Bang"),this.begin("NODE"),20;break;case 20:return this.begin("NODE"),20;break;case 21:return this.begin("NODE"),20;break;case 22:return this.begin("NODE"),20;break;case 23:return this.begin("NODE"),20;break;case 24:return 13;case 25:return 23;case 26:return 11;case 27:this.begin("NSTR2");break;case 28:return"NODE_DESCR";case 29:this.popState();break;case 30:D.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 31:return D.getLogger().trace("description:",O.yytext),"NODE_DESCR";break;case 32:this.popState();break;case 33:return this.popState(),D.getLogger().trace("node end ))"),"NODE_DEND";break;case 34:return this.popState(),D.getLogger().trace("node end )"),"NODE_DEND";break;case 35:return this.popState(),D.getLogger().trace("node end ...",O.yytext),"NODE_DEND";break;case 36:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 37:return this.popState(),D.getLogger().trace("node end (-"),"NODE_DEND";break;case 38:return this.popState(),D.getLogger().trace("node end (-"),"NODE_DEND";break;case 39:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 40:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 41:return D.getLogger().trace("Long description:",O.yytext),21;break;case 42:return D.getLogger().trace("Long description:",O.yytext),21;break}},"anonymous"),rules:[/^(?:@\{)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^\"]+)/i,/^(?:[^}^"]+)/i,/^(?:\})/i,/^(?:\s*%%.*)/i,/^(?:kanban\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}@]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{shapeDataEndBracket:{rules:[],inclusive:!1},shapeDataStr:{rules:[2,3],inclusive:!1},shapeData:{rules:[1,4,5],inclusive:!1},CLASS:{rules:[9,10],inclusive:!1},ICON:{rules:[14,15],inclusive:!1},NSTR2:{rules:[28,29],inclusive:!1},NSTR:{rules:[31,32],inclusive:!1},NODE:{rules:[27,30,33,34,35,36,37,38,39,40,41,42],inclusive:!1},INITIAL:{rules:[0,6,7,8,11,12,13,16,17,18,19,20,21,22,23,24,25,26],inclusive:!0}}};return _}();S.lexer=w;function E(){this.yy={}}return o(E,"Parser"),E.prototype=S,S.Parser=E,new E}();dF.parser=dF;fye=dF});var ol,mF,pF,gF,Met,Iet,pye,Oet,Pet,Xi,Bet,Fet,$et,zet,Get,Vet,Uet,mye,gye=N(()=>{"use strict";Gt();pr();yt();_a();PT();ol=[],mF=[],pF=0,gF={},Met=o(()=>{ol=[],mF=[],pF=0,gF={}},"clear"),Iet=o(t=>{if(ol.length===0)return null;let e=ol[0].level,r=null;for(let n=ol.length-1;n>=0;n--)if(ol[n].level===e&&!r&&(r=ol[n]),ol[n].levell.parentId===i.id);for(let l of s){let u={id:l.id,parentId:i.id,label:wr(l.label??"",n),isGroup:!1,ticket:l?.ticket,priority:l?.priority,assigned:l?.assigned,icon:l?.icon,shape:"kanbanItem",level:l.level,rx:5,ry:5,cssStyles:["text-align: left"]};e.push(u)}}return{nodes:e,edges:t,other:{},config:me()}},"getData"),Pet=o((t,e,r,n,i)=>{let a=me(),s=a.mindmap?.padding??or.mindmap.padding;switch(n){case Xi.ROUNDED_RECT:case Xi.RECT:case Xi.HEXAGON:s*=2}let l={id:wr(e,a)||"kbn"+pF++,level:t,label:wr(r,a),width:a.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:s,isGroup:!1};if(i!==void 0){let h;i.includes(` +`)?h=i+` +`:h=`{ +`+i+` +}`;let f=Tm(h,{schema:bm});if(f.shape&&(f.shape!==f.shape.toLowerCase()||f.shape.includes("_")))throw new Error(`No such shape: ${f.shape}. Shape names should be lowercase.`);f?.shape&&f.shape==="kanbanItem"&&(l.shape=f?.shape),f?.label&&(l.label=f?.label),f?.icon&&(l.icon=f?.icon.toString()),f?.assigned&&(l.assigned=f?.assigned.toString()),f?.ticket&&(l.ticket=f?.ticket.toString()),f?.priority&&(l.priority=f?.priority)}let u=Iet(t);u?l.parentId=u.id||"kbn"+pF++:mF.push(l),ol.push(l)},"addNode"),Xi={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},Bet=o((t,e)=>{switch(X.debug("In get type",t,e),t){case"[":return Xi.RECT;case"(":return e===")"?Xi.ROUNDED_RECT:Xi.CLOUD;case"((":return Xi.CIRCLE;case")":return Xi.CLOUD;case"))":return Xi.BANG;case"{{":return Xi.HEXAGON;default:return Xi.DEFAULT}},"getType"),Fet=o((t,e)=>{gF[t]=e},"setElementForId"),$et=o(t=>{if(!t)return;let e=me(),r=ol[ol.length-1];t.icon&&(r.icon=wr(t.icon,e)),t.class&&(r.cssClasses=wr(t.class,e))},"decorateNode"),zet=o(t=>{switch(t){case Xi.DEFAULT:return"no-border";case Xi.RECT:return"rect";case Xi.ROUNDED_RECT:return"rounded-rect";case Xi.CIRCLE:return"circle";case Xi.CLOUD:return"cloud";case Xi.BANG:return"bang";case Xi.HEXAGON:return"hexgon";default:return"no-border"}},"type2Str"),Get=o(()=>X,"getLogger"),Vet=o(t=>gF[t],"getElementById"),Uet={clear:Met,addNode:Pet,getSections:pye,getData:Oet,nodeType:Xi,getType:Bet,setElementForId:Fet,decorateNode:$et,type2Str:zet,getLogger:Get,getElementById:Vet},mye=Uet});var Het,yye,vye=N(()=>{"use strict";Gt();yt();Vl();xi();_a();aw();mw();Het=o(async(t,e,r,n)=>{X.debug(`Rendering kanban diagram +`+t);let a=n.db.getData(),s=me();s.htmlLabels=!1;let l=Li(e),u=l.append("g");u.attr("class","sections");let h=l.append("g");h.attr("class","items");let f=a.nodes.filter(v=>v.isGroup),d=0,p=10,m=[],g=25;for(let v of f){let x=s?.kanban?.sectionWidth||200;d=d+1,v.x=x*d+(d-1)*p/2,v.width=x,v.y=0,v.height=x*3,v.rx=5,v.ry=5,v.cssClasses=v.cssClasses+" section-"+d;let b=await Cm(u,v);g=Math.max(g,b?.labelBBox?.height),m.push(b)}let y=0;for(let v of f){let x=m[y];y=y+1;let b=s?.kanban?.sectionWidth||200,T=-b*3/2+g,S=T,w=a.nodes.filter(C=>C.parentId===v.id);for(let C of w){if(C.isGroup)throw new Error("Groups within groups are not allowed in Kanban diagrams");C.x=v.x,C.width=b-1.5*p;let O=(await Am(h,C,{config:s})).node().getBBox();C.y=S+O.height/2,await M2(C),S=C.y+O.height/2+p/2}let E=x.cluster.select("rect"),_=Math.max(S-T+3*p,50)+(g-25);E.attr("height",_)}Lo(void 0,l,s.mindmap?.padding??or.kanban.padding,s.mindmap?.useMaxWidth??or.kanban.useMaxWidth)},"draw"),yye={draw:Het}});var Wet,qet,xye,bye=N(()=>{"use strict";Ks();Xm();Wet=o(t=>{let e="";for(let n=0;nt.darkMode?Ot(n,i):Lt(n,i),"adjuster");for(let n=0;n` + .edge { + stroke-width: 3; + } + ${Wet(t)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${t.git0}; + } + .section-root text { + fill: ${t.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .cluster-label, .label { + color: ${t.textColor}; + fill: ${t.textColor}; + } + .kanban-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } + ${Nc()} +`,"getStyles"),xye=qet});var Tye={};ur(Tye,{diagram:()=>Yet});var Yet,wye=N(()=>{"use strict";dye();gye();vye();bye();Yet={db:mye,renderer:yye,parser:fye,styles:xye}});var yF,E4,Sye=N(()=>{"use strict";yF=function(){var t=o(function(l,u,h,f){for(h=h||{},f=l.length;f--;h[l[f]]=u);return h},"o"),e=[1,9],r=[1,10],n=[1,5,10,12],i={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:o(function(u,h,f,d,p,m,g){var y=m.length-1;switch(p){case 7:let v=d.findOrCreateNode(m[y-4].trim().replaceAll('""','"')),x=d.findOrCreateNode(m[y-2].trim().replaceAll('""','"')),b=parseFloat(m[y].trim());d.addLink(v,x,b);break;case 8:case 9:case 11:this.$=m[y];break;case 10:this.$=m[y-1];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:e,20:r},{1:[2,6],7:11,10:[1,12]},t(r,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(n,[2,8]),t(n,[2,9]),{19:[1,16]},t(n,[2,11]),{1:[2,1]},{1:[2,5]},t(r,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:e,20:r},{15:18,16:7,17:8,18:e,20:r},{18:[1,19]},t(r,[2,3]),{12:[1,20]},t(n,[2,10]),{15:21,16:7,17:8,18:e,20:r},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:o(function(u,h){if(h.recoverable)this.trace(u);else{var f=new Error(u);throw f.hash=h,f}},"parseError"),parse:o(function(u){var h=this,f=[0],d=[],p=[null],m=[],g=this.table,y="",v=0,x=0,b=0,T=2,S=1,w=m.slice.call(arguments,1),E=Object.create(this.lexer),_={yy:{}};for(var C in this.yy)Object.prototype.hasOwnProperty.call(this.yy,C)&&(_.yy[C]=this.yy[C]);E.setInput(u,_.yy),_.yy.lexer=E,_.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var D=E.yylloc;m.push(D);var O=E.options&&E.options.ranges;typeof _.yy.parseError=="function"?this.parseError=_.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function R(Y){f.length=f.length-2*Y,p.length=p.length-Y,m.length=m.length-Y}o(R,"popStack");function k(){var Y;return Y=d.pop()||E.lex()||S,typeof Y!="number"&&(Y instanceof Array&&(d=Y,Y=d.pop()),Y=h.symbols_[Y]||Y),Y}o(k,"lex");for(var L,A,I,M,P,B,F={},z,$,U,K;;){if(I=f[f.length-1],this.defaultActions[I]?M=this.defaultActions[I]:((L===null||typeof L>"u")&&(L=k()),M=g[I]&&g[I][L]),typeof M>"u"||!M.length||!M[0]){var ee="";K=[];for(z in g[I])this.terminals_[z]&&z>T&&K.push("'"+this.terminals_[z]+"'");E.showPosition?ee="Parse error on line "+(v+1)+`: +`+E.showPosition()+` +Expecting `+K.join(", ")+", got '"+(this.terminals_[L]||L)+"'":ee="Parse error on line "+(v+1)+": Unexpected "+(L==S?"end of input":"'"+(this.terminals_[L]||L)+"'"),this.parseError(ee,{text:E.match,token:this.terminals_[L]||L,line:E.yylineno,loc:D,expected:K})}if(M[0]instanceof Array&&M.length>1)throw new Error("Parse Error: multiple actions possible at state: "+I+", token: "+L);switch(M[0]){case 1:f.push(L),p.push(E.yytext),m.push(E.yylloc),f.push(M[1]),L=null,A?(L=A,A=null):(x=E.yyleng,y=E.yytext,v=E.yylineno,D=E.yylloc,b>0&&b--);break;case 2:if($=this.productions_[M[1]][1],F.$=p[p.length-$],F._$={first_line:m[m.length-($||1)].first_line,last_line:m[m.length-1].last_line,first_column:m[m.length-($||1)].first_column,last_column:m[m.length-1].last_column},O&&(F._$.range=[m[m.length-($||1)].range[0],m[m.length-1].range[1]]),B=this.performAction.apply(F,[y,x,v,_.yy,M[1],p,m].concat(w)),typeof B<"u")return B;$&&(f=f.slice(0,-1*$*2),p=p.slice(0,-1*$),m=m.slice(0,-1*$)),f.push(this.productions_[M[1]][0]),p.push(F.$),m.push(F._$),U=g[f[f.length-2]][f[f.length-1]],f.push(U);break;case 3:return!0}}return!0},"parse")},a=function(){var l={EOF:1,parseError:o(function(h,f){if(this.yy.parser)this.yy.parser.parseError(h,f);else throw new Error(h)},"parseError"),setInput:o(function(u,h){return this.yy=h||this.yy||{},this._input=u,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var u=this._input[0];this.yytext+=u,this.yyleng++,this.offset++,this.match+=u,this.matched+=u;var h=u.match(/(?:\r\n?|\n).*/g);return h?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),u},"input"),unput:o(function(u){var h=u.length,f=u.split(/(?:\r\n?|\n)/g);this._input=u+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-h),this.offset-=h;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===d.length?this.yylloc.first_column:0)+d[d.length-f.length].length-f[0].length:this.yylloc.first_column-h},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-h]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(u){this.unput(this.match.slice(u))},"less"),pastInput:o(function(){var u=this.matched.substr(0,this.matched.length-this.match.length);return(u.length>20?"...":"")+u.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var u=this.match;return u.length<20&&(u+=this._input.substr(0,20-u.length)),(u.substr(0,20)+(u.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var u=this.pastInput(),h=new Array(u.length+1).join("-");return u+this.upcomingInput()+` +`+h+"^"},"showPosition"),test_match:o(function(u,h){var f,d,p;if(this.options.backtrack_lexer&&(p={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(p.yylloc.range=this.yylloc.range.slice(0))),d=u[0].match(/(?:\r\n?|\n).*/g),d&&(this.yylineno+=d.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:d?d[d.length-1].length-d[d.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+u[0].length},this.yytext+=u[0],this.match+=u[0],this.matches=u,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(u[0].length),this.matched+=u[0],f=this.performAction.call(this,this.yy,this,h,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),f)return f;if(this._backtrack){for(var m in p)this[m]=p[m];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var u,h,f,d;this._more||(this.yytext="",this.match="");for(var p=this._currentRules(),m=0;mh[0].length)){if(h=f,d=m,this.options.backtrack_lexer){if(u=this.test_match(f,p[m]),u!==!1)return u;if(this._backtrack){h=!1;continue}else return!1}else if(!this.options.flex)break}return h?(u=this.test_match(h,p[d]),u!==!1?u:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var h=this.next();return h||this.lex()},"lex"),begin:o(function(h){this.conditionStack.push(h)},"begin"),popState:o(function(){var h=this.conditionStack.length-1;return h>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(h){return h=this.conditionStack.length-1-Math.abs(h||0),h>=0?this.conditionStack[h]:"INITIAL"},"topState"),pushState:o(function(h){this.begin(h)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(h,f,d,p){var m=p;switch(d){case 0:return this.pushState("csv"),4;break;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;break;case 5:return 20;case 6:return this.popState("escaped_text"),18;break;case 7:return 19}},"anonymous"),rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};return l}();i.lexer=a;function s(){this.yy={}}return o(s,"Parser"),s.prototype=i,i.Parser=s,new s}();yF.parser=yF;E4=yF});var pC,mC,dC,Qet,vF,Zet,xF,Jet,ett,ttt,rtt,Cye,Aye=N(()=>{"use strict";Gt();pr();ci();pC=[],mC=[],dC=new Map,Qet=o(()=>{pC=[],mC=[],dC=new Map,kr()},"clear"),vF=class{constructor(e,r,n=0){this.source=e;this.target=r;this.value=n}static{o(this,"SankeyLink")}},Zet=o((t,e,r)=>{pC.push(new vF(t,e,r))},"addLink"),xF=class{constructor(e){this.ID=e}static{o(this,"SankeyNode")}},Jet=o(t=>{t=Ze.sanitizeText(t,me());let e=dC.get(t);return e===void 0&&(e=new xF(t),dC.set(t,e),mC.push(e)),e},"findOrCreateNode"),ett=o(()=>mC,"getNodes"),ttt=o(()=>pC,"getLinks"),rtt=o(()=>({nodes:mC.map(t=>({id:t.ID})),links:pC.map(t=>({source:t.source.ID,target:t.target.ID,value:t.value}))}),"getGraph"),Cye={nodesMap:dC,getConfig:o(()=>me().sankey,"getConfig"),getNodes:ett,getLinks:ttt,getGraph:rtt,addLink:Zet,findOrCreateNode:Jet,getAccTitle:Dr,setAccTitle:Ar,getAccDescription:Rr,setAccDescription:Lr,getDiagramTitle:Nr,setDiagramTitle:Or,clear:Qet}});function S4(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}var _ye=N(()=>{"use strict";o(S4,"max")});function my(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var Dye=N(()=>{"use strict";o(my,"min")});function gy(t,e){let r=0;if(e===void 0)for(let n of t)(n=+n)&&(r+=n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&(r+=i)}return r}var Lye=N(()=>{"use strict";o(gy,"sum")});var bF=N(()=>{"use strict";_ye();Dye();Lye()});function ntt(t){return t.target.depth}function TF(t){return t.depth}function wF(t,e){return e-1-t.height}function C4(t,e){return t.sourceLinks.length?t.depth:e-1}function kF(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?my(t.sourceLinks,ntt)-1:0}var EF=N(()=>{"use strict";bF();o(ntt,"targetDepth");o(TF,"left");o(wF,"right");o(C4,"justify");o(kF,"center")});function yy(t){return function(){return t}}var Rye=N(()=>{"use strict";o(yy,"constant")});function Nye(t,e){return gC(t.source,e.source)||t.index-e.index}function Mye(t,e){return gC(t.target,e.target)||t.index-e.index}function gC(t,e){return t.y0-e.y0}function SF(t){return t.value}function itt(t){return t.index}function att(t){return t.nodes}function stt(t){return t.links}function Iye(t,e){let r=t.get(e);if(!r)throw new Error("missing: "+e);return r}function Oye({nodes:t}){for(let e of t){let r=e.y0,n=r;for(let i of e.sourceLinks)i.y0=r+i.width/2,r+=i.width;for(let i of e.targetLinks)i.y1=n+i.width/2,n+=i.width}}function yC(){let t=0,e=0,r=1,n=1,i=24,a=8,s,l=itt,u=C4,h,f,d=att,p=stt,m=6;function g(){let I={nodes:d.apply(null,arguments),links:p.apply(null,arguments)};return y(I),v(I),x(I),b(I),w(I),Oye(I),I}o(g,"sankey"),g.update=function(I){return Oye(I),I},g.nodeId=function(I){return arguments.length?(l=typeof I=="function"?I:yy(I),g):l},g.nodeAlign=function(I){return arguments.length?(u=typeof I=="function"?I:yy(I),g):u},g.nodeSort=function(I){return arguments.length?(h=I,g):h},g.nodeWidth=function(I){return arguments.length?(i=+I,g):i},g.nodePadding=function(I){return arguments.length?(a=s=+I,g):a},g.nodes=function(I){return arguments.length?(d=typeof I=="function"?I:yy(I),g):d},g.links=function(I){return arguments.length?(p=typeof I=="function"?I:yy(I),g):p},g.linkSort=function(I){return arguments.length?(f=I,g):f},g.size=function(I){return arguments.length?(t=e=0,r=+I[0],n=+I[1],g):[r-t,n-e]},g.extent=function(I){return arguments.length?(t=+I[0][0],r=+I[1][0],e=+I[0][1],n=+I[1][1],g):[[t,e],[r,n]]},g.iterations=function(I){return arguments.length?(m=+I,g):m};function y({nodes:I,links:M}){for(let[B,F]of I.entries())F.index=B,F.sourceLinks=[],F.targetLinks=[];let P=new Map(I.map((B,F)=>[l(B,F,I),B]));for(let[B,F]of M.entries()){F.index=B;let{source:z,target:$}=F;typeof z!="object"&&(z=F.source=Iye(P,z)),typeof $!="object"&&($=F.target=Iye(P,$)),z.sourceLinks.push(F),$.targetLinks.push(F)}if(f!=null)for(let{sourceLinks:B,targetLinks:F}of I)B.sort(f),F.sort(f)}o(y,"computeNodeLinks");function v({nodes:I}){for(let M of I)M.value=M.fixedValue===void 0?Math.max(gy(M.sourceLinks,SF),gy(M.targetLinks,SF)):M.fixedValue}o(v,"computeNodeValues");function x({nodes:I}){let M=I.length,P=new Set(I),B=new Set,F=0;for(;P.size;){for(let z of P){z.depth=F;for(let{target:$}of z.sourceLinks)B.add($)}if(++F>M)throw new Error("circular link");P=B,B=new Set}}o(x,"computeNodeDepths");function b({nodes:I}){let M=I.length,P=new Set(I),B=new Set,F=0;for(;P.size;){for(let z of P){z.height=F;for(let{source:$}of z.targetLinks)B.add($)}if(++F>M)throw new Error("circular link");P=B,B=new Set}}o(b,"computeNodeHeights");function T({nodes:I}){let M=S4(I,F=>F.depth)+1,P=(r-t-i)/(M-1),B=new Array(M);for(let F of I){let z=Math.max(0,Math.min(M-1,Math.floor(u.call(null,F,M))));F.layer=z,F.x0=t+z*P,F.x1=F.x0+i,B[z]?B[z].push(F):B[z]=[F]}if(h)for(let F of B)F.sort(h);return B}o(T,"computeNodeLayers");function S(I){let M=my(I,P=>(n-e-(P.length-1)*s)/gy(P,SF));for(let P of I){let B=e;for(let F of P){F.y0=B,F.y1=B+F.value*M,B=F.y1+s;for(let z of F.sourceLinks)z.width=z.value*M}B=(n-B+s)/(P.length+1);for(let F=0;FP.length)-1)),S(M);for(let P=0;P0))continue;let ee=(U/K-$.y0)*M;$.y0+=ee,$.y1+=ee,R($)}h===void 0&&z.sort(gC),C(z,P)}}o(E,"relaxLeftToRight");function _(I,M,P){for(let B=I.length,F=B-2;F>=0;--F){let z=I[F];for(let $ of z){let U=0,K=0;for(let{target:Y,value:ce}of $.sourceLinks){let Z=ce*(Y.layer-$.layer);U+=A($,Y)*Z,K+=Z}if(!(K>0))continue;let ee=(U/K-$.y0)*M;$.y0+=ee,$.y1+=ee,R($)}h===void 0&&z.sort(gC),C(z,P)}}o(_,"relaxRightToLeft");function C(I,M){let P=I.length>>1,B=I[P];O(I,B.y0-s,P-1,M),D(I,B.y1+s,P+1,M),O(I,n,I.length-1,M),D(I,e,0,M)}o(C,"resolveCollisions");function D(I,M,P,B){for(;P1e-6&&(F.y0+=z,F.y1+=z),M=F.y1+s}}o(D,"resolveCollisionsTopToBottom");function O(I,M,P,B){for(;P>=0;--P){let F=I[P],z=(F.y1-M)*B;z>1e-6&&(F.y0-=z,F.y1-=z),M=F.y0-s}}o(O,"resolveCollisionsBottomToTop");function R({sourceLinks:I,targetLinks:M}){if(f===void 0){for(let{source:{sourceLinks:P}}of M)P.sort(Mye);for(let{target:{targetLinks:P}}of I)P.sort(Nye)}}o(R,"reorderNodeLinks");function k(I){if(f===void 0)for(let{sourceLinks:M,targetLinks:P}of I)M.sort(Mye),P.sort(Nye)}o(k,"reorderLinks");function L(I,M){let P=I.y0-(I.sourceLinks.length-1)*s/2;for(let{target:B,width:F}of I.sourceLinks){if(B===M)break;P+=F+s}for(let{source:B,width:F}of M.targetLinks){if(B===I)break;P-=F}return P}o(L,"targetTop");function A(I,M){let P=M.y0-(M.targetLinks.length-1)*s/2;for(let{source:B,width:F}of M.targetLinks){if(B===I)break;P+=F+s}for(let{target:B,width:F}of I.sourceLinks){if(B===M)break;P-=F}return P}return o(A,"sourceTop"),g}var Pye=N(()=>{"use strict";bF();EF();Rye();o(Nye,"ascendingSourceBreadth");o(Mye,"ascendingTargetBreadth");o(gC,"ascendingBreadth");o(SF,"value");o(itt,"defaultId");o(att,"defaultNodes");o(stt,"defaultLinks");o(Iye,"find");o(Oye,"computeLinkBreadths");o(yC,"Sankey")});function _F(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function Bye(){return new _F}var CF,AF,i0,ott,DF,Fye=N(()=>{"use strict";CF=Math.PI,AF=2*CF,i0=1e-6,ott=AF-i0;o(_F,"Path");o(Bye,"path");_F.prototype=Bye.prototype={constructor:_F,moveTo:o(function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},"moveTo"),closePath:o(function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},"closePath"),lineTo:o(function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},"lineTo"),quadraticCurveTo:o(function(t,e,r,n){this._+="Q"+ +t+","+ +e+","+(this._x1=+r)+","+(this._y1=+n)},"quadraticCurveTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._+="C"+ +t+","+ +e+","+ +r+","+ +n+","+(this._x1=+i)+","+(this._y1=+a)},"bezierCurveTo"),arcTo:o(function(t,e,r,n,i){t=+t,e=+e,r=+r,n=+n,i=+i;var a=this._x1,s=this._y1,l=r-t,u=n-e,h=a-t,f=s-e,d=h*h+f*f;if(i<0)throw new Error("negative radius: "+i);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(d>i0)if(!(Math.abs(f*l-u*h)>i0)||!i)this._+="L"+(this._x1=t)+","+(this._y1=e);else{var p=r-a,m=n-s,g=l*l+u*u,y=p*p+m*m,v=Math.sqrt(g),x=Math.sqrt(d),b=i*Math.tan((CF-Math.acos((g+d-y)/(2*v*x)))/2),T=b/x,S=b/v;Math.abs(T-1)>i0&&(this._+="L"+(t+T*h)+","+(e+T*f)),this._+="A"+i+","+i+",0,0,"+ +(f*p>h*m)+","+(this._x1=t+S*l)+","+(this._y1=e+S*u)}},"arcTo"),arc:o(function(t,e,r,n,i,a){t=+t,e=+e,r=+r,a=!!a;var s=r*Math.cos(n),l=r*Math.sin(n),u=t+s,h=e+l,f=1^a,d=a?n-i:i-n;if(r<0)throw new Error("negative radius: "+r);this._x1===null?this._+="M"+u+","+h:(Math.abs(this._x1-u)>i0||Math.abs(this._y1-h)>i0)&&(this._+="L"+u+","+h),r&&(d<0&&(d=d%AF+AF),d>ott?this._+="A"+r+","+r+",0,1,"+f+","+(t-s)+","+(e-l)+"A"+r+","+r+",0,1,"+f+","+(this._x1=u)+","+(this._y1=h):d>i0&&(this._+="A"+r+","+r+",0,"+ +(d>=CF)+","+f+","+(this._x1=t+r*Math.cos(i))+","+(this._y1=e+r*Math.sin(i))))},"arc"),rect:o(function(t,e,r,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +r+"v"+ +n+"h"+-r+"Z"},"rect"),toString:o(function(){return this._},"toString")};DF=Bye});var $ye=N(()=>{"use strict";Fye()});function vC(t){return o(function(){return t},"constant")}var zye=N(()=>{"use strict";o(vC,"default")});function Gye(t){return t[0]}function Vye(t){return t[1]}var Uye=N(()=>{"use strict";o(Gye,"x");o(Vye,"y")});var Hye,Wye=N(()=>{"use strict";Hye=Array.prototype.slice});function ltt(t){return t.source}function ctt(t){return t.target}function utt(t){var e=ltt,r=ctt,n=Gye,i=Vye,a=null;function s(){var l,u=Hye.call(arguments),h=e.apply(this,u),f=r.apply(this,u);if(a||(a=l=DF()),t(a,+n.apply(this,(u[0]=h,u)),+i.apply(this,u),+n.apply(this,(u[0]=f,u)),+i.apply(this,u)),l)return a=null,l+""||null}return o(s,"link"),s.source=function(l){return arguments.length?(e=l,s):e},s.target=function(l){return arguments.length?(r=l,s):r},s.x=function(l){return arguments.length?(n=typeof l=="function"?l:vC(+l),s):n},s.y=function(l){return arguments.length?(i=typeof l=="function"?l:vC(+l),s):i},s.context=function(l){return arguments.length?(a=l??null,s):a},s}function htt(t,e,r,n,i){t.moveTo(e,r),t.bezierCurveTo(e=(e+n)/2,r,e,i,n,i)}function LF(){return utt(htt)}var qye=N(()=>{"use strict";$ye();Wye();zye();Uye();o(ltt,"linkSource");o(ctt,"linkTarget");o(utt,"link");o(htt,"curveHorizontal");o(LF,"linkHorizontal")});var Yye=N(()=>{"use strict";qye()});function ftt(t){return[t.source.x1,t.y0]}function dtt(t){return[t.target.x0,t.y1]}function xC(){return LF().source(ftt).target(dtt)}var Xye=N(()=>{"use strict";Yye();o(ftt,"horizontalSource");o(dtt,"horizontalTarget");o(xC,"default")});var jye=N(()=>{"use strict";Pye();EF();Xye()});var A4,Kye=N(()=>{"use strict";A4=class t{static{o(this,"Uid")}static{this.count=0}static next(e){return new t(e+ ++t.count)}constructor(e){this.id=e,this.href=`#${e}`}toString(){return"url("+this.href+")"}}});var ptt,mtt,Qye,Zye=N(()=>{"use strict";Gt();fr();jye();xi();Kye();ptt={left:TF,right:wF,center:kF,justify:C4},mtt=o(function(t,e,r,n){let{securityLevel:i,sankey:a}=me(),s=$3.sankey,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=a?.width??s.width,d=a?.height??s.width,p=a?.useMaxWidth??s.useMaxWidth,m=a?.nodeAlignment??s.nodeAlignment,g=a?.prefix??s.prefix,y=a?.suffix??s.suffix,v=a?.showValues??s.showValues,x=n.db.getGraph(),b=ptt[m];yC().nodeId(O=>O.id).nodeWidth(10).nodePadding(10+(v?15:0)).nodeAlign(b).extent([[0,0],[f,d]])(x);let w=Js(PD);h.append("g").attr("class","nodes").selectAll(".node").data(x.nodes).join("g").attr("class","node").attr("id",O=>(O.uid=A4.next("node-")).id).attr("transform",function(O){return"translate("+O.x0+","+O.y0+")"}).attr("x",O=>O.x0).attr("y",O=>O.y0).append("rect").attr("height",O=>O.y1-O.y0).attr("width",O=>O.x1-O.x0).attr("fill",O=>w(O.id));let E=o(({id:O,value:R})=>v?`${O} +${g}${Math.round(R*100)/100}${y}`:O,"getText");h.append("g").attr("class","node-labels").attr("font-size",14).selectAll("text").data(x.nodes).join("text").attr("x",O=>O.x0(O.y1+O.y0)/2).attr("dy",`${v?"0":"0.35"}em`).attr("text-anchor",O=>O.x0(R.uid=A4.next("linearGradient-")).id).attr("gradientUnits","userSpaceOnUse").attr("x1",R=>R.source.x1).attr("x2",R=>R.target.x0);O.append("stop").attr("offset","0%").attr("stop-color",R=>w(R.source.id)),O.append("stop").attr("offset","100%").attr("stop-color",R=>w(R.target.id))}let D;switch(C){case"gradient":D=o(O=>O.uid,"coloring");break;case"source":D=o(O=>w(O.source.id),"coloring");break;case"target":D=o(O=>w(O.target.id),"coloring");break;default:D=C}_.append("path").attr("d",xC()).attr("stroke",D).attr("stroke-width",O=>Math.max(1,O.width)),Lo(void 0,h,0,p)},"draw"),Qye={draw:mtt}});var Jye,eve=N(()=>{"use strict";Jye=o(t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,` +`).trim(),"prepareTextForParsing")});var gtt,tve,rve=N(()=>{"use strict";gtt=o(t=>`.label { + font-family: ${t.fontFamily}; + }`,"getStyles"),tve=gtt});var nve={};ur(nve,{diagram:()=>vtt});var ytt,vtt,ive=N(()=>{"use strict";Sye();Aye();Zye();eve();rve();ytt=E4.parse.bind(E4);E4.parse=t=>ytt(Jye(t));vtt={styles:tve,parser:E4,db:Cye,renderer:Qye}});var ove,RF,wtt,ktt,Ett,Stt,Ctt,qf,NF=N(()=>{"use strict";mi();_a();er();ci();ove={packet:[]},RF=structuredClone(ove),wtt=or.packet,ktt=o(()=>{let t=$n({...wtt,...tr().packet});return t.showBits&&(t.paddingY+=10),t},"getConfig"),Ett=o(()=>RF.packet,"getPacket"),Stt=o(t=>{t.length>0&&RF.packet.push(t)},"pushWord"),Ctt=o(()=>{kr(),RF=structuredClone(ove)},"clear"),qf={pushWord:Stt,getPacket:Ett,getConfig:ktt,clear:Ctt,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var Att,_tt,Dtt,lve,cve=N(()=>{"use strict";bf();yt();Mp();NF();Att=1e4,_tt=o(t=>{Jo(t,qf);let e=-1,r=[],n=1,{bitsPerRow:i}=qf.getConfig();for(let{start:a,end:s,bits:l,label:u}of t.blocks){if(a!==void 0&&s!==void 0&&s{if(t.start===void 0)throw new Error("start should have been set during first phase");if(t.end===void 0)throw new Error("end should have been set during first phase");if(t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);if(t.end+1<=e*r)return[t,void 0];let n=e*r-1,i=e*r;return[{start:t.start,end:n,label:t.label,bits:n-t.start},{start:i,end:t.end,label:t.label,bits:t.end-i}]},"getNextFittingBlock"),lve={parse:o(async t=>{let e=await vs("packet",t);X.debug(e),_tt(e)},"parse")}});var Ltt,Rtt,uve,hve=N(()=>{"use strict";Vl();xi();Ltt=o((t,e,r,n)=>{let i=n.db,a=i.getConfig(),{rowHeight:s,paddingY:l,bitWidth:u,bitsPerRow:h}=a,f=i.getPacket(),d=i.getDiagramTitle(),p=s+l,m=p*(f.length+1)-(d?0:s),g=u*h+2,y=Li(e);y.attr("viewbox",`0 0 ${g} ${m}`),fn(y,m,g,a.useMaxWidth);for(let[v,x]of f.entries())Rtt(y,x,v,a);y.append("text").text(d).attr("x",g/2).attr("y",m-p/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),Rtt=o((t,e,r,{rowHeight:n,paddingX:i,paddingY:a,bitWidth:s,bitsPerRow:l,showBits:u})=>{let h=t.append("g"),f=r*(n+a)+a;for(let d of e){let p=d.start%l*s+1,m=(d.end-d.start+1)*s-i;if(h.append("rect").attr("x",p).attr("y",f).attr("width",m).attr("height",n).attr("class","packetBlock"),h.append("text").attr("x",p+m/2).attr("y",f+n/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(d.label),!u)continue;let g=d.end===d.start,y=f-2;h.append("text").attr("x",p+(g?m/2:0)).attr("y",y).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",g?"middle":"start").text(d.start),g||h.append("text").attr("x",p+m).attr("y",y).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(d.end)}},"drawWord"),uve={draw:Ltt}});var Ntt,fve,dve=N(()=>{"use strict";er();Ntt={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},fve=o(({packet:t}={})=>{let e=$n(Ntt,t);return` + .packetByte { + font-size: ${e.byteFontSize}; + } + .packetByte.start { + fill: ${e.startByteColor}; + } + .packetByte.end { + fill: ${e.endByteColor}; + } + .packetLabel { + fill: ${e.labelColor}; + font-size: ${e.labelFontSize}; + } + .packetTitle { + fill: ${e.titleColor}; + font-size: ${e.titleFontSize}; + } + .packetBlock { + stroke: ${e.blockStrokeColor}; + stroke-width: ${e.blockStrokeWidth}; + fill: ${e.blockFillColor}; + } + `},"styles")});var pve={};ur(pve,{diagram:()=>Mtt});var Mtt,mve=N(()=>{"use strict";NF();cve();hve();dve();Mtt={parser:lve,db:qf,renderer:uve,styles:fve}});var vy,vve,a0,Ptt,Btt,xve,Ftt,$tt,ztt,Gtt,Vtt,Utt,Htt,s0,MF=N(()=>{"use strict";mi();_a();er();ci();vy={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},vve={axes:[],curves:[],options:vy},a0=structuredClone(vve),Ptt=or.radar,Btt=o(()=>$n({...Ptt,...tr().radar}),"getConfig"),xve=o(()=>a0.axes,"getAxes"),Ftt=o(()=>a0.curves,"getCurves"),$tt=o(()=>a0.options,"getOptions"),ztt=o(t=>{a0.axes=t.map(e=>({name:e.name,label:e.label??e.name}))},"setAxes"),Gtt=o(t=>{a0.curves=t.map(e=>({name:e.name,label:e.label??e.name,entries:Vtt(e.entries)}))},"setCurves"),Vtt=o(t=>{if(t[0].axis==null)return t.map(r=>r.value);let e=xve();if(e.length===0)throw new Error("Axes must be populated before curves for reference entries");return e.map(r=>{let n=t.find(i=>i.axis?.$refText===r.name);if(n===void 0)throw new Error("Missing entry for axis "+r.label);return n.value})},"computeCurveEntries"),Utt=o(t=>{let e=t.reduce((r,n)=>(r[n.name]=n,r),{});a0.options={showLegend:e.showLegend?.value??vy.showLegend,ticks:e.ticks?.value??vy.ticks,max:e.max?.value??vy.max,min:e.min?.value??vy.min,graticule:e.graticule?.value??vy.graticule}},"setOptions"),Htt=o(()=>{kr(),a0=structuredClone(vve)},"clear"),s0={getAxes:xve,getCurves:Ftt,getOptions:$tt,setAxes:ztt,setCurves:Gtt,setOptions:Utt,getConfig:Btt,clear:Htt,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var Wtt,bve,Tve=N(()=>{"use strict";bf();yt();Mp();MF();Wtt=o(t=>{Jo(t,s0);let{axes:e,curves:r,options:n}=t;s0.setAxes(e),s0.setCurves(r),s0.setOptions(n)},"populate"),bve={parse:o(async t=>{let e=await vs("radar",t);X.debug(e),Wtt(e)},"parse")}});function Ktt(t,e,r,n,i,a,s){let l=e.length,u=Math.min(s.width,s.height)/2;r.forEach((h,f)=>{if(h.entries.length!==l)return;let d=h.entries.map((p,m)=>{let g=2*Math.PI*m/l-Math.PI/2,y=Qtt(p,n,i,u),v=y*Math.cos(g),x=y*Math.sin(g);return{x:v,y:x}});a==="circle"?t.append("path").attr("d",Ztt(d,s.curveTension)).attr("class",`radarCurve-${f}`):a==="polygon"&&t.append("polygon").attr("points",d.map(p=>`${p.x},${p.y}`).join(" ")).attr("class",`radarCurve-${f}`)})}function Qtt(t,e,r,n){let i=Math.min(Math.max(t,e),r);return n*(i-e)/(r-e)}function Ztt(t,e){let r=t.length,n=`M${t[0].x},${t[0].y}`;for(let i=0;i{let h=t.append("g").attr("transform",`translate(${i}, ${a+u*s})`);h.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${u}`),h.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(l.label)})}var qtt,Ytt,Xtt,jtt,wve,kve=N(()=>{"use strict";Vl();qtt=o((t,e,r,n)=>{let i=n.db,a=i.getAxes(),s=i.getCurves(),l=i.getOptions(),u=i.getConfig(),h=i.getDiagramTitle(),f=Li(e),d=Ytt(f,u),p=l.max??Math.max(...s.map(y=>Math.max(...y.entries))),m=l.min,g=Math.min(u.width,u.height)/2;Xtt(d,a,g,l.ticks,l.graticule),jtt(d,a,g,u),Ktt(d,a,s,m,p,l.graticule,u),Jtt(d,s,l.showLegend,u),d.append("text").attr("class","radarTitle").text(h).attr("x",0).attr("y",-u.height/2-u.marginTop)},"draw"),Ytt=o((t,e)=>{let r=e.width+e.marginLeft+e.marginRight,n=e.height+e.marginTop+e.marginBottom,i={x:e.marginLeft+e.width/2,y:e.marginTop+e.height/2};return t.attr("viewbox",`0 0 ${r} ${n}`).attr("width",r).attr("height",n),t.append("g").attr("transform",`translate(${i.x}, ${i.y})`)},"drawFrame"),Xtt=o((t,e,r,n,i)=>{if(i==="circle")for(let a=0;a{let d=2*f*Math.PI/a-Math.PI/2,p=l*Math.cos(d),m=l*Math.sin(d);return`${p},${m}`}).join(" ");t.append("polygon").attr("points",u).attr("class","radarGraticule")}}},"drawGraticule"),jtt=o((t,e,r,n)=>{let i=e.length;for(let a=0;a{"use strict";er();By();mi();ert=o((t,e)=>{let r="";for(let n=0;n{let e=dh(),r=tr(),n=$n(e,r.themeVariables),i=$n(n.radar,t);return{themeVariables:n,radarOptions:i}},"buildRadarStyleOptions"),Eve=o(({radar:t}={})=>{let{themeVariables:e,radarOptions:r}=trt(t);return` + .radarTitle { + font-size: ${e.fontSize}; + color: ${e.titleColor}; + dominant-baseline: hanging; + text-anchor: middle; + } + .radarAxisLine { + stroke: ${r.axisColor}; + stroke-width: ${r.axisStrokeWidth}; + } + .radarAxisLabel { + dominant-baseline: middle; + text-anchor: middle; + font-size: ${r.axisLabelFontSize}px; + color: ${r.axisColor}; + } + .radarGraticule { + fill: ${r.graticuleColor}; + fill-opacity: ${r.graticuleOpacity}; + stroke: ${r.graticuleColor}; + stroke-width: ${r.graticuleStrokeWidth}; + } + .radarLegendText { + text-anchor: start; + font-size: ${r.legendFontSize}px; + dominant-baseline: hanging; + } + ${ert(e,r)} + `},"styles")});var Cve={};ur(Cve,{diagram:()=>rrt});var rrt,Ave=N(()=>{"use strict";MF();Tve();kve();Sve();rrt={parser:bve,db:s0,renderer:wve,styles:Eve}});var IF,Lve,Rve=N(()=>{"use strict";IF=function(){var t=o(function(T,S,w,E){for(w=w||{},E=T.length;E--;w[T[E]]=S);return w},"o"),e=[1,7],r=[1,13],n=[1,14],i=[1,15],a=[1,19],s=[1,16],l=[1,17],u=[1,18],h=[8,30],f=[8,21,28,29,30,31,32,40,44,47],d=[1,23],p=[1,24],m=[8,15,16,21,28,29,30,31,32,40,44,47],g=[8,15,16,21,27,28,29,30,31,32,40,44,47],y=[1,49],v={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:o(function(S,w,E,_,C,D,O){var R=D.length-1;switch(C){case 4:_.getLogger().debug("Rule: separator (NL) ");break;case 5:_.getLogger().debug("Rule: separator (Space) ");break;case 6:_.getLogger().debug("Rule: separator (EOF) ");break;case 7:_.getLogger().debug("Rule: hierarchy: ",D[R-1]),_.setHierarchy(D[R-1]);break;case 8:_.getLogger().debug("Stop NL ");break;case 9:_.getLogger().debug("Stop EOF ");break;case 10:_.getLogger().debug("Stop NL2 ");break;case 11:_.getLogger().debug("Stop EOF2 ");break;case 12:_.getLogger().debug("Rule: statement: ",D[R]),typeof D[R].length=="number"?this.$=D[R]:this.$=[D[R]];break;case 13:_.getLogger().debug("Rule: statement #2: ",D[R-1]),this.$=[D[R-1]].concat(D[R]);break;case 14:_.getLogger().debug("Rule: link: ",D[R],S),this.$={edgeTypeStr:D[R],label:""};break;case 15:_.getLogger().debug("Rule: LABEL link: ",D[R-3],D[R-1],D[R]),this.$={edgeTypeStr:D[R],label:D[R-1]};break;case 18:let k=parseInt(D[R]),L=_.generateId();this.$={id:L,type:"space",label:"",width:k,children:[]};break;case 23:_.getLogger().debug("Rule: (nodeStatement link node) ",D[R-2],D[R-1],D[R]," typestr: ",D[R-1].edgeTypeStr);let A=_.edgeStrToEdgeData(D[R-1].edgeTypeStr);this.$=[{id:D[R-2].id,label:D[R-2].label,type:D[R-2].type,directions:D[R-2].directions},{id:D[R-2].id+"-"+D[R].id,start:D[R-2].id,end:D[R].id,label:D[R-1].label,type:"edge",directions:D[R].directions,arrowTypeEnd:A,arrowTypeStart:"arrow_open"},{id:D[R].id,label:D[R].label,type:_.typeStr2Type(D[R].typeStr),directions:D[R].directions}];break;case 24:_.getLogger().debug("Rule: nodeStatement (abc88 node size) ",D[R-1],D[R]),this.$={id:D[R-1].id,label:D[R-1].label,type:_.typeStr2Type(D[R-1].typeStr),directions:D[R-1].directions,widthInColumns:parseInt(D[R],10)};break;case 25:_.getLogger().debug("Rule: nodeStatement (node) ",D[R]),this.$={id:D[R].id,label:D[R].label,type:_.typeStr2Type(D[R].typeStr),directions:D[R].directions,widthInColumns:1};break;case 26:_.getLogger().debug("APA123",this?this:"na"),_.getLogger().debug("COLUMNS: ",D[R]),this.$={type:"column-setting",columns:D[R]==="auto"?-1:parseInt(D[R])};break;case 27:_.getLogger().debug("Rule: id-block statement : ",D[R-2],D[R-1]);let I=_.generateId();this.$={...D[R-2],type:"composite",children:D[R-1]};break;case 28:_.getLogger().debug("Rule: blockStatement : ",D[R-2],D[R-1],D[R]);let M=_.generateId();this.$={id:M,type:"composite",label:"",children:D[R-1]};break;case 29:_.getLogger().debug("Rule: node (NODE_ID separator): ",D[R]),this.$={id:D[R]};break;case 30:_.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",D[R-1],D[R]),this.$={id:D[R-1],label:D[R].label,typeStr:D[R].typeStr,directions:D[R].directions};break;case 31:_.getLogger().debug("Rule: dirList: ",D[R]),this.$=[D[R]];break;case 32:_.getLogger().debug("Rule: dirList: ",D[R-1],D[R]),this.$=[D[R-1]].concat(D[R]);break;case 33:_.getLogger().debug("Rule: nodeShapeNLabel: ",D[R-2],D[R-1],D[R]),this.$={typeStr:D[R-2]+D[R],label:D[R-1]};break;case 34:_.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",D[R-3],D[R-2]," #3:",D[R-1],D[R]),this.$={typeStr:D[R-3]+D[R],label:D[R-2],directions:D[R-1]};break;case 35:case 36:this.$={type:"classDef",id:D[R-1].trim(),css:D[R].trim()};break;case 37:this.$={type:"applyClass",id:D[R-1].trim(),styleClass:D[R].trim()};break;case 38:this.$={type:"applyStyles",id:D[R-1].trim(),stylesStr:D[R].trim()};break}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{8:[1,20]},t(h,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:e,28:r,29:n,31:i,32:a,40:s,44:l,47:u}),t(f,[2,16],{14:22,15:d,16:p}),t(f,[2,17]),t(f,[2,18]),t(f,[2,19]),t(f,[2,20]),t(f,[2,21]),t(f,[2,22]),t(m,[2,25],{27:[1,25]}),t(f,[2,26]),{19:26,26:12,32:a},{11:27,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},t(g,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},t(h,[2,13]),{26:35,32:a},{32:[2,14]},{17:[1,36]},t(m,[2,24]),{11:37,13:4,14:22,15:d,16:p,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},t(g,[2,30]),{18:[1,43]},{18:[1,44]},t(m,[2,23]),{18:[1,45]},{30:[1,46]},t(f,[2,28]),t(f,[2,35]),t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),{37:[1,47]},{34:48,35:y},{15:[1,50]},t(f,[2,27]),t(g,[2,33]),{39:[1,51]},{34:52,35:y,39:[2,31]},{32:[2,15]},t(g,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:o(function(S,w){if(w.recoverable)this.trace(S);else{var E=new Error(S);throw E.hash=w,E}},"parseError"),parse:o(function(S){var w=this,E=[0],_=[],C=[null],D=[],O=this.table,R="",k=0,L=0,A=0,I=2,M=1,P=D.slice.call(arguments,1),B=Object.create(this.lexer),F={yy:{}};for(var z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,z)&&(F.yy[z]=this.yy[z]);B.setInput(S,F.yy),F.yy.lexer=B,F.yy.parser=this,typeof B.yylloc>"u"&&(B.yylloc={});var $=B.yylloc;D.push($);var U=B.options&&B.options.ranges;typeof F.yy.parseError=="function"?this.parseError=F.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function K(se){E.length=E.length-2*se,C.length=C.length-se,D.length=D.length-se}o(K,"popStack");function ee(){var se;return se=_.pop()||B.lex()||M,typeof se!="number"&&(se instanceof Array&&(_=se,se=_.pop()),se=w.symbols_[se]||se),se}o(ee,"lex");for(var Y,ce,Z,ue,Q,j,ne={},te,he,le,J;;){if(Z=E[E.length-1],this.defaultActions[Z]?ue=this.defaultActions[Z]:((Y===null||typeof Y>"u")&&(Y=ee()),ue=O[Z]&&O[Z][Y]),typeof ue>"u"||!ue.length||!ue[0]){var Se="";J=[];for(te in O[Z])this.terminals_[te]&&te>I&&J.push("'"+this.terminals_[te]+"'");B.showPosition?Se="Parse error on line "+(k+1)+`: +`+B.showPosition()+` +Expecting `+J.join(", ")+", got '"+(this.terminals_[Y]||Y)+"'":Se="Parse error on line "+(k+1)+": Unexpected "+(Y==M?"end of input":"'"+(this.terminals_[Y]||Y)+"'"),this.parseError(Se,{text:B.match,token:this.terminals_[Y]||Y,line:B.yylineno,loc:$,expected:J})}if(ue[0]instanceof Array&&ue.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Z+", token: "+Y);switch(ue[0]){case 1:E.push(Y),C.push(B.yytext),D.push(B.yylloc),E.push(ue[1]),Y=null,ce?(Y=ce,ce=null):(L=B.yyleng,R=B.yytext,k=B.yylineno,$=B.yylloc,A>0&&A--);break;case 2:if(he=this.productions_[ue[1]][1],ne.$=C[C.length-he],ne._$={first_line:D[D.length-(he||1)].first_line,last_line:D[D.length-1].last_line,first_column:D[D.length-(he||1)].first_column,last_column:D[D.length-1].last_column},U&&(ne._$.range=[D[D.length-(he||1)].range[0],D[D.length-1].range[1]]),j=this.performAction.apply(ne,[R,L,k,F.yy,ue[1],C,D].concat(P)),typeof j<"u")return j;he&&(E=E.slice(0,-1*he*2),C=C.slice(0,-1*he),D=D.slice(0,-1*he)),E.push(this.productions_[ue[1]][0]),C.push(ne.$),D.push(ne._$),le=O[E[E.length-2]][E[E.length-1]],E.push(le);break;case 3:return!0}}return!0},"parse")},x=function(){var T={EOF:1,parseError:o(function(w,E){if(this.yy.parser)this.yy.parser.parseError(w,E);else throw new Error(w)},"parseError"),setInput:o(function(S,w){return this.yy=w||this.yy||{},this._input=S,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var S=this._input[0];this.yytext+=S,this.yyleng++,this.offset++,this.match+=S,this.matched+=S;var w=S.match(/(?:\r\n?|\n).*/g);return w?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),S},"input"),unput:o(function(S){var w=S.length,E=S.split(/(?:\r\n?|\n)/g);this._input=S+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-w),this.offset-=w;var _=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),E.length-1&&(this.yylineno-=E.length-1);var C=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:E?(E.length===_.length?this.yylloc.first_column:0)+_[_.length-E.length].length-E[0].length:this.yylloc.first_column-w},this.options.ranges&&(this.yylloc.range=[C[0],C[0]+this.yyleng-w]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). +`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(S){this.unput(this.match.slice(S))},"less"),pastInput:o(function(){var S=this.matched.substr(0,this.matched.length-this.match.length);return(S.length>20?"...":"")+S.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var S=this.match;return S.length<20&&(S+=this._input.substr(0,20-S.length)),(S.substr(0,20)+(S.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var S=this.pastInput(),w=new Array(S.length+1).join("-");return S+this.upcomingInput()+` +`+w+"^"},"showPosition"),test_match:o(function(S,w){var E,_,C;if(this.options.backtrack_lexer&&(C={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(C.yylloc.range=this.yylloc.range.slice(0))),_=S[0].match(/(?:\r\n?|\n).*/g),_&&(this.yylineno+=_.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:_?_[_.length-1].length-_[_.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+S[0].length},this.yytext+=S[0],this.match+=S[0],this.matches=S,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(S[0].length),this.matched+=S[0],E=this.performAction.call(this,this.yy,this,w,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),E)return E;if(this._backtrack){for(var D in C)this[D]=C[D];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var S,w,E,_;this._more||(this.yytext="",this.match="");for(var C=this._currentRules(),D=0;Dw[0].length)){if(w=E,_=D,this.options.backtrack_lexer){if(S=this.test_match(E,C[D]),S!==!1)return S;if(this._backtrack){w=!1;continue}else return!1}else if(!this.options.flex)break}return w?(S=this.test_match(w,C[_]),S!==!1?S:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var w=this.next();return w||this.lex()},"lex"),begin:o(function(w){this.conditionStack.push(w)},"begin"),popState:o(function(){var w=this.conditionStack.length-1;return w>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(w){return w=this.conditionStack.length-1-Math.abs(w||0),w>=0?this.conditionStack[w]:"INITIAL"},"topState"),pushState:o(function(w){this.begin(w)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(w,E,_,C){var D=C;switch(_){case 0:return 10;case 1:return w.getLogger().debug("Found space-block"),31;break;case 2:return w.getLogger().debug("Found nl-block"),31;break;case 3:return w.getLogger().debug("Found space-block"),29;break;case 4:w.getLogger().debug(".",E.yytext);break;case 5:w.getLogger().debug("_",E.yytext);break;case 6:return 5;case 7:return E.yytext=-1,28;break;case 8:return E.yytext=E.yytext.replace(/columns\s+/,""),w.getLogger().debug("COLUMNS (LEX)",E.yytext),28;break;case 9:this.pushState("md_string");break;case 10:return"MD_STR";case 11:this.popState();break;case 12:this.pushState("string");break;case 13:w.getLogger().debug("LEX: POPPING STR:",E.yytext),this.popState();break;case 14:return w.getLogger().debug("LEX: STR end:",E.yytext),"STR";break;case 15:return E.yytext=E.yytext.replace(/space\:/,""),w.getLogger().debug("SPACE NUM (LEX)",E.yytext),21;break;case 16:return E.yytext="1",w.getLogger().debug("COLUMNS (LEX)",E.yytext),21;break;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;break;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 22:return this.popState(),this.pushState("CLASSDEFID"),41;break;case 23:return this.popState(),42;break;case 24:return this.pushState("CLASS"),44;break;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;break;case 26:return this.popState(),46;break;case 27:return this.pushState("STYLE_STMNT"),47;break;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;break;case 29:return this.popState(),49;break;case 30:return this.pushState("acc_title"),"acc_title";break;case 31:return this.popState(),"acc_title_value";break;case 32:return this.pushState("acc_descr"),"acc_descr";break;case 33:return this.popState(),"acc_descr_value";break;case 34:this.pushState("acc_descr_multiline");break;case 35:this.popState();break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 39:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 40:return this.popState(),w.getLogger().debug("Lex: ))"),"NODE_DEND";break;case 41:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 42:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 43:return this.popState(),w.getLogger().debug("Lex: (-"),"NODE_DEND";break;case 44:return this.popState(),w.getLogger().debug("Lex: -)"),"NODE_DEND";break;case 45:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 46:return this.popState(),w.getLogger().debug("Lex: ]]"),"NODE_DEND";break;case 47:return this.popState(),w.getLogger().debug("Lex: ("),"NODE_DEND";break;case 48:return this.popState(),w.getLogger().debug("Lex: ])"),"NODE_DEND";break;case 49:return this.popState(),w.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 50:return this.popState(),w.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 51:return this.popState(),w.getLogger().debug("Lex: )]"),"NODE_DEND";break;case 52:return this.popState(),w.getLogger().debug("Lex: )"),"NODE_DEND";break;case 53:return this.popState(),w.getLogger().debug("Lex: ]>"),"NODE_DEND";break;case 54:return this.popState(),w.getLogger().debug("Lex: ]"),"NODE_DEND";break;case 55:return w.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;break;case 56:return w.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;break;case 57:return w.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;break;case 58:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 59:return w.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;break;case 60:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 61:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 62:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 63:return w.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;break;case 64:return w.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;break;case 65:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 66:return this.pushState("NODE"),36;break;case 67:return this.pushState("NODE"),36;break;case 68:return this.pushState("NODE"),36;break;case 69:return this.pushState("NODE"),36;break;case 70:return this.pushState("NODE"),36;break;case 71:return this.pushState("NODE"),36;break;case 72:return this.pushState("NODE"),36;break;case 73:return w.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;break;case 74:return this.pushState("BLOCK_ARROW"),w.getLogger().debug("LEX ARR START"),38;break;case 75:return w.getLogger().debug("Lex: NODE_ID",E.yytext),32;break;case 76:return w.getLogger().debug("Lex: EOF",E.yytext),8;break;case 77:this.pushState("md_string");break;case 78:this.pushState("md_string");break;case 79:return"NODE_DESCR";case 80:this.popState();break;case 81:w.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:w.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return w.getLogger().debug("LEX: NODE_DESCR:",E.yytext),"NODE_DESCR";break;case 84:w.getLogger().debug("LEX POPPING"),this.popState();break;case 85:w.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (right): dir:",E.yytext),"DIR";break;case 87:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (left):",E.yytext),"DIR";break;case 88:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (x):",E.yytext),"DIR";break;case 89:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (y):",E.yytext),"DIR";break;case 90:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (up):",E.yytext),"DIR";break;case 91:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (down):",E.yytext),"DIR";break;case 92:return E.yytext="]>",w.getLogger().debug("Lex (ARROW_DIR end):",E.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";break;case 93:return w.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 94:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 95:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 96:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 97:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 98:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 99:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 100:this.pushState("md_string");break;case 101:return w.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";break;case 102:return this.popState(),w.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 103:return this.popState(),w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 104:return this.popState(),w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 105:return w.getLogger().debug("Lex: COLON",E.yytext),E.yytext=E.yytext.slice(1),27;break}},"anonymous"),rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}};return T}();v.lexer=x;function b(){this.yy={}}return o(b,"Parser"),b.prototype=v,v.Parser=b,new b}();IF.parser=IF;Lve=IF});function frt(t){switch(X.debug("typeStr2Type",t),t){case"[]":return"square";case"()":return X.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}}function drt(t){switch(X.debug("typeStr2Type",t),t){case"==":return"thick";default:return"normal"}}function prt(t){switch(t.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}}var Yl,PF,OF,Nve,Mve,art,Ove,srt,bC,ort,lrt,crt,urt,Pve,BF,_4,hrt,Ive,mrt,grt,yrt,vrt,xrt,brt,Trt,wrt,krt,Ert,Srt,Bve,Fve=N(()=>{"use strict";JL();mi();Gt();yt();pr();ci();Yl=new Map,PF=[],OF=new Map,Nve="color",Mve="fill",art="bgFill",Ove=",",srt=me(),bC=new Map,ort=o(t=>Ze.sanitizeText(t,srt),"sanitizeText"),lrt=o(function(t,e=""){let r=bC.get(t);r||(r={id:t,styles:[],textStyles:[]},bC.set(t,r)),e?.split(Ove).forEach(n=>{let i=n.replace(/([^;]*);/,"$1").trim();if(RegExp(Nve).exec(n)){let s=i.replace(Mve,art).replace(Nve,Mve);r.textStyles.push(s)}r.styles.push(i)})},"addStyleClass"),crt=o(function(t,e=""){let r=Yl.get(t);e!=null&&(r.styles=e.split(Ove))},"addStyle2Node"),urt=o(function(t,e){t.split(",").forEach(function(r){let n=Yl.get(r);if(n===void 0){let i=r.trim();n={id:i,type:"na",children:[]},Yl.set(i,n)}n.classes||(n.classes=[]),n.classes.push(e)})},"setCssClass"),Pve=o((t,e)=>{let r=t.flat(),n=[];for(let i of r){if(i.label&&(i.label=ort(i.label)),i.type==="classDef"){lrt(i.id,i.css);continue}if(i.type==="applyClass"){urt(i.id,i?.styleClass??"");continue}if(i.type==="applyStyles"){i?.stylesStr&&crt(i.id,i?.stylesStr);continue}if(i.type==="column-setting")e.columns=i.columns??-1;else if(i.type==="edge"){let a=(OF.get(i.id)??0)+1;OF.set(i.id,a),i.id=a+"-"+i.id,PF.push(i)}else{i.label||(i.type==="composite"?i.label="":i.label=i.id);let a=Yl.get(i.id);if(a===void 0?Yl.set(i.id,i):(i.type!=="na"&&(a.type=i.type),i.label!==i.id&&(a.label=i.label)),i.children&&Pve(i.children,i),i.type==="space"){let s=i.width??1;for(let l=0;l{X.debug("Clear called"),kr(),_4={id:"root",type:"composite",children:[],columns:-1},Yl=new Map([["root",_4]]),BF=[],bC=new Map,PF=[],OF=new Map},"clear");o(frt,"typeStr2Type");o(drt,"edgeTypeStr2Type");o(prt,"edgeStrToEdgeData");Ive=0,mrt=o(()=>(Ive++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Ive),"generateId"),grt=o(t=>{_4.children=t,Pve(t,_4),BF=_4.children},"setHierarchy"),yrt=o(t=>{let e=Yl.get(t);return e?e.columns?e.columns:e.children?e.children.length:-1:-1},"getColumns"),vrt=o(()=>[...Yl.values()],"getBlocksFlat"),xrt=o(()=>BF||[],"getBlocks"),brt=o(()=>PF,"getEdges"),Trt=o(t=>Yl.get(t),"getBlock"),wrt=o(t=>{Yl.set(t.id,t)},"setBlock"),krt=o(()=>X,"getLogger"),Ert=o(function(){return bC},"getClasses"),Srt={getConfig:o(()=>tr().block,"getConfig"),typeStr2Type:frt,edgeTypeStr2Type:drt,edgeStrToEdgeData:prt,getLogger:krt,getBlocksFlat:vrt,getBlocks:xrt,getEdges:brt,setHierarchy:grt,getBlock:Trt,setBlock:wrt,getColumns:yrt,getClasses:Ert,clear:hrt,generateId:mrt},Bve=Srt});var TC,Crt,$ve,zve=N(()=>{"use strict";Ks();Xm();TC=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),Crt=o(t=>`.label { + font-family: ${t.fontFamily}; + color: ${t.nodeTextColor||t.textColor}; + } + .cluster-label text { + fill: ${t.titleColor}; + } + .cluster-label span,p { + color: ${t.titleColor}; + } + + + + .label text,span,p { + fill: ${t.nodeTextColor||t.textColor}; + color: ${t.nodeTextColor||t.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${t.mainBkg}; + stroke: ${t.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${t.arrowheadColor}; + } + + .edgePath .path { + stroke: ${t.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${t.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${t.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${t.edgeLabelBackground}; + fill: ${t.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${TC(t.edgeLabelBackground,.5)}; + // background-color: + } + + .node .cluster { + // fill: ${TC(t.mainBkg,.5)}; + fill: ${TC(t.clusterBkg,.5)}; + stroke: ${TC(t.clusterBorder,.2)}; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + stroke-width: 1px; + } + + .cluster text { + fill: ${t.titleColor}; + } + + .cluster span,p { + color: ${t.titleColor}; + } + /* .cluster div { + color: ${t.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${t.fontFamily}; + font-size: 12px; + background: ${t.tertiaryColor}; + border: 1px solid ${t.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${t.textColor}; + } + ${Nc()} +`,"getStyles"),$ve=Crt});var Art,_rt,Drt,Lrt,Rrt,Nrt,Mrt,Irt,Ort,Prt,Brt,Gve,Vve=N(()=>{"use strict";yt();Art=o((t,e,r,n)=>{e.forEach(i=>{Brt[i](t,r,n)})},"insertMarkers"),_rt=o((t,e,r)=>{X.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),Drt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),Lrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),Rrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),Nrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),Mrt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),Irt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),Ort=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),Prt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),Brt={extension:_rt,composition:Drt,aggregation:Lrt,dependency:Rrt,lollipop:Nrt,point:Mrt,circle:Irt,cross:Ort,barb:Prt},Gve=Art});function Frt(t,e){if(t===0||!Number.isInteger(t))throw new Error("Columns must be an integer !== 0.");if(e<0||!Number.isInteger(e))throw new Error("Position must be a non-negative integer."+e);if(t<0)return{px:e,py:0};if(t===1)return{px:0,py:e};let r=e%t,n=Math.floor(e/t);return{px:r,py:n}}function FF(t,e,r=0,n=0){X.debug("setBlockSizes abc95 (start)",t.id,t?.size?.x,"block width =",t?.size,"siblingWidth",r),t?.size?.width||(t.size={width:r,height:n,x:0,y:0});let i=0,a=0;if(t.children?.length>0){for(let m of t.children)FF(m,e);let s=$rt(t);i=s.width,a=s.height,X.debug("setBlockSizes abc95 maxWidth of",t.id,":s children is ",i,a);for(let m of t.children)m.size&&(X.debug(`abc95 Setting size of children of ${t.id} id=${m.id} ${i} ${a} ${JSON.stringify(m.size)}`),m.size.width=i*(m.widthInColumns??1)+ki*((m.widthInColumns??1)-1),m.size.height=a,m.size.x=0,m.size.y=0,X.debug(`abc95 updating size of ${t.id} children child:${m.id} maxWidth:${i} maxHeight:${a}`));for(let m of t.children)FF(m,e,i,a);let l=t.columns??-1,u=0;for(let m of t.children)u+=m.widthInColumns??1;let h=t.children.length;l>0&&l0?Math.min(t.children.length,l):t.children.length;if(m>0){let g=(d-m*ki-ki)/m;X.debug("abc95 (growing to fit) width",t.id,d,t.size?.width,g);for(let y of t.children)y.size&&(y.size.width=g)}}t.size={width:d,height:p,x:0,y:0}}X.debug("setBlockSizes abc94 (done)",t.id,t?.size?.x,t?.size?.width,t?.size?.y,t?.size?.height)}function Uve(t,e){X.debug(`abc85 layout blocks (=>layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`);let r=t.columns??-1;if(X.debug("layoutBlocks columns abc95",t.id,"=>",r,t),t.children&&t.children.length>0){let n=t?.children[0]?.size?.width??0,i=t.children.length*n+(t.children.length-1)*ki;X.debug("widthOfChildren 88",i,"posX");let a=0;X.debug("abc91 block?.size?.x",t.id,t?.size?.x);let s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-ki,l=0;for(let u of t.children){let h=t;if(!u.size)continue;let{width:f,height:d}=u.size,{px:p,py:m}=Frt(r,a);if(m!=l&&(l=m,s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-ki,X.debug("New row in layout for block",t.id," and child ",u.id,l)),X.debug(`abc89 layout blocks (child) id: ${u.id} Pos: ${a} (px, py) ${p},${m} (${h?.size?.x},${h?.size?.y}) parent: ${h.id} width: ${f}${ki}`),h.size){let g=f/2;u.size.x=s+ki+g,X.debug(`abc91 layout blocks (calc) px, pyid:${u.id} startingPos=X${s} new startingPosX${u.size.x} ${g} padding=${ki} width=${f} halfWidth=${g} => x:${u.size.x} y:${u.size.y} ${u.widthInColumns} (width * (child?.w || 1)) / 2 ${f*(u?.widthInColumns??1)/2}`),s=u.size.x+g,u.size.y=h.size.y-h.size.height/2+m*(d+ki)+d/2+ki,X.debug(`abc88 layout blocks (calc) px, pyid:${u.id}startingPosX${s}${ki}${g}=>x:${u.size.x}y:${u.size.y}${u.widthInColumns}(width * (child?.w || 1)) / 2${f*(u?.widthInColumns??1)/2}`)}u.children&&Uve(u,e),a+=u?.widthInColumns??1,X.debug("abc88 columnsPos",u,a)}}X.debug(`layout blocks (<==layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`)}function Hve(t,{minX:e,minY:r,maxX:n,maxY:i}={minX:0,minY:0,maxX:0,maxY:0}){if(t.size&&t.id!=="root"){let{x:a,y:s,width:l,height:u}=t.size;a-l/2n&&(n=a+l/2),s+u/2>i&&(i=s+u/2)}if(t.children)for(let a of t.children)({minX:e,minY:r,maxX:n,maxY:i}=Hve(a,{minX:e,minY:r,maxX:n,maxY:i}));return{minX:e,minY:r,maxX:n,maxY:i}}function Wve(t){let e=t.getBlock("root");if(!e)return;FF(e,t,0,0),Uve(e,t),X.debug("getBlocks",JSON.stringify(e,null,2));let{minX:r,minY:n,maxX:i,maxY:a}=Hve(e),s=a-n,l=i-r;return{x:r,y:n,width:l,height:s}}var ki,$rt,qve=N(()=>{"use strict";yt();Gt();ki=me()?.block?.padding??8;o(Frt,"calculateBlockPosition");$rt=o(t=>{let e=0,r=0;for(let n of t.children){let{width:i,height:a,x:s,y:l}=n.size??{width:0,height:0,x:0,y:0};X.debug("getMaxChildSize abc95 child:",n.id,"width:",i,"height:",a,"x:",s,"y:",l,n.type),n.type!=="space"&&(i>e&&(e=i/(t.widthInColumns??1)),a>r&&(r=a))}return{width:e,height:r}},"getMaxChildSize");o(FF,"setBlockSizes");o(Uve,"layoutBlocks");o(Hve,"findBounds");o(Wve,"layout")});function Yve(t,e){e&&t.attr("style",e)}function zrt(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label,i=t.isNode?"nodeLabel":"edgeLabel",a=r.append("span");return a.html(n),Yve(a,t.labelStyle),a.attr("class",i),Yve(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var Grt,ks,wC=N(()=>{"use strict";fr();yt();Gt();pr();er();ao();o(Yve,"applyStyle");o(zrt,"addHtmlLabel");Grt=o(async(t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),dr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"
    "),X.debug("vertexText"+i);let a=await dL(na(i)),s={isNode:n,label:a,labelStyle:e.replace("fill:","color:")};return zrt(s)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),ks=Grt});var jve,Vrt,Xve,Kve=N(()=>{"use strict";yt();jve=o((t,e,r,n,i)=>{e.arrowTypeStart&&Xve(t,"start",e.arrowTypeStart,r,n,i),e.arrowTypeEnd&&Xve(t,"end",e.arrowTypeEnd,r,n,i)},"addEdgeMarkers"),Vrt={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},Xve=o((t,e,r,n,i,a)=>{let s=Vrt[r];if(!s){X.warn(`Unknown arrow type: ${r}`);return}let l=e==="start"?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${a}-${s}${l})`)},"addEdgeMarker")});function kC(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}var $F,Xa,Zve,Jve,Urt,Hrt,Qve,e2e,t2e=N(()=>{"use strict";yt();wC();ao();fr();Gt();er();pr();PL();R2();Kve();$F={},Xa={},Zve=o(async(t,e)=>{let r=me(),n=dr(r.flowchart.htmlLabels),i=e.labelType==="markdown"?qn(t,e.label,{style:e.labelStyle,useHtmlLabels:n,addSvgBackground:!0},r):await ks(e.label,e.labelStyle),a=t.insert("g").attr("class","edgeLabel"),s=a.insert("g").attr("class","label");s.node().appendChild(i);let l=i.getBBox();if(n){let h=i.children[0],f=Ge(i);l=h.getBoundingClientRect(),f.attr("width",l.width),f.attr("height",l.height)}s.attr("transform","translate("+-l.width/2+", "+-l.height/2+")"),$F[e.id]=a,e.width=l.width,e.height=l.height;let u;if(e.startLabelLeft){let h=await ks(e.startLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].startLeft=f,kC(u,e.startLabelLeft)}if(e.startLabelRight){let h=await ks(e.startLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=f.node().appendChild(h),d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].startRight=f,kC(u,e.startLabelRight)}if(e.endLabelLeft){let h=await ks(e.endLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].endLeft=f,kC(u,e.endLabelLeft)}if(e.endLabelRight){let h=await ks(e.endLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].endRight=f,kC(u,e.endLabelRight)}return i},"insertEdgeLabel");o(kC,"setTerminalWidth");Jve=o((t,e)=>{X.debug("Moving label abc88 ",t.id,t.label,$F[t.id],e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Bu(n);if(t.label){let a=$F[t.id],s=t.x,l=t.y;if(r){let u=Vt.calcLabelPosition(r);X.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=Xa[t.id].startLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=Xa[t.id].startRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=Xa[t.id].endLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=Xa[t.id].endRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),Urt=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),Hrt=o((t,e,r)=>{X.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(e)} + insidePoint : ${JSON.stringify(r)} + node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.xMath.abs(n-e.x)*u){let d=r.y{X.debug("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(!Urt(e,a)&&!i){let s=Hrt(e,n,a),l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)||r.push(s),i=!0}else n=a,i||r.push(a)}),r},"cutPathAtIntersect"),e2e=o(function(t,e,r,n,i,a,s){let l=r.points;X.debug("abc88 InsertEdge: edge=",r,"e=",e);let u=!1,h=a.node(e.v);var f=a.node(e.w);f?.intersect&&h?.intersect&&(l=l.slice(1,r.points.length-1),l.unshift(h.intersect(l[0])),l.push(f.intersect(l[l.length-1]))),r.toCluster&&(X.debug("to cluster abc88",n[r.toCluster]),l=Qve(r.points,n[r.toCluster].node),u=!0),r.fromCluster&&(X.debug("from cluster abc88",n[r.fromCluster]),l=Qve(l.reverse(),n[r.fromCluster].node).reverse(),u=!0);let d=l.filter(S=>!Number.isNaN(S.y)),p=No;r.curve&&(i==="graph"||i==="flowchart")&&(p=r.curve);let{x:m,y:g}=ow(r),y=Cl().x(m).y(g).curve(p),v;switch(r.thickness){case"normal":v="edge-thickness-normal";break;case"thick":v="edge-thickness-thick";break;case"invisible":v="edge-thickness-thick";break;default:v=""}switch(r.pattern){case"solid":v+=" edge-pattern-solid";break;case"dotted":v+=" edge-pattern-dotted";break;case"dashed":v+=" edge-pattern-dashed";break}let x=t.append("path").attr("d",y(d)).attr("id",r.id).attr("class"," "+v+(r.classes?" "+r.classes:"")).attr("style",r.style),b="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(b=mu(!0)),jve(x,r,b,s,i);let T={};return u&&(T.updatedPath=l),T.originalPath=r.points,T},"insertEdge")});var Wrt,r2e,n2e=N(()=>{"use strict";Wrt=o(t=>{let e=new Set;for(let r of t)switch(r){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(r);break}return e},"expandAndDeduplicateDirections"),r2e=o((t,e,r)=>{let n=Wrt(t),i=2,a=e.height+2*r.padding,s=a/i,l=e.width+2*s+r.padding,u=r.padding/2;return n.has("right")&&n.has("left")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:s,y:0},{x:l/2,y:2*u},{x:l-s,y:0},{x:l,y:0},{x:l,y:-a/3},{x:l+2*u,y:-a/2},{x:l,y:-2*a/3},{x:l,y:-a},{x:l-s,y:-a},{x:l/2,y:-a-2*u},{x:s,y:-a},{x:0,y:-a},{x:0,y:-2*a/3},{x:-2*u,y:-a/2},{x:0,y:-a/3}]:n.has("right")&&n.has("left")&&n.has("up")?[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}]:n.has("right")&&n.has("left")&&n.has("down")?[{x:0,y:0},{x:s,y:-a},{x:l-s,y:-a},{x:l,y:0}]:n.has("right")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:l,y:-s},{x:l,y:-a+s},{x:0,y:-a}]:n.has("left")&&n.has("up")&&n.has("down")?[{x:l,y:0},{x:0,y:-s},{x:0,y:-a+s},{x:l,y:-a}]:n.has("right")&&n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")&&n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:n.has("right")&&n.has("up")?[{x:0,y:0},{x:l,y:-s},{x:0,y:-a}]:n.has("right")&&n.has("down")?[{x:0,y:0},{x:l,y:0},{x:0,y:-a}]:n.has("left")&&n.has("up")?[{x:l,y:0},{x:0,y:-s},{x:l,y:-a}]:n.has("left")&&n.has("down")?[{x:l,y:0},{x:0,y:0},{x:l,y:-a}]:n.has("right")?[{x:s,y:-u},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a+u}]:n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")?[{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u}]:n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:[{x:0,y:0}]},"getArrowPoints")});function qrt(t,e){return t.intersect(e)}var i2e,a2e=N(()=>{"use strict";o(qrt,"intersectNode");i2e=qrt});function Yrt(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x{"use strict";o(Yrt,"intersectEllipse");EC=Yrt});function Xrt(t,e,r){return EC(t,e,e,r)}var s2e,o2e=N(()=>{"use strict";zF();o(Xrt,"intersectCircle");s2e=Xrt});function jrt(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&l2e(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&l2e(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function l2e(t,e){return t*e>0}var c2e,u2e=N(()=>{"use strict";o(jrt,"intersectLine");o(l2e,"sameSign");c2e=jrt});function Krt(t,e,r){var n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(g){s=Math.min(s,g.x),l=Math.min(l,g.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var u=n-t.width/2-s,h=i-t.height/2-l,f=0;f1&&a.sort(function(g,y){var v=g.x-r.x,x=g.y-r.y,b=Math.sqrt(v*v+x*x),T=y.x-r.x,S=y.y-r.y,w=Math.sqrt(T*T+S*S);return b{"use strict";u2e();h2e=Krt;o(Krt,"intersectPolygon")});var Qrt,d2e,p2e=N(()=>{"use strict";Qrt=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),d2e=Qrt});var In,GF=N(()=>{"use strict";a2e();o2e();zF();f2e();p2e();In={node:i2e,circle:s2e,ellipse:EC,polygon:h2e,rect:d2e}});function Xl(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var Ni,Jn,VF=N(()=>{"use strict";wC();ao();Gt();fr();pr();er();Ni=o(async(t,e,r,n)=>{let i=me(),a,s=e.useHtmlLabels||dr(i.flowchart.htmlLabels);r?a=r:a="node default";let l=t.insert("g").attr("class",a).attr("id",e.domId||e.id),u=l.insert("g").attr("class","label").attr("style",e.labelStyle),h;e.labelText===void 0?h="":h=typeof e.labelText=="string"?e.labelText:e.labelText[0];let f=u.node(),d;e.labelType==="markdown"?d=qn(u,wr(na(h),i),{useHtmlLabels:s,width:e.width||i.flowchart.wrappingWidth,classes:"markdown-node-label"},i):d=f.appendChild(await ks(wr(na(h),i),e.labelStyle,!1,n));let p=d.getBBox(),m=e.padding/2;if(dr(i.flowchart.htmlLabels)){let g=d.children[0],y=Ge(d),v=g.getElementsByTagName("img");if(v){let x=h.replace(/]*>/g,"").trim()==="";await Promise.all([...v].map(b=>new Promise(T=>{function S(){if(b.style.display="flex",b.style.flexDirection="column",x){let w=i.fontSize?i.fontSize:window.getComputedStyle(document.body).fontSize,_=parseInt(w,10)*5+"px";b.style.minWidth=_,b.style.maxWidth=_}else b.style.width="100%";T(b)}o(S,"setupImage"),setTimeout(()=>{b.complete&&S()}),b.addEventListener("error",S),b.addEventListener("load",S)})))}p=g.getBoundingClientRect(),y.attr("width",p.width),y.attr("height",p.height)}return s?u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"):u.attr("transform","translate(0, "+-p.height/2+")"),e.centerLabel&&u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),u.insert("rect",":first-child"),{shapeSvg:l,bbox:p,halfPadding:m,label:u}},"labelHelper"),Jn=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds");o(Xl,"insertPolygonShape")});var Zrt,m2e,g2e=N(()=>{"use strict";VF();yt();Gt();GF();Zrt=o(async(t,e)=>{e.useHtmlLabels||me().flowchart.htmlLabels||(e.centerLabel=!0);let{shapeSvg:n,bbox:i,halfPadding:a}=await Ni(t,e,"node "+e.classes,!0);X.info("Classes = ",e.classes);let s=n.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-a).attr("y",-i.height/2-a).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Jn(e,s),e.intersect=function(l){return In.rect(e,l)},n},"note"),m2e=Zrt});function UF(t,e,r,n){let i=[],a=o(l=>{i.push(l,0)},"addBorder"),s=o(l=>{i.push(0,l)},"skipBorder");e.includes("t")?(X.debug("add top border"),a(r)):s(r),e.includes("r")?(X.debug("add right border"),a(n)):s(n),e.includes("b")?(X.debug("add bottom border"),a(r)):s(r),e.includes("l")?(X.debug("add left border"),a(n)):s(n),t.attr("stroke-dasharray",i.join(" "))}var y2e,bo,v2e,Jrt,ent,tnt,rnt,nnt,int,ant,snt,ont,lnt,cnt,unt,hnt,fnt,dnt,pnt,mnt,gnt,ynt,x2e,vnt,xnt,b2e,SC,HF,T2e,w2e=N(()=>{"use strict";fr();Gt();pr();yt();n2e();wC();GF();g2e();VF();y2e=o(t=>t?" "+t:"","formatClass"),bo=o((t,e)=>`${e||"node default"}${y2e(t.classes)} ${y2e(t.class)}`,"getClassesFromNode"),v2e=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=i+a,l=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];X.info("Question main (Circle)");let u=Xl(r,s,s,l);return u.attr("style",e.style),Jn(e,u),e.intersect=function(h){return X.warn("Intersect called"),In.polygon(e,l,h)},r},"question"),Jrt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=28,i=[{x:0,y:n/2},{x:n/2,y:0},{x:0,y:-n/2},{x:-n/2,y:0}];return r.insert("polygon",":first-child").attr("points",i.map(function(s){return s.x+","+s.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(s){return In.circle(e,14,s)},r},"choice"),ent=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=4,a=n.height+e.padding,s=a/i,l=n.width+2*s+e.padding,u=[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}],h=Xl(r,l,a,u);return h.attr("style",e.style),Jn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"hexagon"),tnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,void 0,!0),i=2,a=n.height+2*e.padding,s=a/i,l=n.width+2*s+e.padding,u=r2e(e.directions,n,e),h=Xl(r,l,a,u);return h.attr("style",e.style),Jn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"block_arrow"),rnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-a/2,y:0},{x:i,y:0},{x:i,y:-a},{x:-a/2,y:-a},{x:0,y:-a/2}];return Xl(r,i,a,s).attr("style",e.style),e.width=i+a,e.height=a,e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_left_inv_arrow"),nnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_right"),int=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:2*a/6,y:0},{x:i+a/6,y:0},{x:i-2*a/6,y:-a},{x:-a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_left"),ant=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i+2*a/6,y:0},{x:i-a/6,y:-a},{x:a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"trapezoid"),snt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:-2*a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"inv_trapezoid"),ont=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i+a/2,y:0},{x:i,y:-a/2},{x:i+a/2,y:-a},{x:0,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_right_inv_arrow"),lnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=i/2,s=a/(2.5+i/50),l=n.height+s+e.padding,u="M 0,"+s+" a "+a+","+s+" 0,0,0 "+i+" 0 a "+a+","+s+" 0,0,0 "+-i+" 0 l 0,"+l+" a "+a+","+s+" 0,0,0 "+i+" 0 l 0,"+-l,h=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",u).attr("transform","translate("+-i/2+","+-(l/2+s)+")");return Jn(e,h),e.intersect=function(f){let d=In.rect(e,f),p=d.x-e.x;if(a!=0&&(Math.abs(p)e.height/2-s)){let m=s*s*(1-p*p/(a*a));m!=0&&(m=Math.sqrt(m)),m=s-m,f.y-e.y>0&&(m=-m),d.y+=m}return d},r},"cylinder"),cnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,"node "+e.classes+" "+e.class,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(UF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{X.warn(`Unknown node property ${d}`)})}return Jn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"rect"),unt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,"node "+e.classes,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(UF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{X.warn(`Unknown node property ${d}`)})}return Jn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"composite"),hnt=o(async(t,e)=>{let{shapeSvg:r}=await Ni(t,e,"label",!0);X.trace("Classes = ",e.class);let n=r.insert("rect",":first-child"),i=0,a=0;if(n.attr("width",i).attr("height",a),r.attr("class","label edgeLabel"),e.props){let s=new Set(Object.keys(e.props));e.props.borders&&(UF(n,e.props.borders,i,a),s.delete("borders")),s.forEach(l=>{X.warn(`Unknown node property ${l}`)})}return Jn(e,n),e.intersect=function(s){return In.rect(e,s)},r},"labelRect");o(UF,"applyNodePropertyBorders");fnt=o(async(t,e)=>{let r;e.classes?r="node "+e.classes:r="node default";let n=t.insert("g").attr("class",r).attr("id",e.domId||e.id),i=n.insert("rect",":first-child"),a=n.insert("line"),s=n.insert("g").attr("class","label"),l=e.labelText.flat?e.labelText.flat():e.labelText,u="";typeof l=="object"?u=l[0]:u=l,X.info("Label text abc79",u,l,typeof l=="object");let h=s.node().appendChild(await ks(u,e.labelStyle,!0,!0)),f={width:0,height:0};if(dr(me().flowchart.htmlLabels)){let y=h.children[0],v=Ge(h);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}X.info("Text 2",l);let d=l.slice(1,l.length),p=h.getBBox(),m=s.node().appendChild(await ks(d.join?d.join("
    "):d,e.labelStyle,!0,!0));if(dr(me().flowchart.htmlLabels)){let y=m.children[0],v=Ge(m);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}let g=e.padding/2;return Ge(m).attr("transform","translate( "+(f.width>p.width?0:(p.width-f.width)/2)+", "+(p.height+g+5)+")"),Ge(h).attr("transform","translate( "+(f.width{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.height+e.padding,a=n.width+i/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",i/2).attr("ry",i/2).attr("x",-a/2).attr("y",-i/2).attr("width",a).attr("height",i);return Jn(e,s),e.intersect=function(l){return In.rect(e,l)},r},"stadium"),pnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,bo(e,void 0),!0),a=r.insert("circle",":first-child");return a.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),X.info("Circle main"),Jn(e,a),e.intersect=function(s){return X.info("Circle intersect",e,n.width/2+i,s),In.circle(e,n.width/2+i,s)},r},"circle"),mnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,bo(e,void 0),!0),a=5,s=r.insert("g",":first-child"),l=s.insert("circle"),u=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+a).attr("width",n.width+e.padding+a*2).attr("height",n.height+e.padding+a*2),u.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),X.info("DoubleCircle main"),Jn(e,l),e.intersect=function(h){return X.info("DoubleCircle intersect",e,n.width/2+i+a,h),In.circle(e,n.width/2+i+a,h)},r},"doublecircle"),gnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i,y:0},{x:i,y:-a},{x:0,y:-a},{x:0,y:0},{x:-8,y:0},{x:i+8,y:0},{x:i+8,y:-a},{x:-8,y:-a},{x:-8,y:0}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"subroutine"),ynt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),Jn(e,n),e.intersect=function(i){return In.circle(e,7,i)},r},"start"),x2e=o((t,e,r)=>{let n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=70,a=10;r==="LR"&&(i=10,a=70);let s=n.append("rect").attr("x",-1*i/2).attr("y",-1*a/2).attr("width",i).attr("height",a).attr("class","fork-join");return Jn(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(l){return In.rect(e,l)},n},"forkJoin"),vnt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child"),i=r.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),n.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),Jn(e,i),e.intersect=function(a){return In.circle(e,7,a)},r},"end"),xnt=o(async(t,e)=>{let r=e.padding/2,n=4,i=8,a;e.classes?a="node "+e.classes:a="node default";let s=t.insert("g").attr("class",a).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),u=s.insert("line"),h=s.insert("line"),f=0,d=n,p=s.insert("g").attr("class","label"),m=0,g=e.classData.annotations?.[0],y=e.classData.annotations[0]?"\xAB"+e.classData.annotations[0]+"\xBB":"",v=p.node().appendChild(await ks(y,e.labelStyle,!0,!0)),x=v.getBBox();if(dr(me().flowchart.htmlLabels)){let C=v.children[0],D=Ge(v);x=C.getBoundingClientRect(),D.attr("width",x.width),D.attr("height",x.height)}e.classData.annotations[0]&&(d+=x.height+n,f+=x.width);let b=e.classData.label;e.classData.type!==void 0&&e.classData.type!==""&&(me().flowchart.htmlLabels?b+="<"+e.classData.type+">":b+="<"+e.classData.type+">");let T=p.node().appendChild(await ks(b,e.labelStyle,!0,!0));Ge(T).attr("class","classTitle");let S=T.getBBox();if(dr(me().flowchart.htmlLabels)){let C=T.children[0],D=Ge(T);S=C.getBoundingClientRect(),D.attr("width",S.width),D.attr("height",S.height)}d+=S.height+n,S.width>f&&(f=S.width);let w=[];e.classData.members.forEach(async C=>{let D=C.getDisplayDetails(),O=D.displayText;me().flowchart.htmlLabels&&(O=O.replace(//g,">"));let R=p.node().appendChild(await ks(O,D.cssStyle?D.cssStyle:e.labelStyle,!0,!0)),k=R.getBBox();if(dr(me().flowchart.htmlLabels)){let L=R.children[0],A=Ge(R);k=L.getBoundingClientRect(),A.attr("width",k.width),A.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,w.push(R)}),d+=i;let E=[];if(e.classData.methods.forEach(async C=>{let D=C.getDisplayDetails(),O=D.displayText;me().flowchart.htmlLabels&&(O=O.replace(//g,">"));let R=p.node().appendChild(await ks(O,D.cssStyle?D.cssStyle:e.labelStyle,!0,!0)),k=R.getBBox();if(dr(me().flowchart.htmlLabels)){let L=R.children[0],A=Ge(R);k=L.getBoundingClientRect(),A.attr("width",k.width),A.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,E.push(R)}),d+=i,g){let C=(f-x.width)/2;Ge(v).attr("transform","translate( "+(-1*f/2+C)+", "+-1*d/2+")"),m=x.height+n}let _=(f-S.width)/2;return Ge(T).attr("transform","translate( "+(-1*f/2+_)+", "+(-1*d/2+m)+")"),m+=S.height+n,u.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,w.forEach(C=>{Ge(C).attr("transform","translate( "+-f/2+", "+(-1*d/2+m+i/2)+")");let D=C?.getBBox();m+=(D?.height??0)+n}),m+=i,h.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,E.forEach(C=>{Ge(C).attr("transform","translate( "+-f/2+", "+(-1*d/2+m)+")");let D=C?.getBBox();m+=(D?.height??0)+n}),l.attr("style",e.style).attr("class","outer title-state").attr("x",-f/2-r).attr("y",-(d/2)-r).attr("width",f+e.padding).attr("height",d+e.padding),Jn(e,l),e.intersect=function(C){return In.rect(e,C)},s},"class_box"),b2e={rhombus:v2e,composite:unt,question:v2e,rect:cnt,labelRect:hnt,rectWithTitle:fnt,choice:Jrt,circle:pnt,doublecircle:mnt,stadium:dnt,hexagon:ent,block_arrow:tnt,rect_left_inv_arrow:rnt,lean_right:nnt,lean_left:int,trapezoid:ant,inv_trapezoid:snt,rect_right_inv_arrow:ont,cylinder:lnt,start:ynt,end:vnt,note:m2e,subroutine:gnt,fork:x2e,join:x2e,class_box:xnt},SC={},HF=o(async(t,e,r)=>{let n,i;if(e.link){let a;me().securityLevel==="sandbox"?a="_top":e.linkTarget&&(a=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",a),i=await b2e[e.shape](n,e,r)}else i=await b2e[e.shape](t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),SC[e.id]=n,e.haveCallback&&SC[e.id].attr("class",SC[e.id].attr("class")+" clickable"),n},"insertNode"),T2e=o(t=>{let e=SC[t.id];X.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});function k2e(t,e,r=!1){let n=t,i="default";(n?.classes?.length||0)>0&&(i=(n?.classes??[]).join(" ")),i=i+" flowchart-label";let a=0,s="",l;switch(n.type){case"round":a=5,s="rect";break;case"composite":a=0,s="composite",l=0;break;case"square":s="rect";break;case"diamond":s="question";break;case"hexagon":s="hexagon";break;case"block_arrow":s="block_arrow";break;case"odd":s="rect_left_inv_arrow";break;case"lean_right":s="lean_right";break;case"lean_left":s="lean_left";break;case"trapezoid":s="trapezoid";break;case"inv_trapezoid":s="inv_trapezoid";break;case"rect_left_inv_arrow":s="rect_left_inv_arrow";break;case"circle":s="circle";break;case"ellipse":s="ellipse";break;case"stadium":s="stadium";break;case"subroutine":s="subroutine";break;case"cylinder":s="cylinder";break;case"group":s="rect";break;case"doublecircle":s="doublecircle";break;default:s="rect"}let u=D9(n?.styles??[]),h=n.label,f=n.size??{width:0,height:0,x:0,y:0};return{labelStyle:u.labelStyle,shape:s,labelText:h,rx:a,ry:a,class:i,style:u.style,id:n.id,directions:n.directions,width:f.width,height:f.height,x:f.x,y:f.y,positioned:r,intersect:void 0,type:n.type,padding:l??tr()?.block?.padding??0}}async function bnt(t,e,r){let n=k2e(e,r,!1);if(n.type==="group")return;let i=tr(),a=await HF(t,n,{config:i}),s=a.node().getBBox(),l=r.getBlock(n.id);l.size={width:s.width,height:s.height,x:0,y:0,node:a},r.setBlock(l),a.remove()}async function Tnt(t,e,r){let n=k2e(e,r,!0);if(r.getBlock(n.id).type!=="space"){let a=tr();await HF(t,n,{config:a}),e.intersect=n?.intersect,T2e(n)}}async function WF(t,e,r,n){for(let i of e)await n(t,i,r),i.children&&await WF(t,i.children,r,n)}async function E2e(t,e,r){await WF(t,e,r,bnt)}async function S2e(t,e,r){await WF(t,e,r,Tnt)}async function C2e(t,e,r,n,i){let a=new sn({multigraph:!0,compound:!0});a.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(let s of r)s.size&&a.setNode(s.id,{width:s.size.width,height:s.size.height,intersect:s.intersect});for(let s of e)if(s.start&&s.end){let l=n.getBlock(s.start),u=n.getBlock(s.end);if(l?.size&&u?.size){let h=l.size,f=u.size,d=[{x:h.x,y:h.y},{x:h.x+(f.x-h.x)/2,y:h.y+(f.y-h.y)/2},{x:f.x,y:f.y}];e2e(t,{v:s.start,w:s.end,name:s.id},{...s,arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",a,i),s.label&&(await Zve(t,{...s,label:s.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),Jve({...s,x:d[1].x,y:d[1].y},{originalPath:d}))}}}var A2e=N(()=>{"use strict";Wo();mi();t2e();w2e();er();o(k2e,"getNodeFromBlock");o(bnt,"calculateBlockSize");o(Tnt,"insertBlockPositioned");o(WF,"performOperations");o(E2e,"calculateBlockSizes");o(S2e,"insertBlocks");o(C2e,"insertEdges")});var wnt,knt,_2e,D2e=N(()=>{"use strict";fr();mi();Vve();yt();xi();qve();A2e();wnt=o(function(t,e){return e.db.getClasses()},"getClasses"),knt=o(async function(t,e,r,n){let{securityLevel:i,block:a}=tr(),s=n.db,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`);Gve(h,["point","circle","cross"],n.type,e);let d=s.getBlocks(),p=s.getBlocksFlat(),m=s.getEdges(),g=h.insert("g").attr("class","block");await E2e(g,d,s);let y=Wve(s);if(await S2e(g,d,s),await C2e(g,m,p,s,e),y){let v=y,x=Math.max(1,Math.round(.125*(v.width/v.height))),b=v.height+x+10,T=v.width+10,{useMaxWidth:S}=a;fn(h,b,T,!!S),X.debug("Here Bounds",y,v),h.attr("viewBox",`${v.x-5} ${v.y-5} ${v.width+10} ${v.height+10}`)}},"draw"),_2e={draw:knt,getClasses:wnt}});var L2e={};ur(L2e,{diagram:()=>Ent});var Ent,R2e=N(()=>{"use strict";Rve();Fve();zve();D2e();Ent={parser:Lve,db:Bve,renderer:_2e,styles:$ve}});var qF,YF,D4,I2e,XF,ja,ru,L4,O2e,_nt,R4,P2e,B2e,F2e,$2e,z2e,CC,Yf,AC=N(()=>{"use strict";qF={L:"left",R:"right",T:"top",B:"bottom"},YF={L:o(t=>`${t},${t/2} 0,${t} 0,0`,"L"),R:o(t=>`0,${t/2} ${t},0 ${t},${t}`,"R"),T:o(t=>`0,0 ${t},0 ${t/2},${t}`,"T"),B:o(t=>`${t/2},0 ${t},${t} 0,${t}`,"B")},D4={L:o((t,e)=>t-e+2,"L"),R:o((t,e)=>t-2,"R"),T:o((t,e)=>t-e+2,"T"),B:o((t,e)=>t-2,"B")},I2e=o(function(t){return ja(t)?t==="L"?"R":"L":t==="T"?"B":"T"},"getOppositeArchitectureDirection"),XF=o(function(t){let e=t;return e==="L"||e==="R"||e==="T"||e==="B"},"isArchitectureDirection"),ja=o(function(t){let e=t;return e==="L"||e==="R"},"isArchitectureDirectionX"),ru=o(function(t){let e=t;return e==="T"||e==="B"},"isArchitectureDirectionY"),L4=o(function(t,e){let r=ja(t)&&ru(e),n=ru(t)&&ja(e);return r||n},"isArchitectureDirectionXY"),O2e=o(function(t){let e=t[0],r=t[1],n=ja(e)&&ru(r),i=ru(e)&&ja(r);return n||i},"isArchitecturePairXY"),_nt=o(function(t){return t!=="LL"&&t!=="RR"&&t!=="TT"&&t!=="BB"},"isValidArchitectureDirectionPair"),R4=o(function(t,e){let r=`${t}${e}`;return _nt(r)?r:void 0},"getArchitectureDirectionPair"),P2e=o(function([t,e],r){let n=r[0],i=r[1];return ja(n)?ru(i)?[t+(n==="L"?-1:1),e+(i==="T"?1:-1)]:[t+(n==="L"?-1:1),e]:ja(i)?[t+(i==="L"?1:-1),e+(n==="T"?1:-1)]:[t,e+(n==="T"?1:-1)]},"shiftPositionByArchitectureDirectionPair"),B2e=o(function(t){return t==="LT"||t==="TL"?[1,1]:t==="BL"||t==="LB"?[1,-1]:t==="BR"||t==="RB"?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),F2e=o(function(t,e){return L4(t,e)?"bend":ja(t)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),$2e=o(function(t){return t.type==="service"},"isArchitectureService"),z2e=o(function(t){return t.type==="junction"},"isArchitectureJunction"),CC=o(t=>t.data(),"edgeData"),Yf=o(t=>t.data(),"nodeData")});function Mi(t){return V2e()[t]}var G2e,vr,Dnt,Lnt,Rnt,Nnt,Mnt,Int,jF,Ont,Pnt,Bnt,Fnt,$nt,znt,Gnt,V2e,o0,N4=N(()=>{"use strict";_a();mi();SS();ci();AC();er();G2e=or.architecture,vr=new Tf(()=>({nodes:{},groups:{},edges:[],registeredIds:{},config:G2e,dataStructures:void 0,elements:{}})),Dnt=o(()=>{vr.reset(),kr()},"clear"),Lnt=o(function({id:t,icon:e,in:r,title:n,iconText:i}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The service id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The service [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The service [${t}]'s parent does not exist. Please make sure the parent is created before this service`);if(vr.records.registeredIds[r]==="node")throw new Error(`The service [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"service",icon:e,iconText:i,title:n,edges:[],in:r}},"addService"),Rnt=o(()=>Object.values(vr.records.nodes).filter($2e),"getServices"),Nnt=o(function({id:t,in:e}){vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"junction",edges:[],in:e}},"addJunction"),Mnt=o(()=>Object.values(vr.records.nodes).filter(z2e),"getJunctions"),Int=o(()=>Object.values(vr.records.nodes),"getNodes"),jF=o(t=>vr.records.nodes[t],"getNode"),Ont=o(function({id:t,icon:e,in:r,title:n}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The group id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The group [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The group [${t}]'s parent does not exist. Please make sure the parent is created before this group`);if(vr.records.registeredIds[r]==="node")throw new Error(`The group [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="group",vr.records.groups[t]={id:t,icon:e,title:n,in:r}},"addGroup"),Pnt=o(()=>Object.values(vr.records.groups),"getGroups"),Bnt=o(function({lhsId:t,rhsId:e,lhsDir:r,rhsDir:n,lhsInto:i,rhsInto:a,lhsGroup:s,rhsGroup:l,title:u}){if(!XF(r))throw new Error(`Invalid direction given for left hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${r}`);if(!XF(n))throw new Error(`Invalid direction given for right hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${n}`);if(vr.records.nodes[t]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The left-hand id [${t}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(vr.records.nodes[e]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The right-hand id [${e}] does not yet exist. Please create the service/group before declaring an edge to it.`);let h=vr.records.nodes[t].in,f=vr.records.nodes[e].in;if(s&&h&&f&&h==f)throw new Error(`The left-hand id [${t}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(l&&h&&f&&h==f)throw new Error(`The right-hand id [${e}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);let d={lhsId:t,lhsDir:r,lhsInto:i,lhsGroup:s,rhsId:e,rhsDir:n,rhsInto:a,rhsGroup:l,title:u};vr.records.edges.push(d),vr.records.nodes[t]&&vr.records.nodes[e]&&(vr.records.nodes[t].edges.push(vr.records.edges[vr.records.edges.length-1]),vr.records.nodes[e].edges.push(vr.records.edges[vr.records.edges.length-1]))},"addEdge"),Fnt=o(()=>vr.records.edges,"getEdges"),$nt=o(()=>{if(vr.records.dataStructures===void 0){let t={},e=Object.entries(vr.records.nodes).reduce((l,[u,h])=>(l[u]=h.edges.reduce((f,d)=>{let p=jF(d.lhsId)?.in,m=jF(d.rhsId)?.in;if(p&&m&&p!==m){let g=F2e(d.lhsDir,d.rhsDir);g!=="bend"&&(t[p]??={},t[p][m]=g,t[m]??={},t[m][p]=g)}if(d.lhsId===u){let g=R4(d.lhsDir,d.rhsDir);g&&(f[g]=d.rhsId)}else{let g=R4(d.rhsDir,d.lhsDir);g&&(f[g]=d.lhsId)}return f},{}),l),{}),r=Object.keys(e)[0],n={[r]:1},i=Object.keys(e).reduce((l,u)=>u===r?l:{...l,[u]:1},{}),a=o(l=>{let u={[l]:[0,0]},h=[l];for(;h.length>0;){let f=h.shift();if(f){n[f]=1,delete i[f];let d=e[f],[p,m]=u[f];Object.entries(d).forEach(([g,y])=>{n[y]||(u[y]=P2e([p,m],g),h.push(y))})}}return u},"BFS"),s=[a(r)];for(;Object.keys(i).length>0;)s.push(a(Object.keys(i)[0]));vr.records.dataStructures={adjList:e,spatialMaps:s,groupAlignments:t}}return vr.records.dataStructures},"getDataStructures"),znt=o((t,e)=>{vr.records.elements[t]=e},"setElementForId"),Gnt=o(t=>vr.records.elements[t],"getElementById"),V2e=o(()=>$n({...G2e,...tr().architecture}),"getConfig"),o0={clear:Dnt,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,getConfig:V2e,addService:Lnt,getServices:Rnt,addJunction:Nnt,getJunctions:Mnt,getNodes:Int,getNode:jF,addGroup:Ont,getGroups:Pnt,addEdge:Bnt,getEdges:Fnt,setElementForId:znt,getElementById:Gnt,getDataStructures:$nt};o(Mi,"getConfigField")});var Vnt,U2e,H2e=N(()=>{"use strict";bf();yt();Mp();N4();Vnt=o((t,e)=>{Jo(t,e),t.groups.map(e.addGroup),t.services.map(r=>e.addService({...r,type:"service"})),t.junctions.map(r=>e.addJunction({...r,type:"junction"})),t.edges.map(e.addEdge)},"populateDb"),U2e={parse:o(async t=>{let e=await vs("architecture",t);X.debug(e),Vnt(e,o0)},"parse")}});var Unt,W2e,q2e=N(()=>{"use strict";Unt=o(t=>` + .edge { + stroke-width: ${t.archEdgeWidth}; + stroke: ${t.archEdgeColor}; + fill: none; + } + + .arrow { + fill: ${t.archEdgeArrowColor}; + } + + .node-bkg { + fill: none; + stroke: ${t.archGroupBorderColor}; + stroke-width: ${t.archGroupBorderWidth}; + stroke-dasharray: 8; + } + .node-icon-text { + display: flex; + align-items: center; + } + + .node-icon-text > div { + color: #fff; + margin: 1px; + height: fit-content; + text-align: center; + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + } +`,"getStyles"),W2e=Unt});var QF=Pi((M4,KF)=>{"use strict";o(function(e,r){typeof M4=="object"&&typeof KF=="object"?KF.exports=r():typeof define=="function"&&define.amd?define([],r):typeof M4=="object"?M4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(M4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=28)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(5);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;yp?(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)):this.labelPosHorizontal=="right"&&this.setWidth(p+this.labelWidth)),this.labelHeight&&(this.labelPosVertical=="top"?(this.rect.y-=this.labelHeight,this.setHeight(m+this.labelHeight)):this.labelPosVertical=="center"&&this.labelHeight>m?(this.rect.y-=(this.labelHeight-m)/2,this.setHeight(this.labelHeight)):this.labelPosVertical=="bottom"&&this.setHeight(m+this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";var n=r(0);function i(){}o(i,"FDLayoutConstants");for(var a in n)i[a]=n[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=i.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=i},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(7),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,T=0;T-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(w,1),x.target!=x.source&&x.target.edges.splice(E,1);var S=x.source.owner.getEdges().indexOf(x);if(S==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(S,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,T=this.getNodes(),S=T.length,w=0;wv&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(T[0].getParent().paddingLeft!=null?b=T[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,T,S,w,E,_,C=this.nodes,D=C.length,O=0;OT&&(y=T),vw&&(x=w),bT&&(y=T),vw&&(x=w),b=this.nodes.length){var D=0;v.forEach(function(O){O.owner==g&&D++}),D==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(6),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]d)return l[0]=u,l[1]=m,l[2]=f,l[3]=C,!1;if(hf)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(uf?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):A===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-I===M?f>u?(l[2]=_,l[3]=C,L=!0):(l[2]=E,l[3]=w,L=!0):I===M&&(f>u?(l[2]=S,l[3]=w,L=!0):(l[2]=D,l[3]=C,L=!0)),k&&L)return!1;if(u>f?h>d?(P=this.getCardinalDirection(A,M,4),B=this.getCardinalDirection(I,M,2)):(P=this.getCardinalDirection(-A,M,3),B=this.getCardinalDirection(-I,M,1)):h>d?(P=this.getCardinalDirection(-A,M,1),B=this.getCardinalDirection(-I,M,3)):(P=this.getCardinalDirection(A,M,2),B=this.getCardinalDirection(I,M,4)),!k)switch(P){case 1:z=m,F=u+-T/M,l[0]=F,l[1]=z;break;case 2:F=x,z=h+b*M,l[0]=F,l[1]=z;break;case 3:z=v,F=u+T/M,l[0]=F,l[1]=z;break;case 4:F=y,z=h+-b*M,l[0]=F,l[1]=z;break}if(!L)switch(B){case 1:U=w,$=f+-R/M,l[2]=$,l[3]=U;break;case 2:$=D,U=d+O*M,l[2]=$,l[3]=U;break;case 3:U=C,$=f+R/M,l[2]=$,l[3]=U;break;case 4:$=_,U=d+-O*M,l[2]=$,l[3]=U;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,T=void 0,S=void 0,w=void 0,E=void 0,_=void 0,C=void 0,D=void 0;return T=p-f,w=h-d,_=d*f-h*p,S=v-g,E=m-y,C=y*g-m*v,D=T*E-S*w,D===0?null:(x=(w*C-E*_)/D,b=(S*_-T*C)/D,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l=0){var v=(-m+Math.sqrt(m*m-4*p*g))/(2*p),x=(-m-Math.sqrt(m*m-4*p*g))/(2*p),b=null;return v>=0&&v<=1?[v]:x>=0&&x<=1?[x]:b}else return null},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,t.exports=i},function(t,e,r){"use strict";function n(){}o(n,"IMath"),n.sign=function(i){return i>0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g0&&g;){for(T.push(w[0]);T.length>0&&g;){var E=T[0];T.splice(0,1),b.add(E);for(var _=E.getEdges(),x=0;x<_.length;x++){var C=_[x].getOtherEnd(E);if(S.get(E)!=C)if(!b.has(C))T.push(C),S.set(C,E);else{g=!1;break}}}if(!g)m=[];else{var D=[].concat(n(b));m.push(D);for(var x=0;x-1&&w.splice(R,1)}b=new Set,S=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x0){for(var v=this.edgeToDummyNodes.get(y),x=0;x=0&&g.splice(C,1);var D=S.getNeighborsList();D.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),A=L-1;A==1&&E.push(k),v.set(k,A)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(5);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);pa.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.displacementThresholdPerNode=3*a.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;mT||b>T)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(T=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>T||b>T)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement=x.length||T>=x[0].length)){for(var S=0;Sh},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";function n(){}o(n,"SVD"),n.svd=function(i){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=i.length,this.n=i[0].length;var a=Math.min(this.m,this.n);this.s=function(bt){for(var ut=[];bt-- >0;)ut.push(0);return ut}(Math.min(this.m+1,this.n)),this.U=function(bt){var ut=o(function St(ft){if(ft.length==0)return 0;for(var vt=[],nt=0;nt0;)ut.push(0);return ut}(this.n),l=function(bt){for(var ut=[];bt-- >0;)ut.push(0);return ut}(this.m),u=!0,h=!0,f=Math.min(this.m-1,this.n),d=Math.max(0,Math.min(this.n-2,this.m)),p=0;p=0;M--)if(this.s[M]!==0){for(var P=M+1;P=0;ee--){if(function(bt,ut){return bt&&ut}(ee0;){var le=void 0,J=void 0;for(le=L-2;le>=-1&&le!==-1;le--)if(Math.abs(s[le])<=he+te*(Math.abs(this.s[le])+Math.abs(this.s[le+1]))){s[le]=0;break}if(le===L-2)J=4;else{var Se=void 0;for(Se=L-1;Se>=le&&Se!==le;Se--){var se=(Se!==L?Math.abs(s[Se]):0)+(Se!==le+1?Math.abs(s[Se-1]):0);if(Math.abs(this.s[Se])<=he+te*se){this.s[Se]=0;break}}Se===le?J=3:Se===L-1?J=1:(J=2,le=Se)}switch(le++,J){case 1:{var ae=s[L-2];s[L-2]=0;for(var Oe=L-2;Oe>=le;Oe--){var ye=n.hypot(this.s[Oe],ae),Be=this.s[Oe]/ye,He=ae/ye;if(this.s[Oe]=ye,Oe!==le&&(ae=-He*s[Oe-1],s[Oe-1]=Be*s[Oe-1]),h)for(var ze=0;ze=this.s[le+1]);){var ot=this.s[le];if(this.s[le]=this.s[le+1],this.s[le+1]=ot,h&&leMath.abs(a)?(s=a/i,s=Math.abs(i)*Math.sqrt(1+s*s)):a!=0?(s=i/a,s=Math.abs(a)*Math.sqrt(1+s*s)):s=0,s},t.exports=n},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l{"use strict";o(function(e,r){typeof I4=="object"&&typeof ZF=="object"?ZF.exports=r(QF()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof I4=="object"?I4.coseBase=r(QF()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(I4,function(t){return(()=>{"use strict";var e={45:(a,s,l)=>{var u={};u.layoutBase=l(551),u.CoSEConstants=l(806),u.CoSEEdge=l(767),u.CoSEGraph=l(880),u.CoSEGraphManager=l(578),u.CoSELayout=l(765),u.CoSENode=l(991),u.ConstraintHandler=l(902),a.exports=u},806:(a,s,l)=>{var u=l(551).FDLayoutConstants;function h(){}o(h,"CoSEConstants");for(var f in u)h[f]=u[f];h.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,h.DEFAULT_RADIAL_SEPARATION=u.DEFAULT_EDGE_LENGTH,h.DEFAULT_COMPONENT_SEPERATION=60,h.TILE=!0,h.TILING_PADDING_VERTICAL=10,h.TILING_PADDING_HORIZONTAL=10,h.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,h.ENFORCE_CONSTRAINTS=!0,h.APPLY_LAYOUT=!0,h.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,h.TREE_REDUCTION_ON_INCREMENTAL=!0,h.PURE_INCREMENTAL=h.DEFAULT_INCREMENTAL,a.exports=h},767:(a,s,l)=>{var u=l(551).FDLayoutEdge;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEEdge"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},880:(a,s,l)=>{var u=l(551).LGraph;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEGraph"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},578:(a,s,l)=>{var u=l(551).LGraphManager;function h(d){u.call(this,d)}o(h,"CoSEGraphManager"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},765:(a,s,l)=>{var u=l(551).FDLayout,h=l(578),f=l(880),d=l(991),p=l(767),m=l(806),g=l(902),y=l(551).FDLayoutConstants,v=l(551).LayoutConstants,x=l(551).Point,b=l(551).PointD,T=l(551).DimensionD,S=l(551).Layout,w=l(551).Integer,E=l(551).IGeometry,_=l(551).LGraph,C=l(551).Transform,D=l(551).LinkedList;function O(){u.call(this),this.toBeTiled={},this.constraints={}}o(O,"CoSELayout"),O.prototype=Object.create(u.prototype);for(var R in u)O[R]=u[R];O.prototype.newGraphManager=function(){var k=new h(this);return this.graphManager=k,k},O.prototype.newGraph=function(k){return new f(null,this.graphManager,k)},O.prototype.newNode=function(k){return new d(this.graphManager,k)},O.prototype.newEdge=function(k){return new p(null,null,k)},O.prototype.initParameters=function(){u.prototype.initParameters.call(this,arguments),this.isSubLayout||(m.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=m.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=m.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=y.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=y.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=y.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},O.prototype.initSpringEmbedder=function(){u.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/y.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},O.prototype.layout=function(){var k=v.DEFAULT_CREATE_BENDS_AS_NEEDED;return k&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},O.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(m.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(P){return L.has(P)});this.graphManager.setAllNodesToApplyGravitation(A)}}else{var k=this.getFlatForest();if(k.length>0)this.positionNodesRadially(k);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(I){return L.has(I)});this.graphManager.setAllNodesToApplyGravitation(A),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(g.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),m.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},O.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%y.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var k=new Set(this.getAllNodes()),L=this.nodesWithGravity.filter(function(M){return k.has(M)});this.graphManager.setAllNodesToApplyGravitation(L),this.graphManager.updateBounds(),this.updateGrid(),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var A=!this.isTreeGrowing&&!this.isGrowthFinished,I=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(A,I),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},O.prototype.getPositionsData=function(){for(var k=this.graphManager.getAllNodes(),L={},A=0;A0&&this.updateDisplacements();for(var A=0;A0&&(I.fixedNodeWeight=P)}}if(this.constraints.relativePlacementConstraint){var B=new Map,F=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(Z){k.fixedNodesOnHorizontal.add(Z),k.fixedNodesOnVertical.add(Z)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var z=this.constraints.alignmentConstraint.vertical,A=0;A=2*Z.length/3;j--)ue=Math.floor(Math.random()*(j+1)),Q=Z[j],Z[j]=Z[ue],Z[ue]=Q;return Z},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(Z){if(Z.left){var ue=B.has(Z.left)?B.get(Z.left):Z.left,Q=B.has(Z.right)?B.get(Z.right):Z.right;k.nodesInRelativeHorizontal.includes(ue)||(k.nodesInRelativeHorizontal.push(ue),k.nodeToRelativeConstraintMapHorizontal.set(ue,[]),k.dummyToNodeForVerticalAlignment.has(ue)?k.nodeToTempPositionMapHorizontal.set(ue,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(ue)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(ue,k.idToNodeMap.get(ue).getCenterX())),k.nodesInRelativeHorizontal.includes(Q)||(k.nodesInRelativeHorizontal.push(Q),k.nodeToRelativeConstraintMapHorizontal.set(Q,[]),k.dummyToNodeForVerticalAlignment.has(Q)?k.nodeToTempPositionMapHorizontal.set(Q,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(Q)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(Q,k.idToNodeMap.get(Q).getCenterX())),k.nodeToRelativeConstraintMapHorizontal.get(ue).push({right:Q,gap:Z.gap}),k.nodeToRelativeConstraintMapHorizontal.get(Q).push({left:ue,gap:Z.gap})}else{var j=F.has(Z.top)?F.get(Z.top):Z.top,ne=F.has(Z.bottom)?F.get(Z.bottom):Z.bottom;k.nodesInRelativeVertical.includes(j)||(k.nodesInRelativeVertical.push(j),k.nodeToRelativeConstraintMapVertical.set(j,[]),k.dummyToNodeForHorizontalAlignment.has(j)?k.nodeToTempPositionMapVertical.set(j,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(j)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(j,k.idToNodeMap.get(j).getCenterY())),k.nodesInRelativeVertical.includes(ne)||(k.nodesInRelativeVertical.push(ne),k.nodeToRelativeConstraintMapVertical.set(ne,[]),k.dummyToNodeForHorizontalAlignment.has(ne)?k.nodeToTempPositionMapVertical.set(ne,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(ne)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(ne,k.idToNodeMap.get(ne).getCenterY())),k.nodeToRelativeConstraintMapVertical.get(j).push({bottom:ne,gap:Z.gap}),k.nodeToRelativeConstraintMapVertical.get(ne).push({top:j,gap:Z.gap})}});else{var U=new Map,K=new Map;this.constraints.relativePlacementConstraint.forEach(function(Z){if(Z.left){var ue=B.has(Z.left)?B.get(Z.left):Z.left,Q=B.has(Z.right)?B.get(Z.right):Z.right;U.has(ue)?U.get(ue).push(Q):U.set(ue,[Q]),U.has(Q)?U.get(Q).push(ue):U.set(Q,[ue])}else{var j=F.has(Z.top)?F.get(Z.top):Z.top,ne=F.has(Z.bottom)?F.get(Z.bottom):Z.bottom;K.has(j)?K.get(j).push(ne):K.set(j,[ne]),K.has(ne)?K.get(ne).push(j):K.set(ne,[j])}});var ee=o(function(ue,Q){var j=[],ne=[],te=new D,he=new Set,le=0;return ue.forEach(function(J,Se){if(!he.has(Se)){j[le]=[],ne[le]=!1;var se=Se;for(te.push(se),he.add(se),j[le].push(se);te.length!=0;){se=te.shift(),Q.has(se)&&(ne[le]=!0);var ae=ue.get(se);ae.forEach(function(Oe){he.has(Oe)||(te.push(Oe),he.add(Oe),j[le].push(Oe))})}le++}}),{components:j,isFixed:ne}},"constructComponents"),Y=ee(U,k.fixedNodesOnHorizontal);this.componentsOnHorizontal=Y.components,this.fixedComponentsOnHorizontal=Y.isFixed;var ce=ee(K,k.fixedNodesOnVertical);this.componentsOnVertical=ce.components,this.fixedComponentsOnVertical=ce.isFixed}}},O.prototype.updateDisplacements=function(){var k=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function(ce){var Z=k.idToNodeMap.get(ce.nodeId);Z.displacementX=0,Z.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var L=this.constraints.alignmentConstraint.vertical,A=0;A1){var F;for(F=0;FI&&(I=Math.floor(B.y)),P=Math.floor(B.x+m.DEFAULT_COMPONENT_SEPERATION)}this.transform(new b(v.WORLD_CENTER_X-B.x/2,v.WORLD_CENTER_Y-B.y/2))},O.radialLayout=function(k,L,A){var I=Math.max(this.maxDiagonalInTree(k),m.DEFAULT_RADIAL_SEPARATION);O.branchRadialLayout(L,null,0,359,0,I);var M=_.calculateBounds(k),P=new C;P.setDeviceOrgX(M.getMinX()),P.setDeviceOrgY(M.getMinY()),P.setWorldOrgX(A.x),P.setWorldOrgY(A.y);for(var B=0;B1;){var j=Q[0];Q.splice(0,1);var ne=ee.indexOf(j);ne>=0&&ee.splice(ne,1),Z--,Y--}L!=null?ue=(ee.indexOf(Q[0])+1)%Z:ue=0;for(var te=Math.abs(I-A)/Y,he=ue;ce!=Y;he=++he%Z){var le=ee[he].getOtherEnd(k);if(le!=L){var J=(A+ce*te)%360,Se=(J+te)%360;O.branchRadialLayout(le,k,J,Se,M+P,P),ce++}}},O.maxDiagonalInTree=function(k){for(var L=w.MIN_VALUE,A=0;AL&&(L=M)}return L},O.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},O.prototype.groupZeroDegreeMembers=function(){var k=this,L={};this.memberGroups={},this.idToDummyNode={};for(var A=[],I=this.graphManager.getAllNodes(),M=0;M"u"&&(L[F]=[]),L[F]=L[F].concat(P)}Object.keys(L).forEach(function(z){if(L[z].length>1){var $="DummyCompound_"+z;k.memberGroups[$]=L[z];var U=L[z][0].getParent(),K=new d(k.graphManager);K.id=$,K.paddingLeft=U.paddingLeft||0,K.paddingRight=U.paddingRight||0,K.paddingBottom=U.paddingBottom||0,K.paddingTop=U.paddingTop||0,k.idToDummyNode[$]=K;var ee=k.getGraphManager().add(k.newGraph(),K),Y=U.getChild();Y.add(K);for(var ce=0;ceM?(I.rect.x-=(I.labelWidth-M)/2,I.setWidth(I.labelWidth),I.labelMarginLeft=(I.labelWidth-M)/2):I.labelPosHorizontal=="right"&&I.setWidth(M+I.labelWidth)),I.labelHeight&&(I.labelPosVertical=="top"?(I.rect.y-=I.labelHeight,I.setHeight(P+I.labelHeight),I.labelMarginTop=I.labelHeight):I.labelPosVertical=="center"&&I.labelHeight>P?(I.rect.y-=(I.labelHeight-P)/2,I.setHeight(I.labelHeight),I.labelMarginTop=(I.labelHeight-P)/2):I.labelPosVertical=="bottom"&&I.setHeight(P+I.labelHeight))}})},O.prototype.repopulateCompounds=function(){for(var k=this.compoundOrder.length-1;k>=0;k--){var L=this.compoundOrder[k],A=L.id,I=L.paddingLeft,M=L.paddingTop,P=L.labelMarginLeft,B=L.labelMarginTop;this.adjustLocations(this.tiledMemberPack[A],L.rect.x,L.rect.y,I,M,P,B)}},O.prototype.repopulateZeroDegreeMembers=function(){var k=this,L=this.tiledZeroDegreePack;Object.keys(L).forEach(function(A){var I=k.idToDummyNode[A],M=I.paddingLeft,P=I.paddingTop,B=I.labelMarginLeft,F=I.labelMarginTop;k.adjustLocations(L[A],I.rect.x,I.rect.y,M,P,B,F)})},O.prototype.getToBeTiled=function(k){var L=k.id;if(this.toBeTiled[L]!=null)return this.toBeTiled[L];var A=k.getChild();if(A==null)return this.toBeTiled[L]=!1,!1;for(var I=A.getNodes(),M=0;M0)return this.toBeTiled[L]=!1,!1;if(P.getChild()==null){this.toBeTiled[P.id]=!1;continue}if(!this.getToBeTiled(P))return this.toBeTiled[L]=!1,!1}return this.toBeTiled[L]=!0,!0},O.prototype.getNodeDegree=function(k){for(var L=k.id,A=k.getEdges(),I=0,M=0;MU&&(U=ee.rect.height)}A+=U+k.verticalPadding}},O.prototype.tileCompoundMembers=function(k,L){var A=this;this.tiledMemberPack=[],Object.keys(k).forEach(function(I){var M=L[I];if(A.tiledMemberPack[I]=A.tileNodes(k[I],M.paddingLeft+M.paddingRight),M.rect.width=A.tiledMemberPack[I].width,M.rect.height=A.tiledMemberPack[I].height,M.setCenter(A.tiledMemberPack[I].centerX,A.tiledMemberPack[I].centerY),M.labelMarginLeft=0,M.labelMarginTop=0,m.NODE_DIMENSIONS_INCLUDE_LABELS){var P=M.rect.width,B=M.rect.height;M.labelWidth&&(M.labelPosHorizontal=="left"?(M.rect.x-=M.labelWidth,M.setWidth(P+M.labelWidth),M.labelMarginLeft=M.labelWidth):M.labelPosHorizontal=="center"&&M.labelWidth>P?(M.rect.x-=(M.labelWidth-P)/2,M.setWidth(M.labelWidth),M.labelMarginLeft=(M.labelWidth-P)/2):M.labelPosHorizontal=="right"&&M.setWidth(P+M.labelWidth)),M.labelHeight&&(M.labelPosVertical=="top"?(M.rect.y-=M.labelHeight,M.setHeight(B+M.labelHeight),M.labelMarginTop=M.labelHeight):M.labelPosVertical=="center"&&M.labelHeight>B?(M.rect.y-=(M.labelHeight-B)/2,M.setHeight(M.labelHeight),M.labelMarginTop=(M.labelHeight-B)/2):M.labelPosVertical=="bottom"&&M.setHeight(B+M.labelHeight))}})},O.prototype.tileNodes=function(k,L){var A=this.tileNodesByFavoringDim(k,L,!0),I=this.tileNodesByFavoringDim(k,L,!1),M=this.getOrgRatio(A),P=this.getOrgRatio(I),B;return PF&&(F=ce.getWidth())});var z=P/M,$=B/M,U=Math.pow(A-I,2)+4*(z+I)*($+A)*M,K=(I-A+Math.sqrt(U))/(2*(z+I)),ee;L?(ee=Math.ceil(K),ee==K&&ee++):ee=Math.floor(K);var Y=ee*(z+I)-I;return F>Y&&(Y=F),Y+=I*2,Y},O.prototype.tileNodesByFavoringDim=function(k,L,A){var I=m.TILING_PADDING_VERTICAL,M=m.TILING_PADDING_HORIZONTAL,P=m.TILING_COMPARE_BY,B={rows:[],rowWidth:[],rowHeight:[],width:0,height:L,verticalPadding:I,horizontalPadding:M,centerX:0,centerY:0};P&&(B.idealRowWidth=this.calcIdealRowWidth(k,A));var F=o(function(Z){return Z.rect.width*Z.rect.height},"getNodeArea"),z=o(function(Z,ue){return F(ue)-F(Z)},"areaCompareFcn");k.sort(function(ce,Z){var ue=z;return B.idealRowWidth?(ue=P,ue(ce.id,Z.id)):ue(ce,Z)});for(var $=0,U=0,K=0;K0&&(B+=k.horizontalPadding),k.rowWidth[A]=B,k.width0&&(F+=k.verticalPadding);var z=0;F>k.rowHeight[A]&&(z=k.rowHeight[A],k.rowHeight[A]=F,z=k.rowHeight[A]-z),k.height+=z,k.rows[A].push(L)},O.prototype.getShortestRowIndex=function(k){for(var L=-1,A=Number.MAX_VALUE,I=0;IA&&(L=I,A=k.rowWidth[I]);return L},O.prototype.canAddHorizontal=function(k,L,A){if(k.idealRowWidth){var I=k.rows.length-1,M=k.rowWidth[I];return M+L+k.horizontalPadding<=k.idealRowWidth}var P=this.getShortestRowIndex(k);if(P<0)return!0;var B=k.rowWidth[P];if(B+k.horizontalPadding+L<=k.width)return!0;var F=0;k.rowHeight[P]0&&(F=A+k.verticalPadding-k.rowHeight[P]);var z;k.width-B>=L+k.horizontalPadding?z=(k.height+F)/(B+L+k.horizontalPadding):z=(k.height+F)/k.width,F=A+k.verticalPadding;var $;return k.widthP&&L!=A){I.splice(-1,1),k.rows[A].push(M),k.rowWidth[L]=k.rowWidth[L]-P,k.rowWidth[A]=k.rowWidth[A]+P,k.width=k.rowWidth[instance.getLongestRowIndex(k)];for(var B=Number.MIN_VALUE,F=0;FB&&(B=I[F].height);L>0&&(B+=k.verticalPadding);var z=k.rowHeight[L]+k.rowHeight[A];k.rowHeight[L]=B,k.rowHeight[A]0)for(var Y=M;Y<=P;Y++)ee[0]+=this.grid[Y][B-1].length+this.grid[Y][B].length-1;if(P0)for(var Y=B;Y<=F;Y++)ee[3]+=this.grid[M-1][Y].length+this.grid[M][Y].length-1;for(var ce=w.MAX_VALUE,Z,ue,Q=0;Q{var u=l(551).FDLayoutNode,h=l(551).IMath;function f(p,m,g,y){u.call(this,p,m,g,y)}o(f,"CoSENode"),f.prototype=Object.create(u.prototype);for(var d in u)f[d]=u[d];f.prototype.calculateDisplacement=function(){var p=this.graphManager.getLayout();this.getChild()!=null&&this.fixedNodeWeight?(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementX=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementX)),Math.abs(this.displacementY)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementY=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},f.prototype.propogateDisplacementToChildren=function(p,m){for(var g=this.getChild().getNodes(),y,v=0;v{function u(g){if(Array.isArray(g)){for(var y=0,v=Array(g.length);y0){var ct=0;Ue.forEach(function(ot){Te=="horizontal"?(be.set(ot,x.has(ot)?b[x.get(ot)]:pe.get(ot)),ct+=be.get(ot)):(be.set(ot,x.has(ot)?T[x.get(ot)]:pe.get(ot)),ct+=be.get(ot))}),ct=ct/Ue.length,st.forEach(function(ot){W.has(ot)||be.set(ot,ct)})}else{var We=0;st.forEach(function(ot){Te=="horizontal"?We+=x.has(ot)?b[x.get(ot)]:pe.get(ot):We+=x.has(ot)?T[x.get(ot)]:pe.get(ot)}),We=We/st.length,st.forEach(function(ot){be.set(ot,We)})}});for(var qe=o(function(){var Ue=De.shift(),ct=V.get(Ue);ct.forEach(function(We){if(be.get(We.id)ot&&(ot=vt),ntYt&&(Yt=nt)}}catch(Dt){Mt=!0,bt=Dt}finally{try{!Tt&&ut.return&&ut.return()}finally{if(Mt)throw bt}}var pn=(ct+ot)/2-(We+Yt)/2,kt=!0,On=!1,tn=void 0;try{for(var Mr=st[Symbol.iterator](),Ir;!(kt=(Ir=Mr.next()).done);kt=!0){var Pn=Ir.value;be.set(Pn,be.get(Pn)+pn)}}catch(Dt){On=!0,tn=Dt}finally{try{!kt&&Mr.return&&Mr.return()}finally{if(On)throw tn}}})}return be},"findAppropriatePositionForRelativePlacement"),R=o(function(V){var Te=0,W=0,pe=0,ve=0;if(V.forEach(function(Ve){Ve.left?b[x.get(Ve.left)]-b[x.get(Ve.right)]>=0?Te++:W++:T[x.get(Ve.top)]-T[x.get(Ve.bottom)]>=0?pe++:ve++}),Te>W&&pe>ve)for(var Pe=0;PeW)for(var _e=0;_eve)for(var be=0;be1)y.fixedNodeConstraint.forEach(function(oe,V){I[V]=[oe.position.x,oe.position.y],M[V]=[b[x.get(oe.nodeId)],T[x.get(oe.nodeId)]]}),P=!0;else if(y.alignmentConstraint)(function(){var oe=0;if(y.alignmentConstraint.vertical){for(var V=y.alignmentConstraint.vertical,Te=o(function(be){var Ve=new Set;V[be].forEach(function(at){Ve.add(at)});var De=new Set([].concat(u(Ve)).filter(function(at){return F.has(at)})),qe=void 0;De.size>0?qe=b[x.get(De.values().next().value)]:qe=D(Ve).x,V[be].forEach(function(at){I[oe]=[qe,T[x.get(at)]],M[oe]=[b[x.get(at)],T[x.get(at)]],oe++})},"_loop2"),W=0;W0?qe=b[x.get(De.values().next().value)]:qe=D(Ve).y,pe[be].forEach(function(at){I[oe]=[b[x.get(at)],qe],M[oe]=[b[x.get(at)],T[x.get(at)]],oe++})},"_loop3"),Pe=0;PeK&&(K=U[Y].length,ee=Y);if(K<$.size/2)R(y.relativePlacementConstraint),P=!1,B=!1;else{var ce=new Map,Z=new Map,ue=[];U[ee].forEach(function(oe){z.get(oe).forEach(function(V){V.direction=="horizontal"?(ce.has(oe)?ce.get(oe).push(V):ce.set(oe,[V]),ce.has(V.id)||ce.set(V.id,[]),ue.push({left:oe,right:V.id})):(Z.has(oe)?Z.get(oe).push(V):Z.set(oe,[V]),Z.has(V.id)||Z.set(V.id,[]),ue.push({top:oe,bottom:V.id}))})}),R(ue),B=!1;var Q=O(ce,"horizontal"),j=O(Z,"vertical");U[ee].forEach(function(oe,V){M[V]=[b[x.get(oe)],T[x.get(oe)]],I[V]=[],Q.has(oe)?I[V][0]=Q.get(oe):I[V][0]=b[x.get(oe)],j.has(oe)?I[V][1]=j.get(oe):I[V][1]=T[x.get(oe)]}),P=!0}}if(P){for(var ne=void 0,te=d.transpose(I),he=d.transpose(M),le=0;le0){var Be={x:0,y:0};y.fixedNodeConstraint.forEach(function(oe,V){var Te={x:b[x.get(oe.nodeId)],y:T[x.get(oe.nodeId)]},W=oe.position,pe=C(W,Te);Be.x+=pe.x,Be.y+=pe.y}),Be.x/=y.fixedNodeConstraint.length,Be.y/=y.fixedNodeConstraint.length,b.forEach(function(oe,V){b[V]+=Be.x}),T.forEach(function(oe,V){T[V]+=Be.y}),y.fixedNodeConstraint.forEach(function(oe){b[x.get(oe.nodeId)]=oe.position.x,T[x.get(oe.nodeId)]=oe.position.y})}if(y.alignmentConstraint){if(y.alignmentConstraint.vertical)for(var He=y.alignmentConstraint.vertical,ze=o(function(V){var Te=new Set;He[V].forEach(function(ve){Te.add(ve)});var W=new Set([].concat(u(Te)).filter(function(ve){return F.has(ve)})),pe=void 0;W.size>0?pe=b[x.get(W.values().next().value)]:pe=D(Te).x,Te.forEach(function(ve){F.has(ve)||(b[x.get(ve)]=pe)})},"_loop4"),Le=0;Le0?pe=T[x.get(W.values().next().value)]:pe=D(Te).y,Te.forEach(function(ve){F.has(ve)||(T[x.get(ve)]=pe)})},"_loop5"),q=0;q{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(45);return i})()})});var Y2e=Pi((O4,e$)=>{"use strict";o(function(e,r){typeof O4=="object"&&typeof e$=="object"?e$.exports=r(JF()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof O4=="object"?O4.cytoscapeFcose=r(JF()):e.cytoscapeFcose=r(e.coseBase)},"webpackUniversalModuleDefinition")(O4,function(t){return(()=>{"use strict";var e={658:a=>{a.exports=Object.assign!=null?Object.assign.bind(Object):function(s){for(var l=arguments.length,u=Array(l>1?l-1:0),h=1;h{var u=function(){function d(p,m){var g=[],y=!0,v=!1,x=void 0;try{for(var b=p[Symbol.iterator](),T;!(y=(T=b.next()).done)&&(g.push(T.value),!(m&&g.length===m));y=!0);}catch(S){v=!0,x=S}finally{try{!y&&b.return&&b.return()}finally{if(v)throw x}}return g}return o(d,"sliceIterator"),function(p,m){if(Array.isArray(p))return p;if(Symbol.iterator in Object(p))return d(p,m);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),h=l(140).layoutBase.LinkedList,f={};f.getTopMostNodes=function(d){for(var p={},m=0;m0&&P.merge($)});for(var B=0;B1){T=x[0],S=T.connectedEdges().length,x.forEach(function(M){M.connectedEdges().length0&&g.set("dummy"+(g.size+1),_),C},f.relocateComponent=function(d,p,m){if(!m.fixedNodeConstraint){var g=Number.POSITIVE_INFINITY,y=Number.NEGATIVE_INFINITY,v=Number.POSITIVE_INFINITY,x=Number.NEGATIVE_INFINITY;if(m.quality=="draft"){var b=!0,T=!1,S=void 0;try{for(var w=p.nodeIndexes[Symbol.iterator](),E;!(b=(E=w.next()).done);b=!0){var _=E.value,C=u(_,2),D=C[0],O=C[1],R=m.cy.getElementById(D);if(R){var k=R.boundingBox(),L=p.xCoords[O]-k.w/2,A=p.xCoords[O]+k.w/2,I=p.yCoords[O]-k.h/2,M=p.yCoords[O]+k.h/2;Ly&&(y=A),Ix&&(x=M)}}}catch($){T=!0,S=$}finally{try{!b&&w.return&&w.return()}finally{if(T)throw S}}var P=d.x-(y+g)/2,B=d.y-(x+v)/2;p.xCoords=p.xCoords.map(function($){return $+P}),p.yCoords=p.yCoords.map(function($){return $+B})}else{Object.keys(p).forEach(function($){var U=p[$],K=U.getRect().x,ee=U.getRect().x+U.getRect().width,Y=U.getRect().y,ce=U.getRect().y+U.getRect().height;Ky&&(y=ee),Yx&&(x=ce)});var F=d.x-(y+g)/2,z=d.y-(x+v)/2;Object.keys(p).forEach(function($){var U=p[$];U.setCenter(U.getCenterX()+F,U.getCenterY()+z)})}}},f.calcBoundingBox=function(d,p,m,g){for(var y=Number.MAX_SAFE_INTEGER,v=Number.MIN_SAFE_INTEGER,x=Number.MAX_SAFE_INTEGER,b=Number.MIN_SAFE_INTEGER,T=void 0,S=void 0,w=void 0,E=void 0,_=d.descendants().not(":parent"),C=_.length,D=0;DT&&(y=T),vw&&(x=w),b{var u=l(548),h=l(140).CoSELayout,f=l(140).CoSENode,d=l(140).layoutBase.PointD,p=l(140).layoutBase.DimensionD,m=l(140).layoutBase.LayoutConstants,g=l(140).layoutBase.FDLayoutConstants,y=l(140).CoSEConstants,v=o(function(b,T){var S=b.cy,w=b.eles,E=w.nodes(),_=w.edges(),C=void 0,D=void 0,O=void 0,R={};b.randomize&&(C=T.nodeIndexes,D=T.xCoords,O=T.yCoords);var k=o(function($){return typeof $=="function"},"isFn"),L=o(function($,U){return k($)?$(U):$},"optFn"),A=u.calcParentsWithoutChildren(S,w),I=o(function z($,U,K,ee){for(var Y=U.length,ce=0;ce0){var te=void 0;te=K.getGraphManager().add(K.newGraph(),Q),z(te,ue,K,ee)}}},"processChildrenList"),M=o(function($,U,K){for(var ee=0,Y=0,ce=0;ce0?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=ee/Y:k(b.idealEdgeLength)?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=50:y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=b.idealEdgeLength,y.MIN_REPULSION_DIST=g.MIN_REPULSION_DIST=g.DEFAULT_EDGE_LENGTH/10,y.DEFAULT_RADIAL_SEPARATION=g.DEFAULT_EDGE_LENGTH)},"processEdges"),P=o(function($,U){U.fixedNodeConstraint&&($.constraints.fixedNodeConstraint=U.fixedNodeConstraint),U.alignmentConstraint&&($.constraints.alignmentConstraint=U.alignmentConstraint),U.relativePlacementConstraint&&($.constraints.relativePlacementConstraint=U.relativePlacementConstraint)},"processConstraints");b.nestingFactor!=null&&(y.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=g.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=b.nestingFactor),b.gravity!=null&&(y.DEFAULT_GRAVITY_STRENGTH=g.DEFAULT_GRAVITY_STRENGTH=b.gravity),b.numIter!=null&&(y.MAX_ITERATIONS=g.MAX_ITERATIONS=b.numIter),b.gravityRange!=null&&(y.DEFAULT_GRAVITY_RANGE_FACTOR=g.DEFAULT_GRAVITY_RANGE_FACTOR=b.gravityRange),b.gravityCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_STRENGTH=g.DEFAULT_COMPOUND_GRAVITY_STRENGTH=b.gravityCompound),b.gravityRangeCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=g.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=b.gravityRangeCompound),b.initialEnergyOnIncremental!=null&&(y.DEFAULT_COOLING_FACTOR_INCREMENTAL=g.DEFAULT_COOLING_FACTOR_INCREMENTAL=b.initialEnergyOnIncremental),b.tilingCompareBy!=null&&(y.TILING_COMPARE_BY=b.tilingCompareBy),b.quality=="proof"?m.QUALITY=2:m.QUALITY=0,y.NODE_DIMENSIONS_INCLUDE_LABELS=g.NODE_DIMENSIONS_INCLUDE_LABELS=m.NODE_DIMENSIONS_INCLUDE_LABELS=b.nodeDimensionsIncludeLabels,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!b.randomize,y.ANIMATE=g.ANIMATE=m.ANIMATE=b.animate,y.TILE=b.tile,y.TILING_PADDING_VERTICAL=typeof b.tilingPaddingVertical=="function"?b.tilingPaddingVertical.call():b.tilingPaddingVertical,y.TILING_PADDING_HORIZONTAL=typeof b.tilingPaddingHorizontal=="function"?b.tilingPaddingHorizontal.call():b.tilingPaddingHorizontal,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!0,y.PURE_INCREMENTAL=!b.randomize,m.DEFAULT_UNIFORM_LEAF_NODE_SIZES=b.uniformNodeDimensions,b.step=="transformed"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!1),b.step=="enforced"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!1),b.step=="cose"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!0),b.step=="all"&&(b.randomize?y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!0),b.fixedNodeConstraint||b.alignmentConstraint||b.relativePlacementConstraint?y.TREE_REDUCTION_ON_INCREMENTAL=!1:y.TREE_REDUCTION_ON_INCREMENTAL=!0;var B=new h,F=B.newGraphManager();return I(F.addRoot(),u.getTopMostNodes(E),B,b),M(B,F,_),P(B,b),B.runLayout(),R},"coseLayout");a.exports={coseLayout:v}},212:(a,s,l)=>{var u=function(){function b(T,S){for(var w=0;w0)if(M){var F=d.getTopMostNodes(w.eles.nodes());if(k=d.connectComponents(E,w.eles,F),k.forEach(function(se){var ae=se.boundingBox();L.push({x:ae.x1+ae.w/2,y:ae.y1+ae.h/2})}),w.randomize&&k.forEach(function(se){w.eles=se,C.push(m(w))}),w.quality=="default"||w.quality=="proof"){var z=E.collection();if(w.tile){var $=new Map,U=[],K=[],ee=0,Y={nodeIndexes:$,xCoords:U,yCoords:K},ce=[];if(k.forEach(function(se,ae){se.edges().length==0&&(se.nodes().forEach(function(Oe,ye){z.merge(se.nodes()[ye]),Oe.isParent()||(Y.nodeIndexes.set(se.nodes()[ye].id(),ee++),Y.xCoords.push(se.nodes()[0].position().x),Y.yCoords.push(se.nodes()[0].position().y))}),ce.push(ae))}),z.length>1){var Z=z.boundingBox();L.push({x:Z.x1+Z.w/2,y:Z.y1+Z.h/2}),k.push(z),C.push(Y);for(var ue=ce.length-1;ue>=0;ue--)k.splice(ce[ue],1),C.splice(ce[ue],1),L.splice(ce[ue],1)}}k.forEach(function(se,ae){w.eles=se,R.push(y(w,C[ae])),d.relocateComponent(L[ae],R[ae],w)})}else k.forEach(function(se,ae){d.relocateComponent(L[ae],C[ae],w)});var Q=new Set;if(k.length>1){var j=[],ne=_.filter(function(se){return se.css("display")=="none"});k.forEach(function(se,ae){var Oe=void 0;if(w.quality=="draft"&&(Oe=C[ae].nodeIndexes),se.nodes().not(ne).length>0){var ye={};ye.edges=[],ye.nodes=[];var Be=void 0;se.nodes().not(ne).forEach(function(He){if(w.quality=="draft")if(!He.isParent())Be=Oe.get(He.id()),ye.nodes.push({x:C[ae].xCoords[Be]-He.boundingbox().w/2,y:C[ae].yCoords[Be]-He.boundingbox().h/2,width:He.boundingbox().w,height:He.boundingbox().h});else{var ze=d.calcBoundingBox(He,C[ae].xCoords,C[ae].yCoords,Oe);ye.nodes.push({x:ze.topLeftX,y:ze.topLeftY,width:ze.width,height:ze.height})}else R[ae][He.id()]&&ye.nodes.push({x:R[ae][He.id()].getLeft(),y:R[ae][He.id()].getTop(),width:R[ae][He.id()].getWidth(),height:R[ae][He.id()].getHeight()})}),se.edges().forEach(function(He){var ze=He.source(),Le=He.target();if(ze.css("display")!="none"&&Le.css("display")!="none")if(w.quality=="draft"){var Ie=Oe.get(ze.id()),xe=Oe.get(Le.id()),q=[],de=[];if(ze.isParent()){var ie=d.calcBoundingBox(ze,C[ae].xCoords,C[ae].yCoords,Oe);q.push(ie.topLeftX+ie.width/2),q.push(ie.topLeftY+ie.height/2)}else q.push(C[ae].xCoords[Ie]),q.push(C[ae].yCoords[Ie]);if(Le.isParent()){var oe=d.calcBoundingBox(Le,C[ae].xCoords,C[ae].yCoords,Oe);de.push(oe.topLeftX+oe.width/2),de.push(oe.topLeftY+oe.height/2)}else de.push(C[ae].xCoords[xe]),de.push(C[ae].yCoords[xe]);ye.edges.push({startX:q[0],startY:q[1],endX:de[0],endY:de[1]})}else R[ae][ze.id()]&&R[ae][Le.id()]&&ye.edges.push({startX:R[ae][ze.id()].getCenterX(),startY:R[ae][ze.id()].getCenterY(),endX:R[ae][Le.id()].getCenterX(),endY:R[ae][Le.id()].getCenterY()})}),ye.nodes.length>0&&(j.push(ye),Q.add(ae))}});var te=I.packComponents(j,w.randomize).shifts;if(w.quality=="draft")C.forEach(function(se,ae){var Oe=se.xCoords.map(function(Be){return Be+te[ae].dx}),ye=se.yCoords.map(function(Be){return Be+te[ae].dy});se.xCoords=Oe,se.yCoords=ye});else{var he=0;Q.forEach(function(se){Object.keys(R[se]).forEach(function(ae){var Oe=R[se][ae];Oe.setCenter(Oe.getCenterX()+te[he].dx,Oe.getCenterY()+te[he].dy)}),he++})}}}else{var P=w.eles.boundingBox();if(L.push({x:P.x1+P.w/2,y:P.y1+P.h/2}),w.randomize){var B=m(w);C.push(B)}w.quality=="default"||w.quality=="proof"?(R.push(y(w,C[0])),d.relocateComponent(L[0],R[0],w)):d.relocateComponent(L[0],C[0],w)}var le=o(function(ae,Oe){if(w.quality=="default"||w.quality=="proof"){typeof ae=="number"&&(ae=Oe);var ye=void 0,Be=void 0,He=ae.data("id");return R.forEach(function(Le){He in Le&&(ye={x:Le[He].getRect().getCenterX(),y:Le[He].getRect().getCenterY()},Be=Le[He])}),w.nodeDimensionsIncludeLabels&&(Be.labelWidth&&(Be.labelPosHorizontal=="left"?ye.x+=Be.labelWidth/2:Be.labelPosHorizontal=="right"&&(ye.x-=Be.labelWidth/2)),Be.labelHeight&&(Be.labelPosVertical=="top"?ye.y+=Be.labelHeight/2:Be.labelPosVertical=="bottom"&&(ye.y-=Be.labelHeight/2))),ye==null&&(ye={x:ae.position("x"),y:ae.position("y")}),{x:ye.x,y:ye.y}}else{var ze=void 0;return C.forEach(function(Le){var Ie=Le.nodeIndexes.get(ae.id());Ie!=null&&(ze={x:Le.xCoords[Ie],y:Le.yCoords[Ie]})}),ze==null&&(ze={x:ae.position("x"),y:ae.position("y")}),{x:ze.x,y:ze.y}}},"getPositions");if(w.quality=="default"||w.quality=="proof"||w.randomize){var J=d.calcParentsWithoutChildren(E,_),Se=_.filter(function(se){return se.css("display")=="none"});w.eles=_.not(Se),_.nodes().not(":parent").not(Se).layoutPositions(S,w,le),J.length>0&&J.forEach(function(se){se.position(le(se))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")},"run")}]),b}();a.exports=x},657:(a,s,l)=>{var u=l(548),h=l(140).layoutBase.Matrix,f=l(140).layoutBase.SVD,d=o(function(m){var g=m.cy,y=m.eles,v=y.nodes(),x=y.nodes(":parent"),b=new Map,T=new Map,S=new Map,w=[],E=[],_=[],C=[],D=[],O=[],R=[],k=[],L=void 0,A=void 0,I=1e8,M=1e-9,P=m.piTol,B=m.samplingType,F=m.nodeSeparation,z=void 0,$=o(function(){for(var Te=0,W=0,pe=!1;W=Pe;){be=ve[Pe++];for(var st=w[be],Ue=0;Ueqe&&(qe=D[We],at=We)}return at},"BFS"),K=o(function(Te){var W=void 0;if(Te){W=Math.floor(Math.random()*A),L=W;for(var ve=0;ve=1)break;qe=De}for(var st=0;st=1)break;qe=De}for(var ct=0;ct0&&(W.isParent()?w[Te].push(S.get(W.id())):w[Te].push(W.id()))})});var J=o(function(Te){var W=T.get(Te),pe=void 0;b.get(Te).forEach(function(ve){g.getElementById(ve).isParent()?pe=S.get(ve):pe=ve,w[W].push(pe),w[T.get(pe)].push(Te)})},"_loop"),Se=!0,se=!1,ae=void 0;try{for(var Oe=b.keys()[Symbol.iterator](),ye;!(Se=(ye=Oe.next()).done);Se=!0){var Be=ye.value;J(Be)}}catch(V){se=!0,ae=V}finally{try{!Se&&Oe.return&&Oe.return()}finally{if(se)throw ae}}A=T.size;var He=void 0;if(A>2){z=A{var u=l(212),h=o(function(d){d&&d("layout","fcose",u)},"register");typeof cytoscape<"u"&&h(cytoscape),a.exports=h},140:a=>{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(579);return i})()})});var xy,l0,t$=N(()=>{"use strict";jl();xy=o(t=>`${t}`,"wrapIcon"),l0={prefix:"mermaid-architecture",height:80,width:80,icons:{database:{body:xy('')},server:{body:xy('')},disk:{body:xy('')},internet:{body:xy('')},cloud:{body:xy('')},unknown:t7,blank:{body:xy("")}}}});var X2e,j2e,K2e,Q2e,Z2e=N(()=>{"use strict";jl();Gt();ao();N4();t$();AC();X2e=o(async function(t,e){let r=Mi("padding"),n=Mi("iconSize"),i=n/2,a=n/6,s=a/2;await Promise.all(e.edges().map(async l=>{let{source:u,sourceDir:h,sourceArrow:f,sourceGroup:d,target:p,targetDir:m,targetArrow:g,targetGroup:y,label:v}=CC(l),{x,y:b}=l[0].sourceEndpoint(),{x:T,y:S}=l[0].midpoint(),{x:w,y:E}=l[0].targetEndpoint(),_=r+4;if(d&&(ja(h)?x+=h==="L"?-_:_:b+=h==="T"?-_:_+18),y&&(ja(m)?w+=m==="L"?-_:_:E+=m==="T"?-_:_+18),!d&&o0.getNode(u)?.type==="junction"&&(ja(h)?x+=h==="L"?i:-i:b+=h==="T"?i:-i),!y&&o0.getNode(p)?.type==="junction"&&(ja(m)?w+=m==="L"?i:-i:E+=m==="T"?i:-i),l[0]._private.rscratch){let C=t.insert("g");if(C.insert("path").attr("d",`M ${x},${b} L ${T},${S} L${w},${E} `).attr("class","edge"),f){let D=ja(h)?D4[h](x,a):x-s,O=ru(h)?D4[h](b,a):b-s;C.insert("polygon").attr("points",YF[h](a)).attr("transform",`translate(${D},${O})`).attr("class","arrow")}if(g){let D=ja(m)?D4[m](w,a):w-s,O=ru(m)?D4[m](E,a):E-s;C.insert("polygon").attr("points",YF[m](a)).attr("transform",`translate(${D},${O})`).attr("class","arrow")}if(v){let D=L4(h,m)?"XY":ja(h)?"X":"Y",O=0;D==="X"?O=Math.abs(x-w):D==="Y"?O=Math.abs(b-E)/1.5:O=Math.abs(x-w)/2;let R=C.append("g");if(await qn(R,v,{useHtmlLabels:!1,width:O,classes:"architecture-service-label"},me()),R.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),D==="X")R.attr("transform","translate("+T+", "+S+")");else if(D==="Y")R.attr("transform","translate("+T+", "+S+") rotate(-90)");else if(D==="XY"){let k=R4(h,m);if(k&&O2e(k)){let L=R.node().getBoundingClientRect(),[A,I]=B2e(k);R.attr("dominant-baseline","auto").attr("transform",`rotate(${-1*A*I*45})`);let M=R.node().getBoundingClientRect();R.attr("transform",` + translate(${T}, ${S-L.height/2}) + translate(${A*M.width/2}, ${I*M.height/2}) + rotate(${-1*A*I*45}, 0, ${L.height/2}) + `)}}}}}))},"drawEdges"),j2e=o(async function(t,e){let n=Mi("padding")*.75,i=Mi("fontSize"),s=Mi("iconSize")/2;await Promise.all(e.nodes().map(async l=>{let u=Yf(l);if(u.type==="group"){let{h,w:f,x1:d,y1:p}=l.boundingBox();t.append("rect").attr("x",d+s).attr("y",p+s).attr("width",f).attr("height",h).attr("class","node-bkg");let m=t.append("g"),g=d,y=p;if(u.icon){let v=m.append("g");v.html(`${await Es(u.icon,{height:n,width:n,fallbackPrefix:l0.prefix})}`),v.attr("transform","translate("+(g+s+1)+", "+(y+s+1)+")"),g+=n,y+=i/2-1-2}if(u.label){let v=m.append("g");await qn(v,u.label,{useHtmlLabels:!1,width:f,classes:"architecture-service-label"},me()),v.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","start").attr("text-anchor","start"),v.attr("transform","translate("+(g+s+4)+", "+(y+s+2)+")")}}}))},"drawGroups"),K2e=o(async function(t,e,r){for(let n of r){let i=e.append("g"),a=Mi("iconSize");if(n.title){let h=i.append("g");await qn(h,n.title,{useHtmlLabels:!1,width:a*1.5,classes:"architecture-service-label"},me()),h.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),h.attr("transform","translate("+a/2+", "+a+")")}let s=i.append("g");if(n.icon)s.html(`${await Es(n.icon,{height:a,width:a,fallbackPrefix:l0.prefix})}`);else if(n.iconText){s.html(`${await Es("blank",{height:a,width:a,fallbackPrefix:l0.prefix})}`);let d=s.append("g").append("foreignObject").attr("width",a).attr("height",a).append("div").attr("class","node-icon-text").attr("style",`height: ${a}px;`).append("div").html(n.iconText),p=parseInt(window.getComputedStyle(d.node(),null).getPropertyValue("font-size").replace(/\D/g,""))??16;d.attr("style",`-webkit-line-clamp: ${Math.floor((a-2)/p)};`)}else s.append("path").attr("class","node-bkg").attr("id","node-"+n.id).attr("d",`M0 ${a} v${-a} q0,-5 5,-5 h${a} q5,0 5,5 v${a} H0 Z`);i.attr("class","architecture-service");let{width:l,height:u}=i._groups[0][0].getBBox();n.width=l,n.height=u,t.setElementForId(n.id,i)}return 0},"drawServices"),Q2e=o(function(t,e,r){r.forEach(n=>{let i=e.append("g"),a=Mi("iconSize");i.append("g").append("rect").attr("id","node-"+n.id).attr("fill-opacity","0").attr("width",a).attr("height",a),i.attr("class","architecture-junction");let{width:l,height:u}=i._groups[0][0].getBBox();i.width=l,i.height=u,t.setElementForId(n.id,i)})},"drawJunctions")});function Hnt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"service",id:r.id,icon:r.icon,label:r.title,parent:r.in,width:Mi("iconSize"),height:Mi("iconSize")},classes:"node-service"})})}function Wnt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"junction",id:r.id,parent:r.in,width:Mi("iconSize"),height:Mi("iconSize")},classes:"node-junction"})})}function qnt(t,e){e.nodes().map(r=>{let n=Yf(r);if(n.type==="group")return;n.x=r.position().x,n.y=r.position().y,t.getElementById(n.id).attr("transform","translate("+(n.x||0)+","+(n.y||0)+")")})}function Ynt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"group",id:r.id,icon:r.icon,label:r.title,parent:r.in},classes:"node-group"})})}function Xnt(t,e){t.forEach(r=>{let{lhsId:n,rhsId:i,lhsInto:a,lhsGroup:s,rhsInto:l,lhsDir:u,rhsDir:h,rhsGroup:f,title:d}=r,p=L4(r.lhsDir,r.rhsDir)?"segments":"straight",m={id:`${n}-${i}`,label:d,source:n,sourceDir:u,sourceArrow:a,sourceGroup:s,sourceEndpoint:u==="L"?"0 50%":u==="R"?"100% 50%":u==="T"?"50% 0":"50% 100%",target:i,targetDir:h,targetArrow:l,targetGroup:f,targetEndpoint:h==="L"?"0 50%":h==="R"?"100% 50%":h==="T"?"50% 0":"50% 100%"};e.add({group:"edges",data:m,classes:p})})}function jnt(t,e,r){let n=o((l,u)=>Object.entries(l).reduce((h,[f,d])=>{let p=0,m=Object.entries(d);if(m.length===1)return h[f]=m[0][1],h;for(let g=0;g{let u={},h={};return Object.entries(l).forEach(([f,[d,p]])=>{let m=t.getNode(f)?.in??"default";u[p]??={},u[p][m]??=[],u[p][m].push(f),h[d]??={},h[d][m]??=[],h[d][m].push(f)}),{horiz:Object.values(n(u,"horizontal")).filter(f=>f.length>1),vert:Object.values(n(h,"vertical")).filter(f=>f.length>1)}}),[a,s]=i.reduce(([l,u],{horiz:h,vert:f})=>[[...l,...h],[...u,...f]],[[],[]]);return{horizontal:a,vertical:s}}function Knt(t){let e=[],r=o(i=>`${i[0]},${i[1]}`,"posToStr"),n=o(i=>i.split(",").map(a=>parseInt(a)),"strToPos");return t.forEach(i=>{let a=Object.fromEntries(Object.entries(i).map(([h,f])=>[r(f),h])),s=[r([0,0])],l={},u={L:[-1,0],R:[1,0],T:[0,1],B:[0,-1]};for(;s.length>0;){let h=s.shift();if(h){l[h]=1;let f=a[h];if(f){let d=n(h);Object.entries(u).forEach(([p,m])=>{let g=r([d[0]+m[0],d[1]+m[1]]),y=a[g];y&&!l[g]&&(s.push(g),e.push({[qF[p]]:y,[qF[I2e(p)]]:f,gap:1.5*Mi("iconSize")}))})}}}}),e}function Qnt(t,e,r,n,i,{spatialMaps:a,groupAlignments:s}){return new Promise(l=>{let u=Ge("body").append("div").attr("id","cy").attr("style","display:none"),h=sl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"straight",label:"data(label)","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"edge.segments",style:{"curve-style":"segments","segment-weights":"0","segment-distances":[.5],"edge-distances":"endpoints","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"node",style:{"compound-sizing-wrt-labels":"include"}},{selector:"node[label]",style:{"text-valign":"bottom","text-halign":"center","font-size":`${Mi("fontSize")}px`}},{selector:".node-service",style:{label:"data(label)",width:"data(width)",height:"data(height)"}},{selector:".node-junction",style:{width:"data(width)",height:"data(height)"}},{selector:".node-group",style:{padding:`${Mi("padding")}px`}}],layout:{name:"grid",boundingBox:{x1:0,x2:100,y1:0,y2:100}}});u.remove(),Ynt(r,h),Hnt(t,h),Wnt(e,h),Xnt(n,h);let f=jnt(i,a,s),d=Knt(a),p=h.layout({name:"fcose",quality:"proof",styleEnabled:!1,animate:!1,nodeDimensionsIncludeLabels:!1,idealEdgeLength(m){let[g,y]=m.connectedNodes(),{parent:v}=Yf(g),{parent:x}=Yf(y);return v===x?1.5*Mi("iconSize"):.5*Mi("iconSize")},edgeElasticity(m){let[g,y]=m.connectedNodes(),{parent:v}=Yf(g),{parent:x}=Yf(y);return v===x?.45:.001},alignmentConstraint:f,relativePlacementConstraint:d});p.one("layoutstop",()=>{function m(g,y,v,x){let b,T,{x:S,y:w}=g,{x:E,y:_}=y;T=(x-w+(S-v)*(w-_)/(S-E))/Math.sqrt(1+Math.pow((w-_)/(S-E),2)),b=Math.sqrt(Math.pow(x-w,2)+Math.pow(v-S,2)-Math.pow(T,2));let C=Math.sqrt(Math.pow(E-S,2)+Math.pow(_-w,2));b=b/C;let D=(E-S)*(x-w)-(_-w)*(v-S);switch(!0){case D>=0:D=1;break;case D<0:D=-1;break}let O=(E-S)*(v-S)+(_-w)*(x-w);switch(!0){case O>=0:O=1;break;case O<0:O=-1;break}return T=Math.abs(T)*D,b=b*O,{distances:T,weights:b}}o(m,"getSegmentWeights"),h.startBatch();for(let g of Object.values(h.edges()))if(g.data?.()){let{x:y,y:v}=g.source().position(),{x,y:b}=g.target().position();if(y!==x&&v!==b){let T=g.sourceEndpoint(),S=g.targetEndpoint(),{sourceDir:w}=CC(g),[E,_]=ru(w)?[T.x,S.y]:[S.x,T.y],{weights:C,distances:D}=m(T,S,E,_);g.style("segment-distances",D),g.style("segment-weights",C)}}h.endBatch(),p.run()}),p.run(),h.ready(m=>{X.info("Ready",m),l(h)})})}var J2e,Znt,exe,txe=N(()=>{"use strict";jl();oF();J2e=Aa(Y2e(),1);fr();yt();Vl();xi();N4();t$();AC();Z2e();X4([{name:l0.prefix,icons:l0}]);sl.use(J2e.default);o(Hnt,"addServices");o(Wnt,"addJunctions");o(qnt,"positionNodes");o(Ynt,"addGroups");o(Xnt,"addEdges");o(jnt,"getAlignments");o(Knt,"getRelativeConstraints");o(Qnt,"layoutArchitecture");Znt=o(async(t,e,r,n)=>{let i=n.db,a=i.getServices(),s=i.getJunctions(),l=i.getGroups(),u=i.getEdges(),h=i.getDataStructures(),f=Li(e),d=f.append("g");d.attr("class","architecture-edges");let p=f.append("g");p.attr("class","architecture-services");let m=f.append("g");m.attr("class","architecture-groups"),await K2e(i,p,a),Q2e(i,p,s);let g=await Qnt(a,s,l,u,i,h);await X2e(d,g),await j2e(m,g),qnt(i,g),Lo(void 0,f,Mi("padding"),Mi("useMaxWidth"))},"draw"),exe={draw:Znt}});var rxe={};ur(rxe,{diagram:()=>Jnt});var Jnt,nxe=N(()=>{"use strict";H2e();N4();q2e();txe();Jnt={parser:U2e,db:o0,renderer:exe,styles:W2e}});var by,r$=N(()=>{"use strict";_a();mi();er();zt();ci();by=class{constructor(){this.nodes=[];this.levels=new Map;this.outerNodes=[];this.classes=new Map;this.setAccTitle=Ar;this.getAccTitle=Dr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getAccDescription=Rr;this.setAccDescription=Lr}static{o(this,"TreeMapDB")}getNodes(){return this.nodes}getConfig(){let e=or,r=tr();return $n({...e.treemap,...r.treemap??{}})}addNode(e,r){this.nodes.push(e),this.levels.set(e,r),r===0&&(this.outerNodes.push(e),this.root??=e)}getRoot(){return{name:"",children:this.outerNodes}}addClass(e,r){let n=this.classes.get(e)??{id:e,styles:[],textStyles:[]},i=r.replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");i&&i.forEach(a=>{S2(a)&&(n?.textStyles?n.textStyles.push(a):n.textStyles=[a]),n?.styles?n.styles.push(a):n.styles=[a]}),this.classes.set(e,n)}getClasses(){return this.classes}getStylesForClass(e){return this.classes.get(e)?.styles??[]}clear(){kr(),this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.root=void 0}}});function sxe(t){if(!t.length)return[];let e=[],r=[];return t.forEach(n=>{let i={name:n.name,children:n.type==="Leaf"?void 0:[]};for(i.classSelector=n?.classSelector,n?.cssCompiledStyles&&(i.cssCompiledStyles=[n.cssCompiledStyles]),n.type==="Leaf"&&n.value!==void 0&&(i.value=n.value);r.length>0&&r[r.length-1].level>=n.level;)r.pop();if(r.length===0)e.push(i);else{let a=r[r.length-1].node;a.children?a.children.push(i):a.children=[i]}n.type!=="Leaf"&&r.push({node:i,level:n.level})}),e}var oxe=N(()=>{"use strict";o(sxe,"buildHierarchy")});var nit,iit,n$,lxe=N(()=>{"use strict";bf();yt();Mp();oxe();r$();nit=o((t,e)=>{Jo(t,e);let r=[];for(let a of t.TreemapRows??[])a.$type==="ClassDefStatement"&&e.addClass(a.className??"",a.styleText??"");for(let a of t.TreemapRows??[]){let s=a.item;if(!s)continue;let l=a.indent?parseInt(a.indent):0,u=iit(s),h=s.classSelector?e.getStylesForClass(s.classSelector):[],f=h.length>0?h.join(";"):void 0,d={level:l,name:u,type:s.$type,value:s.value,classSelector:s.classSelector,cssCompiledStyles:f};r.push(d)}let n=sxe(r),i=o((a,s)=>{for(let l of a)e.addNode(l,s),l.children&&l.children.length>0&&i(l.children,s+1)},"addNodesRecursively");i(n,0)},"populate"),iit=o(t=>t.name?String(t.name):"","getItemName"),n$={parser:{yy:void 0},parse:o(async t=>{try{let r=await vs("treemap",t);X.debug("Treemap AST:",r);let n=n$.parser?.yy;if(!(n instanceof by))throw new Error("parser.parser?.yy was not a TreemapDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");nit(r,n)}catch(e){throw X.error("Error parsing treemap:",e),e}},"parse")}});var ait,Ty,P4,sit,oit,cxe,uxe=N(()=>{"use strict";Vl();np();xi();fr();zt();mi();yt();ait=10,Ty=10,P4=25,sit=o((t,e,r,n)=>{let i=n.db,a=i.getConfig(),s=a.padding??ait,l=i.getDiagramTitle(),u=i.getRoot(),{themeVariables:h}=tr();if(!u)return;let f=l?30:0,d=Li(e),p=a.nodeWidth?a.nodeWidth*Ty:960,m=a.nodeHeight?a.nodeHeight*Ty:500,g=p,y=m+f;d.attr("viewBox",`0 0 ${g} ${y}`),fn(d,y,g,a.useMaxWidth);let v;try{let A=a.valueFormat||",";if(A==="$0,0")v=o(I=>"$"+cc(",")(I),"valueFormat");else if(A.startsWith("$")&&A.includes(",")){let I=/\.\d+/.exec(A),M=I?I[0]:"";v=o(P=>"$"+cc(","+M)(P),"valueFormat")}else if(A.startsWith("$")){let I=A.substring(1);v=o(M=>"$"+cc(I||"")(M),"valueFormat")}else v=cc(A)}catch(A){X.error("Error creating format function:",A),v=cc(",")}let x=Js().range(["transparent",h.cScale0,h.cScale1,h.cScale2,h.cScale3,h.cScale4,h.cScale5,h.cScale6,h.cScale7,h.cScale8,h.cScale9,h.cScale10,h.cScale11]),b=Js().range(["transparent",h.cScalePeer0,h.cScalePeer1,h.cScalePeer2,h.cScalePeer3,h.cScalePeer4,h.cScalePeer5,h.cScalePeer6,h.cScalePeer7,h.cScalePeer8,h.cScalePeer9,h.cScalePeer10,h.cScalePeer11]),T=Js().range([h.cScaleLabel0,h.cScaleLabel1,h.cScaleLabel2,h.cScaleLabel3,h.cScaleLabel4,h.cScaleLabel5,h.cScaleLabel6,h.cScaleLabel7,h.cScaleLabel8,h.cScaleLabel9,h.cScaleLabel10,h.cScaleLabel11]);l&&d.append("text").attr("x",g/2).attr("y",f/2).attr("class","treemapTitle").attr("text-anchor","middle").attr("dominant-baseline","middle").text(l);let S=d.append("g").attr("transform",`translate(0, ${f})`).attr("class","treemapContainer"),w=z0(u).sum(A=>A.value??0).sort((A,I)=>(I.value??0)-(A.value??0)),_=D5().size([p,m]).paddingTop(A=>A.children&&A.children.length>0?P4+Ty:0).paddingInner(s).paddingLeft(A=>A.children&&A.children.length>0?Ty:0).paddingRight(A=>A.children&&A.children.length>0?Ty:0).paddingBottom(A=>A.children&&A.children.length>0?Ty:0).round(!0)(w),C=_.descendants().filter(A=>A.children&&A.children.length>0),D=S.selectAll(".treemapSection").data(C).enter().append("g").attr("class","treemapSection").attr("transform",A=>`translate(${A.x0},${A.y0})`);D.append("rect").attr("width",A=>A.x1-A.x0).attr("height",P4).attr("class","treemapSectionHeader").attr("fill","none").attr("fill-opacity",.6).attr("stroke-width",.6).attr("style",A=>A.depth===0?"display: none;":""),D.append("clipPath").attr("id",(A,I)=>`clip-section-${e}-${I}`).append("rect").attr("width",A=>Math.max(0,A.x1-A.x0-12)).attr("height",P4),D.append("rect").attr("width",A=>A.x1-A.x0).attr("height",A=>A.y1-A.y0).attr("class",(A,I)=>`treemapSection section${I}`).attr("fill",A=>x(A.data.name)).attr("fill-opacity",.6).attr("stroke",A=>b(A.data.name)).attr("stroke-width",2).attr("stroke-opacity",.4).attr("style",A=>{if(A.depth===0)return"display: none;";let I=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I.nodeStyles+";"+I.borderStyles.join(";")}),D.append("text").attr("class","treemapSectionLabel").attr("x",6).attr("y",P4/2).attr("dominant-baseline","middle").text(A=>A.depth===0?"":A.data.name).attr("font-weight","bold").attr("style",A=>{if(A.depth===0)return"display: none;";let I="dominant-baseline: middle; font-size: 12px; fill:"+T(A.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")}).each(function(A){if(A.depth===0)return;let I=Ge(this),M=A.data.name;I.text(M);let P=A.x1-A.x0,B=6,F;a.showValues!==!1&&A.value?F=P-10-30-10-B:F=P-B-6;let $=Math.max(15,F),U=I.node();if(U.getComputedTextLength()>$){let ee="...",Y=M;for(;Y.length>0;){if(Y=M.substring(0,Y.length-1),Y.length===0){I.text(ee),U.getComputedTextLength()>$&&I.text("");break}if(I.text(Y+ee),U.getComputedTextLength()<=$)break}}}),a.showValues!==!1&&D.append("text").attr("class","treemapSectionValue").attr("x",A=>A.x1-A.x0-10).attr("y",P4/2).attr("text-anchor","end").attr("dominant-baseline","middle").text(A=>A.value?v(A.value):"").attr("font-style","italic").attr("style",A=>{if(A.depth===0)return"display: none;";let I="text-anchor: end; dominant-baseline: middle; font-size: 10px; fill:"+T(A.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")});let O=_.leaves(),R=S.selectAll(".treemapLeafGroup").data(O).enter().append("g").attr("class",(A,I)=>`treemapNode treemapLeafGroup leaf${I}${A.data.classSelector?` ${A.data.classSelector}`:""}x`).attr("transform",A=>`translate(${A.x0},${A.y0})`);R.append("rect").attr("width",A=>A.x1-A.x0).attr("height",A=>A.y1-A.y0).attr("class","treemapLeaf").attr("fill",A=>A.parent?x(A.parent.data.name):x(A.data.name)).attr("style",A=>Ye({cssCompiledStyles:A.data.cssCompiledStyles}).nodeStyles).attr("fill-opacity",.3).attr("stroke",A=>A.parent?x(A.parent.data.name):x(A.data.name)).attr("stroke-width",3),R.append("clipPath").attr("id",(A,I)=>`clip-${e}-${I}`).append("rect").attr("width",A=>Math.max(0,A.x1-A.x0-4)).attr("height",A=>Math.max(0,A.y1-A.y0-4)),R.append("text").attr("class","treemapLabel").attr("x",A=>(A.x1-A.x0)/2).attr("y",A=>(A.y1-A.y0)/2).attr("style",A=>{let I="text-anchor: middle; dominant-baseline: middle; font-size: 38px;fill:"+T(A.data.name)+";",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")}).attr("clip-path",(A,I)=>`url(#clip-${e}-${I})`).text(A=>A.data.name).each(function(A){let I=Ge(this),M=A.x1-A.x0,P=A.y1-A.y0,B=I.node(),F=4,z=M-2*F,$=P-2*F;if(z<10||$<10){I.style("display","none");return}let U=parseInt(I.style("font-size"),10),K=8,ee=28,Y=.6,ce=6,Z=2;for(;B.getComputedTextLength()>z&&U>K;)U--,I.style("font-size",`${U}px`);let ue=Math.max(ce,Math.min(ee,Math.round(U*Y))),Q=U+Z+ue;for(;Q>$&&U>K&&(U--,ue=Math.max(ce,Math.min(ee,Math.round(U*Y))),!(ue$;I.style("font-size",`${U}px`),(B.getComputedTextLength()>z||U(I.x1-I.x0)/2).attr("y",function(I){return(I.y1-I.y0)/2}).attr("style",I=>{let M="text-anchor: middle; dominant-baseline: hanging; font-size: 28px;fill:"+T(I.data.name)+";",P=Ye({cssCompiledStyles:I.data.cssCompiledStyles});return M+P.labelStyles.replace("color:","fill:")}).attr("clip-path",(I,M)=>`url(#clip-${e}-${M})`).text(I=>I.value?v(I.value):"").each(function(I){let M=Ge(this),P=this.parentNode;if(!P){M.style("display","none");return}let B=Ge(P).select(".treemapLabel");if(B.empty()||B.style("display")==="none"){M.style("display","none");return}let F=parseFloat(B.style("font-size")),z=28,$=.6,U=6,K=2,ee=Math.max(U,Math.min(z,Math.round(F*$)));M.style("font-size",`${ee}px`);let ce=(I.y1-I.y0)/2+F/2+K;M.attr("y",ce);let Z=I.x1-I.x0,j=I.y1-I.y0-4,ne=Z-2*4;M.node().getComputedTextLength()>ne||ce+ee>j||ee{"use strict";er();lit={sectionStrokeColor:"black",sectionStrokeWidth:"1",sectionFillColor:"#efefef",leafStrokeColor:"black",leafStrokeWidth:"1",leafFillColor:"#efefef",labelColor:"black",labelFontSize:"12px",valueFontSize:"10px",valueColor:"black",titleColor:"black",titleFontSize:"14px"},cit=o(({treemap:t}={})=>{let e=$n(lit,t);return` + .treemapNode.section { + stroke: ${e.sectionStrokeColor}; + stroke-width: ${e.sectionStrokeWidth}; + fill: ${e.sectionFillColor}; + } + .treemapNode.leaf { + stroke: ${e.leafStrokeColor}; + stroke-width: ${e.leafStrokeWidth}; + fill: ${e.leafFillColor}; + } + .treemapLabel { + fill: ${e.labelColor}; + font-size: ${e.labelFontSize}; + } + .treemapValue { + fill: ${e.valueColor}; + font-size: ${e.valueFontSize}; + } + .treemapTitle { + fill: ${e.titleColor}; + font-size: ${e.titleFontSize}; + } + `},"getStyles"),hxe=cit});var dxe={};ur(dxe,{diagram:()=>uit});var uit,pxe=N(()=>{"use strict";r$();lxe();uxe();fxe();uit={parser:n$,get db(){return new by},renderer:cxe,styles:hxe}});var Kit={};ur(Kit,{default:()=>jit});jl();r7();rd();var cK="c4",lAe=o(t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),"detector"),cAe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(lK(),oK));return{id:cK,diagram:t}},"loader"),uAe={id:cK,detector:lAe,loader:cAe},uK=uAe;var use="flowchart",qPe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-wrapper"||e?.flowchart?.defaultRenderer==="elk"?!1:/^\s*graph/.test(t),"detector"),YPe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:use,diagram:t}},"loader"),XPe={id:use,detector:qPe,loader:YPe},hse=XPe;var fse="flowchart-v2",jPe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-d3"?!1:(e?.flowchart?.defaultRenderer==="elk"&&(e.layout="elk"),/^\s*graph/.test(t)&&e?.flowchart?.defaultRenderer==="dagre-wrapper"?!0:/^\s*flowchart/.test(t)),"detector"),KPe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:fse,diagram:t}},"loader"),QPe={id:fse,detector:jPe,loader:KPe},dse=QPe;var wse="er",rBe=o(t=>/^\s*erDiagram/.test(t),"detector"),nBe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Tse(),bse));return{id:wse,diagram:t}},"loader"),iBe={id:wse,detector:rBe,loader:nBe},kse=iBe;var Lhe="gitGraph",IGe=o(t=>/^\s*gitGraph/.test(t),"detector"),OGe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Dhe(),_he));return{id:Lhe,diagram:t}},"loader"),PGe={id:Lhe,detector:IGe,loader:OGe},Rhe=PGe;var ofe="gantt",kVe=o(t=>/^\s*gantt/.test(t),"detector"),EVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(sfe(),afe));return{id:ofe,diagram:t}},"loader"),SVe={id:ofe,detector:kVe,loader:EVe},lfe=SVe;var yfe="info",RVe=o(t=>/^\s*info/.test(t),"detector"),NVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(gfe(),mfe));return{id:yfe,diagram:t}},"loader"),vfe={id:yfe,detector:RVe,loader:NVe};var _fe="pie",WVe=o(t=>/^\s*pie/.test(t),"detector"),qVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Afe(),Cfe));return{id:_fe,diagram:t}},"loader"),Dfe={id:_fe,detector:WVe,loader:qVe};var Vfe="quadrantChart",uUe=o(t=>/^\s*quadrantChart/.test(t),"detector"),hUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Gfe(),zfe));return{id:Vfe,diagram:t}},"loader"),fUe={id:Vfe,detector:uUe,loader:hUe},Ufe=fUe;var gde="xychart",DUe=o(t=>/^\s*xychart-beta/.test(t),"detector"),LUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(mde(),pde));return{id:gde,diagram:t}},"loader"),RUe={id:gde,detector:DUe,loader:LUe},yde=RUe;var Cde="requirement",OUe=o(t=>/^\s*requirement(Diagram)?/.test(t),"detector"),PUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Sde(),Ede));return{id:Cde,diagram:t}},"loader"),BUe={id:Cde,detector:OUe,loader:PUe},Ade=BUe;var Yde="sequence",bHe=o(t=>/^\s*sequenceDiagram/.test(t),"detector"),THe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(qde(),Wde));return{id:Yde,diagram:t}},"loader"),wHe={id:Yde,detector:bHe,loader:THe},Xde=wHe;var epe="class",_He=o((t,e)=>e?.class?.defaultRenderer==="dagre-wrapper"?!1:/^\s*classDiagram/.test(t),"detector"),DHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Jde(),Zde));return{id:epe,diagram:t}},"loader"),LHe={id:epe,detector:_He,loader:DHe},tpe=LHe;var ipe="classDiagram",NHe=o((t,e)=>/^\s*classDiagram/.test(t)&&e?.class?.defaultRenderer==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(t),"detector"),MHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(npe(),rpe));return{id:ipe,diagram:t}},"loader"),IHe={id:ipe,detector:NHe,loader:MHe},ape=IHe;var Ppe="state",aWe=o((t,e)=>e?.state?.defaultRenderer==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(t),"detector"),sWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Ope(),Ipe));return{id:Ppe,diagram:t}},"loader"),oWe={id:Ppe,detector:aWe,loader:sWe},Bpe=oWe;var zpe="stateDiagram",cWe=o((t,e)=>!!(/^\s*stateDiagram-v2/.test(t)||/^\s*stateDiagram/.test(t)&&e?.state?.defaultRenderer==="dagre-wrapper"),"detector"),uWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>($pe(),Fpe));return{id:zpe,diagram:t}},"loader"),hWe={id:zpe,detector:cWe,loader:uWe},Gpe=hWe;var n0e="journey",NWe=o(t=>/^\s*journey/.test(t),"detector"),MWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(r0e(),t0e));return{id:n0e,diagram:t}},"loader"),IWe={id:n0e,detector:NWe,loader:MWe},i0e=IWe;yt();Vl();xi();var OWe=o((t,e,r)=>{X.debug(`rendering svg for syntax error +`);let n=Li(e),i=n.append("g");n.attr("viewBox","0 0 2412 512"),fn(n,100,512,!0),i.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),i.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),i.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),i.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),i.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),i.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),i.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),i.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw"),QP={draw:OWe},a0e=QP;var PWe={db:{},renderer:QP,parser:{parse:o(()=>{},"parse")}},s0e=PWe;var o0e="flowchart-elk",BWe=o((t,e={})=>/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&e?.flowchart?.defaultRenderer==="elk"?(e.layout="elk",!0):!1,"detector"),FWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:o0e,diagram:t}},"loader"),$We={id:o0e,detector:BWe,loader:FWe},l0e=$We;var I0e="timeline",iqe=o(t=>/^\s*timeline/.test(t),"detector"),aqe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(M0e(),N0e));return{id:I0e,diagram:t}},"loader"),sqe={id:I0e,detector:iqe,loader:aqe},O0e=sqe;var uye="mindmap",Let=o(t=>/^\s*mindmap/.test(t),"detector"),Ret=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(cye(),lye));return{id:uye,diagram:t}},"loader"),Net={id:uye,detector:Let,loader:Ret},hye=Net;var kye="kanban",Xet=o(t=>/^\s*kanban/.test(t),"detector"),jet=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(wye(),Tye));return{id:kye,diagram:t}},"loader"),Ket={id:kye,detector:Xet,loader:jet},Eye=Ket;var ave="sankey",xtt=o(t=>/^\s*sankey-beta/.test(t),"detector"),btt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ive(),nve));return{id:ave,diagram:t}},"loader"),Ttt={id:ave,detector:xtt,loader:btt},sve=Ttt;var gve="packet",Itt=o(t=>/^\s*packet(-beta)?/.test(t),"detector"),Ott=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(mve(),pve));return{id:gve,diagram:t}},"loader"),yve={id:gve,detector:Itt,loader:Ott};var _ve="radar",nrt=o(t=>/^\s*radar-beta/.test(t),"detector"),irt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Ave(),Cve));return{id:_ve,diagram:t}},"loader"),Dve={id:_ve,detector:nrt,loader:irt};var N2e="block",Snt=o(t=>/^\s*block-beta/.test(t),"detector"),Cnt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(R2e(),L2e));return{id:N2e,diagram:t}},"loader"),Ant={id:N2e,detector:Snt,loader:Cnt},M2e=Ant;var ixe="architecture",eit=o(t=>/^\s*architecture/.test(t),"detector"),tit=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(nxe(),rxe));return{id:ixe,diagram:t}},"loader"),rit={id:ixe,detector:eit,loader:tit},axe=rit;rd();Gt();var mxe="treemap",hit=o(t=>/^\s*treemap/.test(t),"detector"),fit=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(pxe(),dxe));return{id:mxe,diagram:t}},"loader"),gxe={id:mxe,detector:hit,loader:fit};var yxe=!1,wy=o(()=>{yxe||(yxe=!0,dd("error",s0e,t=>t.toLowerCase().trim()==="error"),dd("---",{db:{clear:o(()=>{},"clear")},styles:{},renderer:{draw:o(()=>{},"draw")},parser:{parse:o(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:o(()=>null,"init")},t=>t.toLowerCase().trimStart().startsWith("---")),Ly(l0e,hye,axe),Ly(uK,Eye,ape,tpe,kse,lfe,vfe,Dfe,Ade,Xde,dse,hse,O0e,Rhe,Gpe,Bpe,i0e,Ufe,sve,yve,yde,M2e,Dve,gxe))},"addDiagrams");yt();rd();Gt();var vxe=o(async()=>{X.debug("Loading registered diagrams");let e=(await Promise.allSettled(Object.entries(au).map(async([r,{detector:n,loader:i}])=>{if(i)try{iv(r)}catch{try{let{diagram:a,id:s}=await i();dd(s,a,n)}catch(a){throw X.error(`Failed to load external diagram with key ${r}. Removing from detectors.`),delete au[r],a}}}))).filter(r=>r.status==="rejected");if(e.length>0){X.error(`Failed to load ${e.length} external diagrams`);for(let r of e)X.error(r);throw new Error(`Failed to load ${e.length} external diagrams`)}},"loadRegisteredDiagrams");yt();fr();var _C="comm",DC="rule",LC="decl";var xxe="@import";var bxe="@namespace",Txe="@keyframes";var wxe="@layer";var i$=Math.abs,B4=String.fromCharCode;function RC(t){return t.trim()}o(RC,"trim");function F4(t,e,r){return t.replace(e,r)}o(F4,"replace");function kxe(t,e,r){return t.indexOf(e,r)}o(kxe,"indexof");function Xf(t,e){return t.charCodeAt(e)|0}o(Xf,"charat");function jf(t,e,r){return t.slice(e,r)}o(jf,"substr");function To(t){return t.length}o(To,"strlen");function Exe(t){return t.length}o(Exe,"sizeof");function ky(t,e){return e.push(t),t}o(ky,"append");var NC=1,Ey=1,Sxe=0,ll=0,Ii=0,Cy="";function MC(t,e,r,n,i,a,s,l){return{value:t,root:e,parent:r,type:n,props:i,children:a,line:NC,column:Ey,length:s,return:"",siblings:l}}o(MC,"node");function Cxe(){return Ii}o(Cxe,"char");function Axe(){return Ii=ll>0?Xf(Cy,--ll):0,Ey--,Ii===10&&(Ey=1,NC--),Ii}o(Axe,"prev");function cl(){return Ii=ll2||Sy(Ii)>3?"":" "}o(Lxe,"whitespace");function Rxe(t,e){for(;--e&&cl()&&!(Ii<48||Ii>102||Ii>57&&Ii<65||Ii>70&&Ii<97););return IC(t,$4()+(e<6&&lh()==32&&cl()==32))}o(Rxe,"escaping");function a$(t){for(;cl();)switch(Ii){case t:return ll;case 34:case 39:t!==34&&t!==39&&a$(Ii);break;case 40:t===41&&a$(t);break;case 92:cl();break}return ll}o(a$,"delimiter");function Nxe(t,e){for(;cl()&&t+Ii!==57;)if(t+Ii===84&&lh()===47)break;return"/*"+IC(e,ll-1)+"*"+B4(t===47?t:cl())}o(Nxe,"commenter");function Mxe(t){for(;!Sy(lh());)cl();return IC(t,ll)}o(Mxe,"identifier");function Pxe(t){return Dxe(PC("",null,null,null,[""],t=_xe(t),0,[0],t))}o(Pxe,"compile");function PC(t,e,r,n,i,a,s,l,u){for(var h=0,f=0,d=s,p=0,m=0,g=0,y=1,v=1,x=1,b=0,T="",S=i,w=a,E=n,_=T;v;)switch(g=b,b=cl()){case 40:if(g!=108&&Xf(_,d-1)==58){kxe(_+=F4(OC(b),"&","&\f"),"&\f",i$(h?l[h-1]:0))!=-1&&(x=-1);break}case 34:case 39:case 91:_+=OC(b);break;case 9:case 10:case 13:case 32:_+=Lxe(g);break;case 92:_+=Rxe($4()-1,7);continue;case 47:switch(lh()){case 42:case 47:ky(dit(Nxe(cl(),$4()),e,r,u),u),(Sy(g||1)==5||Sy(lh()||1)==5)&&To(_)&&jf(_,-1,void 0)!==" "&&(_+=" ");break;default:_+="/"}break;case 123*y:l[h++]=To(_)*x;case 125*y:case 59:case 0:switch(b){case 0:case 125:v=0;case 59+f:x==-1&&(_=F4(_,/\f/g,"")),m>0&&(To(_)-d||y===0&&g===47)&&ky(m>32?Oxe(_+";",n,r,d-1,u):Oxe(F4(_," ","")+";",n,r,d-2,u),u);break;case 59:_+=";";default:if(ky(E=Ixe(_,e,r,h,f,i,l,T,S=[],w=[],d,a),a),b===123)if(f===0)PC(_,e,E,E,S,a,d,l,w);else{switch(p){case 99:if(Xf(_,3)===110)break;case 108:if(Xf(_,2)===97)break;default:f=0;case 100:case 109:case 115:}f?PC(t,E,E,n&&ky(Ixe(t,E,E,0,0,i,l,T,i,S=[],d,w),w),i,w,d,l,n?S:w):PC(_,E,E,E,[""],w,0,l,w)}}h=f=m=0,y=x=1,T=_="",d=s;break;case 58:d=1+To(_),m=g;default:if(y<1){if(b==123)--y;else if(b==125&&y++==0&&Axe()==125)continue}switch(_+=B4(b),b*y){case 38:x=f>0?1:(_+="\f",-1);break;case 44:l[h++]=(To(_)-1)*x,x=1;break;case 64:lh()===45&&(_+=OC(cl())),p=lh(),f=d=To(T=_+=Mxe($4())),b++;break;case 45:g===45&&To(_)==2&&(y=0)}}return a}o(PC,"parse");function Ixe(t,e,r,n,i,a,s,l,u,h,f,d){for(var p=i-1,m=i===0?a:[""],g=Exe(m),y=0,v=0,x=0;y0?m[b]+" "+T:F4(T,/&\f/g,m[b])))&&(u[x++]=S);return MC(t,e,r,i===0?DC:l,u,h,f,d)}o(Ixe,"ruleset");function dit(t,e,r,n){return MC(t,e,r,_C,B4(Cxe()),jf(t,2,-2),0,n)}o(dit,"comment");function Oxe(t,e,r,n,i){return MC(t,e,r,LC,jf(t,0,n),jf(t,n+1,-1),n,i)}o(Oxe,"declaration");function BC(t,e){for(var r="",n=0;n{zxe.forEach(t=>{t()}),zxe=[]},"attachFunctions");yt();var Vxe=o(t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart(),"cleanupComments");Q4();PT();function Uxe(t){let e=t.match(K4);if(!e)return{text:t,metadata:{}};let r=Tm(e[1],{schema:bm})??{};r=typeof r=="object"&&!Array.isArray(r)?r:{};let n={};return r.displayMode&&(n.displayMode=r.displayMode.toString()),r.title&&(n.title=r.title.toString()),r.config&&(n.config=r.config),{text:t.slice(e[0].length),metadata:n}}o(Uxe,"extractFrontMatter");er();var mit=o(t=>t.replace(/\r\n?/g,` +`).replace(/<(\w+)([^>]*)>/g,(e,r,n)=>"<"+r+n.replace(/="([^"]*)"/g,"='$1'")+">"),"cleanupText"),git=o(t=>{let{text:e,metadata:r}=Uxe(t),{displayMode:n,title:i,config:a={}}=r;return n&&(a.gantt||(a.gantt={}),a.gantt.displayMode=n),{title:i,config:a,text:e}},"processFrontmatter"),yit=o(t=>{let e=Vt.detectInit(t)??{},r=Vt.detectDirective(t,"wrap");return Array.isArray(r)?e.wrap=r.some(({type:n})=>n==="wrap"):r?.type==="wrap"&&(e.wrap=!0),{text:Kj(t),directive:e}},"processDirectives");function s$(t){let e=mit(t),r=git(e),n=yit(r.text),i=$n(r.config,n.directive);return t=Vxe(n.text),{code:t,title:r.title,config:i}}o(s$,"preprocessDiagram");TA();n3();er();function Hxe(t){let e=new TextEncoder().encode(t),r=Array.from(e,n=>String.fromCodePoint(n)).join("");return btoa(r)}o(Hxe,"toBase64");var vit=5e4,xit="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa",bit="sandbox",Tit="loose",wit="http://www.w3.org/2000/svg",kit="http://www.w3.org/1999/xlink",Eit="http://www.w3.org/1999/xhtml",Sit="100%",Cit="100%",Ait="border:0;margin:0;",_it="margin:0",Dit="allow-top-navigation-by-user-activation allow-popups",Lit='The "iframe" tag is not supported by your browser.',Rit=["foreignobject"],Nit=["dominant-baseline"];function Xxe(t){let e=s$(t);return $y(),Mz(e.config??{}),e}o(Xxe,"processAndSetConfigs");async function Mit(t,e){wy();try{let{code:r,config:n}=Xxe(t);return{diagramType:(await jxe(r)).type,config:n}}catch(r){if(e?.suppressErrors)return!1;throw r}}o(Mit,"parse");var Wxe=o((t,e,r=[])=>` +.${t} ${e} { ${r.join(" !important; ")} !important; }`,"cssImportantStyles"),Iit=o((t,e=new Map)=>{let r="";if(t.themeCSS!==void 0&&(r+=` +${t.themeCSS}`),t.fontFamily!==void 0&&(r+=` +:root { --mermaid-font-family: ${t.fontFamily}}`),t.altFontFamily!==void 0&&(r+=` +:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),e instanceof Map){let s=t.htmlLabels??t.flowchart?.htmlLabels?["> *","span"]:["rect","polygon","ellipse","circle","path"];e.forEach(l=>{hr(l.styles)||s.forEach(u=>{r+=Wxe(l.id,u,l.styles)}),hr(l.textStyles)||(r+=Wxe(l.id,"tspan",(l?.textStyles||[]).map(u=>u.replace("color","fill"))))})}return r},"createCssStyles"),Oit=o((t,e,r,n)=>{let i=Iit(t,r),a=MV(e,i,t.themeVariables);return BC(Pxe(`${n}{${a}}`),Bxe)},"createUserStyles"),Pit=o((t="",e,r)=>{let n=t;return!r&&!e&&(n=n.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),n=na(n),n=n.replace(/
    /g,"
    "),n},"cleanUpSvgCode"),Bit=o((t="",e)=>{let r=e?.viewBox?.baseVal?.height?e.viewBox.baseVal.height+"px":Cit,n=Hxe(`${t}`);return``},"putIntoIFrame"),qxe=o((t,e,r,n,i)=>{let a=t.append("div");a.attr("id",r),n&&a.attr("style",n);let s=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns",wit);return i&&s.attr("xmlns:xlink",i),s.append("g"),t},"appendDivSvgG");function Yxe(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}o(Yxe,"sandboxedIframe");var Fit=o((t,e,r,n)=>{t.getElementById(e)?.remove(),t.getElementById(r)?.remove(),t.getElementById(n)?.remove()},"removeExistingElements"),$it=o(async function(t,e,r){wy();let n=Xxe(e);e=n.code;let i=tr();X.debug(i),e.length>(i?.maxTextSize??vit)&&(e=xit);let a="#"+t,s="i"+t,l="#"+s,u="d"+t,h="#"+u,f=o(()=>{let L=Ge(p?l:h).node();L&&"remove"in L&&L.remove()},"removeTempElements"),d=Ge("body"),p=i.securityLevel===bit,m=i.securityLevel===Tit,g=i.fontFamily;if(r!==void 0){if(r&&(r.innerHTML=""),p){let k=Yxe(Ge(r),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge(r);qxe(d,t,u,`font-family: ${g}`,kit)}else{if(Fit(document,t,u,s),p){let k=Yxe(Ge("body"),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge("body");qxe(d,t,u)}let y,v;try{y=await Ay.fromText(e,{title:n.title})}catch(k){if(i.suppressErrorRendering)throw f(),k;y=await Ay.fromText("error"),v=k}let x=d.select(h).node(),b=y.type,T=x.firstChild,S=T.firstChild,w=y.renderer.getClasses?.(e,y),E=Oit(i,b,w,a),_=document.createElement("style");_.innerHTML=E,T.insertBefore(_,S);try{await y.renderer.draw(e,t,Db.version,y)}catch(k){throw i.suppressErrorRendering?f():a0e.draw(e,t,Db.version),k}let C=d.select(`${h} svg`),D=y.db.getAccTitle?.(),O=y.db.getAccDescription?.();Git(b,C,D,O),d.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",Eit);let R=d.select(h).node().innerHTML;if(X.debug("config.arrowMarkerAbsolute",i.arrowMarkerAbsolute),R=Pit(R,p,dr(i.arrowMarkerAbsolute)),p){let k=d.select(h+" svg").node();R=Bit(R,k)}else m||(R=mh.sanitize(R,{ADD_TAGS:Rit,ADD_ATTR:Nit,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));if(Gxe(),v)throw v;return f(),{diagramType:b,svg:R,bindFunctions:y.db.bindFunctions}},"render");function zit(t={}){let e=Un({},t);e?.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables||(e.themeVariables={}),e.themeVariables.fontFamily=e.fontFamily),Lz(e),e?.theme&&e.theme in Eo?e.themeVariables=Eo[e.theme].getThemeVariables(e.themeVariables):e&&(e.themeVariables=Eo.default.getThemeVariables(e.themeVariables));let r=typeof e=="object"?T7(e):w7();Dy(r.logLevel),wy()}o(zit,"initialize");var jxe=o((t,e={})=>{let{code:r}=s$(t);return Ay.fromText(r,e)},"getDiagramFromText");function Git(t,e,r,n){Fxe(e,t),$xe(e,r,n,e.attr("id"))}o(Git,"addA11yInfo");var Kf=Object.freeze({render:$it,parse:Mit,getDiagramFromText:jxe,initialize:zit,getConfig:tr,setConfig:a3,getSiteConfig:w7,updateSiteConfig:Rz,reset:o(()=>{$y()},"reset"),globalReset:o(()=>{$y(ph)},"globalReset"),defaultConfig:ph});Dy(tr().logLevel);$y(tr());rp();er();var Vit=o((t,e,r)=>{X.warn(t),I9(t)?(r&&r(t.str,t.hash),e.push({...t,message:t.str,error:t})):(r&&r(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),Kxe=o(async function(t={querySelector:".mermaid"}){try{await Uit(t)}catch(e){if(I9(e)&&X.error(e.str),ch.parseError&&ch.parseError(e),!t.suppressErrors)throw X.error("Use the suppressErrors option to suppress these errors"),e}},"run"),Uit=o(async function({postRenderCallback:t,querySelector:e,nodes:r}={querySelector:".mermaid"}){let n=Kf.getConfig();X.debug(`${t?"":"No "}Callback function found`);let i;if(r)i=r;else if(e)i=document.querySelectorAll(e);else throw new Error("Nodes and querySelector are both undefined");X.debug(`Found ${i.length} diagrams`),n?.startOnLoad!==void 0&&(X.debug("Start On Load: "+n?.startOnLoad),Kf.updateSiteConfig({startOnLoad:n?.startOnLoad}));let a=new Vt.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed),s,l=[];for(let u of Array.from(i)){X.info("Rendering diagram: "+u.id);if(u.getAttribute("data-processed"))continue;u.setAttribute("data-processed","true");let h=`mermaid-${a.next()}`;s=u.innerHTML,s=j4(Vt.entityDecode(s)).trim().replace(//gi,"
    ");let f=Vt.detectInit(s);f&&X.debug("Detected early reinit: ",f);try{let{svg:d,bindFunctions:p}=await ebe(h,s,u);u.innerHTML=d,t&&await t(h),p&&p(u)}catch(d){Vit(d,l,ch.parseError)}}if(l.length>0)throw l[0]},"runThrowsErrors"),Qxe=o(function(t){Kf.initialize(t)},"initialize"),Hit=o(async function(t,e,r){X.warn("mermaid.init is deprecated. Please use run instead."),t&&Qxe(t);let n={postRenderCallback:r,querySelector:".mermaid"};typeof e=="string"?n.querySelector=e:e&&(e instanceof HTMLElement?n.nodes=[e]:n.nodes=e),await Kxe(n)},"init"),Wit=o(async(t,{lazyLoad:e=!0}={})=>{wy(),Ly(...t),e===!1&&await vxe()},"registerExternalDiagrams"),Zxe=o(function(){if(ch.startOnLoad){let{startOnLoad:t}=Kf.getConfig();t&&ch.run().catch(e=>X.error("Mermaid failed to initialize",e))}},"contentLoaded");if(typeof document<"u"){window.addEventListener("load",Zxe,!1)}var qit=o(function(t){ch.parseError=t},"setParseErrorHandler"),FC=[],o$=!1,Jxe=o(async()=>{if(!o$){for(o$=!0;FC.length>0;){let t=FC.shift();if(t)try{await t()}catch(e){X.error("Error executing queue",e)}}o$=!1}},"executeQueue"),Yit=o(async(t,e)=>new Promise((r,n)=>{let i=o(()=>new Promise((a,s)=>{Kf.parse(t,e).then(l=>{a(l),r(l)},l=>{X.error("Error parsing",l),ch.parseError?.(l),s(l),n(l)})}),"performCall");FC.push(i),Jxe().catch(n)}),"parse"),ebe=o((t,e,r)=>new Promise((n,i)=>{let a=o(()=>new Promise((s,l)=>{Kf.render(t,e,r).then(u=>{s(u),n(u)},u=>{X.error("Error parsing",u),ch.parseError?.(u),l(u),i(u)})}),"performCall");FC.push(a),Jxe().catch(i)}),"render"),Xit=o(()=>Object.keys(au).map(t=>({id:t})),"getRegisteredDiagramsMetadata"),ch={startOnLoad:!0,mermaidAPI:Kf,parse:Yit,render:ebe,init:Hit,run:Kxe,registerExternalDiagrams:Wit,registerLayoutLoaders:tN,initialize:Qxe,parseError:void 0,contentLoaded:Zxe,setParseErrorHandler:qit,detectType:m0,registerIconPacks:X4,getRegisteredDiagramsMetadata:Xit},jit=ch;return ube(Kit);})(); +/*! Check if previously processed */ +/*! + * Wait for document loaded before starting the execution + */ +/*! Bundled license information: + +dompurify/dist/purify.es.mjs: + (*! @license DOMPurify 3.2.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.5/LICENSE *) + +js-yaml/dist/js-yaml.mjs: + (*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT *) + +lodash-es/lodash.js: + (** + * @license + * Lodash (Custom Build) + * Build: `lodash modularize exports="es" -o ./` + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + *) + +cytoscape/dist/cytoscape.esm.mjs: + (*! + Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable + Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) + Licensed under The MIT License (http://opensource.org/licenses/MIT) + *) + (*! + Event object based on jQuery events, MIT license + + https://jquery.org/license/ + https://tldrlegal.com/license/mit-license + https://github.com/jquery/jquery/blob/master/src/event.js + *) + (*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License *) + (*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License *) +*/ +globalThis["mermaid"] = globalThis.__esbuild_esm_mermaid_nm["mermaid"].default; \ No newline at end of file diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml new file mode 100644 index 0000000..5015c8e --- /dev/null +++ b/docs/public/sitemap.xml @@ -0,0 +1 @@ +https://mpilhlt.github.io/dhamps-vdb/categories/https://mpilhlt.github.io/dhamps-vdb/https://mpilhlt.github.io/dhamps-vdb/tags/ \ No newline at end of file diff --git a/docs/public/tags/index.html b/docs/public/tags/index.html new file mode 100644 index 0000000..161d839 --- /dev/null +++ b/docs/public/tags/index.html @@ -0,0 +1,3 @@ +Tags | dhamps-vdb Documentation + +
    \ No newline at end of file diff --git a/docs/public/tags/index.xml b/docs/public/tags/index.xml new file mode 100644 index 0000000..c74ecd9 --- /dev/null +++ b/docs/public/tags/index.xml @@ -0,0 +1 @@ +Tags on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/tags/Recent content in Tags on dhamps-vdb DocumentationHugoen-us \ No newline at end of file diff --git a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content new file mode 100644 index 0000000..db845ba --- /dev/null +++ b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content @@ -0,0 +1 @@ +@charset "UTF-8";:root{--font-size:16px;--font-size-smaller:0.875rem;--font-size-smallest:0.75rem;--body-font-weight:400;--body-background:white;--body-background-tint:transparent;--body-font-color:black;--border-radius:0.25rem}/*!modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize*/*,::before,::after{box-sizing:border-box}html{font-family:system-ui,segoe ui,Roboto,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji;line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,liberation mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:initial}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}.flex{display:flex}.flex.gap{gap:1rem}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-small,small{font-size:.875em}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}html{font-size:var(--font-size);scroll-behavior:smooth;touch-action:manipulation;scrollbar-gutter:stable}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background)var(--body-background-tint);font-weight:var(--body-font-weight);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-weight:inherit}a{flex:auto;align-items:center;gap:.5em;text-decoration:none;cursor:default}a[href],a[role=button]{color:var(--color-link);cursor:pointer}:focus-visible,input.toggle:focus-visible+label{outline-style:auto;outline-color:var(--color-link)}nav ul{padding:0;margin:0;list-style:none}nav ul li{position:relative}nav ul a{padding:.5em 0;display:flex;transition:opacity .1s ease-in-out}nav ul a[href]:hover,nav ul a[role=button]:hover{opacity:.5}nav ul ul{padding-inline-start:1.5em}ul.pagination{display:flex;justify-content:center;list-style-type:none;padding-inline-start:0}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}a .book-icon{height:1em;width:1em}.book-brand{margin-top:0;margin-bottom:1rem}.book-brand img{height:1.5em;width:1.5em}.book-menu{flex:0 0 16rem;font-size:var(--font-size-smaller)}.book-menu .book-menu-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;word-wrap:break-word;display:flex}.book-menu a.active{color:var(--color-link)}.book-menu label>img:last-child{height:1em;width:1em;cursor:pointer;align-self:center;transition:transform .1s ease-in-out}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-menu input.toggle:checked+label+ul{display:block}body[dir=rtl] .book-menu input.toggle+label>img:last-child{transform:rotate(180deg)}body[dir=rtl] .book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-section-flat{margin:1rem 0}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:4rem}.book-post .book-post-date img{height:1em;width:1em;margin-inline-end:.5em}.book-post .book-post-content{margin-top:1rem}.book-post .book-post-thumbnail{flex:0 0 34%}.book-post .book-post-thumbnail img{width:100%;aspect-ratio:4/3;object-fit:cover}.book-header{margin-bottom:1rem}.book-header label{line-height:0}.book-header h3{overflow:hidden;text-overflow:ellipsis;margin:0 1rem}.book-layout-landing .book-header{display:block;position:relative;z-index:1}.book-layout-landing .book-header nav>ul{display:flex;gap:1rem;justify-content:end}.book-layout-landing .book-header nav>ul>li{display:block;white-space:nowrap}.book-layout-landing .book-header nav>ul>li>ul{display:none;position:absolute;padding:0}.book-layout-landing .book-header nav>ul>li:hover>ul,.book-layout-landing .book-header nav>ul>li:focus-within>ul{display:block}.book-search{position:relative;margin:.5rem 0}.book-search input{width:100%;padding:.5rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search ul a{padding-bottom:0}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:var(--font-size-smallest)}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc a{display:block}.book-toc img{height:1em;width:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:var(--font-size-smaller)}.book-footer a{margin:.25rem 0;padding:.25rem 0}.book-comments{margin-top:1rem}.book-copyright{margin-top:1rem}.book-languages{margin-bottom:1rem}.book-languages span{padding:0}.book-languages ul{padding-inline-start:1.5em}.book-menu-content,.book-toc-content{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){.book-menu{visibility:hidden;margin-inline-start:-16rem;z-index:1}.book-menu .book-menu-content{background:var(--body-background)}.book-toc{display:none}.book-header{display:block}.book-post-container{flex-direction:column-reverse}#menu-control,#toc-control{display:inline}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:fixed;top:0;bottom:0;left:0;right:0}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked~main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:inherit;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;margin-inline-start:.25em}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus-visible,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus-visible,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus-visible,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus-visible,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus-visible,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus-visible{opacity:initial;text-decoration:none}.markdown h1{font-size:2rem}.markdown h2{font-size:1.5rem}.markdown h3{font-size:1.25rem}.markdown h4{font-size:1.125rem}.markdown h5{font-size:1rem}.markdown h6{font-size:.875rem}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a[href]:hover{text-decoration:underline}.markdown a[href]:visited{color:var(--color-visited-link)}.markdown img{max-width:100%;height:auto}.markdown code{direction:ltr;unicode-bidi:embed;padding:.125em .25em;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);overflow-x:auto}.markdown pre:focus{outline-style:auto;outline-color:var(--color-link)}.markdown pre code{padding:0;border:0;background:0 0}.markdown p{word-wrap:break-word}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:var(--border-radius)}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200);text-align:start}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem;word-wrap:break-word}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:0;margin-bottom:1rem}.markdown .highlight{direction:ltr;unicode-bidi:embed;border-radius:var(--border-radius)}.markdown .highlight table tbody{border:1px solid var(--gray-200)}.markdown .highlight table tr pre{border:0}.markdown .highlight table tr td pre code>span{display:flex}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;margin:1rem 0;border:1px solid var(--gray-200);border-radius:var(--border-radius)}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer;list-style:none}.markdown details summary::before{content:"›";display:inline-block;margin-inline-end:.5rem;transition:transform .1s ease-in-out}.markdown details[open] summary{margin-bottom:0}.markdown details[open] summary::before{transform:rotate(90deg)}.markdown figure{margin:1rem 0}.markdown figure figcaption{margin-top:1rem}.markdown-inner>:first-child,.markdown .book-steps>ol>li>:first-child,.markdown figure figcaption>:first-child{margin-top:0}.markdown-inner>:last-child,.markdown .book-steps>ol>li>:last-child,.markdown figure figcaption>:last-child{margin-bottom:0}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-columns{gap:1rem}.markdown .book-columns>div{margin:1rem 0;min-width:13.2rem}.markdown .book-columns>ul{list-style:none;display:flex;padding:0;flex-wrap:wrap;gap:1rem}.markdown .book-columns>ul>li{flex:1 1;min-width:13.2rem}.markdown a.book-btn[href]{display:inline-block;font-size:var(--font-size-smaller);color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:var(--border-radius);cursor:pointer}.markdown a.book-btn[href]:hover{text-decoration:none}.markdown .book-hint.note{border-color:var(--color-accent-note);background-color:var(--color-accent-note-tint)}.markdown .book-hint.tip{border-color:var(--color-accent-tip);background-color:var(--color-accent-tip-tint)}.markdown .book-hint.important{border-color:var(--color-accent-important);background-color:var(--color-accent-important-tint)}.markdown .book-hint.warning{border-color:var(--color-accent-warning);background-color:var(--color-accent-warning-tint)}.markdown .book-hint.caution{border-color:var(--color-accent-caution);background-color:var(--color-accent-caution-tint)}.markdown .book-hint.default{border-color:var(--color-accent-default);background-color:var(--color-accent-default-tint)}.markdown .book-hint.info{border-color:var(--color-accent-info);background-color:var(--color-accent-info-tint)}.markdown .book-hint.success{border-color:var(--color-accent-success);background-color:var(--color-accent-success-tint)}.markdown .book-hint.danger{border-color:var(--color-accent-danger);background-color:var(--color-accent-danger-tint)}.markdown .book-badge{display:inline-block;font-size:var(--font-size-smaller);font-weight:var(--body-font-weight);vertical-align:middle;border-radius:var(--border-radius);border:1px solid var(--accent-color);overflow:hidden;text-wrap:nowrap;color:var(--body-font-color)}.markdown .book-badge.note{--accent-color:var(--color-accent-note)}.markdown .book-badge.tip{--accent-color:var(--color-accent-tip)}.markdown .book-badge.important{--accent-color:var(--color-accent-important)}.markdown .book-badge.warning{--accent-color:var(--color-accent-warning)}.markdown .book-badge.caution{--accent-color:var(--color-accent-caution)}.markdown .book-badge.default{--accent-color:var(--color-accent-default)}.markdown .book-badge.info{--accent-color:var(--color-accent-info)}.markdown .book-badge.success{--accent-color:var(--color-accent-success)}.markdown .book-badge.danger{--accent-color:var(--color-accent-danger)}.markdown .book-badge span{display:inline-block;padding:0 .5rem}.markdown .book-badge span.book-badge-value{color:var(--body-background);background-color:var(--accent-color)}.markdown .book-steps{position:relative}.markdown .book-steps>ol{counter-reset:steps;list-style:none;padding-inline-start:1.25rem;margin-top:2rem}.markdown .book-steps>ol>li::before{content:counter(steps);counter-increment:steps;position:absolute;display:flex;justify-content:center;left:.5rem;height:1.5rem;width:1.5rem;padding:.25rem;border-radius:.5rem;white-space:nowrap;line-height:1rem;color:var(--body-background);background:var(--gray-500);outline:.25rem solid var(--body-background)}.markdown .book-steps>ol>li{border-inline-start:1px solid var(--gray-500);padding-inline-start:3rem;padding-bottom:2rem}.markdown .book-steps>ol>li:last-child{border:0}.markdown .book-card{display:block;overflow:hidden;height:100%;border-radius:var(--border-radius);border:1px solid var(--gray-200)}.markdown .book-card>a{display:block;height:100%}.markdown .book-card>a[href],.markdown .book-card>a[href]:visited{color:var(--body-font-color)}.markdown .book-card>a[href]:hover{text-decoration:none;background:var(--gray-100)}.markdown .book-card>a>img,.markdown .book-card>img{width:100%;display:block;aspect-ratio:4/3;object-fit:cover}.markdown .book-card .markdown-inner,.markdown .book-card figure figcaption,.markdown figure .book-card figcaption,.markdown .book-card .book-steps>ol>li{padding:1rem}.markdown .book-image input+img{cursor:zoom-in;transition:transform .2s ease-in-out}.markdown .book-image input:checked+img{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--body-background);object-fit:contain;width:100%;height:100%;z-index:1;cursor:zoom-out;padding:1rem}.markdown .book-asciinema{margin:1rem 0}.markdown .book-hero{min-height:24rem;align-content:center}.markdown .book-hero h1{font-size:3em}.markdown .book-codeblock-filename{background:var(--gray-100);border:1px solid var(--gray-200);border-bottom:0;font-size:var(--font-size-smaller);margin-top:1rem;padding:.25rem .5rem;border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}.markdown .book-codeblock-filename a{color:var(--body-font-color)}.markdown .book-codeblock-filename+.highlight pre{margin-top:0;border-start-start-radius:0;border-start-end-radius:0}:root{--body-background:white;--body-background-tint:none;--body-font-color:black;--color-link:#0055bb;--color-visited-link:#5500bb;--icon-filter:none;--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-accent-default:#64748b;--color-accent-default-tint:rgba(100, 116, 139, 0.1);--color-accent-note:#4486dd;--color-accent-note-tint:rgba(68, 134, 221, 0.1);--color-accent-tip:#3bad3b;--color-accent-tip-tint:rgba(59, 173, 59, 0.1);--color-accent-important:#8144dd;--color-accent-important-tint:rgba(129, 68, 221, 0.1);--color-accent-warning:#f59e42;--color-accent-warning-tint:rgba(245, 158, 66, 0.1);--color-accent-caution:#d84747;--color-accent-caution-tint:rgba(216, 71, 71, 0.1);--color-accent-info:#4486dd;--color-accent-info-tint:rgba(68, 134, 221, 0.1);--color-accent-success:#3bad3b;--color-accent-success-tint:rgba(59, 173, 59, 0.1);--color-accent-danger:#d84747;--color-accent-danger-tint:rgba(216, 71, 71, 0.1)} \ No newline at end of file diff --git a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json new file mode 100644 index 0000000..322e46d --- /dev/null +++ b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json @@ -0,0 +1 @@ +{"Target":"book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css","MediaType":"text/css","Data":{"Integrity":"sha256-zCxSTtJQqsgbI9H0r4c0SRezJSCIQf7KCWj+RQ9XBXU="}} \ No newline at end of file diff --git a/docs/themes/book b/docs/themes/book new file mode 160000 index 0000000..81a841c --- /dev/null +++ b/docs/themes/book @@ -0,0 +1 @@ +Subproject commit 81a841c92d62f2ed8d9134b0b18623b8b2471661 From 361c40d78a0aaa182a74675044358ad71d146381 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:25:08 +0000 Subject: [PATCH 3/9] Add comprehensive API documentation with 10 new markdown files - api/authentication.md: Bearer token auth, admin vs user keys, error handling - api/endpoints/users.md: User CRUD operations, API key generation - api/endpoints/projects.md: Project management, sharing, ownership transfer - api/endpoints/llm-services.md: Instances and definitions architecture - api/endpoints/api-standards.md: Authentication method configuration - api/endpoints/embeddings.md: Batch upload, validation, metadata schemas - api/endpoints/similars.md: Vector similarity search with filtering - api/query-parameters.md: Complete reference for pagination and filtering - api/patch-updates.md: Partial resource updates documentation - api/error-handling.md: HTTP status codes, error formats, troubleshooting Each file includes: - Hugo front matter with title and weight - HTTP methods and authentication requirements - curl examples with request/response formats - Parameter documentation - Error handling examples - Links to related documentation Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- docs/content/api/authentication.md | 194 +++++ docs/content/api/endpoints/api-standards.md | 457 ++++++++++++ docs/content/api/endpoints/embeddings.md | 532 ++++++++++++++ docs/content/api/endpoints/llm-services.md | 518 +++++++++++++ docs/content/api/endpoints/projects.md | 504 +++++++++++++ docs/content/api/endpoints/similars.md | 502 +++++++++++++ docs/content/api/endpoints/users.md | 304 ++++++++ docs/content/api/error-handling.md | 768 ++++++++++++++++++++ docs/content/api/patch-updates.md | 547 ++++++++++++++ docs/content/api/query-parameters.md | 465 ++++++++++++ 10 files changed, 4791 insertions(+) create mode 100644 docs/content/api/authentication.md create mode 100644 docs/content/api/endpoints/api-standards.md create mode 100644 docs/content/api/endpoints/embeddings.md create mode 100644 docs/content/api/endpoints/llm-services.md create mode 100644 docs/content/api/endpoints/projects.md create mode 100644 docs/content/api/endpoints/similars.md create mode 100644 docs/content/api/endpoints/users.md create mode 100644 docs/content/api/error-handling.md create mode 100644 docs/content/api/patch-updates.md create mode 100644 docs/content/api/query-parameters.md diff --git a/docs/content/api/authentication.md b/docs/content/api/authentication.md new file mode 100644 index 0000000..074a9fa --- /dev/null +++ b/docs/content/api/authentication.md @@ -0,0 +1,194 @@ +--- +title: "Authentication" +weight: 1 +--- + +# API Authentication + +All API requests (except public project read operations) require authentication using API keys passed in the `Authorization` header with a `Bearer` prefix. + +## Authentication Method + +Include your API key in the `Authorization` header of every request: + +``` +Authorization: Bearer your_api_key_here +``` + +## API Key Types + +### Admin API Key + +- Full access to all API endpoints and resources +- Can create and manage users +- Can access all projects and resources across all users +- Required for administrative operations +- Set via `ADMIN_KEY` environment variable + +**Admin-only operations:** +- `POST /v1/users` - Create new users +- `GET /v1/users` - List all users +- `GET /v1/admin/*` - Admin endpoints +- Create/modify `_system` LLM service definitions +- Access any user's resources + +### User API Key + +- Access limited to user's own resources and shared projects +- Cannot create other users +- Cannot access admin endpoints +- Returned when creating a new user (store securely) + +**User capabilities:** +- Manage own projects and LLM services +- Upload and query embeddings in owned projects +- Access projects shared with them (read or edit access) +- Delete own account + +## Getting an API Key + +### Admin Key + +Set the admin key via environment variable when launching the service: + +```bash +export ADMIN_KEY="your-secure-admin-key-here" +./dhamps-vdb +``` + +### User Key + +Create a new user using the admin API key: + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com" + }' +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com", + "api_key": "024v2013621509245f2e24" +} +``` + +**⚠️ Important:** The API key is only returned once during user creation. Store it securely - it cannot be recovered. + +## Authorization Header Format + +### Correct Format + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer 024v2013621509245f2e24" +``` + +### Common Mistakes + +❌ Missing "Bearer" prefix: +``` +Authorization: 024v2013621509245f2e24 +``` + +❌ Wrong prefix: +``` +Authorization: Token 024v2013621509245f2e24 +``` + +❌ Extra quotes: +``` +Authorization: Bearer "024v2013621509245f2e24" +``` + +## Authentication Errors + +### 401 Unauthorized + +Returned when authentication credentials are missing or invalid. + +**Causes:** +- Missing `Authorization` header +- Invalid API key +- Malformed header format + +**Example response:** + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +### 403 Forbidden + +Returned when authentication succeeds but authorization fails. + +**Causes:** +- Attempting to access another user's resources +- User lacking required permissions +- Non-admin accessing admin endpoints + +**Example response:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to access this resource" +} +``` + +## Public Access + +Projects can be made publicly accessible by setting `public_read: true` when creating or updating the project. Public projects allow unauthenticated read access to: + +- Project metadata +- Embeddings +- Similarity search + +See [Public Access Documentation](/docs/PUBLIC_ACCESS.md) for details. + +## Security Best Practices + +1. **Never commit API keys** to version control +2. **Use environment variables** to store API keys in your applications +3. **Rotate keys regularly** by creating new users and deleting old ones +4. **Use HTTPS** in production to prevent key interception +5. **Store admin keys securely** using secrets management systems +6. **Limit admin key distribution** to essential personnel only + +## Example Authenticated Request + +```bash +# List user's projects +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer 024v2013621509245f2e24" + +# Create a new project +curl -X POST "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer 024v2013621509245f2e24" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-project", + "description": "My research project", + "instance_owner": "alice", + "instance_handle": "my-openai" + }' +``` + +## Related Documentation + +- [Error Handling](error-handling/) - Complete error response reference +- [Users Endpoint](endpoints/users/) - User management API diff --git a/docs/content/api/endpoints/api-standards.md b/docs/content/api/endpoints/api-standards.md new file mode 100644 index 0000000..e45c079 --- /dev/null +++ b/docs/content/api/endpoints/api-standards.md @@ -0,0 +1,457 @@ +--- +title: "API Standards" +weight: 4 +--- + +# API Standards Endpoint + +Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances. + +## Overview + +API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include: + +- **OpenAI**: Bearer token in `Authorization` header +- **Cohere**: API key in `Authorization` header with `Bearer` prefix +- **Google Gemini**: API key as query parameter +- **Ollama**: No authentication required + +Pre-seeded standards are available for common providers. See [testdata/valid_api_standard_*.json](https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata) for examples. + +--- + +## Endpoints + +### List All API Standards + +Get all defined API standards. This endpoint is publicly accessible (no authentication required). + +**Endpoint:** `GET /v1/api-standards` + +**Authentication:** Public (no authentication required) + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/api-standards" +``` + +**Response:** + +```json +{ + "standards": [ + { + "api_standard_handle": "openai", + "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings", + "key_method": "auth_bearer", + "key_field": "Authorization" + }, + { + "api_standard_handle": "cohere", + "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed", + "key_method": "auth_bearer", + "key_field": "Authorization" + }, + { + "api_standard_handle": "gemini", + "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings", + "key_method": "query_param", + "key_field": "key" + } + ] +} +``` + +--- + +### Get API Standard + +Retrieve information about a specific API standard. This endpoint is publicly accessible. + +**Endpoint:** `GET /v1/api-standards/{standardname}` + +**Authentication:** Public (no authentication required) + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/api-standards/openai" +``` + +**Response:** + +```json +{ + "api_standard_handle": "openai", + "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings", + "key_method": "auth_bearer", + "key_field": "Authorization" +} +``` + +--- + +### Create API Standard + +Register a new API standard definition. Admin-only operation. + +**Endpoint:** `POST /v1/api-standards` + +**Authentication:** Admin only + +**Request Body:** + +```json +{ + "api_standard_handle": "custom-provider", + "description": "Custom provider embedding API", + "key_method": "auth_bearer", + "key_field": "Authorization" +} +``` + +**Parameters:** + +- `api_standard_handle` (string, required): Unique identifier for the standard +- `description` (string, required): Description including API documentation URL +- `key_method` (string, required): Authentication method + - `auth_bearer`: Bearer token in header + - `auth_apikey`: API key in header + - `query_param`: API key as query parameter + - `none`: No authentication +- `key_field` (string, required): Field name for the API key + - For headers: typically `"Authorization"` or `"X-API-Key"` + - For query params: parameter name like `"key"` or `"api_key"` + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/api-standards" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "api_standard_handle": "ollama", + "description": "Ollama local embedding API, no authentication required", + "key_method": "none", + "key_field": "" + }' +``` + +**Response:** + +```json +{ + "api_standard_handle": "ollama", + "description": "Ollama local embedding API, no authentication required", + "key_method": "none", + "key_field": "" +} +``` + +--- + +### Update API Standard (PUT) + +Create or update an API standard with a specific handle. Admin-only operation. + +**Endpoint:** `PUT /v1/api-standards/{standardname}` + +**Authentication:** Admin only + +**Request Body:** Same as POST endpoint + +**Example:** + +```bash +curl -X PUT "https://api.example.com/v1/api-standards/custom-provider" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "api_standard_handle": "custom-provider", + "description": "Updated description for custom provider", + "key_method": "auth_bearer", + "key_field": "Authorization" + }' +``` + +--- + +### Delete API Standard + +Delete an API standard definition. Admin-only operation. + +**Endpoint:** `DELETE /v1/api-standards/{standardname}` + +**Authentication:** Admin only + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/api-standards/custom-provider" \ + -H "Authorization: Bearer admin_api_key" +``` + +**Response:** + +```json +{ + "message": "API standard 'custom-provider' deleted successfully" +} +``` + +**⚠️ Warning:** Cannot delete API standards that are referenced by LLM service instances. + +--- + +### Partial Update (PATCH) + +Update specific API standard fields without providing all data. Admin-only operation. + +**Endpoint:** `PATCH /v1/api-standards/{standardname}` + +**Authentication:** Admin only + +**Example - Update description:** + +```bash +curl -X PATCH "https://api.example.com/v1/api-standards/openai" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "OpenAI Embeddings API v1 - Updated documentation link" + }' +``` + +See [PATCH Updates](../patch-updates/) for more details. + +--- + +## API Standard Properties + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `api_standard_handle` | string | Yes | Unique identifier (e.g., "openai", "cohere") | +| `description` | string | Yes | Description with API documentation URL | +| `key_method` | string | Yes | Authentication method | +| `key_field` | string | Yes | Field name for API key/token | + +--- + +## Authentication Methods + +### auth_bearer + +Bearer token authentication in the `Authorization` header. + +**Example:** +```json +{ + "key_method": "auth_bearer", + "key_field": "Authorization" +} +``` + +**HTTP Request:** +``` +Authorization: Bearer sk-proj-abc123... +``` + +**Used by:** OpenAI, Cohere, Anthropic + +--- + +### auth_apikey + +API key in a custom header field. + +**Example:** +```json +{ + "key_method": "auth_apikey", + "key_field": "X-API-Key" +} +``` + +**HTTP Request:** +``` +X-API-Key: abc123... +``` + +**Used by:** Some custom API providers + +--- + +### query_param + +API key passed as a URL query parameter. + +**Example:** +```json +{ + "key_method": "query_param", + "key_field": "key" +} +``` + +**HTTP Request:** +``` +GET https://api.example.com/embed?key=abc123... +``` + +**Used by:** Google Gemini, some older APIs + +--- + +### none + +No authentication required. + +**Example:** +```json +{ + "key_method": "none", + "key_field": "" +} +``` + +**Used by:** Ollama (local), self-hosted models without auth + +--- + +## Pre-seeded API Standards + +The following API standards are created during database migration: + +### openai + +```json +{ + "api_standard_handle": "openai", + "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings", + "key_method": "auth_bearer", + "key_field": "Authorization" +} +``` + +### cohere + +```json +{ + "api_standard_handle": "cohere", + "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed", + "key_method": "auth_bearer", + "key_field": "Authorization" +} +``` + +### gemini + +```json +{ + "api_standard_handle": "gemini", + "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings", + "key_method": "query_param", + "key_field": "key" +} +``` + +--- + +## Use Cases + +### Creating a Custom API Standard + +For self-hosted or custom LLM services: + +```bash +curl -X POST "https://api.example.com/v1/api-standards" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "api_standard_handle": "vllm-local", + "description": "vLLM local deployment with custom auth", + "key_method": "auth_apikey", + "key_field": "X-API-Key" + }' +``` + +### Referencing in LLM Service Instance + +Once created, reference the API standard in your LLM service instance: + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-vllm" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "my-vllm", + "endpoint": "https://vllm.local/v1/embeddings", + "api_standard": "vllm-local", + "model": "custom-embed", + "dimensions": 768, + "api_key_encrypted": "my-secret-key" + }' +``` + +--- + +## Common Errors + +### 400 Bad Request + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Invalid key_method: must be one of auth_bearer, auth_apikey, query_param, none" +} +``` + +### 401 Unauthorized (Admin Operations) + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +### 403 Forbidden (Admin Operations) + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only admin users can create/modify/delete API standards" +} +``` + +### 404 Not Found + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "API standard 'custom-provider' not found" +} +``` + +### 409 Conflict + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Cannot delete API standard: referenced by 5 LLM service instances" +} +``` + +--- + +## Related Documentation + +- [LLM Services](llm-services/) - LLM service instances reference API standards +- [Authentication](../authentication/) - User authentication methods +- [Testdata Examples](https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata) - Example API standard definitions diff --git a/docs/content/api/endpoints/embeddings.md b/docs/content/api/endpoints/embeddings.md new file mode 100644 index 0000000..886ab25 --- /dev/null +++ b/docs/content/api/endpoints/embeddings.md @@ -0,0 +1,532 @@ +--- +title: "Embeddings" +weight: 5 +--- + +# Embeddings Endpoint + +Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project's LLM service instance dimensions. + +## Endpoints + +### List Embeddings + +Get all embeddings for a project with pagination support. + +**Endpoint:** `GET /v1/embeddings/{username}/{projectname}` + +**Authentication:** Admin, owner, authorized readers, or public if `public_read` is enabled + +**Query Parameters:** + +- `limit` (integer, default: 10, max: 200): Maximum number of results to return +- `offset` (integer, default: 0): Pagination offset + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=0" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "embeddings": [ + { + "text_id": "doc123", + "user_handle": "alice", + "project_handle": "research-docs", + "instance_handle": "openai-large", + "text": "This is a research document about machine learning.", + "vector": [-0.020850, 0.018522, 0.053270, ...], + "vector_dim": 3072, + "metadata": { + "author": "Alice Doe", + "year": 2024 + } + } + ], + "total_count": 150, + "limit": 20, + "offset": 0 +} +``` + +--- + +### Upload Embeddings (Batch) + +Upload one or more embeddings to a project. Supports batch upload for efficiency. + +**Endpoint:** `POST /v1/embeddings/{username}/{projectname}` + +**Authentication:** Admin, owner, or authorized editors + +**Request Body:** + +```json +{ + "embeddings": [ + { + "text_id": "doc123", + "instance_handle": "openai-large", + "text": "This is a research document.", + "vector": [-0.020850, 0.018522, 0.053270, ...], + "vector_dim": 3072, + "metadata": { + "author": "Alice Doe", + "year": 2024 + } + }, + { + "text_id": "doc124", + "instance_handle": "openai-large", + "text": "Another research document.", + "vector": [0.012345, -0.054321, 0.098765, ...], + "vector_dim": 3072, + "metadata": { + "author": "Bob Smith", + "year": 2024 + } + } + ] +} +``` + +**Parameters:** + +- `embeddings` (array, required): Array of embedding objects + - `text_id` (string, required): Unique identifier for the text (URL-encoded recommended) + - `instance_handle` (string, required): Handle of the LLM service instance used + - `vector` (array of floats, required): Embedding vector + - `vector_dim` (integer, required): Number of dimensions in the vector + - `text` (string, optional): The original text + - `metadata` (object, optional): Additional metadata (validated against project schema if defined) + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + { + "text_id": "doc123", + "instance_handle": "openai-large", + "text": "Machine learning research document.", + "vector": [-0.020850, 0.018522, 0.053270], + "vector_dim": 3, + "metadata": { + "author": "Alice Doe", + "year": 2024 + } + } + ] + }' +``` + +**Response:** + +```json +{ + "message": "1 embedding(s) uploaded successfully", + "uploaded": ["doc123"] +} +``` + +--- + +### Get Single Embedding + +Retrieve information about a specific embedding by its text identifier. + +**Endpoint:** `GET /v1/embeddings/{username}/{projectname}/{identifier}` + +**Authentication:** Admin, owner, authorized readers, or public if `public_read` is enabled + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "text_id": "doc123", + "user_handle": "alice", + "project_handle": "research-docs", + "project_id": 1, + "instance_handle": "openai-large", + "text": "Machine learning research document.", + "vector": [-0.020850, 0.018522, 0.053270, ...], + "vector_dim": 3072, + "metadata": { + "author": "Alice Doe", + "year": 2024 + } +} +``` + +**Note:** URL-encode the identifier if it contains special characters (e.g., URLs). + +**Example with URL identifier:** + +```bash +# URL-encoded identifier +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/https%3A%2F%2Fexample.com%2Fdoc123" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Delete Single Embedding + +Delete a specific embedding by its text identifier. + +**Endpoint:** `DELETE /v1/embeddings/{username}/{projectname}/{identifier}` + +**Authentication:** Admin, owner, or authorized editors + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "message": "Embedding 'doc123' deleted successfully" +} +``` + +--- + +### Delete All Embeddings + +Delete all embeddings in a project. + +**Endpoint:** `DELETE /v1/embeddings/{username}/{projectname}` + +**Authentication:** Admin or owner + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "message": "All embeddings deleted from project alice/research-docs", + "deleted_count": 150 +} +``` + +**⚠️ Warning:** This operation is irreversible. + +--- + +## Request Format Details + +### Text Identifiers + +Text identifiers (`text_id`) should be: +- **Unique** within a project +- **URL-encoded** if they contain special characters +- **Descriptive** for easier retrieval + +**Examples:** +- Simple: `"doc123"`, `"article-456"` +- URL-based: `"https://example.com/docs/123"` (URL-encode in requests) +- Path-based: `"books/chapter1/section2"` + +### Vector Format + +Vectors must be: +- **Arrays of floats** (float32 or float64) +- **Matching dimensions** specified in `vector_dim` +- **Consistent dimensions** with the project's LLM service instance + +**Example:** + +```json +{ + "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003], + "vector_dim": 5 +} +``` + +### Metadata Format + +Metadata is a flexible JSON object that can contain any valid JSON data: + +**Simple metadata:** + +```json +{ + "metadata": { + "author": "Alice Doe", + "year": 2024, + "category": "research" + } +} +``` + +**Nested metadata:** + +```json +{ + "metadata": { + "author": { + "name": "Alice Doe", + "id": "author-123" + }, + "publication": { + "year": 2024, + "title": "Machine Learning Research" + }, + "tags": ["AI", "ML", "embeddings"] + } +} +``` + +--- + +## Validation + +### Dimension Validation + +The API automatically validates that: + +1. **Vector dimension consistency**: The `vector_dim` field must match the dimensions configured in the LLM service instance +2. **Vector length verification**: The actual number of elements in the `vector` array must match the declared `vector_dim` + +**Error example:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions" +} +``` + +### Metadata Schema Validation + +If the project has a `metadataScheme` defined, all uploaded embeddings' metadata will be validated against it. + +**Example project schema:** + +```json +{ + "type": "object", + "properties": { + "author": {"type": "string"}, + "year": {"type": "integer"} + }, + "required": ["author"] +} +``` + +**Valid metadata:** + +```json +{ + "author": "Alice Doe", + "year": 2024 +} +``` + +**Invalid metadata (missing required field):** + +```json +{ + "year": 2024 +} +``` + +**Error response:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n - author: author is required" +} +``` + +--- + +## Response Format + +### List Response + +```json +{ + "embeddings": [...], + "total_count": 150, + "limit": 20, + "offset": 0 +} +``` + +### Single Embedding Response + +```json +{ + "text_id": "doc123", + "user_handle": "alice", + "project_handle": "research-docs", + "project_id": 1, + "instance_handle": "openai-large", + "text": "...", + "vector": [...], + "vector_dim": 3072, + "metadata": {...} +} +``` + +### Upload Response + +```json +{ + "message": "3 embedding(s) uploaded successfully", + "uploaded": ["doc123", "doc124", "doc125"] +} +``` + +--- + +## Common Errors + +### 400 Bad Request - Dimension Mismatch + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions" +} +``` + +### 400 Bad Request - Invalid Vector + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "vector length (1536) does not match declared vector_dim (3072)" +} +``` + +### 400 Bad Request - Metadata Schema Violation + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n - author: author is required" +} +``` + +### 403 Forbidden + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to upload embeddings to this project" +} +``` + +### 404 Not Found - Project + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Project 'alice/research-docs' not found" +} +``` + +### 404 Not Found - Embedding + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Embedding 'doc123' not found in project 'alice/research-docs'" +} +``` + +### 409 Conflict + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Embedding 'doc123' already exists in project 'alice/research-docs'" +} +``` + +--- + +## Best Practices + +### Batch Uploads + +Upload multiple embeddings in a single request for better performance: + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "embeddings": [ + {...}, + {...}, + {...} + ] + }' +``` + +### URL-Encoded Identifiers + +Use URL encoding for identifiers with special characters: + +```python +import urllib.parse + +text_id = "https://example.com/docs/123" +encoded_id = urllib.parse.quote(text_id, safe='') +# Result: "https%3A%2F%2Fexample.com%2Fdocs%2F123" +``` + +### Metadata Design + +Design metadata schemas that: +- Include commonly queried fields +- Use consistent data types +- Validate required fields +- Support your similarity search filtering needs + +--- + +## Related Documentation + +- [Projects](projects/) - Project management and configuration +- [Similars](similars/) - Similarity search using embeddings +- [Query Parameters](../query-parameters/) - Pagination and filtering options +- [Error Handling](../error-handling/) - Complete error reference diff --git a/docs/content/api/endpoints/llm-services.md b/docs/content/api/endpoints/llm-services.md new file mode 100644 index 0000000..0c71efb --- /dev/null +++ b/docs/content/api/endpoints/llm-services.md @@ -0,0 +1,518 @@ +--- +title: "LLM Services" +weight: 3 +--- + +# LLM Services Endpoint + +Manage LLM service instances and definitions. The system supports two types of LLM service resources: + +1. **Definitions**: Reusable templates owned by `_system` or individual users +2. **Instances**: User-specific configurations with API keys that reference definitions or stand alone + +## Architecture Overview + +``` +definitions (templates) + └── owned by _system or users + └── contain: endpoint, model, dimensions, api_standard + └── no API keys + +instances (user-specific) + └── owned by individual users + └── reference a definition (optional) + └── contain encrypted API keys + └── can be shared with other users +``` + +For complete details, see [LLM Service Refactoring Documentation](/docs/LLM_SERVICE_REFACTORING.md). + +--- + +## Instance Endpoints + +### List User's Instances + +Get all LLM service instances owned by or shared with a user. + +**Endpoint:** `GET /v1/llm-services/{username}` + +**Authentication:** Admin or the user themselves + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "instances": [ + { + "instance_id": 1, + "instance_handle": "openai-large", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "OpenAI large embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "definition_id": 1 + }, + { + "instance_id": 2, + "instance_handle": "custom-model", + "owner": "alice", + "endpoint": "https://custom.api.example.com/embed", + "api_standard": "openai", + "model": "custom-embed-v1", + "dimensions": 1536 + } + ] +} +``` + +**Note:** API keys are never returned in GET responses for security. + +--- + +### Create or Update Instance (PUT) + +Create a new LLM service instance or update an existing one. + +**Endpoint:** `PUT /v1/llm-services/{username}/{instance_handle}` + +**Authentication:** Admin or the user themselves + +**Request Body (Standalone Instance):** + +```json +{ + "instance_handle": "openai-large", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "OpenAI large embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-proj-..." +} +``` + +**Request Body (From Definition):** + +```json +{ + "instance_handle": "my-openai", + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "sk-proj-..." +} +``` + +**Parameters:** + +- `instance_handle` (string, required): Unique identifier within user's namespace +- `endpoint` (string, required for standalone): API endpoint URL +- `description` (string, optional): Instance description +- `api_standard` (string, required for standalone): Reference to API standard (e.g., "openai", "cohere") +- `model` (string, required for standalone): Model name +- `dimensions` (integer, required for standalone): Vector dimensions +- `api_key_encrypted` (string, optional): API key (encrypted if ENCRYPTION_KEY is set) +- `definition_owner` (string, optional): Owner of the definition template +- `definition_handle` (string, optional): Handle of the definition template + +**Example - Standalone:** + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "openai-large", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "api_key_encrypted": "sk-proj-..." + }' +``` + +**Example - From _system Definition:** + +```bash +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "instance_handle": "my-openai", + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "sk-proj-..." + }' +``` + +**Response:** + +```json +{ + "instance_id": 1, + "instance_handle": "openai-large", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072 +} +``` + +**Security Note:** API keys are encrypted using AES-256-GCM if the `ENCRYPTION_KEY` environment variable is set. Keys are never returned in responses. + +--- + +### Get Instance Information + +Retrieve information about a specific LLM service instance. + +**Endpoint:** `GET /v1/llm-services/{username}/{instance_handle}` + +**Authentication:** Admin, owner, or users with shared access + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "instance_id": 1, + "instance_handle": "openai-large", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "OpenAI large embeddings", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072, + "definition_id": 1 +} +``` + +--- + +### Delete Instance + +Delete an LLM service instance. + +**Endpoint:** `DELETE /v1/llm-services/{username}/{instance_handle}` + +**Authentication:** Admin or the owner + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "message": "LLM service instance alice/openai-large deleted successfully" +} +``` + +**⚠️ Warning:** Cannot delete instances that are in use by projects. + +--- + +### Partial Update (PATCH) + +Update specific instance fields without providing all data. + +**Endpoint:** `PATCH /v1/llm-services/{username}/{instance_handle}` + +**Authentication:** Admin or the owner + +**Example - Update description:** + +```bash +curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated description" + }' +``` + +See [PATCH Updates](../patch-updates/) for more details. + +--- + +## Instance Sharing + +### Share Instance + +Share an LLM service instance with another user. + +**Endpoint:** `POST /v1/llm-services/{owner}/{instance}/share` + +**Authentication:** Admin or the instance owner + +**Request Body:** + +```json +{ + "share_with_handle": "bob", + "role": "reader" +} +``` + +**Roles:** +- `reader`: Can use the instance but cannot see API keys +- `editor`: Can use the instance (owner can still modify) +- `owner`: Full control (cannot be granted via sharing) + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/llm-services/alice/openai-large/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "bob", + "role": "reader" + }' +``` + +**Important:** Shared users can USE the instance but cannot see the API key. + +--- + +### Unshare Instance + +Remove a user's access to a shared instance. + +**Endpoint:** `DELETE /v1/llm-services/{owner}/{instance}/share/{user_handle}` + +**Authentication:** Admin or the instance owner + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large/share/bob" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### List Shared Users + +Get a list of users the instance is shared with. + +**Endpoint:** `GET /v1/llm-services/{owner}/{instance}/shared-with` + +**Authentication:** Admin or the instance owner + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large/shared-with" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "instance": "alice/openai-large", + "shared_with": [ + { + "user_handle": "bob", + "role": "reader" + } + ] +} +``` + +--- + +## Definition Endpoints + +### List System Definitions + +Get all LLM service definitions owned by `_system`. + +**Endpoint:** `GET /v1/llm-service-definitions/_system` + +**Authentication:** Any authenticated user + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/llm-service-definitions/_system" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "definitions": [ + { + "definition_id": 1, + "definition_handle": "openai-large", + "owner": "_system", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "OpenAI text-embedding-3-large", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072 + }, + { + "definition_id": 2, + "definition_handle": "openai-small", + "owner": "_system", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "OpenAI text-embedding-3-small", + "api_standard": "openai", + "model": "text-embedding-3-small", + "dimensions": 1536 + } + ] +} +``` + +**Pre-seeded System Definitions:** +- `openai-large`: OpenAI text-embedding-3-large (3072 dimensions) +- `openai-small`: OpenAI text-embedding-3-small (1536 dimensions) +- `cohere-v4`: Cohere embed-english-v4.0 (1536 dimensions) +- `gemini-embedding-001`: Google Gemini embedding-001 (768 dimensions) + +--- + +### Create User Definition + +Create a reusable LLM service definition template. + +**Endpoint:** `POST /v1/llm-service-definitions/{username}` + +**Authentication:** Admin or the user themselves + +**Request Body:** + +```json +{ + "definition_handle": "custom-model", + "endpoint": "https://custom.api.example.com/embed", + "description": "Custom embedding model", + "api_standard": "openai", + "model": "custom-embed-v1", + "dimensions": 1024 +} +``` + +**Note:** Only admin users can create `_system` definitions. + +--- + +## Instance Properties + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `instance_handle` | string | Yes | Unique identifier within user's namespace | +| `owner` | string | Read-only | Instance owner's user handle | +| `endpoint` | string | Yes* | API endpoint URL | +| `description` | string | No | Instance description | +| `api_standard` | string | Yes* | Reference to API standard | +| `model` | string | Yes* | Model name | +| `dimensions` | integer | Yes* | Vector dimensions | +| `api_key_encrypted` | string | Write-only | API key (never returned) | +| `definition_id` | integer | Read-only | Reference to definition template | + +\* Required for standalone instances; inherited from definition if using template + +--- + +## Security Features + +### API Key Encryption + +- **Algorithm:** AES-256-GCM +- **Key Source:** `ENCRYPTION_KEY` environment variable +- **Storage:** Encrypted in `api_key_encrypted` column +- **Retrieval:** Never returned in API responses + +### API Key Protection + +API keys are write-only: +- Provided during instance creation/update +- Encrypted before storage +- Never returned in GET/list responses +- Shared users cannot see API keys + +### Shared Instance Access + +When an instance is shared: +- Shared users can USE the instance for projects +- Shared users CANNOT see the API key +- Shared users CANNOT modify the instance +- Only owner can manage sharing + +--- + +## Common Errors + +### 400 Bad Request + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Instance must specify either all configuration fields or reference a definition" +} +``` + +### 403 Forbidden + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only admin users can create _system definitions" +} +``` + +### 404 Not Found + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "LLM service instance 'alice/openai-large' not found" +} +``` + +### 409 Conflict + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Cannot delete instance: in use by 3 projects" +} +``` + +--- + +## Related Documentation + +- [API Standards](api-standards/) - Managing API standard definitions +- [Projects](projects/) - Projects require an LLM service instance +- [LLM Service Refactoring](/docs/LLM_SERVICE_REFACTORING.md) - Complete architecture documentation diff --git a/docs/content/api/endpoints/projects.md b/docs/content/api/endpoints/projects.md new file mode 100644 index 0000000..f6147f0 --- /dev/null +++ b/docs/content/api/endpoints/projects.md @@ -0,0 +1,504 @@ +--- +title: "Projects" +weight: 2 +--- + +# Projects Endpoint + +Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance. + +## Endpoints + +### List User's Projects + +Get all projects owned by a user. + +**Endpoint:** `GET /v1/projects/{username}` + +**Authentication:** Admin, the user themselves, or users with shared access + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "projects": [ + { + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Research document embeddings", + "instance_id": 5, + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false, + "created_at": "2024-01-15T10:30:00Z" + } + ] +} +``` + +--- + +### Create Project + +Register a new project for a user. + +**Endpoint:** `POST /v1/projects/{username}` + +**Authentication:** Admin or the user themselves + +**Request Body:** + +```json +{ + "project_handle": "research-docs", + "description": "Research document embeddings", + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}", + "shared_with": [ + { + "user_handle": "bob", + "role": "reader" + } + ] +} +``` + +**Parameters:** + +- `project_handle` (string, required): Unique project identifier within the user's namespace +- `description` (string, optional): Project description +- `instance_owner` (string, required): Owner of the LLM service instance +- `instance_handle` (string, required): Handle of the LLM service instance to use +- `public_read` (boolean, optional): Allow unauthenticated read access (default: false) +- `metadataScheme` (string, optional): JSON Schema for validating embedding metadata +- `shared_with` (array, optional): List of users to share the project with + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-docs", + "description": "Research document embeddings", + "instance_owner": "alice", + "instance_handle": "openai-large" + }' +``` + +**Response:** + +```json +{ + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Research document embeddings", + "instance_id": 5, + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false +} +``` + +--- + +### Get Project Information + +Retrieve information about a specific project. + +**Endpoint:** `GET /v1/projects/{username}/{projectname}` + +**Authentication:** Admin, owner, authorized readers, or public if `public_read` is enabled + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Research document embeddings", + "instance_id": 5, + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false, + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}", + "created_at": "2024-01-15T10:30:00Z" +} +``` + +--- + +### Update Project (PUT) + +Create or update a project with the specified handle. + +**Endpoint:** `PUT /v1/projects/{username}/{projectname}` + +**Authentication:** Admin or the owner + +**Request Body:** Same as POST endpoint + +**Example:** + +```bash +curl -X PUT "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "research-docs", + "description": "Updated description", + "instance_owner": "alice", + "instance_handle": "openai-large" + }' +``` + +--- + +### Delete Project + +Delete a project and all its embeddings. + +**Endpoint:** `DELETE /v1/projects/{username}/{projectname}` + +**Authentication:** Admin or the owner + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "message": "Project alice/research-docs deleted successfully" +} +``` + +**⚠️ Warning:** This operation is irreversible and will delete all embeddings in the project. + +--- + +### Partial Update (PATCH) + +Update specific project fields without providing all data. + +**Endpoint:** `PATCH /v1/projects/{username}/{projectname}` + +**Authentication:** Admin or the owner + +**Example - Enable public read access:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "public_read": true + }' +``` + +**Example - Update description:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated project description" + }' +``` + +See [PATCH Updates](../patch-updates/) for more details. + +--- + +## Project Sharing + +### Share Project + +Share a project with another user, granting them read or edit access. + +**Endpoint:** `POST /v1/projects/{owner}/{project}/share` + +**Authentication:** Admin or the project owner + +**Request Body:** + +```json +{ + "share_with_handle": "bob", + "role": "reader" +} +``` + +**Roles:** +- `reader`: Read-only access to embeddings and similarity search +- `editor`: Read and write access to embeddings + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/research-docs/share" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "share_with_handle": "bob", + "role": "reader" + }' +``` + +**Response:** + +```json +{ + "message": "Project shared successfully", + "project": "alice/research-docs", + "shared_with": "bob", + "role": "reader" +} +``` + +--- + +### Unshare Project + +Remove a user's access to a shared project. + +**Endpoint:** `DELETE /v1/projects/{owner}/{project}/share/{user_handle}` + +**Authentication:** Admin or the project owner + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs/share/bob" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "message": "Project unshared successfully", + "project": "alice/research-docs", + "removed_user": "bob" +} +``` + +--- + +### List Shared Users + +Get a list of users the project is shared with. + +**Endpoint:** `GET /v1/projects/{owner}/{project}/shared-with` + +**Authentication:** Admin or the project owner + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice/research-docs/shared-with" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "project": "alice/research-docs", + "shared_with": [ + { + "user_handle": "bob", + "role": "reader" + }, + { + "user_handle": "charlie", + "role": "editor" + } + ] +} +``` + +**Note:** Only the project owner can view this list. Users with shared access cannot see who else has access. + +--- + +## Project Ownership Transfer + +### Transfer Ownership + +Transfer ownership of a project to another user. + +**Endpoint:** `POST /v1/projects/{owner}/{project}/transfer-ownership` + +**Authentication:** Admin or the project owner + +**Request Body:** + +```json +{ + "new_owner_handle": "bob" +} +``` + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/projects/alice/research-docs/transfer-ownership" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "new_owner_handle": "bob" + }' +``` + +**Response:** + +```json +{ + "message": "Project ownership transferred successfully", + "old_owner": "alice", + "new_owner": "bob", + "project_handle": "research-docs", + "new_path": "/v1/projects/bob/research-docs" +} +``` + +**Important Notes:** +- Only the current owner can transfer ownership +- The new owner must be an existing user +- The new owner cannot already have a project with the same handle +- After transfer, the old owner loses all access to the project +- All embeddings and project data remain intact + +--- + +## Query Parameters + +### List Projects + +When listing projects, the following query parameters are available: + +- `limit` (integer, default: 10, max: 200): Maximum number of results to return +- `offset` (integer, default: 0): Pagination offset + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice?limit=20&offset=40" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +## Project Properties + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `project_handle` | string | Yes | Unique identifier within user's namespace | +| `owner` | string | Read-only | Project owner's user handle | +| `description` | string | No | Project description | +| `instance_owner` | string | Yes | Owner of the LLM service instance | +| `instance_handle` | string | Yes | Handle of the LLM service instance | +| `instance_id` | integer | Read-only | Internal ID of the LLM service instance | +| `public_read` | boolean | No | Allow unauthenticated read access | +| `metadataScheme` | string | No | JSON Schema for metadata validation | +| `created_at` | timestamp | Read-only | Project creation timestamp | + +--- + +## Metadata Schema Validation + +Projects can define a JSON Schema to validate metadata attached to embeddings. See the main README for examples. + +**Example Schema:** + +```json +{ + "type": "object", + "properties": { + "author": {"type": "string"}, + "year": {"type": "integer"} + }, + "required": ["author"] +} +``` + +When uploading embeddings, metadata will be validated against this schema. Invalid metadata will result in a `400 Bad Request` error. + +--- + +## Common Errors + +### 400 Bad Request + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Project must have instance_id" +} +``` + +### 403 Forbidden + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to modify this project" +} +``` + +### 404 Not Found + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Project 'alice/research-docs' not found" +} +``` + +### 409 Conflict + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Project 'alice/research-docs' already exists" +} +``` + +--- + +## Related Documentation + +- [LLM Services](llm-services/) - Managing LLM service instances +- [Embeddings](embeddings/) - Adding and retrieving embeddings +- [Similars](similars/) - Similarity search +- [Public Access](/docs/PUBLIC_ACCESS.md) - Public project configuration diff --git a/docs/content/api/endpoints/similars.md b/docs/content/api/endpoints/similars.md new file mode 100644 index 0000000..6c92524 --- /dev/null +++ b/docs/content/api/endpoints/similars.md @@ -0,0 +1,502 @@ +--- +title: "Similars" +weight: 6 +--- + +# Similarity Search Endpoints + +Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them. + +## Endpoints + +### GET Similar Documents (from stored embeddings) + +Find documents similar to an already-stored document by its text identifier. + +**Endpoint:** `GET /v1/similars/{username}/{projectname}/{identifier}` + +**Authentication:** Admin, owner, authorized readers, or public if `public_read` is enabled + +**Query Parameters:** + +- `count` (integer, optional, default: 10, max: 200): Number of similar documents to return +- `threshold` (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold +- `limit` (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for `count`) +- `offset` (integer, optional, default: 0): Pagination offset +- `metadata_path` (string, optional): Metadata field path for filtering (must be used with `metadata_value`) +- `metadata_value` (string, optional): Metadata value to exclude from results (must be used with `metadata_path`) + +**Example - Basic search:** + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Example - With metadata filtering:** + +```bash +# Exclude documents with author="John Doe" +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json", + "user_handle": "alice", + "project_handle": "research-docs", + "results": [ + { + "id": "doc456", + "similarity": 0.95 + }, + { + "id": "doc789", + "similarity": 0.87 + }, + { + "id": "doc321", + "similarity": 0.82 + } + ] +} +``` + +--- + +### POST Similar Documents (from raw embeddings) + +Find similar documents by submitting a raw embedding vector without storing it in the database. Useful for one-time queries or testing. + +**Endpoint:** `POST /v1/similars/{username}/{projectname}` + +**Authentication:** Admin, owner, authorized readers, or public if `public_read` is enabled + +**Query Parameters:** Same as GET endpoint above + +**Request Body:** + +```json +{ + "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003, ...] +} +``` + +The vector must be an array of float values with dimensions matching the project's LLM service instance configuration. + +**Example - Basic search:** + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] + }' +``` + +**Example - With metadata filtering:** + +```bash +# Exclude documents from the same category +curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=5&metadata_path=category&metadata_value=biology" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [-0.020850, 0.018522, 0.053270, ...] + }' +``` + +**Response:** Same format as GET endpoint + +--- + +## Query Parameters Reference + +### count / limit + +Maximum number of similar documents to return. + +- **Type:** Integer +- **Default:** 10 +- **Max:** 200 +- **Note:** `count` and `limit` are aliases; use either one + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20" +``` + +--- + +### threshold + +Minimum similarity score threshold. Only documents with similarity scores >= threshold are returned. + +- **Type:** Float +- **Default:** 0.5 +- **Range:** 0.0 to 1.0 (where 1.0 is most similar) + +**Example:** + +```bash +# Only return very similar documents (>= 0.8) +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8" +``` + +--- + +### offset + +Pagination offset for large result sets. + +- **Type:** Integer +- **Default:** 0 +- **Use:** Skip the first N results + +**Example:** + +```bash +# Get results 21-40 +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20" +``` + +--- + +### metadata_path + +Metadata field path for filtering results. Must be used together with `metadata_value`. + +- **Type:** String +- **Format:** JSON path notation (e.g., `"author"`, `"author.name"`, `"publication.year"`) +- **Use:** Exclude documents where metadata field matches a specific value + +**Examples:** + +```bash +# Simple field +metadata_path=author + +# Nested field +metadata_path=author.name + +# Deeply nested field +metadata_path=publication.journal.name +``` + +--- + +### metadata_value + +Metadata value to exclude from results. Must be used together with `metadata_path`. + +- **Type:** String +- **Use:** Excludes documents where the metadata field at `metadata_path` equals this value + +**Example - Exclude same author:** + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe" +``` + +**Example - Exclude same category:** + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=research" +``` + +**Example - Nested field:** + +```bash +# Exclude documents from same author ID +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083" +``` + +--- + +## Response Format + +Both GET and POST endpoints return the same response format: + +```json +{ + "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json", + "user_handle": "alice", + "project_handle": "research-docs", + "results": [ + { + "id": "doc456", + "similarity": 0.95 + }, + { + "id": "doc789", + "similarity": 0.87 + }, + { + "id": "doc321", + "similarity": 0.82 + } + ] +} +``` + +**Response Fields:** + +- `$schema` (string): JSON schema reference +- `user_handle` (string): Project owner's username +- `project_handle` (string): Project identifier +- `results` (array): Array of similar documents, ordered by similarity (highest first) + - `id` (string): Document text identifier + - `similarity` (float): Cosine similarity score (0-1, where 1 is most similar) + +--- + +## Similarity Calculation + +### Cosine Distance + +The API uses **cosine distance** (or equivalently, cosine similarity) to calculate vector similarity: + +- **Range:** 0 to 1 +- **1.0:** Identical vectors +- **0.0:** Orthogonal vectors (completely dissimilar) +- **Higher values:** More similar documents + +### Dimension Filtering + +The system automatically filters results to only include embeddings with matching dimensions. This ensures: +- Only embeddings with matching `vector_dim` are compared +- Only embeddings from the same project are considered +- Invalid comparisons are prevented + +--- + +## Dimension Validation (POST only) + +When using the POST endpoint with raw embeddings, the API validates: + +1. The project has an associated LLM service instance +2. The submitted vector dimensions match the instance's configured dimensions +3. If dimensions don't match, a `400 Bad Request` error is returned + +**Error example:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "vector dimension mismatch: expected 1536 dimensions, got 768" +} +``` + +--- + +## Metadata Filtering + +Both endpoints support metadata filtering to exclude documents based on metadata field values. This uses **negative matching** (excludes documents where the field matches the value). + +### Use Cases + +**Exclude documents from the same source:** + +```bash +# When finding similar documents to doc123, exclude others from the same author +curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=author_id&metadata_value=A0083" +``` + +**Exclude documents from the same category:** + +```bash +# Find similar documents in other categories +curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology" +``` + +**Exclude documents with the same tag:** + +```bash +# Find documents with similar content but different tags +curl -X POST ".../similars/alice/research-docs?metadata_path=primary_tag&metadata_value=machine-learning" \ + -d '{"vector": [...]}' +``` + +### Nested Field Access + +Use dot notation for nested metadata fields: + +```bash +# Exclude documents from the same author (nested field) +metadata_path=author.id&metadata_value=author-123 + +# Exclude documents from the same publication year +metadata_path=publication.year&metadata_value=2024 + +# Deeply nested field +metadata_path=source.journal.publisher&metadata_value=Springer +``` + +--- + +## Examples + +### Basic Similarity Search + +Find 5 most similar documents with at least 0.7 similarity: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Search with Raw Vector + +Submit a vector without storing it: + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] + }' +``` + +--- + +### Search with Metadata Filtering + +Find similar documents but exclude those from the same author: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Paginated Results + +Get the next page of results: + +```bash +# Page 1 +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=0" + +# Page 2 +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20" + +# Page 3 +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40" +``` + +--- + +### Complex Query + +High threshold, metadata filtering, and pagination: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&threshold=0.9&offset=0&metadata_path=category&metadata_value=biology" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +## Common Errors + +### 400 Bad Request - Dimension Mismatch (POST only) + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "vector dimension mismatch: expected 1536 dimensions, got 768" +} +``` + +### 400 Bad Request - Missing metadata_value + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata_path requires metadata_value to be specified" +} +``` + +### 400 Bad Request - Invalid threshold + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "threshold must be between 0.0 and 1.0" +} +``` + +### 403 Forbidden + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to search this project" +} +``` + +### 404 Not Found - Project + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Project 'alice/research-docs' not found" +} +``` + +### 404 Not Found - Embedding (GET only) + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Embedding 'doc123' not found in project 'alice/research-docs'" +} +``` + +--- + +## Performance Considerations + +### Indexing + +The database uses vector indexes for efficient similarity search. See the database migrations for index configuration. + +### Result Limits + +- Default limit: 10 results +- Maximum limit: 200 results +- Use pagination for large result sets + +### Threshold Optimization + +Higher thresholds reduce result set size and improve performance: + +- **0.5-0.7:** Broad similarity (default) +- **0.7-0.85:** Moderate similarity +- **0.85-0.95:** High similarity +- **0.95-1.0:** Near-identical documents + +--- + +## Related Documentation + +- [Embeddings](embeddings/) - Storing embeddings for similarity search +- [Projects](projects/) - Project configuration +- [Query Parameters](../query-parameters/) - Complete parameter reference +- [Error Handling](../error-handling/) - Error response format diff --git a/docs/content/api/endpoints/users.md b/docs/content/api/endpoints/users.md new file mode 100644 index 0000000..f63e2e1 --- /dev/null +++ b/docs/content/api/endpoints/users.md @@ -0,0 +1,304 @@ +--- +title: "Users" +weight: 1 +--- + +# Users Endpoint + +Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information. + +## Endpoints + +### List All Users + +Get a list of all registered user handles. + +**Endpoint:** `GET /v1/users` + +**Authentication:** Admin only + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" +``` + +**Response:** + +```json +{ + "users": ["alice", "bob", "charlie"] +} +``` + +--- + +### Create User + +Register a new user and generate their API key. + +**Endpoint:** `POST /v1/users` + +**Authentication:** Admin only + +**Request Body:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com" +} +``` + +**Parameters:** + +- `user_handle` (string, required): Unique identifier for the user (alphanumeric, hyphens, underscores) +- `name` (string, optional): User's full name +- `email` (string, optional): User's email address + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com" + }' +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com", + "api_key": "024v2013621509245f2e24" +} +``` + +**⚠️ Important:** The `api_key` is only returned once during user creation. Store it securely - it cannot be recovered later. + +**Error Responses:** + +- `400 Bad Request`: Invalid user handle or missing required fields +- `409 Conflict`: User handle already exists + +--- + +### Get User Information + +Retrieve information about a specific user. + +**Endpoint:** `GET /v1/users/{username}` + +**Authentication:** Admin or the user themselves + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/users/alice" \ + -H "Authorization: Bearer alice_or_admin_api_key" +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com" +} +``` + +**Note:** API key is never returned in GET responses for security reasons. + +--- + +### Create or Update User (PUT) + +Register a new user with a specific handle or update existing user information. + +**Endpoint:** `PUT /v1/users/{username}` + +**Authentication:** Admin only + +**Request Body:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice@example.com" +} +``` + +**Example:** + +```bash +curl -X PUT "https://api.example.com/v1/users/alice" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "user_handle": "alice", + "name": "Alice Smith", + "email": "alice.smith@example.com" + }' +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Smith", + "email": "alice.smith@example.com", + "api_key": "024v2013621509245f2e24" +} +``` + +--- + +### Delete User + +Delete a user and all their associated resources (projects, LLM services, embeddings). + +**Endpoint:** `DELETE /v1/users/{username}` + +**Authentication:** Admin or the user themselves + +**Example:** + +```bash +curl -X DELETE "https://api.example.com/v1/users/alice" \ + -H "Authorization: Bearer alice_or_admin_api_key" +``` + +**Response:** + +```json +{ + "message": "User alice deleted successfully" +} +``` + +**⚠️ Warning:** This operation is irreversible and will delete: +- All projects owned by the user +- All LLM service instances owned by the user +- All embeddings in the user's projects +- All sharing relationships + +--- + +### Partial Update (PATCH) + +Update specific user fields without providing all user data. + +**Endpoint:** `PATCH /v1/users/{username}` + +**Authentication:** Admin or the user themselves + +**Request Body:** + +```json +{ + "name": "Alice Smith" +} +``` + +**Example:** + +```bash +curl -X PATCH "https://api.example.com/v1/users/alice" \ + -H "Authorization: Bearer alice_or_admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "email": "newemail@example.com" + }' +``` + +See [PATCH Updates](../patch-updates/) for more details. + +--- + +## User Properties + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `user_handle` | string | Yes | Unique identifier (alphanumeric, hyphens, underscores) | +| `name` | string | No | User's full name | +| `email` | string | No | User's email address | +| `api_key` | string | Read-only | Generated API key (only returned on creation) | + +## Special User: _system + +The `_system` user is a special internal user that: +- Owns global LLM service definitions +- Cannot be used for authentication +- Cannot be deleted +- Is created automatically during database migrations + +Users can create LLM service instances from `_system` definitions. + +## Common Errors + +### 400 Bad Request + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Invalid user_handle: must be alphanumeric with hyphens or underscores" +} +``` + +### 401 Unauthorized + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +### 403 Forbidden + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only admin users can create new users" +} +``` + +### 404 Not Found + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "User 'alice' not found" +} +``` + +### 409 Conflict + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "User 'alice' already exists" +} +``` + +## Related Documentation + +- [Authentication](../authentication/) - API key authentication details +- [Projects](projects/) - Project management +- [LLM Services](llm-services/) - LLM service instances diff --git a/docs/content/api/error-handling.md b/docs/content/api/error-handling.md new file mode 100644 index 0000000..d97dcc6 --- /dev/null +++ b/docs/content/api/error-handling.md @@ -0,0 +1,768 @@ +--- +title: "Error Handling" +weight: 9 +--- + +# Error Handling + +The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions. + +## Error Response Format + +All error responses follow this structure: + +```json +{ + "title": "Error Title", + "status": 400, + "detail": "Detailed error message explaining what went wrong" +} +``` + +**Fields:** + +- `title` (string): Human-readable error title +- `status` (integer): HTTP status code +- `detail` (string): Detailed description of the error + +## HTTP Status Codes + +### 2xx Success + +#### 200 OK + +Request succeeded. Response body contains requested data. + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "projects": [...] +} +``` + +--- + +#### 201 Created + +Resource created successfully. Response body contains the new resource. + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -d '{"user_handle": "bob"}' +``` + +**Response:** + +```json +{ + "user_handle": "bob", + "api_key": "..." +} +``` + +--- + +### 4xx Client Errors + +#### 400 Bad Request + +The request is invalid or contains malformed data. + +**Common causes:** +- Invalid JSON syntax +- Missing required fields +- Invalid field values or types +- Dimension mismatches in embeddings +- Metadata schema violations +- Invalid query parameter values + +**Examples:** + +**Invalid JSON:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Invalid JSON: unexpected end of input" +} +``` + +**Missing required field:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Missing required field: project_handle" +} +``` + +**Dimension mismatch:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions" +} +``` + +**Metadata validation:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n - author: author is required" +} +``` + +**Invalid query parameter:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "limit must be between 1 and 200" +} +``` + +--- + +#### 401 Unauthorized + +Authentication failed or credentials are missing. + +**Common causes:** +- Missing `Authorization` header +- Invalid API key +- Expired API key +- Malformed `Authorization` header + +**Example:** + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +**Troubleshooting:** + +- Verify the `Authorization` header is present +- Check the API key is correct +- Ensure the header format is `Authorization: Bearer ` +- Verify the user still exists + +--- + +#### 403 Forbidden + +Authentication succeeded but authorization failed. The authenticated user lacks permission for the requested operation. + +**Common causes:** +- User attempting to access another user's private resources +- Non-admin attempting admin-only operations +- User attempting to modify shared resources they don't own +- Attempting to access resources with insufficient role (reader vs editor) + +**Examples:** + +**Admin-only operation:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only admin users can create new users" +} +``` + +**Accessing another user's resource:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to access this project" +} +``` + +**Insufficient role:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to modify embeddings in this project. Editor role required." +} +``` + +--- + +#### 404 Not Found + +The requested resource does not exist. + +**Common causes:** +- Resource was deleted +- Incorrect resource identifier +- Typo in URL path +- Resource never existed + +**Examples:** + +**User not found:** + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "User 'alice' not found" +} +``` + +**Project not found:** + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Project 'alice/research-docs' not found" +} +``` + +**Embedding not found:** + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Embedding 'doc123' not found in project 'alice/research-docs'" +} +``` + +**LLM service not found:** + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "LLM service instance 'alice/openai-large' not found" +} +``` + +--- + +#### 409 Conflict + +The request conflicts with the current state of the resource. + +**Common causes:** +- Creating a resource that already exists +- Deleting a resource that is in use +- Concurrent modification conflicts + +**Examples:** + +**Resource already exists:** + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "User 'alice' already exists" +} +``` + +**Resource in use:** + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Cannot delete LLM service instance: in use by 3 projects" +} +``` + +**Ownership transfer conflict:** + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "New owner already has a project with handle 'research-docs'" +} +``` + +--- + +#### 422 Unprocessable Entity + +The request is syntactically correct but semantically invalid. + +**Common causes:** +- Invalid JSON Schema +- Logical validation failures +- Constraint violations + +**Example:** + +```json +{ + "title": "Unprocessable Entity", + "status": 422, + "detail": "metadataScheme is not valid JSON Schema: invalid schema structure" +} +``` + +--- + +### 5xx Server Errors + +#### 500 Internal Server Error + +An unexpected error occurred on the server. + +**Common causes:** +- Database connection failures +- Unexpected exceptions +- Configuration errors + +**Example:** + +```json +{ + "title": "Internal Server Error", + "status": 500, + "detail": "An internal error occurred. Please try again later." +} +``` + +**Action:** Contact support if the error persists. + +--- + +#### 503 Service Unavailable + +The service is temporarily unavailable. + +**Common causes:** +- Database maintenance +- Service overload +- Network issues + +**Example:** + +```json +{ + "title": "Service Unavailable", + "status": 503, + "detail": "Service temporarily unavailable. Please try again later." +} +``` + +**Action:** Retry the request after a delay. + +--- + +## Common Error Scenarios + +### Authentication Errors + +#### Missing Authorization Header + +**Request:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" +``` + +**Response:** + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +**Solution:** Include the `Authorization` header: + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +#### Invalid API Key + +**Request:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice" \ + -H "Authorization: Bearer invalid_key" +``` + +**Response:** + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +**Solution:** Verify your API key is correct. + +--- + +### Permission Errors + +#### Non-Admin Creating Users + +**Request:** + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer alice_api_key" \ + -d '{"user_handle": "bob"}' +``` + +**Response:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "Only admin users can create new users" +} +``` + +**Solution:** Use an admin API key. + +--- + +#### Accessing Another User's Project + +**Request:** + +```bash +curl -X GET "https://api.example.com/v1/projects/bob/private-project" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to access this project" +} +``` + +**Solution:** Request the project owner to share the project with you. + +--- + +### Validation Errors + +#### Invalid JSON + +**Request:** + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{"user_handle": "bob"' +``` + +**Response:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Invalid JSON: unexpected end of input" +} +``` + +**Solution:** Fix the JSON syntax. + +--- + +#### Dimension Mismatch + +**Request:** + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \ + -d '{ + "embeddings": [{ + "text_id": "doc123", + "instance_handle": "openai-large", + "vector": [0.1, 0.2, 0.3], + "vector_dim": 3 + }] + }' +``` + +**Response:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3 dimensions but LLM service 'openai-large' expects 3072 dimensions" +} +``` + +**Solution:** Ensure vector dimensions match the LLM service configuration. + +--- + +#### Metadata Schema Violation + +**Request:** + +```bash +curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \ + -d '{ + "embeddings": [{ + "text_id": "doc123", + "instance_handle": "openai-large", + "vector": [...], + "vector_dim": 3072, + "metadata": { + "year": 2024 + } + }] + }' +``` + +**Response (if project schema requires "author"):** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n - author: author is required" +} +``` + +**Solution:** Include all required metadata fields. + +--- + +### Resource Conflicts + +#### Creating Duplicate Resource + +**Request:** + +```bash +curl -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -d '{"user_handle": "alice"}' +``` + +**Response:** + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "User 'alice' already exists" +} +``` + +**Solution:** Use a different user handle or update the existing user. + +--- + +#### Deleting Resource In Use + +**Request:** + +```bash +curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Response:** + +```json +{ + "title": "Conflict", + "status": 409, + "detail": "Cannot delete LLM service instance: in use by 3 projects" +} +``` + +**Solution:** Delete or update the projects using this instance first. + +--- + +## Error Handling Best Practices + +### Client-Side Error Handling + +**Python example:** + +```python +import requests + +response = requests.get( + "https://api.example.com/v1/projects/alice", + headers={"Authorization": f"Bearer {api_key}"} +) + +if response.status_code == 200: + projects = response.json()["projects"] + print(f"Found {len(projects)} projects") + +elif response.status_code == 401: + print("Authentication failed - check API key") + +elif response.status_code == 403: + print("Permission denied") + +elif response.status_code == 404: + print("User not found") + +elif response.status_code >= 500: + print("Server error - retry later") + +else: + error = response.json() + print(f"Error: {error['detail']}") +``` + +--- + +### Retry Logic + +For transient errors (5xx), implement exponential backoff: + +```python +import time +import requests + +def api_request_with_retry(url, max_retries=3): + for attempt in range(max_retries): + response = requests.get(url, headers={...}) + + if response.status_code < 500: + return response + + if attempt < max_retries - 1: + wait_time = 2 ** attempt # Exponential backoff + print(f"Retrying in {wait_time}s...") + time.sleep(wait_time) + + return response +``` + +--- + +### Validation Before Request + +Validate data locally before sending to reduce 400 errors: + +```python +def create_embedding(text_id, vector, metadata): + # Validate locally + if not text_id: + raise ValueError("text_id is required") + + if not isinstance(vector, list): + raise ValueError("vector must be a list") + + if len(vector) != 3072: + raise ValueError("vector must have 3072 dimensions") + + # Send request + response = requests.post( + "https://api.example.com/v1/embeddings/alice/research-docs", + json={ + "embeddings": [{ + "text_id": text_id, + "instance_handle": "openai-large", + "vector": vector, + "vector_dim": len(vector), + "metadata": metadata + }] + }, + headers={"Authorization": f"Bearer {api_key}"} + ) + + return response.json() +``` + +--- + +## Troubleshooting + +### Check API Documentation + +Always refer to the live API documentation: + +- **OpenAPI YAML:** `/openapi.yaml` +- **Interactive Docs:** `/docs` + +--- + +### Verify Request Format + +Use tools like `curl -v` to inspect the full request: + +```bash +curl -v -X POST "https://api.example.com/v1/users" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{"user_handle": "bob"}' +``` + +--- + +### Check Status and Logs + +For persistent 5xx errors, check service status and logs (if you have access). + +--- + +### Contact Support + +If errors persist or the cause is unclear: + +1. Note the error message and status code +2. Record the request details (method, URL, headers, body) +3. Check if the issue is reproducible +4. Contact support with this information + +--- + +## Related Documentation + +- [Authentication](authentication/) - API authentication guide +- [Query Parameters](query-parameters/) - Valid parameter values +- [Endpoints](endpoints/) - Complete endpoint reference diff --git a/docs/content/api/patch-updates.md b/docs/content/api/patch-updates.md new file mode 100644 index 0000000..00c1ad9 --- /dev/null +++ b/docs/content/api/patch-updates.md @@ -0,0 +1,547 @@ +--- +title: "PATCH Updates" +weight: 8 +--- + +# PATCH Method for Partial Updates + +The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change. + +## Overview + +PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint: + +1. Retrieves the current resource state via GET +2. Merges your changes with the existing data +3. Applies the update via PUT + +This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects. + +## Supported Resources + +PATCH is available for: + +- **Users:** `/v1/users/{username}` +- **Projects:** `/v1/projects/{username}/{projectname}` +- **LLM Services:** `/v1/llm-services/{username}/{llm_servicename}` +- **API Standards:** `/v1/api-standards/{standardname}` + +## Request Format + +**Endpoint:** `PATCH {resource_url}` + +**Content-Type:** `application/json` + +**Body:** JSON object containing only the fields to update + +## Examples + +### Update Project Description + +Change only the project description without affecting other fields. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated project description" + }' +``` + +**Response:** + +```json +{ + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Updated project description", + "instance_id": 5, + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false +} +``` + +--- + +### Enable Public Read Access + +Make a project publicly accessible without changing other settings. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "public_read": true + }' +``` + +**Response:** + +```json +{ + "project_id": 1, + "project_handle": "research-docs", + "owner": "alice", + "description": "Research document embeddings", + "instance_id": 5, + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": true +} +``` + +--- + +### Update User Email + +Change a user's email address without affecting other user data. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/users/alice" \ + -H "Authorization: Bearer alice_or_admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "email": "alice.new@example.com" + }' +``` + +**Response:** + +```json +{ + "user_handle": "alice", + "name": "Alice Doe", + "email": "alice.new@example.com" +} +``` + +--- + +### Update LLM Service Description + +Change the description of an LLM service instance. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Production OpenAI embeddings service" + }' +``` + +**Response:** + +```json +{ + "instance_id": 1, + "instance_handle": "openai-large", + "owner": "alice", + "endpoint": "https://api.openai.com/v1/embeddings", + "description": "Production OpenAI embeddings service", + "api_standard": "openai", + "model": "text-embedding-3-large", + "dimensions": 3072 +} +``` + +--- + +### Update API Standard Documentation + +Update the description of an API standard (admin only). + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/api-standards/openai" \ + -H "Authorization: Bearer admin_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "OpenAI Embeddings API, Version 1 - Updated 2024" + }' +``` + +--- + +### Update Multiple Fields + +You can update multiple fields in a single PATCH request. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Updated description", + "public_read": true + }' +``` + +--- + +### Add Project Metadata Schema + +Add or update a project's metadata validation schema. + +**Request:** + +```bash +curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}" + }' +``` + +--- + +## Use Cases + +### Configuration Changes + +Update configuration settings without rebuilding entire resource objects: + +```bash +# Enable/disable public access +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{"public_read": true}' + +# Update instance dimensions +curl -X PATCH ".../llm-services/alice/custom-model" \ + -d '{"dimensions": 1024}' +``` + +--- + +### Metadata Management + +Update descriptive metadata: + +```bash +# Update project description +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{"description": "New description"}' + +# Update user name +curl -X PATCH ".../users/alice" \ + -d '{"name": "Alice Smith"}' +``` + +--- + +### Schema Evolution + +Add or update validation schemas: + +```bash +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{ + "metadataScheme": "{\"type\":\"object\",\"properties\":{\"category\":{\"type\":\"string\"}}}" + }' +``` + +--- + +## Authentication + +PATCH requests require the same authentication as PUT requests for the resource: + +| Resource | Who Can PATCH | +|----------|---------------| +| Users | Admin or the user themselves | +| Projects | Admin or project owner | +| LLM Services | Admin or instance owner | +| API Standards | Admin only | + +--- + +## Behavior Details + +### Merge Strategy + +PATCH uses a **shallow merge** strategy: + +- Top-level fields you specify **replace** the existing values +- Nested objects are replaced entirely (not deep-merged) +- Fields you don't specify remain unchanged + +**Example:** + +Existing project: +```json +{ + "description": "Old description", + "public_read": false, + "metadataScheme": "{...old schema...}" +} +``` + +PATCH request: +```json +{ + "description": "New description" +} +``` + +Result: +```json +{ + "description": "New description", + "public_read": false, + "metadataScheme": "{...old schema...}" +} +``` + +--- + +### Validation + +All field values are validated according to the resource's schema: + +- Field types must be correct +- Required fields (if specified) must be valid +- Constraints (e.g., string length, enum values) are enforced + +--- + +### Atomic Operations + +PATCH operations are atomic: +- Either all changes succeed, or none are applied +- If validation fails, the resource remains unchanged + +--- + +## Comparison: PATCH vs PUT + +### PUT (Complete Replacement) + +**Requires:** All fields (except read-only ones) + +```bash +curl -X PUT ".../projects/alice/research-docs" \ + -d '{ + "project_handle": "research-docs", + "description": "Updated description", + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": false + }' +``` + +**Use when:** Creating or completely replacing a resource + +--- + +### PATCH (Partial Update) + +**Requires:** Only fields to change + +```bash +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{ + "description": "Updated description" + }' +``` + +**Use when:** Modifying one or a few fields of an existing resource + +--- + +## Error Handling + +### 400 Bad Request + +Invalid field values or types: + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "Invalid value for field 'public_read': expected boolean, got string" +} +``` + +--- + +### 401 Unauthorized + +Missing or invalid authentication: + +```json +{ + "title": "Unauthorized", + "status": 401, + "detail": "Invalid or missing authorization credentials" +} +``` + +--- + +### 403 Forbidden + +Insufficient permissions: + +```json +{ + "title": "Forbidden", + "status": 403, + "detail": "You don't have permission to modify this resource" +} +``` + +--- + +### 404 Not Found + +Resource doesn't exist: + +```json +{ + "title": "Not Found", + "status": 404, + "detail": "Project 'alice/research-docs' not found" +} +``` + +--- + +### 422 Unprocessable Entity + +Validation failed: + +```json +{ + "title": "Unprocessable Entity", + "status": 422, + "detail": "metadataScheme is not valid JSON Schema" +} +``` + +--- + +## Best Practices + +### Use PATCH for Single-Field Updates + +**Do:** +```bash +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{"public_read": true}' +``` + +**Don't:** +```bash +# Unnecessarily complex +curl -X PUT ".../projects/alice/research-docs" \ + -d '{ + "project_handle": "research-docs", + "description": "Research docs", + "instance_owner": "alice", + "instance_handle": "openai-large", + "public_read": true + }' +``` + +--- + +### Group Related Changes + +Update multiple related fields in one request: + +```bash +curl -X PATCH ".../projects/alice/research-docs" \ + -d '{ + "description": "Updated project", + "public_read": true, + "metadataScheme": "{...new schema...}" + }' +``` + +--- + +### Validate Before Patching + +When possible, validate changes locally before submitting: + +```python +# Python example +def update_project_description(project_path, new_description): + if not new_description or len(new_description) > 500: + raise ValueError("Invalid description") + + response = requests.patch( + f"{API_BASE}/projects/{project_path}", + json={"description": new_description}, + headers={"Authorization": f"Bearer {API_KEY}"} + ) + return response.json() +``` + +--- + +### Handle Errors Gracefully + +```python +response = requests.patch( + f"{API_BASE}/projects/alice/research-docs", + json={"public_read": True}, + headers={"Authorization": f"Bearer {API_KEY}"} +) + +if response.status_code == 200: + print("Updated successfully") +elif response.status_code == 403: + print("Permission denied") +elif response.status_code == 404: + print("Project not found") +else: + print(f"Error: {response.json()['detail']}") +``` + +--- + +## Limitations + +### Not Available For + +PATCH is **not** available for: +- Endpoints that don't support GET and PUT +- List endpoints (e.g., `GET /v1/projects/alice`) +- Action endpoints (e.g., `/share`, `/transfer-ownership`) + +### Cannot Change Identifiers + +You cannot use PATCH to change resource identifiers: +- `user_handle` +- `project_handle` +- `instance_handle` +- `api_standard_handle` + +To rename a resource, you must create a new resource and delete the old one. + +--- + +## Related Documentation + +- [Users](endpoints/users/) - User management endpoints +- [Projects](endpoints/projects/) - Project management endpoints +- [LLM Services](endpoints/llm-services/) - LLM service instance endpoints +- [API Standards](endpoints/api-standards/) - API standard endpoints +- [Error Handling](error-handling/) - Error response reference diff --git a/docs/content/api/query-parameters.md b/docs/content/api/query-parameters.md new file mode 100644 index 0000000..514f24f --- /dev/null +++ b/docs/content/api/query-parameters.md @@ -0,0 +1,465 @@ +--- +title: "Query Parameters" +weight: 7 +--- + +# Query Parameters Reference + +Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration. + +## Pagination Parameters + +### limit + +Maximum number of results to return in a single response. + +**Type:** Integer +**Default:** 10 +**Maximum:** 200 +**Minimum:** 1 + +**Used by:** +- `GET /v1/embeddings/{user}/{project}` - List embeddings +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search +- `GET /v1/projects/{user}` - List projects + +**Example:** + +```bash +# Get 50 embeddings +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=50" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Aliases:** +- `count` - Used in similarity search endpoints (same behavior as `limit`) + +--- + +### offset + +Number of results to skip before returning data. Used for pagination. + +**Type:** Integer +**Default:** 0 +**Minimum:** 0 + +**Used by:** +- `GET /v1/embeddings/{user}/{project}` - List embeddings +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search +- `GET /v1/projects/{user}` - List projects + +**Example:** + +```bash +# Get results 21-40 (page 2) +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=20" \ + -H "Authorization: Bearer alice_api_key" + +# Get results 41-60 (page 3) +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=40" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Pagination Formula:** +``` +Page N: offset = (N - 1) * limit +``` + +--- + +## Similarity Search Parameters + +### count + +Number of similar documents to return. Alias for `limit` in similarity search endpoints. + +**Type:** Integer +**Default:** 10 +**Maximum:** 200 +**Minimum:** 1 + +**Used by:** +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search + +**Example:** + +```bash +# Find 5 most similar documents +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Note:** `count` and `limit` can be used interchangeably in similarity endpoints. + +--- + +### threshold + +Minimum similarity score threshold. Only results with similarity >= threshold are returned. + +**Type:** Float +**Default:** 0.5 +**Range:** 0.0 to 1.0 +**Note:** 1.0 = most similar, 0.0 = least similar + +**Used by:** +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search + +**Example:** + +```bash +# Only return highly similar documents (>= 0.8) +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8" \ + -H "Authorization: Bearer alice_api_key" + +# Return moderately similar documents (>= 0.6) +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.6" \ + -H "Authorization: Bearer alice_api_key" +``` + +**Threshold Guidelines:** + +| Threshold | Interpretation | Use Case | +|-----------|----------------|----------| +| 0.95-1.0 | Near-identical | Duplicate detection | +| 0.85-0.95 | Very similar | Finding closely related documents | +| 0.7-0.85 | Moderately similar | Broad similarity search | +| 0.5-0.7 | Loosely similar | Exploratory search | +| 0.0-0.5 | Weakly similar | Generally not useful | + +--- + +## Metadata Filtering Parameters + +### metadata_path + +JSON path to a metadata field for filtering results. Must be used together with `metadata_value`. + +**Type:** String +**Format:** JSON path notation (e.g., `"author"`, `"author.name"`, `"publication.year"`) + +**Used by:** +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search + +**Path Notation:** +- **Simple field:** `author` +- **Nested field:** `author.name` +- **Deeply nested:** `publication.journal.name` + +**Example:** + +```bash +# Simple field path +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=John%20Doe" + +# Nested field path +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083" +``` + +--- + +### metadata_value + +Metadata value to exclude from similarity search results. Must be used together with `metadata_path`. + +**Type:** String +**Behavior:** Negative matching (excludes documents where field equals this value) + +**Used by:** +- `GET /v1/similars/{user}/{project}/{id}` - Similarity search +- `POST /v1/similars/{user}/{project}` - Raw vector search + +**Example:** + +```bash +# Exclude documents from the same author +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe" \ + -H "Authorization: Bearer alice_api_key" + +# Exclude documents from the same category +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology" \ + -H "Authorization: Bearer alice_api_key" +``` + +**URL Encoding:** + +Always URL-encode metadata values that contain special characters: + +```bash +# Value: "John Doe" → "John%20Doe" +# Value: "2024-01-15" → "2024-01-15" (no special chars) +# Value: "author@example.com" → "author%40example.com" +``` + +--- + +## Parameter Combinations + +### Pagination with Filtering + +Combine limit, offset, and threshold: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40&threshold=0.7" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Similarity Search with Metadata Filtering + +Combine threshold and metadata filtering: + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&threshold=0.8&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Complete Query with All Parameters + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&offset=0&threshold=0.75&metadata_path=category&metadata_value=biology" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +## Endpoint-Specific Parameters + +### List Embeddings + +**Endpoint:** `GET /v1/embeddings/{user}/{project}` + +**Supported Parameters:** +- `limit` (default: 10, max: 200) +- `offset` (default: 0) + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=100&offset=200" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### List Projects + +**Endpoint:** `GET /v1/projects/{user}` + +**Supported Parameters:** +- `limit` (default: 10, max: 200) +- `offset` (default: 0) + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/projects/alice?limit=50&offset=0" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Similarity Search (GET) + +**Endpoint:** `GET /v1/similars/{user}/{project}/{id}` + +**Supported Parameters:** +- `count` / `limit` (default: 10, max: 200) +- `offset` (default: 0) +- `threshold` (default: 0.5, range: 0.0-1.0) +- `metadata_path` (optional, requires `metadata_value`) +- `metadata_value` (optional, requires `metadata_path`) + +**Example:** + +```bash +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&threshold=0.7&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer alice_api_key" +``` + +--- + +### Similarity Search (POST) + +**Endpoint:** `POST /v1/similars/{user}/{project}` + +**Supported Parameters:** Same as GET similarity search + +**Example:** + +```bash +curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \ + -H "Authorization: Bearer alice_api_key" \ + -H "Content-Type: application/json" \ + -d '{ + "vector": [-0.020850, 0.018522, 0.053270, ...] + }' +``` + +--- + +## Parameter Validation + +### Invalid Parameter Values + +**Error Response:** + +```json +{ + "title": "Bad Request", + "status": 400, + "detail": "limit must be between 1 and 200" +} +``` + +**Common Validation Errors:** + +- `limit` exceeds maximum (200) +- `limit` less than minimum (1) +- `offset` is negative +- `threshold` outside range 0.0-1.0 +- `metadata_path` without `metadata_value` +- `metadata_value` without `metadata_path` + +--- + +## Best Practices + +### Pagination + +**Do:** +- Use consistent `limit` values across pages +- Start with `offset=0` for the first page +- Increment `offset` by `limit` for each subsequent page + +**Example pagination logic:** + +```python +limit = 20 +page = 1 + +# Page 1 +offset = (page - 1) * limit # 0 +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}" + +# Page 2 +page = 2 +offset = (page - 1) * limit # 20 +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}" + +# Page 3 +page = 3 +offset = (page - 1) * limit # 40 +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}" +``` + +--- + +### Similarity Search + +**Do:** +- Use higher thresholds (0.7-0.9) for focused searches +- Use lower thresholds (0.5-0.7) for exploratory searches +- Combine with `count` to limit result size +- Use metadata filtering to exclude unwanted results + +**Don't:** +- Request more results than needed (affects performance) +- Use very low thresholds (<0.5) unless necessary + +--- + +### Metadata Filtering + +**Do:** +- URL-encode metadata values with special characters +- Use specific field paths for nested metadata +- Test metadata paths with sample queries first + +**Example:** + +```bash +# Good: URL-encoded, specific path +metadata_path=author.id&metadata_value=A0083 + +# Good: Simple field +metadata_path=category&metadata_value=biology + +# Bad: Not URL-encoded +metadata_path=author name&metadata_value=John Doe + +# Good: URL-encoded +metadata_path=author%20name&metadata_value=John%20Doe +``` + +--- + +## Response Formats + +### Paginated Response + +Endpoints that support pagination typically return: + +```json +{ + "items": [...], + "total_count": 500, + "limit": 20, + "offset": 40, + "has_more": true +} +``` + +**Fields:** +- `items`: Array of results +- `total_count`: Total number of items available +- `limit`: Number of items requested per page +- `offset`: Current offset +- `has_more`: Boolean indicating if more results exist + +--- + +### Similarity Response + +Similarity endpoints return: + +```json +{ + "user_handle": "alice", + "project_handle": "research-docs", + "results": [ + { + "id": "doc456", + "similarity": 0.95 + }, + { + "id": "doc789", + "similarity": 0.87 + } + ] +} +``` + +**Notes:** +- Results are ordered by similarity (highest first) +- Only results >= `threshold` are included +- Maximum of `count`/`limit` results returned +- Filtered by `metadata_path`/`metadata_value` if specified + +--- + +## Related Documentation + +- [Embeddings](endpoints/embeddings/) - Embedding storage and retrieval +- [Similars](endpoints/similars/) - Similarity search details +- [Projects](endpoints/projects/) - Project management +- [Error Handling](error-handling/) - Error responses From ad0ca2ace91253a3a045a6785fa184c85130b44d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:29:24 +0000 Subject: [PATCH 4/9] Add comprehensive deployment documentation for Docker, database, environment variables, and security Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- docs/content/deployment/database.md | 494 ++++++++++++ docs/content/deployment/docker.md | 297 +++++++ .../deployment/environment-variables.md | 493 ++++++++++++ docs/content/deployment/security.md | 741 ++++++++++++++++++ 4 files changed, 2025 insertions(+) create mode 100644 docs/content/deployment/database.md create mode 100644 docs/content/deployment/docker.md create mode 100644 docs/content/deployment/environment-variables.md create mode 100644 docs/content/deployment/security.md diff --git a/docs/content/deployment/database.md b/docs/content/deployment/database.md new file mode 100644 index 0000000..ba9be71 --- /dev/null +++ b/docs/content/deployment/database.md @@ -0,0 +1,494 @@ +--- +title: "Database Setup" +weight: 2 +--- + +# Database Setup + +dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension. + +## Requirements + +- **PostgreSQL**: Version 11 or higher +- **pgvector**: Extension for vector similarity search +- **Storage**: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count) + +## Installing PostgreSQL with pgvector + +### Using Docker (Recommended) + +The easiest way to get PostgreSQL with pgvector: + +```bash +docker run -d \ + --name postgres-pgvector \ + -p 5432:5432 \ + -e POSTGRES_PASSWORD=secure_password \ + -v postgres_data:/var/lib/postgresql/data \ + pgvector/pgvector:0.7.4-pg16 +``` + +### On Ubuntu/Debian + +```bash +# Add PostgreSQL APT repository +sudo apt install curl ca-certificates +sudo install -d /usr/share/postgresql-common/pgdg +sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \ + https://www.postgresql.org/media/keys/ACCC4CF8.asc +echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ + https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \ + sudo tee /etc/apt/sources.list.d/pgdg.list + +# Install PostgreSQL +sudo apt update +sudo apt install postgresql-16 postgresql-contrib-16 + +# Install pgvector +sudo apt install postgresql-16-pgvector +``` + +### On macOS + +```bash +# Using Homebrew +brew install postgresql@16 +brew install pgvector + +# Start PostgreSQL +brew services start postgresql@16 +``` + +### On RHEL/CentOS/Fedora + +```bash +# Install PostgreSQL +sudo dnf install postgresql16-server postgresql16-contrib + +# Install pgvector (build from source) +sudo dnf install postgresql16-devel git gcc make +git clone https://github.com/pgvector/pgvector.git +cd pgvector +make +sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_config +``` + +## Database Configuration + +### Step 1: Create Database + +Connect to PostgreSQL as superuser: + +```bash +# Local connection +sudo -u postgres psql + +# Remote connection +psql -h db.example.com -U postgres +``` + +Create the database: + +```sql +-- Create database +CREATE DATABASE dhamps_vdb; +``` + +### Step 2: Create User + +Create a dedicated user for dhamps-vdb: + +```sql +-- Create user with password +CREATE USER dhamps_user WITH PASSWORD 'secure_password_here'; +``` + +**Best practices:** +- Use strong, randomly generated password (e.g., `openssl rand -base64 32`) +- Store password securely (password manager, secrets management) +- Rotate passwords regularly + +### Step 3: Grant Privileges + +Grant necessary permissions: + +```sql +-- Grant database privileges +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; + +-- Connect to the database +\c dhamps_vdb + +-- Grant schema privileges +GRANT ALL ON SCHEMA public TO dhamps_user; + +-- For PostgreSQL 15+, also grant: +GRANT CREATE ON DATABASE dhamps_vdb TO dhamps_user; +``` + +### Step 4: Enable pgvector Extension + +Still connected to the `dhamps_vdb` database: + +```sql +-- Enable pgvector extension +CREATE EXTENSION IF NOT EXISTS vector; + +-- Verify extension is installed +\dx +``` + +Expected output should include: + +``` +List of installed extensions + Name | Version | Schema | Description +---------+---------+------------+------------------------------ + vector | 0.7.4 | public | vector data type and ivfflat and hnsw access methods +``` + +### Step 5: Verify Setup + +Test the setup: + +```sql +-- Test vector creation +SELECT '[1,2,3]'::vector; + +-- Should return: [1,2,3] + +-- Test vector distance +SELECT '[1,2,3]'::vector <=> '[4,5,6]'::vector AS distance; + +-- Should return a float (distance value) +``` + +Exit psql: + +```sql +\q +``` + +## Connection String Format + +dhamps-vdb connects using these environment variables: + +```bash +SERVICE_DBHOST=localhost # Database hostname +SERVICE_DBPORT=5432 # Database port +SERVICE_DBUSER=dhamps_user # Database username +SERVICE_DBPASSWORD=password # Database password +SERVICE_DBNAME=dhamps_vdb # Database name +``` + +The connection string format used internally: + +``` +postgresql://username:password@host:port/database?sslmode=disable +``` + +## Production Configuration + +### PostgreSQL Tuning + +Edit `postgresql.conf` for better vector search performance: + +```ini +# Memory settings +shared_buffers = 4GB # 25% of RAM +effective_cache_size = 12GB # 75% of RAM +maintenance_work_mem = 1GB +work_mem = 50MB + +# Parallel query settings +max_parallel_workers_per_gather = 4 +max_parallel_workers = 8 + +# Connection settings +max_connections = 100 + +# For pgvector specifically +shared_preload_libraries = 'vector' # Add if not present + +# Write-ahead log +wal_level = replica # For replication +max_wal_senders = 3 # For replicas +``` + +Restart PostgreSQL after changes: + +```bash +# On systemd systems +sudo systemctl restart postgresql + +# On Docker +docker restart postgres-container +``` + +### Connection Pooling + +For high-load scenarios, use connection pooling with PgBouncer: + +```bash +# Install PgBouncer +sudo apt install pgbouncer + +# Configure /etc/pgbouncer/pgbouncer.ini +[databases] +dhamps_vdb = host=localhost port=5432 dbname=dhamps_vdb + +[pgbouncer] +listen_addr = 127.0.0.1 +listen_port = 6432 +auth_type = md5 +auth_file = /etc/pgbouncer/userlist.txt +pool_mode = transaction +max_client_conn = 1000 +default_pool_size = 20 +``` + +Connect dhamps-vdb to PgBouncer instead of PostgreSQL directly. + +### SSL/TLS Encryption + +Enable SSL in `postgresql.conf`: + +```ini +ssl = on +ssl_cert_file = '/etc/postgresql/server.crt' +ssl_key_file = '/etc/postgresql/server.key' +ssl_ca_file = '/etc/postgresql/ca.crt' +``` + +Update connection string: + +```bash +# Update dhamps-vdb configuration +SERVICE_DBHOST=db.example.com +# Change connection to use SSL (requires code modification or PostgreSQL parameter) +``` + +### Network Security + +Restrict access in `pg_hba.conf`: + +``` +# TYPE DATABASE USER ADDRESS METHOD + +# Allow dhamps_user from application server only +host dhamps_vdb dhamps_user 10.0.1.0/24 md5 + +# Allow localhost connections +local all all peer +host all all 127.0.0.1/32 md5 +host all all ::1/128 md5 +``` + +Reload PostgreSQL: + +```bash +sudo systemctl reload postgresql +``` + +## Backup and Recovery + +### Automated Backups + +Daily backup script: + +```bash +#!/bin/bash +# /usr/local/bin/backup-dhamps-vdb.sh + +BACKUP_DIR="/backups/dhamps-vdb" +DATE=$(date +%Y%m%d_%H%M%S) +DB_NAME="dhamps_vdb" + +# Create backup +pg_dump -U dhamps_user -h localhost $DB_NAME | gzip > "$BACKUP_DIR/dhamps-vdb-$DATE.sql.gz" + +# Keep last 30 days +find $BACKUP_DIR -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete + +# Verify backup +if [ $? -eq 0 ]; then + echo "Backup successful: $DATE" +else + echo "Backup failed: $DATE" >&2 + exit 1 +fi +``` + +Set up cron job: + +```bash +# Run daily at 2 AM +0 2 * * * /usr/local/bin/backup-dhamps-vdb.sh +``` + +### Restore from Backup + +```bash +# Decompress and restore +gunzip -c /backups/dhamps-vdb/dhamps-vdb-20240208.sql.gz | \ + psql -U dhamps_user -h localhost dhamps_vdb +``` + +### Point-in-Time Recovery (PITR) + +Enable WAL archiving in `postgresql.conf`: + +```ini +wal_level = replica +archive_mode = on +archive_command = 'test ! -f /archive/%f && cp %p /archive/%f' +``` + +## Monitoring + +### Check Database Size + +```sql +-- Database size +SELECT pg_size_pretty(pg_database_size('dhamps_vdb')); + +-- Table sizes +SELECT + schemaname, + tablename, + pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size +FROM pg_tables +WHERE schemaname = 'public' +ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC; +``` + +### Check Connection Status + +```sql +-- Active connections +SELECT count(*) FROM pg_stat_activity WHERE datname = 'dhamps_vdb'; + +-- Connection details +SELECT + pid, + usename, + application_name, + client_addr, + state, + query +FROM pg_stat_activity +WHERE datname = 'dhamps_vdb'; +``` + +### Monitor Performance + +```sql +-- Enable pg_stat_statements +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; + +-- View slow queries +SELECT + query, + calls, + total_time, + mean_time, + max_time +FROM pg_stat_statements +WHERE query NOT LIKE '%pg_stat_statements%' +ORDER BY mean_time DESC +LIMIT 10; +``` + +## Troubleshooting + +### Cannot Connect to Database + +```bash +# Check if PostgreSQL is running +sudo systemctl status postgresql + +# Check PostgreSQL logs +sudo tail -f /var/log/postgresql/postgresql-16-main.log + +# Test connection +psql -h localhost -U dhamps_user -d dhamps_vdb +``` + +### pgvector Extension Not Found + +```sql +-- Check available extensions +SELECT * FROM pg_available_extensions WHERE name = 'vector'; + +-- If not listed, install pgvector package +-- See installation section above +``` + +### Permission Denied + +```sql +-- Reconnect as superuser +\c dhamps_vdb postgres + +-- Re-grant privileges +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; +GRANT ALL ON SCHEMA public TO dhamps_user; +GRANT ALL ON ALL TABLES IN SCHEMA public TO dhamps_user; +GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO dhamps_user; + +-- For future objects +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO dhamps_user; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO dhamps_user; +``` + +### Out of Disk Space + +```bash +# Check disk usage +df -h + +# Check PostgreSQL data directory +du -sh /var/lib/postgresql/16/main/ + +# Clean up old WAL files (if safe) +# Check archive status first +``` + +### Slow Queries + +```sql +-- Check missing indexes +SELECT + schemaname, + tablename, + attname, + n_distinct, + correlation +FROM pg_stats +WHERE schemaname = 'public' +ORDER BY n_distinct DESC; + +-- Analyze tables +ANALYZE; + +-- Vacuum tables +VACUUM ANALYZE; +``` + +## Migration from Other Databases + +dhamps-vdb is designed specifically for PostgreSQL with pgvector. Migration from other databases requires: + +1. Export data from source database +2. Set up PostgreSQL with pgvector +3. Transform data to match dhamps-vdb schema +4. Import using dhamps-vdb API or direct SQL + +## Further Reading + +- [PostgreSQL Documentation](https://www.postgresql.org/docs/) +- [pgvector GitHub](https://github.com/pgvector/pgvector) +- [PostgreSQL Tuning Guide](https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server) +- [Environment Variables](../environment-variables/) +- [Docker Deployment](../docker/) +- [Security Guide](../security/) diff --git a/docs/content/deployment/docker.md b/docs/content/deployment/docker.md new file mode 100644 index 0000000..7c7ea6b --- /dev/null +++ b/docs/content/deployment/docker.md @@ -0,0 +1,297 @@ +--- +title: "Docker Deployment" +weight: 1 +--- + +# Docker Deployment + +This guide covers production-focused Docker deployment for dhamps-vdb. + +## Overview + +For detailed Docker setup instructions, see [Getting Started with Docker](../../getting-started/docker/). This page focuses on production deployment considerations. + +## Production Deployment + +### Prerequisites + +- Docker Engine 20.10+ +- Docker Compose 2.0+ (or docker-compose 1.29+) +- PostgreSQL 11+ with pgvector extension (included in compose setup) + +### Quick Production Setup + +```bash +# Clone repository +git clone https://github.com/mpilhlt/dhamps-vdb.git +cd dhamps-vdb + +# Generate secure keys +./docker-setup.sh + +# Review and customize .env +nano .env + +# Deploy +docker-compose up -d +``` + +## Production Considerations + +### Use Reverse Proxy + +Always run behind a reverse proxy (nginx, Traefik, Caddy) for: + +- **HTTPS/TLS termination** +- **Request filtering** +- **Rate limiting** +- **Load balancing** + +Example nginx configuration: + +```nginx +upstream dhamps-vdb { + server localhost:8880; +} + +server { + listen 443 ssl http2; + server_name api.example.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location / { + proxy_pass http://dhamps-vdb; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +### Container Resource Limits + +Set resource limits in `docker-compose.yml`: + +```yaml +services: + dhamps-vdb: + deploy: + resources: + limits: + cpus: '2' + memory: 2G + reservations: + cpus: '0.5' + memory: 512M + + postgres: + deploy: + resources: + limits: + cpus: '2' + memory: 4G + reservations: + cpus: '1' + memory: 2G +``` + +### Use Specific Image Tags + +Avoid `latest` in production: + +```yaml +services: + postgres: + image: pgvector/pgvector:0.7.4-pg16 # Specific version + + dhamps-vdb: + image: dhamps-vdb:v0.1.0 # Tag your builds +``` + +### Health Monitoring + +The image includes health checks. Monitor with: + +```bash +# Check health status +docker inspect --format='{{.State.Health.Status}}' dhamps-vdb + +# View health check logs +docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' dhamps-vdb + +# Integrate with monitoring (Prometheus, etc.) +``` + +### Logging + +Configure logging drivers in `docker-compose.yml`: + +```yaml +services: + dhamps-vdb: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +Or use centralized logging: + +```yaml +services: + dhamps-vdb: + logging: + driver: "syslog" + options: + syslog-address: "tcp://logserver:514" +``` + +## External Database Deployment + +For production, consider using a managed PostgreSQL service or separate database server. + +### Requirements + +- PostgreSQL 11+ with pgvector extension +- Network connectivity from container to database +- Database user with appropriate privileges + +See [Database Setup](../database/) for detailed instructions. + +### Configuration + +Update `.env`: + +```bash +SERVICE_DBHOST=db.example.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=secure_password +SERVICE_DBNAME=dhamps_vdb +``` + +Modify `docker-compose.yml` to remove postgres service: + +```yaml +services: + dhamps-vdb: + build: . + ports: + - "8880:8880" + env_file: .env + restart: unless-stopped +``` + +## Scaling and High Availability + +### Horizontal Scaling + +Run multiple instances behind a load balancer: + +```yaml +services: + dhamps-vdb: + build: . + deploy: + replicas: 3 + restart_policy: + condition: on-failure +``` + +**Note:** All instances must connect to the same database. + +### Database Replication + +For high availability: + +- Use PostgreSQL replication (streaming or logical) +- Consider read replicas for read-heavy workloads +- Point write operations to primary, reads to replicas + +## Backup Strategy + +### Database Backups + +```bash +# Automated daily backups +0 2 * * * docker-compose exec -T postgres pg_dump -U postgres dhamps_vdb | gzip > /backups/dhamps-vdb-$(date +\%Y\%m\%d).sql.gz + +# Keep last 30 days +find /backups -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete +``` + +### Volume Backups + +```bash +# Backup Docker volume +docker run --rm -v dhamps-vdb_postgres_data:/data -v /backups:/backup alpine tar czf /backup/postgres-data-$(date +\%Y\%m\%d).tar.gz /data +``` + +### Environment Configuration Backups + +```bash +# Backup .env (securely!) +gpg --encrypt --recipient admin@example.com .env > .env.gpg +``` + +## Troubleshooting + +### Container Performance Issues + +```bash +# Check resource usage +docker stats + +# Check container logs +docker-compose logs -f --tail=100 dhamps-vdb + +# Check slow queries (if database is slow) +docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;" +``` + +### Network Connectivity Issues + +```bash +# Test database connection from container +docker-compose exec dhamps-vdb nc -zv postgres 5432 + +# Check DNS resolution +docker-compose exec dhamps-vdb nslookup postgres + +# Test API from inside container +docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs +``` + +### Update and Rollback + +```bash +# Update to new version +docker-compose pull +docker-compose up -d + +# Rollback if needed +docker-compose down +docker-compose up -d --force-recreate +``` + +## Security Best Practices + +- See [Security Guide](../security/) for comprehensive security recommendations +- Use [Environment Variables Guide](../environment-variables/) for proper configuration +- Never expose database port publicly +- Use strong, randomly generated keys (see `./docker-setup.sh`) +- Keep Docker and images updated +- Run containers as non-root (already configured) + +## Further Reading + +- [Docker Official Documentation](https://docs.docker.com/) +- [PostgreSQL Docker Hub](https://hub.docker.com/_/postgres) +- [pgvector Extension](https://github.com/pgvector/pgvector) +- [Database Setup Guide](../database/) +- [Environment Variables Reference](../environment-variables/) +- [Security Best Practices](../security/) diff --git a/docs/content/deployment/environment-variables.md b/docs/content/deployment/environment-variables.md new file mode 100644 index 0000000..6e143f0 --- /dev/null +++ b/docs/content/deployment/environment-variables.md @@ -0,0 +1,493 @@ +--- +title: "Environment Variables" +weight: 3 +--- + +# Environment Variables + +Complete reference for all environment variables used by dhamps-vdb. + +## Overview + +dhamps-vdb is configured entirely through environment variables. These can be set: + +1. **In a `.env` file** (recommended for Docker) +2. **As system environment variables** +3. **Via command-line flags** (some variables only) + +## Required Variables + +These variables **must** be set for dhamps-vdb to function: + +### SERVICE_ADMINKEY + +Admin API key for administrative operations. + +- **Type:** String +- **Required:** Yes +- **Default:** None +- **Environment Variable:** `SERVICE_ADMINKEY` +- **Command-line Flag:** `--admin-key` + +**Description:** Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations. + +**Example:** + +```bash +SERVICE_ADMINKEY=Ch4ngeM3SecureAdminKey! +``` + +**Security:** +- Generate with: `openssl rand -base64 32` +- Never commit to version control +- Rotate regularly +- Store securely (password manager, secrets vault) + +**Usage:** + +```bash +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer $SERVICE_ADMINKEY" \ + -H "Content-Type: application/json" \ + -d '{"user_handle": "alice", "full_name": "Alice Smith"}' +``` + +### ENCRYPTION_KEY + +Encryption key for protecting user API keys in the database. + +- **Type:** String (32+ characters) +- **Required:** Yes +- **Default:** None +- **Environment Variable:** `ENCRYPTION_KEY` + +**Description:** AES-256 encryption key used to encrypt user API keys before storing them in the database. Must be at least 32 characters. The key is hashed with SHA-256 to ensure exactly 32 bytes for AES-256 encryption. + +**Example:** + +```bash +ENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6 +``` + +**Security:** +- Generate with: `openssl rand -hex 32` +- Minimum 32 characters required +- Never commit to version control +- **CRITICAL:** If lost, all stored API keys become unrecoverable +- Backup securely and separately from database +- Never change in production (will invalidate all existing API keys) + +**Technical Details:** +- Uses AES-256-GCM for encryption +- SHA-256 hash ensures correct key length +- Each encryption uses unique nonce +- Encrypted keys stored as base64 in database + +## Optional Variables + +### SERVICE_DEBUG + +Enable debug logging. + +- **Type:** Boolean +- **Required:** No +- **Default:** `true` +- **Environment Variable:** `SERVICE_DEBUG` +- **Command-line Flag:** `-d`, `--debug` + +**Description:** Enables verbose debug logging including request details, SQL queries, and internal operations. + +**Example:** + +```bash +SERVICE_DEBUG=false # Production (less verbose) +SERVICE_DEBUG=true # Development (verbose) +``` + +**Impact:** +- `true`: Detailed logs, useful for debugging +- `false`: Minimal logs, recommended for production + +### SERVICE_HOST + +Hostname or IP address to bind the service to. + +- **Type:** String +- **Required:** No +- **Default:** `localhost` +- **Environment Variable:** `SERVICE_HOST` +- **Command-line Flag:** `--host` + +**Description:** Network interface to listen on. Use `0.0.0.0` to listen on all interfaces (required for Docker). + +**Examples:** + +```bash +SERVICE_HOST=localhost # Local development only +SERVICE_HOST=0.0.0.0 # Listen on all interfaces (Docker) +SERVICE_HOST=10.0.1.5 # Specific interface +``` + +**Security:** +- Use `localhost` for development +- Use `0.0.0.0` for Docker/production with firewall +- Never expose directly to internet without reverse proxy + +### SERVICE_PORT + +Port number for the API service. + +- **Type:** Integer +- **Required:** No +- **Default:** `8880` +- **Environment Variable:** `SERVICE_PORT` +- **Command-line Flag:** `-p`, `--port` + +**Description:** TCP port the service listens on. + +**Example:** + +```bash +SERVICE_PORT=8880 # Default +SERVICE_PORT=8080 # Alternative +SERVICE_PORT=3000 # Custom +``` + +**Notes:** +- Ports below 1024 require root/admin privileges +- Ensure port is not already in use +- Update firewall rules accordingly + +## Database Variables + +### SERVICE_DBHOST + +Database hostname or IP address. + +- **Type:** String +- **Required:** No +- **Default:** `localhost` +- **Environment Variable:** `SERVICE_DBHOST` +- **Command-line Flag:** `--db-host` + +**Description:** PostgreSQL server hostname. + +**Examples:** + +```bash +SERVICE_DBHOST=localhost # Local PostgreSQL +SERVICE_DBHOST=postgres # Docker Compose service name +SERVICE_DBHOST=db.example.com # Remote database +SERVICE_DBHOST=10.0.1.100 # Database IP address +``` + +### SERVICE_DBPORT + +Database port number. + +- **Type:** Integer +- **Required:** No +- **Default:** `5432` +- **Environment Variable:** `SERVICE_DBPORT` +- **Command-line Flag:** `--db-port` + +**Description:** PostgreSQL server port. + +**Example:** + +```bash +SERVICE_DBPORT=5432 # Default PostgreSQL port +SERVICE_DBPORT=5433 # Alternative port +``` + +### SERVICE_DBUSER + +Database username. + +- **Type:** String +- **Required:** No +- **Default:** `postgres` +- **Environment Variable:** `SERVICE_DBUSER` +- **Command-line Flag:** `--db-user` + +**Description:** PostgreSQL user for database connections. + +**Example:** + +```bash +SERVICE_DBUSER=postgres # Default superuser +SERVICE_DBUSER=dhamps_user # Dedicated user (recommended) +``` + +**Security:** +- Create dedicated user (not superuser) for production +- Use principle of least privilege +- See [Database Setup](../database/) for user creation + +### SERVICE_DBPASSWORD + +Database password. + +- **Type:** String +- **Required:** No +- **Default:** `password` +- **Environment Variable:** `SERVICE_DBPASSWORD` +- **Command-line Flag:** `--db-password` + +**Description:** Password for database authentication. + +**Example:** + +```bash +SERVICE_DBPASSWORD=secure_database_password_here +``` + +**Security:** +- Use strong, randomly generated password +- Never use default password in production +- Never commit to version control +- Store in secrets management system +- Rotate regularly + +### SERVICE_DBNAME + +Database name. + +- **Type:** String +- **Required:** No +- **Default:** `postgres` +- **Environment Variable:** `SERVICE_DBNAME` +- **Command-line Flag:** `--db-name` + +**Description:** Name of the PostgreSQL database. + +**Example:** + +```bash +SERVICE_DBNAME=dhamps_vdb # Production database +SERVICE_DBNAME=dhamps_test # Testing database +``` + +## Configuration Examples + +### Development Setup + +```bash +# .env file for development +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8880 +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=postgres +SERVICE_DBNAME=dhamps_vdb +SERVICE_ADMINKEY=dev-admin-key-not-for-production +ENCRYPTION_KEY=dev-encryption-key-min-32-chars-long +``` + +### Docker Compose Setup + +```bash +# .env file for Docker Compose +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 +SERVICE_DBHOST=postgres +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=secure_db_password_here +SERVICE_DBNAME=dhamps_vdb +SERVICE_ADMINKEY=generated_admin_key_from_setup_script +ENCRYPTION_KEY=generated_encryption_key_from_setup_script +``` + +### Production Setup + +```bash +# .env file for production (or use secrets management) +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 +SERVICE_DBHOST=db.internal.example.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_prod_user +SERVICE_DBPASSWORD= +SERVICE_DBNAME=dhamps_vdb_prod +SERVICE_ADMINKEY= +ENCRYPTION_KEY= +``` + +## Setting Environment Variables + +### Using .env File (Recommended) + +Create a `.env` file in the project root: + +```bash +# Copy template +cp template.env .env + +# Edit with your values +nano .env +``` + +The application automatically loads `.env` on startup. + +### Using System Environment Variables + +```bash +# Linux/macOS +export SERVICE_ADMINKEY="your-admin-key" +export ENCRYPTION_KEY="your-encryption-key" + +# Windows PowerShell +$env:SERVICE_ADMINKEY = "your-admin-key" +$env:ENCRYPTION_KEY = "your-encryption-key" + +# Windows Command Prompt +set SERVICE_ADMINKEY=your-admin-key +set ENCRYPTION_KEY=your-encryption-key +``` + +### Using Docker + +With docker run: + +```bash +docker run -d \ + -e SERVICE_ADMINKEY=admin-key \ + -e ENCRYPTION_KEY=encryption-key \ + -e SERVICE_DBHOST=db-host \ + dhamps-vdb:latest +``` + +With docker-compose.yml: + +```yaml +services: + dhamps-vdb: + image: dhamps-vdb:latest + environment: + SERVICE_DEBUG: "false" + SERVICE_HOST: "0.0.0.0" + SERVICE_PORT: "8880" + SERVICE_DBHOST: "postgres" + env_file: + - .env # Load additional variables from file +``` + +### Using Command-Line Flags + +Some variables support command-line flags: + +```bash +./dhamps-vdb \ + --debug \ + --host 0.0.0.0 \ + --port 8880 \ + --admin-key your-admin-key \ + --db-host localhost \ + --db-port 5432 \ + --db-user postgres \ + --db-password password \ + --db-name dhamps_vdb +``` + +**Note:** ENCRYPTION_KEY must be set as environment variable, not flag. + +## Validation and Troubleshooting + +### Missing Required Variables + +If required variables are not set, the service will fail to start: + +``` +Error: SERVICE_ADMINKEY environment variable is not set +``` + +**Solution:** Set the missing variable. + +### Invalid ENCRYPTION_KEY + +If ENCRYPTION_KEY is too short or invalid: + +``` +Error: ENCRYPTION_KEY environment variable is not set +``` + +**Solution:** Ensure key is at least 32 characters: + +```bash +openssl rand -hex 32 +``` + +### Database Connection Failure + +``` +Error: failed to connect to database +``` + +**Check:** +- `SERVICE_DBHOST` is correct and reachable +- `SERVICE_DBPORT` is correct +- `SERVICE_DBUSER` and `SERVICE_DBPASSWORD` are valid +- `SERVICE_DBNAME` exists +- PostgreSQL is running +- Firewall allows connection + +### Testing Configuration + +```bash +# Start service with debug logging +SERVICE_DEBUG=true ./dhamps-vdb + +# Check if service starts successfully +curl http://localhost:8880/docs + +# Test admin authentication +curl -X GET http://localhost:8880/v1/users \ + -H "Authorization: Bearer $SERVICE_ADMINKEY" +``` + +## Security Best Practices + +1. **Never commit `.env` files** to version control + - Already in `.gitignore` + - Use `.env.example` templates + +2. **Generate secure random keys** + ```bash + openssl rand -base64 32 # Admin key + openssl rand -hex 32 # Encryption key + ``` + +3. **Use secrets management** in production + - HashiCorp Vault + - AWS Secrets Manager + - Azure Key Vault + - Docker Secrets (Swarm) + - Kubernetes Secrets + +4. **Rotate keys regularly** + - Admin key: Every 90 days + - Database password: Every 90 days + - **Encryption key:** Cannot be rotated without re-encrypting all API keys + +5. **Principle of least privilege** + - Use dedicated database user (not superuser) + - Grant only necessary permissions + - Restrict network access + +6. **Monitor and audit** + - Log admin key usage + - Monitor failed authentication attempts + - Review access patterns + +## Further Reading + +- [Docker Deployment Guide](../docker/) +- [Database Setup](../database/) +- [Security Best Practices](../security/) +- [Configuration Guide](../../getting-started/configuration/) +- [Quick Start](../../getting-started/quick-start/) diff --git a/docs/content/deployment/security.md b/docs/content/deployment/security.md new file mode 100644 index 0000000..7de673a --- /dev/null +++ b/docs/content/deployment/security.md @@ -0,0 +1,741 @@ +--- +title: "Security Best Practices" +weight: 4 +--- + +# Security Best Practices + +Comprehensive guide for securing your dhamps-vdb production deployment. + +## Security Overview + +dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments. + +## HTTPS/TLS Configuration + +### Why HTTPS is Required + +- **Encryption in transit**: Protects API keys and data from interception +- **Authentication**: Verifies server identity +- **Compliance**: Required by most security standards + +### Using a Reverse Proxy + +**Never expose dhamps-vdb directly to the internet.** Always use a reverse proxy with TLS termination. + +#### Nginx with Let's Encrypt + +Install Certbot: + +```bash +sudo apt install nginx certbot python3-certbot-nginx +``` + +Configure nginx (`/etc/nginx/sites-available/dhamps-vdb`): + +```nginx +upstream dhamps_backend { + server 127.0.0.1:8880; + keepalive 32; +} + +server { + listen 80; + server_name api.example.com; + + # Redirect HTTP to HTTPS + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name api.example.com; + + # SSL certificates (managed by Certbot) + ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; + + # Modern SSL configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # HSTS (HTTP Strict Transport Security) + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + # Security headers + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Proxy settings + location / { + proxy_pass http://dhamps_backend; + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Connection ""; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # Buffer settings + proxy_buffering on; + proxy_buffer_size 4k; + proxy_buffers 8 4k; + } + + # Rate limiting (optional, see below) + limit_req zone=api_limit burst=20 nodelay; + limit_req_status 429; +} +``` + +Enable site and get certificate: + +```bash +sudo ln -s /etc/nginx/sites-available/dhamps-vdb /etc/nginx/sites-enabled/ +sudo certbot --nginx -d api.example.com +sudo systemctl reload nginx +``` + +Auto-renewal: + +```bash +# Certbot creates a systemd timer automatically +sudo systemctl status certbot.timer + +# Test renewal +sudo certbot renew --dry-run +``` + +#### Traefik (Docker) + +`docker-compose.yml`: + +```yaml +version: '3.8' + +services: + traefik: + image: traefik:v2.10 + command: + - "--providers.docker=true" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com" + - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./letsencrypt:/letsencrypt + + dhamps-vdb: + build: . + labels: + - "traefik.enable=true" + - "traefik.http.routers.dhamps-vdb.rule=Host(`api.example.com`)" + - "traefik.http.routers.dhamps-vdb.entrypoints=websecure" + - "traefik.http.routers.dhamps-vdb.tls.certresolver=letsencrypt" + # Redirect HTTP to HTTPS + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + - "traefik.http.routers.dhamps-vdb-http.rule=Host(`api.example.com`)" + - "traefik.http.routers.dhamps-vdb-http.entrypoints=web" + - "traefik.http.routers.dhamps-vdb-http.middlewares=redirect-to-https" +``` + +#### Caddy (Automatic HTTPS) + +`Caddyfile`: + +``` +api.example.com { + reverse_proxy localhost:8880 + + # Automatic HTTPS via Let's Encrypt + tls admin@example.com + + # Security headers + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains" + X-Frame-Options "DENY" + X-Content-Type-Options "nosniff" + X-XSS-Protection "1; mode=block" + } +} +``` + +## API Key Management + +### Admin Key Security + +The `SERVICE_ADMINKEY` has full control over the system. + +**Best practices:** + +1. **Generate securely:** + ```bash + openssl rand -base64 32 + ``` + +2. **Store securely:** + - Password manager (1Password, Bitwarden) + - Secrets manager (Vault, AWS Secrets Manager) + - Never in version control + - Never in logs or error messages + +3. **Rotate regularly:** + - Every 90 days minimum + - After team member departure + - After suspected compromise + +4. **Audit usage:** + - Log all admin operations + - Monitor for unusual activity + - Review regularly + +### User API Keys + +User API keys are automatically generated and encrypted before database storage. + +**Security features:** + +- **One-time display:** Keys shown only at creation +- **Encrypted storage:** AES-256-GCM encryption +- **Non-recoverable:** Lost keys cannot be retrieved + +**For users:** + +1. **Secure storage:** + - Use environment variables + - Never hardcode in applications + - Never commit to repositories + +2. **Use HTTPS:** + - Always transmit over TLS + - Validate server certificates + +3. **Rotate if compromised:** + - Delete old user and create new one + - Update all client applications + +### Bearer Token Authentication + +All API requests require authentication: + +```bash +curl -X GET https://api.example.com/v1/projects/alice \ + -H "Authorization: Bearer your-api-key-here" +``` + +**Security:** + +- Use `Authorization` header (not query parameters) +- Never log full API keys +- Validate on every request +- Use HTTPS to prevent interception + +## Encryption Key Security + +The `ENCRYPTION_KEY` protects all user API keys in the database. + +### Critical Security Points + +⚠️ **CRITICAL:** If the encryption key is lost or changed, **all user API keys become permanently unrecoverable.** + +**Best practices:** + +1. **Generate securely:** + ```bash + openssl rand -hex 32 + ``` + +2. **Backup separately:** + - Store in multiple secure locations + - Separate from database backups + - Document recovery procedure + - Test recovery process + +3. **Never rotate in production:** + - Cannot be changed without re-encrypting all keys + - Requires database migration + - Risk of data loss + +4. **Protect at rest:** + - Encrypt .env files: `gpg --encrypt .env` + - Use secrets management (Vault, AWS Secrets Manager) + - Restrict file permissions: `chmod 600 .env` + +5. **Protect in transit:** + - Never send over unencrypted channels + - Use secure channels for team sharing + - Avoid email/chat + +### Encryption Details + +- **Algorithm:** AES-256-GCM +- **Key derivation:** SHA-256 hash of input key +- **Nonce:** Unique per encryption +- **Authentication:** GCM provides authentication +- **Storage format:** Base64-encoded ciphertext + +### Disaster Recovery + +Document and test recovery procedure: + +```markdown +## Encryption Key Recovery Procedure + +1. Retrieve backup encryption key from [location] +2. Verify key integrity: [checksum/hash] +3. Update deployment configuration +4. Restart services +5. Verify user authentication works +6. Document incident +``` + +## Database Security + +### Network Security + +1. **Restrict access:** + ```sql + -- In pg_hba.conf + # Allow only from application server + host dhamps_vdb dhamps_user 10.0.1.0/24 md5 + ``` + +2. **Firewall rules:** + ```bash + # UFW example + sudo ufw allow from 10.0.1.0/24 to any port 5432 + sudo ufw deny 5432 + ``` + +3. **Use VPC/private network:** + - Keep database on private network + - No public internet exposure + - VPN for remote administration + +### Database Authentication + +1. **Strong passwords:** + ```bash + # Generate secure password + openssl rand -base64 32 + ``` + +2. **Dedicated user:** + ```sql + -- Not superuser + CREATE USER dhamps_user WITH PASSWORD 'secure_password'; + GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; + ``` + +3. **SSL/TLS connections:** + ```ini + # postgresql.conf + ssl = on + ssl_cert_file = 'server.crt' + ssl_key_file = 'server.key' + ssl_ca_file = 'ca.crt' + ``` + +### Database Encryption + +1. **Encryption at rest:** + - Use encrypted filesystems (LUKS, dm-crypt) + - Cloud provider encryption (AWS RDS encryption) + - Transparent Data Encryption (TDE) + +2. **Backup encryption:** + ```bash + # Encrypt backup + pg_dump -U postgres dhamps_vdb | gzip | \ + gpg --encrypt --recipient admin@example.com > backup.sql.gz.gpg + ``` + +### Database Auditing + +Enable audit logging: + +```sql +-- Install pgaudit +CREATE EXTENSION pgaudit; + +-- Configure logging +ALTER SYSTEM SET pgaudit.log = 'write, ddl'; +ALTER SYSTEM SET pgaudit.log_catalog = off; +ALTER SYSTEM SET pgaudit.log_parameter = on; + +-- Reload config +SELECT pg_reload_conf(); +``` + +## Network Security + +### Firewall Configuration + +```bash +# UFW example +sudo ufw default deny incoming +sudo ufw default allow outgoing + +# Allow SSH +sudo ufw allow 22/tcp + +# Allow HTTP/HTTPS (reverse proxy) +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp + +# Application port (if not behind proxy) +# sudo ufw allow from trusted_network to any port 8880 + +# Database (from app server only) +sudo ufw allow from 10.0.1.0/24 to any port 5432 + +sudo ufw enable +``` + +### Network Segmentation + +Deploy in isolated networks: + +``` +Internet + ↓ +[Reverse Proxy] ← (DMZ/Public subnet) + ↓ +[dhamps-vdb] ← (Application subnet) + ↓ +[PostgreSQL] ← (Database subnet) +``` + +### Rate Limiting + +Protect against abuse and DoS attacks. + +**Nginx:** + +```nginx +# Define rate limit zone +http { + limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; + limit_req_zone $binary_remote_addr zone=api_burst:10m rate=100r/s; +} + +server { + location /v1/ { + limit_req zone=api_limit burst=20 nodelay; + limit_req_status 429; + proxy_pass http://dhamps_backend; + } +} +``` + +**Application-level** (future enhancement): +- Implement token bucket or leaky bucket +- Per-user rate limits +- Different limits for different endpoints + +## Backup Strategies + +### Database Backups + +1. **Automated daily backups:** + ```bash + #!/bin/bash + # /usr/local/bin/backup-dhamps.sh + + DATE=$(date +%Y%m%d_%H%M%S) + BACKUP_DIR="/backups/dhamps-vdb" + + # Create backup + pg_dump -U dhamps_user dhamps_vdb | gzip > \ + "$BACKUP_DIR/db-$DATE.sql.gz" + + # Encrypt backup + gpg --encrypt --recipient admin@example.com \ + "$BACKUP_DIR/db-$DATE.sql.gz" + + # Remove unencrypted backup + rm "$BACKUP_DIR/db-$DATE.sql.gz" + + # Verify backup + gpg --decrypt "$BACKUP_DIR/db-$DATE.sql.gz.gpg" | gunzip | head -n 5 + + # Upload to offsite storage + aws s3 cp "$BACKUP_DIR/db-$DATE.sql.gz.gpg" \ + s3://backups/dhamps-vdb/ --storage-class GLACIER + + # Cleanup old local backups (keep 7 days) + find $BACKUP_DIR -name "db-*.sql.gz.gpg" -mtime +7 -delete + ``` + +2. **Cron schedule:** + ```cron + 0 2 * * * /usr/local/bin/backup-dhamps.sh + ``` + +3. **Test restores regularly:** + ```bash + # Monthly restore test + 0 3 1 * * /usr/local/bin/test-restore.sh + ``` + +### Configuration Backups + +```bash +# Backup environment configuration +cp .env .env.backup +gpg --encrypt --recipient admin@example.com .env.backup + +# Backup with timestamp +tar czf config-$(date +%Y%m%d).tar.gz .env docker-compose.yml +gpg --encrypt --recipient admin@example.com config-*.tar.gz +``` + +### Backup Retention Policy + +- **Daily backups:** Keep 7 days locally +- **Weekly backups:** Keep 4 weeks offsite +- **Monthly backups:** Keep 12 months in cold storage +- **Yearly backups:** Keep 7 years (compliance dependent) + +### Offsite Backups + +Always maintain offsite backups: + +- **Cloud storage:** AWS S3, Azure Blob Storage, GCP Cloud Storage +- **Different geographic region** +- **Encrypted before upload** +- **Test restoration procedures** + +## Monitoring and Alerting + +### What to Monitor + +1. **Authentication failures:** + ```bash + # Parse logs for 401 responses + grep "401" /var/log/nginx/access.log | wc -l + ``` + +2. **Unusual API usage:** + - Spike in requests + - Requests to non-existent endpoints + - Large data transfers + +3. **Database health:** + - Connection count + - Query performance + - Disk usage + - Replication lag (if applicable) + +4. **System resources:** + - CPU usage + - Memory usage + - Disk I/O + - Network throughput + +### Log Management + +1. **Centralized logging:** + - ELK Stack (Elasticsearch, Logstash, Kibana) + - Splunk + - Graylog + - CloudWatch Logs (AWS) + +2. **Log retention:** + - Application logs: 30 days minimum + - Access logs: 90 days minimum + - Audit logs: 1 year minimum (compliance dependent) + +3. **Log security:** + - Never log API keys in full (mask: `api_key=abc...xyz`) + - Never log passwords + - Encrypt archived logs + - Restrict access to logs + +### Alerting + +Set up alerts for: + +- Failed authentication attempts (>10/minute) +- Database connection failures +- Disk space >80% full +- Service downtime +- Unusual network traffic +- SSL certificate expiration (30 days before) + +## Security Checklist + +Use this checklist for production deployments: + +### Pre-Deployment + +- [ ] Strong, random `SERVICE_ADMINKEY` generated +- [ ] Strong, random `ENCRYPTION_KEY` generated (32+ chars) +- [ ] Strong database password set +- [ ] `.env` file encrypted or in secrets manager +- [ ] `.env` not in version control +- [ ] Encryption key backed up separately from database + +### Network & Access + +- [ ] HTTPS/TLS configured with valid certificate +- [ ] Reverse proxy deployed (nginx/Traefik/Caddy) +- [ ] Firewall configured and enabled +- [ ] Database on private network only +- [ ] Rate limiting configured +- [ ] HSTS header enabled +- [ ] Security headers configured + +### Database + +- [ ] PostgreSQL 11+ with pgvector installed +- [ ] Dedicated database user (not superuser) +- [ ] Strong database password +- [ ] SSL/TLS for database connections +- [ ] Database firewall rules configured +- [ ] pg_hba.conf restricts access by IP +- [ ] Regular backups configured +- [ ] Backup encryption enabled +- [ ] Restore procedure tested + +### Application + +- [ ] Service runs as non-root user +- [ ] Debug logging disabled (`SERVICE_DEBUG=false`) +- [ ] Resource limits configured +- [ ] Health checks enabled +- [ ] Logging configured +- [ ] Monitoring configured +- [ ] Alerting configured + +### Operations + +- [ ] Backup procedure documented +- [ ] Restore procedure documented and tested +- [ ] Disaster recovery plan created +- [ ] Security incident response plan created +- [ ] Key rotation schedule defined +- [ ] Access control documented (who has admin key) +- [ ] Regular security updates scheduled + +### Compliance + +- [ ] Data retention policy defined +- [ ] Privacy policy reviewed +- [ ] Terms of service reviewed +- [ ] GDPR compliance (if applicable) +- [ ] Data processing agreements in place +- [ ] Audit logging enabled + +## Incident Response + +### Suspected API Key Compromise + +1. **Immediate actions:** + - Identify compromised user + - Delete user (invalidates API key) + - Create new user with new API key + - Review access logs for unauthorized access + +2. **Investigation:** + - Determine scope of compromise + - Check for data exfiltration + - Document incident + +3. **Notification:** + - Notify affected parties (if required) + - Document lessons learned + - Update security procedures + +### Database Breach + +1. **Immediate actions:** + - Isolate database server + - Revoke network access + - Change all database credentials + - Activate incident response team + +2. **Assessment:** + - Determine data accessed + - Check encryption effectiveness + - Review audit logs + +3. **Recovery:** + - Restore from clean backup + - Apply security patches + - Update firewall rules + - Notify affected parties (if required) + - Document and learn + +### Encryption Key Loss + +⚠️ **CRITICAL SITUATION:** If encryption key is lost, all user API keys are unrecoverable. + +1. **Recovery attempt:** + - Check all backup locations + - Review documentation + - Contact all team members + +2. **If unrecoverable:** + - All users must be deleted and recreated + - New API keys issued to all users + - All client applications must be updated + - Communicate timeline to users + +3. **Prevention:** + - Review backup procedures + - Add redundant backup locations + - Document key locations + - Test recovery process + +## Security Updates + +### Regular Updates + +- **Weekly:** Review security advisories +- **Monthly:** Apply security patches +- **Quarterly:** Security audit and penetration testing +- **Yearly:** Full security review and compliance audit + +### Update Procedure + +1. **Test in staging environment** +2. **Backup production database and configuration** +3. **Schedule maintenance window** +4. **Apply updates** +5. **Verify functionality** +6. **Monitor for issues** + +### Subscribe to Security Advisories + +- PostgreSQL security announcements +- pgvector security updates +- Docker security advisories +- Go security advisories +- Operating system security updates + +## Further Reading + +- [OWASP Top 10](https://owasp.org/www-project-top-ten/) +- [PostgreSQL Security](https://www.postgresql.org/docs/current/security.html) +- [Docker Security Best Practices](https://docs.docker.com/engine/security/) +- [Let's Encrypt Documentation](https://letsencrypt.org/docs/) +- [Environment Variables Reference](../environment-variables/) +- [Database Setup Guide](../database/) +- [Docker Deployment](../docker/) From 949e7dc7b3c89ad45a4c2f7881b0783a57a5b35e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:34:27 +0000 Subject: [PATCH 5/9] Add development documentation: testing, contributing, architecture, performance Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- docs/content/development/architecture.md | 814 +++++++++++++++++++++ docs/content/development/contributing.md | 683 +++++++++++++++++ docs/content/development/performance.md | 888 +++++++++++++++++++++++ docs/content/development/testing.md | 510 +++++++++++++ 4 files changed, 2895 insertions(+) create mode 100644 docs/content/development/architecture.md create mode 100644 docs/content/development/contributing.md create mode 100644 docs/content/development/performance.md create mode 100644 docs/content/development/testing.md diff --git a/docs/content/development/architecture.md b/docs/content/development/architecture.md new file mode 100644 index 0000000..f4ed2bb --- /dev/null +++ b/docs/content/development/architecture.md @@ -0,0 +1,814 @@ +--- +title: "Architecture" +weight: 3 +--- + +# Technical Architecture + +This document provides a technical deep-dive into dhamps-vdb's architecture for developers who want to understand or modify the codebase. + +## Project Structure + +``` +dhamps-vdb/ +├── main.go # Application entry point +├── go.mod # Go module definition +├── go.sum # Dependency checksums +├── sqlc.yaml # sqlc configuration +├── template.env # Environment template +├── .env # Local config (gitignored) +│ +├── api/ +│ └── openapi.yml # OpenAPI spec (not actively maintained) +│ +├── internal/ # Internal packages (non-importable) +│ ├── auth/ # Authentication logic +│ │ └── authenticate.go # Bearer token validation +│ │ +│ ├── crypto/ # Encryption utilities +│ │ └── crypto.go # AES-256-GCM encryption +│ │ +│ ├── database/ # Database layer +│ │ ├── database.go # Connection pool management +│ │ ├── migrations.go # Migration runner +│ │ ├── db.go # Generated by sqlc +│ │ ├── models.go # Generated by sqlc +│ │ ├── queries.sql.go # Generated by sqlc +│ │ │ +│ │ ├── migrations/ # SQL migrations +│ │ │ ├── 001_create_initial_scheme.sql +│ │ │ ├── 002_create_emb_index.sql +│ │ │ ├── 003_add_public_read_flag.sql +│ │ │ ├── 004_refactor_llm_services_architecture.sql +│ │ │ ├── tern.conf.tpl # Template for tern +│ │ │ └── tern.conf # Generated (gitignored) +│ │ │ +│ │ └── queries/ # SQL queries for sqlc +│ │ └── queries.sql # All database queries +│ │ +│ ├── handlers/ # HTTP request handlers +│ │ ├── handlers.go # Common handler utilities +│ │ ├── users.go # User endpoints +│ │ ├── projects.go # Project endpoints +│ │ ├── llm_services.go # LLM service endpoints +│ │ ├── api_standards.go # API standard endpoints +│ │ ├── embeddings.go # Embedding endpoints +│ │ ├── similars.go # Similarity search endpoints +│ │ ├── admin.go # Admin endpoints +│ │ │ +│ │ └── *_test.go # Test files +│ │ ├── users_test.go +│ │ ├── projects_test.go +│ │ ├── projects_sharing_test.go +│ │ ├── embeddings_test.go +│ │ ├── llm_services_test.go +│ │ ├── editor_permissions_test.go +│ │ └── handlers_test.go +│ │ +│ └── models/ # Data models and options +│ ├── options.go # CLI/environment options +│ ├── users.go # User models +│ ├── projects.go # Project models +│ ├── instances.go # LLM instance models (new) +│ ├── api_standards.go # API standard models +│ ├── embeddings.go # Embedding models +│ ├── similars.go # Similarity search models +│ └── admin.go # Admin operation models +│ +├── testdata/ # Test fixtures +│ ├── postgres/ # PostgreSQL test data +│ │ ├── enable-vector.sql +│ │ └── users.yml +│ │ +│ └── *.json # JSON test fixtures +│ ├── valid_user.json +│ ├── valid_embeddings.json +│ ├── valid_api_standard_*.json +│ └── valid_llm_service_*.json +│ +└── docs/ # Documentation + ├── content/ # Hugo content + └── *.md # Additional docs +``` + +## Code Organization + +### 1. Entry Point (`main.go`) + +The application entry point handles: + +```go +func main() { + // 1. Parse CLI options and environment variables + cli := huma.NewCLI(func(hooks huma.Hooks, opts *models.Options) { + + // 2. Initialize database connection pool + pool := database.InitDB(opts) + defer pool.Close() + + // 3. Run database migrations + database.RunMigrations(pool, opts) + + // 4. Create HTTP router and Huma API + router := http.NewServeMux() + api := humago.New(router, huma.DefaultConfig("dhamps-vdb", "0.1.0")) + + // 5. Register all routes + handlers.AddRoutes(pool, keyGen, api) + + // 6. Start HTTP server + server := &http.Server{ + Addr: fmt.Sprintf("%s:%d", opts.Host, opts.Port), + Handler: router, + } + server.ListenAndServe() + }) + + cli.Run() +} +``` + +### 2. Handlers (`internal/handlers/`) + +Handlers process HTTP requests using the Huma framework pattern: + +```go +// Example: Create User Handler +func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { + + // Define request/response types + type CreateUserInput struct { + Body models.CreateUserRequest + } + + type CreateUserOutput struct { + Body models.User + } + + // Register operation with Huma + huma.Register(api, huma.Operation{ + OperationID: "create-user", + Method: http.MethodPost, + Path: "/v1/users", + Summary: "Create a new user", + Description: "Admin only. Creates user and returns API key.", + Security: []map[string][]string{{"bearer": {}}}, + }, func(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { + + // 1. Get authenticated user from context + authUser := auth.GetAuthenticatedUser(ctx) + + // 2. Check authorization (admin only) + if !authUser.IsAdmin { + return nil, huma.Error403Forbidden("admin access required") + } + + // 3. Validate input + if err := input.Body.Validate(); err != nil { + return nil, huma.Error400BadRequest("invalid input", err) + } + + // 4. Business logic + user, apiKey, err := createUserWithKey(ctx, pool, keyGen, &input.Body) + if err != nil { + return nil, handleDatabaseError(err) + } + + // 5. Return response + return &CreateUserOutput{Body: *user}, nil + }) +} +``` + +**Handler file organization:** + +- `handlers.go` - Common utilities (context keys, error handling) +- `users.go` - User CRUD operations +- `projects.go` - Project CRUD and sharing +- `llm_services.go` - LLM service/instance management +- `embeddings.go` - Embedding CRUD operations +- `similars.go` - Similarity search +- `admin.go` - Administrative operations + +### 3. Models (`internal/models/`) + +Models define request/response structures: + +```go +// User model +type User struct { + UserHandle string `json:"user_handle" example:"alice"` + Name string `json:"name" example:"Alice Smith"` + Email string `json:"email" example:"alice@example.com"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// Request model with validation +type CreateUserRequest struct { + UserHandle string `json:"user_handle" minLength:"1" maxLength:"50" pattern:"^[a-z0-9_-]+$"` + Name string `json:"name" minLength:"1" maxLength:"100"` + Email string `json:"email" format:"email"` +} + +func (r *CreateUserRequest) Validate() error { + if r.UserHandle == "" { + return fmt.Errorf("user_handle is required") + } + if r.UserHandle == "_system" { + return fmt.Errorf("_system is a reserved handle") + } + return nil +} +``` + +**Model conventions:** + +- Request models: `Create*Request`, `Update*Request` +- Response models: `*Response`, `*Output` +- Database models: Match database schema (generated by sqlc) + +### 4. Database Layer (`internal/database/`) + +#### Connection Management (`database.go`) + +```go +func InitDB(opts *models.Options) *pgxpool.Pool { + connString := fmt.Sprintf( + "postgres://%s:%s@%s:%d/%s", + opts.DBUser, opts.DBPassword, + opts.DBHost, opts.DBPort, opts.DBName, + ) + + config, err := pgxpool.ParseConfig(connString) + if err != nil { + log.Fatal(err) + } + + // Configure connection pool + config.MaxConns = 20 + config.MinConns = 5 + config.MaxConnIdleTime = time.Minute * 5 + + pool, err := pgxpool.NewWithConfig(context.Background(), config) + if err != nil { + log.Fatal(err) + } + + return pool +} +``` + +#### Migrations (`migrations.go`) + +Uses [tern](https://github.com/jackc/tern) for versioned migrations: + +```go +func RunMigrations(pool *pgxpool.Pool, opts *models.Options) error { + // Create tern configuration + config := createTernConfig(opts) + + // Initialize migrator + migrator, err := migrate.NewMigrator(context.Background(), pool, "schema_version") + if err != nil { + return err + } + + // Run pending migrations + err = migrator.Migrate(context.Background()) + if err != nil { + return fmt.Errorf("migration failed: %w", err) + } + + return nil +} +``` + +Migration files are numbered sequentially: + +```sql +-- 001_create_initial_scheme.sql +CREATE TABLE users ( + user_id SERIAL PRIMARY KEY, + user_handle TEXT UNIQUE NOT NULL, + vdb_key TEXT UNIQUE NOT NULL, + ... +); + +CREATE TABLE projects ( + project_id SERIAL PRIMARY KEY, + project_handle TEXT NOT NULL, + owner TEXT NOT NULL REFERENCES users(user_handle), + ... +); + +-- 002_create_emb_index.sql +CREATE INDEX embedding_vector_idx +ON embeddings +USING hnsw (vector vector_cosine_ops); +``` + +#### SQLC Queries (`queries/queries.sql`) + +Write SQL, generate type-safe Go code: + +```sql +-- name: UpsertUser :one +INSERT INTO users ( + user_handle, name, email, vdb_key, created_at, updated_at +) VALUES ( + $1, $2, $3, $4, NOW(), NOW() +) +ON CONFLICT (user_handle) DO UPDATE SET + name = EXCLUDED.name, + email = EXCLUDED.email, + updated_at = NOW() +RETURNING *; + +-- name: GetUserByHandle :one +SELECT * FROM users WHERE user_handle = $1; + +-- name: GetAllUsers :many +SELECT user_handle, name, email, created_at, updated_at +FROM users +ORDER BY user_handle ASC; + +-- name: DeleteUser :exec +DELETE FROM users WHERE user_handle = $1; +``` + +Generated Go code (`queries.sql.go`): + +```go +// Generated by sqlc +func (q *Queries) UpsertUser(ctx context.Context, arg UpsertUserParams) (User, error) { + row := q.db.QueryRow(ctx, upsertUser, + arg.UserHandle, + arg.Name, + arg.Email, + arg.VdbKey, + ) + var i User + err := row.Scan( + &i.UserID, + &i.UserHandle, + &i.Name, + &i.Email, + &i.VdbKey, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} +``` + +**sqlc configuration (`sqlc.yaml`):** + +```yaml +version: "2" +sql: + - engine: "postgresql" + queries: "internal/database/queries/queries.sql" + schema: "internal/database/migrations/" + gen: + go: + package: "database" + out: "internal/database" + emit_json_tags: true + emit_db_tags: true + emit_prepared_queries: false + emit_interface: false +``` + +**Regenerate code after query changes:** + +```bash +sqlc generate --no-remote +``` + +### 5. Authentication (`internal/auth/`) + +Token-based authentication using Bearer tokens: + +```go +// Middleware checks Authorization header +func AuthMiddleware(pool *pgxpool.Pool, adminKey string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + // Extract Bearer token + authHeader := r.Header.Get("Authorization") + token := strings.TrimPrefix(authHeader, "Bearer ") + + if token == "" { + // Allow public access for certain endpoints + ctx := context.WithValue(r.Context(), "user", nil) + next.ServeHTTP(w, r.WithContext(ctx)) + return + } + + // Check admin key + if token == adminKey { + user := &AuthUser{Handle: "_admin", IsAdmin: true} + ctx := context.WithValue(r.Context(), "user", user) + next.ServeHTTP(w, r.WithContext(ctx)) + return + } + + // Look up user by API key hash + hash := hashAPIKey(token) + user, err := db.GetUserByKeyHash(r.Context(), pool, hash) + if err != nil { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + authUser := &AuthUser{Handle: user.UserHandle, IsAdmin: false} + ctx := context.WithValue(r.Context(), "user", authUser) + next.ServeHTTP(w, r.WithContext(ctx)) + }) + } +} + +// Helper to get authenticated user from context +func GetAuthenticatedUser(ctx context.Context) *AuthUser { + user, _ := ctx.Value("user").(*AuthUser) + return user +} +``` + +### 6. Encryption (`internal/crypto/`) + +AES-256-GCM encryption for sensitive data (API keys): + +```go +// Encrypt data with AES-256-GCM +func Encrypt(plaintext []byte, key []byte) ([]byte, error) { + // Ensure key is 32 bytes + keyHash := sha256.Sum256(key) + + // Create AES cipher + block, err := aes.NewCipher(keyHash[:]) + if err != nil { + return nil, err + } + + // Create GCM + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + // Generate random nonce + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, err + } + + // Encrypt and append nonce + ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) + return ciphertext, nil +} + +func Decrypt(ciphertext []byte, key []byte) ([]byte, error) { + // Derive key + keyHash := sha256.Sum256(key) + + block, err := aes.NewCipher(keyHash[:]) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + // Extract nonce + nonceSize := gcm.NonceSize() + nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] + + // Decrypt + plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, err + } + + return plaintext, nil +} +``` + +## Huma Framework Integration + +dhamps-vdb uses [Huma](https://huma.rocks/) for API development: + +### Benefits + +1. **Automatic OpenAPI generation** - No manual spec maintenance +2. **Request/response validation** - Type-safe with JSON schema +3. **Error handling** - Standardized error responses +4. **Documentation** - Interactive docs at `/docs` + +### Operation Registration Pattern + +```go +huma.Register(api, huma.Operation{ + OperationID: "get-project", + Method: http.MethodGet, + Path: "/v1/projects/{owner}/{project}", + Summary: "Get project details", + Description: "Returns full project information including metadata schema", + Tags: []string{"Projects"}, + Security: []map[string][]string{{"bearer": {}}}, + MaxBodyBytes: 1024, // Limit request size + DefaultStatus: http.StatusOK, + Errors: []int{400, 401, 403, 404, 500}, +}, handlerFunction) +``` + +### Input/Output Patterns + +```go +// Path parameters, query parameters, and body +type GetSimilarInput struct { + Owner string `path:"owner" doc:"Project owner"` + Project string `path:"project" doc:"Project handle"` + TextID string `path:"text_id" doc:"Text identifier"` + Threshold float32 `query:"threshold" default:"0.5" doc:"Similarity threshold"` + Limit int `query:"limit" default:"10" maximum:"200" doc:"Max results"` +} + +// Response with status code +type GetSimilarOutput struct { + Status int + Body models.SimilarResponse +} +``` + +### Error Response Pattern + +```go +// Standard error responses +return nil, huma.Error400BadRequest("validation failed", err) +return nil, huma.Error401Unauthorized("invalid credentials") +return nil, huma.Error403Forbidden("insufficient permissions") +return nil, huma.Error404NotFound("project not found") +return nil, huma.Error500InternalServerError("database error", err) + +// Custom error with details +return nil, huma.NewError(400, "Dimension Mismatch", + fmt.Sprintf("expected %d dimensions, got %d", expected, actual)) +``` + +## Design Patterns + +### 1. Repository Pattern (via sqlc) + +Database access is centralized in generated queries: + +```go +// Don't write SQL in handlers +// Bad: +rows, err := pool.Query(ctx, "SELECT * FROM users") + +// Good: Use generated functions +users, err := db.GetAllUsers(ctx) +``` + +### 2. Dependency Injection + +Pass dependencies explicitly: + +```go +// Inject pool into handlers +func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { + // Routes have access to pool +} + +// Store in context for handler access +ctx = context.WithValue(ctx, PoolKey, pool) +``` + +### 3. Interface-Based Testing + +Use interfaces for testability: + +```go +// Production: Real random key generator +type StandardKeyGen struct{} +func (s StandardKeyGen) RandomKey(len int) (string, error) { + b := make([]byte, len) + _, err := rand.Read(b) + return hex.EncodeToString(b), err +} + +// Testing: Deterministic key generator +type MockKeyGen struct { + Keys []string + idx int +} +func (m *MockKeyGen) RandomKey(len int) (string, error) { + key := m.Keys[m.idx] + m.idx++ + return key, nil +} +``` + +### 4. Validation at Multiple Layers + +```go +// 1. Huma validates request structure +type CreateEmbeddingInput struct { + Body models.Embedding `maxLength:"1000000"` +} + +// 2. Model validates business rules +func (e *Embedding) Validate() error { + if e.TextID == "" { + return fmt.Errorf("text_id required") + } + return nil +} + +// 3. Handler validates against database state +func CreateEmbedding(ctx context.Context, input *CreateEmbeddingInput) error { + // Check project exists + // Validate dimensions match LLM service + // Validate metadata against schema + // Then insert +} +``` + +### 5. Error Wrapping + +Provide context while preserving original error: + +```go +user, err := db.GetUserByHandle(ctx, handle) +if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, huma.Error404NotFound("user not found") + } + return nil, fmt.Errorf("failed to retrieve user %s: %w", handle, err) +} +``` + +## Internal Packages + +Go's `internal/` directory enforces package privacy: + +```go +// This import works within dhamps-vdb +import "github.com/mpilhlt/dhamps-vdb/internal/database" + +// This import would FAIL from external projects +// Enforced by Go compiler +``` + +Benefits: +- Clear API boundaries +- Implementation details hidden +- Refactoring without breaking external users + +## Performance Considerations + +### Connection Pooling + +```go +config.MaxConns = 20 // Max concurrent connections +config.MinConns = 5 // Keep-alive connections +config.MaxConnIdleTime = 5 * time.Minute +``` + +### Query Optimization + +Use UNION ALL for better performance: + +```go +// Instead of LEFT JOIN with OR conditions +query := ` + SELECT * FROM projects WHERE owner = $1 + UNION ALL + SELECT p.* FROM projects p + INNER JOIN projects_shared_with ps USING (project_id) + WHERE ps.user_handle = $1 + ORDER BY owner, project_handle +` +``` + +### Index Strategy + +```sql +-- Dimension filtering (very important) +CREATE INDEX ON embeddings(project_id, vector_dim); + +-- Vector similarity (HNSW for accuracy) +CREATE INDEX ON embeddings USING hnsw (vector vector_cosine_ops); + +-- Access lookups +CREATE INDEX ON projects_shared_with(user_handle); +CREATE INDEX ON projects(owner, project_handle); +``` + +See [Performance Guide](../performance/) for detailed optimization strategies. + +## Testing Architecture + +### Test Organization + +```go +// handlers_test.go - Setup and utilities +func setupTestDB(t *testing.T) *pgxpool.Pool { } +func createTestUser(t *testing.T, pool *pgxpool.Pool) *models.User { } + +// users_test.go - User-specific tests +func TestCreateUser(t *testing.T) { } +func TestGetUser(t *testing.T) { } + +// projects_sharing_test.go - Sharing feature tests +func TestShareProject(t *testing.T) { } +``` + +### Testcontainers Integration + +```go +func setupTestDB(t *testing.T) *pgxpool.Pool { + ctx := context.Background() + + // Start PostgreSQL with pgvector + req := testcontainers.ContainerRequest{ + Image: "pgvector/pgvector:0.7.4-pg16", + ExposedPorts: []string{"5432/tcp"}, + Env: map[string]string{ + "POSTGRES_PASSWORD": "password", + "POSTGRES_DB": "testdb", + }, + } + + container, err := testcontainers.GenericContainer(ctx, + testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }) + require.NoError(t, err) + + // Connect and migrate + pool := connectAndMigrate(ctx, container) + return pool +} +``` + +See [Testing Guide](../testing/) for comprehensive testing documentation. + +## Build and Deployment + +### Building + +```bash +# Development build +go build -o dhamps-vdb main.go + +# Production build with optimizations +go build -ldflags="-s -w" -o dhamps-vdb main.go + +# Cross-compilation +GOOS=linux GOARCH=amd64 go build -o dhamps-vdb-linux main.go +``` + +### Docker Build + +Multi-stage build for minimal image: + +```dockerfile +# Build stage +FROM golang:1.21-alpine AS builder +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN go build -ldflags="-s -w" -o dhamps-vdb main.go + +# Runtime stage +FROM alpine:latest +RUN apk --no-cache add ca-certificates +WORKDIR /root/ +COPY --from=builder /app/dhamps-vdb . +EXPOSE 8880 +CMD ["./dhamps-vdb"] +``` + +### Configuration + +Application reads configuration from: + +1. **Command line flags**: `--port 8080` +2. **Environment variables**: `SERVICE_PORT=8080` +3. **`.env` file**: `SERVICE_PORT=8080` + +Priority: CLI flags > Environment > .env file > Defaults + +## Next Steps + +- [Testing Guide](testing/) - Learn how to test changes +- [Contributing Guide](contributing/) - Start contributing +- [Performance Guide](performance/) - Optimize queries and indexes diff --git a/docs/content/development/contributing.md b/docs/content/development/contributing.md new file mode 100644 index 0000000..43b778a --- /dev/null +++ b/docs/content/development/contributing.md @@ -0,0 +1,683 @@ +--- +title: "Contributing" +weight: 2 +--- + +# Contributing Guide + +Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started. + +## Development Setup + +### Prerequisites + +- **Go 1.21+**: [Download Go](https://go.dev/dl/) +- **PostgreSQL 16+**: With pgvector extension +- **sqlc**: For generating type-safe database code +- **Docker/Podman**: For running tests +- **Git**: For version control + +### Clone and Build + +```bash +# Clone repository +git clone https://github.com/mpilhlt/dhamps-vdb.git +cd dhamps-vdb + +# Install dependencies +go get ./... + +# Generate sqlc code +sqlc generate --no-remote + +# Build application +go build -o build/dhamps-vdb main.go + +# Or run directly +go run main.go +``` + +### Environment Setup + +Create a `.env` file for local development: + +```bash +# Copy template +cp template.env .env + +# Edit with your settings +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8880 +SERVICE_ADMINKEY=your-secure-admin-key-here + +# Database settings +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=password +SERVICE_DBNAME=dhamps_vdb_dev + +# Encryption key (32+ characters) +ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars +``` + +**Important**: Never commit `.env` files (already in `.gitignore`) + +### Database Setup + +For local development: + +```bash +# Start PostgreSQL with pgvector +podman run -p 5432:5432 \ + -e POSTGRES_PASSWORD=password \ + -e POSTGRES_DB=dhamps_vdb_dev \ + pgvector/pgvector:0.7.4-pg16 + +# Or use docker-compose +docker-compose up -d + +# Application auto-migrates on startup +go run main.go +``` + +### Verify Setup + +```bash +# Check application starts +go run main.go + +# In another terminal, test API +curl http://localhost:8880/docs + +# Run tests +go test -v ./... +``` + +## Code Style + +### Go Formatting + +dhamps-vdb follows standard Go conventions: + +```bash +# Format all code +go fmt ./... + +# Check for common issues +go vet ./... + +# Run linter (if installed) +golangci-lint run +``` + +### Code Organization + +Follow existing patterns: + +```go +// Package comment at top of file +package handlers + +import ( + // Standard library first + "context" + "fmt" + + // External packages + "github.com/danielgtaylor/huma/v2" + "github.com/jackc/pgx/v5/pgxpool" + + // Internal packages + "github.com/mpilhlt/dhamps-vdb/internal/database" + "github.com/mpilhlt/dhamps-vdb/internal/models" +) + +// Exported function with doc comment +// GetUsers retrieves all users from the database +func GetUsers(ctx context.Context, pool *pgxpool.Pool) ([]models.User, error) { + // Implementation +} +``` + +### Naming Conventions + +**Files:** +- `handlers/users.go` - Implementation +- `handlers/users_test.go` - Tests +- `handlers/users_sharing_test.go` - Specific feature tests + +**Functions:** +- `GetUsers()` - List/retrieve multiple +- `GetUser()` - Retrieve single +- `CreateUser()` - Create new +- `UpdateUser()` - Update existing +- `DeleteUser()` - Delete +- `LinkUserToProject()` - Create association +- `IsProjectOwner()` - Boolean check + +**Database Queries (in `queries.sql`):** +- `-- name: GetAllUsers :many` +- `-- name: RetrieveUserByHandle :one` +- `-- name: UpsertUser :one` +- `-- name: DeleteUser :exec` + +### Error Handling + +```go +// Return errors, don't panic +func CreateUser(ctx context.Context, pool *pgxpool.Pool, user models.User) error { + if user.Handle == "" { + return fmt.Errorf("user handle is required") + } + + // Wrap errors with context + err := db.InsertUser(ctx, user) + if err != nil { + return fmt.Errorf("failed to insert user: %w", err) + } + + return nil +} + +// Use specific error responses in handlers +func handleCreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { + err := CreateUser(ctx, pool, input.Body) + if err != nil { + return nil, huma.Error400BadRequest("invalid user data", err) + } + + return &CreateUserOutput{Body: result}, nil +} +``` + +### Comments + +Comment public APIs and complex logic: + +```go +// GetAccessibleProjects returns all projects the user can access. +// This includes projects owned by the user and projects shared with them. +// Results are paginated using limit and offset. +func GetAccessibleProjects(ctx context.Context, pool *pgxpool.Pool, + userHandle string, limit, offset int) ([]models.Project, error) { + + // Use UNION ALL for better query performance + // See docs/PERFORMANCE_OPTIMIZATION.md for details + query := ` + SELECT * FROM projects WHERE owner = $1 + UNION ALL + SELECT p.* FROM projects p + INNER JOIN projects_shared_with ps ON p.project_id = ps.project_id + WHERE ps.user_handle = $1 + ` + + // Implementation... +} +``` + +Don't over-comment obvious code: + +```go +// Bad - obvious +// i is set to 0 +i := 0 + +// Good - explains why +// Start from second element (first is header) +i := 1 +``` + +## Git Workflow + +### Branching Strategy + +```bash +# Create feature branch from main +git checkout main +git pull origin main +git checkout -b feature/your-feature-name + +# Create fix branch +git checkout -b fix/issue-description + +# Create docs branch +git checkout -b docs/update-contributing-guide +``` + +Branch naming: +- `feature/*` - New features +- `fix/*` - Bug fixes +- `docs/*` - Documentation updates +- `test/*` - Test improvements +- `refactor/*` - Code refactoring + +### Commit Messages + +Write clear, descriptive commit messages: + +```bash +# Good commit messages +git commit -m "Add project sharing functionality" +git commit -m "Fix dimension validation for embeddings" +git commit -m "Update contributing guide with git workflow" + +# Multi-line for complex changes +git commit -m "Refactor similarity search query + +- Use UNION ALL for better performance +- Add dimension filtering to subqueries +- Update tests to verify performance improvement + +Closes #123" +``` + +**Commit message format:** +- First line: Brief summary (50 chars or less) +- Blank line +- Detailed explanation if needed +- Reference issues: `Closes #123` or `Fixes #456` + +### Pull Request Process + +1. **Create feature branch** + ```bash + git checkout -b feature/my-feature + ``` + +2. **Make changes and commit** + ```bash + git add . + git commit -m "Add feature description" + ``` + +3. **Keep branch updated** + ```bash + git fetch origin + git rebase origin/main + ``` + +4. **Push to your fork** + ```bash + git push origin feature/my-feature + ``` + +5. **Create Pull Request** + - Go to GitHub repository + - Click "New Pull Request" + - Select your branch + - Fill in PR template + +6. **PR Review Process** + - Automated tests run + - Code review by maintainers + - Address feedback + - Merge when approved + +### PR Title Format + +``` +[Type] Brief description + +Examples: +[Feature] Add project ownership transfer +[Fix] Correct dimension validation in embeddings +[Docs] Update API documentation for similarity search +[Test] Add integration tests for sharing workflow +[Refactor] Simplify authentication middleware +``` + +### PR Description Template + +```markdown +## Description +Brief description of changes + +## Motivation +Why is this change needed? + +## Changes +- Change 1 +- Change 2 +- Change 3 + +## Testing +How was this tested? +- [ ] Unit tests pass +- [ ] Integration tests pass +- [ ] Manual testing performed + +## Related Issues +Closes #123 +Relates to #456 + +## Checklist +- [ ] Code follows style guidelines +- [ ] Tests added/updated +- [ ] Documentation updated +- [ ] No breaking changes (or clearly documented) +``` + +## Testing Requirements + +All contributions must include tests: + +### For New Features + +```go +// Add tests in same package +// File: handlers/projects.go +func CreateProject(...) { ... } + +// File: handlers/projects_test.go +func TestCreateProject(t *testing.T) { + // Test happy path + // Test error cases + // Test edge cases +} +``` + +### For Bug Fixes + +```go +// Add regression test +func TestBugFix_Issue123(t *testing.T) { + // Reproduce the bug + // Verify it's fixed +} +``` + +### Test Coverage + +Aim for reasonable coverage: + +```bash +# Check coverage +go test -cover ./... + +# Generate coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out +``` + +Target coverage: **70%+** for new code + +### Running Tests + +```bash +# Before submitting PR +go test -v ./... + +# With race detection +go test -race ./... + +# Specific package +go test -v ./internal/handlers +``` + +See [Testing Guide](../testing/) for detailed information. + +## Documentation Updates + +### When to Update Docs + +Update documentation for: + +- **New features**: Add usage examples +- **API changes**: Update endpoint documentation +- **Breaking changes**: Clearly document migration path +- **Configuration**: New environment variables or options + +### Documentation Structure + +``` +docs/content/ +├── getting-started/ # Installation, quickstart +├── concepts/ # Core concepts +├── guides/ # How-to guides +├── api/ # API reference +└── development/ # Development docs (this section) +``` + +### Adding Documentation + +```bash +# Create new doc file +cd docs/content/guides +cat > new-guide.md <1000) + - Many shared relationships (>100 shares per user) + - Query time consistently >100ms + +**Always profile first:** + +```sql +EXPLAIN ANALYZE +SELECT instances.*, ... +FROM instances +LEFT JOIN instances_shared_with ON ... +WHERE instances.owner = 'alice' OR instances_shared_with.user_handle = 'alice'; +``` + +## Index Optimization + +### Current Indexes + +From migration `004_refactor_llm_services_architecture.sql`: + +```sql +-- API Standards / Definitions +CREATE INDEX idx_definitions_handle + ON definitions(definition_handle); + +CREATE INDEX idx_definitions_owner_handle + ON definitions(owner, definition_handle); + +-- Instances +CREATE INDEX idx_instances_handle + ON instances(instance_handle); + +-- Sharing (implicit from PRIMARY KEY) +-- instances_shared_with(instance_id, user_handle) +``` + +### Recommended Additional Indexes + +#### 1. Owner Lookups + +```sql +-- For queries: WHERE instances.owner = ? +CREATE INDEX idx_instances_owner + ON instances(owner); +``` + +**Benefit:** Fast retrieval of user's owned instances + +**Use case:** +```sql +SELECT * FROM instances WHERE owner = 'alice'; +``` + +#### 2. Shared Instance Lookups + +```sql +-- For queries: WHERE user_handle = ? +CREATE INDEX idx_instances_shared_user + ON instances_shared_with(user_handle); +``` + +**Benefit:** Fast retrieval of instances shared with user + +**Use case:** +```sql +SELECT i.* FROM instances i +INNER JOIN instances_shared_with isw ON i.instance_id = isw.instance_id +WHERE isw.user_handle = 'bob'; +``` + +#### 3. Composite Owner+Handle Index + +```sql +-- For unique constraint and lookups +CREATE UNIQUE INDEX idx_instances_owner_handle + ON instances(owner, instance_handle); +``` + +**Benefit:** Enforces uniqueness and enables index-only scans + +**Use case:** +```sql +SELECT * FROM instances +WHERE owner = 'alice' AND instance_handle = 'my-service'; +``` + +#### 4. Embedding Dimension Filtering + +```sql +-- Critical for similarity search performance +CREATE INDEX idx_embeddings_project_dim + ON embeddings(project_id, vector_dim); +``` + +**Benefit:** Filters embeddings by dimension before vector comparison + +**Use case:** +```sql +SELECT * FROM embeddings +WHERE project_id = 123 + AND vector_dim = 1536 +ORDER BY vector <=> $1::vector +LIMIT 10; +``` + +#### 5. Project Ownership + +```sql +CREATE INDEX idx_projects_owner + ON projects(owner); + +CREATE UNIQUE INDEX idx_projects_owner_handle + ON projects(owner, project_handle); +``` + +### Index Analysis + +Check if indexes are being used: + +```sql +-- Analyze query plan +EXPLAIN ANALYZE +SELECT * FROM instances WHERE owner = 'alice'; + +-- Check index usage statistics +SELECT + schemaname, + tablename, + indexname, + idx_scan, + idx_tup_read, + idx_tup_fetch +FROM pg_stat_user_indexes +WHERE schemaname = 'public' +ORDER BY idx_scan DESC; + +-- Find unused indexes +SELECT + schemaname, + tablename, + indexname +FROM pg_stat_user_indexes +WHERE idx_scan = 0 + AND schemaname = 'public'; +``` + +### Index Maintenance + +```sql +-- Update statistics for query planner +ANALYZE instances; +ANALYZE instances_shared_with; +ANALYZE embeddings; + +-- Rebuild index if fragmented +REINDEX INDEX idx_instances_owner; + +-- Check index size +SELECT + indexname, + pg_size_pretty(pg_relation_size(indexrelid)) AS size +FROM pg_stat_user_indexes +WHERE schemaname = 'public' +ORDER BY pg_relation_size(indexrelid) DESC; +``` + +## Vector Index Optimization + +### HNSW vs IVFFlat + +**Current implementation uses HNSW:** + +```sql +CREATE INDEX embedding_vector_idx +ON embeddings +USING hnsw (vector vector_cosine_ops); +``` + +#### HNSW (Hierarchical Navigable Small World) + +**Pros:** +- Better recall (finds more similar results) +- Better query performance +- No training required + +**Cons:** +- Slower index build time +- Higher memory usage +- Larger index size + +**Configuration options:** + +```sql +-- Default: m=16, ef_construction=64 +CREATE INDEX embedding_vector_idx +ON embeddings +USING hnsw (vector vector_cosine_ops) +WITH (m = 16, ef_construction = 64); + +-- Higher quality (slower build): m=32, ef_construction=128 +CREATE INDEX embedding_vector_idx_hq +ON embeddings +USING hnsw (vector vector_cosine_ops) +WITH (m = 32, ef_construction = 128); +``` + +**Parameters:** +- `m`: Number of connections per layer (default 16, range 2-100) +- `ef_construction`: Size of candidate list during build (default 64, range 4-1000) +- Higher values = better recall but slower build and more memory + +#### IVFFlat (Inverted File with Flat compression) + +**Alternative for very large datasets:** + +```sql +CREATE INDEX embedding_vector_idx_ivf +ON embeddings +USING ivfflat (vector vector_cosine_ops) +WITH (lists = 100); +``` + +**Pros:** +- Faster index build +- Lower memory usage +- Smaller index size + +**Cons:** +- Requires training (ANALYZE before creating index) +- Lower recall than HNSW +- Need to tune `lists` parameter + +**When to use:** +- Dataset >1M embeddings +- Build time is critical +- Memory constrained environment + +**Configuration:** + +```sql +-- Rule of thumb: lists = sqrt(total_rows) +-- For 100K embeddings: lists = 316 +-- For 1M embeddings: lists = 1000 + +-- Train the index +ANALYZE embeddings; + +-- Create with appropriate lists +CREATE INDEX embedding_vector_idx_ivf +ON embeddings +USING ivfflat (vector vector_cosine_ops) +WITH (lists = 1000); + +-- Set probes at query time +SET ivfflat.probes = 10; -- Default is 1, higher = better recall +``` + +### Query-Time Optimization + +For HNSW, set `hnsw.ef_search`: + +```sql +-- Default: ef_search = 40 +-- Higher = better recall but slower queries +SET hnsw.ef_search = 100; + +SELECT vector <=> $1::vector AS distance +FROM embeddings +WHERE project_id = 123 +ORDER BY distance +LIMIT 10; +``` + +### Dimension-Specific Indexes + +For multi-dimensional projects: + +```sql +-- Separate indexes per common dimension +CREATE INDEX idx_embeddings_768_vector +ON embeddings USING hnsw (vector vector_cosine_ops) +WHERE vector_dim = 768; + +CREATE INDEX idx_embeddings_1536_vector +ON embeddings USING hnsw (vector vector_cosine_ops) +WHERE vector_dim = 1536; + +CREATE INDEX idx_embeddings_3072_vector +ON embeddings USING hnsw (vector vector_cosine_ops) +WHERE vector_dim = 3072; +``` + +**Benefit:** Smaller indexes = faster queries for specific dimensions + +## Caching Strategies + +### 1. System Definitions Cache + +System definitions rarely change: + +```go +var ( + systemDefsCache []models.Definition + systemDefsCacheMu sync.RWMutex + systemDefsCacheTTL = 5 * time.Minute + systemDefsCacheExp time.Time +) + +func GetSystemDefinitions(ctx context.Context, pool *pgxpool.Pool) ([]models.Definition, error) { + systemDefsCacheMu.RLock() + if time.Now().Before(systemDefsCacheExp) && systemDefsCache != nil { + defer systemDefsCacheMu.RUnlock() + return systemDefsCache, nil + } + systemDefsCacheMu.RUnlock() + + // Fetch from database + defs, err := db.GetDefinitionsByOwner(ctx, "_system") + if err != nil { + return nil, err + } + + // Update cache + systemDefsCacheMu.Lock() + systemDefsCache = defs + systemDefsCacheExp = time.Now().Add(systemDefsCacheTTL) + systemDefsCacheMu.Unlock() + + return defs, nil +} +``` + +### 2. User Instances Cache + +Cache user's instance list with short TTL: + +```go +type InstanceCache struct { + data map[string][]models.Instance + mu sync.RWMutex + ttl time.Duration + exp map[string]time.Time +} + +func (c *InstanceCache) Get(userHandle string) ([]models.Instance, bool) { + c.mu.RLock() + defer c.mu.RUnlock() + + if exp, ok := c.exp[userHandle]; ok && time.Now().Before(exp) { + return c.data[userHandle], true + } + return nil, false +} + +func (c *InstanceCache) Set(userHandle string, instances []models.Instance) { + c.mu.Lock() + defer c.mu.Unlock() + + c.data[userHandle] = instances + c.exp[userHandle] = time.Now().Add(c.ttl) +} + +func (c *InstanceCache) Invalidate(userHandle string) { + c.mu.Lock() + defer c.mu.Unlock() + + delete(c.data, userHandle) + delete(c.exp, userHandle) +} +``` + +**Usage:** + +```go +var instanceCache = &InstanceCache{ + data: make(map[string][]models.Instance), + exp: make(map[string]time.Time), + ttl: 30 * time.Second, +} + +func GetUserInstances(ctx context.Context, pool *pgxpool.Pool, userHandle string) ([]models.Instance, error) { + // Check cache + if instances, ok := instanceCache.Get(userHandle); ok { + return instances, nil + } + + // Query database + instances, err := db.GetAccessibleInstances(ctx, userHandle) + if err != nil { + return nil, err + } + + // Cache results + instanceCache.Set(userHandle, instances) + return instances, nil +} +``` + +### 3. Project Metadata Cache + +Cache project metadata including schema: + +```go +type ProjectCache struct { + projects map[string]*models.Project // key: "owner/handle" + mu sync.RWMutex + ttl time.Duration +} + +func (c *ProjectCache) Get(owner, handle string) (*models.Project, bool) { + key := fmt.Sprintf("%s/%s", owner, handle) + c.mu.RLock() + defer c.mu.RUnlock() + + project, ok := c.projects[key] + return project, ok +} +``` + +### 4. Redis-Based Caching + +For distributed deployments: + +```go +import "github.com/go-redis/redis/v8" + +type RedisCache struct { + client *redis.Client + ttl time.Duration +} + +func (c *RedisCache) GetProject(ctx context.Context, owner, handle string) (*models.Project, error) { + key := fmt.Sprintf("project:%s:%s", owner, handle) + + data, err := c.client.Get(ctx, key).Bytes() + if err == redis.Nil { + return nil, nil // Not in cache + } else if err != nil { + return nil, err + } + + var project models.Project + err = json.Unmarshal(data, &project) + return &project, err +} + +func (c *RedisCache) SetProject(ctx context.Context, project *models.Project) error { + key := fmt.Sprintf("project:%s:%s", project.Owner, project.Handle) + data, err := json.Marshal(project) + if err != nil { + return err + } + + return c.client.Set(ctx, key, data, c.ttl).Err() +} +``` + +### Cache Invalidation + +Always invalidate cache on updates: + +```go +func UpdateProject(ctx context.Context, pool *pgxpool.Pool, project *models.Project) error { + // Update database + err := db.UpdateProject(ctx, project) + if err != nil { + return err + } + + // Invalidate cache + projectCache.Invalidate(project.Owner, project.Handle) + + return nil +} +``` + +## Connection Pool Optimization + +### Pool Configuration + +```go +func InitDB(opts *models.Options) *pgxpool.Pool { + config, err := pgxpool.ParseConfig(connString) + if err != nil { + log.Fatal(err) + } + + // Connection pool settings + config.MaxConns = 20 // Max concurrent connections + config.MinConns = 5 // Keep-alive connections + config.MaxConnLifetime = time.Hour // Recycle connections + config.MaxConnIdleTime = 5 * time.Minute // Close idle connections + config.HealthCheckPeriod = time.Minute // Health check frequency + + // Statement cache + config.ConnConfig.StatementCacheCapacity = 100 + + pool, err := pgxpool.NewWithConfig(context.Background(), config) + return pool +} +``` + +### Pool Sizing + +**General rule:** + +``` +MaxConns = (available_cores * 2) + effective_spindle_count +``` + +**Example scenarios:** + +- **4-core CPU, SSD**: MaxConns = 10-20 +- **8-core CPU, SSD**: MaxConns = 20-40 +- **Under heavy load**: Start conservative, increase based on monitoring + +### Monitor Pool Usage + +```go +func monitorPool(pool *pgxpool.Pool) { + ticker := time.NewTicker(30 * time.Second) + + for range ticker.C { + stat := pool.Stat() + log.Printf("Pool stats: total=%d, idle=%d, acquired=%d, waiting=%d", + stat.TotalConns(), + stat.IdleConns(), + stat.AcquiredConns(), + stat.MaxConns()-stat.TotalConns(), + ) + } +} +``` + +## Performance Testing + +### Load Testing Setup + +Use [vegeta](https://github.com/tsenart/vegeta) for HTTP load testing: + +```bash +# Install vegeta +go install github.com/tsenart/vegeta@latest + +# Create targets file +cat > targets.txt < old.txt +# Make changes +go test -bench=. -benchmem ./... > new.txt +benchcmp old.txt new.txt +``` + +### Database Performance Testing + +Test with realistic data: + +```sql +-- Generate test data +INSERT INTO embeddings (project_id, text_id, vector, vector_dim, metadata) +SELECT + 1, + 'doc_' || generate_series, + array_fill(random()::real, ARRAY[1536])::vector, + 1536, + '{"author": "test"}'::jsonb +FROM generate_series(1, 100000); + +-- Test query performance +EXPLAIN (ANALYZE, BUFFERS) +SELECT text_id, vector <=> $1::vector AS distance +FROM embeddings +WHERE project_id = 1 AND vector_dim = 1536 +ORDER BY distance +LIMIT 10; +``` + +## Metrics and Monitoring + +### Application Metrics + +Track key metrics: + +```go +type Metrics struct { + QueryDuration prometheus.Histogram + QueryCount prometheus.Counter + CacheHits prometheus.Counter + CacheMisses prometheus.Counter + PoolWaitDuration prometheus.Histogram +} + +func recordQueryMetrics(start time.Time, query string) { + duration := time.Since(start).Seconds() + metrics.QueryDuration.Observe(duration) + metrics.QueryCount.Inc() +} +``` + +### PostgreSQL Metrics + +Monitor database performance: + +```sql +-- Slow queries +SELECT + query, + calls, + total_time, + mean_time, + max_time +FROM pg_stat_statements +ORDER BY mean_time DESC +LIMIT 10; + +-- Table statistics +SELECT + schemaname, + tablename, + n_tup_ins, + n_tup_upd, + n_tup_del, + n_live_tup, + n_dead_tup +FROM pg_stat_user_tables; + +-- Index usage +SELECT + schemaname, + tablename, + indexname, + idx_scan, + idx_tup_read, + idx_tup_fetch +FROM pg_stat_user_indexes +ORDER BY idx_scan DESC; +``` + +### Performance Targets + +Based on typical usage: + +| Operation | Target | Acceptable | Action Required | +|-----------|--------|------------|-----------------| +| Single instance lookup | < 10ms | < 50ms | > 50ms | +| List accessible instances (<100) | < 50ms | < 100ms | > 100ms | +| Create/update instance | < 100ms | < 200ms | > 200ms | +| Similarity search (10 results) | < 50ms | < 100ms | > 100ms | +| Similarity search (100 results) | < 100ms | < 200ms | > 200ms | +| Embedding insert (single) | < 50ms | < 100ms | > 100ms | +| Embedding batch (100) | < 500ms | < 1000ms | > 1000ms | + +## Implementation Priority + +### High Priority + +1. **Profile current performance** with realistic data +2. **Add dimension filtering index**: `idx_embeddings_project_dim` +3. **Monitor slow queries** with pg_stat_statements + +### Medium Priority + +1. **Implement UNION ALL optimization** if GetAllAccessibleInstances > 100ms +2. **Add caching for system definitions** +3. **Optimize connection pool settings** based on load + +### Low Priority + +1. **Add Redis caching layer** for high-traffic deployments +2. **Implement application metrics** with Prometheus +3. **Add additional indexes** based on actual query patterns +4. **Tune HNSW parameters** for specific use cases + +## General Best Practices + +### 1. Measure Before Optimizing + +```bash +# Profile in production +EXPLAIN ANALYZE your_query; + +# Load test +vegeta attack -duration=60s -rate=100 + +# Benchmark +go test -bench=. -benchmem +``` + +### 2. Start Conservative + +- Don't optimize prematurely +- Use simple queries first +- Add complexity only when needed + +### 3. Monitor Continuously + +- Track query performance +- Monitor connection pool +- Watch index usage +- Alert on slow queries + +### 4. Document Optimizations + +- Note why optimization was needed +- Include before/after metrics +- Document trade-offs made + +## Further Reading + +- [PostgreSQL Performance Tuning](https://wiki.postgresql.org/wiki/Performance_Optimization) +- [pgvector Performance Guide](https://github.com/pgvector/pgvector#performance) +- [Go Database/SQL Tutorial](https://go.dev/doc/database/querying) +- [Connection Pool Best Practices](https://github.com/jackc/pgx/wiki/Connection-Pool-Best-Practices) diff --git a/docs/content/development/testing.md b/docs/content/development/testing.md new file mode 100644 index 0000000..b59372d --- /dev/null +++ b/docs/content/development/testing.md @@ -0,0 +1,510 @@ +--- +title: "Testing" +weight: 1 +--- + +# Testing Guide + +This guide covers how to run and write tests for dhamps-vdb. + +## Running Tests + +dhamps-vdb uses integration tests that spin up real PostgreSQL containers using [testcontainers](https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/). This approach ensures tests run against actual database instances with pgvector support. + +### Prerequisites + +**Using Podman (Recommended for Linux):** + +```bash +# Start podman socket +systemctl --user start podman.socket + +# Export DOCKER_HOST for testcontainers +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock +``` + +**Using Docker:** + +Testcontainers works with Docker out of the box. Ensure Docker daemon is running. + +### Running All Tests + +```bash +# Run all tests with verbose output +go test -v ./... + +# Run tests without verbose output +go test ./... + +# Run tests with coverage +go test -cover ./... + +# Generate coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out +``` + +### Running Specific Tests + +```bash +# Run tests in a specific package +go test -v ./internal/handlers + +# Run a specific test function +go test -v ./internal/handlers -run TestCreateUser + +# Run tests matching a pattern +go test -v ./... -run ".*Sharing.*" +``` + +### Test Containers + +Tests automatically manage PostgreSQL containers with pgvector: + +- Container is started before tests run +- Database schema is migrated automatically +- Container is cleaned up after tests complete +- Each test suite gets a fresh database state + +## Test Structure + +### Package Organization + +Tests are organized alongside the code they test: + +``` +internal/ +├── handlers/ +│ ├── users.go # Implementation +│ ├── users_test.go # Unit/integration tests +│ ├── projects.go +│ ├── projects_test.go +│ ├── projects_sharing_test.go +│ ├── embeddings.go +│ └── embeddings_test.go +├── database/ +│ └── queries.sql # SQL queries for sqlc +└── models/ + ├── users.go + └── projects.go +``` + +### Test Files + +Test files follow Go conventions: + +- **Filename**: `*_test.go` +- **Package**: Same as code under test (e.g., `package handlers`) +- **Test functions**: `func TestFunctionName(t *testing.T)` + +### Test Fixtures + +Test data is stored in `testdata/`: + +``` +testdata/ +├── postgres/ +│ ├── enable-vector.sql # Database initialization +│ └── users.yml +├── valid_embeddings.json +├── valid_user.json +├── valid_api_standard_openai_v1.json +├── valid_llm_service_openai-large-full.json +└── invalid_embeddings.json +``` + +## Writing Tests + +### Basic Test Structure + +```go +package handlers + +import ( + "context" + "testing" + + "github.com/mpilhlt/dhamps-vdb/internal/database" + "github.com/stretchr/testify/assert" +) + +func TestCreateUser(t *testing.T) { + // Setup: Initialize database pool and test data + ctx := context.Background() + pool := setupTestDatabase(t) + defer pool.Close() + + // Execute: Call function under test + result, err := CreateUser(ctx, pool, userData) + + // Assert: Verify results + assert.NoError(t, err) + assert.Equal(t, "testuser", result.UserHandle) +} +``` + +### Integration Test Example + +```go +func TestProjectSharingWorkflow(t *testing.T) { + pool := setupTestDatabase(t) + defer pool.Close() + + // Create test users + alice := createTestUser(t, pool, "alice") + bob := createTestUser(t, pool, "bob") + + // Create project as Alice + project := createTestProject(t, pool, alice, "test-project") + + // Share project with Bob + err := shareProject(t, pool, alice, project.ID, bob.Handle, "reader") + assert.NoError(t, err) + + // Verify Bob can access project + projects := getAccessibleProjects(t, pool, bob) + assert.Contains(t, projects, project) +} +``` + +### Testing with Testcontainers + +```go +func setupTestDatabase(t *testing.T) *pgxpool.Pool { + ctx := context.Background() + + // Create PostgreSQL container with pgvector + req := testcontainers.ContainerRequest{ + Image: "pgvector/pgvector:0.7.4-pg16", + ExposedPorts: []string{"5432/tcp"}, + Env: map[string]string{ + "POSTGRES_PASSWORD": "password", + "POSTGRES_DB": "testdb", + }, + WaitStrategy: wait.ForLog("database system is ready to accept connections"), + } + + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }) + require.NoError(t, err) + + // Get connection details + host, _ := container.Host(ctx) + port, _ := container.MappedPort(ctx, "5432") + + // Connect and migrate + connString := fmt.Sprintf("postgres://postgres:password@%s:%s/testdb", host, port.Port()) + pool := connectAndMigrate(t, connString) + + return pool +} +``` + +### Validation Testing + +Test dimension and metadata validation: + +```go +func TestEmbeddingDimensionValidation(t *testing.T) { + pool := setupTestDatabase(t) + defer pool.Close() + + // Create LLM service with 1536 dimensions + llmService := createTestLLMService(t, pool, "openai", 1536) + + // Try to insert embedding with wrong dimensions + embedding := models.Embedding{ + TextID: "doc1", + Vector: make([]float32, 768), // Wrong size! + VectorDim: 768, + } + + err := insertEmbedding(t, pool, embedding) + assert.Error(t, err) + assert.Contains(t, err.Error(), "dimension mismatch") +} + +func TestMetadataSchemaValidation(t *testing.T) { + pool := setupTestDatabase(t) + defer pool.Close() + + // Create project with metadata schema + schema := `{"type":"object","properties":{"author":{"type":"string"}},"required":["author"]}` + project := createProjectWithSchema(t, pool, "alice", "test", schema) + + // Valid metadata should succeed + validMeta := `{"author":"John Doe"}` + err := insertEmbeddingWithMetadata(t, pool, project.ID, validMeta) + assert.NoError(t, err) + + // Invalid metadata should fail + invalidMeta := `{"year":2024}` // Missing required 'author' + err = insertEmbeddingWithMetadata(t, pool, project.ID, invalidMeta) + assert.Error(t, err) +} +``` + +### Table-Driven Tests + +For testing multiple scenarios: + +```go +func TestSimilaritySearch(t *testing.T) { + tests := []struct { + name string + threshold float32 + limit int + expected int + }{ + {"high threshold", 0.9, 10, 2}, + {"medium threshold", 0.7, 10, 5}, + {"low threshold", 0.5, 10, 8}, + {"with limit", 0.5, 3, 3}, + } + + pool := setupTestDatabase(t) + defer pool.Close() + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + results := searchSimilar(t, pool, "doc1", tt.threshold, tt.limit) + assert.Len(t, results, tt.expected) + }) + } +} +``` + +### Cleanup Testing + +Verify database cleanup: + +```go +func TestDatabaseCleanup(t *testing.T) { + pool := setupTestDatabase(t) + defer pool.Close() + + // Create test data + user := createTestUser(t, pool, "alice") + project := createTestProject(t, pool, user, "test") + createTestEmbeddings(t, pool, project, 10) + + // Delete user (should cascade) + err := deleteUser(t, pool, user.Handle) + assert.NoError(t, err) + + // Verify all related data is deleted + assertTableEmpty(t, pool, "users") + assertTableEmpty(t, pool, "projects") + assertTableEmpty(t, pool, "embeddings") +} +``` + +## Test Helpers + +Create helper functions to reduce boilerplate: + +```go +// setupTestDatabase initializes a test database with migrations +func setupTestDatabase(t *testing.T) *pgxpool.Pool { + // Implementation... +} + +// createTestUser creates a user for testing +func createTestUser(t *testing.T, pool *pgxpool.Pool, handle string) *models.User { + // Implementation... +} + +// createTestProject creates a project for testing +func createTestProject(t *testing.T, pool *pgxpool.Pool, owner *models.User, handle string) *models.Project { + // Implementation... +} + +// assertTableEmpty verifies a table has no rows +func assertTableEmpty(t *testing.T, pool *pgxpool.Pool, tableName string) { + var count int + err := pool.QueryRow(context.Background(), + fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)).Scan(&count) + require.NoError(t, err) + assert.Equal(t, 0, count, "table %s should be empty", tableName) +} +``` + +## CI/CD Integration + +### GitHub Actions + +Example GitHub Actions workflow: + +```yaml +name: Tests + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.21' + + - name: Run tests + run: | + go test -v -race -coverprofile=coverage.txt ./... + + - name: Upload coverage + uses: codecov/codecov-action@v3 + with: + files: ./coverage.txt +``` + +### Local CI Testing + +Test as CI would: + +```bash +# Clean test with race detection +go clean -testcache +go test -v -race ./... + +# Test with coverage +go test -coverprofile=coverage.out ./... + +# Check for test caching issues +go test -count=1 ./... +``` + +## Best Practices + +### 1. **Use testcontainers for Real Databases** +- Don't mock the database layer +- Test against actual PostgreSQL with pgvector +- Catch SQL-specific issues + +### 2. **Isolate Tests** +- Each test should be independent +- Use transactions or cleanup between tests +- Don't rely on test execution order + +### 3. **Test Validation Logic** +- Test dimension validation +- Test metadata schema validation +- Test authorization checks + +### 4. **Test Error Conditions** +- Invalid input +- Missing resources (404) +- Unauthorized access (403) +- Constraint violations + +### 5. **Keep Tests Fast** +- Use parallel tests where possible: `t.Parallel()` +- Reuse test database containers when appropriate +- Avoid unnecessary sleeps + +### 6. **Use Descriptive Names** +```go +// Good +func TestProjectSharingWithReaderRole(t *testing.T) + +// Less clear +func TestSharing(t *testing.T) +``` + +### 7. **Assert Meaningfully** +```go +// Good - specific assertion +assert.Equal(t, "alice", project.Owner) + +// Less helpful +assert.True(t, project.Owner == "alice") +``` + +## Debugging Tests + +### Verbose Output + +```bash +# See all test output +go test -v ./internal/handlers + +# See SQL queries (if logging enabled) +SERVICE_DEBUG=true go test -v ./... +``` + +### Run Single Test + +```bash +# Focus on one failing test +go test -v ./internal/handlers -run TestCreateProject +``` + +### Keep Test Database Running + +For manual inspection, prevent container cleanup: + +```go +func TestWithDebugContainer(t *testing.T) { + container := setupContainer(t) + // Comment out: defer container.Terminate(ctx) + + host, port := getContainerDetails(container) + t.Logf("Database running at %s:%s", host, port) + + // Run test... + + // Container stays running for manual inspection + time.Sleep(time.Hour) +} +``` + +Then connect with psql: + +```bash +psql -h localhost -p -U postgres -d testdb +``` + +## Common Issues + +### Container Startup Failures + +```bash +# Check Docker/Podman is running +systemctl --user status podman.socket + +# Check for port conflicts +netstat -tulpn | grep 5432 + +# Clean up containers +podman rm -f $(podman ps -aq) +``` + +### Test Timeouts + +Increase timeout for slow containers: + +```go +WaitStrategy: wait.ForLog("ready").WithStartupTimeout(2 * time.Minute) +``` + +### Permission Errors + +Ensure test user has proper permissions: + +```sql +GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser; +GRANT ALL ON SCHEMA public TO testuser; +``` + +## Further Reading + +- [Go Testing Documentation](https://pkg.go.dev/testing) +- [Testcontainers for Go](https://golang.testcontainers.org/) +- [Testify Assertions](https://github.com/stretchr/testify) +- [Table-Driven Tests in Go](https://dave.cheney.net/2019/05/07/prefer-table-driven-tests) From 1ef0e5df9f90117f17ab27337e9ff41cd058cace Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:38:24 +0000 Subject: [PATCH 6/9] Add comprehensive reference documentation files - Add reference/configuration.md: Complete config reference consolidating info from getting-started/configuration.md and deployment/environment-variables.md - Add reference/database-schema.md: Full database schema reference documenting all tables from migration files 001 and 004 - Add reference/roadmap.md: Product roadmap extracted from README.md with completed/planned features Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- docs/content/reference/configuration.md | 524 ++++++++++++++++++++++ docs/content/reference/database-schema.md | 514 +++++++++++++++++++++ docs/content/reference/roadmap.md | 346 ++++++++++++++ 3 files changed, 1384 insertions(+) create mode 100644 docs/content/reference/configuration.md create mode 100644 docs/content/reference/database-schema.md create mode 100644 docs/content/reference/roadmap.md diff --git a/docs/content/reference/configuration.md b/docs/content/reference/configuration.md new file mode 100644 index 0000000..ef561a1 --- /dev/null +++ b/docs/content/reference/configuration.md @@ -0,0 +1,524 @@ +--- +title: "Configuration Reference" +weight: 1 +--- + +# Configuration Reference + +Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration. + +## Overview + +dhamps-vdb is configured through a combination of: + +1. **Environment variables** (recommended) +2. **Command-line flags** (overrides environment variables) +3. **`.env` files** (for Docker and local development) + +Configuration is loaded in the following priority order (highest to lowest): + +1. Command-line flags +2. Environment variables +3. `.env` file values +4. Default values from `options.go` + +## Configuration Options + +### Service Configuration + +Options for controlling the API service behavior. + +| Option | Environment Variable | CLI Flag | Type | Default | Required | Description | +|--------|---------------------|----------|------|---------|----------|-------------| +| Debug | `SERVICE_DEBUG` | `-d`, `--debug` | Boolean | `true` | No | Enable verbose debug logging | +| Host | `SERVICE_HOST` | `--host` | String | `localhost` | No | Hostname or IP to bind to | +| Port | `SERVICE_PORT` | `-p`, `--port` | Integer | `8880` | No | Port number to listen on | + +**Debug Mode:** +- `true` - Detailed logs including SQL queries, request details, internal operations +- `false` - Minimal logs for production use + +**Host Configuration:** +- `localhost` - Local development only +- `0.0.0.0` - Listen on all interfaces (required for Docker) +- Specific IP - Bind to particular network interface + +**Port Configuration:** +- Default: `8880` +- Ports below 1024 require elevated privileges +- Ensure port is not in use by another service + +### Database Configuration + +Options for connecting to the PostgreSQL database with pgvector extension. + +| Option | Environment Variable | CLI Flag | Type | Default | Required | Description | +|--------|---------------------|----------|------|---------|----------|-------------| +| DB Host | `SERVICE_DBHOST` | `--db-host` | String | `localhost` | Yes | PostgreSQL server hostname | +| DB Port | `SERVICE_DBPORT` | `--db-port` | Integer | `5432` | No | PostgreSQL server port | +| DB User | `SERVICE_DBUSER` | `--db-user` | String | `postgres` | Yes | Database username | +| DB Password | `SERVICE_DBPASSWORD` | `--db-password` | String | `password` | Yes | Database password | +| DB Name | `SERVICE_DBNAME` | `--db-name` | String | `postgres` | Yes | Database name | + +**Database Requirements:** +- PostgreSQL 12+ (16+ recommended) +- pgvector extension installed and enabled +- User must have CREATE, ALTER, DROP, INSERT, SELECT, UPDATE, DELETE privileges +- Database must exist before starting dhamps-vdb + +**Common Database Hosts:** +- `localhost` - Local PostgreSQL instance +- `postgres` - Docker Compose service name +- `db.example.com` - Remote database server +- IP address - Direct connection to database + +### Security Configuration + +Critical security settings for authentication and encryption. + +| Option | Environment Variable | CLI Flag | Type | Default | Required | Description | +|--------|---------------------|----------|------|---------|----------|-------------| +| Admin Key | `SERVICE_ADMINKEY` | `--admin-key` | String | - | **Yes** | Master API key for admin operations | +| Encryption Key | `ENCRYPTION_KEY` | - | String | - | **Yes** | AES-256 key for API key encryption | + +**Admin Key (`SERVICE_ADMINKEY`):** +- Master API key with full administrative privileges +- Used to create users and manage global resources +- Generate with: `openssl rand -base64 32` +- Must be kept secure and rotated regularly +- Transmitted via `Authorization: Bearer` header + +**Encryption Key (`ENCRYPTION_KEY`):** +- Used to encrypt user API keys in the database +- Minimum 32 characters required +- Uses AES-256-GCM encryption with SHA-256 hashing +- **CRITICAL:** If lost, all stored API keys become unrecoverable +- Cannot be changed without re-encrypting all existing API keys +- Generate with: `openssl rand -hex 32` +- Must be backed up securely and separately from database + +## Configuration Files + +### .env File + +The recommended way to configure dhamps-vdb. Create a `.env` file in the project root: + +```bash +# Copy template +cp template.env .env + +# Edit with your values +nano .env +``` + +**Example `.env` file:** + +```bash +# Service Configuration +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 + +# Database Configuration +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=secure_password_here +SERVICE_DBNAME=dhamps_vdb + +# Security Configuration +SERVICE_ADMINKEY=generated_admin_key_here +ENCRYPTION_KEY=generated_encryption_key_min_32_chars +``` + +**Security Notes:** +- `.env` files are in `.gitignore` by default +- Never commit `.env` files to version control +- Set restrictive permissions: `chmod 600 .env` +- Use different keys for dev/staging/production + +### template.env + +Starting template for configuration: + +```bash +#!/usr/bin/env bash + +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8888 +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=postgres +SERVICE_DBNAME=postgres +SERVICE_ADMINKEY=Ch4ngeM3! + +# Encryption key for API keys in LLM service instances +# Must be secure random string, at least 32 characters +# Generate with: openssl rand -hex 32 +ENCRYPTION_KEY=ChangeThisToASecureRandomKey123456789012 +``` + +## Docker Configuration + +### Docker Compose + +The `docker-compose.yml` file defines the full stack including PostgreSQL: + +```yaml +services: + postgres: + image: pgvector/pgvector:0.7.4-pg16 + environment: + POSTGRES_USER: ${SERVICE_DBUSER:-postgres} + POSTGRES_PASSWORD: ${SERVICE_DBPASSWORD:-postgres} + POSTGRES_DB: ${SERVICE_DBNAME:-dhamps_vdb} + ports: + - "${POSTGRES_PORT:-5432}:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + + dhamps-vdb: + build: + context: . + dockerfile: Dockerfile + depends_on: + postgres: + condition: service_healthy + environment: + SERVICE_DEBUG: ${SERVICE_DEBUG:-false} + SERVICE_HOST: ${SERVICE_HOST:-0.0.0.0} + SERVICE_PORT: ${SERVICE_PORT:-8880} + SERVICE_DBHOST: ${SERVICE_DBHOST:-postgres} + SERVICE_DBPORT: ${SERVICE_DBPORT:-5432} + SERVICE_DBUSER: ${SERVICE_DBUSER:-postgres} + SERVICE_DBPASSWORD: ${SERVICE_DBPASSWORD:-postgres} + SERVICE_DBNAME: ${SERVICE_DBNAME:-dhamps_vdb} + SERVICE_ADMINKEY: ${SERVICE_ADMINKEY} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} + ports: + - "${API_PORT:-8880}:8880" +``` + +**Docker-Specific Variables:** +- `POSTGRES_PORT` - External port for PostgreSQL (default: 5432) +- `API_PORT` - External port for dhamps-vdb API (default: 8880) + +### Docker Setup Script + +Automated setup using `docker-setup.sh`: + +```bash +# Run automated setup (generates secure keys) +./docker-setup.sh + +# Start services +docker-compose up -d + +# View logs +docker-compose logs -f dhamps-vdb +``` + +The script automatically: +- Generates secure `SERVICE_ADMINKEY` +- Generates secure `ENCRYPTION_KEY` +- Creates `.env` file with proper configuration +- Validates Docker and docker-compose installation + +### Docker Run Command + +For standalone container deployment: + +```bash +docker run -d \ + --name dhamps-vdb \ + -e SERVICE_DEBUG=false \ + -e SERVICE_HOST=0.0.0.0 \ + -e SERVICE_PORT=8880 \ + -e SERVICE_DBHOST=db.example.com \ + -e SERVICE_DBPORT=5432 \ + -e SERVICE_DBUSER=dhamps_user \ + -e SERVICE_DBPASSWORD=secure_password \ + -e SERVICE_DBNAME=dhamps_vdb \ + -e SERVICE_ADMINKEY=admin_key_here \ + -e ENCRYPTION_KEY=encryption_key_here \ + -p 8880:8880 \ + dhamps-vdb:latest +``` + +### External Database + +Using `docker-compose.external-db.yml` for external PostgreSQL: + +```bash +# Set database connection in .env +SERVICE_DBHOST=db.external.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=secure_password +SERVICE_DBNAME=dhamps_vdb + +# Start without bundled PostgreSQL +docker-compose -f docker-compose.external-db.yml up -d +``` + +## Configuration Scenarios + +### Development Environment + +Optimized for local development with verbose logging: + +```bash +# .env for development +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8880 +SERVICE_DBHOST=localhost +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=postgres +SERVICE_DBNAME=dhamps_vdb_dev +SERVICE_ADMINKEY=dev-admin-key-not-for-production +ENCRYPTION_KEY=dev-encryption-key-at-least-32-chars +``` + +**Start service:** +```bash +./dhamps-vdb +``` + +### Docker Development + +Docker-based development with hot reload: + +```bash +# .env for Docker development +SERVICE_DEBUG=true +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 +SERVICE_DBHOST=postgres +SERVICE_DBPORT=5432 +SERVICE_DBUSER=postgres +SERVICE_DBPASSWORD=postgres +SERVICE_DBNAME=dhamps_vdb +SERVICE_ADMINKEY=dev-admin-key +ENCRYPTION_KEY=dev-encryption-32-chars-minimum +``` + +**Start with:** +```bash +docker-compose up +``` + +### Production Environment + +Production-ready configuration with security hardening: + +```bash +# .env for production +SERVICE_DEBUG=false +SERVICE_HOST=0.0.0.0 +SERVICE_PORT=8880 +SERVICE_DBHOST=prod-db.internal.example.com +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_prod_user +SERVICE_DBPASSWORD= +SERVICE_DBNAME=dhamps_vdb_prod +SERVICE_ADMINKEY= +ENCRYPTION_KEY= +``` + +**Production Best Practices:** +- Use secrets management (Vault, AWS Secrets Manager, etc.) +- Disable debug logging (`SERVICE_DEBUG=false`) +- Use dedicated database user (not superuser) +- Enable SSL/TLS for database connections +- Deploy behind reverse proxy (nginx, Traefik) +- Set up monitoring and alerting +- Regular key rotation (except ENCRYPTION_KEY) +- Firewall rules to restrict access + +### Testing Environment + +Configuration for running tests: + +```bash +# Tests use testcontainers - no external config needed +go test -v ./... +``` + +**Test-specific setup:** +```bash +# Enable Docker for testcontainers +systemctl --user start podman.socket +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock + +# Run tests +go test -v ./... +``` + +## Validation and Verification + +### Startup Validation + +dhamps-vdb validates configuration on startup: + +1. **Required variables check** - Fails if missing +2. **Database connection test** - Verifies connectivity +3. **Schema migration** - Applies pending migrations +4. **Extension check** - Verifies pgvector is available + +### Configuration Test + +Verify configuration is working: + +```bash +# Check service health +curl http://localhost:8880/docs + +# Test admin authentication +curl -X GET http://localhost:8880/v1/users \ + -H "Authorization: Bearer ${SERVICE_ADMINKEY}" + +# Check database connectivity +docker-compose exec dhamps-vdb echo "Config OK" +``` + +### Common Issues + +**Missing Required Variables:** +``` +Error: SERVICE_ADMINKEY environment variable is not set +``` +Solution: Set all required variables. + +**Database Connection Failed:** +``` +Error: failed to connect to database +``` +Solution: Verify `SERVICE_DBHOST`, credentials, and that PostgreSQL is running. + +**Invalid Encryption Key:** +``` +Error: ENCRYPTION_KEY must be at least 32 characters +``` +Solution: Generate proper key with `openssl rand -hex 32`. + +**Port Already in Use:** +``` +Error: bind: address already in use +``` +Solution: Change `SERVICE_PORT` or stop conflicting service. + +## Generating Secure Keys + +### Admin Key Generation + +```bash +# Base64 encoded (recommended) +openssl rand -base64 32 + +# Hex encoded (alternative) +openssl rand -hex 24 + +# Output example: +# Kx7mP9nQ2rT5vY8zA1bC4dF6gH9jK0lM3nP5qR7sT9u= +``` + +### Encryption Key Generation + +```bash +# 32-byte hex key (required format) +openssl rand -hex 32 + +# Output example: +# a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6 +``` + +### Secure Key Storage + +**Development:** +- Store in `.env` file (not committed) +- Use password manager for team sharing + +**Production:** +- Use secrets management system +- Rotate admin key every 90 days +- Never rotate encryption key (breaks existing API keys) +- Store encryption key backup separately from database + +## Environment-Specific Examples + +### Local with External PostgreSQL + +```bash +SERVICE_DEBUG=true +SERVICE_HOST=localhost +SERVICE_PORT=8880 +SERVICE_DBHOST=192.168.1.100 +SERVICE_DBPORT=5432 +SERVICE_DBUSER=dhamps_user +SERVICE_DBPASSWORD=user_password +SERVICE_DBNAME=dhamps_vdb +SERVICE_ADMINKEY=$(openssl rand -base64 32) +ENCRYPTION_KEY=$(openssl rand -hex 32) +``` + +### Kubernetes ConfigMap + Secrets + +ConfigMap: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: dhamps-vdb-config +data: + SERVICE_DEBUG: "false" + SERVICE_HOST: "0.0.0.0" + SERVICE_PORT: "8880" + SERVICE_DBHOST: "postgres-service" + SERVICE_DBPORT: "5432" + SERVICE_DBUSER: "dhamps_user" + SERVICE_DBNAME: "dhamps_vdb" +``` + +Secrets: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: dhamps-vdb-secrets +type: Opaque +stringData: + SERVICE_DBPASSWORD: "secure_db_password" + SERVICE_ADMINKEY: "secure_admin_key" + ENCRYPTION_KEY: "secure_encryption_key_32_chars_min" +``` + +### Docker Swarm Secrets + +```bash +# Create secrets +echo "admin_key_here" | docker secret create dhamps_admin_key - +echo "encryption_key" | docker secret create dhamps_encryption_key - + +# Reference in stack file +services: + dhamps-vdb: + secrets: + - dhamps_admin_key + - dhamps_encryption_key + environment: + SERVICE_ADMINKEY_FILE: /run/secrets/dhamps_admin_key + ENCRYPTION_KEY_FILE: /run/secrets/dhamps_encryption_key +``` + +## Related Documentation + +- [Getting Started - Installation](../getting-started/installation/) +- [Getting Started - Quick Start](../getting-started/quick-start/) +- [Deployment - Docker](../deployment/docker/) +- [Deployment - Database Setup](../deployment/database/) +- [Deployment - Security](../deployment/security/) +- [Reference - Database Schema](database-schema/) diff --git a/docs/content/reference/database-schema.md b/docs/content/reference/database-schema.md new file mode 100644 index 0000000..797917a --- /dev/null +++ b/docs/content/reference/database-schema.md @@ -0,0 +1,514 @@ +--- +title: "Database Schema Reference" +weight: 2 +--- + +# Database Schema Reference + +Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes. + +## Overview + +The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in `internal/database/migrations/`. + +**Key Features:** +- Vector embeddings stored as `halfvec` for efficient storage +- HNSW indexes for fast approximate nearest neighbor search +- Automatic timestamp tracking (`created_at`, `updated_at`) +- Foreign key constraints with CASCADE deletion +- Role-based access control through association tables +- Multi-tenancy support (user-owned resources) + +## Schema Migrations + +Current schema version is defined by 4 migration files: + +1. **001_create_initial_scheme.sql** - Core tables and relationships +2. **002_create_emb_index.sql** - HNSW vector indexes +3. **003_add_public_read_flag.sql** - Public access support +4. **004_refactor_llm_services_architecture.sql** - LLM service architecture refactor + +## Core Tables + +### users + +Stores user accounts with API authentication. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `user_handle` | `VARCHAR(20)` | PRIMARY KEY | Unique user identifier (username) | +| `name` | `TEXT` | | Full name or display name | +| `email` | `TEXT` | UNIQUE, NOT NULL | Email address | +| `vdb_key` | `CHAR(64)` | UNIQUE, NOT NULL | API key (64-character hex) | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Indexes:** +- Primary key on `user_handle` +- Unique constraint on `email` +- Unique constraint on `vdb_key` + +**Special Users:** +- `_system` - Reserved system user for global LLM service definitions + +**Relationships:** +- Owns projects (1:N) +- Owns LLM service instances (1:N) +- Owns embeddings (1:N) +- Can share projects (N:M via `users_projects`) +- Can share LLM service instances (N:M via `instances_shared_with`) + +**Notes:** +- `vdb_key` is generated during user creation and returned once +- Cannot be recovered if lost +- Transmitted as `Authorization: Bearer` token + +### projects + +Stores embedding projects owned by users. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `project_id` | `SERIAL` | PRIMARY KEY | Auto-incrementing project ID | +| `project_handle` | `VARCHAR(20)` | NOT NULL | Project identifier (unique per owner) | +| `owner` | `VARCHAR(20)` | NOT NULL, FK→users | Project owner user handle | +| `description` | `TEXT` | | Project description | +| `metadata_scheme` | `TEXT` | | JSON Schema for validating embedding metadata | +| `public_read` | `BOOLEAN` | DEFAULT FALSE | Allow unauthenticated read access | +| `instance_id` | `INTEGER` | FK→instances | LLM service instance used for embeddings | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `UNIQUE (owner, project_handle)` - Project handles unique per owner +- `ON DELETE CASCADE` - Delete project when owner deleted +- `ON DELETE RESTRICT` - Prevent instance deletion if used by project + +**Relationships:** +- Owned by one user (N:1) +- Uses one LLM service instance (N:1) +- Has many embeddings (1:N) +- Can be shared with users (N:M via `users_projects`) + +**Metadata Schema:** +- Stored as JSON Schema string +- Used to validate embedding metadata +- Optional (can be NULL) +- See [Data Validation](../../concepts/metadata/) for details + +**Public Access:** +- When `public_read=TRUE`, allows unauthenticated embedding queries +- Controlled via API or by setting shared_with to `["*"]` + +### embeddings + +Stores vector embeddings with text identifiers and metadata. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `embeddings_id` | `SERIAL` | PRIMARY KEY | Auto-incrementing embedding ID | +| `text_id` | `TEXT` | INDEXED | Text identifier (URL, DOI, custom ID) | +| `owner` | `VARCHAR(20)` | NOT NULL, FK→users | Embedding owner user handle | +| `project_id` | `SERIAL` | NOT NULL, FK→projects | Project the embedding belongs to | +| `instance_id` | `SERIAL` | NOT NULL, FK→instances | LLM service instance used | +| `text` | `TEXT` | | Optional full text of the embedded content | +| `vector` | `halfvec` | NOT NULL | Embedding vector (half-precision float) | +| `vector_dim` | `INTEGER` | NOT NULL | Vector dimensionality | +| `metadata` | `jsonb` | | Optional metadata (validated if schema defined) | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `UNIQUE (text_id, owner, project_id, instance_id)` - Unique text IDs per project/instance +- `ON DELETE CASCADE` - Delete embeddings when owner, project, or instance deleted + +**Indexes:** +- Primary key on `embeddings_id` +- B-tree index on `text_id` +- HNSW vector indexes for dimensions: 384, 768, 1024, 1536, 3072 (see [Vector Indexes](#vector-indexes)) + +**Vector Storage:** +- Uses `halfvec` type (16-bit floating point) for efficient storage +- Dimensions must match LLM service instance configuration +- Validated on upload against instance dimensions + +**Relationships:** +- Owned by one user (N:1) +- Belongs to one project (N:1) +- Created with one LLM service instance (N:1) + +## LLM Service Architecture + +The LLM service architecture separates service definitions (templates) from user-specific instances. + +### definitions + +Templates for LLM embedding services (shared or user-specific). + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `definition_id` | `SERIAL` | PRIMARY KEY | Auto-incrementing definition ID | +| `definition_handle` | `VARCHAR(20)` | NOT NULL | Definition identifier (unique per owner) | +| `owner` | `VARCHAR(20)` | NOT NULL, FK→users | Definition owner (_system for global) | +| `endpoint` | `TEXT` | NOT NULL | API endpoint URL | +| `description` | `TEXT` | | Service description | +| `api_standard` | `VARCHAR(20)` | NOT NULL, FK→api_standards | API standard handle | +| `model` | `TEXT` | NOT NULL | Model name (e.g., text-embedding-3-large) | +| `dimensions` | `INTEGER` | NOT NULL | Vector dimensions produced by model | +| `context_limit` | `INTEGER` | NOT NULL | Maximum context length (tokens/chars) | +| `is_public` | `BOOLEAN` | NOT NULL, DEFAULT FALSE | Share with all users if true | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `UNIQUE (owner, definition_handle)` - Definition handles unique per owner +- `ON DELETE CASCADE` - Delete definition when owner deleted + +**Built-in Definitions:** + +System-provided definitions (owned by `_system`, `is_public=TRUE`): + +| Handle | Model | Dimensions | Context Limit | API Standard | +|--------|-------|------------|---------------|--------------| +| `openai-large` | text-embedding-3-large | 3072 | 8192 | openai | +| `openai-small` | text-embedding-3-small | 1536 | 8191 | openai | +| `cohere-v4` | embed-v4.0 | 1536 | 128000 | cohere | +| `gemini-embedding-001` | gemini-embedding-001 | 3072 | 2048 | gemini | + +**Relationships:** +- Owned by one user (N:1) +- References one API standard (N:1) +- Can be shared with users (N:M via `definitions_shared_with`) +- Used by instances (1:N) + +### instances + +User-specific configurations of LLM services with API keys. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `instance_id` | `SERIAL` | PRIMARY KEY | Auto-incrementing instance ID | +| `instance_handle` | `VARCHAR(20)` | NOT NULL | Instance identifier (unique per owner) | +| `owner` | `VARCHAR(20)` | NOT NULL, FK→users | Instance owner user handle | +| `endpoint` | `TEXT` | NOT NULL | API endpoint URL | +| `description` | `TEXT` | | Instance description | +| `api_standard` | `VARCHAR(20)` | NOT NULL, FK→api_standards | API standard handle | +| `model` | `TEXT` | NOT NULL | Model name | +| `dimensions` | `INTEGER` | NOT NULL | Vector dimensions | +| `context_limit` | `INTEGER` | NOT NULL | Maximum context length | +| `definition_id` | `INTEGER` | FK→definitions | Reference to definition template | +| `api_key_encrypted` | `BYTEA` | | Encrypted API key for service authentication | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `UNIQUE (owner, instance_handle)` - Instance handles unique per owner +- `ON DELETE CASCADE` - Delete instance when owner deleted +- `ON DELETE SET NULL` - Keep instance if definition deleted + +**Indexes:** +- Composite index on `(owner, instance_handle)` + +**API Key Encryption:** +- Encrypted using AES-256-GCM +- Encryption key from `ENCRYPTION_KEY` environment variable +- Cannot be recovered if encryption key is lost +- Stored as base64-encoded BYTEA + +**Relationships:** +- Owned by one user (N:1) +- References one API standard (N:1) +- Based on one definition template (N:1, optional) +- Used by projects (1:N) +- Used by embeddings (1:N) +- Can be shared with users (N:M via `instances_shared_with`) + +### api_standards + +Defines API specifications for LLM embedding services. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `api_standard_handle` | `VARCHAR(20)` | PRIMARY KEY | Standard identifier (e.g., openai, cohere) | +| `description` | `TEXT` | | API description and version info | +| `key_method` | `VARCHAR(20)` | NOT NULL, FK→key_methods | Authentication method | +| `key_field` | `VARCHAR(20)` | | Header/field name for API key | +| `created_at` | `TIMESTAMP` | NOT NULL | Creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Built-in Standards:** + +| Handle | Description | Key Method | Key Field | +|--------|-------------|------------|-----------| +| `openai` | OpenAI Embeddings API v1 | auth_bearer | Authorization | +| `cohere` | Cohere Embed API v2 | auth_bearer | Authorization | +| `gemini` | Gemini Embeddings API | auth_bearer | x-goog-api-key | + +**Relationships:** +- Used by definitions (1:N) +- Used by instances (1:N) +- References one key_method (N:1) + +## Association Tables + +### users_projects + +Defines project sharing and access control. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `user_handle` | `VARCHAR(20)` | FK→users, PK | User being granted access | +| `project_id` | `SERIAL` | FK→projects, PK | Project being shared | +| `role` | `VARCHAR(20)` | NOT NULL, FK→vdb_roles | Access level (owner/editor/reader) | +| `created_at` | `TIMESTAMP` | NOT NULL | Share creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `PRIMARY KEY (user_handle, project_id)` - One role per user per project +- `ON DELETE CASCADE` - Remove sharing when user or project deleted + +**Roles:** +- `owner` - Full control (only project creator) +- `editor` - Can add/modify/delete embeddings +- `reader` - Read-only access to embeddings + +### instances_shared_with + +Defines LLM service instance sharing. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `user_handle` | `VARCHAR(20)` | FK→users, PK | User being granted access | +| `instance_id` | `INTEGER` | FK→instances, PK | Instance being shared | +| `role` | `VARCHAR(20)` | NOT NULL, FK→vdb_roles | Access level | +| `created_at` | `TIMESTAMP` | NOT NULL | Share creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `PRIMARY KEY (user_handle, instance_id)` - One role per user per instance +- `ON DELETE CASCADE` - Remove sharing when user or instance deleted + +### definitions_shared_with + +Defines LLM service definition sharing. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `user_handle` | `VARCHAR(20)` | FK→users, PK | User being granted access | +| `definition_id` | `INTEGER` | FK→definitions, PK | Definition being shared | +| `created_at` | `TIMESTAMP` | NOT NULL | Share creation timestamp | +| `updated_at` | `TIMESTAMP` | NOT NULL | Last update timestamp | + +**Constraints:** +- `PRIMARY KEY (user_handle, definition_id)` - One share per user per definition +- `ON DELETE CASCADE` - Remove sharing when user or definition deleted + +**Indexes:** +- Index on `user_handle` for efficient user lookups +- Index on `definition_id` for efficient definition lookups + +## Reference Tables + +### vdb_roles + +Enumeration of valid access roles. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `vdb_role` | `VARCHAR(20)` | PRIMARY KEY | Role name | + +**Values:** +- `owner` - Full control over resource +- `editor` - Read and write access +- `reader` - Read-only access + +### key_methods + +Enumeration of API authentication methods. + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `key_method` | `VARCHAR(20)` | PRIMARY KEY | Authentication method | + +**Values:** +- `auth_bearer` - Bearer token in Authorization header +- `body_form` - API key in request body +- `query_param` - API key in URL query parameter +- `custom_header` - API key in custom header + +## Vector Indexes + +HNSW (Hierarchical Navigable Small World) indexes for fast approximate nearest neighbor search. + +### Index Configuration + +All vector indexes use HNSW with these parameters: +- `m = 24` - Number of neighbors per node +- `ef_construction = 200` - Build-time accuracy parameter +- `ef_search = 100` - Query-time accuracy parameter +- Expected recall: ~99.8% + +### Dimension-Specific Indexes + +| Index Name | Dimensions | Common Models | +|-----------|------------|---------------| +| `embeddings_vector_384` | 384 | Cohere embed-multilingual-light-v3.0, embed-english-light-v3.0 | +| `embeddings_vector_768` | 768 | BERT base, Cohere embed-multilingual-v2.0, Gemini Embeddings | +| `embeddings_vector_1024` | 1024 | BERT large, SBERT, Cohere embed-multilingual-v3.0, embed-english-v3.0 | +| `embeddings_vector_1536` | 1536 | OpenAI text-embedding-ada-002, text-embedding-3-small, Cohere embed-v4.0 | +| `embeddings_vector_3072` | 3072 | OpenAI text-embedding-3-large, Gemini embedding-001 | + +**Index Structure:** +```sql +CREATE INDEX embeddings_vector_1536 ON embeddings +USING hnsw ((vector::halfvec(1536)) halfvec_cosine_ops) +WITH (m = 24, ef_construction = 200) +WHERE (vector_dim = 1536); +``` + +**Usage:** +- Indexes are partial - only include vectors of matching dimension +- Automatically used for similarity queries with matching dimensions +- Use cosine distance for similarity calculation + +## Relationships Diagram + +``` +users (1) ──owns──> (N) projects (1) ──contains──> (N) embeddings + │ │ │ + │ └─> uses (1) instances (N) <───┘ + │ │ + │ └─> based on (1) definitions + │ │ + ├──owns──> (N) instances ──uses──> (1) api_standards + │ │ │ + │ └─> references (1) definitions + │ + └──owns──> (N) definitions ──references──> (1) api_standards + +Sharing: + users (N) <──shares─> (M) projects (via users_projects) + users (N) <──shares─> (M) instances (via instances_shared_with) + users (N) <──shares─> (M) definitions (via definitions_shared_with) +``` + +## Data Validation + +### Dimension Validation + +Embeddings must have dimensions matching their LLM service instance: +- `embeddings.vector_dim` must equal `instances.dimensions` +- Enforced at API level during upload +- Similarity queries automatically filter by matching dimensions + +### Metadata Validation + +Projects can define JSON Schema in `metadata_scheme`: +- Validates all embedding metadata on upload +- Optional - if NULL, metadata not validated +- Enforced at API level +- Admin sanity check validates all existing metadata + +### Sanity Check Queries + +The `/v1/admin/sanity-check` endpoint verifies: +1. All embeddings have dimensions matching their instance +2. All metadata conforms to project schemas (if defined) + +## Common Queries + +### Find User's Projects + +```sql +SELECT p.project_handle, p.description, p.created_at +FROM projects p +WHERE p.owner = 'alice' +ORDER BY p.created_at DESC; +``` + +### Find Shared Projects + +```sql +SELECT p.project_handle, p.owner, up.role +FROM users_projects up +JOIN projects p ON up.project_id = p.project_id +WHERE up.user_handle = 'bob' +ORDER BY p.owner, p.project_handle; +``` + +### Find Similar Embeddings + +```sql +SELECT text_id, vector <-> '[0.1, 0.2, ...]'::vector AS distance +FROM embeddings +WHERE project_id = 123 AND vector_dim = 1536 +ORDER BY vector <-> '[0.1, 0.2, ...]'::vector +LIMIT 10; +``` + +### Count Embeddings by Project + +```sql +SELECT p.project_handle, COUNT(e.embeddings_id) AS embedding_count +FROM projects p +LEFT JOIN embeddings e ON p.project_id = e.project_id +WHERE p.owner = 'alice' +GROUP BY p.project_id, p.project_handle +ORDER BY embedding_count DESC; +``` + +## Database Maintenance + +### Backup Recommendations + +**Critical Data:** +- User accounts (`users`) +- API keys (`vdb_key` in users, `api_key_encrypted` in instances) +- ENCRYPTION_KEY environment variable (backup separately!) +- Projects and embeddings + +**Backup Strategy:** +```bash +# Full database backup +pg_dump -U postgres dhamps_vdb > backup.sql + +# Backup encryption key separately +echo "$ENCRYPTION_KEY" > encryption_key.backup +chmod 400 encryption_key.backup +``` + +### Vacuum and Analyze + +```sql +-- Regular maintenance +VACUUM ANALYZE embeddings; +VACUUM ANALYZE projects; + +-- Rebuild vector indexes if needed +REINDEX INDEX embeddings_vector_1536; +``` + +### Monitoring Queries + +```sql +-- Check index usage +SELECT schemaname, tablename, indexname, idx_scan +FROM pg_stat_user_indexes +WHERE tablename = 'embeddings' +ORDER BY idx_scan DESC; + +-- Check table sizes +SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) +FROM pg_class +WHERE relname IN ('embeddings', 'projects', 'users') +ORDER BY pg_total_relation_size(oid) DESC; +``` + +## Related Documentation + +- [Concepts - Architecture](../../concepts/architecture/) +- [Concepts - Projects](../../concepts/projects/) +- [Concepts - Metadata](../../concepts/metadata/) +- [Deployment - Database Setup](../../deployment/database/) +- [Reference - Configuration](configuration/) +- [API - Endpoints](../../api/endpoints/) diff --git a/docs/content/reference/roadmap.md b/docs/content/reference/roadmap.md new file mode 100644 index 0000000..469aafb --- /dev/null +++ b/docs/content/reference/roadmap.md @@ -0,0 +1,346 @@ +--- +title: "Product Roadmap" +weight: 3 +--- + +# Product Roadmap + +Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements. + +## Overview + +This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority. + +## Completed Features + +### Core Functionality + +- [x] **User authentication & restrictions on some API calls** + - Bearer token authentication + - Role-based access control + - Admin vs user permissions + +- [x] **API versioning** + - Version 1 API with `/v1/` prefix + - Backward compatibility support + +- [x] **Better options handling** + - Command-line flags via Huma CLI + - Environment variable configuration + - `.env` file support + +- [x] **Handle metadata** + - JSONB storage for flexible metadata + - Metadata attached to embeddings + +- [x] **Validation with metadata schema** + - JSON Schema validation for embedding metadata + - Project-level schema definitions + - Automatic validation on upload + +- [x] **Filter similar passages by metadata field** + - Metadata-based filtering in similarity queries + - Exclude documents by metadata value + - Query parameters: `metadata_path` and `metadata_value` + +### Data Management + +- [x] **Use transactions** + - Atomic operations for multi-step actions + - Consistency for project creation with sharing + - Rollback on errors + +- [x] **Catch POST to existing resources** + - Prevent duplicate creation + - Return appropriate error codes + - Suggest using PUT for updates + +- [x] **Always use specific error messages** + - Detailed error descriptions + - Helpful troubleshooting information + - Consistent error response format + +### Testing & Quality + +- [x] **Tests** + - Integration tests for all major operations + - Testcontainers for isolated database testing + - Cleanup verification queries + +- [x] **When testing, check cleanup by adding a new query/function to see if all tables are empty** + - Verify test isolation + - Ensure no data leakage between tests + +- [x] **Make sure input is validated consistently** + - Dimension validation for embeddings + - Schema validation for metadata + - Request validation via Huma + +### Collaboration Features + +- [x] **Add project sharing/unsharing functions & API paths** + - Share projects with specific users + - Define roles: owner, editor, reader + - API endpoints for managing sharing + +- [x] **Add mechanism to allow anonymous/public reading access to embeddings** + - `public_read` flag on projects + - Wildcard sharing via `"*"` in `shared_with` + - Unauthenticated access to public embeddings + +- [x] **Transfer of projects from one owner to another as new operation** + - Owner-initiated project transfers + - Ownership verification + - Automatic cleanup of old owner associations + +### Service Architecture + +- [x] **Add definition creation/listing/deletion functions & paths** + - LLM service definitions (templates) + - Instances (user-specific configurations) + - System-provided global definitions + +### Deployment & Operations + +- [x] **Dockerization** + - Multi-stage Dockerfile + - Docker Compose with PostgreSQL + - External database support + - Automated setup script + +- [x] **Make sure pagination is supported consistently** + - Limit and offset parameters + - Consistent across all list endpoints + - Documented pagination behavior + +### Security + +- [x] **Prevent acceptance of requests as user "_system"** + - Reserved system user for internal use + - Blocked from external authentication + - Protected system-owned resources + +## In Progress + +### Documentation + +- [ ] **Revisit all documentation** + - Comprehensive reference documentation + - Updated API examples + - Docker deployment guides + +- [ ] **Add documentation for metadata filtering of similars** + - Document `metadata_path` and `metadata_value` parameters + - Provide usage examples + - Explain use cases (exclude same author, etc.) + - **Note:** Query parameters are: `metadata_path` and `metadata_value` as in: `https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7&limit=5&metadata_path=author_id&metadata_value=A0083` + +## Planned Features + +### High Priority + +#### Network Connectivity + +- [ ] **Implement and make consequent use of max_idle (5), max_concurr (5), timeouts, and cancellations** + - Connection pool management + - Maximum idle connections: 5 + - Maximum concurrent connections: 5 + - Request timeouts + - Context cancellation support + +- [ ] **Concurrency (leaky bucket approach) and Rate limiting** + - Leaky bucket algorithm for concurrency control + - Rate limiting using Redis + - Sliding window implementation + - Standard rate limit headers + - See [Huma request limits](https://huma.rocks/features/request-limits/) for implementation + +- [ ] **Caching** + - Response caching for frequently accessed data + - Cache invalidation strategies + - Redis or in-memory caching + - Configurable TTL + +#### API Standards + +- [ ] **Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio** + - Anthropic embeddings API + - Mistral embeddings API + - llama.cpp server API + - Ollama embeddings API + - vLLM embeddings API + - LM Studio embeddings API + - Standard authentication methods + - Example definitions in testdata + +### Medium Priority + +#### User Experience + +- [ ] **HTML UI** + - Web-based interface for API management + - User-friendly project creation + - Visual embedding explorer + - API key management + - Alternative to CLI/API usage + +- [ ] **Allow to request verbose information even in list outputs** + - `verbose=yes` query parameter + - Full object details in list endpoints + - Optional vs default minimal output + - Performance considerations + +- [ ] **Add possibility to use PATCH method to change existing resources** + - Partial updates without full replacement + - PATCH support for users, projects, instances + - Merge semantics for nested objects + - Validation of partial updates + - **Status:** Partially implemented via automatic PATCH handler + +#### Logging and Monitoring + +- [ ] **Proper logging with `--verbose` and `--quiet` modes** + - Structured logging (JSON format) + - Log levels: ERROR, WARN, INFO, DEBUG, TRACE + - `--verbose` flag for detailed logs + - `--quiet` flag for minimal logs + - Request/response logging + - Performance metrics logging + - Integration with log aggregation systems + +### Future Enhancements + +#### Advanced Features + +- [ ] **Bulk Operations** + - Batch embedding upload + - Bulk deletion + - Transaction support for large operations + +- [ ] **Advanced Search** + - Combined vector + metadata filtering + - Hybrid search (vector + keyword) + - Multi-vector search + - Weighted search results + +- [ ] **Embeddings Management** + - Update embeddings in place + - Re-embedding workflows + - Embedding versioning + - Dimension conversion utilities + +#### Performance + +- [ ] **Query Optimization** + - Query plan analysis + - Index optimization + - Materialized views for common queries + - Database connection pooling improvements + +- [ ] **Scaling** + - Horizontal scaling support + - Read replicas for query load + - Partitioning strategies for large datasets + - Distributed vector search + +#### Security & Access Control + +- [ ] **Fine-grained Permissions** + - Custom roles beyond owner/editor/reader + - Permission inheritance + - Temporary access grants + - IP-based access control + +- [ ] **Audit Logging** + - Track all API operations + - User action history + - Security event logging + - Compliance reporting + +- [ ] **OAuth/SAML Integration** + - OAuth 2.0 authentication + - SAML SSO support + - Identity provider integration + - External authentication services + +#### Integration + +- [ ] **Webhooks** + - Event notifications for embeddings changes + - Project updates notifications + - Configurable webhook endpoints + - Retry logic and delivery guarantees + +- [ ] **Export/Import** + - Project export to standard formats + - Bulk embedding export + - Import from other vector databases + - Migration utilities + +- [ ] **SDK Support** + - Python SDK + - JavaScript/TypeScript SDK + - Go SDK + - CLI improvements + +## Development Process + +### Release Cycle + +- **Minor versions** (0.x.0): New features, API additions +- **Patch versions** (0.0.x): Bug fixes, documentation updates +- **Major versions** (x.0.0): Breaking API changes (future) + +### Feature Requests + +To request a feature or suggest improvements: + +1. Check existing issues on GitHub +2. Open a new issue with: + - Clear description of the feature + - Use cases and motivation + - Proposed implementation (if any) +3. Engage in discussion with maintainers + +### Contribution Guidelines + +Contributions are welcome! See the main repository for: +- Development setup instructions +- Code style guidelines +- Testing requirements +- Pull request process + +## Version History + +### v0.1.0 (2026-02-08) +- Fix many things +- Add many things +- Still API v1 on the way to stable + +### v0.0.1 (2024-12-10) +- Initial public release +- API v1 (work in progress) +- Core functionality implemented +- Docker support +- Project sharing +- Metadata validation + +## Feedback + +We value your feedback! Please share: + +- **Feature requests** - What would make dhamps-vdb more useful? +- **Bug reports** - Help us improve quality +- **Use cases** - How are you using dhamps-vdb? +- **Documentation** - What needs clarification? + +Open an issue on GitHub or contact the maintainers directly. + +## Related Documentation + +- [Getting Started](../../getting-started/) +- [API Documentation](../../api/) +- [Deployment Guide](../../deployment/) +- [Reference - Configuration](configuration/) +- [Reference - Database Schema](database-schema/) +- [GitHub Repository](https://github.com/mpilhlt/dhamps-vdb) From 34ee8bec4fc2a7283a039d48e70a71718c3e2bb9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:42:47 +0000 Subject: [PATCH 7/9] Create complete Hugo documentation structure with 50 markdown files Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- DOCUMENTATION_SUMMARY.md | 192 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 DOCUMENTATION_SUMMARY.md diff --git a/DOCUMENTATION_SUMMARY.md b/DOCUMENTATION_SUMMARY.md new file mode 100644 index 0000000..84c6f4d --- /dev/null +++ b/DOCUMENTATION_SUMMARY.md @@ -0,0 +1,192 @@ +# Hugo Documentation Structure - Complete + +## Summary + +Created **50 markdown files** with **17,102 lines** of comprehensive Hugo documentation for dhamps-vdb. + +## Directory Structure + +``` +docs/content/ +├── _index.md (main landing page) +├── getting-started/ +│ ├── _index.md +│ ├── installation.md +│ ├── docker.md +│ ├── configuration.md +│ ├── quick-start.md +│ └── first-project.md +├── concepts/ +│ ├── _index.md +│ ├── architecture.md +│ ├── users-and-auth.md +│ ├── projects.md +│ ├── embeddings.md +│ ├── llm-services.md +│ ├── similarity-search.md +│ └── metadata.md +├── guides/ +│ ├── _index.md +│ ├── rag-workflow.md +│ ├── project-sharing.md +│ ├── public-projects.md +│ ├── ownership-transfer.md +│ ├── metadata-validation.md +│ ├── metadata-filtering.md +│ ├── batch-operations.md +│ └── instance-management.md +├── api/ +│ ├── _index.md +│ ├── authentication.md +│ ├── query-parameters.md +│ ├── patch-updates.md +│ ├── error-handling.md +│ └── endpoints/ +│ ├── _index.md +│ ├── users.md +│ ├── projects.md +│ ├── llm-services.md +│ ├── api-standards.md +│ ├── embeddings.md +│ └── similars.md +├── deployment/ +│ ├── _index.md +│ ├── docker.md +│ ├── database.md +│ ├── environment-variables.md +│ └── security.md +├── development/ +│ ├── _index.md +│ ├── testing.md +│ ├── contributing.md +│ ├── architecture.md +│ └── performance.md +└── reference/ + ├── _index.md + ├── configuration.md + ├── database-schema.md + └── roadmap.md +``` + +## Content Sources + +Documentation was migrated and organized from: +- README.md - Main content, API overview, features +- DOCKER.md - Complete Docker deployment guide +- docs/PUBLIC_ACCESS.md - Public project access (current state) +- docs/METADATA_SCHEMA_EXAMPLES.md - Validation examples +- docs/PERFORMANCE_OPTIMIZATION.md - Performance notes +- docs/LLM_SERVICE_REFACTORING.md - Current state only (no history) +- internal/models/options.go - Configuration options + +## Quality Standards Met + +✅ **Present tense** - All content describes current state +✅ **User-focused** - Written for end users, not implementers +✅ **Practical examples** - Extensive curl command examples throughout +✅ **Hugo front matter** - All files have proper title and weight +✅ **Information preserved** - No content lost from source files +✅ **No implementation history** - Technical evolution removed +✅ **Metadata filtering** - Correctly documented as EXCLUDE (negative matching) + +## Key Features Documented + +### Getting Started (6 files) +- Installation from source +- Docker deployment (comprehensive guide) +- Configuration with environment variables +- Quick start curl tutorial +- Complete first project walkthrough + +### Concepts (8 files) +- System architecture overview +- Users and authentication +- Project management +- Embeddings storage +- LLM services (definitions vs instances) +- Similarity search algorithms +- Metadata handling + +### Guides (9 files) +- RAG workflow implementation +- Project sharing and collaboration +- Public project access +- Project ownership transfer +- Metadata schema validation +- Metadata filtering (exclusion) +- Batch operations +- LLM service instance management + +### API Reference (11 files) +- Authentication methods +- Complete endpoint documentation: + - Users management + - Projects CRUD + - LLM services configuration + - API standards definitions + - Embeddings storage + - Similarity search (with metadata filtering) +- Query parameters +- PATCH updates +- Error handling + +### Deployment (5 files) +- Docker deployment guide +- PostgreSQL database setup +- Environment variables reference +- Security best practices + +### Development (5 files) +- Testing guide +- Contributing guidelines +- Architecture deep-dive +- Performance optimization notes + +### Reference (4 files) +- Configuration complete reference +- Database schema documentation +- Product roadmap + +## Special Notes + +1. **LLM Services Documentation**: Extracted CURRENT STATE from LLM_SERVICE_REFACTORING.md, removed all implementation history and migration notes. + +2. **Metadata Filtering**: Correctly documented that `metadata_path` and `metadata_value` perform NEGATIVE MATCHING (exclude documents with matching values). + +3. **Public Projects**: Focused on user functionality from PUBLIC_ACCESS.md, removed implementation details. + +4. **Docker Guide**: Comprehensive guide created from DOCKER.md with added troubleshooting and verification steps. + +5. **Configuration**: Complete documentation of all environment variables from options.go plus ENCRYPTION_KEY. + +## Hugo Compatibility + +All files include: +- Front matter with `title` field +- Front matter with `weight` field for ordering +- Markdown headers starting at level 1 (#) +- Valid markdown syntax +- Relative links between pages + +## Next Steps + +1. Configure Hugo site with theme +2. Set up navigation menus +3. Configure search functionality +4. Add site configuration (config.toml/yaml) +5. Deploy to hosting platform +6. Set up CI/CD for automatic deployment + +## Verification + +All 50 files verified present: +```bash +find docs/content -name "*.md" | wc -l +# Output: 50 +``` + +Total lines of documentation: +```bash +wc -l docs/content/**/*.md | tail -1 +# Output: 17102 total +``` From e3a141e0df65827f1673eddc9a065b7f22945326 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:43:49 +0000 Subject: [PATCH 8/9] Add Hugo documentation site with complete content structure Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- docs/public/404.html | 2 +- docs/public/api/authentication/index.html | 45 + .../api/endpoints/api-standards/index.html | 135 +++ .../api/endpoints/embeddings/index.html | 207 ++++ docs/public/api/endpoints/index.html | 13 + docs/public/api/endpoints/index.xml | 103 ++ .../api/endpoints/llm-services/index.html | 164 +++ docs/public/api/endpoints/projects/index.html | 169 +++ docs/public/api/endpoints/similars/index.html | 135 +++ docs/public/api/endpoints/users/index.html | 104 ++ docs/public/api/error-handling/index.html | 236 +++++ docs/public/api/index.html | 18 + docs/public/api/index.xml | 59 ++ docs/public/api/patch-updates/index.html | 169 +++ docs/public/api/query-parameters/index.html | 115 +++ docs/public/categories/index.html | 2 +- docs/public/concepts/architecture/index.html | 92 ++ docs/public/concepts/embeddings/index.html | 153 +++ docs/public/concepts/index.html | 10 + docs/public/concepts/index.xml | 219 ++++ docs/public/concepts/llm-services/index.html | 118 +++ docs/public/concepts/metadata/index.html | 180 ++++ docs/public/concepts/projects/index.html | 145 +++ .../concepts/similarity-search/index.html | 76 ++ .../public/concepts/users-and-auth/index.html | 73 ++ docs/public/deployment/database/index.html | 229 +++++ docs/public/deployment/docker/index.html | 122 +++ .../environment-variables/index.html | 105 ++ docs/public/deployment/index.html | 12 + docs/public/deployment/index.xml | 106 ++ docs/public/deployment/security/index.html | 219 ++++ .../development/architecture/index.html | 547 ++++++++++ .../development/contributing/index.html | 306 ++++++ docs/public/development/index.html | 17 + docs/public/development/index.xml | 137 +++ .../public/development/performance/index.html | 470 +++++++++ docs/public/development/testing/index.html | 288 ++++++ ...b05a356d5d9f40e308f4ec936f40762c90de5.json | 1 + ...f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js | 1 + .../getting-started/configuration/index.html | 52 + docs/public/getting-started/docker/index.html | 183 ++++ .../getting-started/first-project/index.html | 172 ++++ docs/public/getting-started/index.html | 9 + docs/public/getting-started/index.xml | 192 ++++ .../getting-started/installation/index.html | 21 + .../getting-started/quick-start/index.html | 160 +++ .../public/guides/batch-operations/index.html | 508 +++++++++ docs/public/guides/index.html | 10 + docs/public/guides/index.xml | 94 ++ .../guides/instance-management/index.html | 273 +++++ .../guides/metadata-filtering/index.html | 189 ++++ .../guides/metadata-validation/index.html | 372 +++++++ .../guides/ownership-transfer/index.html | 153 +++ docs/public/guides/project-sharing/index.html | 142 +++ docs/public/guides/public-projects/index.html | 162 +++ docs/public/guides/rag-workflow/index.html | 228 +++++ docs/public/icons/toc.svg | 1 + docs/public/index.html | 24 +- docs/public/index.xml | 960 +++++++++++++++++- .../public/reference/configuration/index.html | 200 ++++ .../reference/database-schema/index.html | 67 ++ docs/public/reference/index.html | 6 + docs/public/reference/index.xml | 56 + docs/public/reference/roadmap/index.html | 16 + docs/public/sitemap.xml | 2 +- docs/public/tags/index.html | 2 +- 66 files changed, 9548 insertions(+), 8 deletions(-) create mode 100644 docs/public/api/authentication/index.html create mode 100644 docs/public/api/endpoints/api-standards/index.html create mode 100644 docs/public/api/endpoints/embeddings/index.html create mode 100644 docs/public/api/endpoints/index.html create mode 100644 docs/public/api/endpoints/index.xml create mode 100644 docs/public/api/endpoints/llm-services/index.html create mode 100644 docs/public/api/endpoints/projects/index.html create mode 100644 docs/public/api/endpoints/similars/index.html create mode 100644 docs/public/api/endpoints/users/index.html create mode 100644 docs/public/api/error-handling/index.html create mode 100644 docs/public/api/index.html create mode 100644 docs/public/api/index.xml create mode 100644 docs/public/api/patch-updates/index.html create mode 100644 docs/public/api/query-parameters/index.html create mode 100644 docs/public/concepts/architecture/index.html create mode 100644 docs/public/concepts/embeddings/index.html create mode 100644 docs/public/concepts/index.html create mode 100644 docs/public/concepts/index.xml create mode 100644 docs/public/concepts/llm-services/index.html create mode 100644 docs/public/concepts/metadata/index.html create mode 100644 docs/public/concepts/projects/index.html create mode 100644 docs/public/concepts/similarity-search/index.html create mode 100644 docs/public/concepts/users-and-auth/index.html create mode 100644 docs/public/deployment/database/index.html create mode 100644 docs/public/deployment/docker/index.html create mode 100644 docs/public/deployment/environment-variables/index.html create mode 100644 docs/public/deployment/index.html create mode 100644 docs/public/deployment/index.xml create mode 100644 docs/public/deployment/security/index.html create mode 100644 docs/public/development/architecture/index.html create mode 100644 docs/public/development/contributing/index.html create mode 100644 docs/public/development/index.html create mode 100644 docs/public/development/index.xml create mode 100644 docs/public/development/performance/index.html create mode 100644 docs/public/development/testing/index.html create mode 100644 docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json create mode 100644 docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js create mode 100644 docs/public/getting-started/configuration/index.html create mode 100644 docs/public/getting-started/docker/index.html create mode 100644 docs/public/getting-started/first-project/index.html create mode 100644 docs/public/getting-started/index.html create mode 100644 docs/public/getting-started/index.xml create mode 100644 docs/public/getting-started/installation/index.html create mode 100644 docs/public/getting-started/quick-start/index.html create mode 100644 docs/public/guides/batch-operations/index.html create mode 100644 docs/public/guides/index.html create mode 100644 docs/public/guides/index.xml create mode 100644 docs/public/guides/instance-management/index.html create mode 100644 docs/public/guides/metadata-filtering/index.html create mode 100644 docs/public/guides/metadata-validation/index.html create mode 100644 docs/public/guides/ownership-transfer/index.html create mode 100644 docs/public/guides/project-sharing/index.html create mode 100644 docs/public/guides/public-projects/index.html create mode 100644 docs/public/guides/rag-workflow/index.html create mode 100644 docs/public/icons/toc.svg create mode 100644 docs/public/reference/configuration/index.html create mode 100644 docs/public/reference/database-schema/index.html create mode 100644 docs/public/reference/index.html create mode 100644 docs/public/reference/index.xml create mode 100644 docs/public/reference/roadmap/index.html diff --git a/docs/public/404.html b/docs/public/404.html index fc52734..077f282 100644 --- a/docs/public/404.html +++ b/docs/public/404.html @@ -1,4 +1,4 @@ 404 Page not found | dhamps-vdb Documentation -

    Page +

    Page Not Found

    dhamps-vdb Documentation

    \ No newline at end of file diff --git a/docs/public/api/authentication/index.html b/docs/public/api/authentication/index.html new file mode 100644 index 0000000..0608475 --- /dev/null +++ b/docs/public/api/authentication/index.html @@ -0,0 +1,45 @@ +Authentication | dhamps-vdb Documentation + +

    API Authentication#

    All API requests (except public project read operations) require authentication using API keys passed in the Authorization header with a Bearer prefix.

    Authentication Method#

    Include your API key in the Authorization header of every request:

    Authorization: Bearer your_api_key_here

    API Key Types#

    Admin API Key#

    • Full access to all API endpoints and resources
    • Can create and manage users
    • Can access all projects and resources across all users
    • Required for administrative operations
    • Set via ADMIN_KEY environment variable

    Admin-only operations:

    • POST /v1/users - Create new users
    • GET /v1/users - List all users
    • GET /v1/admin/* - Admin endpoints
    • Create/modify _system LLM service definitions
    • Access any user’s resources

    User API Key#

    • Access limited to user’s own resources and shared projects
    • Cannot create other users
    • Cannot access admin endpoints
    • Returned when creating a new user (store securely)

    User capabilities:

    • Manage own projects and LLM services
    • Upload and query embeddings in owned projects
    • Access projects shared with them (read or edit access)
    • Delete own account

    Getting an API Key#

    Admin Key#

    Set the admin key via environment variable when launching the service:

    export ADMIN_KEY="your-secure-admin-key-here"
    +./dhamps-vdb

    User Key#

    Create a new user using the admin API key:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "alice",
    +    "name": "Alice Doe",
    +    "email": "alice@example.com"
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice@example.com",
    +  "api_key": "024v2013621509245f2e24"
    +}

    ⚠️ Important: The API key is only returned once during user creation. Store it securely - it cannot be recovered.

    Authorization Header Format#

    Correct Format#

    curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer 024v2013621509245f2e24"

    Common Mistakes#

    ❌ Missing “Bearer” prefix:

    Authorization: 024v2013621509245f2e24

    ❌ Wrong prefix:

    Authorization: Token 024v2013621509245f2e24

    ❌ Extra quotes:

    Authorization: Bearer "024v2013621509245f2e24"

    Authentication Errors#

    401 Unauthorized#

    Returned when authentication credentials are missing or invalid.

    Causes:

    • Missing Authorization header
    • Invalid API key
    • Malformed header format

    Example response:

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    403 Forbidden#

    Returned when authentication succeeds but authorization fails.

    Causes:

    • Attempting to access another user’s resources
    • User lacking required permissions
    • Non-admin accessing admin endpoints

    Example response:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to access this resource"
    +}

    Public Access#

    Projects can be made publicly accessible by setting public_read: true when creating or updating the project. Public projects allow unauthenticated read access to:

    • Project metadata
    • Embeddings
    • Similarity search

    See Public Access Documentation for details.

    Security Best Practices#

    1. Never commit API keys to version control
    2. Use environment variables to store API keys in your applications
    3. Rotate keys regularly by creating new users and deleting old ones
    4. Use HTTPS in production to prevent key interception
    5. Store admin keys securely using secrets management systems
    6. Limit admin key distribution to essential personnel only

    Example Authenticated Request#

    # List user's projects
    +curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer 024v2013621509245f2e24"
    +
    +# Create a new project
    +curl -X POST "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer 024v2013621509245f2e24" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "my-project",
    +    "description": "My research project",
    +    "instance_owner": "alice",
    +    "instance_handle": "my-openai"
    +  }'
    \ No newline at end of file diff --git a/docs/public/api/endpoints/api-standards/index.html b/docs/public/api/endpoints/api-standards/index.html new file mode 100644 index 0000000..9927c9d --- /dev/null +++ b/docs/public/api/endpoints/api-standards/index.html @@ -0,0 +1,135 @@ +API Standards | dhamps-vdb Documentation + +

    API Standards Endpoint#

    Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.

    Overview#

    API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:

    • OpenAI: Bearer token in Authorization header
    • Cohere: API key in Authorization header with Bearer prefix
    • Google Gemini: API key as query parameter
    • Ollama: No authentication required

    Pre-seeded standards are available for common providers. See testdata/valid_api_standard_*.json for examples.


    Endpoints#

    List All API Standards#

    Get all defined API standards. This endpoint is publicly accessible (no authentication required).

    Endpoint: GET /v1/api-standards

    Authentication: Public (no authentication required)

    Example:

    curl -X GET "https://api.example.com/v1/api-standards"

    Response:

    {
    +  "standards": [
    +    {
    +      "api_standard_handle": "openai",
    +      "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    +      "key_method": "auth_bearer",
    +      "key_field": "Authorization"
    +    },
    +    {
    +      "api_standard_handle": "cohere",
    +      "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed",
    +      "key_method": "auth_bearer",
    +      "key_field": "Authorization"
    +    },
    +    {
    +      "api_standard_handle": "gemini",
    +      "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings",
    +      "key_method": "query_param",
    +      "key_field": "key"
    +    }
    +  ]
    +}

    Get API Standard#

    Retrieve information about a specific API standard. This endpoint is publicly accessible.

    Endpoint: GET /v1/api-standards/{standardname}

    Authentication: Public (no authentication required)

    Example:

    curl -X GET "https://api.example.com/v1/api-standards/openai"

    Response:

    {
    +  "api_standard_handle": "openai",
    +  "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    +  "key_method": "auth_bearer",
    +  "key_field": "Authorization"
    +}

    Create API Standard#

    Register a new API standard definition. Admin-only operation.

    Endpoint: POST /v1/api-standards

    Authentication: Admin only

    Request Body:

    {
    +  "api_standard_handle": "custom-provider",
    +  "description": "Custom provider embedding API",
    +  "key_method": "auth_bearer",
    +  "key_field": "Authorization"
    +}

    Parameters:

    • api_standard_handle (string, required): Unique identifier for the standard
    • description (string, required): Description including API documentation URL
    • key_method (string, required): Authentication method
      • auth_bearer: Bearer token in header
      • auth_apikey: API key in header
      • query_param: API key as query parameter
      • none: No authentication
    • key_field (string, required): Field name for the API key
      • For headers: typically "Authorization" or "X-API-Key"
      • For query params: parameter name like "key" or "api_key"

    Example:

    curl -X POST "https://api.example.com/v1/api-standards" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "api_standard_handle": "ollama",
    +    "description": "Ollama local embedding API, no authentication required",
    +    "key_method": "none",
    +    "key_field": ""
    +  }'

    Response:

    {
    +  "api_standard_handle": "ollama",
    +  "description": "Ollama local embedding API, no authentication required",
    +  "key_method": "none",
    +  "key_field": ""
    +}

    Update API Standard (PUT)#

    Create or update an API standard with a specific handle. Admin-only operation.

    Endpoint: PUT /v1/api-standards/{standardname}

    Authentication: Admin only

    Request Body: Same as POST endpoint

    Example:

    curl -X PUT "https://api.example.com/v1/api-standards/custom-provider" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "api_standard_handle": "custom-provider",
    +    "description": "Updated description for custom provider",
    +    "key_method": "auth_bearer",
    +    "key_field": "Authorization"
    +  }'

    Delete API Standard#

    Delete an API standard definition. Admin-only operation.

    Endpoint: DELETE /v1/api-standards/{standardname}

    Authentication: Admin only

    Example:

    curl -X DELETE "https://api.example.com/v1/api-standards/custom-provider" \
    +  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    +  "message": "API standard 'custom-provider' deleted successfully"
    +}

    ⚠️ Warning: Cannot delete API standards that are referenced by LLM service instances.


    Partial Update (PATCH)#

    Update specific API standard fields without providing all data. Admin-only operation.

    Endpoint: PATCH /v1/api-standards/{standardname}

    Authentication: Admin only

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/api-standards/openai" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "OpenAI Embeddings API v1 - Updated documentation link"
    +  }'

    See PATCH Updates for more details.


    API Standard Properties#

    FieldTypeRequiredDescription
    api_standard_handlestringYesUnique identifier (e.g., “openai”, “cohere”)
    descriptionstringYesDescription with API documentation URL
    key_methodstringYesAuthentication method
    key_fieldstringYesField name for API key/token

    Authentication Methods#

    auth_bearer#

    Bearer token authentication in the Authorization header.

    Example:

    {
    +  "key_method": "auth_bearer",
    +  "key_field": "Authorization"
    +}

    HTTP Request:

    Authorization: Bearer sk-proj-abc123...

    Used by: OpenAI, Cohere, Anthropic


    auth_apikey#

    API key in a custom header field.

    Example:

    {
    +  "key_method": "auth_apikey",
    +  "key_field": "X-API-Key"
    +}

    HTTP Request:

    X-API-Key: abc123...

    Used by: Some custom API providers


    query_param#

    API key passed as a URL query parameter.

    Example:

    {
    +  "key_method": "query_param",
    +  "key_field": "key"
    +}

    HTTP Request:

    GET https://api.example.com/embed?key=abc123...

    Used by: Google Gemini, some older APIs


    none#

    No authentication required.

    Example:

    {
    +  "key_method": "none",
    +  "key_field": ""
    +}

    Used by: Ollama (local), self-hosted models without auth


    Pre-seeded API Standards#

    The following API standards are created during database migration:

    openai#

    {
    +  "api_standard_handle": "openai",
    +  "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    +  "key_method": "auth_bearer",
    +  "key_field": "Authorization"
    +}

    cohere#

    {
    +  "api_standard_handle": "cohere",
    +  "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed",
    +  "key_method": "auth_bearer",
    +  "key_field": "Authorization"
    +}

    gemini#

    {
    +  "api_standard_handle": "gemini",
    +  "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings",
    +  "key_method": "query_param",
    +  "key_field": "key"
    +}

    Use Cases#

    Creating a Custom API Standard#

    For self-hosted or custom LLM services:

    curl -X POST "https://api.example.com/v1/api-standards" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "api_standard_handle": "vllm-local",
    +    "description": "vLLM local deployment with custom auth",
    +    "key_method": "auth_apikey",
    +    "key_field": "X-API-Key"
    +  }'

    Referencing in LLM Service Instance#

    Once created, reference the API standard in your LLM service instance:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-vllm" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "my-vllm",
    +    "endpoint": "https://vllm.local/v1/embeddings",
    +    "api_standard": "vllm-local",
    +    "model": "custom-embed",
    +    "dimensions": 768,
    +    "api_key_encrypted": "my-secret-key"
    +  }'

    Common Errors#

    400 Bad Request#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Invalid key_method: must be one of auth_bearer, auth_apikey, query_param, none"
    +}

    401 Unauthorized (Admin Operations)#

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    403 Forbidden (Admin Operations)#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only admin users can create/modify/delete API standards"
    +}

    404 Not Found#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "API standard 'custom-provider' not found"
    +}

    409 Conflict#

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Cannot delete API standard: referenced by 5 LLM service instances"
    +}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/embeddings/index.html b/docs/public/api/endpoints/embeddings/index.html new file mode 100644 index 0000000..9deb413 --- /dev/null +++ b/docs/public/api/endpoints/embeddings/index.html @@ -0,0 +1,207 @@ +Embeddings | dhamps-vdb Documentation + +

    Embeddings Endpoint#

    Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project’s LLM service instance dimensions.

    Endpoints#

    List Embeddings#

    Get all embeddings for a project with pagination support.

    Endpoint: GET /v1/embeddings/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters:

    • limit (integer, default: 10, max: 200): Maximum number of results to return
    • offset (integer, default: 0): Pagination offset

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=0" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "doc123",
    +      "user_handle": "alice",
    +      "project_handle": "research-docs",
    +      "instance_handle": "openai-large",
    +      "text": "This is a research document about machine learning.",
    +      "vector": [-0.020850, 0.018522, 0.053270, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "Alice Doe",
    +        "year": 2024
    +      }
    +    }
    +  ],
    +  "total_count": 150,
    +  "limit": 20,
    +  "offset": 0
    +}

    Upload Embeddings (Batch)#

    Upload one or more embeddings to a project. Supports batch upload for efficiency.

    Endpoint: POST /v1/embeddings/{username}/{projectname}

    Authentication: Admin, owner, or authorized editors

    Request Body:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "doc123",
    +      "instance_handle": "openai-large",
    +      "text": "This is a research document.",
    +      "vector": [-0.020850, 0.018522, 0.053270, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "Alice Doe",
    +        "year": 2024
    +      }
    +    },
    +    {
    +      "text_id": "doc124",
    +      "instance_handle": "openai-large",
    +      "text": "Another research document.",
    +      "vector": [0.012345, -0.054321, 0.098765, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "Bob Smith",
    +        "year": 2024
    +      }
    +    }
    +  ]
    +}

    Parameters:

    • embeddings (array, required): Array of embedding objects
      • text_id (string, required): Unique identifier for the text (URL-encoded recommended)
      • instance_handle (string, required): Handle of the LLM service instance used
      • vector (array of floats, required): Embedding vector
      • vector_dim (integer, required): Number of dimensions in the vector
      • text (string, optional): The original text
      • metadata (object, optional): Additional metadata (validated against project schema if defined)

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {
    +        "text_id": "doc123",
    +        "instance_handle": "openai-large",
    +        "text": "Machine learning research document.",
    +        "vector": [-0.020850, 0.018522, 0.053270],
    +        "vector_dim": 3,
    +        "metadata": {
    +          "author": "Alice Doe",
    +          "year": 2024
    +        }
    +      }
    +    ]
    +  }'

    Response:

    {
    +  "message": "1 embedding(s) uploaded successfully",
    +  "uploaded": ["doc123"]
    +}

    Get Single Embedding#

    Retrieve information about a specific embedding by its text identifier.

    Endpoint: GET /v1/embeddings/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "text_id": "doc123",
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "project_id": 1,
    +  "instance_handle": "openai-large",
    +  "text": "Machine learning research document.",
    +  "vector": [-0.020850, 0.018522, 0.053270, ...],
    +  "vector_dim": 3072,
    +  "metadata": {
    +    "author": "Alice Doe",
    +    "year": 2024
    +  }
    +}

    Note: URL-encode the identifier if it contains special characters (e.g., URLs).

    Example with URL identifier:

    # URL-encoded identifier
    +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/https%3A%2F%2Fexample.com%2Fdoc123" \
    +  -H "Authorization: Bearer alice_api_key"

    Delete Single Embedding#

    Delete a specific embedding by its text identifier.

    Endpoint: DELETE /v1/embeddings/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, or authorized editors

    Example:

    curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "Embedding 'doc123' deleted successfully"
    +}

    Delete All Embeddings#

    Delete all embeddings in a project.

    Endpoint: DELETE /v1/embeddings/{username}/{projectname}

    Authentication: Admin or owner

    Example:

    curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "All embeddings deleted from project alice/research-docs",
    +  "deleted_count": 150
    +}

    ⚠️ Warning: This operation is irreversible.


    Request Format Details#

    Text Identifiers#

    Text identifiers (text_id) should be:

    • Unique within a project
    • URL-encoded if they contain special characters
    • Descriptive for easier retrieval

    Examples:

    • Simple: "doc123", "article-456"
    • URL-based: "https://example.com/docs/123" (URL-encode in requests)
    • Path-based: "books/chapter1/section2"

    Vector Format#

    Vectors must be:

    • Arrays of floats (float32 or float64)
    • Matching dimensions specified in vector_dim
    • Consistent dimensions with the project’s LLM service instance

    Example:

    {
    +  "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003],
    +  "vector_dim": 5
    +}

    Metadata Format#

    Metadata is a flexible JSON object that can contain any valid JSON data:

    Simple metadata:

    {
    +  "metadata": {
    +    "author": "Alice Doe",
    +    "year": 2024,
    +    "category": "research"
    +  }
    +}

    Nested metadata:

    {
    +  "metadata": {
    +    "author": {
    +      "name": "Alice Doe",
    +      "id": "author-123"
    +    },
    +    "publication": {
    +      "year": 2024,
    +      "title": "Machine Learning Research"
    +    },
    +    "tags": ["AI", "ML", "embeddings"]
    +  }
    +}

    Validation#

    Dimension Validation#

    The API automatically validates that:

    1. Vector dimension consistency: The vector_dim field must match the dimensions configured in the LLM service instance
    2. Vector length verification: The actual number of elements in the vector array must match the declared vector_dim

    Error example:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    +}

    Metadata Schema Validation#

    If the project has a metadataScheme defined, all uploaded embeddings’ metadata will be validated against it.

    Example project schema:

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {"type": "string"},
    +    "year": {"type": "integer"}
    +  },
    +  "required": ["author"]
    +}

    Valid metadata:

    {
    +  "author": "Alice Doe",
    +  "year": 2024
    +}

    Invalid metadata (missing required field):

    {
    +  "year": 2024
    +}

    Error response:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    +}

    Response Format#

    List Response#

    {
    +  "embeddings": [...],
    +  "total_count": 150,
    +  "limit": 20,
    +  "offset": 0
    +}

    Single Embedding Response#

    {
    +  "text_id": "doc123",
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "project_id": 1,
    +  "instance_handle": "openai-large",
    +  "text": "...",
    +  "vector": [...],
    +  "vector_dim": 3072,
    +  "metadata": {...}
    +}

    Upload Response#

    {
    +  "message": "3 embedding(s) uploaded successfully",
    +  "uploaded": ["doc123", "doc124", "doc125"]
    +}

    Common Errors#

    400 Bad Request - Dimension Mismatch#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    +}

    400 Bad Request - Invalid Vector#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "vector length (1536) does not match declared vector_dim (3072)"
    +}

    400 Bad Request - Metadata Schema Violation#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    +}

    403 Forbidden#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to upload embeddings to this project"
    +}

    404 Not Found - Project#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Project 'alice/research-docs' not found"
    +}

    404 Not Found - Embedding#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    +}

    409 Conflict#

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Embedding 'doc123' already exists in project 'alice/research-docs'"
    +}

    Best Practices#

    Batch Uploads#

    Upload multiple embeddings in a single request for better performance:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {...},
    +      {...},
    +      {...}
    +    ]
    +  }'

    URL-Encoded Identifiers#

    Use URL encoding for identifiers with special characters:

    import urllib.parse
    +
    +text_id = "https://example.com/docs/123"
    +encoded_id = urllib.parse.quote(text_id, safe='')
    +# Result: "https%3A%2F%2Fexample.com%2Fdocs%2F123"

    Metadata Design#

    Design metadata schemas that:

    • Include commonly queried fields
    • Use consistent data types
    • Validate required fields
    • Support your similarity search filtering needs

    \ No newline at end of file diff --git a/docs/public/api/endpoints/index.html b/docs/public/api/endpoints/index.html new file mode 100644 index 0000000..bbe8993 --- /dev/null +++ b/docs/public/api/endpoints/index.html @@ -0,0 +1,13 @@ +Endpoints | dhamps-vdb Documentation + +

    API Endpoints#

    Complete reference for all dhamps-vdb API endpoints.

    Endpoint Categories#

    Endpoint Format#

    All endpoints follow the pattern:

    {METHOD} /v1/{resource}/{user}/{identifier}

    Where:

    • METHOD: HTTP method (GET, POST, PUT, DELETE, PATCH)
    • resource: Resource type (users, projects, embeddings, etc.)
    • user: User handle (owner of the resource)
    • identifier: Specific resource identifier

    Authentication#

    Most endpoints require authentication via the Authorization header:

    Authorization: Bearer your_api_key_here

    Public projects allow unauthenticated access to read operations.

    \ No newline at end of file diff --git a/docs/public/api/endpoints/index.xml b/docs/public/api/endpoints/index.xml new file mode 100644 index 0000000..1f54c8b --- /dev/null +++ b/docs/public/api/endpoints/index.xml @@ -0,0 +1,103 @@ +Endpoints on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/Recent content in Endpoints on dhamps-vdb DocumentationHugoen-usUsershttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/<h1 id="users-endpoint">Users Endpoint<a class="anchor" href="#users-endpoint">#</a></h1> +<p>Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-all-users">List All Users<a class="anchor" href="#list-all-users">#</a></h3> +<p>Get a list of all registered user handles.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/users</code></p> +<p><strong>Authentication:</strong> Admin only</p> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/users&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer admin_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;users&#34;</span>: [<span style="color:#e6db74">&#34;alice&#34;</span>, <span style="color:#e6db74">&#34;bob&#34;</span>, <span style="color:#e6db74">&#34;charlie&#34;</span>] +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> +<h3 id="create-user">Create User<a class="anchor" href="#create-user">#</a></h3> +<p>Register a new user and generate their API key.</p> +<p><strong>Endpoint:</strong> <code>POST /v1/users</code></p> +<p><strong>Authentication:</strong> Admin only</p> +<p><strong>Request Body:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Doe&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Parameters:</strong></p>Projectshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/<h1 id="projects-endpoint">Projects Endpoint<a class="anchor" href="#projects-endpoint">#</a></h1> +<p>Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-users-projects">List User&rsquo;s Projects<a class="anchor" href="#list-users-projects">#</a></h3> +<p>Get all projects owned by a user.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/projects/{username}</code></p> +<p><strong>Authentication:</strong> Admin, the user themselves, or users with shared access</p> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/projects/alice&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;projects&#34;</span>: [ +</span></span><span style="display:flex;"><span> { +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_id&#34;</span>: <span style="color:#ae81ff">1</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_handle&#34;</span>: <span style="color:#e6db74">&#34;research-docs&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Research document embeddings&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_id&#34;</span>: <span style="color:#ae81ff">5</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;openai-large&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;public_read&#34;</span>: <span style="color:#66d9ef">false</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> +</span></span><span style="display:flex;"><span> } +</span></span><span style="display:flex;"><span> ] +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> +<h3 id="create-project">Create Project<a class="anchor" href="#create-project">#</a></h3> +<p>Register a new project for a user.</p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/<h1 id="llm-services-endpoint">LLM Services Endpoint<a class="anchor" href="#llm-services-endpoint">#</a></h1> +<p>Manage LLM service instances and definitions. The system supports two types of LLM service resources:</p> +<ol> +<li><strong>Definitions</strong>: Reusable templates owned by <code>_system</code> or individual users</li> +<li><strong>Instances</strong>: User-specific configurations with API keys that reference definitions or stand alone</li> +</ol> +<h2 id="architecture-overview">Architecture Overview<a class="anchor" href="#architecture-overview">#</a></h2> +<pre tabindex="0"><code>definitions (templates) + └── owned by _system or users + └── contain: endpoint, model, dimensions, api_standard + └── no API keys + +instances (user-specific) + └── owned by individual users + └── reference a definition (optional) + └── contain encrypted API keys + └── can be shared with other users</code></pre><p>For complete details, see <a href="https://mpilhlt.github.io/dhamps-vdb/docs/LLM_SERVICE_REFACTORING.md">LLM Service Refactoring Documentation</a>.</p>API Standardshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/<h1 id="api-standards-endpoint">API Standards Endpoint<a class="anchor" href="#api-standards-endpoint">#</a></h1> +<p>Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:</p> +<ul> +<li><strong>OpenAI</strong>: Bearer token in <code>Authorization</code> header</li> +<li><strong>Cohere</strong>: API key in <code>Authorization</code> header with <code>Bearer</code> prefix</li> +<li><strong>Google Gemini</strong>: API key as query parameter</li> +<li><strong>Ollama</strong>: No authentication required</li> +</ul> +<p>Pre-seeded standards are available for common providers. See <a href="https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata">testdata/valid_api_standard_*.json</a> for examples.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/<h1 id="embeddings-endpoint">Embeddings Endpoint<a class="anchor" href="#embeddings-endpoint">#</a></h1> +<p>Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project&rsquo;s LLM service instance dimensions.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-embeddings">List Embeddings<a class="anchor" href="#list-embeddings">#</a></h3> +<p>Get all embeddings for a project with pagination support.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/embeddings/{username}/{projectname}</code></p> +<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> +<p><strong>Query Parameters:</strong></p> +<ul> +<li><code>limit</code> (integer, default: 10, max: 200): Maximum number of results to return</li> +<li><code>offset</code> (integer, default: 0): Pagination offset</li> +</ul> +<p><strong>Example:</strong></p>Similarshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/<h1 id="similarity-search-endpoints">Similarity Search Endpoints<a class="anchor" href="#similarity-search-endpoints">#</a></h1> +<p>Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="get-similar-documents-from-stored-embeddings">GET Similar Documents (from stored embeddings)<a class="anchor" href="#get-similar-documents-from-stored-embeddings">#</a></h3> +<p>Find documents similar to an already-stored document by its text identifier.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/similars/{username}/{projectname}/{identifier}</code></p> +<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> +<p><strong>Query Parameters:</strong></p> +<ul> +<li><code>count</code> (integer, optional, default: 10, max: 200): Number of similar documents to return</li> +<li><code>threshold</code> (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold</li> +<li><code>limit</code> (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for <code>count</code>)</li> +<li><code>offset</code> (integer, optional, default: 0): Pagination offset</li> +<li><code>metadata_path</code> (string, optional): Metadata field path for filtering (must be used with <code>metadata_value</code>)</li> +<li><code>metadata_value</code> (string, optional): Metadata value to exclude from results (must be used with <code>metadata_path</code>)</li> +</ul> +<p><strong>Example - Basic search:</strong></p> \ No newline at end of file diff --git a/docs/public/api/endpoints/llm-services/index.html b/docs/public/api/endpoints/llm-services/index.html new file mode 100644 index 0000000..aaa192b --- /dev/null +++ b/docs/public/api/endpoints/llm-services/index.html @@ -0,0 +1,164 @@ +LLM Services | dhamps-vdb Documentation + +

    LLM Services Endpoint#

    Manage LLM service instances and definitions. The system supports two types of LLM service resources:

    1. Definitions: Reusable templates owned by _system or individual users
    2. Instances: User-specific configurations with API keys that reference definitions or stand alone

    Architecture Overview#

    definitions (templates)
    +  └── owned by _system or users
    +  └── contain: endpoint, model, dimensions, api_standard
    +  └── no API keys
    +
    +instances (user-specific)
    +  └── owned by individual users
    +  └── reference a definition (optional)
    +  └── contain encrypted API keys
    +  └── can be shared with other users

    For complete details, see LLM Service Refactoring Documentation.


    Instance Endpoints#

    List User’s Instances#

    Get all LLM service instances owned by or shared with a user.

    Endpoint: GET /v1/llm-services/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "instances": [
    +    {
    +      "instance_id": 1,
    +      "instance_handle": "openai-large",
    +      "owner": "alice",
    +      "endpoint": "https://api.openai.com/v1/embeddings",
    +      "description": "OpenAI large embeddings",
    +      "api_standard": "openai",
    +      "model": "text-embedding-3-large",
    +      "dimensions": 3072,
    +      "definition_id": 1
    +    },
    +    {
    +      "instance_id": 2,
    +      "instance_handle": "custom-model",
    +      "owner": "alice",
    +      "endpoint": "https://custom.api.example.com/embed",
    +      "api_standard": "openai",
    +      "model": "custom-embed-v1",
    +      "dimensions": 1536
    +    }
    +  ]
    +}

    Note: API keys are never returned in GET responses for security.


    Create or Update Instance (PUT)#

    Create a new LLM service instance or update an existing one.

    Endpoint: PUT /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the user themselves

    Request Body (Standalone Instance):

    {
    +  "instance_handle": "openai-large",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "description": "OpenAI large embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072,
    +  "api_key_encrypted": "sk-proj-..."
    +}

    Request Body (From Definition):

    {
    +  "instance_handle": "my-openai",
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-large",
    +  "api_key_encrypted": "sk-proj-..."
    +}

    Parameters:

    • instance_handle (string, required): Unique identifier within user’s namespace
    • endpoint (string, required for standalone): API endpoint URL
    • description (string, optional): Instance description
    • api_standard (string, required for standalone): Reference to API standard (e.g., “openai”, “cohere”)
    • model (string, required for standalone): Model name
    • dimensions (integer, required for standalone): Vector dimensions
    • api_key_encrypted (string, optional): API key (encrypted if ENCRYPTION_KEY is set)
    • definition_owner (string, optional): Owner of the definition template
    • definition_handle (string, optional): Handle of the definition template

    Example - Standalone:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "openai-large",
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "api_key_encrypted": "sk-proj-..."
    +  }'

    Example - From _system Definition:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "my-openai",
    +    "definition_owner": "_system",
    +    "definition_handle": "openai-large",
    +    "api_key_encrypted": "sk-proj-..."
    +  }'

    Response:

    {
    +  "instance_id": 1,
    +  "instance_handle": "openai-large",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072
    +}

    Security Note: API keys are encrypted using AES-256-GCM if the ENCRYPTION_KEY environment variable is set. Keys are never returned in responses.


    Get Instance Information#

    Retrieve information about a specific LLM service instance.

    Endpoint: GET /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin, owner, or users with shared access

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "instance_id": 1,
    +  "instance_handle": "openai-large",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "description": "OpenAI large embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072,
    +  "definition_id": 1
    +}

    Delete Instance#

    Delete an LLM service instance.

    Endpoint: DELETE /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the owner

    Example:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "LLM service instance alice/openai-large deleted successfully"
    +}

    ⚠️ Warning: Cannot delete instances that are in use by projects.


    Partial Update (PATCH)#

    Update specific instance fields without providing all data.

    Endpoint: PATCH /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the owner

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated description"
    +  }'

    See PATCH Updates for more details.


    Instance Sharing#

    Share Instance#

    Share an LLM service instance with another user.

    Endpoint: POST /v1/llm-services/{owner}/{instance}/share

    Authentication: Admin or the instance owner

    Request Body:

    {
    +  "share_with_handle": "bob",
    +  "role": "reader"
    +}

    Roles:

    • reader: Can use the instance but cannot see API keys
    • editor: Can use the instance (owner can still modify)
    • owner: Full control (cannot be granted via sharing)

    Example:

    curl -X POST "https://api.example.com/v1/llm-services/alice/openai-large/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "bob",
    +    "role": "reader"
    +  }'

    Important: Shared users can USE the instance but cannot see the API key.


    Unshare Instance#

    Remove a user’s access to a shared instance.

    Endpoint: DELETE /v1/llm-services/{owner}/{instance}/share/{user_handle}

    Authentication: Admin or the instance owner

    Example:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large/share/bob" \
    +  -H "Authorization: Bearer alice_api_key"

    List Shared Users#

    Get a list of users the instance is shared with.

    Endpoint: GET /v1/llm-services/{owner}/{instance}/shared-with

    Authentication: Admin or the instance owner

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large/shared-with" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "instance": "alice/openai-large",
    +  "shared_with": [
    +    {
    +      "user_handle": "bob",
    +      "role": "reader"
    +    }
    +  ]
    +}

    Definition Endpoints#

    List System Definitions#

    Get all LLM service definitions owned by _system.

    Endpoint: GET /v1/llm-service-definitions/_system

    Authentication: Any authenticated user

    Example:

    curl -X GET "https://api.example.com/v1/llm-service-definitions/_system" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "definitions": [
    +    {
    +      "definition_id": 1,
    +      "definition_handle": "openai-large",
    +      "owner": "_system",
    +      "endpoint": "https://api.openai.com/v1/embeddings",
    +      "description": "OpenAI text-embedding-3-large",
    +      "api_standard": "openai",
    +      "model": "text-embedding-3-large",
    +      "dimensions": 3072
    +    },
    +    {
    +      "definition_id": 2,
    +      "definition_handle": "openai-small",
    +      "owner": "_system",
    +      "endpoint": "https://api.openai.com/v1/embeddings",
    +      "description": "OpenAI text-embedding-3-small",
    +      "api_standard": "openai",
    +      "model": "text-embedding-3-small",
    +      "dimensions": 1536
    +    }
    +  ]
    +}

    Pre-seeded System Definitions:

    • openai-large: OpenAI text-embedding-3-large (3072 dimensions)
    • openai-small: OpenAI text-embedding-3-small (1536 dimensions)
    • cohere-v4: Cohere embed-english-v4.0 (1536 dimensions)
    • gemini-embedding-001: Google Gemini embedding-001 (768 dimensions)

    Create User Definition#

    Create a reusable LLM service definition template.

    Endpoint: POST /v1/llm-service-definitions/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    +  "definition_handle": "custom-model",
    +  "endpoint": "https://custom.api.example.com/embed",
    +  "description": "Custom embedding model",
    +  "api_standard": "openai",
    +  "model": "custom-embed-v1",
    +  "dimensions": 1024
    +}

    Note: Only admin users can create _system definitions.


    Instance Properties#

    FieldTypeRequiredDescription
    instance_handlestringYesUnique identifier within user’s namespace
    ownerstringRead-onlyInstance owner’s user handle
    endpointstringYes*API endpoint URL
    descriptionstringNoInstance description
    api_standardstringYes*Reference to API standard
    modelstringYes*Model name
    dimensionsintegerYes*Vector dimensions
    api_key_encryptedstringWrite-onlyAPI key (never returned)
    definition_idintegerRead-onlyReference to definition template

    * Required for standalone instances; inherited from definition if using template


    Security Features#

    API Key Encryption#

    • Algorithm: AES-256-GCM
    • Key Source: ENCRYPTION_KEY environment variable
    • Storage: Encrypted in api_key_encrypted column
    • Retrieval: Never returned in API responses

    API Key Protection#

    API keys are write-only:

    • Provided during instance creation/update
    • Encrypted before storage
    • Never returned in GET/list responses
    • Shared users cannot see API keys

    Shared Instance Access#

    When an instance is shared:

    • Shared users can USE the instance for projects
    • Shared users CANNOT see the API key
    • Shared users CANNOT modify the instance
    • Only owner can manage sharing

    Common Errors#

    400 Bad Request#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Instance must specify either all configuration fields or reference a definition"
    +}

    403 Forbidden#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only admin users can create _system definitions"
    +}

    404 Not Found#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "LLM service instance 'alice/openai-large' not found"
    +}

    409 Conflict#

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Cannot delete instance: in use by 3 projects"
    +}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/projects/index.html b/docs/public/api/endpoints/projects/index.html new file mode 100644 index 0000000..26b81ce --- /dev/null +++ b/docs/public/api/endpoints/projects/index.html @@ -0,0 +1,169 @@ +Projects | dhamps-vdb Documentation + +

    Projects Endpoint#

    Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.

    Endpoints#

    List User’s Projects#

    Get all projects owned by a user.

    Endpoint: GET /v1/projects/{username}

    Authentication: Admin, the user themselves, or users with shared access

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "projects": [
    +    {
    +      "project_id": 1,
    +      "project_handle": "research-docs",
    +      "owner": "alice",
    +      "description": "Research document embeddings",
    +      "instance_id": 5,
    +      "instance_owner": "alice",
    +      "instance_handle": "openai-large",
    +      "public_read": false,
    +      "created_at": "2024-01-15T10:30:00Z"
    +    }
    +  ]
    +}

    Create Project#

    Register a new project for a user.

    Endpoint: POST /v1/projects/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    +  "project_handle": "research-docs",
    +  "description": "Research document embeddings",
    +  "instance_owner": "alice",
    +  "instance_handle": "openai-large",
    +  "public_read": false,
    +  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}",
    +  "shared_with": [
    +    {
    +      "user_handle": "bob",
    +      "role": "reader"
    +    }
    +  ]
    +}

    Parameters:

    • project_handle (string, required): Unique project identifier within the user’s namespace
    • description (string, optional): Project description
    • instance_owner (string, required): Owner of the LLM service instance
    • instance_handle (string, required): Handle of the LLM service instance to use
    • public_read (boolean, optional): Allow unauthenticated read access (default: false)
    • metadataScheme (string, optional): JSON Schema for validating embedding metadata
    • shared_with (array, optional): List of users to share the project with

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Research document embeddings",
    +    "instance_owner": "alice",
    +    "instance_handle": "openai-large"
    +  }'

    Response:

    {
    +  "project_id": 1,
    +  "project_handle": "research-docs",
    +  "owner": "alice",
    +  "description": "Research document embeddings",
    +  "instance_id": 5,
    +  "instance_owner": "alice",
    +  "instance_handle": "openai-large",
    +  "public_read": false
    +}

    Get Project Information#

    Retrieve information about a specific project.

    Endpoint: GET /v1/projects/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "project_id": 1,
    +  "project_handle": "research-docs",
    +  "owner": "alice",
    +  "description": "Research document embeddings",
    +  "instance_id": 5,
    +  "instance_owner": "alice",
    +  "instance_handle": "openai-large",
    +  "public_read": false,
    +  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}",
    +  "created_at": "2024-01-15T10:30:00Z"
    +}

    Update Project (PUT)#

    Create or update a project with the specified handle.

    Endpoint: PUT /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Request Body: Same as POST endpoint

    Example:

    curl -X PUT "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Updated description",
    +    "instance_owner": "alice",
    +    "instance_handle": "openai-large"
    +  }'

    Delete Project#

    Delete a project and all its embeddings.

    Endpoint: DELETE /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Example:

    curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "Project alice/research-docs deleted successfully"
    +}

    ⚠️ Warning: This operation is irreversible and will delete all embeddings in the project.


    Partial Update (PATCH)#

    Update specific project fields without providing all data.

    Endpoint: PATCH /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Example - Enable public read access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "public_read": true
    +  }'

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated project description"
    +  }'

    See PATCH Updates for more details.


    Project Sharing#

    Share Project#

    Share a project with another user, granting them read or edit access.

    Endpoint: POST /v1/projects/{owner}/{project}/share

    Authentication: Admin or the project owner

    Request Body:

    {
    +  "share_with_handle": "bob",
    +  "role": "reader"
    +}

    Roles:

    • reader: Read-only access to embeddings and similarity search
    • editor: Read and write access to embeddings

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice/research-docs/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "bob",
    +    "role": "reader"
    +  }'

    Response:

    {
    +  "message": "Project shared successfully",
    +  "project": "alice/research-docs",
    +  "shared_with": "bob",
    +  "role": "reader"
    +}

    Unshare Project#

    Remove a user’s access to a shared project.

    Endpoint: DELETE /v1/projects/{owner}/{project}/share/{user_handle}

    Authentication: Admin or the project owner

    Example:

    curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs/share/bob" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "Project unshared successfully",
    +  "project": "alice/research-docs",
    +  "removed_user": "bob"
    +}

    List Shared Users#

    Get a list of users the project is shared with.

    Endpoint: GET /v1/projects/{owner}/{project}/shared-with

    Authentication: Admin or the project owner

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice/research-docs/shared-with" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "project": "alice/research-docs",
    +  "shared_with": [
    +    {
    +      "user_handle": "bob",
    +      "role": "reader"
    +    },
    +    {
    +      "user_handle": "charlie",
    +      "role": "editor"
    +    }
    +  ]
    +}

    Note: Only the project owner can view this list. Users with shared access cannot see who else has access.


    Project Ownership Transfer#

    Transfer Ownership#

    Transfer ownership of a project to another user.

    Endpoint: POST /v1/projects/{owner}/{project}/transfer-ownership

    Authentication: Admin or the project owner

    Request Body:

    {
    +  "new_owner_handle": "bob"
    +}

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice/research-docs/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "new_owner_handle": "bob"
    +  }'

    Response:

    {
    +  "message": "Project ownership transferred successfully",
    +  "old_owner": "alice",
    +  "new_owner": "bob",
    +  "project_handle": "research-docs",
    +  "new_path": "/v1/projects/bob/research-docs"
    +}

    Important Notes:

    • Only the current owner can transfer ownership
    • The new owner must be an existing user
    • The new owner cannot already have a project with the same handle
    • After transfer, the old owner loses all access to the project
    • All embeddings and project data remain intact

    Query Parameters#

    List Projects#

    When listing projects, the following query parameters are available:

    • limit (integer, default: 10, max: 200): Maximum number of results to return
    • offset (integer, default: 0): Pagination offset

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice?limit=20&offset=40" \
    +  -H "Authorization: Bearer alice_api_key"

    Project Properties#

    FieldTypeRequiredDescription
    project_handlestringYesUnique identifier within user’s namespace
    ownerstringRead-onlyProject owner’s user handle
    descriptionstringNoProject description
    instance_ownerstringYesOwner of the LLM service instance
    instance_handlestringYesHandle of the LLM service instance
    instance_idintegerRead-onlyInternal ID of the LLM service instance
    public_readbooleanNoAllow unauthenticated read access
    metadataSchemestringNoJSON Schema for metadata validation
    created_attimestampRead-onlyProject creation timestamp

    Metadata Schema Validation#

    Projects can define a JSON Schema to validate metadata attached to embeddings. See the main README for examples.

    Example Schema:

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {"type": "string"},
    +    "year": {"type": "integer"}
    +  },
    +  "required": ["author"]
    +}

    When uploading embeddings, metadata will be validated against this schema. Invalid metadata will result in a 400 Bad Request error.


    Common Errors#

    400 Bad Request#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Project must have instance_id"
    +}

    403 Forbidden#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to modify this project"
    +}

    404 Not Found#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Project 'alice/research-docs' not found"
    +}

    409 Conflict#

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Project 'alice/research-docs' already exists"
    +}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/similars/index.html b/docs/public/api/endpoints/similars/index.html new file mode 100644 index 0000000..3ff4a46 --- /dev/null +++ b/docs/public/api/endpoints/similars/index.html @@ -0,0 +1,135 @@ +Similars | dhamps-vdb Documentation + +

    Similarity Search Endpoints#

    Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.

    Endpoints#

    GET Similar Documents (from stored embeddings)#

    Find documents similar to an already-stored document by its text identifier.

    Endpoint: GET /v1/similars/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters:

    • count (integer, optional, default: 10, max: 200): Number of similar documents to return
    • threshold (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold
    • limit (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for count)
    • offset (integer, optional, default: 0): Pagination offset
    • metadata_path (string, optional): Metadata field path for filtering (must be used with metadata_value)
    • metadata_value (string, optional): Metadata value to exclude from results (must be used with metadata_path)

    Example - Basic search:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_api_key"

    Example - With metadata filtering:

    # Exclude documents with author="John Doe"
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json",
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "results": [
    +    {
    +      "id": "doc456",
    +      "similarity": 0.95
    +    },
    +    {
    +      "id": "doc789",
    +      "similarity": 0.87
    +    },
    +    {
    +      "id": "doc321",
    +      "similarity": 0.82
    +    }
    +  ]
    +}

    POST Similar Documents (from raw embeddings)#

    Find similar documents by submitting a raw embedding vector without storing it in the database. Useful for one-time queries or testing.

    Endpoint: POST /v1/similars/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters: Same as GET endpoint above

    Request Body:

    {
    +  "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003, ...]
    +}

    The vector must be an array of float values with dimensions matching the project’s LLM service instance configuration.

    Example - Basic search:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003]
    +  }'

    Example - With metadata filtering:

    # Exclude documents from the same category
    +curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=5&metadata_path=category&metadata_value=biology" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [-0.020850, 0.018522, 0.053270, ...]
    +  }'

    Response: Same format as GET endpoint


    Query Parameters Reference#

    count / limit#

    Maximum number of similar documents to return.

    • Type: Integer
    • Default: 10
    • Max: 200
    • Note: count and limit are aliases; use either one

    Example:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20"

    threshold#

    Minimum similarity score threshold. Only documents with similarity scores >= threshold are returned.

    • Type: Float
    • Default: 0.5
    • Range: 0.0 to 1.0 (where 1.0 is most similar)

    Example:

    # Only return very similar documents (>= 0.8)
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8"

    offset#

    Pagination offset for large result sets.

    • Type: Integer
    • Default: 0
    • Use: Skip the first N results

    Example:

    # Get results 21-40
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20"

    metadata_path#

    Metadata field path for filtering results. Must be used together with metadata_value.

    • Type: String
    • Format: JSON path notation (e.g., "author", "author.name", "publication.year")
    • Use: Exclude documents where metadata field matches a specific value

    Examples:

    # Simple field
    +metadata_path=author
    +
    +# Nested field
    +metadata_path=author.name
    +
    +# Deeply nested field
    +metadata_path=publication.journal.name

    metadata_value#

    Metadata value to exclude from results. Must be used together with metadata_path.

    • Type: String
    • Use: Excludes documents where the metadata field at metadata_path equals this value

    Example - Exclude same author:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe"

    Example - Exclude same category:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=research"

    Example - Nested field:

    # Exclude documents from same author ID
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083"

    Response Format#

    Both GET and POST endpoints return the same response format:

    {
    +  "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json",
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "results": [
    +    {
    +      "id": "doc456",
    +      "similarity": 0.95
    +    },
    +    {
    +      "id": "doc789",
    +      "similarity": 0.87
    +    },
    +    {
    +      "id": "doc321",
    +      "similarity": 0.82
    +    }
    +  ]
    +}

    Response Fields:

    • $schema (string): JSON schema reference
    • user_handle (string): Project owner’s username
    • project_handle (string): Project identifier
    • results (array): Array of similar documents, ordered by similarity (highest first)
      • id (string): Document text identifier
      • similarity (float): Cosine similarity score (0-1, where 1 is most similar)

    Similarity Calculation#

    Cosine Distance#

    The API uses cosine distance (or equivalently, cosine similarity) to calculate vector similarity:

    • Range: 0 to 1
    • 1.0: Identical vectors
    • 0.0: Orthogonal vectors (completely dissimilar)
    • Higher values: More similar documents

    Dimension Filtering#

    The system automatically filters results to only include embeddings with matching dimensions. This ensures:

    • Only embeddings with matching vector_dim are compared
    • Only embeddings from the same project are considered
    • Invalid comparisons are prevented

    Dimension Validation (POST only)#

    When using the POST endpoint with raw embeddings, the API validates:

    1. The project has an associated LLM service instance
    2. The submitted vector dimensions match the instance’s configured dimensions
    3. If dimensions don’t match, a 400 Bad Request error is returned

    Error example:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "vector dimension mismatch: expected 1536 dimensions, got 768"
    +}

    Metadata Filtering#

    Both endpoints support metadata filtering to exclude documents based on metadata field values. This uses negative matching (excludes documents where the field matches the value).

    Use Cases#

    Exclude documents from the same source:

    # When finding similar documents to doc123, exclude others from the same author
    +curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=author_id&metadata_value=A0083"

    Exclude documents from the same category:

    # Find similar documents in other categories
    +curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology"

    Exclude documents with the same tag:

    # Find documents with similar content but different tags
    +curl -X POST ".../similars/alice/research-docs?metadata_path=primary_tag&metadata_value=machine-learning" \
    +  -d '{"vector": [...]}'

    Nested Field Access#

    Use dot notation for nested metadata fields:

    # Exclude documents from the same author (nested field)
    +metadata_path=author.id&metadata_value=author-123
    +
    +# Exclude documents from the same publication year
    +metadata_path=publication.year&metadata_value=2024
    +
    +# Deeply nested field
    +metadata_path=source.journal.publisher&metadata_value=Springer

    Examples#

    Find 5 most similar documents with at least 0.7 similarity:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_api_key"

    Search with Raw Vector#

    Submit a vector without storing it:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003]
    +  }'

    Search with Metadata Filtering#

    Find similar documents but exclude those from the same author:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"

    Paginated Results#

    Get the next page of results:

    # Page 1
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=0"
    +
    +# Page 2
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20"
    +
    +# Page 3
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40"

    Complex Query#

    High threshold, metadata filtering, and pagination:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&threshold=0.9&offset=0&metadata_path=category&metadata_value=biology" \
    +  -H "Authorization: Bearer alice_api_key"

    Common Errors#

    400 Bad Request - Dimension Mismatch (POST only)#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "vector dimension mismatch: expected 1536 dimensions, got 768"
    +}

    400 Bad Request - Missing metadata_value#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata_path requires metadata_value to be specified"
    +}

    400 Bad Request - Invalid threshold#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "threshold must be between 0.0 and 1.0"
    +}

    403 Forbidden#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to search this project"
    +}

    404 Not Found - Project#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Project 'alice/research-docs' not found"
    +}

    404 Not Found - Embedding (GET only)#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    +}

    Performance Considerations#

    Indexing#

    The database uses vector indexes for efficient similarity search. See the database migrations for index configuration.

    Result Limits#

    • Default limit: 10 results
    • Maximum limit: 200 results
    • Use pagination for large result sets

    Threshold Optimization#

    Higher thresholds reduce result set size and improve performance:

    • 0.5-0.7: Broad similarity (default)
    • 0.7-0.85: Moderate similarity
    • 0.85-0.95: High similarity
    • 0.95-1.0: Near-identical documents

    \ No newline at end of file diff --git a/docs/public/api/endpoints/users/index.html b/docs/public/api/endpoints/users/index.html new file mode 100644 index 0000000..53cf9ad --- /dev/null +++ b/docs/public/api/endpoints/users/index.html @@ -0,0 +1,104 @@ +Users | dhamps-vdb Documentation + +

    Users Endpoint#

    Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.

    Endpoints#

    List All Users#

    Get a list of all registered user handles.

    Endpoint: GET /v1/users

    Authentication: Admin only

    Example:

    curl -X GET "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    +  "users": ["alice", "bob", "charlie"]
    +}

    Create User#

    Register a new user and generate their API key.

    Endpoint: POST /v1/users

    Authentication: Admin only

    Request Body:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice@example.com"
    +}

    Parameters:

    • user_handle (string, required): Unique identifier for the user (alphanumeric, hyphens, underscores)
    • name (string, optional): User’s full name
    • email (string, optional): User’s email address

    Example:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "alice",
    +    "name": "Alice Doe",
    +    "email": "alice@example.com"
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice@example.com",
    +  "api_key": "024v2013621509245f2e24"
    +}

    ⚠️ Important: The api_key is only returned once during user creation. Store it securely - it cannot be recovered later.

    Error Responses:

    • 400 Bad Request: Invalid user handle or missing required fields
    • 409 Conflict: User handle already exists

    Get User Information#

    Retrieve information about a specific user.

    Endpoint: GET /v1/users/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X GET "https://api.example.com/v1/users/alice" \
    +  -H "Authorization: Bearer alice_or_admin_api_key"

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice@example.com"
    +}

    Note: API key is never returned in GET responses for security reasons.


    Create or Update User (PUT)#

    Register a new user with a specific handle or update existing user information.

    Endpoint: PUT /v1/users/{username}

    Authentication: Admin only

    Request Body:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice@example.com"
    +}

    Example:

    curl -X PUT "https://api.example.com/v1/users/alice" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "alice",
    +    "name": "Alice Smith",
    +    "email": "alice.smith@example.com"
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Smith",
    +  "email": "alice.smith@example.com",
    +  "api_key": "024v2013621509245f2e24"
    +}

    Delete User#

    Delete a user and all their associated resources (projects, LLM services, embeddings).

    Endpoint: DELETE /v1/users/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X DELETE "https://api.example.com/v1/users/alice" \
    +  -H "Authorization: Bearer alice_or_admin_api_key"

    Response:

    {
    +  "message": "User alice deleted successfully"
    +}

    ⚠️ Warning: This operation is irreversible and will delete:

    • All projects owned by the user
    • All LLM service instances owned by the user
    • All embeddings in the user’s projects
    • All sharing relationships

    Partial Update (PATCH)#

    Update specific user fields without providing all user data.

    Endpoint: PATCH /v1/users/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    +  "name": "Alice Smith"
    +}

    Example:

    curl -X PATCH "https://api.example.com/v1/users/alice" \
    +  -H "Authorization: Bearer alice_or_admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "email": "newemail@example.com"
    +  }'

    See PATCH Updates for more details.


    User Properties#

    FieldTypeRequiredDescription
    user_handlestringYesUnique identifier (alphanumeric, hyphens, underscores)
    namestringNoUser’s full name
    emailstringNoUser’s email address
    api_keystringRead-onlyGenerated API key (only returned on creation)

    Special User: _system#

    The _system user is a special internal user that:

    • Owns global LLM service definitions
    • Cannot be used for authentication
    • Cannot be deleted
    • Is created automatically during database migrations

    Users can create LLM service instances from _system definitions.

    Common Errors#

    400 Bad Request#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Invalid user_handle: must be alphanumeric with hyphens or underscores"
    +}

    401 Unauthorized#

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    403 Forbidden#

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only admin users can create new users"
    +}

    404 Not Found#

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "User 'alice' not found"
    +}

    409 Conflict#

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "User 'alice' already exists"
    +}
    \ No newline at end of file diff --git a/docs/public/api/error-handling/index.html b/docs/public/api/error-handling/index.html new file mode 100644 index 0000000..97e5264 --- /dev/null +++ b/docs/public/api/error-handling/index.html @@ -0,0 +1,236 @@ +Error Handling | dhamps-vdb Documentation + +

    Error Handling#

    The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.

    Error Response Format#

    All error responses follow this structure:

    {
    +  "title": "Error Title",
    +  "status": 400,
    +  "detail": "Detailed error message explaining what went wrong"
    +}

    Fields:

    • title (string): Human-readable error title
    • status (integer): HTTP status code
    • detail (string): Detailed description of the error

    HTTP Status Codes#

    2xx Success#

    200 OK#

    Request succeeded. Response body contains requested data.

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "projects": [...]
    +}

    201 Created#

    Resource created successfully. Response body contains the new resource.

    Example:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -d '{"user_handle": "bob"}'

    Response:

    {
    +  "user_handle": "bob",
    +  "api_key": "..."
    +}

    4xx Client Errors#

    400 Bad Request#

    The request is invalid or contains malformed data.

    Common causes:

    • Invalid JSON syntax
    • Missing required fields
    • Invalid field values or types
    • Dimension mismatches in embeddings
    • Metadata schema violations
    • Invalid query parameter values

    Examples:

    Invalid JSON:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Invalid JSON: unexpected end of input"
    +}

    Missing required field:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Missing required field: project_handle"
    +}

    Dimension mismatch:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    +}

    Metadata validation:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    +}

    Invalid query parameter:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "limit must be between 1 and 200"
    +}

    401 Unauthorized#

    Authentication failed or credentials are missing.

    Common causes:

    • Missing Authorization header
    • Invalid API key
    • Expired API key
    • Malformed Authorization header

    Example:

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    Troubleshooting:

    • Verify the Authorization header is present
    • Check the API key is correct
    • Ensure the header format is Authorization: Bearer <api_key>
    • Verify the user still exists

    403 Forbidden#

    Authentication succeeded but authorization failed. The authenticated user lacks permission for the requested operation.

    Common causes:

    • User attempting to access another user’s private resources
    • Non-admin attempting admin-only operations
    • User attempting to modify shared resources they don’t own
    • Attempting to access resources with insufficient role (reader vs editor)

    Examples:

    Admin-only operation:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only admin users can create new users"
    +}

    Accessing another user’s resource:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to access this project"
    +}

    Insufficient role:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to modify embeddings in this project. Editor role required."
    +}

    404 Not Found#

    The requested resource does not exist.

    Common causes:

    • Resource was deleted
    • Incorrect resource identifier
    • Typo in URL path
    • Resource never existed

    Examples:

    User not found:

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "User 'alice' not found"
    +}

    Project not found:

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Project 'alice/research-docs' not found"
    +}

    Embedding not found:

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    +}

    LLM service not found:

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "LLM service instance 'alice/openai-large' not found"
    +}

    409 Conflict#

    The request conflicts with the current state of the resource.

    Common causes:

    • Creating a resource that already exists
    • Deleting a resource that is in use
    • Concurrent modification conflicts

    Examples:

    Resource already exists:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "User 'alice' already exists"
    +}

    Resource in use:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Cannot delete LLM service instance: in use by 3 projects"
    +}

    Ownership transfer conflict:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "New owner already has a project with handle 'research-docs'"
    +}

    422 Unprocessable Entity#

    The request is syntactically correct but semantically invalid.

    Common causes:

    • Invalid JSON Schema
    • Logical validation failures
    • Constraint violations

    Example:

    {
    +  "title": "Unprocessable Entity",
    +  "status": 422,
    +  "detail": "metadataScheme is not valid JSON Schema: invalid schema structure"
    +}

    5xx Server Errors#

    500 Internal Server Error#

    An unexpected error occurred on the server.

    Common causes:

    • Database connection failures
    • Unexpected exceptions
    • Configuration errors

    Example:

    {
    +  "title": "Internal Server Error",
    +  "status": 500,
    +  "detail": "An internal error occurred. Please try again later."
    +}

    Action: Contact support if the error persists.


    503 Service Unavailable#

    The service is temporarily unavailable.

    Common causes:

    • Database maintenance
    • Service overload
    • Network issues

    Example:

    {
    +  "title": "Service Unavailable",
    +  "status": 503,
    +  "detail": "Service temporarily unavailable. Please try again later."
    +}

    Action: Retry the request after a delay.


    Common Error Scenarios#

    Authentication Errors#

    Missing Authorization Header#

    Request:

    curl -X GET "https://api.example.com/v1/projects/alice"

    Response:

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    Solution: Include the Authorization header:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer alice_api_key"

    Invalid API Key#

    Request:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer invalid_key"

    Response:

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    Solution: Verify your API key is correct.


    Permission Errors#

    Non-Admin Creating Users#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -d '{"user_handle": "bob"}'

    Response:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only admin users can create new users"
    +}

    Solution: Use an admin API key.


    Accessing Another User’s Project#

    Request:

    curl -X GET "https://api.example.com/v1/projects/bob/private-project" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to access this project"
    +}

    Solution: Request the project owner to share the project with you.


    Validation Errors#

    Invalid JSON#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle": "bob"'

    Response:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Invalid JSON: unexpected end of input"
    +}

    Solution: Fix the JSON syntax.


    Dimension Mismatch#

    Request:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc123",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3],
    +      "vector_dim": 3
    +    }]
    +  }'

    Response:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3 dimensions but LLM service 'openai-large' expects 3072 dimensions"
    +}

    Solution: Ensure vector dimensions match the LLM service configuration.


    Metadata Schema Violation#

    Request:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc123",
    +      "instance_handle": "openai-large",
    +      "vector": [...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "year": 2024
    +      }
    +    }]
    +  }'

    Response (if project schema requires “author”):

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    +}

    Solution: Include all required metadata fields.


    Resource Conflicts#

    Creating Duplicate Resource#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -d '{"user_handle": "alice"}'

    Response:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "User 'alice' already exists"
    +}

    Solution: Use a different user handle or update the existing user.


    Deleting Resource In Use#

    Request:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "Cannot delete LLM service instance: in use by 3 projects"
    +}

    Solution: Delete or update the projects using this instance first.


    Error Handling Best Practices#

    Client-Side Error Handling#

    Python example:

    import requests
    +
    +response = requests.get(
    +    "https://api.example.com/v1/projects/alice",
    +    headers={"Authorization": f"Bearer {api_key}"}
    +)
    +
    +if response.status_code == 200:
    +    projects = response.json()["projects"]
    +    print(f"Found {len(projects)} projects")
    +    
    +elif response.status_code == 401:
    +    print("Authentication failed - check API key")
    +    
    +elif response.status_code == 403:
    +    print("Permission denied")
    +    
    +elif response.status_code == 404:
    +    print("User not found")
    +    
    +elif response.status_code >= 500:
    +    print("Server error - retry later")
    +    
    +else:
    +    error = response.json()
    +    print(f"Error: {error['detail']}")

    Retry Logic#

    For transient errors (5xx), implement exponential backoff:

    import time
    +import requests
    +
    +def api_request_with_retry(url, max_retries=3):
    +    for attempt in range(max_retries):
    +        response = requests.get(url, headers={...})
    +        
    +        if response.status_code < 500:
    +            return response
    +            
    +        if attempt < max_retries - 1:
    +            wait_time = 2 ** attempt  # Exponential backoff
    +            print(f"Retrying in {wait_time}s...")
    +            time.sleep(wait_time)
    +    
    +    return response

    Validation Before Request#

    Validate data locally before sending to reduce 400 errors:

    def create_embedding(text_id, vector, metadata):
    +    # Validate locally
    +    if not text_id:
    +        raise ValueError("text_id is required")
    +    
    +    if not isinstance(vector, list):
    +        raise ValueError("vector must be a list")
    +    
    +    if len(vector) != 3072:
    +        raise ValueError("vector must have 3072 dimensions")
    +    
    +    # Send request
    +    response = requests.post(
    +        "https://api.example.com/v1/embeddings/alice/research-docs",
    +        json={
    +            "embeddings": [{
    +                "text_id": text_id,
    +                "instance_handle": "openai-large",
    +                "vector": vector,
    +                "vector_dim": len(vector),
    +                "metadata": metadata
    +            }]
    +        },
    +        headers={"Authorization": f"Bearer {api_key}"}
    +    )
    +    
    +    return response.json()

    Troubleshooting#

    Check API Documentation#

    Always refer to the live API documentation:

    • OpenAPI YAML: /openapi.yaml
    • Interactive Docs: /docs

    Verify Request Format#

    Use tools like curl -v to inspect the full request:

    curl -v -X POST "https://api.example.com/v1/users" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle": "bob"}'

    Check Status and Logs#

    For persistent 5xx errors, check service status and logs (if you have access).


    Contact Support#

    If errors persist or the cause is unclear:

    1. Note the error message and status code
    2. Record the request details (method, URL, headers, body)
    3. Check if the issue is reproducible
    4. Contact support with this information

    \ No newline at end of file diff --git a/docs/public/api/index.html b/docs/public/api/index.html new file mode 100644 index 0000000..ed3425a --- /dev/null +++ b/docs/public/api/index.html @@ -0,0 +1,18 @@ +API Reference | dhamps-vdb Documentation + +

    API Reference#

    Complete reference for the dhamps-vdb REST API.

    API Version#

    Current version: v1

    All endpoints are prefixed with /v1/ (e.g., POST /v1/embeddings/{user}/{project}).

    API Documentation#

    The complete, always up-to-date API specification is available at:

    • OpenAPI YAML: /openapi.yaml
    • Interactive Documentation: /docs

    Reference Sections#

    Quick Example#

    # Authenticate with API key
    +curl -X GET "https://api.example.com/v1/projects/alice" \
    +  -H "Authorization: Bearer your_api_key_here"

    All API requests require authentication except for public project read operations.

    \ No newline at end of file diff --git a/docs/public/api/index.xml b/docs/public/api/index.xml new file mode 100644 index 0000000..0824b4a --- /dev/null +++ b/docs/public/api/index.xml @@ -0,0 +1,59 @@ +API Reference on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/api/Recent content in API Reference on dhamps-vdb DocumentationHugoen-usAuthenticationhttps://mpilhlt.github.io/dhamps-vdb/api/authentication/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/authentication/<h1 id="api-authentication">API Authentication<a class="anchor" href="#api-authentication">#</a></h1> +<p>All API requests (except public project read operations) require authentication using API keys passed in the <code>Authorization</code> header with a <code>Bearer</code> prefix.</p> +<h2 id="authentication-method">Authentication Method<a class="anchor" href="#authentication-method">#</a></h2> +<p>Include your API key in the <code>Authorization</code> header of every request:</p> +<pre tabindex="0"><code>Authorization: Bearer your_api_key_here</code></pre><h2 id="api-key-types">API Key Types<a class="anchor" href="#api-key-types">#</a></h2> +<h3 id="admin-api-key">Admin API Key<a class="anchor" href="#admin-api-key">#</a></h3> +<ul> +<li>Full access to all API endpoints and resources</li> +<li>Can create and manage users</li> +<li>Can access all projects and resources across all users</li> +<li>Required for administrative operations</li> +<li>Set via <code>ADMIN_KEY</code> environment variable</li> +</ul> +<p><strong>Admin-only operations:</strong></p>Query Parametershttps://mpilhlt.github.io/dhamps-vdb/api/query-parameters/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/<h1 id="query-parameters-reference">Query Parameters Reference<a class="anchor" href="#query-parameters-reference">#</a></h1> +<p>Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.</p> +<h2 id="pagination-parameters">Pagination Parameters<a class="anchor" href="#pagination-parameters">#</a></h2> +<h3 id="limit">limit<a class="anchor" href="#limit">#</a></h3> +<p>Maximum number of results to return in a single response.</p> +<p><strong>Type:</strong> Integer<br> +<strong>Default:</strong> 10<br> +<strong>Maximum:</strong> 200<br> +<strong>Minimum:</strong> 1</p> +<p><strong>Used by:</strong></p> +<ul> +<li><code>GET /v1/embeddings/{user}/{project}</code> - List embeddings</li> +<li><code>GET /v1/similars/{user}/{project}/{id}</code> - Similarity search</li> +<li><code>POST /v1/similars/{user}/{project}</code> - Raw vector search</li> +<li><code>GET /v1/projects/{user}</code> - List projects</li> +</ul> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get 50 embeddings</span> +</span></span><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Aliases:</strong></p>PATCH Updateshttps://mpilhlt.github.io/dhamps-vdb/api/patch-updates/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/<h1 id="patch-method-for-partial-updates">PATCH Method for Partial Updates<a class="anchor" href="#patch-method-for-partial-updates">#</a></h1> +<p>The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:</p> +<ol> +<li>Retrieves the current resource state via GET</li> +<li>Merges your changes with the existing data</li> +<li>Applies the update via PUT</li> +</ol> +<p>This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.</p>Error Handlinghttps://mpilhlt.github.io/dhamps-vdb/api/error-handling/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/error-handling/<h1 id="error-handling">Error Handling<a class="anchor" href="#error-handling">#</a></h1> +<p>The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.</p> +<h2 id="error-response-format">Error Response Format<a class="anchor" href="#error-response-format">#</a></h2> +<p>All error responses follow this structure:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Error Title&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;status&#34;</span>: <span style="color:#ae81ff">400</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;detail&#34;</span>: <span style="color:#e6db74">&#34;Detailed error message explaining what went wrong&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Fields:</strong></p> +<ul> +<li><code>title</code> (string): Human-readable error title</li> +<li><code>status</code> (integer): HTTP status code</li> +<li><code>detail</code> (string): Detailed description of the error</li> +</ul> +<h2 id="http-status-codes">HTTP Status Codes<a class="anchor" href="#http-status-codes">#</a></h2> +<h3 id="2xx-success">2xx Success<a class="anchor" href="#2xx-success">#</a></h3> +<h4 id="200-ok">200 OK<a class="anchor" href="#200-ok">#</a></h4> +<p>Request succeeded. Response body contains requested data.</p> \ No newline at end of file diff --git a/docs/public/api/patch-updates/index.html b/docs/public/api/patch-updates/index.html new file mode 100644 index 0000000..60335f6 --- /dev/null +++ b/docs/public/api/patch-updates/index.html @@ -0,0 +1,169 @@ +PATCH Updates | dhamps-vdb Documentation + +

    PATCH Method for Partial Updates#

    The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.

    Overview#

    PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:

    1. Retrieves the current resource state via GET
    2. Merges your changes with the existing data
    3. Applies the update via PUT

    This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.

    Supported Resources#

    PATCH is available for:

    • Users: /v1/users/{username}
    • Projects: /v1/projects/{username}/{projectname}
    • LLM Services: /v1/llm-services/{username}/{llm_servicename}
    • API Standards: /v1/api-standards/{standardname}

    Request Format#

    Endpoint: PATCH {resource_url}

    Content-Type: application/json

    Body: JSON object containing only the fields to update

    Examples#

    Update Project Description#

    Change only the project description without affecting other fields.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated project description"
    +  }'

    Response:

    {
    +  "project_id": 1,
    +  "project_handle": "research-docs",
    +  "owner": "alice",
    +  "description": "Updated project description",
    +  "instance_id": 5,
    +  "instance_owner": "alice",
    +  "instance_handle": "openai-large",
    +  "public_read": false
    +}

    Enable Public Read Access#

    Make a project publicly accessible without changing other settings.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "public_read": true
    +  }'

    Response:

    {
    +  "project_id": 1,
    +  "project_handle": "research-docs",
    +  "owner": "alice",
    +  "description": "Research document embeddings",
    +  "instance_id": 5,
    +  "instance_owner": "alice",
    +  "instance_handle": "openai-large",
    +  "public_read": true
    +}

    Update User Email#

    Change a user’s email address without affecting other user data.

    Request:

    curl -X PATCH "https://api.example.com/v1/users/alice" \
    +  -H "Authorization: Bearer alice_or_admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "email": "alice.new@example.com"
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Doe",
    +  "email": "alice.new@example.com"
    +}

    Update LLM Service Description#

    Change the description of an LLM service instance.

    Request:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Production OpenAI embeddings service"
    +  }'

    Response:

    {
    +  "instance_id": 1,
    +  "instance_handle": "openai-large",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "description": "Production OpenAI embeddings service",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072
    +}

    Update API Standard Documentation#

    Update the description of an API standard (admin only).

    Request:

    curl -X PATCH "https://api.example.com/v1/api-standards/openai" \
    +  -H "Authorization: Bearer admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "OpenAI Embeddings API, Version 1 - Updated 2024"
    +  }'

    Update Multiple Fields#

    You can update multiple fields in a single PATCH request.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated description",
    +    "public_read": true
    +  }'

    Add Project Metadata Schema#

    Add or update a project’s metadata validation schema.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    +  }'

    Use Cases#

    Configuration Changes#

    Update configuration settings without rebuilding entire resource objects:

    # Enable/disable public access
    +curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{"public_read": true}'
    +
    +# Update instance dimensions
    +curl -X PATCH ".../llm-services/alice/custom-model" \
    +  -d '{"dimensions": 1024}'

    Metadata Management#

    Update descriptive metadata:

    # Update project description
    +curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{"description": "New description"}'
    +
    +# Update user name
    +curl -X PATCH ".../users/alice" \
    +  -d '{"name": "Alice Smith"}'

    Schema Evolution#

    Add or update validation schemas:

    curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"category\":{\"type\":\"string\"}}}"
    +  }'

    Authentication#

    PATCH requests require the same authentication as PUT requests for the resource:

    ResourceWho Can PATCH
    UsersAdmin or the user themselves
    ProjectsAdmin or project owner
    LLM ServicesAdmin or instance owner
    API StandardsAdmin only

    Behavior Details#

    Merge Strategy#

    PATCH uses a shallow merge strategy:

    • Top-level fields you specify replace the existing values
    • Nested objects are replaced entirely (not deep-merged)
    • Fields you don’t specify remain unchanged

    Example:

    Existing project:

    {
    +  "description": "Old description",
    +  "public_read": false,
    +  "metadataScheme": "{...old schema...}"
    +}

    PATCH request:

    {
    +  "description": "New description"
    +}

    Result:

    {
    +  "description": "New description",
    +  "public_read": false,
    +  "metadataScheme": "{...old schema...}"
    +}

    Validation#

    All field values are validated according to the resource’s schema:

    • Field types must be correct
    • Required fields (if specified) must be valid
    • Constraints (e.g., string length, enum values) are enforced

    Atomic Operations#

    PATCH operations are atomic:

    • Either all changes succeed, or none are applied
    • If validation fails, the resource remains unchanged

    Comparison: PATCH vs PUT#

    PUT (Complete Replacement)#

    Requires: All fields (except read-only ones)

    curl -X PUT ".../projects/alice/research-docs" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Updated description",
    +    "instance_owner": "alice",
    +    "instance_handle": "openai-large",
    +    "public_read": false
    +  }'

    Use when: Creating or completely replacing a resource


    PATCH (Partial Update)#

    Requires: Only fields to change

    curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{
    +    "description": "Updated description"
    +  }'

    Use when: Modifying one or a few fields of an existing resource


    Error Handling#

    400 Bad Request#

    Invalid field values or types:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "Invalid value for field 'public_read': expected boolean, got string"
    +}

    401 Unauthorized#

    Missing or invalid authentication:

    {
    +  "title": "Unauthorized",
    +  "status": 401,
    +  "detail": "Invalid or missing authorization credentials"
    +}

    403 Forbidden#

    Insufficient permissions:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "You don't have permission to modify this resource"
    +}

    404 Not Found#

    Resource doesn’t exist:

    {
    +  "title": "Not Found",
    +  "status": 404,
    +  "detail": "Project 'alice/research-docs' not found"
    +}

    422 Unprocessable Entity#

    Validation failed:

    {
    +  "title": "Unprocessable Entity",
    +  "status": 422,
    +  "detail": "metadataScheme is not valid JSON Schema"
    +}

    Best Practices#

    Use PATCH for Single-Field Updates#

    Do:

    curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{"public_read": true}'

    Don’t:

    # Unnecessarily complex
    +curl -X PUT ".../projects/alice/research-docs" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Research docs",
    +    "instance_owner": "alice",
    +    "instance_handle": "openai-large",
    +    "public_read": true
    +  }'

    Update multiple related fields in one request:

    curl -X PATCH ".../projects/alice/research-docs" \
    +  -d '{
    +    "description": "Updated project",
    +    "public_read": true,
    +    "metadataScheme": "{...new schema...}"
    +  }'

    Validate Before Patching#

    When possible, validate changes locally before submitting:

    # Python example
    +def update_project_description(project_path, new_description):
    +    if not new_description or len(new_description) > 500:
    +        raise ValueError("Invalid description")
    +    
    +    response = requests.patch(
    +        f"{API_BASE}/projects/{project_path}",
    +        json={"description": new_description},
    +        headers={"Authorization": f"Bearer {API_KEY}"}
    +    )
    +    return response.json()

    Handle Errors Gracefully#

    response = requests.patch(
    +    f"{API_BASE}/projects/alice/research-docs",
    +    json={"public_read": True},
    +    headers={"Authorization": f"Bearer {API_KEY}"}
    +)
    +
    +if response.status_code == 200:
    +    print("Updated successfully")
    +elif response.status_code == 403:
    +    print("Permission denied")
    +elif response.status_code == 404:
    +    print("Project not found")
    +else:
    +    print(f"Error: {response.json()['detail']}")

    Limitations#

    Not Available For#

    PATCH is not available for:

    • Endpoints that don’t support GET and PUT
    • List endpoints (e.g., GET /v1/projects/alice)
    • Action endpoints (e.g., /share, /transfer-ownership)

    Cannot Change Identifiers#

    You cannot use PATCH to change resource identifiers:

    • user_handle
    • project_handle
    • instance_handle
    • api_standard_handle

    To rename a resource, you must create a new resource and delete the old one.


    \ No newline at end of file diff --git a/docs/public/api/query-parameters/index.html b/docs/public/api/query-parameters/index.html new file mode 100644 index 0000000..d037f96 --- /dev/null +++ b/docs/public/api/query-parameters/index.html @@ -0,0 +1,115 @@ +Query Parameters | dhamps-vdb Documentation + +

    Query Parameters Reference#

    Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.

    Pagination Parameters#

    limit#

    Maximum number of results to return in a single response.

    Type: Integer
    Default: 10
    Maximum: 200
    Minimum: 1

    Used by:

    • GET /v1/embeddings/{user}/{project} - List embeddings
    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search
    • GET /v1/projects/{user} - List projects

    Example:

    # Get 50 embeddings
    +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=50" \
    +  -H "Authorization: Bearer alice_api_key"

    Aliases:

    • count - Used in similarity search endpoints (same behavior as limit)

    offset#

    Number of results to skip before returning data. Used for pagination.

    Type: Integer
    Default: 0
    Minimum: 0

    Used by:

    • GET /v1/embeddings/{user}/{project} - List embeddings
    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search
    • GET /v1/projects/{user} - List projects

    Example:

    # Get results 21-40 (page 2)
    +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=20" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Get results 41-60 (page 3)
    +curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=40" \
    +  -H "Authorization: Bearer alice_api_key"

    Pagination Formula:

    Page N: offset = (N - 1) * limit

    Similarity Search Parameters#

    count#

    Number of similar documents to return. Alias for limit in similarity search endpoints.

    Type: Integer
    Default: 10
    Maximum: 200
    Minimum: 1

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Find 5 most similar documents
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5" \
    +  -H "Authorization: Bearer alice_api_key"

    Note: count and limit can be used interchangeably in similarity endpoints.


    threshold#

    Minimum similarity score threshold. Only results with similarity >= threshold are returned.

    Type: Float
    Default: 0.5
    Range: 0.0 to 1.0
    Note: 1.0 = most similar, 0.0 = least similar

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Only return highly similar documents (>= 0.8)
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Return moderately similar documents (>= 0.6)
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.6" \
    +  -H "Authorization: Bearer alice_api_key"

    Threshold Guidelines:

    ThresholdInterpretationUse Case
    0.95-1.0Near-identicalDuplicate detection
    0.85-0.95Very similarFinding closely related documents
    0.7-0.85Moderately similarBroad similarity search
    0.5-0.7Loosely similarExploratory search
    0.0-0.5Weakly similarGenerally not useful

    Metadata Filtering Parameters#

    metadata_path#

    JSON path to a metadata field for filtering results. Must be used together with metadata_value.

    Type: String
    Format: JSON path notation (e.g., "author", "author.name", "publication.year")

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Path Notation:

    • Simple field: author
    • Nested field: author.name
    • Deeply nested: publication.journal.name

    Example:

    # Simple field path
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=John%20Doe"
    +
    +# Nested field path
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083"

    metadata_value#

    Metadata value to exclude from similarity search results. Must be used together with metadata_path.

    Type: String
    Behavior: Negative matching (excludes documents where field equals this value)

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Exclude documents from the same author
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Exclude documents from the same category
    +curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology" \
    +  -H "Authorization: Bearer alice_api_key"

    URL Encoding:

    Always URL-encode metadata values that contain special characters:

    # Value: "John Doe" → "John%20Doe"
    +# Value: "2024-01-15" → "2024-01-15" (no special chars)
    +# Value: "author@example.com" → "author%40example.com"

    Parameter Combinations#

    Pagination with Filtering#

    Combine limit, offset, and threshold:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40&threshold=0.7" \
    +  -H "Authorization: Bearer alice_api_key"

    Similarity Search with Metadata Filtering#

    Combine threshold and metadata filtering:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&threshold=0.8&metadata_path=author&metadata_value=John%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"

    Complete Query with All Parameters#

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&offset=0&threshold=0.75&metadata_path=category&metadata_value=biology" \
    +  -H "Authorization: Bearer alice_api_key"

    Endpoint-Specific Parameters#

    List Embeddings#

    Endpoint: GET /v1/embeddings/{user}/{project}

    Supported Parameters:

    • limit (default: 10, max: 200)
    • offset (default: 0)

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=100&offset=200" \
    +  -H "Authorization: Bearer alice_api_key"

    List Projects#

    Endpoint: GET /v1/projects/{user}

    Supported Parameters:

    • limit (default: 10, max: 200)
    • offset (default: 0)

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice?limit=50&offset=0" \
    +  -H "Authorization: Bearer alice_api_key"

    Similarity Search (GET)#

    Endpoint: GET /v1/similars/{user}/{project}/{id}

    Supported Parameters:

    • count / limit (default: 10, max: 200)
    • offset (default: 0)
    • threshold (default: 0.5, range: 0.0-1.0)
    • metadata_path (optional, requires metadata_value)
    • metadata_value (optional, requires metadata_path)

    Example:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&threshold=0.7&metadata_path=author&metadata_value=John%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"

    Similarity Search (POST)#

    Endpoint: POST /v1/similars/{user}/{project}

    Supported Parameters: Same as GET similarity search

    Example:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [-0.020850, 0.018522, 0.053270, ...]
    +  }'

    Parameter Validation#

    Invalid Parameter Values#

    Error Response:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "limit must be between 1 and 200"
    +}

    Common Validation Errors:

    • limit exceeds maximum (200)
    • limit less than minimum (1)
    • offset is negative
    • threshold outside range 0.0-1.0
    • metadata_path without metadata_value
    • metadata_value without metadata_path

    Best Practices#

    Pagination#

    Do:

    • Use consistent limit values across pages
    • Start with offset=0 for the first page
    • Increment offset by limit for each subsequent page

    Example pagination logic:

    limit = 20
    +page = 1
    +
    +# Page 1
    +offset = (page - 1) * limit  # 0
    +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"
    +
    +# Page 2
    +page = 2
    +offset = (page - 1) * limit  # 20
    +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"
    +
    +# Page 3
    +page = 3
    +offset = (page - 1) * limit  # 40
    +url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"

    Do:

    • Use higher thresholds (0.7-0.9) for focused searches
    • Use lower thresholds (0.5-0.7) for exploratory searches
    • Combine with count to limit result size
    • Use metadata filtering to exclude unwanted results

    Don’t:

    • Request more results than needed (affects performance)
    • Use very low thresholds (<0.5) unless necessary

    Metadata Filtering#

    Do:

    • URL-encode metadata values with special characters
    • Use specific field paths for nested metadata
    • Test metadata paths with sample queries first

    Example:

    # Good: URL-encoded, specific path
    +metadata_path=author.id&metadata_value=A0083
    +
    +# Good: Simple field
    +metadata_path=category&metadata_value=biology
    +
    +# Bad: Not URL-encoded
    +metadata_path=author name&metadata_value=John Doe
    +
    +# Good: URL-encoded
    +metadata_path=author%20name&metadata_value=John%20Doe

    Response Formats#

    Paginated Response#

    Endpoints that support pagination typically return:

    {
    +  "items": [...],
    +  "total_count": 500,
    +  "limit": 20,
    +  "offset": 40,
    +  "has_more": true
    +}

    Fields:

    • items: Array of results
    • total_count: Total number of items available
    • limit: Number of items requested per page
    • offset: Current offset
    • has_more: Boolean indicating if more results exist

    Similarity Response#

    Similarity endpoints return:

    {
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "results": [
    +    {
    +      "id": "doc456",
    +      "similarity": 0.95
    +    },
    +    {
    +      "id": "doc789",
    +      "similarity": 0.87
    +    }
    +  ]
    +}

    Notes:

    • Results are ordered by similarity (highest first)
    • Only results >= threshold are included
    • Maximum of count/limit results returned
    • Filtered by metadata_path/metadata_value if specified

    \ No newline at end of file diff --git a/docs/public/categories/index.html b/docs/public/categories/index.html index 88cde22..5ab8dbd 100644 --- a/docs/public/categories/index.html +++ b/docs/public/categories/index.html @@ -1,3 +1,3 @@ Categories | dhamps-vdb Documentation - +
    \ No newline at end of file diff --git a/docs/public/concepts/architecture/index.html b/docs/public/concepts/architecture/index.html new file mode 100644 index 0000000..68b8f06 --- /dev/null +++ b/docs/public/concepts/architecture/index.html @@ -0,0 +1,92 @@ +Architecture | dhamps-vdb Documentation + +

    Architecture#

    dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.

    System Overview#

    ┌─────────────┐
    +│   Client    │
    +│ Application │
    +└──────┬──────┘
    +       │ HTTP/REST
    +       │
    +┌──────▼──────────────────────────┐
    +│      dhamps-vdb API Server      │
    +│  ┌──────────────────────────┐   │
    +│  │   Authentication Layer   │   │
    +│  └────────┬─────────────────┘   │
    +│  ┌────────▼─────────────────┐   │
    +│  │   Request Handlers       │   │
    +│  │  (Users, Projects, etc)  │   │
    +│  └────────┬─────────────────┘   │
    +│  ┌────────▼─────────────────┐   │
    +│  │   Validation Layer       │   │
    +│  │  (Dimensions, Metadata)  │   │
    +│  └────────┬─────────────────┘   │
    +│  ┌────────▼─────────────────┐   │
    +│  │     SQLC Queries         │   │
    +│  │  (Type-safe SQL)         │   │
    +│  └────────┬─────────────────┘   │
    +└───────────┼──────────────────────┘
    +            │
    +    ┌───────▼──────────────┐
    +    │   PostgreSQL + 16    │
    +    │  with pgvector 0.7   │
    +    │                      │
    +    │  ┌────────────────┐  │
    +    │  │ Vector Index   │  │
    +    │  │ (HNSW/IVFFlat) │  │
    +    │  └────────────────┘  │
    +    └──────────────────────┘

    Core Components#

    API Layer#

    Built with Huma framework on top of Go’s http.ServeMux:

    • OpenAPI documentation generation
    • Automatic request/response validation
    • JSON schema support
    • REST endpoint routing

    Authentication#

    Token-based authentication using API keys:

    • Admin key: For administrative operations (user creation, system management)
    • User keys: SHA-256 hashed, unique per user
    • Bearer token: Transmitted in Authorization header

    Data Storage#

    PostgreSQL with pgvector extension:

    • Vector storage: Native pgvector support for embeddings
    • Vector search: Cosine similarity using <=> operator
    • ACID compliance: Transactional consistency
    • Relational integrity: Foreign keys and constraints

    Code Generation#

    Uses sqlc for type-safe database queries:

    • SQL queries → Go functions
    • Compile-time type checking
    • No ORM overhead
    • Direct PostgreSQL integration

    Data Model#

    Core Entities#

    users
    +  ├── projects (1:many)
    +  │   ├── embeddings (1:many)
    +  │   └── instance (1:1)
    +  │
    +  └── instances (1:many)
    +      └── definition (many:1, optional)
    +
    +_system (special user)
    +  └── definitions (1:many)

    Key Relationships#

    Users → Projects

    • One user owns many projects
    • Projects can be shared with other users (reader/editor roles)
    • Projects can be public (unauthenticated read access)

    Projects → Instances

    • Each project references exactly one LLM service instance
    • Instance defines embedding dimensions and configuration

    Projects → Embeddings

    • One project contains many embeddings
    • Each embedding has a unique text_id within the project
    • Embeddings store vector, metadata, and optional text

    Users → Instances

    • Users own their instances
    • Instances can be shared with other users
    • Instances store encrypted API keys

    Instances → Definitions

    • Instances can optionally reference a definition (template)
    • System definitions (_system owner) provide defaults
    • User definitions allow custom templates

    Request Flow#

    1. Create Embedding#

    Client Request
    +     ↓
    +Authentication Middleware
    +     ↓
    +Authorization Check (owner/editor?)
    +     ↓
    +Dimension Validation (vector_dim matches instance?)
    +     ↓
    +Metadata Validation (matches project schema?)
    +     ↓
    +Database Insert (with transaction)
    +     ↓
    +Response
    Client Request (text_id or vector)
    +     ↓
    +Authentication Middleware (or public check)
    +     ↓
    +Authorization Check (owner/reader/public?)
    +     ↓
    +Dimension Validation (if raw vector)
    +     ↓
    +Vector Similarity Query
    +     ├── Cosine distance calculation
    +     ├── Threshold filtering
    +     ├── Metadata filtering (exclude matches)
    +     └── Limit/offset pagination
    +     ↓
    +Results (sorted by similarity)
    +     ↓
    +Response

    Storage Architecture#

    Vector Index#

    pgvector supports multiple index types:

    • IVFFlat: Faster build, approximate search
    • HNSW: Slower build, better recall

    Current implementation uses HNSW for better accuracy.

    Vector Storage Format#

    CREATE TABLE embeddings (
    +  embedding_id SERIAL PRIMARY KEY,
    +  text_id TEXT NOT NULL,
    +  project_id INT REFERENCES projects,
    +  vector vector(3072),  -- Dimension varies
    +  vector_dim INT NOT NULL,
    +  metadata JSONB,
    +  text TEXT,
    +  ...
    +)

    Index Strategy#

    CREATE INDEX embedding_vector_idx 
    +ON embeddings 
    +USING hnsw (vector vector_cosine_ops);

    Optimized for cosine similarity searches.

    Security Architecture#

    API Key Encryption#

    • Algorithm: AES-256-GCM
    • Key Source: ENCRYPTION_KEY environment variable
    • Key Derivation: SHA-256 hash to ensure 32-byte key
    • Storage: Binary (BYTEA) in database

    Access Control#

    Three-tier access model:

    1. Owner: Full control (read, write, delete, share, transfer)
    2. Editor: Read and write embeddings
    3. Reader: Read-only access to embeddings and search

    Special access:

    • Admin: System-wide operations (user management, sanity checks)
    • Public: Unauthenticated read access (if public_read=true)

    Data Isolation#

    • Users can only access their own resources or shared resources
    • Cross-user queries are prevented at the database level
    • Project ownership enforced via foreign keys

    Migration System#

    Uses tern for database migrations:

    migrations/
    +  ├── 001_create_initial_scheme.sql
    +  ├── 002_create_emb_index.sql
    +  ├── 003_add_public_read_flag.sql
    +  └── 004_refactor_llm_services_architecture.sql

    Migrations run automatically on startup with rollback support.

    Performance Characteristics#

    Vector Search Performance#

    • Small datasets (<10K embeddings): <10ms per query
    • Medium datasets (10K-100K): 10-50ms per query
    • Large datasets (>100K): 50-200ms per query

    Performance depends on:

    • Vector dimensions
    • Index type and parameters
    • Hardware (CPU, RAM, disk)
    • Number of results requested

    Scaling Considerations#

    Vertical Scaling:

    • More RAM = faster searches (more vectors in memory)
    • Faster CPUs = faster vector comparisons
    • SSD storage = faster index scans

    Horizontal Scaling:

    • Read replicas for search queries
    • Separate write/read workloads
    • Connection pooling for concurrent requests

    Technology Stack#

    Core Technologies#

    • Language: Go 1.21+
    • Web Framework: Huma 2.x
    • Database: PostgreSQL 16+
    • Vector Extension: pgvector 0.7.4
    • Query Generator: sqlc 1.x
    • Migration Tool: tern 2.x

    Development Tools#

    • Testing: Go standard library + testcontainers
    • Documentation: OpenAPI 3.0 (auto-generated)
    • Building: Docker multi-stage builds
    • Deployment: Docker Compose

    Design Principles#

    1. Type Safety#

    • sqlc generates type-safe Go code from SQL
    • Strong typing prevents SQL injection
    • Compile-time validation of queries

    2. Simplicity#

    • REST API (not GraphQL)
    • Straightforward URL patterns
    • Standard HTTP methods

    3. Security#

    • API key encryption at rest
    • No API keys in responses
    • Role-based access control

    4. Validation#

    • Automatic dimension validation
    • Optional metadata schema validation
    • Request/response validation via OpenAPI

    5. Extensibility#

    • User-defined metadata schemas
    • Custom LLM service configurations
    • Flexible sharing model

    Limitations#

    Current Constraints#

    • No multi-tenancy: Each installation is single-tenant
    • No replication: Manual setup required for HA
    • No caching: All queries hit database
    • Synchronous API: No async/batch upload endpoints

    Future Enhancements#

    See Roadmap for planned improvements.

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/embeddings/index.html b/docs/public/concepts/embeddings/index.html new file mode 100644 index 0000000..b3ae7f2 --- /dev/null +++ b/docs/public/concepts/embeddings/index.html @@ -0,0 +1,153 @@ +Embeddings | dhamps-vdb Documentation + +

    Embeddings#

    Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.

    What are Embeddings?#

    Embeddings are numerical representations (vectors) of text that capture semantic meaning:

    • Vector: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)
    • Dimensions: Fixed length determined by LLM model
    • Similarity: Vectors of similar text are close in vector space
    • Purpose: Enable semantic search and retrieval

    Embedding Structure#

    Required Fields#

    • text_id: Unique identifier for the document (max 300 characters)
    • instance_handle: LLM service instance that generated the embedding
    • vector: Array of float32 values (embedding vector)
    • vector_dim: Declared dimension count (must match vector length)

    Optional Fields#

    • text: Original text content (for reference)
    • metadata: Structured JSON data about the document

    Example#

    {
    +  "text_id": "doc-123",
    +  "instance_handle": "my-openai",
    +  "text": "Introduction to machine learning concepts",
    +  "vector": [0.023, -0.015, 0.087, ..., 0.042],
    +  "vector_dim": 3072,
    +  "metadata": {
    +    "title": "ML Introduction",
    +    "author": "Alice",
    +    "year": 2024,
    +    "category": "tutorial"
    +  }
    +}

    Creating Embeddings#

    Single Embedding#

    POST /v1/embeddings/alice/research-docs
    +
    +{
    +  "embeddings": [
    +    {
    +      "text_id": "doc1",
    +      "instance_handle": "my-openai",
    +      "vector": [0.1, 0.2, ..., 0.3],
    +      "vector_dim": 3072,
    +      "metadata": {"author": "Alice"}
    +    }
    +  ]
    +}

    Batch Upload#

    POST /v1/embeddings/alice/research-docs
    +
    +{
    +  "embeddings": [
    +    {
    +      "text_id": "doc1",
    +      "instance_handle": "my-openai",
    +      "vector": [...],
    +      "vector_dim": 3072
    +    },
    +    {
    +      "text_id": "doc2",
    +      "instance_handle": "my-openai",
    +      "vector": [...],
    +      "vector_dim": 3072
    +    },
    +    ...
    +  ]
    +}

    Batch upload tips:

    • Upload 100-1000 embeddings per request
    • Use consistent instance_handle
    • Ensure all vectors have same dimensions
    • Include metadata for searchability

    Text Identifiers#

    Format#

    Text IDs can be any string up to 300 characters:

    Common patterns:

    • URLs: https://id.example.com/doc/123
    • URNs: urn:example:doc:123
    • Paths: /corpus/section1/doc123
    • IDs: doc-abc-123-xyz

    URL Encoding#

    URL-encode text IDs when using them in API paths:

    # Original ID
    +text_id="https://id.example.com/texts/W0017:1.3.1"
    +
    +# URL-encoded for API
    +encoded="https%3A%2F%2Fid.example.com%2Ftexts%2FW0017%3A1.3.1"
    +
    +# Use in API call
    +GET /v1/embeddings/alice/project/$encoded

    Uniqueness#

    Text IDs must be unique within a project:

    • Same ID in different projects: ✅ Allowed
    • Same ID twice in one project: ❌ Conflict error

    Validation#

    Dimension Validation#

    The system automatically validates vector dimensions:

    Checks performed:

    1. vector_dim matches declared instance dimensions
    2. Actual vector array length matches vector_dim
    3. All embeddings in project have consistent dimensions

    Example error:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'my-openai' expects 1536 dimensions"
    +}

    Metadata Validation#

    If project has a metadata schema, all embeddings are validated:

    Example error:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc1': metadata validation failed:\n  - author is required\n  - year must be integer"
    +}

    See Metadata Validation Guide for details.

    Retrieving Embeddings#

    List All Embeddings#

    GET /v1/embeddings/alice/research-docs?limit=100&offset=0

    Returns paginated list of embeddings with:

    • text_id
    • metadata
    • vector_dim
    • created_at

    Vectors are included by default (can be large).

    Get Single Embedding#

    GET /v1/embeddings/alice/research-docs/doc1

    Returns complete embedding including vector.

    Pagination#

    Use limit and offset for large projects:

    # First page (0-99)
    +GET /v1/embeddings/alice/research-docs?limit=100&offset=0
    +
    +# Second page (100-199)
    +GET /v1/embeddings/alice/research-docs?limit=100&offset=100
    +
    +# Third page (200-299)
    +GET /v1/embeddings/alice/research-docs?limit=100&offset=200

    Updating Embeddings#

    Currently, embeddings cannot be updated directly. To modify:

    1. Delete existing embedding
    2. Upload new version with same text_id
    # Delete old version
    +DELETE /v1/embeddings/alice/research-docs/doc1
    +
    +# Upload new version
    +POST /v1/embeddings/alice/research-docs
    +{
    +  "embeddings": [{
    +    "text_id": "doc1",
    +    "instance_handle": "my-openai",
    +    "vector": [...new vector...],
    +    "vector_dim": 3072,
    +    "metadata": {...updated metadata...}
    +  }]
    +}

    Deleting Embeddings#

    Delete Single Embedding#

    DELETE /v1/embeddings/alice/research-docs/doc1

    Delete All Embeddings#

    DELETE /v1/embeddings/alice/research-docs

    Warning: This deletes all embeddings in the project permanently.

    Metadata#

    Purpose#

    Metadata provides structured information about documents:

    • Filtering: Exclude documents in similarity searches
    • Organization: Categorize and group documents
    • Context: Store additional document information
    • Validation: Ensure consistent structure (with schema)

    Structure#

    Metadata is stored as JSONB in PostgreSQL:

    {
    +  "author": "William Shakespeare",
    +  "title": "Hamlet",
    +  "year": 1603,
    +  "act": 1,
    +  "scene": 1,
    +  "genre": "drama",
    +  "language": "English"
    +}

    Nested Metadata#

    Complex structures are supported:

    {
    +  "author": {
    +    "name": "William Shakespeare",
    +    "birth_year": 1564,
    +    "nationality": "English"
    +  },
    +  "publication": {
    +    "year": 1603,
    +    "publisher": "First Folio",
    +    "edition": 1
    +  },
    +  "tags": ["tragedy", "revenge", "madness"]
    +}

    Filtering by Metadata#

    Use metadata to exclude documents from similarity searches:

    # Exclude documents from same author
    +GET /v1/similars/alice/project/doc1?metadata_path=author&metadata_value=Shakespeare

    See Metadata Filtering Guide for details.

    Storage Considerations#

    Vector Storage#

    Vectors are stored using pgvector extension:

    • Type: vector(N) where N is dimension count
    • Size: 4 bytes per dimension + overhead
    • Example: 3072-dimension vector ≈ 12KB

    Storage Calculation#

    Estimate storage per embedding:

    Vector:   4 bytes × dimensions
    +Text ID:  length in bytes (avg ~50 bytes)
    +Text:     length in bytes (optional)
    +Metadata: JSON size (varies, avg ~500 bytes)
    +Overhead: ~100 bytes (indexes, etc.)
    +
    +Example (3072-dim with metadata):
    +4 × 3072 + 50 + 500 + 100 ≈ 13KB per embedding

    Large Projects#

    For projects with millions of embeddings:

    • Use pagination when listing
    • Consider partial indexes for metadata
    • Monitor database size
    • Plan backup strategy

    Performance#

    Upload Performance#

    • Small batches (1-10): ~100ms per request
    • Medium batches (100-500): ~500ms-2s per request
    • Large batches (1000+): ~2-10s per request

    Retrieval Performance#

    • Single embedding: <10ms
    • Paginated list (100 items): ~50ms
    • Large project scan: Use pagination

    Optimization Tips#

    • Batch uploads when possible
    • Use appropriate page sizes
    • Include only needed fields
    • Monitor query performance

    Common Patterns#

    Document Chunking#

    Split long documents into chunks:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "doc1:chunk1",
    +      "text": "First part of document...",
    +      "vector": [...],
    +      "metadata": {"doc_id": "doc1", "chunk": 1}
    +    },
    +    {
    +      "text_id": "doc1:chunk2",
    +      "text": "Second part of document...",
    +      "vector": [...],
    +      "metadata": {"doc_id": "doc1", "chunk": 2}
    +    }
    +  ]
    +}

    Versioned Documents#

    Track document versions:

    {
    +  "text_id": "doc1:v2",
    +  "vector": [...],
    +  "metadata": {
    +    "doc_id": "doc1",
    +    "version": 2,
    +    "updated_at": "2024-01-15T10:30:00Z"
    +  }
    +}

    Multi-Language Documents#

    Store embeddings for different languages:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "doc1:en",
    +      "text": "English version...",
    +      "vector": [...],
    +      "metadata": {"doc_id": "doc1", "language": "en"}
    +    },
    +    {
    +      "text_id": "doc1:de",
    +      "text": "Deutsche Version...",
    +      "vector": [...],
    +      "metadata": {"doc_id": "doc1", "language": "de"}
    +    }
    +  ]
    +}

    Troubleshooting#

    Dimension Mismatch#

    Error: “vector dimension mismatch”

    Cause: Vector dimensions don’t match instance configuration

    Solution:

    • Check instance dimensions: GET /v1/llm-services/owner/instance
    • Regenerate embeddings with correct model
    • Ensure vector_dim matches actual vector length

    Metadata Validation Failed#

    Error: “metadata validation failed”

    Cause: Metadata doesn’t match project schema

    Solution:

    • Check project schema: GET /v1/projects/owner/project
    • Update metadata to match schema
    • Or update schema to accept metadata

    Text ID Conflict#

    Error: “embedding with text_id already exists”

    Cause: Attempting to upload duplicate text_id

    Solution:

    • Use different text_id
    • Delete existing embedding first
    • Check for unintended duplicates

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/index.html b/docs/public/concepts/index.html new file mode 100644 index 0000000..b158ab5 --- /dev/null +++ b/docs/public/concepts/index.html @@ -0,0 +1,10 @@ +Concepts | dhamps-vdb Documentation + +

    Core Concepts#

    Understanding the key concepts behind dhamps-vdb helps you make the most of its features. This section explains the fundamental building blocks and how they work together.

    Overview#

    dhamps-vdb is a vector database designed for Retrieval Augmented Generation (RAG) workflows. It stores embeddings with metadata and provides fast similarity search capabilities.

    Key Components#

    • Users - Individual accounts with authentication
    • Projects - Containers for embeddings with access control
    • Embeddings - Vector representations of text with metadata
    • LLM Services - Configurations for embedding models
    • Similarity Search - Find similar documents using vector distance

    Architecture#

    dhamps-vdb uses PostgreSQL with the pgvector extension for vector operations. It provides a RESTful API with token-based authentication and supports multi-user environments with project sharing.

    \ No newline at end of file diff --git a/docs/public/concepts/index.xml b/docs/public/concepts/index.xml new file mode 100644 index 0000000..5bd9c65 --- /dev/null +++ b/docs/public/concepts/index.xml @@ -0,0 +1,219 @@ +Concepts on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/concepts/Recent content in Concepts on dhamps-vdb DocumentationHugoen-usArchitecturehttps://mpilhlt.github.io/dhamps-vdb/concepts/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/<h1 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h1> +<p>dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.</p> +<h2 id="system-overview">System Overview<a class="anchor" href="#system-overview">#</a></h2> +<pre tabindex="0"><code>┌─────────────┐ +│ Client │ +│ Application │ +└──────┬──────┘ + │ HTTP/REST + │ +┌──────▼──────────────────────────┐ +│ dhamps-vdb API Server │ +│ ┌──────────────────────────┐ │ +│ │ Authentication Layer │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Request Handlers │ │ +│ │ (Users, Projects, etc) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Validation Layer │ │ +│ │ (Dimensions, Metadata) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ SQLC Queries │ │ +│ │ (Type-safe SQL) │ │ +│ └────────┬─────────────────┘ │ +└───────────┼──────────────────────┘ + │ + ┌───────▼──────────────┐ + │ PostgreSQL + 16 │ + │ with pgvector 0.7 │ + │ │ + │ ┌────────────────┐ │ + │ │ Vector Index │ │ + │ │ (HNSW/IVFFlat) │ │ + │ └────────────────┘ │ + └──────────────────────┘</code></pre><h2 id="core-components">Core Components<a class="anchor" href="#core-components">#</a></h2> +<h3 id="api-layer">API Layer<a class="anchor" href="#api-layer">#</a></h3> +<p>Built with <a href="https://huma.rocks/">Huma</a> framework on top of Go&rsquo;s <code>http.ServeMux</code>:</p>Users and Authenticationhttps://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/<h1 id="users-and-authentication">Users and Authentication<a class="anchor" href="#users-and-authentication">#</a></h1> +<p>dhamps-vdb uses token-based authentication with API keys for all operations.</p> +<h2 id="user-model">User Model<a class="anchor" href="#user-model">#</a></h2> +<h3 id="user-properties">User Properties<a class="anchor" href="#user-properties">#</a></h3> +<ul> +<li><strong>user_handle</strong>: Unique identifier (3-20 characters, alphanumeric + underscore)</li> +<li><strong>name</strong>: Full name (optional)</li> +<li><strong>email</strong>: Email address (unique, required)</li> +<li><strong>vdb_key</strong>: API key (SHA-256 hash, 64 characters)</li> +<li><strong>created_at</strong>: Timestamp of creation</li> +<li><strong>updated_at</strong>: Timestamp of last update</li> +</ul> +<h3 id="special-users">Special Users<a class="anchor" href="#special-users">#</a></h3> +<p><strong><code>_system</code> User</strong></p> +<ul> +<li>Created automatically during database migration</li> +<li>Owns system-wide LLM service definitions</li> +<li>Cannot be used for authentication</li> +<li>Provides default configurations for all users</li> +</ul> +<h2 id="authentication-flow">Authentication Flow<a class="anchor" href="#authentication-flow">#</a></h2> +<h3 id="api-key-authentication">API Key Authentication<a class="anchor" href="#api-key-authentication">#</a></h3> +<p>All requests (except public endpoints) require authentication:</p>Projectshttps://mpilhlt.github.io/dhamps-vdb/concepts/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/projects/<h1 id="projects">Projects<a class="anchor" href="#projects">#</a></h1> +<p>Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.</p> +<h2 id="what-is-a-project">What is a Project?<a class="anchor" href="#what-is-a-project">#</a></h2> +<p>A project is a collection of document embeddings that share:</p> +<ul> +<li>A single LLM service instance (embedding configuration)</li> +<li>Optional metadata schema for validation</li> +<li>Access control (ownership and sharing)</li> +<li>Consistent vector dimensions</li> +</ul> +<h2 id="project-properties">Project Properties<a class="anchor" href="#project-properties">#</a></h2> +<h3 id="core-fields">Core Fields<a class="anchor" href="#core-fields">#</a></h3> +<ul> +<li><strong>project_handle</strong>: Unique identifier within owner&rsquo;s namespace (3-20 characters)</li> +<li><strong>owner</strong>: User who owns the project</li> +<li><strong>description</strong>: Human-readable project description</li> +<li><strong>instance_id</strong>: Reference to LLM service instance (required, 1:1 relationship)</li> +<li><strong>metadataScheme</strong>: Optional JSON Schema for metadata validation</li> +<li><strong>public_read</strong>: Boolean flag for public read access</li> +<li><strong>created_at</strong>: Creation timestamp</li> +<li><strong>updated_at</strong>: Last modification timestamp</li> +</ul> +<h3 id="unique-constraints">Unique Constraints<a class="anchor" href="#unique-constraints">#</a></h3> +<p>Projects are uniquely identified by <code>(owner, project_handle)</code>:</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/<h1 id="embeddings">Embeddings<a class="anchor" href="#embeddings">#</a></h1> +<p>Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.</p> +<h2 id="what-are-embeddings">What are Embeddings?<a class="anchor" href="#what-are-embeddings">#</a></h2> +<p>Embeddings are numerical representations (vectors) of text that capture semantic meaning:</p> +<ul> +<li><strong>Vector</strong>: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)</li> +<li><strong>Dimensions</strong>: Fixed length determined by LLM model</li> +<li><strong>Similarity</strong>: Vectors of similar text are close in vector space</li> +<li><strong>Purpose</strong>: Enable semantic search and retrieval</li> +</ul> +<h2 id="embedding-structure">Embedding Structure<a class="anchor" href="#embedding-structure">#</a></h2> +<h3 id="required-fields">Required Fields<a class="anchor" href="#required-fields">#</a></h3> +<ul> +<li><strong>text_id</strong>: Unique identifier for the document (max 300 characters)</li> +<li><strong>instance_handle</strong>: LLM service instance that generated the embedding</li> +<li><strong>vector</strong>: Array of float32 values (embedding vector)</li> +<li><strong>vector_dim</strong>: Declared dimension count (must match vector length)</li> +</ul> +<h3 id="optional-fields">Optional Fields<a class="anchor" href="#optional-fields">#</a></h3> +<ul> +<li><strong>text</strong>: Original text content (for reference)</li> +<li><strong>metadata</strong>: Structured JSON data about the document</li> +</ul> +<h3 id="example">Example<a class="anchor" href="#example">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc-123&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text&#34;</span>: <span style="color:#e6db74">&#34;Introduction to machine learning concepts&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector&#34;</span>: [<span style="color:#ae81ff">0.023</span>, <span style="color:#ae81ff">-0.015</span>, <span style="color:#ae81ff">0.087</span>, <span style="color:#960050;background-color:#1e0010">...</span>, <span style="color:#ae81ff">0.042</span>], +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;metadata&#34;</span>: { +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;ML Introduction&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">2024</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;category&#34;</span>: <span style="color:#e6db74">&#34;tutorial&#34;</span> +</span></span><span style="display:flex;"><span> } +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h2 id="creating-embeddings">Creating Embeddings<a class="anchor" href="#creating-embeddings">#</a></h2> +<h3 id="single-embedding">Single Embedding<a class="anchor" href="#single-embedding">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>0.1, 0.2, ..., 0.3<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: 3072, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;metadata&#34;</span>: <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span><span style="color:#f92672">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><h3 id="batch-upload">Batch Upload<a class="anchor" href="#batch-upload">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc2&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, +</span></span><span style="display:flex;"><span> ... +</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><p><strong>Batch upload tips:</strong></p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/<h1 id="llm-services">LLM Services<a class="anchor" href="#llm-services">#</a></h1> +<p>LLM Services configure embedding generation, defining models, dimensions, and API access.</p> +<h2 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h2> +<p>dhamps-vdb separates LLM services into two concepts:</p> +<h3 id="llm-service-definitions">LLM Service Definitions<a class="anchor" href="#llm-service-definitions">#</a></h3> +<p>Reusable configuration templates owned by <code>_system</code> or users:</p> +<ul> +<li><strong>Purpose</strong>: Provide standard configurations</li> +<li><strong>Ownership</strong>: <code>_system</code> (global) or individual users</li> +<li><strong>Contents</strong>: Endpoint, model, dimensions, API standard</li> +<li><strong>API Keys</strong>: Not stored (templates only)</li> +<li><strong>Usage</strong>: Templates for creating instances</li> +</ul> +<h3 id="llm-service-instances">LLM Service Instances<a class="anchor" href="#llm-service-instances">#</a></h3> +<p>User-specific configurations with encrypted API keys:</p> +<ul> +<li><strong>Purpose</strong>: Actual service configurations users employ</li> +<li><strong>Ownership</strong>: Individual users</li> +<li><strong>Contents</strong>: Endpoint, model, dimensions, API key (encrypted)</li> +<li><strong>Sharing</strong>: Can be shared with other users</li> +<li><strong>Projects</strong>: Each project references exactly one instance</li> +</ul> +<h2 id="system-definitions">System Definitions<a class="anchor" href="#system-definitions">#</a></h2> +<h3 id="available-definitions">Available Definitions<a class="anchor" href="#available-definitions">#</a></h3> +<p>The <code>_system</code> user provides default definitions:</p>Similarity Searchhttps://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/<h1 id="similarity-search">Similarity Search<a class="anchor" href="#similarity-search">#</a></h1> +<p>Find documents with similar semantic meaning using vector similarity.</p> +<h2 id="how-it-works">How it Works<a class="anchor" href="#how-it-works">#</a></h2> +<p>Similarity search compares embedding vectors using cosine distance:</p> +<ol> +<li><strong>Query vector</strong>: Either from stored embedding or raw vector</li> +<li><strong>Comparison</strong>: Calculate cosine similarity with all project embeddings</li> +<li><strong>Filtering</strong>: Apply threshold and metadata filters</li> +<li><strong>Ranking</strong>: Sort by similarity score (highest first)</li> +<li><strong>Return</strong>: Top N most similar documents</li> +</ol> +<h2 id="search-methods">Search Methods<a class="anchor" href="#search-methods">#</a></h2> +<h3 id="stored-document-search-get">Stored Document Search (GET)<a class="anchor" href="#stored-document-search-get">#</a></h3> +<p>Find documents similar to an already-stored embedding:</p>Metadatahttps://mpilhlt.github.io/dhamps-vdb/concepts/metadata/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/<h1 id="metadata">Metadata<a class="anchor" href="#metadata">#</a></h1> +<p>Structured JSON data attached to embeddings for organization, validation, and filtering.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Metadata provides context and structure for your embeddings:</p> +<ul> +<li><strong>Organization</strong>: Categorize and group documents</li> +<li><strong>Filtering</strong>: Exclude documents in similarity searches</li> +<li><strong>Validation</strong>: Ensure consistent structure (optional)</li> +<li><strong>Context</strong>: Store additional document information</li> +</ul> +<h2 id="metadata-structure">Metadata Structure<a class="anchor" href="#metadata-structure">#</a></h2> +<h3 id="format">Format<a class="anchor" href="#format">#</a></h3> +<p>Metadata is JSON stored as JSONB in PostgreSQL:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;William Shakespeare&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Hamlet&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">1603</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;genre&#34;</span>: <span style="color:#e6db74">&#34;drama&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h3 id="types">Types<a class="anchor" href="#types">#</a></h3> +<p>Supported JSON types:</p> +<ul> +<li><strong>String</strong>: <code>&quot;author&quot;: &quot;Shakespeare&quot;</code></li> +<li><strong>Number</strong>: <code>&quot;year&quot;: 1603</code></li> +<li><strong>Boolean</strong>: <code>&quot;published&quot;: true</code></li> +<li><strong>Array</strong>: <code>&quot;tags&quot;: [&quot;tragedy&quot;, &quot;revenge&quot;]</code></li> +<li><strong>Object</strong>: <code>&quot;author&quot;: {&quot;name&quot;: &quot;...&quot;, &quot;id&quot;: &quot;...&quot;}</code></li> +<li><strong>Null</strong>: <code>&quot;notes&quot;: null</code></li> +</ul> +<h3 id="nested-structure">Nested Structure<a class="anchor" href="#nested-structure">#</a></h3> +<p>Complex hierarchies are supported:</p> \ No newline at end of file diff --git a/docs/public/concepts/llm-services/index.html b/docs/public/concepts/llm-services/index.html new file mode 100644 index 0000000..3c90446 --- /dev/null +++ b/docs/public/concepts/llm-services/index.html @@ -0,0 +1,118 @@ +LLM Services | dhamps-vdb Documentation + +

    LLM Services#

    LLM Services configure embedding generation, defining models, dimensions, and API access.

    Architecture#

    dhamps-vdb separates LLM services into two concepts:

    LLM Service Definitions#

    Reusable configuration templates owned by _system or users:

    • Purpose: Provide standard configurations
    • Ownership: _system (global) or individual users
    • Contents: Endpoint, model, dimensions, API standard
    • API Keys: Not stored (templates only)
    • Usage: Templates for creating instances

    LLM Service Instances#

    User-specific configurations with encrypted API keys:

    • Purpose: Actual service configurations users employ
    • Ownership: Individual users
    • Contents: Endpoint, model, dimensions, API key (encrypted)
    • Sharing: Can be shared with other users
    • Projects: Each project references exactly one instance

    System Definitions#

    Available Definitions#

    The _system user provides default definitions:

    HandleModelDimensionsAPI Standard
    openai-largetext-embedding-3-large3072openai
    openai-smalltext-embedding-3-small1536openai
    cohere-v4embed-multilingual-v4.01536cohere
    gemini-embedding-001text-embedding-0043072gemini

    Viewing System Definitions#

    GET /v1/llm-services/_system
    +Authorization: Bearer user_vdb_key

    Returns list of available system definitions.

    Creating Instances#

    From System Definition#

    Use a predefined system configuration:

    PUT /v1/llm-services/alice/my-openai
    +
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-large",
    +  "description": "My OpenAI embeddings",
    +  "api_key_encrypted": "sk-proj-your-openai-key"
    +}

    Inherits endpoint, model, dimensions from system definition.

    From User Definition#

    Reference a user-created definition:

    PUT /v1/llm-services/alice/custom-instance
    +
    +{
    +  "definition_owner": "alice",
    +  "definition_handle": "my-custom-config",
    +  "api_key_encrypted": "your-api-key"
    +}

    Standalone Instance#

    Create without a definition:

    PUT /v1/llm-services/alice/standalone
    +
    +{
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072,
    +  "description": "Standalone OpenAI instance",
    +  "api_key_encrypted": "sk-proj-your-key"
    +}

    All fields must be specified.

    Instance Properties#

    Core Fields#

    • instance_handle: Unique identifier (3-20 characters)
    • owner: User who owns the instance
    • endpoint: API endpoint URL
    • api_standard: Authentication mechanism (openai, cohere, gemini)
    • model: Model identifier
    • dimensions: Vector dimensionality
    • description: Human-readable description (optional)
    • definition_id: Reference to definition (optional)

    API Key Storage#

    • Write-only: Provided on create/update
    • Encrypted: AES-256-GCM encryption
    • Never returned: Not included in GET responses
    • Secure: Cannot be retrieved after creation

    API Standards#

    Supported Standards#

    StandardKey MethodDocumentation
    openaiAuthorization: BearerOpenAI Docs
    cohereAuthorization: BearerCohere Docs
    geminix-goog-api-key headerGemini Docs

    Creating API Standards#

    Admins can add new standards:

    POST /v1/api-standards
    +Authorization: Bearer ADMIN_KEY
    +
    +{
    +  "api_standard_handle": "custom",
    +  "description": "Custom LLM API",
    +  "key_method": "auth_bearer",
    +  "key_field": null
    +}

    Instance Management#

    List Instances#

    List all accessible instances (owned + shared):

    GET /v1/llm-services/alice
    +Authorization: Bearer alice_vdb_key

    Returns instances where alice is owner or has been granted access.

    Get Instance Details#

    GET /v1/llm-services/alice/my-openai
    +Authorization: Bearer alice_vdb_key

    Returns instance configuration (API key not included).

    Update Instance#

    PATCH /v1/llm-services/alice/my-openai
    +
    +{
    +  "description": "Updated description",
    +  "api_key_encrypted": "new-api-key"
    +}

    Only owner can update instances.

    Delete Instance#

    DELETE /v1/llm-services/alice/my-openai
    +Authorization: Bearer alice_vdb_key

    Constraints:

    • Cannot delete instance used by projects
    • Delete projects first, then instance

    Instance Sharing#

    Share with User#

    POST /v1/llm-services/alice/my-openai/share
    +
    +{
    +  "share_with_handle": "bob",
    +  "role": "reader"
    +}

    Shared users can:

    • Use instance in their projects
    • View instance configuration
    • Cannot:
      • See API key
      • Modify instance
      • Delete instance

    Unshare from User#

    DELETE /v1/llm-services/alice/my-openai/share/bob

    List Shared Users#

    GET /v1/llm-services/alice/my-openai/shared-with

    Only owner can view shared users.

    Instance References#

    In Projects#

    Projects reference instances by owner and handle:

    {
    +  "project_handle": "my-project",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-openai"
    +}

    In Embeddings#

    Embeddings reference instances by handle:

    {
    +  "text_id": "doc1",
    +  "instance_handle": "my-openai",
    +  "vector": [...]
    +}

    The instance owner is inferred from the project.

    Shared Instance Format#

    When using shared instances:

    Own instance: "instance_handle": "my-openai" +Shared instance: Reference via project configuration

    Encryption#

    API Key Encryption#

    API keys are encrypted using AES-256-GCM:

    Encryption process:

    1. User provides plaintext API key
    2. Server encrypts using ENCRYPTION_KEY from environment
    3. Encrypted bytes stored in database
    4. Key derivation: SHA-256 hash ensures 32-byte key

    Decryption:

    • Only occurs internally for LLM API calls
    • Never exposed via API responses
    • Requires same ENCRYPTION_KEY

    Security Notes#

    • Encryption key: Set via ENCRYPTION_KEY environment variable
    • Key loss: Losing encryption key means losing access to API keys
    • Key rotation: Not currently supported
    • Backup: Back up encryption key securely

    LLM Processing#

    Current Status#

    LLM processing (generating embeddings) is not yet implemented.

    Future Implementation#

    Planned features:

    • Process text to generate embeddings
    • Call external LLM APIs
    • Store generated embeddings
    • Batch processing support

    Current Workflow#

    Users must generate embeddings externally:

    1. Generate embeddings using LLM API (OpenAI, Cohere, etc.)
    2. Upload pre-generated embeddings to dhamps-vdb
    3. Use dhamps-vdb for storage and similarity search

    Common Patterns#

    Per-Environment Instances#

    # Development instance
    +PUT /v1/llm-services/alice/dev-embeddings
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-small",
    +  "api_key_encrypted": "dev-api-key"
    +}
    +
    +# Production instance
    +PUT /v1/llm-services/alice/prod-embeddings
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-large",
    +  "api_key_encrypted": "prod-api-key"
    +}

    Team Shared Instance#

    # Owner creates instance
    +PUT /v1/llm-services/team-lead/team-embeddings
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-large",
    +  "api_key_encrypted": "team-api-key"
    +}
    +
    +# Share with team members
    +POST /v1/llm-services/team-lead/team-embeddings/share
    +{"share_with_handle": "member1", "role": "reader"}
    +
    +POST /v1/llm-services/team-lead/team-embeddings/share
    +{"share_with_handle": "member2", "role": "reader"}
    +
    +# Members use in their projects
    +POST /v1/projects/member1
    +{
    +  "project_handle": "my-project",
    +  "instance_owner": "team-lead",
    +  "instance_handle": "team-embeddings"
    +}

    Multi-Model Setup#

    # Large model for important documents
    +PUT /v1/llm-services/alice/high-quality
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-large",
    +  "api_key_encrypted": "api-key"
    +}
    +
    +# Small model for drafts
    +PUT /v1/llm-services/alice/fast-processing
    +{
    +  "definition_owner": "_system",
    +  "definition_handle": "openai-small",
    +  "api_key_encrypted": "api-key"
    +}

    Troubleshooting#

    Cannot Create Instance#

    Possible causes:

    • Instance handle already exists
    • Referenced definition doesn’t exist
    • Missing required fields
    • Invalid API standard

    Solutions:

    • Choose different handle
    • Verify definition: GET /v1/llm-services/_system
    • Include all required fields
    • Use valid API standard: GET /v1/api-standards

    Cannot Use Instance in Project#

    Possible causes:

    • Instance doesn’t exist
    • Instance not owned or shared with user
    • Incorrect owner/handle reference

    Solutions:

    • Verify instance exists
    • Check instance is accessible
    • Confirm spelling of owner and handle

    Dimension Mismatch#

    Error: “dimension validation failed”

    Cause: Embedding dimensions don’t match instance

    Solutions:

    • Check instance dimensions
    • Regenerate embeddings with correct model
    • Create instance with correct dimensions

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/metadata/index.html b/docs/public/concepts/metadata/index.html new file mode 100644 index 0000000..cb36ebb --- /dev/null +++ b/docs/public/concepts/metadata/index.html @@ -0,0 +1,180 @@ +Metadata | dhamps-vdb Documentation + +

    Metadata#

    Structured JSON data attached to embeddings for organization, validation, and filtering.

    Overview#

    Metadata provides context and structure for your embeddings:

    • Organization: Categorize and group documents
    • Filtering: Exclude documents in similarity searches
    • Validation: Ensure consistent structure (optional)
    • Context: Store additional document information

    Metadata Structure#

    Format#

    Metadata is JSON stored as JSONB in PostgreSQL:

    {
    +  "author": "William Shakespeare",
    +  "title": "Hamlet",
    +  "year": 1603,
    +  "genre": "drama"
    +}

    Types#

    Supported JSON types:

    • String: "author": "Shakespeare"
    • Number: "year": 1603
    • Boolean: "published": true
    • Array: "tags": ["tragedy", "revenge"]
    • Object: "author": {"name": "...", "id": "..."}
    • Null: "notes": null

    Nested Structure#

    Complex hierarchies are supported:

    {
    +  "document": {
    +    "id": "W0017",
    +    "type": "manuscript"
    +  },
    +  "author": {
    +    "name": "John Milton",
    +    "birth_year": 1608,
    +    "nationality": "English"
    +  },
    +  "publication": {
    +    "year": 1667,
    +    "publisher": "First Edition",
    +    "location": "London"
    +  },
    +  "tags": ["poetry", "epic", "religious"]
    +}

    Metadata Schemas#

    Purpose#

    JSON Schema validation ensures consistent metadata across all project embeddings.

    Defining a Schema#

    Include metadataScheme when creating/updating project:

    POST /v1/projects/alice
    +
    +{
    +  "project_handle": "research",
    +  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    +}

    Schema Format#

    Use JSON Schema (draft-07+):

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {
    +      "type": "string",
    +      "minLength": 1
    +    },
    +    "year": {
    +      "type": "integer",
    +      "minimum": 1000,
    +      "maximum": 2100
    +    },
    +    "genre": {
    +      "type": "string",
    +      "enum": ["poetry", "prose", "drama"]
    +    }
    +  },
    +  "required": ["author", "year"]
    +}

    Validation Behavior#

    With schema defined:

    • All embeddings validated on upload
    • Invalid metadata rejected with detailed error
    • Schema enforced consistently

    Without schema:

    • Any JSON metadata accepted
    • No validation performed
    • Maximum flexibility

    Common Patterns#

    See Metadata Validation Guide for examples.

    Using Metadata#

    On Upload#

    Include metadata with each embedding:

    POST /v1/embeddings/alice/research
    +
    +{
    +  "embeddings": [
    +    {
    +      "text_id": "doc1",
    +      "instance_handle": "my-embeddings",
    +      "vector": [...],
    +      "metadata": {
    +        "author": "Shakespeare",
    +        "title": "Hamlet",
    +        "year": 1603
    +      }
    +    }
    +  ]
    +}

    In Responses#

    Metadata returned when retrieving embeddings:

    GET /v1/embeddings/alice/research/doc1
    {
    +  "text_id": "doc1",
    +  "metadata": {
    +    "author": "Shakespeare",
    +    "title": "Hamlet",
    +    "year": 1603
    +  },
    +  "vector": [...],
    +  ...
    +}

    Metadata Filtering#

    Exclusion Filter#

    Exclude documents where metadata matches value:

    GET /v1/similars/alice/research/doc1?metadata_path=author&metadata_value=Shakespeare

    Result: Returns similar documents excluding those with metadata.author == "Shakespeare".

    Path Syntax#

    Use JSON path notation:

    Simple field:

    metadata_path=author

    Nested field:

    metadata_path=author.name

    Array element (not currently supported):

    metadata_path=tags[0]

    URL Encoding#

    Encode special characters:

    # Space
    +metadata_value=John%20Doe
    +
    +# Quotes (if needed)
    +metadata_value=%22quoted%20value%22

    Use Cases#

    Exclude same work:

    ?metadata_path=title&metadata_value=Hamlet

    Exclude same author:

    ?metadata_path=author&metadata_value=Shakespeare

    Exclude same source:

    ?metadata_path=source_id&metadata_value=corpus-a

    Exclude same category:

    ?metadata_path=category&metadata_value=draft

    See Metadata Filtering Guide for detailed examples.

    Validation Examples#

    Simple Schema#

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {"type": "string"},
    +    "year": {"type": "integer"}
    +  },
    +  "required": ["author"]
    +}

    Valid metadata:

    {"author": "Shakespeare", "year": 1603}
    +{"author": "Milton"}

    Invalid metadata:

    {"year": 1603}  // Missing required 'author'
    +{"author": 123}  // Wrong type (should be string)

    Schema with Constraints#

    {
    +  "type": "object",
    +  "properties": {
    +    "title": {
    +      "type": "string",
    +      "minLength": 1,
    +      "maxLength": 200
    +    },
    +    "rating": {
    +      "type": "number",
    +      "minimum": 0,
    +      "maximum": 5
    +    },
    +    "tags": {
    +      "type": "array",
    +      "items": {"type": "string"},
    +      "minItems": 1,
    +      "maxItems": 10
    +    }
    +  }
    +}

    Schema with Enums#

    {
    +  "type": "object",
    +  "properties": {
    +    "language": {
    +      "type": "string",
    +      "enum": ["en", "de", "fr", "es", "la"]
    +    },
    +    "status": {
    +      "type": "string",
    +      "enum": ["draft", "review", "published"]
    +    }
    +  }
    +}

    Storage and Performance#

    Storage#

    Metadata stored as JSONB in PostgreSQL:

    • Efficient: Binary storage format
    • Indexable: Can create indexes on fields
    • Queryable: Use PostgreSQL JSON operators

    Size Considerations#

    Typical metadata sizes:

    • Simple: 50-200 bytes
    • Moderate: 200-1000 bytes
    • Complex: 1-5KB
    • Very large: >5KB (consider storing elsewhere)

    Performance#

    Metadata filtering:

    • JSONB queries are efficient
    • Add indexes for frequently filtered fields
    • Keep metadata reasonably sized

    Example index (if needed):

    CREATE INDEX idx_embeddings_author 
    +ON embeddings ((metadata->>'author'));

    Common Patterns#

    Document Provenance#

    Track document source and history:

    {
    +  "source": {
    +    "corpus": "Shakespeare Works",
    +    "collection": "Tragedies",
    +    "document_id": "hamlet",
    +    "version": 2
    +  },
    +  "imported_at": "2024-01-15T10:30:00Z",
    +  "imported_by": "researcher1"
    +}

    Hierarchical Documents#

    Structure for nested documents:

    {
    +  "work": "Paradise Lost",
    +  "book": 1,
    +  "line": 1,
    +  "chapter": null,
    +  "section": "Invocation"
    +}

    Multi-Language Content#

    Track language and translation info:

    {
    +  "language": "en",
    +  "original_language": "la",
    +  "translated_by": "John Smith",
    +  "translation_year": 1850
    +}

    Research Metadata#

    Academic paper metadata:

    {
    +  "doi": "10.1234/example.2024.001",
    +  "authors": ["Alice Smith", "Bob Jones"],
    +  "journal": "Digital Humanities Review",
    +  "year": 2024,
    +  "keywords": ["NLP", "embeddings", "RAG"]
    +}

    Updating Metadata#

    Current Limitation#

    Metadata cannot be updated directly. To change:

    1. Delete embedding
    2. Re-upload with updated metadata
    # Delete
    +DELETE /v1/embeddings/alice/project/doc1
    +
    +# Re-upload with new metadata
    +POST /v1/embeddings/alice/project
    +{
    +  "embeddings": [{
    +    "text_id": "doc1",
    +    "metadata": {...updated...},
    +    ...
    +  }]
    +}

    Schema Updates#

    Updating Project Schema#

    Use PATCH to update schema:

    PATCH /v1/projects/alice/research
    +
    +{
    +  "metadataScheme": "{...new schema...}"
    +}

    Effect on Existing Embeddings#

    • Existing embeddings: Not revalidated
    • New embeddings: Validated against new schema
    • Updates: Validated against current schema

    Migration Strategy#

    When updating schema:

    1. Update project schema
    2. Verify new embeddings work
    3. Optionally re-upload existing embeddings

    Validation Errors#

    Common Errors#

    Missing required field:

    {
    +  "status": 400,
    +  "detail": "metadata validation failed: author is required"
    +}

    Wrong type:

    {
    +  "status": 400,
    +  "detail": "metadata validation failed: year must be integer"
    +}

    Enum violation:

    {
    +  "status": 400,
    +  "detail": "metadata validation failed: genre must be one of [poetry, prose, drama]"
    +}

    Debugging#

    To debug validation errors:

    1. Check project schema: GET /v1/projects/owner/project
    2. Validate metadata with online tool: jsonschemavalidator.net
    3. Review error message for specific field
    4. Update metadata or schema as needed

    Best Practices#

    Schema Design#

    • Start simple, add complexity as needed
    • Use required fields for critical data
    • Use enums for controlled vocabularies
    • Document your schema

    Metadata Content#

    • Keep metadata focused and relevant
    • Avoid redundant data
    • Use consistent field names
    • Consider future queries and filters

    Performance#

    • Keep metadata reasonably sized (<5KB)
    • Index frequently queried fields
    • Avoid deeply nested structures when possible

    Troubleshooting#

    Validation Fails#

    Problem: Metadata doesn’t validate

    Solutions:

    • Check project schema
    • Verify metadata structure
    • Test with JSON Schema validator
    • Review error message details

    Filtering Not Working#

    Problem: Metadata filter doesn’t exclude documents

    Solutions:

    • Verify field path is correct
    • Check value matches exactly (case-sensitive)
    • URL-encode special characters
    • Confirm metadata field exists

    Schema Too Restrictive#

    Problem: Cannot upload valid documents

    Solutions:

    • Make fields optional (remove from required)
    • Broaden type constraints
    • Use oneOf for multiple valid formats
    • Remove unnecessary validations

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/projects/index.html b/docs/public/concepts/projects/index.html new file mode 100644 index 0000000..41cff54 --- /dev/null +++ b/docs/public/concepts/projects/index.html @@ -0,0 +1,145 @@ +Projects | dhamps-vdb Documentation + +

    Projects#

    Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.

    What is a Project?#

    A project is a collection of document embeddings that share:

    • A single LLM service instance (embedding configuration)
    • Optional metadata schema for validation
    • Access control (ownership and sharing)
    • Consistent vector dimensions

    Project Properties#

    Core Fields#

    • project_handle: Unique identifier within owner’s namespace (3-20 characters)
    • owner: User who owns the project
    • description: Human-readable project description
    • instance_id: Reference to LLM service instance (required, 1:1 relationship)
    • metadataScheme: Optional JSON Schema for metadata validation
    • public_read: Boolean flag for public read access
    • created_at: Creation timestamp
    • updated_at: Last modification timestamp

    Unique Constraints#

    Projects are uniquely identified by (owner, project_handle):

    • User “alice” can have project “research”
    • User “bob” can also have project “research”
    • Same user cannot have two projects with same handle

    Creating Projects#

    Basic Project#

    POST /v1/projects/alice
    +
    +{
    +  "project_handle": "literature-study",
    +  "description": "Literary text analysis",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-openai"
    +}

    Project with Metadata Schema#

    POST /v1/projects/alice
    +
    +{
    +  "project_handle": "research-papers",
    +  "description": "Academic papers with structured metadata",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-embeddings",
    +  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"doi\":{\"type\":\"string\"}},\"required\":[\"author\",\"year\"]}"
    +}

    Public Project#

    POST /v1/projects/alice
    +
    +{
    +  "project_handle": "open-dataset",
    +  "description": "Publicly accessible research data",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-embeddings",
    +  "public_read": true
    +}

    Shared Project#

    POST /v1/projects/alice
    +
    +{
    +  "project_handle": "collaborative",
    +  "description": "Team collaboration project",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-embeddings",
    +  "shared_with": [
    +    {
    +      "user_handle": "bob",
    +      "role": "editor"
    +    },
    +    {
    +      "user_handle": "charlie",
    +      "role": "reader"
    +    }
    +  ]
    +}

    Project-Instance Relationship#

    One-to-One Constraint#

    Each project references exactly one LLM service instance:

    Project → Instance (1:1)
    +  ├── Defines vector dimensions
    +  ├── Specifies embedding model
    +  └── Contains API configuration

    Why 1:1?

    • Ensures consistent dimensions across all embeddings
    • Prevents dimension mismatches in similarity searches
    • Simplifies validation and error handling

    Specifying Instance#

    Use owner and handle to reference an instance:

    {
    +  "instance_owner": "alice",
    +  "instance_handle": "my-openai"
    +}

    The instance can be:

    • Owned by project owner: "instance_owner": "alice"
    • Shared with project owner: "instance_owner": "bob" (if bob shared with alice)

    Metadata Schemas#

    Purpose#

    Metadata schemas ensure consistent, structured metadata across all embeddings in a project.

    Schema Format#

    Use JSON Schema (draft-07 or later):

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {"type": "string"},
    +    "title": {"type": "string"},
    +    "year": {
    +      "type": "integer",
    +      "minimum": 1000,
    +      "maximum": 2100
    +    },
    +    "genre": {
    +      "type": "string",
    +      "enum": ["fiction", "non-fiction", "poetry"]
    +    }
    +  },
    +  "required": ["author", "title", "year"]
    +}

    Validation Behavior#

    • With schema: All embeddings validated on upload
    • Without schema: Any JSON metadata accepted
    • Validation failure: Upload rejected with detailed error
    • Schema updates: Only apply to new/updated embeddings

    Example Schemas#

    See Metadata Validation Guide for detailed examples.

    Access Control#

    Ownership#

    • Owner: User who created the project
    • Full control: Read, write, delete, share, transfer
    • Cannot be removed: Owner always has access

    Sharing#

    Projects can be shared with specific users:

    Reader Role

    • View embeddings
    • Search for similar documents
    • View project metadata
    • Cannot modify anything

    Editor Role

    • All reader permissions
    • Add embeddings
    • Modify embeddings
    • Delete embeddings
    • Cannot delete project or change settings

    Managing Sharing:

    # Share with user
    +POST /v1/projects/alice/my-project/share
    +{
    +  "share_with_handle": "bob",
    +  "role": "reader"
    +}
    +
    +# Unshare from user
    +DELETE /v1/projects/alice/my-project/share/bob
    +
    +# List shared users
    +GET /v1/projects/alice/my-project/shared-with

    Public Access#

    Projects can allow unauthenticated read access:

    PATCH /v1/projects/alice/my-project
    +{
    +  "public_read": true
    +}

    With public_read: true:

    • Anyone can view embeddings (no authentication)
    • Anyone can search for similar documents
    • Write operations still require authentication

    See Public Projects Guide for details.

    Project Operations#

    List Projects#

    List all projects owned by a user:

    GET /v1/projects/alice
    +Authorization: Bearer alice_vdb_key

    Returns array of project objects.

    Get Project Details#

    GET /v1/projects/alice/research
    +Authorization: Bearer alice_vdb_key

    Returns full project object including:

    • Configuration
    • Instance reference
    • Metadata schema
    • Sharing information (owner only)

    Update Project#

    Use PATCH for partial updates:

    PATCH /v1/projects/alice/research
    +{
    +  "description": "Updated description"
    +}

    Use PUT for full replacement:

    PUT /v1/projects/alice/research
    +{
    +  "project_handle": "research",
    +  "description": "Complete project configuration",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-embeddings",
    +  "metadataScheme": "{...}"
    +}

    Delete Project#

    DELETE /v1/projects/alice/research
    +Authorization: Bearer alice_vdb_key

    Cascading deletion:

    • All embeddings in project deleted
    • All sharing grants removed
    • Project metadata removed

    Ownership Transfer#

    Transfer project to another user:

    POST /v1/projects/alice/research/transfer-ownership
    +{
    +  "new_owner_handle": "bob"
    +}

    Effects:

    • Project owner changes to bob
    • Project URL changes: /v1/projects/bob/research
    • Alice loses all access (unless re-shared)
    • All embeddings transferred
    • Bob cannot already have project with same handle

    See Ownership Transfer Guide for details.

    Project Limits#

    Current Implementation#

    No enforced limits on:

    • Number of embeddings per project
    • Project storage size
    • Number of shared users

    For large projects:

    • Use pagination when listing embeddings
    • Batch upload embeddings
    • Monitor database size
    • Consider archiving old projects

    Common Patterns#

    Research Project Workflow#

    # 1. Create project
    +POST /v1/projects/alice
    +{
    +  "project_handle": "study-2024",
    +  "description": "2024 Research Study",
    +  "instance_owner": "alice",
    +  "instance_handle": "my-embeddings"
    +}
    +
    +# 2. Upload data
    +POST /v1/embeddings/alice/study-2024
    +{ ... embeddings ... }
    +
    +# 3. Share with team
    +POST /v1/projects/alice/study-2024/share
    +{"share_with_handle": "bob", "role": "reader"}
    +
    +# 4. Make public when published
    +PATCH /v1/projects/alice/study-2024
    +{"public_read": true}

    Multi-Project Organization#

    # Development project
    +POST /v1/projects/alice
    +{
    +  "project_handle": "dev-experiments",
    +  "instance_owner": "alice",
    +  "instance_handle": "dev-embeddings"
    +}
    +
    +# Production project
    +POST /v1/projects/alice
    +{
    +  "project_handle": "prod-dataset",
    +  "instance_owner": "alice",
    +  "instance_handle": "prod-embeddings",
    +  "metadataScheme": "{...}"
    +}
    +
    +# Archive project
    +POST /v1/projects/alice
    +{
    +  "project_handle": "archive-2023",
    +  "instance_owner": "alice",
    +  "instance_handle": "archive-embeddings",
    +  "public_read": true
    +}

    Troubleshooting#

    Cannot Create Project#

    Possible causes:

    • Project handle already exists for this user
    • Invalid project handle format
    • Instance doesn’t exist or not accessible
    • Missing required fields

    Solutions:

    • Choose different project handle
    • Verify instance exists: GET /v1/llm-services/owner
    • Check instance is owned or shared with you
    • Include all required fields (instance_owner, instance_handle)

    Metadata Validation Fails#

    Possible causes:

    • Metadata doesn’t match schema
    • Invalid JSON Schema format
    • Schema too restrictive

    Solutions:

    • Test schema with online validator
    • Verify embedding metadata matches schema
    • Update schema or metadata as needed

    Cannot Share Project#

    Possible causes:

    • Not project owner
    • Target user doesn’t exist
    • Invalid role specified

    Solutions:

    • Only owner can share projects
    • Verify user exists: GET /v1/users/target
    • Use valid role: “reader” or “editor”

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/similarity-search/index.html b/docs/public/concepts/similarity-search/index.html new file mode 100644 index 0000000..e22d8d2 --- /dev/null +++ b/docs/public/concepts/similarity-search/index.html @@ -0,0 +1,76 @@ +Similarity Search | dhamps-vdb Documentation + +

    Similarity Search#

    Find documents with similar semantic meaning using vector similarity.

    How it Works#

    Similarity search compares embedding vectors using cosine distance:

    1. Query vector: Either from stored embedding or raw vector
    2. Comparison: Calculate cosine similarity with all project embeddings
    3. Filtering: Apply threshold and metadata filters
    4. Ranking: Sort by similarity score (highest first)
    5. Return: Top N most similar documents

    Search Methods#

    Stored Document Search (GET)#

    Find documents similar to an already-stored embedding:

    GET /v1/similars/alice/research/doc1?count=10&threshold=0.7

    Use cases:

    • Find related documents
    • Discover similar passages
    • Identify duplicates

    Raw Vector Search (POST)#

    Search using a new embedding without storing it:

    POST /v1/similars/alice/research?count=10&threshold=0.7
    +
    +{
    +  "vector": [0.023, -0.015, ..., 0.042]
    +}

    Use cases:

    • Query without saving
    • Test embeddings
    • Real-time search

    Query Parameters#

    count#

    Number of similar documents to return.

    • Type: Integer
    • Range: 1-200
    • Default: 10
    GET /v1/similars/alice/project/doc1?count=5

    threshold#

    Minimum similarity score (0-1).

    • Type: Float
    • Range: 0.0-1.0
    • Default: 0.5
    • Meaning: 1.0 = identical, 0.0 = unrelated
    GET /v1/similars/alice/project/doc1?threshold=0.8

    limit#

    Maximum number of results (same as count).

    • Type: Integer
    • Range: 1-200
    • Default: 10

    offset#

    Skip first N results (pagination).

    • Type: Integer
    • Minimum: 0
    • Default: 0
    # First page
    +GET /v1/similars/alice/project/doc1?limit=10&offset=0
    +
    +# Second page
    +GET /v1/similars/alice/project/doc1?limit=10&offset=10

    metadata_path#

    JSON path to metadata field for filtering.

    • Type: String
    • Purpose: Specify metadata field to filter
    • Must be used with: metadata_value
    ?metadata_path=author

    metadata_value#

    Value to exclude from results.

    • Type: String
    • Purpose: Exclude documents matching this value
    • Must be used with: metadata_path
    ?metadata_path=author&metadata_value=Shakespeare

    Important: Excludes matches, doesn’t include them.

    Similarity Scores#

    Cosine Similarity#

    dhamps-vdb uses cosine similarity:

    similarity = 1 - cosine_distance

    Score ranges:

    • 1.0: Identical vectors
    • 0.9-1.0: Very similar
    • 0.7-0.9: Similar
    • 0.5-0.7: Somewhat similar
    • <0.5: Not similar

    Interpreting Scores#

    Typical thresholds:

    • 0.9+: Duplicates or near-duplicates
    • 0.8+: Strong semantic similarity
    • 0.7+: Related topics
    • 0.5-0.7: Weak relation
    • <0.5: Unrelated

    Optimal threshold depends on your use case and model.

    Metadata Filtering#

    Exclude by Field#

    Exclude documents where metadata field matches value:

    # Exclude documents from same author
    +GET /v1/similars/alice/lit-study/hamlet-act1?metadata_path=author&metadata_value=Shakespeare

    Result: Returns similar documents, excluding those with metadata.author == "Shakespeare".

    Nested Fields#

    Use dot notation for nested metadata:

    # Exclude documents from same author.name
    +GET /v1/similars/alice/project/doc1?metadata_path=author.name&metadata_value=John%20Doe

    Common Patterns#

    Exclude same work:

    ?metadata_path=title&metadata_value=Hamlet

    Exclude same source:

    ?metadata_path=source_id&metadata_value=corpus-A

    Exclude same category:

    ?metadata_path=category&metadata_value=tutorial

    See Metadata Filtering Guide for details.

    Response Format#

    {
    +  "user_handle": "alice",
    +  "project_handle": "research",
    +  "results": [
    +    {
    +      "id": "doc2",
    +      "similarity": 0.95
    +    },
    +    {
    +      "id": "doc5",
    +      "similarity": 0.87
    +    },
    +    {
    +      "id": "doc8",
    +      "similarity": 0.82
    +    }
    +  ]
    +}

    Fields:

    • user_handle: Project owner
    • project_handle: Project identifier
    • results: Array of similar documents
      • id: Document text_id
      • similarity: Similarity score (0-1)

    Results are sorted by similarity (highest first).

    Performance#

    Query Speed#

    Typical performance:

    • <10K embeddings: <10ms
    • 10K-100K embeddings: 10-50ms
    • 100K-1M embeddings: 50-200ms
    • >1M embeddings: 200-1000ms

    Optimization#

    HNSW Index:

    • Faster queries than IVFFlat
    • Better recall
    • Larger index size

    Query optimization:

    • Use appropriate threshold (higher = fewer results)
    • Limit result count (lower = faster)
    • Consider dimension reduction for large projects

    Scaling#

    For large datasets:

    • Monitor query performance
    • Consider read replicas
    • Use connection pooling
    • Cache frequent queries (application level)

    Common Use Cases#

    RAG Workflow#

    Retrieval Augmented Generation:

    # 1. User query
    +query="What is machine learning?"
    +
    +# 2. Generate query embedding (external)
    +query_vector=[...]
    +
    +# 3. Find similar documents
    +POST /v1/similars/alice/knowledge-base?count=5&threshold=0.7
    +{"vector": $query_vector}
    +
    +# 4. Retrieve full text for top results
    +for each result:
    +  GET /v1/embeddings/alice/knowledge-base/$result_id
    +
    +# 5. Send context to LLM for generation

    Duplicate Detection#

    Find near-duplicate documents:

    # High threshold for duplicates
    +GET /v1/similars/alice/corpus/doc1?count=10&threshold=0.95

    Documents with similarity > 0.95 are likely duplicates.

    Content Discovery#

    Find related content:

    # Moderate threshold for recommendations
    +GET /v1/similars/alice/articles/article1?count=10&threshold=0.7&metadata_path=article_id&metadata_value=article1

    Excludes the source article itself.

    Topic Clustering#

    Find documents on similar topics:

    # For each document, find similar ones
    +for doc in documents:
    +  GET /v1/similars/alice/corpus/$doc?count=20&threshold=0.8

    Group documents by similarity for clustering.

    Dimension Consistency#

    Automatic Filtering#

    Similarity queries only compare embeddings with matching dimensions:

    Project embeddings:
    +  - doc1: 3072 dimensions
    +  - doc2: 3072 dimensions
    +  - doc3: 1536 dimensions (different model)
    +
    +Query for doc1 similars:
    +  → Only compares with doc2
    +  → Ignores doc3 (dimension mismatch)

    Multiple Instances#

    Projects can have embeddings from multiple instances (if dimensions match):

    {
    +  "text_id": "doc1",
    +  "instance_handle": "openai-large",
    +  "vector_dim": 3072
    +}
    +
    +{
    +  "text_id": "doc2",
    +  "instance_handle": "custom-model",
    +  "vector_dim": 3072
    +}

    Both searchable together (same dimensions).

    Access Control#

    Authentication#

    Similarity search respects project access control:

    Owner: Full access +Editor: Can search (read permission) +Reader: Can search (read permission) +Public (if public_read=true): Can search (no auth required)

    Public Projects#

    Public projects allow unauthenticated similarity search:

    # No Authorization header needed
    +GET /v1/similars/alice/public-project/doc1?count=10

    See Public Projects Guide.

    Limitations#

    Current Constraints#

    • No cross-project search: Similarity search is per-project only
    • No filtering by multiple metadata fields: One field at a time
    • No custom distance metrics: Cosine similarity only
    • No approximate search tuning: Uses default HNSW parameters

    Workarounds#

    Cross-project search:

    • Query each project separately
    • Merge results in application

    Multiple metadata filters:

    • Filter by one field in query
    • Apply additional filters in application

    Troubleshooting#

    No Results Returned#

    Possible causes:

    • Threshold too high
    • No embeddings in project
    • Dimension mismatch
    • All results filtered by metadata

    Solutions:

    • Lower threshold (try 0.5)
    • Verify embeddings exist
    • Check dimensions match
    • Remove metadata filter

    Unexpected Results#

    Possible causes:

    • Threshold too low
    • Poor quality embeddings
    • Incorrect model used
    • Metadata filter excluding desired results

    Solutions:

    • Increase threshold
    • Regenerate embeddings
    • Verify correct model/dimensions
    • Adjust metadata filter

    Slow Queries#

    Possible causes:

    • Large dataset (>100K embeddings)
    • No vector index
    • High result count
    • Complex metadata filtering

    Solutions:

    • Reduce result count
    • Check index exists
    • Optimize database
    • Use read replicas

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/users-and-auth/index.html b/docs/public/concepts/users-and-auth/index.html new file mode 100644 index 0000000..e43de59 --- /dev/null +++ b/docs/public/concepts/users-and-auth/index.html @@ -0,0 +1,73 @@ +Users and Authentication | dhamps-vdb Documentation + +

    Users and Authentication#

    dhamps-vdb uses token-based authentication with API keys for all operations.

    User Model#

    User Properties#

    • user_handle: Unique identifier (3-20 characters, alphanumeric + underscore)
    • name: Full name (optional)
    • email: Email address (unique, required)
    • vdb_key: API key (SHA-256 hash, 64 characters)
    • created_at: Timestamp of creation
    • updated_at: Timestamp of last update

    Special Users#

    _system User

    • Created automatically during database migration
    • Owns system-wide LLM service definitions
    • Cannot be used for authentication
    • Provides default configurations for all users

    Authentication Flow#

    API Key Authentication#

    All requests (except public endpoints) require authentication:

    GET /v1/projects/alice/my-project
    +Authorization: Bearer 024v2013621509245f2e24...

    Authentication Process#

    1. Client sends API key in Authorization header with Bearer prefix
    2. Server extracts key and looks up user in database
    3. If user found, request proceeds with user context
    4. If not found or missing, returns 401 Unauthorized

    Admin Authentication#

    Administrative operations require the admin API key:

    curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle":"alice","email":"alice@example.com"}'

    Admin key is set via SERVICE_ADMINKEY environment variable.

    User Creation#

    By Admin#

    Only admin users can create new users:

    POST /v1/users
    +Authorization: Bearer ADMIN_KEY
    +
    +{
    +  "user_handle": "researcher1",
    +  "name": "Research User",
    +  "email": "researcher@example.com"
    +}

    Response:

    {
    +  "user_handle": "researcher1",
    +  "name": "Research User",
    +  "email": "researcher@example.com",
    +  "vdb_key": "024v2013621509245f2e24abcdef...",
    +  "created_at": "2024-01-15T10:30:00Z"
    +}

    Important: Save the vdb_key immediately - it cannot be recovered later.

    User Handle Restrictions#

    • Must be 3-20 characters
    • Alphanumeric characters and underscores only
    • Must be unique
    • Cannot be _system

    User Management#

    Retrieve User Information#

    Users can view their own information:

    GET /v1/users/alice
    +Authorization: Bearer alice_vdb_key

    Admins can view any user:

    GET /v1/users/alice
    +Authorization: Bearer ADMIN_KEY

    List All Users#

    Only admins can list all users:

    GET /v1/users
    +Authorization: Bearer ADMIN_KEY

    Returns array of user handles (not full user objects).

    Update User#

    Users can update their own information:

    PATCH /v1/users/alice
    +Authorization: Bearer alice_vdb_key
    +
    +{
    +  "name": "Alice Smith-Jones",
    +  "email": "alice.smith@example.com"
    +}

    Delete User#

    Users can delete their own account:

    DELETE /v1/users/alice
    +Authorization: Bearer alice_vdb_key

    Admins can delete any user:

    DELETE /v1/users/alice
    +Authorization: Bearer ADMIN_KEY

    Cascading Deletion:

    • All user’s projects are deleted
    • All user’s LLM service instances are deleted
    • All embeddings in user’s projects are deleted
    • Sharing grants from this user to others are removed

    Authorization Model#

    Resource Ownership#

    Users own three types of resources:

    1. Projects: Collections of embeddings
    2. LLM Service Instances: Embedding configurations with API keys
    3. LLM Service Definitions: Reusable configuration templates (optional)

    Access Levels#

    Owner

    • Full control over resource
    • Can read, write, delete
    • Can share with others
    • Can transfer ownership (projects only)

    Editor (via sharing)

    • Read and write access
    • Cannot delete resource
    • Cannot modify sharing
    • Cannot change project settings

    Reader (via sharing)

    • Read-only access
    • Can view embeddings
    • Can search for similar documents
    • Cannot modify anything

    Public (if project.public_read = true)

    • Unauthenticated read access
    • Can view embeddings
    • Can search for similar documents
    • Cannot write or modify

    Security Best Practices#

    API Key Management#

    Storage

    • Store API keys securely (e.g., environment variables, secret managers)
    • Never commit API keys to version control
    • Use different keys for development and production

    Rotation

    • Currently, API keys cannot be rotated
    • To change a key, delete and recreate the user
    • Plan key rotation strategy before production deployment

    Transmission

    • Always use HTTPS in production
    • API keys are transmitted in Authorization header
    • Never pass API keys in URL query parameters

    User Key vs. LLM API Keys#

    dhamps-vdb handles two types of keys:

    1. User API keys (vdb_key): Authenticate users to dhamps-vdb

      • Stored as SHA-256 hash in database
      • Never encrypted (one-way hash)
      • Returned only once on user creation
    2. LLM API keys (api_key_encrypted): Authenticate to LLM services

      • Stored encrypted (AES-256-GCM) in database
      • Never returned in API responses
      • Used internally for LLM processing

    Multi-User Workflows#

    Collaboration Pattern#

    1. Admin creates user accounts for team members
    2. Project Owner creates project with embeddings
    3. Owner shares project with collaborators
    4. Readers can search and view embeddings
    5. Editors can add/modify embeddings

    Organization Pattern#

    1. Admin creates organizational users
    2. Each user creates LLM service instances with their own API keys
    3. Users create projects using their instances
    4. Projects shared within organization as needed

    Public Access Pattern#

    1. User creates project with research data
    2. User sets public_read: true
    3. Anyone can access embeddings and search without authentication
    4. Only owner can modify project

    User Limits#

    Current Implementation#

    No enforced limits on:

    • Number of projects per user
    • Number of embeddings per project
    • Number of LLM service instances per user
    • Storage size per user

    For production deployments, consider implementing:

    • Rate limiting per API key
    • Storage quotas per user
    • Maximum project count per user

    Example Workflows#

    Create and Use User Account#

    # Admin creates user
    +curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer $ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "researcher1",
    +    "email": "researcher@example.com",
    +    "name": "Research User"
    +  }'
    +
    +# Save returned vdb_key
    +export USER_KEY="returned-vdb-key"
    +
    +# User verifies access
    +curl -X GET http://localhost:8880/v1/users/researcher1 \
    +  -H "Authorization: Bearer $USER_KEY"
    +
    +# User creates project
    +curl -X POST http://localhost:8880/v1/projects/researcher1 \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "my-project",
    +    "description": "My research project"
    +  }'

    Share Resources#

    # User shares project with colleague
    +curl -X POST http://localhost:8880/v1/projects/researcher1/my-project/share \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "colleague1",
    +    "role": "reader"
    +  }'
    +
    +# Colleague accesses shared project
    +curl -X GET http://localhost:8880/v1/projects/researcher1/my-project \
    +  -H "Authorization: Bearer $COLLEAGUE_KEY"

    Troubleshooting#

    401 Unauthorized#

    Possible causes:

    • Missing Authorization header
    • Incorrect API key
    • Expired or invalid key
    • Using user key instead of admin key (or vice versa)

    Solution:

    • Verify API key is correct
    • Check Authorization header format: Bearer KEY
    • Ensure operation matches key type (admin vs. user)

    403 Forbidden#

    Possible causes:

    • User doesn’t own resource
    • User not granted access to shared resource
    • Insufficient permissions (reader trying to edit)

    Solution:

    • Verify resource ownership
    • Check sharing grants
    • Ensure user has required role (editor for writes)

    User Creation Failed#

    Possible causes:

    • User handle already exists
    • Email already registered
    • Invalid user handle format
    • Not using admin key

    Solution:

    • Choose different user handle
    • Use unique email address
    • Check user handle format (3-20 chars, alphanumeric + underscore)
    • Verify using admin API key

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/deployment/database/index.html b/docs/public/deployment/database/index.html new file mode 100644 index 0000000..7b92925 --- /dev/null +++ b/docs/public/deployment/database/index.html @@ -0,0 +1,229 @@ +Database Setup | dhamps-vdb Documentation + +

    Database Setup#

    dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.

    Requirements#

    • PostgreSQL: Version 11 or higher
    • pgvector: Extension for vector similarity search
    • Storage: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)

    Installing PostgreSQL with pgvector#

    The easiest way to get PostgreSQL with pgvector:

    docker run -d \
    +  --name postgres-pgvector \
    +  -p 5432:5432 \
    +  -e POSTGRES_PASSWORD=secure_password \
    +  -v postgres_data:/var/lib/postgresql/data \
    +  pgvector/pgvector:0.7.4-pg16

    On Ubuntu/Debian#

    # Add PostgreSQL APT repository
    +sudo apt install curl ca-certificates
    +sudo install -d /usr/share/postgresql-common/pgdg
    +sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
    +  https://www.postgresql.org/media/keys/ACCC4CF8.asc
    +echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \
    +  https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
    +  sudo tee /etc/apt/sources.list.d/pgdg.list
    +
    +# Install PostgreSQL
    +sudo apt update
    +sudo apt install postgresql-16 postgresql-contrib-16
    +
    +# Install pgvector
    +sudo apt install postgresql-16-pgvector

    On macOS#

    # Using Homebrew
    +brew install postgresql@16
    +brew install pgvector
    +
    +# Start PostgreSQL
    +brew services start postgresql@16

    On RHEL/CentOS/Fedora#

    # Install PostgreSQL
    +sudo dnf install postgresql16-server postgresql16-contrib
    +
    +# Install pgvector (build from source)
    +sudo dnf install postgresql16-devel git gcc make
    +git clone https://github.com/pgvector/pgvector.git
    +cd pgvector
    +make
    +sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_config

    Database Configuration#

    Step 1: Create Database#

    Connect to PostgreSQL as superuser:

    # Local connection
    +sudo -u postgres psql
    +
    +# Remote connection
    +psql -h db.example.com -U postgres

    Create the database:

    -- Create database
    +CREATE DATABASE dhamps_vdb;

    Step 2: Create User#

    Create a dedicated user for dhamps-vdb:

    -- Create user with password
    +CREATE USER dhamps_user WITH PASSWORD 'secure_password_here';

    Best practices:

    • Use strong, randomly generated password (e.g., openssl rand -base64 32)
    • Store password securely (password manager, secrets management)
    • Rotate passwords regularly

    Step 3: Grant Privileges#

    Grant necessary permissions:

    -- Grant database privileges
    +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    +
    +-- Connect to the database
    +\c dhamps_vdb
    +
    +-- Grant schema privileges
    +GRANT ALL ON SCHEMA public TO dhamps_user;
    +
    +-- For PostgreSQL 15+, also grant:
    +GRANT CREATE ON DATABASE dhamps_vdb TO dhamps_user;

    Step 4: Enable pgvector Extension#

    Still connected to the dhamps_vdb database:

    -- Enable pgvector extension
    +CREATE EXTENSION IF NOT EXISTS vector;
    +
    +-- Verify extension is installed
    +\dx

    Expected output should include:

    List of installed extensions
    +  Name   | Version |   Schema   |         Description
    +---------+---------+------------+------------------------------
    + vector  | 0.7.4   | public     | vector data type and ivfflat and hnsw access methods

    Step 5: Verify Setup#

    Test the setup:

    -- Test vector creation
    +SELECT '[1,2,3]'::vector;
    +
    +-- Should return: [1,2,3]
    +
    +-- Test vector distance
    +SELECT '[1,2,3]'::vector <=> '[4,5,6]'::vector AS distance;
    +
    +-- Should return a float (distance value)

    Exit psql:

    \q

    Connection String Format#

    dhamps-vdb connects using these environment variables:

    SERVICE_DBHOST=localhost      # Database hostname
    +SERVICE_DBPORT=5432          # Database port
    +SERVICE_DBUSER=dhamps_user   # Database username
    +SERVICE_DBPASSWORD=password  # Database password
    +SERVICE_DBNAME=dhamps_vdb    # Database name

    The connection string format used internally:

    postgresql://username:password@host:port/database?sslmode=disable

    Production Configuration#

    PostgreSQL Tuning#

    Edit postgresql.conf for better vector search performance:

    # Memory settings
    +shared_buffers = 4GB                    # 25% of RAM
    +effective_cache_size = 12GB             # 75% of RAM
    +maintenance_work_mem = 1GB
    +work_mem = 50MB
    +
    +# Parallel query settings
    +max_parallel_workers_per_gather = 4
    +max_parallel_workers = 8
    +
    +# Connection settings
    +max_connections = 100
    +
    +# For pgvector specifically
    +shared_preload_libraries = 'vector'     # Add if not present
    +
    +# Write-ahead log
    +wal_level = replica                     # For replication
    +max_wal_senders = 3                     # For replicas

    Restart PostgreSQL after changes:

    # On systemd systems
    +sudo systemctl restart postgresql
    +
    +# On Docker
    +docker restart postgres-container

    Connection Pooling#

    For high-load scenarios, use connection pooling with PgBouncer:

    # Install PgBouncer
    +sudo apt install pgbouncer
    +
    +# Configure /etc/pgbouncer/pgbouncer.ini
    +[databases]
    +dhamps_vdb = host=localhost port=5432 dbname=dhamps_vdb
    +
    +[pgbouncer]
    +listen_addr = 127.0.0.1
    +listen_port = 6432
    +auth_type = md5
    +auth_file = /etc/pgbouncer/userlist.txt
    +pool_mode = transaction
    +max_client_conn = 1000
    +default_pool_size = 20

    Connect dhamps-vdb to PgBouncer instead of PostgreSQL directly.

    SSL/TLS Encryption#

    Enable SSL in postgresql.conf:

    ssl = on
    +ssl_cert_file = '/etc/postgresql/server.crt'
    +ssl_key_file = '/etc/postgresql/server.key'
    +ssl_ca_file = '/etc/postgresql/ca.crt'

    Update connection string:

    # Update dhamps-vdb configuration
    +SERVICE_DBHOST=db.example.com
    +# Change connection to use SSL (requires code modification or PostgreSQL parameter)

    Network Security#

    Restrict access in pg_hba.conf:

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    +
    +# Allow dhamps_user from application server only
    +host    dhamps_vdb      dhamps_user     10.0.1.0/24            md5
    +
    +# Allow localhost connections
    +local   all             all                                    peer
    +host    all             all             127.0.0.1/32           md5
    +host    all             all             ::1/128                md5

    Reload PostgreSQL:

    sudo systemctl reload postgresql

    Backup and Recovery#

    Automated Backups#

    Daily backup script:

    #!/bin/bash
    +# /usr/local/bin/backup-dhamps-vdb.sh
    +
    +BACKUP_DIR="/backups/dhamps-vdb"
    +DATE=$(date +%Y%m%d_%H%M%S)
    +DB_NAME="dhamps_vdb"
    +
    +# Create backup
    +pg_dump -U dhamps_user -h localhost $DB_NAME | gzip > "$BACKUP_DIR/dhamps-vdb-$DATE.sql.gz"
    +
    +# Keep last 30 days
    +find $BACKUP_DIR -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete
    +
    +# Verify backup
    +if [ $? -eq 0 ]; then
    +    echo "Backup successful: $DATE"
    +else
    +    echo "Backup failed: $DATE" >&2
    +    exit 1
    +fi

    Set up cron job:

    # Run daily at 2 AM
    +0 2 * * * /usr/local/bin/backup-dhamps-vdb.sh

    Restore from Backup#

    # Decompress and restore
    +gunzip -c /backups/dhamps-vdb/dhamps-vdb-20240208.sql.gz | \
    +  psql -U dhamps_user -h localhost dhamps_vdb

    Point-in-Time Recovery (PITR)#

    Enable WAL archiving in postgresql.conf:

    wal_level = replica
    +archive_mode = on
    +archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

    Monitoring#

    Check Database Size#

    -- Database size
    +SELECT pg_size_pretty(pg_database_size('dhamps_vdb'));
    +
    +-- Table sizes
    +SELECT 
    +    schemaname,
    +    tablename,
    +    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
    +FROM pg_tables
    +WHERE schemaname = 'public'
    +ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

    Check Connection Status#

    -- Active connections
    +SELECT count(*) FROM pg_stat_activity WHERE datname = 'dhamps_vdb';
    +
    +-- Connection details
    +SELECT 
    +    pid,
    +    usename,
    +    application_name,
    +    client_addr,
    +    state,
    +    query
    +FROM pg_stat_activity 
    +WHERE datname = 'dhamps_vdb';

    Monitor Performance#

    -- Enable pg_stat_statements
    +CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
    +
    +-- View slow queries
    +SELECT 
    +    query,
    +    calls,
    +    total_time,
    +    mean_time,
    +    max_time
    +FROM pg_stat_statements
    +WHERE query NOT LIKE '%pg_stat_statements%'
    +ORDER BY mean_time DESC
    +LIMIT 10;

    Troubleshooting#

    Cannot Connect to Database#

    # Check if PostgreSQL is running
    +sudo systemctl status postgresql
    +
    +# Check PostgreSQL logs
    +sudo tail -f /var/log/postgresql/postgresql-16-main.log
    +
    +# Test connection
    +psql -h localhost -U dhamps_user -d dhamps_vdb

    pgvector Extension Not Found#

    -- Check available extensions
    +SELECT * FROM pg_available_extensions WHERE name = 'vector';
    +
    +-- If not listed, install pgvector package
    +-- See installation section above

    Permission Denied#

    -- Reconnect as superuser
    +\c dhamps_vdb postgres
    +
    +-- Re-grant privileges
    +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    +GRANT ALL ON SCHEMA public TO dhamps_user;
    +GRANT ALL ON ALL TABLES IN SCHEMA public TO dhamps_user;
    +GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO dhamps_user;
    +
    +-- For future objects
    +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO dhamps_user;
    +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO dhamps_user;

    Out of Disk Space#

    # Check disk usage
    +df -h
    +
    +# Check PostgreSQL data directory
    +du -sh /var/lib/postgresql/16/main/
    +
    +# Clean up old WAL files (if safe)
    +# Check archive status first

    Slow Queries#

    -- Check missing indexes
    +SELECT 
    +    schemaname,
    +    tablename,
    +    attname,
    +    n_distinct,
    +    correlation
    +FROM pg_stats
    +WHERE schemaname = 'public'
    +ORDER BY n_distinct DESC;
    +
    +-- Analyze tables
    +ANALYZE;
    +
    +-- Vacuum tables
    +VACUUM ANALYZE;

    Migration from Other Databases#

    dhamps-vdb is designed specifically for PostgreSQL with pgvector. Migration from other databases requires:

    1. Export data from source database
    2. Set up PostgreSQL with pgvector
    3. Transform data to match dhamps-vdb schema
    4. Import using dhamps-vdb API or direct SQL

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/docker/index.html b/docs/public/deployment/docker/index.html new file mode 100644 index 0000000..e9d80b2 --- /dev/null +++ b/docs/public/deployment/docker/index.html @@ -0,0 +1,122 @@ +Docker Deployment | dhamps-vdb Documentation + +

    Docker Deployment#

    This guide covers production-focused Docker deployment for dhamps-vdb.

    Overview#

    For detailed Docker setup instructions, see Getting Started with Docker. This page focuses on production deployment considerations.

    Production Deployment#

    Prerequisites#

    • Docker Engine 20.10+
    • Docker Compose 2.0+ (or docker-compose 1.29+)
    • PostgreSQL 11+ with pgvector extension (included in compose setup)

    Quick Production Setup#

    # Clone repository
    +git clone https://github.com/mpilhlt/dhamps-vdb.git
    +cd dhamps-vdb
    +
    +# Generate secure keys
    +./docker-setup.sh
    +
    +# Review and customize .env
    +nano .env
    +
    +# Deploy
    +docker-compose up -d

    Production Considerations#

    Use Reverse Proxy#

    Always run behind a reverse proxy (nginx, Traefik, Caddy) for:

    • HTTPS/TLS termination
    • Request filtering
    • Rate limiting
    • Load balancing

    Example nginx configuration:

    upstream dhamps-vdb {
    +    server localhost:8880;
    +}
    +
    +server {
    +    listen 443 ssl http2;
    +    server_name api.example.com;
    +
    +    ssl_certificate /path/to/cert.pem;
    +    ssl_certificate_key /path/to/key.pem;
    +
    +    location / {
    +        proxy_pass http://dhamps-vdb;
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Real-IP $remote_addr;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_set_header X-Forwarded-Proto $scheme;
    +    }
    +}

    Container Resource Limits#

    Set resource limits in docker-compose.yml:

    services:
    +  dhamps-vdb:
    +    deploy:
    +      resources:
    +        limits:
    +          cpus: '2'
    +          memory: 2G
    +        reservations:
    +          cpus: '0.5'
    +          memory: 512M
    +  
    +  postgres:
    +    deploy:
    +      resources:
    +        limits:
    +          cpus: '2'
    +          memory: 4G
    +        reservations:
    +          cpus: '1'
    +          memory: 2G

    Use Specific Image Tags#

    Avoid latest in production:

    services:
    +  postgres:
    +    image: pgvector/pgvector:0.7.4-pg16  # Specific version
    +  
    +  dhamps-vdb:
    +    image: dhamps-vdb:v0.1.0  # Tag your builds

    Health Monitoring#

    The image includes health checks. Monitor with:

    # Check health status
    +docker inspect --format='{{.State.Health.Status}}' dhamps-vdb
    +
    +# View health check logs
    +docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' dhamps-vdb
    +
    +# Integrate with monitoring (Prometheus, etc.)

    Logging#

    Configure logging drivers in docker-compose.yml:

    services:
    +  dhamps-vdb:
    +    logging:
    +      driver: "json-file"
    +      options:
    +        max-size: "10m"
    +        max-file: "3"

    Or use centralized logging:

    services:
    +  dhamps-vdb:
    +    logging:
    +      driver: "syslog"
    +      options:
    +        syslog-address: "tcp://logserver:514"

    External Database Deployment#

    For production, consider using a managed PostgreSQL service or separate database server.

    Requirements#

    • PostgreSQL 11+ with pgvector extension
    • Network connectivity from container to database
    • Database user with appropriate privileges

    See Database Setup for detailed instructions.

    Configuration#

    Update .env:

    SERVICE_DBHOST=db.example.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=secure_password
    +SERVICE_DBNAME=dhamps_vdb

    Modify docker-compose.yml to remove postgres service:

    services:
    +  dhamps-vdb:
    +    build: .
    +    ports:
    +      - "8880:8880"
    +    env_file: .env
    +    restart: unless-stopped

    Scaling and High Availability#

    Horizontal Scaling#

    Run multiple instances behind a load balancer:

    services:
    +  dhamps-vdb:
    +    build: .
    +    deploy:
    +      replicas: 3
    +      restart_policy:
    +        condition: on-failure

    Note: All instances must connect to the same database.

    Database Replication#

    For high availability:

    • Use PostgreSQL replication (streaming or logical)
    • Consider read replicas for read-heavy workloads
    • Point write operations to primary, reads to replicas

    Backup Strategy#

    Database Backups#

    # Automated daily backups
    +0 2 * * * docker-compose exec -T postgres pg_dump -U postgres dhamps_vdb | gzip > /backups/dhamps-vdb-$(date +\%Y\%m\%d).sql.gz
    +
    +# Keep last 30 days
    +find /backups -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete

    Volume Backups#

    # Backup Docker volume
    +docker run --rm -v dhamps-vdb_postgres_data:/data -v /backups:/backup alpine tar czf /backup/postgres-data-$(date +\%Y\%m\%d).tar.gz /data

    Environment Configuration Backups#

    # Backup .env (securely!)
    +gpg --encrypt --recipient admin@example.com .env > .env.gpg

    Troubleshooting#

    Container Performance Issues#

    # Check resource usage
    +docker stats
    +
    +# Check container logs
    +docker-compose logs -f --tail=100 dhamps-vdb
    +
    +# Check slow queries (if database is slow)
    +docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;"

    Network Connectivity Issues#

    # Test database connection from container
    +docker-compose exec dhamps-vdb nc -zv postgres 5432
    +
    +# Check DNS resolution
    +docker-compose exec dhamps-vdb nslookup postgres
    +
    +# Test API from inside container
    +docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs

    Update and Rollback#

    # Update to new version
    +docker-compose pull
    +docker-compose up -d
    +
    +# Rollback if needed
    +docker-compose down
    +docker-compose up -d --force-recreate

    Security Best Practices#

    • See Security Guide for comprehensive security recommendations
    • Use Environment Variables Guide for proper configuration
    • Never expose database port publicly
    • Use strong, randomly generated keys (see ./docker-setup.sh)
    • Keep Docker and images updated
    • Run containers as non-root (already configured)

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/environment-variables/index.html b/docs/public/deployment/environment-variables/index.html new file mode 100644 index 0000000..cd8d460 --- /dev/null +++ b/docs/public/deployment/environment-variables/index.html @@ -0,0 +1,105 @@ +Environment Variables | dhamps-vdb Documentation + +

    Environment Variables#

    Complete reference for all environment variables used by dhamps-vdb.

    Overview#

    dhamps-vdb is configured entirely through environment variables. These can be set:

    1. In a .env file (recommended for Docker)
    2. As system environment variables
    3. Via command-line flags (some variables only)

    Required Variables#

    These variables must be set for dhamps-vdb to function:

    SERVICE_ADMINKEY#

    Admin API key for administrative operations.

    • Type: String
    • Required: Yes
    • Default: None
    • Environment Variable: SERVICE_ADMINKEY
    • Command-line Flag: --admin-key

    Description: Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.

    Example:

    SERVICE_ADMINKEY=Ch4ngeM3SecureAdminKey!

    Security:

    • Generate with: openssl rand -base64 32
    • Never commit to version control
    • Rotate regularly
    • Store securely (password manager, secrets vault)

    Usage:

    curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer $SERVICE_ADMINKEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle": "alice", "full_name": "Alice Smith"}'

    ENCRYPTION_KEY#

    Encryption key for protecting user API keys in the database.

    • Type: String (32+ characters)
    • Required: Yes
    • Default: None
    • Environment Variable: ENCRYPTION_KEY

    Description: AES-256 encryption key used to encrypt user API keys before storing them in the database. Must be at least 32 characters. The key is hashed with SHA-256 to ensure exactly 32 bytes for AES-256 encryption.

    Example:

    ENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

    Security:

    • Generate with: openssl rand -hex 32
    • Minimum 32 characters required
    • Never commit to version control
    • CRITICAL: If lost, all stored API keys become unrecoverable
    • Backup securely and separately from database
    • Never change in production (will invalidate all existing API keys)

    Technical Details:

    • Uses AES-256-GCM for encryption
    • SHA-256 hash ensures correct key length
    • Each encryption uses unique nonce
    • Encrypted keys stored as base64 in database

    Optional Variables#

    SERVICE_DEBUG#

    Enable debug logging.

    • Type: Boolean
    • Required: No
    • Default: true
    • Environment Variable: SERVICE_DEBUG
    • Command-line Flag: -d, --debug

    Description: Enables verbose debug logging including request details, SQL queries, and internal operations.

    Example:

    SERVICE_DEBUG=false   # Production (less verbose)
    +SERVICE_DEBUG=true    # Development (verbose)

    Impact:

    • true: Detailed logs, useful for debugging
    • false: Minimal logs, recommended for production

    SERVICE_HOST#

    Hostname or IP address to bind the service to.

    • Type: String
    • Required: No
    • Default: localhost
    • Environment Variable: SERVICE_HOST
    • Command-line Flag: --host

    Description: Network interface to listen on. Use 0.0.0.0 to listen on all interfaces (required for Docker).

    Examples:

    SERVICE_HOST=localhost    # Local development only
    +SERVICE_HOST=0.0.0.0      # Listen on all interfaces (Docker)
    +SERVICE_HOST=10.0.1.5     # Specific interface

    Security:

    • Use localhost for development
    • Use 0.0.0.0 for Docker/production with firewall
    • Never expose directly to internet without reverse proxy

    SERVICE_PORT#

    Port number for the API service.

    • Type: Integer
    • Required: No
    • Default: 8880
    • Environment Variable: SERVICE_PORT
    • Command-line Flag: -p, --port

    Description: TCP port the service listens on.

    Example:

    SERVICE_PORT=8880      # Default
    +SERVICE_PORT=8080      # Alternative
    +SERVICE_PORT=3000      # Custom

    Notes:

    • Ports below 1024 require root/admin privileges
    • Ensure port is not already in use
    • Update firewall rules accordingly

    Database Variables#

    SERVICE_DBHOST#

    Database hostname or IP address.

    • Type: String
    • Required: No
    • Default: localhost
    • Environment Variable: SERVICE_DBHOST
    • Command-line Flag: --db-host

    Description: PostgreSQL server hostname.

    Examples:

    SERVICE_DBHOST=localhost              # Local PostgreSQL
    +SERVICE_DBHOST=postgres               # Docker Compose service name
    +SERVICE_DBHOST=db.example.com         # Remote database
    +SERVICE_DBHOST=10.0.1.100            # Database IP address

    SERVICE_DBPORT#

    Database port number.

    • Type: Integer
    • Required: No
    • Default: 5432
    • Environment Variable: SERVICE_DBPORT
    • Command-line Flag: --db-port

    Description: PostgreSQL server port.

    Example:

    SERVICE_DBPORT=5432       # Default PostgreSQL port
    +SERVICE_DBPORT=5433       # Alternative port

    SERVICE_DBUSER#

    Database username.

    • Type: String
    • Required: No
    • Default: postgres
    • Environment Variable: SERVICE_DBUSER
    • Command-line Flag: --db-user

    Description: PostgreSQL user for database connections.

    Example:

    SERVICE_DBUSER=postgres        # Default superuser
    +SERVICE_DBUSER=dhamps_user     # Dedicated user (recommended)

    Security:

    • Create dedicated user (not superuser) for production
    • Use principle of least privilege
    • See Database Setup for user creation

    SERVICE_DBPASSWORD#

    Database password.

    • Type: String
    • Required: No
    • Default: password
    • Environment Variable: SERVICE_DBPASSWORD
    • Command-line Flag: --db-password

    Description: Password for database authentication.

    Example:

    SERVICE_DBPASSWORD=secure_database_password_here

    Security:

    • Use strong, randomly generated password
    • Never use default password in production
    • Never commit to version control
    • Store in secrets management system
    • Rotate regularly

    SERVICE_DBNAME#

    Database name.

    • Type: String
    • Required: No
    • Default: postgres
    • Environment Variable: SERVICE_DBNAME
    • Command-line Flag: --db-name

    Description: Name of the PostgreSQL database.

    Example:

    SERVICE_DBNAME=dhamps_vdb      # Production database
    +SERVICE_DBNAME=dhamps_test     # Testing database

    Configuration Examples#

    Development Setup#

    # .env file for development
    +SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=postgres
    +SERVICE_DBNAME=dhamps_vdb
    +SERVICE_ADMINKEY=dev-admin-key-not-for-production
    +ENCRYPTION_KEY=dev-encryption-key-min-32-chars-long

    Docker Compose Setup#

    # .env file for Docker Compose
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=postgres
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=secure_db_password_here
    +SERVICE_DBNAME=dhamps_vdb
    +SERVICE_ADMINKEY=generated_admin_key_from_setup_script
    +ENCRYPTION_KEY=generated_encryption_key_from_setup_script

    Production Setup#

    # .env file for production (or use secrets management)
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=db.internal.example.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_prod_user
    +SERVICE_DBPASSWORD=<from-secrets-manager>
    +SERVICE_DBNAME=dhamps_vdb_prod
    +SERVICE_ADMINKEY=<from-secrets-manager>
    +ENCRYPTION_KEY=<from-secrets-manager>

    Setting Environment Variables#

    Create a .env file in the project root:

    # Copy template
    +cp template.env .env
    +
    +# Edit with your values
    +nano .env

    The application automatically loads .env on startup.

    Using System Environment Variables#

    # Linux/macOS
    +export SERVICE_ADMINKEY="your-admin-key"
    +export ENCRYPTION_KEY="your-encryption-key"
    +
    +# Windows PowerShell
    +$env:SERVICE_ADMINKEY = "your-admin-key"
    +$env:ENCRYPTION_KEY = "your-encryption-key"
    +
    +# Windows Command Prompt
    +set SERVICE_ADMINKEY=your-admin-key
    +set ENCRYPTION_KEY=your-encryption-key

    Using Docker#

    With docker run:

    docker run -d \
    +  -e SERVICE_ADMINKEY=admin-key \
    +  -e ENCRYPTION_KEY=encryption-key \
    +  -e SERVICE_DBHOST=db-host \
    +  dhamps-vdb:latest

    With docker-compose.yml:

    services:
    +  dhamps-vdb:
    +    image: dhamps-vdb:latest
    +    environment:
    +      SERVICE_DEBUG: "false"
    +      SERVICE_HOST: "0.0.0.0"
    +      SERVICE_PORT: "8880"
    +      SERVICE_DBHOST: "postgres"
    +    env_file:
    +      - .env  # Load additional variables from file

    Using Command-Line Flags#

    Some variables support command-line flags:

    ./dhamps-vdb \
    +  --debug \
    +  --host 0.0.0.0 \
    +  --port 8880 \
    +  --admin-key your-admin-key \
    +  --db-host localhost \
    +  --db-port 5432 \
    +  --db-user postgres \
    +  --db-password password \
    +  --db-name dhamps_vdb

    Note: ENCRYPTION_KEY must be set as environment variable, not flag.

    Validation and Troubleshooting#

    Missing Required Variables#

    If required variables are not set, the service will fail to start:

    Error: SERVICE_ADMINKEY environment variable is not set

    Solution: Set the missing variable.

    Invalid ENCRYPTION_KEY#

    If ENCRYPTION_KEY is too short or invalid:

    Error: ENCRYPTION_KEY environment variable is not set

    Solution: Ensure key is at least 32 characters:

    openssl rand -hex 32

    Database Connection Failure#

    Error: failed to connect to database

    Check:

    • SERVICE_DBHOST is correct and reachable
    • SERVICE_DBPORT is correct
    • SERVICE_DBUSER and SERVICE_DBPASSWORD are valid
    • SERVICE_DBNAME exists
    • PostgreSQL is running
    • Firewall allows connection

    Testing Configuration#

    # Start service with debug logging
    +SERVICE_DEBUG=true ./dhamps-vdb
    +
    +# Check if service starts successfully
    +curl http://localhost:8880/docs
    +
    +# Test admin authentication
    +curl -X GET http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer $SERVICE_ADMINKEY"

    Security Best Practices#

    1. Never commit .env files to version control

      • Already in .gitignore
      • Use .env.example templates
    2. Generate secure random keys

      openssl rand -base64 32  # Admin key
      +openssl rand -hex 32     # Encryption key
    3. Use secrets management in production

      • HashiCorp Vault
      • AWS Secrets Manager
      • Azure Key Vault
      • Docker Secrets (Swarm)
      • Kubernetes Secrets
    4. Rotate keys regularly

      • Admin key: Every 90 days
      • Database password: Every 90 days
      • Encryption key: Cannot be rotated without re-encrypting all API keys
    5. Principle of least privilege

      • Use dedicated database user (not superuser)
      • Grant only necessary permissions
      • Restrict network access
    6. Monitor and audit

      • Log admin key usage
      • Monitor failed authentication attempts
      • Review access patterns

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/index.html b/docs/public/deployment/index.html new file mode 100644 index 0000000..0b17b38 --- /dev/null +++ b/docs/public/deployment/index.html @@ -0,0 +1,12 @@ +Deployment | dhamps-vdb Documentation + +

    Deployment Guide#

    Deploy dhamps-vdb to production environments.

    Deployment Options#

    dhamps-vdb can be deployed in several ways:

    • Docker Compose - Simplest option, includes PostgreSQL
    • Docker with External Database - Production-ready setup
    • Standalone Binary - For custom environments
    • Kubernetes - For orchestrated deployments

    Production Considerations#

    When deploying to production:

    • Use strong, randomly generated keys
    • Enable HTTPS/TLS for all API endpoints
    • Configure database backups
    • Set up monitoring and logging
    • Restrict network access to database
    • Use environment variables for sensitive configuration

    Guides#

    \ No newline at end of file diff --git a/docs/public/deployment/index.xml b/docs/public/deployment/index.xml new file mode 100644 index 0000000..8560882 --- /dev/null +++ b/docs/public/deployment/index.xml @@ -0,0 +1,106 @@ +Deployment on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/deployment/Recent content in Deployment on dhamps-vdb DocumentationHugoen-usDocker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/deployment/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> +<p>This guide covers production-focused Docker deployment for dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>For detailed Docker setup instructions, see <a href="../../getting-started/docker/">Getting Started with Docker</a>. This page focuses on production deployment considerations.</p> +<h2 id="production-deployment">Production Deployment<a class="anchor" href="#production-deployment">#</a></h2> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<ul> +<li>Docker Engine 20.10+</li> +<li>Docker Compose 2.0+ (or docker-compose 1.29+)</li> +<li>PostgreSQL 11+ with pgvector extension (included in compose setup)</li> +</ul> +<h3 id="quick-production-setup">Quick Production Setup<a class="anchor" href="#quick-production-setup">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate secure keys</span> +</span></span><span style="display:flex;"><span>./docker-setup.sh +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Review and customize .env</span> +</span></span><span style="display:flex;"><span>nano .env +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Deploy</span> +</span></span><span style="display:flex;"><span>docker-compose up -d</span></span></code></pre></div><h2 id="production-considerations">Production Considerations<a class="anchor" href="#production-considerations">#</a></h2> +<h3 id="use-reverse-proxy">Use Reverse Proxy<a class="anchor" href="#use-reverse-proxy">#</a></h3> +<p>Always run behind a reverse proxy (nginx, Traefik, Caddy) for:</p>Database Setuphttps://mpilhlt.github.io/dhamps-vdb/deployment/database/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/database/<h1 id="database-setup">Database Setup<a class="anchor" href="#database-setup">#</a></h1> +<p>dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.</p> +<h2 id="requirements">Requirements<a class="anchor" href="#requirements">#</a></h2> +<ul> +<li><strong>PostgreSQL</strong>: Version 11 or higher</li> +<li><strong>pgvector</strong>: Extension for vector similarity search</li> +<li><strong>Storage</strong>: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)</li> +</ul> +<h2 id="installing-postgresql-with-pgvector">Installing PostgreSQL with pgvector<a class="anchor" href="#installing-postgresql-with-pgvector">#</a></h2> +<h3 id="using-docker-recommended">Using Docker (Recommended)<a class="anchor" href="#using-docker-recommended">#</a></h3> +<p>The easiest way to get PostgreSQL with pgvector:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --name postgres-pgvector <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -p 5432:5432 <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>secure_password <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -v postgres_data:/var/lib/postgresql/data <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> pgvector/pgvector:0.7.4-pg16</span></span></code></pre></div><h3 id="on-ubuntudebian">On Ubuntu/Debian<a class="anchor" href="#on-ubuntudebian">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Add PostgreSQL APT repository</span> +</span></span><span style="display:flex;"><span>sudo apt install curl ca-certificates +</span></span><span style="display:flex;"><span>sudo install -d /usr/share/postgresql-common/pgdg +</span></span><span style="display:flex;"><span>sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> https://www.postgresql.org/media/keys/ACCC4CF8.asc +</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> https://apt.postgresql.org/pub/repos/apt </span><span style="color:#66d9ef">$(</span>lsb_release -cs<span style="color:#66d9ef">)</span><span style="color:#e6db74">-pgdg main&#34;</span> | <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> sudo tee /etc/apt/sources.list.d/pgdg.list +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> +</span></span><span style="display:flex;"><span>sudo apt update +</span></span><span style="display:flex;"><span>sudo apt install postgresql-16 postgresql-contrib-16 +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector</span> +</span></span><span style="display:flex;"><span>sudo apt install postgresql-16-pgvector</span></span></code></pre></div><h3 id="on-macos">On macOS<a class="anchor" href="#on-macos">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Using Homebrew</span> +</span></span><span style="display:flex;"><span>brew install postgresql@16 +</span></span><span style="display:flex;"><span>brew install pgvector +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start PostgreSQL</span> +</span></span><span style="display:flex;"><span>brew services start postgresql@16</span></span></code></pre></div><h3 id="on-rhelcentosfedora">On RHEL/CentOS/Fedora<a class="anchor" href="#on-rhelcentosfedora">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> +</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-server postgresql16-contrib +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector (build from source)</span> +</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-devel git gcc make +</span></span><span style="display:flex;"><span>git clone https://github.com/pgvector/pgvector.git +</span></span><span style="display:flex;"><span>cd pgvector +</span></span><span style="display:flex;"><span>make +</span></span><span style="display:flex;"><span>sudo make install PG_CONFIG<span style="color:#f92672">=</span>/usr/pgsql-16/bin/pg_config</span></span></code></pre></div><h2 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h2> +<h3 id="step-1-create-database">Step 1: Create Database<a class="anchor" href="#step-1-create-database">#</a></h3> +<p>Connect to PostgreSQL as superuser:</p>Environment Variableshttps://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/<h1 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h1> +<p>Complete reference for all environment variables used by dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb is configured entirely through environment variables. These can be set:</p> +<ol> +<li><strong>In a <code>.env</code> file</strong> (recommended for Docker)</li> +<li><strong>As system environment variables</strong></li> +<li><strong>Via command-line flags</strong> (some variables only)</li> +</ol> +<h2 id="required-variables">Required Variables<a class="anchor" href="#required-variables">#</a></h2> +<p>These variables <strong>must</strong> be set for dhamps-vdb to function:</p> +<h3 id="service_adminkey">SERVICE_ADMINKEY<a class="anchor" href="#service_adminkey">#</a></h3> +<p>Admin API key for administrative operations.</p> +<ul> +<li><strong>Type:</strong> String</li> +<li><strong>Required:</strong> Yes</li> +<li><strong>Default:</strong> None</li> +<li><strong>Environment Variable:</strong> <code>SERVICE_ADMINKEY</code></li> +<li><strong>Command-line Flag:</strong> <code>--admin-key</code></li> +</ul> +<p><strong>Description:</strong> Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.</p>Security Best Practiceshttps://mpilhlt.github.io/dhamps-vdb/deployment/security/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/security/<h1 id="security-best-practices">Security Best Practices<a class="anchor" href="#security-best-practices">#</a></h1> +<p>Comprehensive guide for securing your dhamps-vdb production deployment.</p> +<h2 id="security-overview">Security Overview<a class="anchor" href="#security-overview">#</a></h2> +<p>dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.</p> +<h2 id="httpstls-configuration">HTTPS/TLS Configuration<a class="anchor" href="#httpstls-configuration">#</a></h2> +<h3 id="why-https-is-required">Why HTTPS is Required<a class="anchor" href="#why-https-is-required">#</a></h3> +<ul> +<li><strong>Encryption in transit</strong>: Protects API keys and data from interception</li> +<li><strong>Authentication</strong>: Verifies server identity</li> +<li><strong>Compliance</strong>: Required by most security standards</li> +</ul> +<h3 id="using-a-reverse-proxy">Using a Reverse Proxy<a class="anchor" href="#using-a-reverse-proxy">#</a></h3> +<p><strong>Never expose dhamps-vdb directly to the internet.</strong> Always use a reverse proxy with TLS termination.</p> \ No newline at end of file diff --git a/docs/public/deployment/security/index.html b/docs/public/deployment/security/index.html new file mode 100644 index 0000000..98797d6 --- /dev/null +++ b/docs/public/deployment/security/index.html @@ -0,0 +1,219 @@ +Security Best Practices | dhamps-vdb Documentation + +

    Security Best Practices#

    Comprehensive guide for securing your dhamps-vdb production deployment.

    Security Overview#

    dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.

    HTTPS/TLS Configuration#

    Why HTTPS is Required#

    • Encryption in transit: Protects API keys and data from interception
    • Authentication: Verifies server identity
    • Compliance: Required by most security standards

    Using a Reverse Proxy#

    Never expose dhamps-vdb directly to the internet. Always use a reverse proxy with TLS termination.

    Nginx with Let’s Encrypt#

    Install Certbot:

    sudo apt install nginx certbot python3-certbot-nginx

    Configure nginx (/etc/nginx/sites-available/dhamps-vdb):

    upstream dhamps_backend {
    +    server 127.0.0.1:8880;
    +    keepalive 32;
    +}
    +
    +server {
    +    listen 80;
    +    server_name api.example.com;
    +    
    +    # Redirect HTTP to HTTPS
    +    return 301 https://$server_name$request_uri;
    +}
    +
    +server {
    +    listen 443 ssl http2;
    +    server_name api.example.com;
    +
    +    # SSL certificates (managed by Certbot)
    +    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    +    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    +
    +    # Modern SSL configuration
    +    ssl_protocols TLSv1.2 TLSv1.3;
    +    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    +    ssl_prefer_server_ciphers off;
    +    ssl_session_cache shared:SSL:10m;
    +    ssl_session_timeout 10m;
    +
    +    # HSTS (HTTP Strict Transport Security)
    +    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    +
    +    # Security headers
    +    add_header X-Frame-Options "DENY" always;
    +    add_header X-Content-Type-Options "nosniff" always;
    +    add_header X-XSS-Protection "1; mode=block" always;
    +    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    +
    +    # Proxy settings
    +    location / {
    +        proxy_pass http://dhamps_backend;
    +        proxy_http_version 1.1;
    +        
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Real-IP $remote_addr;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_set_header X-Forwarded-Proto $scheme;
    +        proxy_set_header Connection "";
    +        
    +        # Timeouts
    +        proxy_connect_timeout 60s;
    +        proxy_send_timeout 60s;
    +        proxy_read_timeout 60s;
    +        
    +        # Buffer settings
    +        proxy_buffering on;
    +        proxy_buffer_size 4k;
    +        proxy_buffers 8 4k;
    +    }
    +
    +    # Rate limiting (optional, see below)
    +    limit_req zone=api_limit burst=20 nodelay;
    +    limit_req_status 429;
    +}

    Enable site and get certificate:

    sudo ln -s /etc/nginx/sites-available/dhamps-vdb /etc/nginx/sites-enabled/
    +sudo certbot --nginx -d api.example.com
    +sudo systemctl reload nginx

    Auto-renewal:

    # Certbot creates a systemd timer automatically
    +sudo systemctl status certbot.timer
    +
    +# Test renewal
    +sudo certbot renew --dry-run

    Traefik (Docker)#

    docker-compose.yml:

    version: '3.8'
    +
    +services:
    +  traefik:
    +    image: traefik:v2.10
    +    command:
    +      - "--providers.docker=true"
    +      - "--entrypoints.web.address=:80"
    +      - "--entrypoints.websecure.address=:443"
    +      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
    +      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    +      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    +    ports:
    +      - "80:80"
    +      - "443:443"
    +    volumes:
    +      - /var/run/docker.sock:/var/run/docker.sock:ro
    +      - ./letsencrypt:/letsencrypt
    +
    +  dhamps-vdb:
    +    build: .
    +    labels:
    +      - "traefik.enable=true"
    +      - "traefik.http.routers.dhamps-vdb.rule=Host(`api.example.com`)"
    +      - "traefik.http.routers.dhamps-vdb.entrypoints=websecure"
    +      - "traefik.http.routers.dhamps-vdb.tls.certresolver=letsencrypt"
    +      # Redirect HTTP to HTTPS
    +      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
    +      - "traefik.http.routers.dhamps-vdb-http.rule=Host(`api.example.com`)"
    +      - "traefik.http.routers.dhamps-vdb-http.entrypoints=web"
    +      - "traefik.http.routers.dhamps-vdb-http.middlewares=redirect-to-https"

    Caddy (Automatic HTTPS)#

    Caddyfile:

    api.example.com {
    +    reverse_proxy localhost:8880
    +    
    +    # Automatic HTTPS via Let's Encrypt
    +    tls admin@example.com
    +    
    +    # Security headers
    +    header {
    +        Strict-Transport-Security "max-age=31536000; includeSubDomains"
    +        X-Frame-Options "DENY"
    +        X-Content-Type-Options "nosniff"
    +        X-XSS-Protection "1; mode=block"
    +    }
    +}

    API Key Management#

    Admin Key Security#

    The SERVICE_ADMINKEY has full control over the system.

    Best practices:

    1. Generate securely:

      openssl rand -base64 32
    2. Store securely:

      • Password manager (1Password, Bitwarden)
      • Secrets manager (Vault, AWS Secrets Manager)
      • Never in version control
      • Never in logs or error messages
    3. Rotate regularly:

      • Every 90 days minimum
      • After team member departure
      • After suspected compromise
    4. Audit usage:

      • Log all admin operations
      • Monitor for unusual activity
      • Review regularly

    User API Keys#

    User API keys are automatically generated and encrypted before database storage.

    Security features:

    • One-time display: Keys shown only at creation
    • Encrypted storage: AES-256-GCM encryption
    • Non-recoverable: Lost keys cannot be retrieved

    For users:

    1. Secure storage:

      • Use environment variables
      • Never hardcode in applications
      • Never commit to repositories
    2. Use HTTPS:

      • Always transmit over TLS
      • Validate server certificates
    3. Rotate if compromised:

      • Delete old user and create new one
      • Update all client applications

    Bearer Token Authentication#

    All API requests require authentication:

    curl -X GET https://api.example.com/v1/projects/alice \
    +  -H "Authorization: Bearer your-api-key-here"

    Security:

    • Use Authorization header (not query parameters)
    • Never log full API keys
    • Validate on every request
    • Use HTTPS to prevent interception

    Encryption Key Security#

    The ENCRYPTION_KEY protects all user API keys in the database.

    Critical Security Points#

    ⚠️ CRITICAL: If the encryption key is lost or changed, all user API keys become permanently unrecoverable.

    Best practices:

    1. Generate securely:

      openssl rand -hex 32
    2. Backup separately:

      • Store in multiple secure locations
      • Separate from database backups
      • Document recovery procedure
      • Test recovery process
    3. Never rotate in production:

      • Cannot be changed without re-encrypting all keys
      • Requires database migration
      • Risk of data loss
    4. Protect at rest:

      • Encrypt .env files: gpg --encrypt .env
      • Use secrets management (Vault, AWS Secrets Manager)
      • Restrict file permissions: chmod 600 .env
    5. Protect in transit:

      • Never send over unencrypted channels
      • Use secure channels for team sharing
      • Avoid email/chat

    Encryption Details#

    • Algorithm: AES-256-GCM
    • Key derivation: SHA-256 hash of input key
    • Nonce: Unique per encryption
    • Authentication: GCM provides authentication
    • Storage format: Base64-encoded ciphertext

    Disaster Recovery#

    Document and test recovery procedure:

    ## Encryption Key Recovery Procedure
    +
    +1. Retrieve backup encryption key from [location]
    +2. Verify key integrity: [checksum/hash]
    +3. Update deployment configuration
    +4. Restart services
    +5. Verify user authentication works
    +6. Document incident

    Database Security#

    Network Security#

    1. Restrict access:

      -- In pg_hba.conf
      +# Allow only from application server
      +host    dhamps_vdb    dhamps_user    10.0.1.0/24    md5
    2. Firewall rules:

      # UFW example
      +sudo ufw allow from 10.0.1.0/24 to any port 5432
      +sudo ufw deny 5432
    3. Use VPC/private network:

      • Keep database on private network
      • No public internet exposure
      • VPN for remote administration

    Database Authentication#

    1. Strong passwords:

      # Generate secure password
      +openssl rand -base64 32
    2. Dedicated user:

      -- Not superuser
      +CREATE USER dhamps_user WITH PASSWORD 'secure_password';
      +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    3. SSL/TLS connections:

      # postgresql.conf
      +ssl = on
      +ssl_cert_file = 'server.crt'
      +ssl_key_file = 'server.key'
      +ssl_ca_file = 'ca.crt'

    Database Encryption#

    1. Encryption at rest:

      • Use encrypted filesystems (LUKS, dm-crypt)
      • Cloud provider encryption (AWS RDS encryption)
      • Transparent Data Encryption (TDE)
    2. Backup encryption:

      # Encrypt backup
      +pg_dump -U postgres dhamps_vdb | gzip | \
      +  gpg --encrypt --recipient admin@example.com > backup.sql.gz.gpg

    Database Auditing#

    Enable audit logging:

    -- Install pgaudit
    +CREATE EXTENSION pgaudit;
    +
    +-- Configure logging
    +ALTER SYSTEM SET pgaudit.log = 'write, ddl';
    +ALTER SYSTEM SET pgaudit.log_catalog = off;
    +ALTER SYSTEM SET pgaudit.log_parameter = on;
    +
    +-- Reload config
    +SELECT pg_reload_conf();

    Network Security#

    Firewall Configuration#

    # UFW example
    +sudo ufw default deny incoming
    +sudo ufw default allow outgoing
    +
    +# Allow SSH
    +sudo ufw allow 22/tcp
    +
    +# Allow HTTP/HTTPS (reverse proxy)
    +sudo ufw allow 80/tcp
    +sudo ufw allow 443/tcp
    +
    +# Application port (if not behind proxy)
    +# sudo ufw allow from trusted_network to any port 8880
    +
    +# Database (from app server only)
    +sudo ufw allow from 10.0.1.0/24 to any port 5432
    +
    +sudo ufw enable

    Network Segmentation#

    Deploy in isolated networks:

    Internet
    +    ↓
    +[Reverse Proxy] ← (DMZ/Public subnet)
    +    ↓
    +[dhamps-vdb]    ← (Application subnet)
    +    ↓
    +[PostgreSQL]    ← (Database subnet)

    Rate Limiting#

    Protect against abuse and DoS attacks.

    Nginx:

    # Define rate limit zone
    +http {
    +    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    +    limit_req_zone $binary_remote_addr zone=api_burst:10m rate=100r/s;
    +}
    +
    +server {
    +    location /v1/ {
    +        limit_req zone=api_limit burst=20 nodelay;
    +        limit_req_status 429;
    +        proxy_pass http://dhamps_backend;
    +    }
    +}

    Application-level (future enhancement):

    • Implement token bucket or leaky bucket
    • Per-user rate limits
    • Different limits for different endpoints

    Backup Strategies#

    Database Backups#

    1. Automated daily backups:

      #!/bin/bash
      +# /usr/local/bin/backup-dhamps.sh
      +
      +DATE=$(date +%Y%m%d_%H%M%S)
      +BACKUP_DIR="/backups/dhamps-vdb"
      +
      +# Create backup
      +pg_dump -U dhamps_user dhamps_vdb | gzip > \
      +  "$BACKUP_DIR/db-$DATE.sql.gz"
      +
      +# Encrypt backup
      +gpg --encrypt --recipient admin@example.com \
      +  "$BACKUP_DIR/db-$DATE.sql.gz"
      +
      +# Remove unencrypted backup
      +rm "$BACKUP_DIR/db-$DATE.sql.gz"
      +
      +# Verify backup
      +gpg --decrypt "$BACKUP_DIR/db-$DATE.sql.gz.gpg" | gunzip | head -n 5
      +
      +# Upload to offsite storage
      +aws s3 cp "$BACKUP_DIR/db-$DATE.sql.gz.gpg" \
      +  s3://backups/dhamps-vdb/ --storage-class GLACIER
      +
      +# Cleanup old local backups (keep 7 days)
      +find $BACKUP_DIR -name "db-*.sql.gz.gpg" -mtime +7 -delete
    2. Cron schedule:

      0 2 * * * /usr/local/bin/backup-dhamps.sh
    3. Test restores regularly:

      # Monthly restore test
      +0 3 1 * * /usr/local/bin/test-restore.sh

    Configuration Backups#

    # Backup environment configuration
    +cp .env .env.backup
    +gpg --encrypt --recipient admin@example.com .env.backup
    +
    +# Backup with timestamp
    +tar czf config-$(date +%Y%m%d).tar.gz .env docker-compose.yml
    +gpg --encrypt --recipient admin@example.com config-*.tar.gz

    Backup Retention Policy#

    • Daily backups: Keep 7 days locally
    • Weekly backups: Keep 4 weeks offsite
    • Monthly backups: Keep 12 months in cold storage
    • Yearly backups: Keep 7 years (compliance dependent)

    Offsite Backups#

    Always maintain offsite backups:

    • Cloud storage: AWS S3, Azure Blob Storage, GCP Cloud Storage
    • Different geographic region
    • Encrypted before upload
    • Test restoration procedures

    Monitoring and Alerting#

    What to Monitor#

    1. Authentication failures:

      # Parse logs for 401 responses
      +grep "401" /var/log/nginx/access.log | wc -l
    2. Unusual API usage:

      • Spike in requests
      • Requests to non-existent endpoints
      • Large data transfers
    3. Database health:

      • Connection count
      • Query performance
      • Disk usage
      • Replication lag (if applicable)
    4. System resources:

      • CPU usage
      • Memory usage
      • Disk I/O
      • Network throughput

    Log Management#

    1. Centralized logging:

      • ELK Stack (Elasticsearch, Logstash, Kibana)
      • Splunk
      • Graylog
      • CloudWatch Logs (AWS)
    2. Log retention:

      • Application logs: 30 days minimum
      • Access logs: 90 days minimum
      • Audit logs: 1 year minimum (compliance dependent)
    3. Log security:

      • Never log API keys in full (mask: api_key=abc...xyz)
      • Never log passwords
      • Encrypt archived logs
      • Restrict access to logs

    Alerting#

    Set up alerts for:

    • Failed authentication attempts (>10/minute)
    • Database connection failures
    • Disk space >80% full
    • Service downtime
    • Unusual network traffic
    • SSL certificate expiration (30 days before)

    Security Checklist#

    Use this checklist for production deployments:

    Pre-Deployment#

    • Strong, random SERVICE_ADMINKEY generated
    • Strong, random ENCRYPTION_KEY generated (32+ chars)
    • Strong database password set
    • .env file encrypted or in secrets manager
    • .env not in version control
    • Encryption key backed up separately from database

    Network & Access#

    • HTTPS/TLS configured with valid certificate
    • Reverse proxy deployed (nginx/Traefik/Caddy)
    • Firewall configured and enabled
    • Database on private network only
    • Rate limiting configured
    • HSTS header enabled
    • Security headers configured

    Database#

    • PostgreSQL 11+ with pgvector installed
    • Dedicated database user (not superuser)
    • Strong database password
    • SSL/TLS for database connections
    • Database firewall rules configured
    • pg_hba.conf restricts access by IP
    • Regular backups configured
    • Backup encryption enabled
    • Restore procedure tested

    Application#

    • Service runs as non-root user
    • Debug logging disabled (SERVICE_DEBUG=false)
    • Resource limits configured
    • Health checks enabled
    • Logging configured
    • Monitoring configured
    • Alerting configured

    Operations#

    • Backup procedure documented
    • Restore procedure documented and tested
    • Disaster recovery plan created
    • Security incident response plan created
    • Key rotation schedule defined
    • Access control documented (who has admin key)
    • Regular security updates scheduled

    Compliance#

    • Data retention policy defined
    • Privacy policy reviewed
    • Terms of service reviewed
    • GDPR compliance (if applicable)
    • Data processing agreements in place
    • Audit logging enabled

    Incident Response#

    Suspected API Key Compromise#

    1. Immediate actions:

      • Identify compromised user
      • Delete user (invalidates API key)
      • Create new user with new API key
      • Review access logs for unauthorized access
    2. Investigation:

      • Determine scope of compromise
      • Check for data exfiltration
      • Document incident
    3. Notification:

      • Notify affected parties (if required)
      • Document lessons learned
      • Update security procedures

    Database Breach#

    1. Immediate actions:

      • Isolate database server
      • Revoke network access
      • Change all database credentials
      • Activate incident response team
    2. Assessment:

      • Determine data accessed
      • Check encryption effectiveness
      • Review audit logs
    3. Recovery:

      • Restore from clean backup
      • Apply security patches
      • Update firewall rules
      • Notify affected parties (if required)
      • Document and learn

    Encryption Key Loss#

    ⚠️ CRITICAL SITUATION: If encryption key is lost, all user API keys are unrecoverable.

    1. Recovery attempt:

      • Check all backup locations
      • Review documentation
      • Contact all team members
    2. If unrecoverable:

      • All users must be deleted and recreated
      • New API keys issued to all users
      • All client applications must be updated
      • Communicate timeline to users
    3. Prevention:

      • Review backup procedures
      • Add redundant backup locations
      • Document key locations
      • Test recovery process

    Security Updates#

    Regular Updates#

    • Weekly: Review security advisories
    • Monthly: Apply security patches
    • Quarterly: Security audit and penetration testing
    • Yearly: Full security review and compliance audit

    Update Procedure#

    1. Test in staging environment
    2. Backup production database and configuration
    3. Schedule maintenance window
    4. Apply updates
    5. Verify functionality
    6. Monitor for issues

    Subscribe to Security Advisories#

    • PostgreSQL security announcements
    • pgvector security updates
    • Docker security advisories
    • Go security advisories
    • Operating system security updates

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/development/architecture/index.html b/docs/public/development/architecture/index.html new file mode 100644 index 0000000..eb22de4 --- /dev/null +++ b/docs/public/development/architecture/index.html @@ -0,0 +1,547 @@ +Architecture | dhamps-vdb Documentation + +

    Technical Architecture#

    This document provides a technical deep-dive into dhamps-vdb’s architecture for developers who want to understand or modify the codebase.

    Project Structure#

    dhamps-vdb/
    +├── main.go                        # Application entry point
    +├── go.mod                         # Go module definition
    +├── go.sum                         # Dependency checksums
    +├── sqlc.yaml                      # sqlc configuration
    +├── template.env                   # Environment template
    +├── .env                           # Local config (gitignored)
    +│
    +├── api/
    +│   └── openapi.yml                # OpenAPI spec (not actively maintained)
    +│
    +├── internal/                      # Internal packages (non-importable)
    +│   ├── auth/                      # Authentication logic
    +│   │   └── authenticate.go        # Bearer token validation
    +│   │
    +│   ├── crypto/                    # Encryption utilities
    +│   │   └── crypto.go              # AES-256-GCM encryption
    +│   │
    +│   ├── database/                  # Database layer
    +│   │   ├── database.go            # Connection pool management
    +│   │   ├── migrations.go          # Migration runner
    +│   │   ├── db.go                  # Generated by sqlc
    +│   │   ├── models.go              # Generated by sqlc
    +│   │   ├── queries.sql.go         # Generated by sqlc
    +│   │   │
    +│   │   ├── migrations/            # SQL migrations
    +│   │   │   ├── 001_create_initial_scheme.sql
    +│   │   │   ├── 002_create_emb_index.sql
    +│   │   │   ├── 003_add_public_read_flag.sql
    +│   │   │   ├── 004_refactor_llm_services_architecture.sql
    +│   │   │   ├── tern.conf.tpl      # Template for tern
    +│   │   │   └── tern.conf          # Generated (gitignored)
    +│   │   │
    +│   │   └── queries/               # SQL queries for sqlc
    +│   │       └── queries.sql        # All database queries
    +│   │
    +│   ├── handlers/                  # HTTP request handlers
    +│   │   ├── handlers.go            # Common handler utilities
    +│   │   ├── users.go               # User endpoints
    +│   │   ├── projects.go            # Project endpoints
    +│   │   ├── llm_services.go        # LLM service endpoints
    +│   │   ├── api_standards.go       # API standard endpoints
    +│   │   ├── embeddings.go          # Embedding endpoints
    +│   │   ├── similars.go            # Similarity search endpoints
    +│   │   ├── admin.go               # Admin endpoints
    +│   │   │
    +│   │   └── *_test.go              # Test files
    +│   │       ├── users_test.go
    +│   │       ├── projects_test.go
    +│   │       ├── projects_sharing_test.go
    +│   │       ├── embeddings_test.go
    +│   │       ├── llm_services_test.go
    +│   │       ├── editor_permissions_test.go
    +│   │       └── handlers_test.go
    +│   │
    +│   └── models/                    # Data models and options
    +│       ├── options.go             # CLI/environment options
    +│       ├── users.go               # User models
    +│       ├── projects.go            # Project models
    +│       ├── instances.go           # LLM instance models (new)
    +│       ├── api_standards.go       # API standard models
    +│       ├── embeddings.go          # Embedding models
    +│       ├── similars.go            # Similarity search models
    +│       └── admin.go               # Admin operation models
    +│
    +├── testdata/                      # Test fixtures
    +│   ├── postgres/                  # PostgreSQL test data
    +│   │   ├── enable-vector.sql
    +│   │   └── users.yml
    +│   │
    +│   └── *.json                     # JSON test fixtures
    +│       ├── valid_user.json
    +│       ├── valid_embeddings.json
    +│       ├── valid_api_standard_*.json
    +│       └── valid_llm_service_*.json
    +│
    +└── docs/                          # Documentation
    +    ├── content/                   # Hugo content
    +    └── *.md                       # Additional docs

    Code Organization#

    1. Entry Point (main.go)#

    The application entry point handles:

    func main() {
    +	// 1. Parse CLI options and environment variables
    +	cli := huma.NewCLI(func(hooks huma.Hooks, opts *models.Options) {
    +		
    +		// 2. Initialize database connection pool
    +		pool := database.InitDB(opts)
    +		defer pool.Close()
    +		
    +		// 3. Run database migrations
    +		database.RunMigrations(pool, opts)
    +		
    +		// 4. Create HTTP router and Huma API
    +		router := http.NewServeMux()
    +		api := humago.New(router, huma.DefaultConfig("dhamps-vdb", "0.1.0"))
    +		
    +		// 5. Register all routes
    +		handlers.AddRoutes(pool, keyGen, api)
    +		
    +		// 6. Start HTTP server
    +		server := &http.Server{
    +			Addr:    fmt.Sprintf("%s:%d", opts.Host, opts.Port),
    +			Handler: router,
    +		}
    +		server.ListenAndServe()
    +	})
    +	
    +	cli.Run()
    +}

    2. Handlers (internal/handlers/)#

    Handlers process HTTP requests using the Huma framework pattern:

    // Example: Create User Handler
    +func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) {
    +	
    +	// Define request/response types
    +	type CreateUserInput struct {
    +		Body models.CreateUserRequest
    +	}
    +	
    +	type CreateUserOutput struct {
    +		Body models.User
    +	}
    +	
    +	// Register operation with Huma
    +	huma.Register(api, huma.Operation{
    +		OperationID: "create-user",
    +		Method:      http.MethodPost,
    +		Path:        "/v1/users",
    +		Summary:     "Create a new user",
    +		Description: "Admin only. Creates user and returns API key.",
    +		Security:    []map[string][]string{{"bearer": {}}},
    +	}, func(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) {
    +		
    +		// 1. Get authenticated user from context
    +		authUser := auth.GetAuthenticatedUser(ctx)
    +		
    +		// 2. Check authorization (admin only)
    +		if !authUser.IsAdmin {
    +			return nil, huma.Error403Forbidden("admin access required")
    +		}
    +		
    +		// 3. Validate input
    +		if err := input.Body.Validate(); err != nil {
    +			return nil, huma.Error400BadRequest("invalid input", err)
    +		}
    +		
    +		// 4. Business logic
    +		user, apiKey, err := createUserWithKey(ctx, pool, keyGen, &input.Body)
    +		if err != nil {
    +			return nil, handleDatabaseError(err)
    +		}
    +		
    +		// 5. Return response
    +		return &CreateUserOutput{Body: *user}, nil
    +	})
    +}

    Handler file organization:

    • handlers.go - Common utilities (context keys, error handling)
    • users.go - User CRUD operations
    • projects.go - Project CRUD and sharing
    • llm_services.go - LLM service/instance management
    • embeddings.go - Embedding CRUD operations
    • similars.go - Similarity search
    • admin.go - Administrative operations

    3. Models (internal/models/)#

    Models define request/response structures:

    // User model
    +type User struct {
    +	UserHandle string    `json:"user_handle" example:"alice"`
    +	Name       string    `json:"name" example:"Alice Smith"`
    +	Email      string    `json:"email" example:"alice@example.com"`
    +	CreatedAt  time.Time `json:"created_at"`
    +	UpdatedAt  time.Time `json:"updated_at"`
    +}
    +
    +// Request model with validation
    +type CreateUserRequest struct {
    +	UserHandle string `json:"user_handle" minLength:"1" maxLength:"50" pattern:"^[a-z0-9_-]+$"`
    +	Name       string `json:"name" minLength:"1" maxLength:"100"`
    +	Email      string `json:"email" format:"email"`
    +}
    +
    +func (r *CreateUserRequest) Validate() error {
    +	if r.UserHandle == "" {
    +		return fmt.Errorf("user_handle is required")
    +	}
    +	if r.UserHandle == "_system" {
    +		return fmt.Errorf("_system is a reserved handle")
    +	}
    +	return nil
    +}

    Model conventions:

    • Request models: Create*Request, Update*Request
    • Response models: *Response, *Output
    • Database models: Match database schema (generated by sqlc)

    4. Database Layer (internal/database/)#

    Connection Management (database.go)#

    func InitDB(opts *models.Options) *pgxpool.Pool {
    +	connString := fmt.Sprintf(
    +		"postgres://%s:%s@%s:%d/%s",
    +		opts.DBUser, opts.DBPassword, 
    +		opts.DBHost, opts.DBPort, opts.DBName,
    +	)
    +	
    +	config, err := pgxpool.ParseConfig(connString)
    +	if err != nil {
    +		log.Fatal(err)
    +	}
    +	
    +	// Configure connection pool
    +	config.MaxConns = 20
    +	config.MinConns = 5
    +	config.MaxConnIdleTime = time.Minute * 5
    +	
    +	pool, err := pgxpool.NewWithConfig(context.Background(), config)
    +	if err != nil {
    +		log.Fatal(err)
    +	}
    +	
    +	return pool
    +}

    Migrations (migrations.go)#

    Uses tern for versioned migrations:

    func RunMigrations(pool *pgxpool.Pool, opts *models.Options) error {
    +	// Create tern configuration
    +	config := createTernConfig(opts)
    +	
    +	// Initialize migrator
    +	migrator, err := migrate.NewMigrator(context.Background(), pool, "schema_version")
    +	if err != nil {
    +		return err
    +	}
    +	
    +	// Run pending migrations
    +	err = migrator.Migrate(context.Background())
    +	if err != nil {
    +		return fmt.Errorf("migration failed: %w", err)
    +	}
    +	
    +	return nil
    +}

    Migration files are numbered sequentially:

    -- 001_create_initial_scheme.sql
    +CREATE TABLE users (
    +    user_id SERIAL PRIMARY KEY,
    +    user_handle TEXT UNIQUE NOT NULL,
    +    vdb_key TEXT UNIQUE NOT NULL,
    +    ...
    +);
    +
    +CREATE TABLE projects (
    +    project_id SERIAL PRIMARY KEY,
    +    project_handle TEXT NOT NULL,
    +    owner TEXT NOT NULL REFERENCES users(user_handle),
    +    ...
    +);
    +
    +-- 002_create_emb_index.sql  
    +CREATE INDEX embedding_vector_idx 
    +ON embeddings 
    +USING hnsw (vector vector_cosine_ops);

    SQLC Queries (queries/queries.sql)#

    Write SQL, generate type-safe Go code:

    -- name: UpsertUser :one
    +INSERT INTO users (
    +  user_handle, name, email, vdb_key, created_at, updated_at
    +) VALUES (
    +  $1, $2, $3, $4, NOW(), NOW()
    +)
    +ON CONFLICT (user_handle) DO UPDATE SET
    +  name = EXCLUDED.name,
    +  email = EXCLUDED.email,
    +  updated_at = NOW()
    +RETURNING *;
    +
    +-- name: GetUserByHandle :one
    +SELECT * FROM users WHERE user_handle = $1;
    +
    +-- name: GetAllUsers :many
    +SELECT user_handle, name, email, created_at, updated_at 
    +FROM users 
    +ORDER BY user_handle ASC;
    +
    +-- name: DeleteUser :exec
    +DELETE FROM users WHERE user_handle = $1;

    Generated Go code (queries.sql.go):

    // Generated by sqlc
    +func (q *Queries) UpsertUser(ctx context.Context, arg UpsertUserParams) (User, error) {
    +	row := q.db.QueryRow(ctx, upsertUser,
    +		arg.UserHandle,
    +		arg.Name,
    +		arg.Email,
    +		arg.VdbKey,
    +	)
    +	var i User
    +	err := row.Scan(
    +		&i.UserID,
    +		&i.UserHandle,
    +		&i.Name,
    +		&i.Email,
    +		&i.VdbKey,
    +		&i.CreatedAt,
    +		&i.UpdatedAt,
    +	)
    +	return i, err
    +}

    sqlc configuration (sqlc.yaml):

    version: "2"
    +sql:
    +  - engine: "postgresql"
    +    queries: "internal/database/queries/queries.sql"
    +    schema: "internal/database/migrations/"
    +    gen:
    +      go:
    +        package: "database"
    +        out: "internal/database"
    +        emit_json_tags: true
    +        emit_db_tags: true
    +        emit_prepared_queries: false
    +        emit_interface: false

    Regenerate code after query changes:

    sqlc generate --no-remote

    5. Authentication (internal/auth/)#

    Token-based authentication using Bearer tokens:

    // Middleware checks Authorization header
    +func AuthMiddleware(pool *pgxpool.Pool, adminKey string) func(http.Handler) http.Handler {
    +	return func(next http.Handler) http.Handler {
    +		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    +			
    +			// Extract Bearer token
    +			authHeader := r.Header.Get("Authorization")
    +			token := strings.TrimPrefix(authHeader, "Bearer ")
    +			
    +			if token == "" {
    +				// Allow public access for certain endpoints
    +				ctx := context.WithValue(r.Context(), "user", nil)
    +				next.ServeHTTP(w, r.WithContext(ctx))
    +				return
    +			}
    +			
    +			// Check admin key
    +			if token == adminKey {
    +				user := &AuthUser{Handle: "_admin", IsAdmin: true}
    +				ctx := context.WithValue(r.Context(), "user", user)
    +				next.ServeHTTP(w, r.WithContext(ctx))
    +				return
    +			}
    +			
    +			// Look up user by API key hash
    +			hash := hashAPIKey(token)
    +			user, err := db.GetUserByKeyHash(r.Context(), pool, hash)
    +			if err != nil {
    +				http.Error(w, "Unauthorized", http.StatusUnauthorized)
    +				return
    +			}
    +			
    +			authUser := &AuthUser{Handle: user.UserHandle, IsAdmin: false}
    +			ctx := context.WithValue(r.Context(), "user", authUser)
    +			next.ServeHTTP(w, r.WithContext(ctx))
    +		})
    +	}
    +}
    +
    +// Helper to get authenticated user from context
    +func GetAuthenticatedUser(ctx context.Context) *AuthUser {
    +	user, _ := ctx.Value("user").(*AuthUser)
    +	return user
    +}

    6. Encryption (internal/crypto/)#

    AES-256-GCM encryption for sensitive data (API keys):

    // Encrypt data with AES-256-GCM
    +func Encrypt(plaintext []byte, key []byte) ([]byte, error) {
    +	// Ensure key is 32 bytes
    +	keyHash := sha256.Sum256(key)
    +	
    +	// Create AES cipher
    +	block, err := aes.NewCipher(keyHash[:])
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	// Create GCM
    +	gcm, err := cipher.NewGCM(block)
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	// Generate random nonce
    +	nonce := make([]byte, gcm.NonceSize())
    +	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
    +		return nil, err
    +	}
    +	
    +	// Encrypt and append nonce
    +	ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
    +	return ciphertext, nil
    +}
    +
    +func Decrypt(ciphertext []byte, key []byte) ([]byte, error) {
    +	// Derive key
    +	keyHash := sha256.Sum256(key)
    +	
    +	block, err := aes.NewCipher(keyHash[:])
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	gcm, err := cipher.NewGCM(block)
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	// Extract nonce
    +	nonceSize := gcm.NonceSize()
    +	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    +	
    +	// Decrypt
    +	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	return plaintext, nil
    +}

    Huma Framework Integration#

    dhamps-vdb uses Huma for API development:

    Benefits#

    1. Automatic OpenAPI generation - No manual spec maintenance
    2. Request/response validation - Type-safe with JSON schema
    3. Error handling - Standardized error responses
    4. Documentation - Interactive docs at /docs

    Operation Registration Pattern#

    huma.Register(api, huma.Operation{
    +	OperationID:   "get-project",
    +	Method:        http.MethodGet,
    +	Path:          "/v1/projects/{owner}/{project}",
    +	Summary:       "Get project details",
    +	Description:   "Returns full project information including metadata schema",
    +	Tags:          []string{"Projects"},
    +	Security:      []map[string][]string{{"bearer": {}}},
    +	MaxBodyBytes:  1024,  // Limit request size
    +	DefaultStatus: http.StatusOK,
    +	Errors:        []int{400, 401, 403, 404, 500},
    +}, handlerFunction)

    Input/Output Patterns#

    // Path parameters, query parameters, and body
    +type GetSimilarInput struct {
    +	Owner     string  `path:"owner" doc:"Project owner"`
    +	Project   string  `path:"project" doc:"Project handle"`
    +	TextID    string  `path:"text_id" doc:"Text identifier"`
    +	Threshold float32 `query:"threshold" default:"0.5" doc:"Similarity threshold"`
    +	Limit     int     `query:"limit" default:"10" maximum:"200" doc:"Max results"`
    +}
    +
    +// Response with status code
    +type GetSimilarOutput struct {
    +	Status int
    +	Body   models.SimilarResponse
    +}

    Error Response Pattern#

    // Standard error responses
    +return nil, huma.Error400BadRequest("validation failed", err)
    +return nil, huma.Error401Unauthorized("invalid credentials")
    +return nil, huma.Error403Forbidden("insufficient permissions")
    +return nil, huma.Error404NotFound("project not found")
    +return nil, huma.Error500InternalServerError("database error", err)
    +
    +// Custom error with details
    +return nil, huma.NewError(400, "Dimension Mismatch", 
    +	fmt.Sprintf("expected %d dimensions, got %d", expected, actual))

    Design Patterns#

    1. Repository Pattern (via sqlc)#

    Database access is centralized in generated queries:

    // Don't write SQL in handlers
    +// Bad:
    +rows, err := pool.Query(ctx, "SELECT * FROM users")
    +
    +// Good: Use generated functions
    +users, err := db.GetAllUsers(ctx)

    2. Dependency Injection#

    Pass dependencies explicitly:

    // Inject pool into handlers
    +func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) {
    +	// Routes have access to pool
    +}
    +
    +// Store in context for handler access
    +ctx = context.WithValue(ctx, PoolKey, pool)

    3. Interface-Based Testing#

    Use interfaces for testability:

    // Production: Real random key generator
    +type StandardKeyGen struct{}
    +func (s StandardKeyGen) RandomKey(len int) (string, error) {
    +	b := make([]byte, len)
    +	_, err := rand.Read(b)
    +	return hex.EncodeToString(b), err
    +}
    +
    +// Testing: Deterministic key generator
    +type MockKeyGen struct {
    +	Keys []string
    +	idx  int
    +}
    +func (m *MockKeyGen) RandomKey(len int) (string, error) {
    +	key := m.Keys[m.idx]
    +	m.idx++
    +	return key, nil
    +}

    4. Validation at Multiple Layers#

    // 1. Huma validates request structure
    +type CreateEmbeddingInput struct {
    +	Body models.Embedding `maxLength:"1000000"`
    +}
    +
    +// 2. Model validates business rules
    +func (e *Embedding) Validate() error {
    +	if e.TextID == "" {
    +		return fmt.Errorf("text_id required")
    +	}
    +	return nil
    +}
    +
    +// 3. Handler validates against database state
    +func CreateEmbedding(ctx context.Context, input *CreateEmbeddingInput) error {
    +	// Check project exists
    +	// Validate dimensions match LLM service
    +	// Validate metadata against schema
    +	// Then insert
    +}

    5. Error Wrapping#

    Provide context while preserving original error:

    user, err := db.GetUserByHandle(ctx, handle)
    +if err != nil {
    +	if errors.Is(err, pgx.ErrNoRows) {
    +		return nil, huma.Error404NotFound("user not found")
    +	}
    +	return nil, fmt.Errorf("failed to retrieve user %s: %w", handle, err)
    +}

    Internal Packages#

    Go’s internal/ directory enforces package privacy:

    // This import works within dhamps-vdb
    +import "github.com/mpilhlt/dhamps-vdb/internal/database"
    +
    +// This import would FAIL from external projects
    +// Enforced by Go compiler

    Benefits:

    • Clear API boundaries
    • Implementation details hidden
    • Refactoring without breaking external users

    Performance Considerations#

    Connection Pooling#

    config.MaxConns = 20        // Max concurrent connections
    +config.MinConns = 5         // Keep-alive connections
    +config.MaxConnIdleTime = 5 * time.Minute

    Query Optimization#

    Use UNION ALL for better performance:

    // Instead of LEFT JOIN with OR conditions
    +query := `
    +	SELECT * FROM projects WHERE owner = $1
    +	UNION ALL
    +	SELECT p.* FROM projects p
    +	INNER JOIN projects_shared_with ps USING (project_id)
    +	WHERE ps.user_handle = $1
    +	ORDER BY owner, project_handle
    +`

    Index Strategy#

    -- Dimension filtering (very important)
    +CREATE INDEX ON embeddings(project_id, vector_dim);
    +
    +-- Vector similarity (HNSW for accuracy)
    +CREATE INDEX ON embeddings USING hnsw (vector vector_cosine_ops);
    +
    +-- Access lookups
    +CREATE INDEX ON projects_shared_with(user_handle);
    +CREATE INDEX ON projects(owner, project_handle);

    See Performance Guide for detailed optimization strategies.

    Testing Architecture#

    Test Organization#

    // handlers_test.go - Setup and utilities
    +func setupTestDB(t *testing.T) *pgxpool.Pool { }
    +func createTestUser(t *testing.T, pool *pgxpool.Pool) *models.User { }
    +
    +// users_test.go - User-specific tests
    +func TestCreateUser(t *testing.T) { }
    +func TestGetUser(t *testing.T) { }
    +
    +// projects_sharing_test.go - Sharing feature tests
    +func TestShareProject(t *testing.T) { }

    Testcontainers Integration#

    func setupTestDB(t *testing.T) *pgxpool.Pool {
    +	ctx := context.Background()
    +	
    +	// Start PostgreSQL with pgvector
    +	req := testcontainers.ContainerRequest{
    +		Image:        "pgvector/pgvector:0.7.4-pg16",
    +		ExposedPorts: []string{"5432/tcp"},
    +		Env: map[string]string{
    +			"POSTGRES_PASSWORD": "password",
    +			"POSTGRES_DB":       "testdb",
    +		},
    +	}
    +	
    +	container, err := testcontainers.GenericContainer(ctx, 
    +		testcontainers.GenericContainerRequest{
    +			ContainerRequest: req,
    +			Started:          true,
    +		})
    +	require.NoError(t, err)
    +	
    +	// Connect and migrate
    +	pool := connectAndMigrate(ctx, container)
    +	return pool
    +}

    See Testing Guide for comprehensive testing documentation.

    Build and Deployment#

    Building#

    # Development build
    +go build -o dhamps-vdb main.go
    +
    +# Production build with optimizations
    +go build -ldflags="-s -w" -o dhamps-vdb main.go
    +
    +# Cross-compilation
    +GOOS=linux GOARCH=amd64 go build -o dhamps-vdb-linux main.go

    Docker Build#

    Multi-stage build for minimal image:

    # Build stage
    +FROM golang:1.21-alpine AS builder
    +WORKDIR /app
    +COPY go.mod go.sum ./
    +RUN go mod download
    +COPY . .
    +RUN go build -ldflags="-s -w" -o dhamps-vdb main.go
    +
    +# Runtime stage
    +FROM alpine:latest
    +RUN apk --no-cache add ca-certificates
    +WORKDIR /root/
    +COPY --from=builder /app/dhamps-vdb .
    +EXPOSE 8880
    +CMD ["./dhamps-vdb"]

    Configuration#

    Application reads configuration from:

    1. Command line flags: --port 8080
    2. Environment variables: SERVICE_PORT=8080
    3. .env file: SERVICE_PORT=8080

    Priority: CLI flags > Environment > .env file > Defaults

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/development/contributing/index.html b/docs/public/development/contributing/index.html new file mode 100644 index 0000000..e09f09f --- /dev/null +++ b/docs/public/development/contributing/index.html @@ -0,0 +1,306 @@ +Contributing | dhamps-vdb Documentation + +

    Contributing Guide#

    Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.

    Development Setup#

    Prerequisites#

    • Go 1.21+: Download Go
    • PostgreSQL 16+: With pgvector extension
    • sqlc: For generating type-safe database code
    • Docker/Podman: For running tests
    • Git: For version control

    Clone and Build#

    # Clone repository
    +git clone https://github.com/mpilhlt/dhamps-vdb.git
    +cd dhamps-vdb
    +
    +# Install dependencies
    +go get ./...
    +
    +# Generate sqlc code
    +sqlc generate --no-remote
    +
    +# Build application
    +go build -o build/dhamps-vdb main.go
    +
    +# Or run directly
    +go run main.go

    Environment Setup#

    Create a .env file for local development:

    # Copy template
    +cp template.env .env
    +
    +# Edit with your settings
    +SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8880
    +SERVICE_ADMINKEY=your-secure-admin-key-here
    +
    +# Database settings
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=password
    +SERVICE_DBNAME=dhamps_vdb_dev
    +
    +# Encryption key (32+ characters)
    +ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars

    Important: Never commit .env files (already in .gitignore)

    Database Setup#

    For local development:

    # Start PostgreSQL with pgvector
    +podman run -p 5432:5432 \
    +  -e POSTGRES_PASSWORD=password \
    +  -e POSTGRES_DB=dhamps_vdb_dev \
    +  pgvector/pgvector:0.7.4-pg16
    +
    +# Or use docker-compose
    +docker-compose up -d
    +
    +# Application auto-migrates on startup
    +go run main.go

    Verify Setup#

    # Check application starts
    +go run main.go
    +
    +# In another terminal, test API
    +curl http://localhost:8880/docs
    +
    +# Run tests
    +go test -v ./...

    Code Style#

    Go Formatting#

    dhamps-vdb follows standard Go conventions:

    # Format all code
    +go fmt ./...
    +
    +# Check for common issues
    +go vet ./...
    +
    +# Run linter (if installed)
    +golangci-lint run

    Code Organization#

    Follow existing patterns:

    // Package comment at top of file
    +package handlers
    +
    +import (
    +	// Standard library first
    +	"context"
    +	"fmt"
    +	
    +	// External packages
    +	"github.com/danielgtaylor/huma/v2"
    +	"github.com/jackc/pgx/v5/pgxpool"
    +	
    +	// Internal packages
    +	"github.com/mpilhlt/dhamps-vdb/internal/database"
    +	"github.com/mpilhlt/dhamps-vdb/internal/models"
    +)
    +
    +// Exported function with doc comment
    +// GetUsers retrieves all users from the database
    +func GetUsers(ctx context.Context, pool *pgxpool.Pool) ([]models.User, error) {
    +	// Implementation
    +}

    Naming Conventions#

    Files:

    • handlers/users.go - Implementation
    • handlers/users_test.go - Tests
    • handlers/users_sharing_test.go - Specific feature tests

    Functions:

    • GetUsers() - List/retrieve multiple
    • GetUser() - Retrieve single
    • CreateUser() - Create new
    • UpdateUser() - Update existing
    • DeleteUser() - Delete
    • LinkUserToProject() - Create association
    • IsProjectOwner() - Boolean check

    Database Queries (in queries.sql):

    • -- name: GetAllUsers :many
    • -- name: RetrieveUserByHandle :one
    • -- name: UpsertUser :one
    • -- name: DeleteUser :exec

    Error Handling#

    // Return errors, don't panic
    +func CreateUser(ctx context.Context, pool *pgxpool.Pool, user models.User) error {
    +	if user.Handle == "" {
    +		return fmt.Errorf("user handle is required")
    +	}
    +	
    +	// Wrap errors with context
    +	err := db.InsertUser(ctx, user)
    +	if err != nil {
    +		return fmt.Errorf("failed to insert user: %w", err)
    +	}
    +	
    +	return nil
    +}
    +
    +// Use specific error responses in handlers
    +func handleCreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) {
    +	err := CreateUser(ctx, pool, input.Body)
    +	if err != nil {
    +		return nil, huma.Error400BadRequest("invalid user data", err)
    +	}
    +	
    +	return &CreateUserOutput{Body: result}, nil
    +}

    Comments#

    Comment public APIs and complex logic:

    // GetAccessibleProjects returns all projects the user can access.
    +// This includes projects owned by the user and projects shared with them.
    +// Results are paginated using limit and offset.
    +func GetAccessibleProjects(ctx context.Context, pool *pgxpool.Pool, 
    +	userHandle string, limit, offset int) ([]models.Project, error) {
    +	
    +	// Use UNION ALL for better query performance
    +	// See docs/PERFORMANCE_OPTIMIZATION.md for details
    +	query := `
    +		SELECT * FROM projects WHERE owner = $1
    +		UNION ALL
    +		SELECT p.* FROM projects p
    +		INNER JOIN projects_shared_with ps ON p.project_id = ps.project_id
    +		WHERE ps.user_handle = $1
    +	`
    +	
    +	// Implementation...
    +}

    Don’t over-comment obvious code:

    // Bad - obvious
    +// i is set to 0
    +i := 0
    +
    +// Good - explains why
    +// Start from second element (first is header)
    +i := 1

    Git Workflow#

    Branching Strategy#

    # Create feature branch from main
    +git checkout main
    +git pull origin main
    +git checkout -b feature/your-feature-name
    +
    +# Create fix branch
    +git checkout -b fix/issue-description
    +
    +# Create docs branch
    +git checkout -b docs/update-contributing-guide

    Branch naming:

    • feature/* - New features
    • fix/* - Bug fixes
    • docs/* - Documentation updates
    • test/* - Test improvements
    • refactor/* - Code refactoring

    Commit Messages#

    Write clear, descriptive commit messages:

    # Good commit messages
    +git commit -m "Add project sharing functionality"
    +git commit -m "Fix dimension validation for embeddings"
    +git commit -m "Update contributing guide with git workflow"
    +
    +# Multi-line for complex changes
    +git commit -m "Refactor similarity search query
    +
    +- Use UNION ALL for better performance
    +- Add dimension filtering to subqueries
    +- Update tests to verify performance improvement
    +
    +Closes #123"

    Commit message format:

    • First line: Brief summary (50 chars or less)
    • Blank line
    • Detailed explanation if needed
    • Reference issues: Closes #123 or Fixes #456

    Pull Request Process#

    1. Create feature branch

      git checkout -b feature/my-feature
    2. Make changes and commit

      git add .
      +git commit -m "Add feature description"
    3. Keep branch updated

      git fetch origin
      +git rebase origin/main
    4. Push to your fork

      git push origin feature/my-feature
    5. Create Pull Request

      • Go to GitHub repository
      • Click “New Pull Request”
      • Select your branch
      • Fill in PR template
    6. PR Review Process

      • Automated tests run
      • Code review by maintainers
      • Address feedback
      • Merge when approved

    PR Title Format#

    [Type] Brief description
    +
    +Examples:
    +[Feature] Add project ownership transfer
    +[Fix] Correct dimension validation in embeddings
    +[Docs] Update API documentation for similarity search
    +[Test] Add integration tests for sharing workflow
    +[Refactor] Simplify authentication middleware

    PR Description Template#

    ## Description
    +Brief description of changes
    +
    +## Motivation
    +Why is this change needed?
    +
    +## Changes
    +- Change 1
    +- Change 2
    +- Change 3
    +
    +## Testing
    +How was this tested?
    +- [ ] Unit tests pass
    +- [ ] Integration tests pass
    +- [ ] Manual testing performed
    +
    +## Related Issues
    +Closes #123
    +Relates to #456
    +
    +## Checklist
    +- [ ] Code follows style guidelines
    +- [ ] Tests added/updated
    +- [ ] Documentation updated
    +- [ ] No breaking changes (or clearly documented)

    Testing Requirements#

    All contributions must include tests:

    For New Features#

    // Add tests in same package
    +// File: handlers/projects.go
    +func CreateProject(...) { ... }
    +
    +// File: handlers/projects_test.go
    +func TestCreateProject(t *testing.T) {
    +	// Test happy path
    +	// Test error cases
    +	// Test edge cases
    +}

    For Bug Fixes#

    // Add regression test
    +func TestBugFix_Issue123(t *testing.T) {
    +	// Reproduce the bug
    +	// Verify it's fixed
    +}

    Test Coverage#

    Aim for reasonable coverage:

    # Check coverage
    +go test -cover ./...
    +
    +# Generate coverage report
    +go test -coverprofile=coverage.out ./...
    +go tool cover -html=coverage.out

    Target coverage: 70%+ for new code

    Running Tests#

    # Before submitting PR
    +go test -v ./...
    +
    +# With race detection
    +go test -race ./...
    +
    +# Specific package
    +go test -v ./internal/handlers

    See Testing Guide for detailed information.

    Documentation Updates#

    When to Update Docs#

    Update documentation for:

    • New features: Add usage examples
    • API changes: Update endpoint documentation
    • Breaking changes: Clearly document migration path
    • Configuration: New environment variables or options

    Documentation Structure#

    docs/content/
    +├── getting-started/     # Installation, quickstart
    +├── concepts/            # Core concepts
    +├── guides/              # How-to guides
    +├── api/                 # API reference
    +└── development/         # Development docs (this section)

    Adding Documentation#

    # Create new doc file
    +cd docs/content/guides
    +cat > new-guide.md <<EOF
    +---
    +title: "Your Guide Title"
    +weight: 5
    +---
    +
    +# Your Guide
    +
    +Content here...
    +EOF

    Hugo Front Matter#

    All docs need front matter:

    ---
    +title: "Page Title"
    +weight: 1          # Determines order in menu
    +draft: false       # Set true for work in progress
    +---

    Code Examples in Docs#

    Include working examples:

    ```bash
    +# Example command
    +curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer admin-key" \
    +  -d '{"user_handle":"alice"}'
    +```
    +
    +```go
    +// Example Go code
    +user := models.User{
    +	Handle: "alice",
    +	Name:   "Alice Smith",
    +}
    +err := CreateUser(ctx, pool, user)
    +```

    Issue Reporting#

    Before Creating an Issue#

    1. Search existing issues
    2. Check documentation
    3. Try latest version
    4. Prepare reproduction steps

    Bug Report Template#

    ## Bug Description
    +Clear description of the bug
    +
    +## Steps to Reproduce
    +1. Start application with these settings...
    +2. Send this request...
    +3. Observe error...
    +
    +## Expected Behavior
    +What should happen
    +
    +## Actual Behavior
    +What actually happens
    +
    +## Environment
    +- dhamps-vdb version: v0.1.0
    +- Go version: 1.21.5
    +- PostgreSQL version: 16.1
    +- OS: Ubuntu 22.04
    +
    +## Logs

    Relevant error logs here

    
    +## Additional Context
    +Any other relevant information

    Feature Request Template#

    ## Feature Description
    +Clear description of proposed feature
    +
    +## Use Case
    +Why is this needed? Who benefits?
    +
    +## Proposed Solution
    +How should it work?
    +
    +## Alternatives Considered
    +Other approaches you've thought about
    +
    +## Additional Context
    +Examples, mockups, related features

    Code Review Guidelines#

    For Reviewers#

    • Be constructive: Suggest improvements, don’t just criticize
    • Ask questions: “Could we handle this case?” vs “This is wrong”
    • Explain reasoning: Help author understand why
    • Approve when ready: Don’t be too pedantic on style

    For Authors#

    • Respond to feedback: Address all comments
    • Ask for clarification: If feedback unclear
    • Don’t take it personally: Focus on improving code
    • Update PR: Push changes after addressing feedback

    What Reviewers Check#

    • Code follows style guidelines
    • Tests are comprehensive
    • Documentation is updated
    • No obvious bugs or security issues
    • Error handling is appropriate
    • Performance considerations addressed
    • Breaking changes documented

    Release Process#

    Maintainers handle releases, but contributors should:

    1. Document breaking changes in PR description
    2. Update CHANGELOG if applicable
    3. Tag related issues with milestone

    Development Best Practices#

    1. Start Small#

    • Small PRs are easier to review
    • Focus on one feature/fix per PR
    • Break large changes into multiple PRs

    2. Write Tests First#

    // Write test first (TDD approach)
    +func TestNewFeature(t *testing.T) {
    +	// This will fail initially
    +	result := NewFeature()
    +	assert.Equal(t, expected, result)
    +}
    +
    +// Then implement
    +func NewFeature() Result {
    +	// Implementation
    +}

    3. Use Type Safety#

    // Generate type-safe queries with sqlc
    +// Edit: internal/database/queries/queries.sql
    +-- name: GetUserByHandle :one
    +SELECT * FROM users WHERE user_handle = $1;
    +
    +// Then regenerate
    +sqlc generate --no-remote
    +
    +// Use generated code
    +user, err := db.GetUserByHandle(ctx, handle)

    4. Handle Errors Properly#

    // Don't ignore errors
    +result, err := SomeFunction()
    +if err != nil {
    +	return fmt.Errorf("operation failed: %w", err)
    +}
    +
    +// Provide context
    +if err := ValidateInput(input); err != nil {
    +	return huma.Error400BadRequest("invalid input", err)
    +}

    5. Keep It Simple#

    • Prefer clarity over cleverness
    • Use standard library when possible
    • Don’t over-engineer solutions

    Getting Help#

    Resources#

    • Documentation: Browse /docs folder
    • API Docs: Run locally and visit /docs endpoint
    • Code Examples: Check testdata/ for examples
    • Test Files: See how features are tested

    Communication#

    • GitHub Issues: For bugs and feature requests
    • Pull Requests: For code discussions
    • Code Comments: For implementation questions

    Asking Questions#

    Good questions include:

    • What you’re trying to accomplish
    • What you’ve already tried
    • Relevant code snippets
    • Error messages (full stack trace)

    License#

    By contributing, you agree that your contributions will be licensed under the MIT License.

    Recognition#

    Contributors are acknowledged in:

    • Git commit history
    • GitHub contributors page
    • Release notes (for significant contributions)

    Thank you for contributing to dhamps-vdb! 🎉

    \ No newline at end of file diff --git a/docs/public/development/index.html b/docs/public/development/index.html new file mode 100644 index 0000000..fe982ac --- /dev/null +++ b/docs/public/development/index.html @@ -0,0 +1,17 @@ +Development | dhamps-vdb Documentation + +

    Development Guide#

    Information for developers contributing to dhamps-vdb.

    Getting Started with Development#

    This section covers:

    • Setting up a development environment
    • Running tests
    • Understanding the codebase architecture
    • Contributing guidelines
    • Performance optimization

    Project Structure#

    dhamps-vdb/
    +├── main.go                    # Application entry point
    +├── internal/
    +│   ├── auth/                  # Authentication logic
    +│   ├── database/              # Database layer (sqlc)
    +│   ├── handlers/              # HTTP handlers
    +│   └── models/                # Data models
    +├── testdata/                  # Test fixtures
    +└── docs/                      # Documentation

    Development Workflow#

    1. Make changes to code
    2. Generate sqlc code if database queries changed: sqlc generate
    3. Run tests: go test -v ./...
    4. Build: go build -o dhamps-vdb main.go
    5. Submit pull request

    Resources#

    \ No newline at end of file diff --git a/docs/public/development/index.xml b/docs/public/development/index.xml new file mode 100644 index 0000000..d77939e --- /dev/null +++ b/docs/public/development/index.xml @@ -0,0 +1,137 @@ +Development on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/development/Recent content in Development on dhamps-vdb DocumentationHugoen-usTestinghttps://mpilhlt.github.io/dhamps-vdb/development/testing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/testing/<h1 id="testing-guide">Testing Guide<a class="anchor" href="#testing-guide">#</a></h1> +<p>This guide covers how to run and write tests for dhamps-vdb.</p> +<h2 id="running-tests">Running Tests<a class="anchor" href="#running-tests">#</a></h2> +<p>dhamps-vdb uses integration tests that spin up real PostgreSQL containers using <a href="https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/">testcontainers</a>. This approach ensures tests run against actual database instances with pgvector support.</p> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<p><strong>Using Podman (Recommended for Linux):</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start podman socket</span> +</span></span><span style="display:flex;"><span>systemctl --user start podman.socket +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Export DOCKER_HOST for testcontainers</span> +</span></span><span style="display:flex;"><span>export DOCKER_HOST<span style="color:#f92672">=</span>unix://$XDG_RUNTIME_DIR/podman/podman.sock</span></span></code></pre></div><p><strong>Using Docker:</strong></p> +<p>Testcontainers works with Docker out of the box. Ensure Docker daemon is running.</p>Contributinghttps://mpilhlt.github.io/dhamps-vdb/development/contributing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/contributing/<h1 id="contributing-guide">Contributing Guide<a class="anchor" href="#contributing-guide">#</a></h1> +<p>Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.</p> +<h2 id="development-setup">Development Setup<a class="anchor" href="#development-setup">#</a></h2> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<ul> +<li><strong>Go 1.21+</strong>: <a href="https://go.dev/dl/">Download Go</a></li> +<li><strong>PostgreSQL 16+</strong>: With pgvector extension</li> +<li><strong>sqlc</strong>: For generating type-safe database code</li> +<li><strong>Docker/Podman</strong>: For running tests</li> +<li><strong>Git</strong>: For version control</li> +</ul> +<h3 id="clone-and-build">Clone and Build<a class="anchor" href="#clone-and-build">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies</span> +</span></span><span style="display:flex;"><span>go get ./... +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate sqlc code</span> +</span></span><span style="display:flex;"><span>sqlc generate --no-remote +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build application</span> +</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Or run directly</span> +</span></span><span style="display:flex;"><span>go run main.go</span></span></code></pre></div><h3 id="environment-setup">Environment Setup<a class="anchor" href="#environment-setup">#</a></h3> +<p>Create a <code>.env</code> file for local development:</p>Architecturehttps://mpilhlt.github.io/dhamps-vdb/development/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/architecture/<h1 id="technical-architecture">Technical Architecture<a class="anchor" href="#technical-architecture">#</a></h1> +<p>This document provides a technical deep-dive into dhamps-vdb&rsquo;s architecture for developers who want to understand or modify the codebase.</p> +<h2 id="project-structure">Project Structure<a class="anchor" href="#project-structure">#</a></h2> +<pre tabindex="0"><code>dhamps-vdb/ +├── main.go # Application entry point +├── go.mod # Go module definition +├── go.sum # Dependency checksums +├── sqlc.yaml # sqlc configuration +├── template.env # Environment template +├── .env # Local config (gitignored) +│ +├── api/ +│ └── openapi.yml # OpenAPI spec (not actively maintained) +│ +├── internal/ # Internal packages (non-importable) +│ ├── auth/ # Authentication logic +│ │ └── authenticate.go # Bearer token validation +│ │ +│ ├── crypto/ # Encryption utilities +│ │ └── crypto.go # AES-256-GCM encryption +│ │ +│ ├── database/ # Database layer +│ │ ├── database.go # Connection pool management +│ │ ├── migrations.go # Migration runner +│ │ ├── db.go # Generated by sqlc +│ │ ├── models.go # Generated by sqlc +│ │ ├── queries.sql.go # Generated by sqlc +│ │ │ +│ │ ├── migrations/ # SQL migrations +│ │ │ ├── 001_create_initial_scheme.sql +│ │ │ ├── 002_create_emb_index.sql +│ │ │ ├── 003_add_public_read_flag.sql +│ │ │ ├── 004_refactor_llm_services_architecture.sql +│ │ │ ├── tern.conf.tpl # Template for tern +│ │ │ └── tern.conf # Generated (gitignored) +│ │ │ +│ │ └── queries/ # SQL queries for sqlc +│ │ └── queries.sql # All database queries +│ │ +│ ├── handlers/ # HTTP request handlers +│ │ ├── handlers.go # Common handler utilities +│ │ ├── users.go # User endpoints +│ │ ├── projects.go # Project endpoints +│ │ ├── llm_services.go # LLM service endpoints +│ │ ├── api_standards.go # API standard endpoints +│ │ ├── embeddings.go # Embedding endpoints +│ │ ├── similars.go # Similarity search endpoints +│ │ ├── admin.go # Admin endpoints +│ │ │ +│ │ └── *_test.go # Test files +│ │ ├── users_test.go +│ │ ├── projects_test.go +│ │ ├── projects_sharing_test.go +│ │ ├── embeddings_test.go +│ │ ├── llm_services_test.go +│ │ ├── editor_permissions_test.go +│ │ └── handlers_test.go +│ │ +│ └── models/ # Data models and options +│ ├── options.go # CLI/environment options +│ ├── users.go # User models +│ ├── projects.go # Project models +│ ├── instances.go # LLM instance models (new) +│ ├── api_standards.go # API standard models +│ ├── embeddings.go # Embedding models +│ ├── similars.go # Similarity search models +│ └── admin.go # Admin operation models +│ +├── testdata/ # Test fixtures +│ ├── postgres/ # PostgreSQL test data +│ │ ├── enable-vector.sql +│ │ └── users.yml +│ │ +│ └── *.json # JSON test fixtures +│ ├── valid_user.json +│ ├── valid_embeddings.json +│ ├── valid_api_standard_*.json +│ └── valid_llm_service_*.json +│ +└── docs/ # Documentation + ├── content/ # Hugo content + └── *.md # Additional docs</code></pre><h2 id="code-organization">Code Organization<a class="anchor" href="#code-organization">#</a></h2> +<h3 id="1-entry-point-maingo">1. Entry Point (<code>main.go</code>)<a class="anchor" href="#1-entry-point-maingo">#</a></h3> +<p>The application entry point handles:</p>Performancehttps://mpilhlt.github.io/dhamps-vdb/development/performance/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/performance/<h1 id="performance-optimization-guide">Performance Optimization Guide<a class="anchor" href="#performance-optimization-guide">#</a></h1> +<p>This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.</p> +<h2 id="query-optimization">Query Optimization<a class="anchor" href="#query-optimization">#</a></h2> +<h3 id="getallaccessibleinstances-query">GetAllAccessibleInstances Query<a class="anchor" href="#getallaccessibleinstances-query">#</a></h3> +<p><strong>Problem:</strong> The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.</p> +<p><strong>Current Implementation:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> instances.<span style="color:#f92672">*</span>, +</span></span><span style="display:flex;"><span> COALESCE(instances_shared_with.<span style="color:#66d9ef">role</span>, <span style="color:#e6db74">&#39;owner&#39;</span>) <span style="color:#66d9ef">as</span> <span style="color:#66d9ef">role</span>, +</span></span><span style="display:flex;"><span> (instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span>) <span style="color:#66d9ef">as</span> is_owner +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> instances +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LEFT</span> <span style="color:#66d9ef">JOIN</span> instances_shared_with +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">ON</span> instances.instance_id <span style="color:#f92672">=</span> instances_shared_with.instance_id +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">OR</span> instances_shared_with.user_handle <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#66d9ef">ASC</span>, instances.instance_handle <span style="color:#66d9ef">ASC</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LIMIT</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">2</span> <span style="color:#66d9ef">OFFSET</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">3</span>;</span></span></code></pre></div><p><strong>Issue:</strong> The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.</p> \ No newline at end of file diff --git a/docs/public/development/performance/index.html b/docs/public/development/performance/index.html new file mode 100644 index 0000000..dd95910 --- /dev/null +++ b/docs/public/development/performance/index.html @@ -0,0 +1,470 @@ +Performance | dhamps-vdb Documentation + +

    Performance Optimization Guide#

    This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.

    Query Optimization#

    GetAllAccessibleInstances Query#

    Problem: The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.

    Current Implementation:

    SELECT instances.*, 
    +       COALESCE(instances_shared_with.role, 'owner') as role,
    +       (instances.owner = $1) as is_owner
    +FROM instances
    +LEFT JOIN instances_shared_with
    +  ON instances.instance_id = instances_shared_with.instance_id
    +WHERE instances.owner = $1
    +   OR instances_shared_with.user_handle = $1
    +ORDER BY instances.owner ASC, instances.instance_handle ASC 
    +LIMIT $2 OFFSET $3;

    Issue: The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.

    Use UNION ALL to separate owned instances from shared instances:

    -- Get owned instances
    +SELECT instances.*, 
    +       'owner' as role, 
    +       true as is_owner
    +FROM instances
    +WHERE instances.owner = $1
    +
    +UNION ALL
    +
    +-- Get shared instances
    +SELECT instances.*, 
    +       instances_shared_with.role,
    +       false as is_owner
    +FROM instances
    +INNER JOIN instances_shared_with
    +  ON instances.instance_id = instances_shared_with.instance_id
    +WHERE instances_shared_with.user_handle = $1
    +  AND instances.owner != $1  -- Avoid duplicates
    +
    +ORDER BY owner ASC, instance_handle ASC
    +LIMIT $2 OFFSET $3;

    Benefits:

    1. Separate index scans: Query planner can use different indexes for each UNION branch
    2. Owned instances: Can use index on (owner)
    3. Shared instances: Can use index on (user_handle)
    4. Clearer execution plan: Easier to understand and optimize
    5. Better performance: Especially noticeable with large datasets

    Trade-offs:

    • Slightly more complex SQL
    • Need to deduplicate if user somehow has instance both owned and shared (unlikely scenario)
    • Both queries must have same column structure

    Implementation Example#

    Before (queries.sql):

    -- name: GetAllAccessibleInstances :many
    +SELECT instances.*, ...
    +FROM instances
    +LEFT JOIN instances_shared_with ON ...
    +WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1

    After (queries.sql):

    -- name: GetAllAccessibleInstances :many
    +SELECT instances.*, 'owner' as role, true as is_owner
    +FROM instances
    +WHERE instances.owner = $1
    +UNION ALL
    +SELECT instances.*, isw.role, false as is_owner
    +FROM instances
    +INNER JOIN instances_shared_with isw ON instances.instance_id = isw.instance_id
    +WHERE isw.user_handle = $1 AND instances.owner != $1
    +ORDER BY owner, instance_handle
    +LIMIT $2 OFFSET $3;

    When to optimize:

    • Current implementation is correct and works well for small-medium datasets
    • Consider optimization if performance becomes an issue with:
      • Large numbers of instances (>1000)
      • Many shared relationships (>100 shares per user)
      • Query time consistently >100ms

    Always profile first:

    EXPLAIN ANALYZE 
    +SELECT instances.*, ...
    +FROM instances
    +LEFT JOIN instances_shared_with ON ...
    +WHERE instances.owner = 'alice' OR instances_shared_with.user_handle = 'alice';

    Index Optimization#

    Current Indexes#

    From migration 004_refactor_llm_services_architecture.sql:

    -- API Standards / Definitions
    +CREATE INDEX idx_definitions_handle 
    +  ON definitions(definition_handle);
    +
    +CREATE INDEX idx_definitions_owner_handle 
    +  ON definitions(owner, definition_handle);
    +
    +-- Instances
    +CREATE INDEX idx_instances_handle 
    +  ON instances(instance_handle);
    +
    +-- Sharing (implicit from PRIMARY KEY)
    +-- instances_shared_with(instance_id, user_handle)

    1. Owner Lookups#

    -- For queries: WHERE instances.owner = ?
    +CREATE INDEX idx_instances_owner 
    +  ON instances(owner);

    Benefit: Fast retrieval of user’s owned instances

    Use case:

    SELECT * FROM instances WHERE owner = 'alice';

    2. Shared Instance Lookups#

    -- For queries: WHERE user_handle = ?
    +CREATE INDEX idx_instances_shared_user 
    +  ON instances_shared_with(user_handle);

    Benefit: Fast retrieval of instances shared with user

    Use case:

    SELECT i.* FROM instances i
    +INNER JOIN instances_shared_with isw ON i.instance_id = isw.instance_id
    +WHERE isw.user_handle = 'bob';

    3. Composite Owner+Handle Index#

    -- For unique constraint and lookups
    +CREATE UNIQUE INDEX idx_instances_owner_handle 
    +  ON instances(owner, instance_handle);

    Benefit: Enforces uniqueness and enables index-only scans

    Use case:

    SELECT * FROM instances 
    +WHERE owner = 'alice' AND instance_handle = 'my-service';

    4. Embedding Dimension Filtering#

    -- Critical for similarity search performance
    +CREATE INDEX idx_embeddings_project_dim 
    +  ON embeddings(project_id, vector_dim);

    Benefit: Filters embeddings by dimension before vector comparison

    Use case:

    SELECT * FROM embeddings 
    +WHERE project_id = 123 
    +  AND vector_dim = 1536
    +ORDER BY vector <=> $1::vector
    +LIMIT 10;

    5. Project Ownership#

    CREATE INDEX idx_projects_owner 
    +  ON projects(owner);
    +
    +CREATE UNIQUE INDEX idx_projects_owner_handle 
    +  ON projects(owner, project_handle);

    Index Analysis#

    Check if indexes are being used:

    -- Analyze query plan
    +EXPLAIN ANALYZE 
    +SELECT * FROM instances WHERE owner = 'alice';
    +
    +-- Check index usage statistics
    +SELECT 
    +  schemaname,
    +  tablename,
    +  indexname,
    +  idx_scan,
    +  idx_tup_read,
    +  idx_tup_fetch
    +FROM pg_stat_user_indexes
    +WHERE schemaname = 'public'
    +ORDER BY idx_scan DESC;
    +
    +-- Find unused indexes
    +SELECT 
    +  schemaname,
    +  tablename,
    +  indexname
    +FROM pg_stat_user_indexes
    +WHERE idx_scan = 0
    +  AND schemaname = 'public';

    Index Maintenance#

    -- Update statistics for query planner
    +ANALYZE instances;
    +ANALYZE instances_shared_with;
    +ANALYZE embeddings;
    +
    +-- Rebuild index if fragmented
    +REINDEX INDEX idx_instances_owner;
    +
    +-- Check index size
    +SELECT 
    +  indexname,
    +  pg_size_pretty(pg_relation_size(indexrelid)) AS size
    +FROM pg_stat_user_indexes
    +WHERE schemaname = 'public'
    +ORDER BY pg_relation_size(indexrelid) DESC;

    Vector Index Optimization#

    HNSW vs IVFFlat#

    Current implementation uses HNSW:

    CREATE INDEX embedding_vector_idx 
    +ON embeddings 
    +USING hnsw (vector vector_cosine_ops);

    HNSW (Hierarchical Navigable Small World)#

    Pros:

    • Better recall (finds more similar results)
    • Better query performance
    • No training required

    Cons:

    • Slower index build time
    • Higher memory usage
    • Larger index size

    Configuration options:

    -- Default: m=16, ef_construction=64
    +CREATE INDEX embedding_vector_idx 
    +ON embeddings 
    +USING hnsw (vector vector_cosine_ops)
    +WITH (m = 16, ef_construction = 64);
    +
    +-- Higher quality (slower build): m=32, ef_construction=128
    +CREATE INDEX embedding_vector_idx_hq
    +ON embeddings 
    +USING hnsw (vector vector_cosine_ops)
    +WITH (m = 32, ef_construction = 128);

    Parameters:

    • m: Number of connections per layer (default 16, range 2-100)
    • ef_construction: Size of candidate list during build (default 64, range 4-1000)
    • Higher values = better recall but slower build and more memory

    IVFFlat (Inverted File with Flat compression)#

    Alternative for very large datasets:

    CREATE INDEX embedding_vector_idx_ivf
    +ON embeddings 
    +USING ivfflat (vector vector_cosine_ops)
    +WITH (lists = 100);

    Pros:

    • Faster index build
    • Lower memory usage
    • Smaller index size

    Cons:

    • Requires training (ANALYZE before creating index)
    • Lower recall than HNSW
    • Need to tune lists parameter

    When to use:

    • Dataset >1M embeddings
    • Build time is critical
    • Memory constrained environment

    Configuration:

    -- Rule of thumb: lists = sqrt(total_rows)
    +-- For 100K embeddings: lists = 316
    +-- For 1M embeddings: lists = 1000
    +
    +-- Train the index
    +ANALYZE embeddings;
    +
    +-- Create with appropriate lists
    +CREATE INDEX embedding_vector_idx_ivf
    +ON embeddings 
    +USING ivfflat (vector vector_cosine_ops)
    +WITH (lists = 1000);
    +
    +-- Set probes at query time
    +SET ivfflat.probes = 10;  -- Default is 1, higher = better recall

    Query-Time Optimization#

    For HNSW, set hnsw.ef_search:

    -- Default: ef_search = 40
    +-- Higher = better recall but slower queries
    +SET hnsw.ef_search = 100;
    +
    +SELECT vector <=> $1::vector AS distance
    +FROM embeddings
    +WHERE project_id = 123
    +ORDER BY distance
    +LIMIT 10;

    Dimension-Specific Indexes#

    For multi-dimensional projects:

    -- Separate indexes per common dimension
    +CREATE INDEX idx_embeddings_768_vector 
    +ON embeddings USING hnsw (vector vector_cosine_ops)
    +WHERE vector_dim = 768;
    +
    +CREATE INDEX idx_embeddings_1536_vector 
    +ON embeddings USING hnsw (vector vector_cosine_ops)
    +WHERE vector_dim = 1536;
    +
    +CREATE INDEX idx_embeddings_3072_vector 
    +ON embeddings USING hnsw (vector vector_cosine_ops)
    +WHERE vector_dim = 3072;

    Benefit: Smaller indexes = faster queries for specific dimensions

    Caching Strategies#

    1. System Definitions Cache#

    System definitions rarely change:

    var (
    +	systemDefsCache   []models.Definition
    +	systemDefsCacheMu sync.RWMutex
    +	systemDefsCacheTTL = 5 * time.Minute
    +	systemDefsCacheExp time.Time
    +)
    +
    +func GetSystemDefinitions(ctx context.Context, pool *pgxpool.Pool) ([]models.Definition, error) {
    +	systemDefsCacheMu.RLock()
    +	if time.Now().Before(systemDefsCacheExp) && systemDefsCache != nil {
    +		defer systemDefsCacheMu.RUnlock()
    +		return systemDefsCache, nil
    +	}
    +	systemDefsCacheMu.RUnlock()
    +	
    +	// Fetch from database
    +	defs, err := db.GetDefinitionsByOwner(ctx, "_system")
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	// Update cache
    +	systemDefsCacheMu.Lock()
    +	systemDefsCache = defs
    +	systemDefsCacheExp = time.Now().Add(systemDefsCacheTTL)
    +	systemDefsCacheMu.Unlock()
    +	
    +	return defs, nil
    +}

    2. User Instances Cache#

    Cache user’s instance list with short TTL:

    type InstanceCache struct {
    +	data map[string][]models.Instance
    +	mu   sync.RWMutex
    +	ttl  time.Duration
    +	exp  map[string]time.Time
    +}
    +
    +func (c *InstanceCache) Get(userHandle string) ([]models.Instance, bool) {
    +	c.mu.RLock()
    +	defer c.mu.RUnlock()
    +	
    +	if exp, ok := c.exp[userHandle]; ok && time.Now().Before(exp) {
    +		return c.data[userHandle], true
    +	}
    +	return nil, false
    +}
    +
    +func (c *InstanceCache) Set(userHandle string, instances []models.Instance) {
    +	c.mu.Lock()
    +	defer c.mu.Unlock()
    +	
    +	c.data[userHandle] = instances
    +	c.exp[userHandle] = time.Now().Add(c.ttl)
    +}
    +
    +func (c *InstanceCache) Invalidate(userHandle string) {
    +	c.mu.Lock()
    +	defer c.mu.Unlock()
    +	
    +	delete(c.data, userHandle)
    +	delete(c.exp, userHandle)
    +}

    Usage:

    var instanceCache = &InstanceCache{
    +	data: make(map[string][]models.Instance),
    +	exp:  make(map[string]time.Time),
    +	ttl:  30 * time.Second,
    +}
    +
    +func GetUserInstances(ctx context.Context, pool *pgxpool.Pool, userHandle string) ([]models.Instance, error) {
    +	// Check cache
    +	if instances, ok := instanceCache.Get(userHandle); ok {
    +		return instances, nil
    +	}
    +	
    +	// Query database
    +	instances, err := db.GetAccessibleInstances(ctx, userHandle)
    +	if err != nil {
    +		return nil, err
    +	}
    +	
    +	// Cache results
    +	instanceCache.Set(userHandle, instances)
    +	return instances, nil
    +}

    3. Project Metadata Cache#

    Cache project metadata including schema:

    type ProjectCache struct {
    +	projects map[string]*models.Project  // key: "owner/handle"
    +	mu       sync.RWMutex
    +	ttl      time.Duration
    +}
    +
    +func (c *ProjectCache) Get(owner, handle string) (*models.Project, bool) {
    +	key := fmt.Sprintf("%s/%s", owner, handle)
    +	c.mu.RLock()
    +	defer c.mu.RUnlock()
    +	
    +	project, ok := c.projects[key]
    +	return project, ok
    +}

    4. Redis-Based Caching#

    For distributed deployments:

    import "github.com/go-redis/redis/v8"
    +
    +type RedisCache struct {
    +	client *redis.Client
    +	ttl    time.Duration
    +}
    +
    +func (c *RedisCache) GetProject(ctx context.Context, owner, handle string) (*models.Project, error) {
    +	key := fmt.Sprintf("project:%s:%s", owner, handle)
    +	
    +	data, err := c.client.Get(ctx, key).Bytes()
    +	if err == redis.Nil {
    +		return nil, nil  // Not in cache
    +	} else if err != nil {
    +		return nil, err
    +	}
    +	
    +	var project models.Project
    +	err = json.Unmarshal(data, &project)
    +	return &project, err
    +}
    +
    +func (c *RedisCache) SetProject(ctx context.Context, project *models.Project) error {
    +	key := fmt.Sprintf("project:%s:%s", project.Owner, project.Handle)
    +	data, err := json.Marshal(project)
    +	if err != nil {
    +		return err
    +	}
    +	
    +	return c.client.Set(ctx, key, data, c.ttl).Err()
    +}

    Cache Invalidation#

    Always invalidate cache on updates:

    func UpdateProject(ctx context.Context, pool *pgxpool.Pool, project *models.Project) error {
    +	// Update database
    +	err := db.UpdateProject(ctx, project)
    +	if err != nil {
    +		return err
    +	}
    +	
    +	// Invalidate cache
    +	projectCache.Invalidate(project.Owner, project.Handle)
    +	
    +	return nil
    +}

    Connection Pool Optimization#

    Pool Configuration#

    func InitDB(opts *models.Options) *pgxpool.Pool {
    +	config, err := pgxpool.ParseConfig(connString)
    +	if err != nil {
    +		log.Fatal(err)
    +	}
    +	
    +	// Connection pool settings
    +	config.MaxConns = 20                      // Max concurrent connections
    +	config.MinConns = 5                       // Keep-alive connections
    +	config.MaxConnLifetime = time.Hour        // Recycle connections
    +	config.MaxConnIdleTime = 5 * time.Minute  // Close idle connections
    +	config.HealthCheckPeriod = time.Minute    // Health check frequency
    +	
    +	// Statement cache
    +	config.ConnConfig.StatementCacheCapacity = 100
    +	
    +	pool, err := pgxpool.NewWithConfig(context.Background(), config)
    +	return pool
    +}

    Pool Sizing#

    General rule:

    MaxConns = (available_cores * 2) + effective_spindle_count

    Example scenarios:

    • 4-core CPU, SSD: MaxConns = 10-20
    • 8-core CPU, SSD: MaxConns = 20-40
    • Under heavy load: Start conservative, increase based on monitoring

    Monitor Pool Usage#

    func monitorPool(pool *pgxpool.Pool) {
    +	ticker := time.NewTicker(30 * time.Second)
    +	
    +	for range ticker.C {
    +		stat := pool.Stat()
    +		log.Printf("Pool stats: total=%d, idle=%d, acquired=%d, waiting=%d",
    +			stat.TotalConns(),
    +			stat.IdleConns(),
    +			stat.AcquiredConns(),
    +			stat.MaxConns()-stat.TotalConns(),
    +		)
    +	}
    +}

    Performance Testing#

    Load Testing Setup#

    Use vegeta for HTTP load testing:

    # Install vegeta
    +go install github.com/tsenart/vegeta@latest
    +
    +# Create targets file
    +cat > targets.txt <<EOF
    +GET http://localhost:8880/v1/projects/alice
    +Authorization: Bearer alice_api_key
    +
    +POST http://localhost:8880/v1/similars/alice/project1/doc1
    +Authorization: Bearer alice_api_key
    +Content-Type: application/json
    +
    +GET http://localhost:8880/v1/embeddings/alice/project1?limit=100
    +Authorization: Bearer alice_api_key
    +EOF
    +
    +# Run load test
    +echo "GET http://localhost:8880/v1/projects/alice" | \
    +  vegeta attack -duration=60s -rate=100 -header="Authorization: Bearer key" | \
    +  vegeta report

    Benchmark Tests#

    Create Go benchmarks:

    func BenchmarkGetAccessibleInstances(b *testing.B) {
    +	pool := setupBenchmarkDB(b)
    +	defer pool.Close()
    +	
    +	// Create test data
    +	createTestInstances(b, pool, 1000)
    +	
    +	ctx := context.Background()
    +	
    +	b.ResetTimer()
    +	for i := 0; i < b.N; i++ {
    +		_, err := db.GetAllAccessibleInstances(ctx, "testuser", 10, 0)
    +		if err != nil {
    +			b.Fatal(err)
    +		}
    +	}
    +}
    +
    +func BenchmarkSimilaritySearch(b *testing.B) {
    +	pool := setupBenchmarkDB(b)
    +	defer pool.Close()
    +	
    +	// Create embeddings
    +	createTestEmbeddings(b, pool, 10000)
    +	
    +	ctx := context.Background()
    +	queryVector := generateRandomVector(1536)
    +	
    +	b.ResetTimer()
    +	for i := 0; i < b.N; i++ {
    +		_, err := SearchSimilar(ctx, pool, "alice", "project1", queryVector, 10, 0.5)
    +		if err != nil {
    +			b.Fatal(err)
    +		}
    +	}
    +}

    Run benchmarks:

    # Run all benchmarks
    +go test -bench=. -benchmem ./...
    +
    +# Run specific benchmark
    +go test -bench=BenchmarkSimilaritySearch -benchmem ./internal/handlers
    +
    +# Compare before/after
    +go test -bench=. -benchmem ./... > old.txt
    +# Make changes
    +go test -bench=. -benchmem ./... > new.txt
    +benchcmp old.txt new.txt

    Database Performance Testing#

    Test with realistic data:

    -- Generate test data
    +INSERT INTO embeddings (project_id, text_id, vector, vector_dim, metadata)
    +SELECT 
    +  1,
    +  'doc_' || generate_series,
    +  array_fill(random()::real, ARRAY[1536])::vector,
    +  1536,
    +  '{"author": "test"}'::jsonb
    +FROM generate_series(1, 100000);
    +
    +-- Test query performance
    +EXPLAIN (ANALYZE, BUFFERS) 
    +SELECT text_id, vector <=> $1::vector AS distance
    +FROM embeddings
    +WHERE project_id = 1 AND vector_dim = 1536
    +ORDER BY distance
    +LIMIT 10;

    Metrics and Monitoring#

    Application Metrics#

    Track key metrics:

    type Metrics struct {
    +	QueryDuration    prometheus.Histogram
    +	QueryCount       prometheus.Counter
    +	CacheHits        prometheus.Counter
    +	CacheMisses      prometheus.Counter
    +	PoolWaitDuration prometheus.Histogram
    +}
    +
    +func recordQueryMetrics(start time.Time, query string) {
    +	duration := time.Since(start).Seconds()
    +	metrics.QueryDuration.Observe(duration)
    +	metrics.QueryCount.Inc()
    +}

    PostgreSQL Metrics#

    Monitor database performance:

    -- Slow queries
    +SELECT 
    +  query,
    +  calls,
    +  total_time,
    +  mean_time,
    +  max_time
    +FROM pg_stat_statements
    +ORDER BY mean_time DESC
    +LIMIT 10;
    +
    +-- Table statistics
    +SELECT 
    +  schemaname,
    +  tablename,
    +  n_tup_ins,
    +  n_tup_upd,
    +  n_tup_del,
    +  n_live_tup,
    +  n_dead_tup
    +FROM pg_stat_user_tables;
    +
    +-- Index usage
    +SELECT 
    +  schemaname,
    +  tablename,
    +  indexname,
    +  idx_scan,
    +  idx_tup_read,
    +  idx_tup_fetch
    +FROM pg_stat_user_indexes
    +ORDER BY idx_scan DESC;

    Performance Targets#

    Based on typical usage:

    OperationTargetAcceptableAction Required
    Single instance lookup< 10ms< 50ms> 50ms
    List accessible instances (<100)< 50ms< 100ms> 100ms
    Create/update instance< 100ms< 200ms> 200ms
    Similarity search (10 results)< 50ms< 100ms> 100ms
    Similarity search (100 results)< 100ms< 200ms> 200ms
    Embedding insert (single)< 50ms< 100ms> 100ms
    Embedding batch (100)< 500ms< 1000ms> 1000ms

    Implementation Priority#

    High Priority#

    1. Profile current performance with realistic data
    2. Add dimension filtering index: idx_embeddings_project_dim
    3. Monitor slow queries with pg_stat_statements

    Medium Priority#

    1. Implement UNION ALL optimization if GetAllAccessibleInstances > 100ms
    2. Add caching for system definitions
    3. Optimize connection pool settings based on load

    Low Priority#

    1. Add Redis caching layer for high-traffic deployments
    2. Implement application metrics with Prometheus
    3. Add additional indexes based on actual query patterns
    4. Tune HNSW parameters for specific use cases

    General Best Practices#

    1. Measure Before Optimizing#

    # Profile in production
    +EXPLAIN ANALYZE your_query;
    +
    +# Load test
    +vegeta attack -duration=60s -rate=100
    +
    +# Benchmark
    +go test -bench=. -benchmem

    2. Start Conservative#

    • Don’t optimize prematurely
    • Use simple queries first
    • Add complexity only when needed

    3. Monitor Continuously#

    • Track query performance
    • Monitor connection pool
    • Watch index usage
    • Alert on slow queries

    4. Document Optimizations#

    • Note why optimization was needed
    • Include before/after metrics
    • Document trade-offs made

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/development/testing/index.html b/docs/public/development/testing/index.html new file mode 100644 index 0000000..ce3246f --- /dev/null +++ b/docs/public/development/testing/index.html @@ -0,0 +1,288 @@ +Testing | dhamps-vdb Documentation + +

    Testing Guide#

    This guide covers how to run and write tests for dhamps-vdb.

    Running Tests#

    dhamps-vdb uses integration tests that spin up real PostgreSQL containers using testcontainers. This approach ensures tests run against actual database instances with pgvector support.

    Prerequisites#

    Using Podman (Recommended for Linux):

    # Start podman socket
    +systemctl --user start podman.socket
    +
    +# Export DOCKER_HOST for testcontainers
    +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock

    Using Docker:

    Testcontainers works with Docker out of the box. Ensure Docker daemon is running.

    Running All Tests#

    # Run all tests with verbose output
    +go test -v ./...
    +
    +# Run tests without verbose output
    +go test ./...
    +
    +# Run tests with coverage
    +go test -cover ./...
    +
    +# Generate coverage report
    +go test -coverprofile=coverage.out ./...
    +go tool cover -html=coverage.out

    Running Specific Tests#

    # Run tests in a specific package
    +go test -v ./internal/handlers
    +
    +# Run a specific test function
    +go test -v ./internal/handlers -run TestCreateUser
    +
    +# Run tests matching a pattern
    +go test -v ./... -run ".*Sharing.*"

    Test Containers#

    Tests automatically manage PostgreSQL containers with pgvector:

    • Container is started before tests run
    • Database schema is migrated automatically
    • Container is cleaned up after tests complete
    • Each test suite gets a fresh database state

    Test Structure#

    Package Organization#

    Tests are organized alongside the code they test:

    internal/
    +├── handlers/
    +│   ├── users.go              # Implementation
    +│   ├── users_test.go         # Unit/integration tests
    +│   ├── projects.go
    +│   ├── projects_test.go
    +│   ├── projects_sharing_test.go
    +│   ├── embeddings.go
    +│   └── embeddings_test.go
    +├── database/
    +│   └── queries.sql           # SQL queries for sqlc
    +└── models/
    +    ├── users.go
    +    └── projects.go

    Test Files#

    Test files follow Go conventions:

    • Filename: *_test.go
    • Package: Same as code under test (e.g., package handlers)
    • Test functions: func TestFunctionName(t *testing.T)

    Test Fixtures#

    Test data is stored in testdata/:

    testdata/
    +├── postgres/
    +│   ├── enable-vector.sql     # Database initialization
    +│   └── users.yml
    +├── valid_embeddings.json
    +├── valid_user.json
    +├── valid_api_standard_openai_v1.json
    +├── valid_llm_service_openai-large-full.json
    +└── invalid_embeddings.json

    Writing Tests#

    Basic Test Structure#

    package handlers
    +
    +import (
    +	"context"
    +	"testing"
    +
    +	"github.com/mpilhlt/dhamps-vdb/internal/database"
    +	"github.com/stretchr/testify/assert"
    +)
    +
    +func TestCreateUser(t *testing.T) {
    +	// Setup: Initialize database pool and test data
    +	ctx := context.Background()
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	// Execute: Call function under test
    +	result, err := CreateUser(ctx, pool, userData)
    +	
    +	// Assert: Verify results
    +	assert.NoError(t, err)
    +	assert.Equal(t, "testuser", result.UserHandle)
    +}

    Integration Test Example#

    func TestProjectSharingWorkflow(t *testing.T) {
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	// Create test users
    +	alice := createTestUser(t, pool, "alice")
    +	bob := createTestUser(t, pool, "bob")
    +	
    +	// Create project as Alice
    +	project := createTestProject(t, pool, alice, "test-project")
    +	
    +	// Share project with Bob
    +	err := shareProject(t, pool, alice, project.ID, bob.Handle, "reader")
    +	assert.NoError(t, err)
    +	
    +	// Verify Bob can access project
    +	projects := getAccessibleProjects(t, pool, bob)
    +	assert.Contains(t, projects, project)
    +}

    Testing with Testcontainers#

    func setupTestDatabase(t *testing.T) *pgxpool.Pool {
    +	ctx := context.Background()
    +	
    +	// Create PostgreSQL container with pgvector
    +	req := testcontainers.ContainerRequest{
    +		Image:        "pgvector/pgvector:0.7.4-pg16",
    +		ExposedPorts: []string{"5432/tcp"},
    +		Env: map[string]string{
    +			"POSTGRES_PASSWORD": "password",
    +			"POSTGRES_DB":       "testdb",
    +		},
    +		WaitStrategy: wait.ForLog("database system is ready to accept connections"),
    +	}
    +	
    +	container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
    +		ContainerRequest: req,
    +		Started:          true,
    +	})
    +	require.NoError(t, err)
    +	
    +	// Get connection details
    +	host, _ := container.Host(ctx)
    +	port, _ := container.MappedPort(ctx, "5432")
    +	
    +	// Connect and migrate
    +	connString := fmt.Sprintf("postgres://postgres:password@%s:%s/testdb", host, port.Port())
    +	pool := connectAndMigrate(t, connString)
    +	
    +	return pool
    +}

    Validation Testing#

    Test dimension and metadata validation:

    func TestEmbeddingDimensionValidation(t *testing.T) {
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	// Create LLM service with 1536 dimensions
    +	llmService := createTestLLMService(t, pool, "openai", 1536)
    +	
    +	// Try to insert embedding with wrong dimensions
    +	embedding := models.Embedding{
    +		TextID:    "doc1",
    +		Vector:    make([]float32, 768), // Wrong size!
    +		VectorDim: 768,
    +	}
    +	
    +	err := insertEmbedding(t, pool, embedding)
    +	assert.Error(t, err)
    +	assert.Contains(t, err.Error(), "dimension mismatch")
    +}
    +
    +func TestMetadataSchemaValidation(t *testing.T) {
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	// Create project with metadata schema
    +	schema := `{"type":"object","properties":{"author":{"type":"string"}},"required":["author"]}`
    +	project := createProjectWithSchema(t, pool, "alice", "test", schema)
    +	
    +	// Valid metadata should succeed
    +	validMeta := `{"author":"John Doe"}`
    +	err := insertEmbeddingWithMetadata(t, pool, project.ID, validMeta)
    +	assert.NoError(t, err)
    +	
    +	// Invalid metadata should fail
    +	invalidMeta := `{"year":2024}` // Missing required 'author'
    +	err = insertEmbeddingWithMetadata(t, pool, project.ID, invalidMeta)
    +	assert.Error(t, err)
    +}

    Table-Driven Tests#

    For testing multiple scenarios:

    func TestSimilaritySearch(t *testing.T) {
    +	tests := []struct {
    +		name      string
    +		threshold float32
    +		limit     int
    +		expected  int
    +	}{
    +		{"high threshold", 0.9, 10, 2},
    +		{"medium threshold", 0.7, 10, 5},
    +		{"low threshold", 0.5, 10, 8},
    +		{"with limit", 0.5, 3, 3},
    +	}
    +	
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	for _, tt := range tests {
    +		t.Run(tt.name, func(t *testing.T) {
    +			results := searchSimilar(t, pool, "doc1", tt.threshold, tt.limit)
    +			assert.Len(t, results, tt.expected)
    +		})
    +	}
    +}

    Cleanup Testing#

    Verify database cleanup:

    func TestDatabaseCleanup(t *testing.T) {
    +	pool := setupTestDatabase(t)
    +	defer pool.Close()
    +	
    +	// Create test data
    +	user := createTestUser(t, pool, "alice")
    +	project := createTestProject(t, pool, user, "test")
    +	createTestEmbeddings(t, pool, project, 10)
    +	
    +	// Delete user (should cascade)
    +	err := deleteUser(t, pool, user.Handle)
    +	assert.NoError(t, err)
    +	
    +	// Verify all related data is deleted
    +	assertTableEmpty(t, pool, "users")
    +	assertTableEmpty(t, pool, "projects")
    +	assertTableEmpty(t, pool, "embeddings")
    +}

    Test Helpers#

    Create helper functions to reduce boilerplate:

    // setupTestDatabase initializes a test database with migrations
    +func setupTestDatabase(t *testing.T) *pgxpool.Pool {
    +	// Implementation...
    +}
    +
    +// createTestUser creates a user for testing
    +func createTestUser(t *testing.T, pool *pgxpool.Pool, handle string) *models.User {
    +	// Implementation...
    +}
    +
    +// createTestProject creates a project for testing
    +func createTestProject(t *testing.T, pool *pgxpool.Pool, owner *models.User, handle string) *models.Project {
    +	// Implementation...
    +}
    +
    +// assertTableEmpty verifies a table has no rows
    +func assertTableEmpty(t *testing.T, pool *pgxpool.Pool, tableName string) {
    +	var count int
    +	err := pool.QueryRow(context.Background(), 
    +		fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)).Scan(&count)
    +	require.NoError(t, err)
    +	assert.Equal(t, 0, count, "table %s should be empty", tableName)
    +}

    CI/CD Integration#

    GitHub Actions#

    Example GitHub Actions workflow:

    name: Tests
    +
    +on: [push, pull_request]
    +
    +jobs:
    +  test:
    +    runs-on: ubuntu-latest
    +    
    +    steps:
    +    - uses: actions/checkout@v3
    +    
    +    - name: Set up Go
    +      uses: actions/setup-go@v4
    +      with:
    +        go-version: '1.21'
    +    
    +    - name: Run tests
    +      run: |
    +        go test -v -race -coverprofile=coverage.txt ./...
    +    
    +    - name: Upload coverage
    +      uses: codecov/codecov-action@v3
    +      with:
    +        files: ./coverage.txt

    Local CI Testing#

    Test as CI would:

    # Clean test with race detection
    +go clean -testcache
    +go test -v -race ./...
    +
    +# Test with coverage
    +go test -coverprofile=coverage.out ./...
    +
    +# Check for test caching issues
    +go test -count=1 ./...

    Best Practices#

    1. Use testcontainers for Real Databases#

    • Don’t mock the database layer
    • Test against actual PostgreSQL with pgvector
    • Catch SQL-specific issues

    2. Isolate Tests#

    • Each test should be independent
    • Use transactions or cleanup between tests
    • Don’t rely on test execution order

    3. Test Validation Logic#

    • Test dimension validation
    • Test metadata schema validation
    • Test authorization checks

    4. Test Error Conditions#

    • Invalid input
    • Missing resources (404)
    • Unauthorized access (403)
    • Constraint violations

    5. Keep Tests Fast#

    • Use parallel tests where possible: t.Parallel()
    • Reuse test database containers when appropriate
    • Avoid unnecessary sleeps

    6. Use Descriptive Names#

    // Good
    +func TestProjectSharingWithReaderRole(t *testing.T)
    +
    +// Less clear
    +func TestSharing(t *testing.T)

    7. Assert Meaningfully#

    // Good - specific assertion
    +assert.Equal(t, "alice", project.Owner)
    +
    +// Less helpful
    +assert.True(t, project.Owner == "alice")

    Debugging Tests#

    Verbose Output#

    # See all test output
    +go test -v ./internal/handlers
    +
    +# See SQL queries (if logging enabled)
    +SERVICE_DEBUG=true go test -v ./...

    Run Single Test#

    # Focus on one failing test
    +go test -v ./internal/handlers -run TestCreateProject

    Keep Test Database Running#

    For manual inspection, prevent container cleanup:

    func TestWithDebugContainer(t *testing.T) {
    +	container := setupContainer(t)
    +	// Comment out: defer container.Terminate(ctx)
    +	
    +	host, port := getContainerDetails(container)
    +	t.Logf("Database running at %s:%s", host, port)
    +	
    +	// Run test...
    +	
    +	// Container stays running for manual inspection
    +	time.Sleep(time.Hour)
    +}

    Then connect with psql:

    psql -h localhost -p <port> -U postgres -d testdb

    Common Issues#

    Container Startup Failures#

    # Check Docker/Podman is running
    +systemctl --user status podman.socket
    +
    +# Check for port conflicts
    +netstat -tulpn | grep 5432
    +
    +# Clean up containers
    +podman rm -f $(podman ps -aq)

    Test Timeouts#

    Increase timeout for slow containers:

    WaitStrategy: wait.ForLog("ready").WithStartupTimeout(2 * time.Minute)

    Permission Errors#

    Ensure test user has proper permissions:

    GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
    +GRANT ALL ON SCHEMA public TO testuser;

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json b/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json new file mode 100644 index 0000000..d10a49d --- /dev/null +++ b/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json @@ -0,0 +1 @@ +[{"id":0,"href":"/dhamps-vdb/concepts/architecture/","title":"Architecture","section":"Concepts","content":"Architecture# dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.\nSystem Overview# ┌─────────────┐ │ Client │ │ Application │ └──────┬──────┘ │ HTTP/REST │ ┌──────▼──────────────────────────┐ │ dhamps-vdb API Server │ │ ┌──────────────────────────┐ │ │ │ Authentication Layer │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ Request Handlers │ │ │ │ (Users, Projects, etc) │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ Validation Layer │ │ │ │ (Dimensions, Metadata) │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ SQLC Queries │ │ │ │ (Type-safe SQL) │ │ │ └────────┬─────────────────┘ │ └───────────┼──────────────────────┘ │ ┌───────▼──────────────┐ │ PostgreSQL + 16 │ │ with pgvector 0.7 │ │ │ │ ┌────────────────┐ │ │ │ Vector Index │ │ │ │ (HNSW/IVFFlat) │ │ │ └────────────────┘ │ └──────────────────────┘Core Components# API Layer# Built with Huma framework on top of Go\u0026rsquo;s http.ServeMux:\nOpenAPI documentation generation Automatic request/response validation JSON schema support REST endpoint routing Authentication# Token-based authentication using API keys:\nAdmin key: For administrative operations (user creation, system management) User keys: SHA-256 hashed, unique per user Bearer token: Transmitted in Authorization header Data Storage# PostgreSQL with pgvector extension:\nVector storage: Native pgvector support for embeddings Vector search: Cosine similarity using \u0026lt;=\u0026gt; operator ACID compliance: Transactional consistency Relational integrity: Foreign keys and constraints Code Generation# Uses sqlc for type-safe database queries:\nSQL queries → Go functions Compile-time type checking No ORM overhead Direct PostgreSQL integration Data Model# Core Entities# users ├── projects (1:many) │ ├── embeddings (1:many) │ └── instance (1:1) │ └── instances (1:many) └── definition (many:1, optional) _system (special user) └── definitions (1:many)Key Relationships# Users → Projects\nOne user owns many projects Projects can be shared with other users (reader/editor roles) Projects can be public (unauthenticated read access) Projects → Instances\nEach project references exactly one LLM service instance Instance defines embedding dimensions and configuration Projects → Embeddings\nOne project contains many embeddings Each embedding has a unique text_id within the project Embeddings store vector, metadata, and optional text Users → Instances\nUsers own their instances Instances can be shared with other users Instances store encrypted API keys Instances → Definitions\nInstances can optionally reference a definition (template) System definitions (_system owner) provide defaults User definitions allow custom templates Request Flow# 1. Create Embedding# Client Request ↓ Authentication Middleware ↓ Authorization Check (owner/editor?) ↓ Dimension Validation (vector_dim matches instance?) ↓ Metadata Validation (matches project schema?) ↓ Database Insert (with transaction) ↓ Response2. Similarity Search# Client Request (text_id or vector) ↓ Authentication Middleware (or public check) ↓ Authorization Check (owner/reader/public?) ↓ Dimension Validation (if raw vector) ↓ Vector Similarity Query ├── Cosine distance calculation ├── Threshold filtering ├── Metadata filtering (exclude matches) └── Limit/offset pagination ↓ Results (sorted by similarity) ↓ ResponseStorage Architecture# Vector Index# pgvector supports multiple index types:\nIVFFlat: Faster build, approximate search HNSW: Slower build, better recall Current implementation uses HNSW for better accuracy.\nVector Storage Format# CREATE TABLE embeddings ( embedding_id SERIAL PRIMARY KEY, text_id TEXT NOT NULL, project_id INT REFERENCES projects, vector vector(3072), -- Dimension varies vector_dim INT NOT NULL, metadata JSONB, text TEXT, ... )Index Strategy# CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);Optimized for cosine similarity searches.\nSecurity Architecture# API Key Encryption# Algorithm: AES-256-GCM Key Source: ENCRYPTION_KEY environment variable Key Derivation: SHA-256 hash to ensure 32-byte key Storage: Binary (BYTEA) in database Access Control# Three-tier access model:\nOwner: Full control (read, write, delete, share, transfer) Editor: Read and write embeddings Reader: Read-only access to embeddings and search Special access:\nAdmin: System-wide operations (user management, sanity checks) Public: Unauthenticated read access (if public_read=true) Data Isolation# Users can only access their own resources or shared resources Cross-user queries are prevented at the database level Project ownership enforced via foreign keys Migration System# Uses tern for database migrations:\nmigrations/ ├── 001_create_initial_scheme.sql ├── 002_create_emb_index.sql ├── 003_add_public_read_flag.sql └── 004_refactor_llm_services_architecture.sqlMigrations run automatically on startup with rollback support.\nPerformance Characteristics# Vector Search Performance# Small datasets (\u0026lt;10K embeddings): \u0026lt;10ms per query Medium datasets (10K-100K): 10-50ms per query Large datasets (\u0026gt;100K): 50-200ms per query Performance depends on:\nVector dimensions Index type and parameters Hardware (CPU, RAM, disk) Number of results requested Scaling Considerations# Vertical Scaling:\nMore RAM = faster searches (more vectors in memory) Faster CPUs = faster vector comparisons SSD storage = faster index scans Horizontal Scaling:\nRead replicas for search queries Separate write/read workloads Connection pooling for concurrent requests Technology Stack# Core Technologies# Language: Go 1.21+ Web Framework: Huma 2.x Database: PostgreSQL 16+ Vector Extension: pgvector 0.7.4 Query Generator: sqlc 1.x Migration Tool: tern 2.x Development Tools# Testing: Go standard library + testcontainers Documentation: OpenAPI 3.0 (auto-generated) Building: Docker multi-stage builds Deployment: Docker Compose Design Principles# 1. Type Safety# sqlc generates type-safe Go code from SQL Strong typing prevents SQL injection Compile-time validation of queries 2. Simplicity# REST API (not GraphQL) Straightforward URL patterns Standard HTTP methods 3. Security# API key encryption at rest No API keys in responses Role-based access control 4. Validation# Automatic dimension validation Optional metadata schema validation Request/response validation via OpenAPI 5. Extensibility# User-defined metadata schemas Custom LLM service configurations Flexible sharing model Limitations# Current Constraints# No multi-tenancy: Each installation is single-tenant No replication: Manual setup required for HA No caching: All queries hit database Synchronous API: No async/batch upload endpoints Future Enhancements# See Roadmap for planned improvements.\nNext Steps# Learn about users and authentication Understand projects Explore LLM services "},{"id":1,"href":"/dhamps-vdb/api/authentication/","title":"Authentication","section":"API Reference","content":"API Authentication# All API requests (except public project read operations) require authentication using API keys passed in the Authorization header with a Bearer prefix.\nAuthentication Method# Include your API key in the Authorization header of every request:\nAuthorization: Bearer your_api_key_hereAPI Key Types# Admin API Key# Full access to all API endpoints and resources Can create and manage users Can access all projects and resources across all users Required for administrative operations Set via ADMIN_KEY environment variable Admin-only operations:\nPOST /v1/users - Create new users GET /v1/users - List all users GET /v1/admin/* - Admin endpoints Create/modify _system LLM service definitions Access any user\u0026rsquo;s resources User API Key# Access limited to user\u0026rsquo;s own resources and shared projects Cannot create other users Cannot access admin endpoints Returned when creating a new user (store securely) User capabilities:\nManage own projects and LLM services Upload and query embeddings in owned projects Access projects shared with them (read or edit access) Delete own account Getting an API Key# Admin Key# Set the admin key via environment variable when launching the service:\nexport ADMIN_KEY=\u0026#34;your-secure-admin-key-here\u0026#34; ./dhamps-vdbUser Key# Create a new user using the admin API key:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; }⚠️ Important: The API key is only returned once during user creation. Store it securely - it cannot be recovered.\nAuthorization Header Format# Correct Format# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34;Common Mistakes# ❌ Missing \u0026ldquo;Bearer\u0026rdquo; prefix:\nAuthorization: 024v2013621509245f2e24❌ Wrong prefix:\nAuthorization: Token 024v2013621509245f2e24❌ Extra quotes:\nAuthorization: Bearer \u0026#34;024v2013621509245f2e24\u0026#34;Authentication Errors# 401 Unauthorized# Returned when authentication credentials are missing or invalid.\nCauses:\nMissing Authorization header Invalid API key Malformed header format Example response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden# Returned when authentication succeeds but authorization fails.\nCauses:\nAttempting to access another user\u0026rsquo;s resources User lacking required permissions Non-admin accessing admin endpoints Example response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this resource\u0026#34; }Public Access# Projects can be made publicly accessible by setting public_read: true when creating or updating the project. Public projects allow unauthenticated read access to:\nProject metadata Embeddings Similarity search See Public Access Documentation for details.\nSecurity Best Practices# Never commit API keys to version control Use environment variables to store API keys in your applications Rotate keys regularly by creating new users and deleting old ones Use HTTPS in production to prevent key interception Store admin keys securely using secrets management systems Limit admin key distribution to essential personnel only Example Authenticated Request# # List user\u0026#39;s projects curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34; # Create a new project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My research project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39;Related Documentation# Error Handling - Complete error response reference Users Endpoint - User management API "},{"id":2,"href":"/dhamps-vdb/reference/configuration/","title":"Configuration Reference","section":"Reference","content":"Configuration Reference# Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.\nOverview# dhamps-vdb is configured through a combination of:\nEnvironment variables (recommended) Command-line flags (overrides environment variables) .env files (for Docker and local development) Configuration is loaded in the following priority order (highest to lowest):\nCommand-line flags Environment variables .env file values Default values from options.go Configuration Options# Service Configuration# Options for controlling the API service behavior.\nOption Environment Variable CLI Flag Type Default Required Description Debug SERVICE_DEBUG -d, --debug Boolean true No Enable verbose debug logging Host SERVICE_HOST --host String localhost No Hostname or IP to bind to Port SERVICE_PORT -p, --port Integer 8880 No Port number to listen on Debug Mode:\ntrue - Detailed logs including SQL queries, request details, internal operations false - Minimal logs for production use Host Configuration:\nlocalhost - Local development only 0.0.0.0 - Listen on all interfaces (required for Docker) Specific IP - Bind to particular network interface Port Configuration:\nDefault: 8880 Ports below 1024 require elevated privileges Ensure port is not in use by another service Database Configuration# Options for connecting to the PostgreSQL database with pgvector extension.\nOption Environment Variable CLI Flag Type Default Required Description DB Host SERVICE_DBHOST --db-host String localhost Yes PostgreSQL server hostname DB Port SERVICE_DBPORT --db-port Integer 5432 No PostgreSQL server port DB User SERVICE_DBUSER --db-user String postgres Yes Database username DB Password SERVICE_DBPASSWORD --db-password String password Yes Database password DB Name SERVICE_DBNAME --db-name String postgres Yes Database name Database Requirements:\nPostgreSQL 12+ (16+ recommended) pgvector extension installed and enabled User must have CREATE, ALTER, DROP, INSERT, SELECT, UPDATE, DELETE privileges Database must exist before starting dhamps-vdb Common Database Hosts:\nlocalhost - Local PostgreSQL instance postgres - Docker Compose service name db.example.com - Remote database server IP address - Direct connection to database Security Configuration# Critical security settings for authentication and encryption.\nOption Environment Variable CLI Flag Type Default Required Description Admin Key SERVICE_ADMINKEY --admin-key String - Yes Master API key for admin operations Encryption Key ENCRYPTION_KEY - String - Yes AES-256 key for API key encryption Admin Key (SERVICE_ADMINKEY):\nMaster API key with full administrative privileges Used to create users and manage global resources Generate with: openssl rand -base64 32 Must be kept secure and rotated regularly Transmitted via Authorization: Bearer header Encryption Key (ENCRYPTION_KEY):\nUsed to encrypt user API keys in the database Minimum 32 characters required Uses AES-256-GCM encryption with SHA-256 hashing CRITICAL: If lost, all stored API keys become unrecoverable Cannot be changed without re-encrypting all existing API keys Generate with: openssl rand -hex 32 Must be backed up securely and separately from database Configuration Files# .env File# The recommended way to configure dhamps-vdb. Create a .env file in the project root:\n# Copy template cp template.env .env # Edit with your values nano .envExample .env file:\n# Service Configuration SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 # Database Configuration SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password_here SERVICE_DBNAME=dhamps_vdb # Security Configuration SERVICE_ADMINKEY=generated_admin_key_here ENCRYPTION_KEY=generated_encryption_key_min_32_charsSecurity Notes:\n.env files are in .gitignore by default Never commit .env files to version control Set restrictive permissions: chmod 600 .env Use different keys for dev/staging/production template.env# Starting template for configuration:\n#!/usr/bin/env bash SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8888 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=postgres SERVICE_ADMINKEY=Ch4ngeM3! # Encryption key for API keys in LLM service instances # Must be secure random string, at least 32 characters # Generate with: openssl rand -hex 32 ENCRYPTION_KEY=ChangeThisToASecureRandomKey123456789012Docker Configuration# Docker Compose# The docker-compose.yml file defines the full stack including PostgreSQL:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 environment: POSTGRES_USER: ${SERVICE_DBUSER:-postgres} POSTGRES_PASSWORD: ${SERVICE_DBPASSWORD:-postgres} POSTGRES_DB: ${SERVICE_DBNAME:-dhamps_vdb} ports: - \u0026#34;${POSTGRES_PORT:-5432}:5432\u0026#34; volumes: - postgres_data:/var/lib/postgresql/data dhamps-vdb: build: context: . dockerfile: Dockerfile depends_on: postgres: condition: service_healthy environment: SERVICE_DEBUG: ${SERVICE_DEBUG:-false} SERVICE_HOST: ${SERVICE_HOST:-0.0.0.0} SERVICE_PORT: ${SERVICE_PORT:-8880} SERVICE_DBHOST: ${SERVICE_DBHOST:-postgres} SERVICE_DBPORT: ${SERVICE_DBPORT:-5432} SERVICE_DBUSER: ${SERVICE_DBUSER:-postgres} SERVICE_DBPASSWORD: ${SERVICE_DBPASSWORD:-postgres} SERVICE_DBNAME: ${SERVICE_DBNAME:-dhamps_vdb} SERVICE_ADMINKEY: ${SERVICE_ADMINKEY} ENCRYPTION_KEY: ${ENCRYPTION_KEY} ports: - \u0026#34;${API_PORT:-8880}:8880\u0026#34;Docker-Specific Variables:\nPOSTGRES_PORT - External port for PostgreSQL (default: 5432) API_PORT - External port for dhamps-vdb API (default: 8880) Docker Setup Script# Automated setup using docker-setup.sh:\n# Run automated setup (generates secure keys) ./docker-setup.sh # Start services docker-compose up -d # View logs docker-compose logs -f dhamps-vdbThe script automatically:\nGenerates secure SERVICE_ADMINKEY Generates secure ENCRYPTION_KEY Creates .env file with proper configuration Validates Docker and docker-compose installation Docker Run Command# For standalone container deployment:\ndocker run -d \\ --name dhamps-vdb \\ -e SERVICE_DEBUG=false \\ -e SERVICE_HOST=0.0.0.0 \\ -e SERVICE_PORT=8880 \\ -e SERVICE_DBHOST=db.example.com \\ -e SERVICE_DBPORT=5432 \\ -e SERVICE_DBUSER=dhamps_user \\ -e SERVICE_DBPASSWORD=secure_password \\ -e SERVICE_DBNAME=dhamps_vdb \\ -e SERVICE_ADMINKEY=admin_key_here \\ -e ENCRYPTION_KEY=encryption_key_here \\ -p 8880:8880 \\ dhamps-vdb:latestExternal Database# Using docker-compose.external-db.yml for external PostgreSQL:\n# Set database connection in .env SERVICE_DBHOST=db.external.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdb # Start without bundled PostgreSQL docker-compose -f docker-compose.external-db.yml up -dConfiguration Scenarios# Development Environment# Optimized for local development with verbose logging:\n# .env for development SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb_dev SERVICE_ADMINKEY=dev-admin-key-not-for-production ENCRYPTION_KEY=dev-encryption-key-at-least-32-charsStart service:\n./dhamps-vdbDocker Development# Docker-based development with hot reload:\n# .env for Docker development SERVICE_DEBUG=true SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=postgres SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=dev-admin-key ENCRYPTION_KEY=dev-encryption-32-chars-minimumStart with:\ndocker-compose upProduction Environment# Production-ready configuration with security hardening:\n# .env for production SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=prod-db.internal.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod_user SERVICE_DBPASSWORD=\u0026lt;from-secrets-manager\u0026gt; SERVICE_DBNAME=dhamps_vdb_prod SERVICE_ADMINKEY=\u0026lt;from-secrets-manager\u0026gt; ENCRYPTION_KEY=\u0026lt;from-secrets-manager\u0026gt;Production Best Practices:\nUse secrets management (Vault, AWS Secrets Manager, etc.) Disable debug logging (SERVICE_DEBUG=false) Use dedicated database user (not superuser) Enable SSL/TLS for database connections Deploy behind reverse proxy (nginx, Traefik) Set up monitoring and alerting Regular key rotation (except ENCRYPTION_KEY) Firewall rules to restrict access Testing Environment# Configuration for running tests:\n# Tests use testcontainers - no external config needed go test -v ./...Test-specific setup:\n# Enable Docker for testcontainers systemctl --user start podman.socket export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock # Run tests go test -v ./...Validation and Verification# Startup Validation# dhamps-vdb validates configuration on startup:\nRequired variables check - Fails if missing Database connection test - Verifies connectivity Schema migration - Applies pending migrations Extension check - Verifies pgvector is available Configuration Test# Verify configuration is working:\n# Check service health curl http://localhost:8880/docs # Test admin authentication curl -X GET http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer ${SERVICE_ADMINKEY}\u0026#34; # Check database connectivity docker-compose exec dhamps-vdb echo \u0026#34;Config OK\u0026#34;Common Issues# Missing Required Variables:\nError: SERVICE_ADMINKEY environment variable is not setSolution: Set all required variables.\nDatabase Connection Failed:\nError: failed to connect to databaseSolution: Verify SERVICE_DBHOST, credentials, and that PostgreSQL is running.\nInvalid Encryption Key:\nError: ENCRYPTION_KEY must be at least 32 charactersSolution: Generate proper key with openssl rand -hex 32.\nPort Already in Use:\nError: bind: address already in useSolution: Change SERVICE_PORT or stop conflicting service.\nGenerating Secure Keys# Admin Key Generation# # Base64 encoded (recommended) openssl rand -base64 32 # Hex encoded (alternative) openssl rand -hex 24 # Output example: # Kx7mP9nQ2rT5vY8zA1bC4dF6gH9jK0lM3nP5qR7sT9u=Encryption Key Generation# # 32-byte hex key (required format) openssl rand -hex 32 # Output example: # a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6Secure Key Storage# Development:\nStore in .env file (not committed) Use password manager for team sharing Production:\nUse secrets management system Rotate admin key every 90 days Never rotate encryption key (breaks existing API keys) Store encryption key backup separately from database Environment-Specific Examples# Local with External PostgreSQL# SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=192.168.1.100 SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=user_password SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=$(openssl rand -base64 32) ENCRYPTION_KEY=$(openssl rand -hex 32)Kubernetes ConfigMap + Secrets# ConfigMap:\napiVersion: v1 kind: ConfigMap metadata: name: dhamps-vdb-config data: SERVICE_DEBUG: \u0026#34;false\u0026#34; SERVICE_HOST: \u0026#34;0.0.0.0\u0026#34; SERVICE_PORT: \u0026#34;8880\u0026#34; SERVICE_DBHOST: \u0026#34;postgres-service\u0026#34; SERVICE_DBPORT: \u0026#34;5432\u0026#34; SERVICE_DBUSER: \u0026#34;dhamps_user\u0026#34; SERVICE_DBNAME: \u0026#34;dhamps_vdb\u0026#34;Secrets:\napiVersion: v1 kind: Secret metadata: name: dhamps-vdb-secrets type: Opaque stringData: SERVICE_DBPASSWORD: \u0026#34;secure_db_password\u0026#34; SERVICE_ADMINKEY: \u0026#34;secure_admin_key\u0026#34; ENCRYPTION_KEY: \u0026#34;secure_encryption_key_32_chars_min\u0026#34;Docker Swarm Secrets# # Create secrets echo \u0026#34;admin_key_here\u0026#34; | docker secret create dhamps_admin_key - echo \u0026#34;encryption_key\u0026#34; | docker secret create dhamps_encryption_key - # Reference in stack file services: dhamps-vdb: secrets: - dhamps_admin_key - dhamps_encryption_key environment: SERVICE_ADMINKEY_FILE: /run/secrets/dhamps_admin_key ENCRYPTION_KEY_FILE: /run/secrets/dhamps_encryption_keyRelated Documentation# Getting Started - Installation Getting Started - Quick Start Deployment - Docker Deployment - Database Setup Deployment - Security Reference - Database Schema "},{"id":3,"href":"/dhamps-vdb/deployment/docker/","title":"Docker Deployment","section":"Deployment","content":"Docker Deployment# This guide covers production-focused Docker deployment for dhamps-vdb.\nOverview# For detailed Docker setup instructions, see Getting Started with Docker. This page focuses on production deployment considerations.\nProduction Deployment# Prerequisites# Docker Engine 20.10+ Docker Compose 2.0+ (or docker-compose 1.29+) PostgreSQL 11+ with pgvector extension (included in compose setup) Quick Production Setup# # Clone repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Generate secure keys ./docker-setup.sh # Review and customize .env nano .env # Deploy docker-compose up -dProduction Considerations# Use Reverse Proxy# Always run behind a reverse proxy (nginx, Traefik, Caddy) for:\nHTTPS/TLS termination Request filtering Rate limiting Load balancing Example nginx configuration:\nupstream dhamps-vdb { server localhost:8880; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://dhamps-vdb; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }Container Resource Limits# Set resource limits in docker-compose.yml:\nservices: dhamps-vdb: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 2G reservations: cpus: \u0026#39;0.5\u0026#39; memory: 512M postgres: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 4G reservations: cpus: \u0026#39;1\u0026#39; memory: 2GUse Specific Image Tags# Avoid latest in production:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 # Specific version dhamps-vdb: image: dhamps-vdb:v0.1.0 # Tag your buildsHealth Monitoring# The image includes health checks. Monitor with:\n# Check health status docker inspect --format=\u0026#39;{{.State.Health.Status}}\u0026#39; dhamps-vdb # View health check logs docker inspect --format=\u0026#39;{{range .State.Health.Log}}{{.Output}}{{end}}\u0026#39; dhamps-vdb # Integrate with monitoring (Prometheus, etc.)Logging# Configure logging drivers in docker-compose.yml:\nservices: dhamps-vdb: logging: driver: \u0026#34;json-file\u0026#34; options: max-size: \u0026#34;10m\u0026#34; max-file: \u0026#34;3\u0026#34;Or use centralized logging:\nservices: dhamps-vdb: logging: driver: \u0026#34;syslog\u0026#34; options: syslog-address: \u0026#34;tcp://logserver:514\u0026#34;External Database Deployment# For production, consider using a managed PostgreSQL service or separate database server.\nRequirements# PostgreSQL 11+ with pgvector extension Network connectivity from container to database Database user with appropriate privileges See Database Setup for detailed instructions.\nConfiguration# Update .env:\nSERVICE_DBHOST=db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdbModify docker-compose.yml to remove postgres service:\nservices: dhamps-vdb: build: . ports: - \u0026#34;8880:8880\u0026#34; env_file: .env restart: unless-stoppedScaling and High Availability# Horizontal Scaling# Run multiple instances behind a load balancer:\nservices: dhamps-vdb: build: . deploy: replicas: 3 restart_policy: condition: on-failureNote: All instances must connect to the same database.\nDatabase Replication# For high availability:\nUse PostgreSQL replication (streaming or logical) Consider read replicas for read-heavy workloads Point write operations to primary, reads to replicas Backup Strategy# Database Backups# # Automated daily backups 0 2 * * * docker-compose exec -T postgres pg_dump -U postgres dhamps_vdb | gzip \u0026gt; /backups/dhamps-vdb-$(date +\\%Y\\%m\\%d).sql.gz # Keep last 30 days find /backups -name \u0026#34;dhamps-vdb-*.sql.gz\u0026#34; -mtime +30 -deleteVolume Backups# # Backup Docker volume docker run --rm -v dhamps-vdb_postgres_data:/data -v /backups:/backup alpine tar czf /backup/postgres-data-$(date +\\%Y\\%m\\%d).tar.gz /dataEnvironment Configuration Backups# # Backup .env (securely!) gpg --encrypt --recipient admin@example.com .env \u0026gt; .env.gpgTroubleshooting# Container Performance Issues# # Check resource usage docker stats # Check container logs docker-compose logs -f --tail=100 dhamps-vdb # Check slow queries (if database is slow) docker-compose exec postgres psql -U postgres -d dhamps_vdb -c \u0026#34;SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;\u0026#34;Network Connectivity Issues# # Test database connection from container docker-compose exec dhamps-vdb nc -zv postgres 5432 # Check DNS resolution docker-compose exec dhamps-vdb nslookup postgres # Test API from inside container docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docsUpdate and Rollback# # Update to new version docker-compose pull docker-compose up -d # Rollback if needed docker-compose down docker-compose up -d --force-recreateSecurity Best Practices# See Security Guide for comprehensive security recommendations Use Environment Variables Guide for proper configuration Never expose database port publicly Use strong, randomly generated keys (see ./docker-setup.sh) Keep Docker and images updated Run containers as non-root (already configured) Further Reading# Docker Official Documentation PostgreSQL Docker Hub pgvector Extension Database Setup Guide Environment Variables Reference Security Best Practices "},{"id":4,"href":"/dhamps-vdb/api/endpoints/","title":"Endpoints","section":"API Reference","content":"API Endpoints# Complete reference for all dhamps-vdb API endpoints.\nEndpoint Categories# Users - User management Projects - Project operations LLM Services - LLM service instances API Standards - API standard definitions Embeddings - Embedding storage and retrieval Similars - Similarity search Endpoint Format# All endpoints follow the pattern:\n{METHOD} /v1/{resource}/{user}/{identifier}Where:\nMETHOD: HTTP method (GET, POST, PUT, DELETE, PATCH) resource: Resource type (users, projects, embeddings, etc.) user: User handle (owner of the resource) identifier: Specific resource identifier Authentication# Most endpoints require authentication via the Authorization header:\nAuthorization: Bearer your_api_key_herePublic projects allow unauthenticated access to read operations.\n"},{"id":5,"href":"/dhamps-vdb/getting-started/","title":"Getting Started","section":"dhamps-vdb Documentation","content":"Getting Started with dhamps-vdb# This section helps you get dhamps-vdb up and running quickly. Whether you\u0026rsquo;re using Docker or compiling from source, you\u0026rsquo;ll find everything you need to start using the vector database API.\nWhat You\u0026rsquo;ll Learn# How to install and run dhamps-vdb How to configure the service for your environment Basic usage patterns and workflows Creating your first project and embeddings Prerequisites# Before you begin, ensure you have:\nPostgreSQL 11+ with pgvector extension (or use the provided Docker setup) Go 1.21+ (if compiling from source) Docker and Docker Compose (for containerized deployment) Quick Links# Installation - Compile and install dhamps-vdb Docker Deployment - Run with Docker (recommended) Configuration - Environment variables and options Quick Start - Your first API requests First Project - Complete walkthrough "},{"id":6,"href":"/dhamps-vdb/getting-started/installation/","title":"Installation","section":"Getting Started","content":"Installation# Install dhamps-vdb by compiling from source.\nPrerequisites# Go 1.21 or later PostgreSQL 11+ with pgvector extension sqlc for code generation Quick Install# # Clone the repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Install dependencies and generate code go get ./... sqlc generate --no-remote # Build the binary go build -o build/dhamps-vdb main.goDetailed Steps# 1. Install Dependencies# Download all Go module dependencies:\ngo get ./...2. Generate Database Code# Generate type-safe database queries using sqlc:\nsqlc generate --no-remoteThis creates Go code from SQL queries in internal/database/queries/.\n3. Build the Application# Compile the application:\ngo build -o build/dhamps-vdb main.goThe binary will be created at build/dhamps-vdb.\nRunning Without Building# You can run the application directly without building a binary:\ngo run main.goThis is useful during development but slower than running a pre-built binary.\nVerify Installation# Check that the binary was created successfully:\n./build/dhamps-vdb --helpYou should see the available command-line options.\nNext Steps# After installation, you need to:\nSet up the database Configure environment variables Run the service System Requirements# Memory: Minimum 512MB RAM (2GB+ recommended for production) Disk: Minimal (\u0026lt; 50MB for binary, database size varies) CPU: Any modern CPU (multi-core recommended for concurrent requests) Troubleshooting# sqlc Command Not Found# Install sqlc:\ngo install github.com/sqlc-dev/sqlc/cmd/sqlc@latestMake sure $GOPATH/bin is in your PATH.\nBuild Errors# Ensure you\u0026rsquo;re using Go 1.21 or later:\ngo versionClean the build cache if you encounter issues:\ngo clean -cache go build -o build/dhamps-vdb main.goMissing Dependencies# Force update all dependencies:\ngo mod download go get -u ./..."},{"id":7,"href":"/dhamps-vdb/guides/rag-workflow/","title":"RAG Workflow Guide","section":"Guides","content":"Complete RAG Workflow Guide# This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.\nOverview# A typical RAG workflow involves:\nGenerate embeddings from your text content (using an external LLM service) Upload embeddings to dhamps-vdb Search for similar documents based on a query Retrieve the relevant context Use the context with an LLM to generate responses Prerequisites# Access to dhamps-vdb API with a valid API key An external LLM service for generating embeddings (e.g., OpenAI, Cohere) Text content you want to process Step 1: Generate Embeddings Externally# First, use your chosen LLM service to generate embeddings for your text content. Here\u0026rsquo;s an example using OpenAI\u0026rsquo;s API:\nimport openai # Initialize OpenAI client client = openai.OpenAI(api_key=\u0026#34;your-openai-key\u0026#34;) # Generate embeddings for your text text = \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34; response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=text, dimensions=3072 ) embedding_vector = response.data[0].embeddingStep 2: Create LLM Service Instance# Before uploading embeddings, create an LLM service instance in dhamps-vdb that matches your embedding configuration:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }Step 3: Create a Project# Create a project to organize your embeddings:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-documents\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Document embeddings for RAG\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39;Step 4: Upload Embeddings to dhamps-vdb# Upload your pre-generated embeddings along with metadata and optional text content:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.021, -0.015, 0.043, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;example.txt\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34; } }] }\u0026#39;Tip: Upload multiple embeddings in batches for efficiency (see Batch Operations Guide).\nStep 5: Search for Similar Documents# When you need to retrieve relevant context for a query:\nOption A: Search by Stored Document ID# If you already have a document in your database that represents your query:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/my-documents/doc001?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Option B: Search with Raw Query Embedding# Generate an embedding for your query and search without storing it:\n# Generate query embedding query = \u0026#34;What animals are mentioned?\u0026#34; query_response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=query, dimensions=3072 ) query_vector = query_response.data[0].embeddingcurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/my-documents?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;my-documents\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc042\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc103\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Step 6: Retrieve Context Documents# Retrieve the full content and metadata for the most similar documents:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-documents/doc001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;example.txt\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34; }, \u0026#34;vector_dim\u0026#34;: 3072 }Step 7: Use Context with LLM# Combine the retrieved context with your original query to generate an informed response:\n# Collect context from similar documents context_docs = [] for result in similarity_results[\u0026#39;results\u0026#39;][:3]: doc = get_document(result[\u0026#39;id\u0026#39;]) # Your function to fetch document context_docs.append(doc[\u0026#39;text\u0026#39;]) # Build context string context = \u0026#34;\\n\\n\u0026#34;.join(context_docs) # Generate response with context response = client.chat.completions.create( model=\u0026#34;gpt-4\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Answer based on the provided context.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: f\u0026#34;Context:\\n{context}\\n\\nQuestion: {query}\u0026#34;} ] ) answer = response.choices[0].message.contentComplete Python Example# Here\u0026rsquo;s a complete example combining all steps:\nimport openai import requests # Configuration DHAMPS_API = \u0026#34;https://api.example.com\u0026#34; DHAMPS_KEY = \u0026#34;your-dhamps-api-key\u0026#34; OPENAI_KEY = \u0026#34;your-openai-key\u0026#34; # Initialize OpenAI client = openai.OpenAI(api_key=OPENAI_KEY) def embed_and_store(text_id, text, metadata=None): \u0026#34;\u0026#34;\u0026#34;Generate embedding and store in dhamps-vdb\u0026#34;\u0026#34;\u0026#34; # Generate embedding response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=text, dimensions=3072 ) vector = response.data[0].embedding # Upload to dhamps-vdb requests.post( f\u0026#34;{DHAMPS_API}/v1/embeddings/alice/my-documents\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: text_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: text, \u0026#34;metadata\u0026#34;: metadata or {} }] } ) def search_similar(query, count=5): \u0026#34;\u0026#34;\u0026#34;Search for similar documents using query text\u0026#34;\u0026#34;\u0026#34; # Generate query embedding response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=query, dimensions=3072 ) query_vector = response.data[0].embedding # Search in dhamps-vdb result = requests.post( f\u0026#34;{DHAMPS_API}/v1/similars/alice/my-documents?count={count}\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;vector\u0026#34;: query_vector} ) return result.json()[\u0026#39;results\u0026#39;] def retrieve_context(doc_ids): \u0026#34;\u0026#34;\u0026#34;Retrieve full document content\u0026#34;\u0026#34;\u0026#34; docs = [] for doc_id in doc_ids: response = requests.get( f\u0026#34;{DHAMPS_API}/v1/embeddings/alice/my-documents/{doc_id}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;} ) docs.append(response.json()) return docs def rag_query(query): \u0026#34;\u0026#34;\u0026#34;Complete RAG workflow\u0026#34;\u0026#34;\u0026#34; # Search for similar documents similar = search_similar(query, count=3) # Retrieve context context_docs = retrieve_context([r[\u0026#39;id\u0026#39;] for r in similar]) context = \u0026#34;\\n\\n\u0026#34;.join([doc[\u0026#39;text\u0026#39;] for doc in context_docs]) # Generate answer with LLM response = client.chat.completions.create( model=\u0026#34;gpt-4\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Answer based on the provided context.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: f\u0026#34;Context:\\n{context}\\n\\nQuestion: {query}\u0026#34;} ] ) return response.choices[0].message.content # Usage embed_and_store(\u0026#34;doc001\u0026#34;, \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, {\u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34;}) answer = rag_query(\u0026#34;What animals are mentioned?\u0026#34;) print(answer)Best Practices# Batch Upload: Upload embeddings in batches of 100-1000 for better performance Use Metadata: Include rich metadata for better filtering and organization Set Thresholds: Use similarity thresholds (e.g., 0.7) to filter low-quality matches Cache Embeddings: Cache generated embeddings to avoid redundant API calls Monitor Dimensions: Ensure all embeddings use consistent dimensions (3072 for text-embedding-3-large) Advanced Features# Metadata Filtering# Exclude certain documents from search results using metadata filters:\n# Exclude documents from the same author as the query curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/my-documents/doc001?metadata_path=author\u0026amp;metadata_value=Alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;See the Metadata Filtering Guide for more details.\nMetadata Validation# Enforce consistent metadata structure using JSON Schema validation:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;category\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;See the Metadata Validation Guide for more details.\nRelated Documentation# Batch Operations Guide - Efficiently upload large datasets Metadata Filtering Guide - Advanced search filtering Metadata Validation Guide - Schema validation Instance Management Guide - Managing LLM service instances Troubleshooting# Dimension Mismatch Error# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch\u0026#34; }Solution: Ensure the vector_dim field matches the dimensions configured in your LLM service instance.\nNo Similar Results# If searches return no results, try:\nLowering the similarity threshold (e.g., from 0.8 to 0.5) Increasing the count parameter Verifying embeddings are uploaded correctly Checking that query embeddings use the same model and dimensions "},{"id":8,"href":"/dhamps-vdb/development/testing/","title":"Testing","section":"Development","content":"Testing Guide# This guide covers how to run and write tests for dhamps-vdb.\nRunning Tests# dhamps-vdb uses integration tests that spin up real PostgreSQL containers using testcontainers. This approach ensures tests run against actual database instances with pgvector support.\nPrerequisites# Using Podman (Recommended for Linux):\n# Start podman socket systemctl --user start podman.socket # Export DOCKER_HOST for testcontainers export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sockUsing Docker:\nTestcontainers works with Docker out of the box. Ensure Docker daemon is running.\nRunning All Tests# # Run all tests with verbose output go test -v ./... # Run tests without verbose output go test ./... # Run tests with coverage go test -cover ./... # Generate coverage report go test -coverprofile=coverage.out ./... go tool cover -html=coverage.outRunning Specific Tests# # Run tests in a specific package go test -v ./internal/handlers # Run a specific test function go test -v ./internal/handlers -run TestCreateUser # Run tests matching a pattern go test -v ./... -run \u0026#34;.*Sharing.*\u0026#34;Test Containers# Tests automatically manage PostgreSQL containers with pgvector:\nContainer is started before tests run Database schema is migrated automatically Container is cleaned up after tests complete Each test suite gets a fresh database state Test Structure# Package Organization# Tests are organized alongside the code they test:\ninternal/ ├── handlers/ │ ├── users.go # Implementation │ ├── users_test.go # Unit/integration tests │ ├── projects.go │ ├── projects_test.go │ ├── projects_sharing_test.go │ ├── embeddings.go │ └── embeddings_test.go ├── database/ │ └── queries.sql # SQL queries for sqlc └── models/ ├── users.go └── projects.goTest Files# Test files follow Go conventions:\nFilename: *_test.go Package: Same as code under test (e.g., package handlers) Test functions: func TestFunctionName(t *testing.T) Test Fixtures# Test data is stored in testdata/:\ntestdata/ ├── postgres/ │ ├── enable-vector.sql # Database initialization │ └── users.yml ├── valid_embeddings.json ├── valid_user.json ├── valid_api_standard_openai_v1.json ├── valid_llm_service_openai-large-full.json └── invalid_embeddings.jsonWriting Tests# Basic Test Structure# package handlers import ( \u0026#34;context\u0026#34; \u0026#34;testing\u0026#34; \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; \u0026#34;github.com/stretchr/testify/assert\u0026#34; ) func TestCreateUser(t *testing.T) { // Setup: Initialize database pool and test data ctx := context.Background() pool := setupTestDatabase(t) defer pool.Close() // Execute: Call function under test result, err := CreateUser(ctx, pool, userData) // Assert: Verify results assert.NoError(t, err) assert.Equal(t, \u0026#34;testuser\u0026#34;, result.UserHandle) }Integration Test Example# func TestProjectSharingWorkflow(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create test users alice := createTestUser(t, pool, \u0026#34;alice\u0026#34;) bob := createTestUser(t, pool, \u0026#34;bob\u0026#34;) // Create project as Alice project := createTestProject(t, pool, alice, \u0026#34;test-project\u0026#34;) // Share project with Bob err := shareProject(t, pool, alice, project.ID, bob.Handle, \u0026#34;reader\u0026#34;) assert.NoError(t, err) // Verify Bob can access project projects := getAccessibleProjects(t, pool, bob) assert.Contains(t, projects, project) }Testing with Testcontainers# func setupTestDatabase(t *testing.T) *pgxpool.Pool { ctx := context.Background() // Create PostgreSQL container with pgvector req := testcontainers.ContainerRequest{ Image: \u0026#34;pgvector/pgvector:0.7.4-pg16\u0026#34;, ExposedPorts: []string{\u0026#34;5432/tcp\u0026#34;}, Env: map[string]string{ \u0026#34;POSTGRES_PASSWORD\u0026#34;: \u0026#34;password\u0026#34;, \u0026#34;POSTGRES_DB\u0026#34;: \u0026#34;testdb\u0026#34;, }, WaitStrategy: wait.ForLog(\u0026#34;database system is ready to accept connections\u0026#34;), } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) require.NoError(t, err) // Get connection details host, _ := container.Host(ctx) port, _ := container.MappedPort(ctx, \u0026#34;5432\u0026#34;) // Connect and migrate connString := fmt.Sprintf(\u0026#34;postgres://postgres:password@%s:%s/testdb\u0026#34;, host, port.Port()) pool := connectAndMigrate(t, connString) return pool }Validation Testing# Test dimension and metadata validation:\nfunc TestEmbeddingDimensionValidation(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create LLM service with 1536 dimensions llmService := createTestLLMService(t, pool, \u0026#34;openai\u0026#34;, 1536) // Try to insert embedding with wrong dimensions embedding := models.Embedding{ TextID: \u0026#34;doc1\u0026#34;, Vector: make([]float32, 768), // Wrong size! VectorDim: 768, } err := insertEmbedding(t, pool, embedding) assert.Error(t, err) assert.Contains(t, err.Error(), \u0026#34;dimension mismatch\u0026#34;) } func TestMetadataSchemaValidation(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create project with metadata schema schema := `{\u0026#34;type\u0026#34;:\u0026#34;object\u0026#34;,\u0026#34;properties\u0026#34;:{\u0026#34;author\u0026#34;:{\u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;}},\u0026#34;required\u0026#34;:[\u0026#34;author\u0026#34;]}` project := createProjectWithSchema(t, pool, \u0026#34;alice\u0026#34;, \u0026#34;test\u0026#34;, schema) // Valid metadata should succeed validMeta := `{\u0026#34;author\u0026#34;:\u0026#34;John Doe\u0026#34;}` err := insertEmbeddingWithMetadata(t, pool, project.ID, validMeta) assert.NoError(t, err) // Invalid metadata should fail invalidMeta := `{\u0026#34;year\u0026#34;:2024}` // Missing required \u0026#39;author\u0026#39; err = insertEmbeddingWithMetadata(t, pool, project.ID, invalidMeta) assert.Error(t, err) }Table-Driven Tests# For testing multiple scenarios:\nfunc TestSimilaritySearch(t *testing.T) { tests := []struct { name string threshold float32 limit int expected int }{ {\u0026#34;high threshold\u0026#34;, 0.9, 10, 2}, {\u0026#34;medium threshold\u0026#34;, 0.7, 10, 5}, {\u0026#34;low threshold\u0026#34;, 0.5, 10, 8}, {\u0026#34;with limit\u0026#34;, 0.5, 3, 3}, } pool := setupTestDatabase(t) defer pool.Close() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { results := searchSimilar(t, pool, \u0026#34;doc1\u0026#34;, tt.threshold, tt.limit) assert.Len(t, results, tt.expected) }) } }Cleanup Testing# Verify database cleanup:\nfunc TestDatabaseCleanup(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create test data user := createTestUser(t, pool, \u0026#34;alice\u0026#34;) project := createTestProject(t, pool, user, \u0026#34;test\u0026#34;) createTestEmbeddings(t, pool, project, 10) // Delete user (should cascade) err := deleteUser(t, pool, user.Handle) assert.NoError(t, err) // Verify all related data is deleted assertTableEmpty(t, pool, \u0026#34;users\u0026#34;) assertTableEmpty(t, pool, \u0026#34;projects\u0026#34;) assertTableEmpty(t, pool, \u0026#34;embeddings\u0026#34;) }Test Helpers# Create helper functions to reduce boilerplate:\n// setupTestDatabase initializes a test database with migrations func setupTestDatabase(t *testing.T) *pgxpool.Pool { // Implementation... } // createTestUser creates a user for testing func createTestUser(t *testing.T, pool *pgxpool.Pool, handle string) *models.User { // Implementation... } // createTestProject creates a project for testing func createTestProject(t *testing.T, pool *pgxpool.Pool, owner *models.User, handle string) *models.Project { // Implementation... } // assertTableEmpty verifies a table has no rows func assertTableEmpty(t *testing.T, pool *pgxpool.Pool, tableName string) { var count int err := pool.QueryRow(context.Background(), fmt.Sprintf(\u0026#34;SELECT COUNT(*) FROM %s\u0026#34;, tableName)).Scan(\u0026amp;count) require.NoError(t, err) assert.Equal(t, 0, count, \u0026#34;table %s should be empty\u0026#34;, tableName) }CI/CD Integration# GitHub Actions# Example GitHub Actions workflow:\nname: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v4 with: go-version: \u0026#39;1.21\u0026#39; - name: Run tests run: | go test -v -race -coverprofile=coverage.txt ./... - name: Upload coverage uses: codecov/codecov-action@v3 with: files: ./coverage.txtLocal CI Testing# Test as CI would:\n# Clean test with race detection go clean -testcache go test -v -race ./... # Test with coverage go test -coverprofile=coverage.out ./... # Check for test caching issues go test -count=1 ./...Best Practices# 1. Use testcontainers for Real Databases# Don\u0026rsquo;t mock the database layer Test against actual PostgreSQL with pgvector Catch SQL-specific issues 2. Isolate Tests# Each test should be independent Use transactions or cleanup between tests Don\u0026rsquo;t rely on test execution order 3. Test Validation Logic# Test dimension validation Test metadata schema validation Test authorization checks 4. Test Error Conditions# Invalid input Missing resources (404) Unauthorized access (403) Constraint violations 5. Keep Tests Fast# Use parallel tests where possible: t.Parallel() Reuse test database containers when appropriate Avoid unnecessary sleeps 6. Use Descriptive Names# // Good func TestProjectSharingWithReaderRole(t *testing.T) // Less clear func TestSharing(t *testing.T)7. Assert Meaningfully# // Good - specific assertion assert.Equal(t, \u0026#34;alice\u0026#34;, project.Owner) // Less helpful assert.True(t, project.Owner == \u0026#34;alice\u0026#34;)Debugging Tests# Verbose Output# # See all test output go test -v ./internal/handlers # See SQL queries (if logging enabled) SERVICE_DEBUG=true go test -v ./...Run Single Test# # Focus on one failing test go test -v ./internal/handlers -run TestCreateProjectKeep Test Database Running# For manual inspection, prevent container cleanup:\nfunc TestWithDebugContainer(t *testing.T) { container := setupContainer(t) // Comment out: defer container.Terminate(ctx) host, port := getContainerDetails(container) t.Logf(\u0026#34;Database running at %s:%s\u0026#34;, host, port) // Run test... // Container stays running for manual inspection time.Sleep(time.Hour) }Then connect with psql:\npsql -h localhost -p \u0026lt;port\u0026gt; -U postgres -d testdbCommon Issues# Container Startup Failures# # Check Docker/Podman is running systemctl --user status podman.socket # Check for port conflicts netstat -tulpn | grep 5432 # Clean up containers podman rm -f $(podman ps -aq)Test Timeouts# Increase timeout for slow containers:\nWaitStrategy: wait.ForLog(\u0026#34;ready\u0026#34;).WithStartupTimeout(2 * time.Minute)Permission Errors# Ensure test user has proper permissions:\nGRANT ALL PRIVILEGES ON DATABASE testdb TO testuser; GRANT ALL ON SCHEMA public TO testuser;Further Reading# Go Testing Documentation Testcontainers for Go Testify Assertions Table-Driven Tests in Go "},{"id":9,"href":"/dhamps-vdb/api/endpoints/users/","title":"Users","section":"Endpoints","content":"Users Endpoint# Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.\nEndpoints# List All Users# Get a list of all registered user handles.\nEndpoint: GET /v1/users\nAuthentication: Admin only\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;users\u0026#34;: [\u0026#34;alice\u0026#34;, \u0026#34;bob\u0026#34;, \u0026#34;charlie\u0026#34;] } Create User# Register a new user and generate their API key.\nEndpoint: POST /v1/users\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Parameters:\nuser_handle (string, required): Unique identifier for the user (alphanumeric, hyphens, underscores) name (string, optional): User\u0026rsquo;s full name email (string, optional): User\u0026rsquo;s email address Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; }⚠️ Important: The api_key is only returned once during user creation. Store it securely - it cannot be recovered later.\nError Responses:\n400 Bad Request: Invalid user handle or missing required fields 409 Conflict: User handle already exists Get User Information# Retrieve information about a specific user.\nEndpoint: GET /v1/users/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Note: API key is never returned in GET responses for security reasons.\nCreate or Update User (PUT)# Register a new user with a specific handle or update existing user information.\nEndpoint: PUT /v1/users/{username}\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Example:\ncurl -X PUT \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; } Delete User# Delete a user and all their associated resources (projects, LLM services, embeddings).\nEndpoint: DELETE /v1/users/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;User alice deleted successfully\u0026#34; }⚠️ Warning: This operation is irreversible and will delete:\nAll projects owned by the user All LLM service instances owned by the user All embeddings in the user\u0026rsquo;s projects All sharing relationships Partial Update (PATCH)# Update specific user fields without providing all user data.\nEndpoint: PATCH /v1/users/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34; }Example:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;email\u0026#34;: \u0026#34;newemail@example.com\u0026#34; }\u0026#39;See PATCH Updates for more details.\nUser Properties# Field Type Required Description user_handle string Yes Unique identifier (alphanumeric, hyphens, underscores) name string No User\u0026rsquo;s full name email string No User\u0026rsquo;s email address api_key string Read-only Generated API key (only returned on creation) Special User: _system# The _system user is a special internal user that:\nOwns global LLM service definitions Cannot be used for authentication Cannot be deleted Is created automatically during database migrations Users can create LLM service instances from _system definitions.\nCommon Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid user_handle: must be alphanumeric with hyphens or underscores\u0026#34; }401 Unauthorized# { \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Related Documentation# Authentication - API key authentication details Projects - Project management LLM Services - LLM service instances "},{"id":10,"href":"/dhamps-vdb/concepts/","title":"Concepts","section":"dhamps-vdb Documentation","content":"Core Concepts# Understanding the key concepts behind dhamps-vdb helps you make the most of its features. This section explains the fundamental building blocks and how they work together.\nOverview# dhamps-vdb is a vector database designed for Retrieval Augmented Generation (RAG) workflows. It stores embeddings with metadata and provides fast similarity search capabilities.\nKey Components# Users - Individual accounts with authentication Projects - Containers for embeddings with access control Embeddings - Vector representations of text with metadata LLM Services - Configurations for embedding models Similarity Search - Find similar documents using vector distance Architecture# dhamps-vdb uses PostgreSQL with the pgvector extension for vector operations. It provides a RESTful API with token-based authentication and supports multi-user environments with project sharing.\n"},{"id":11,"href":"/dhamps-vdb/getting-started/configuration/","title":"Configuration","section":"Getting Started","content":"Configuration# Configure dhamps-vdb using environment variables or command-line options.\nEnvironment Variables# All configuration can be set via environment variables. Use a .env file to keep sensitive information secure.\nService Configuration# Variable Description Default Required SERVICE_DEBUG Enable debug logging true No SERVICE_HOST Hostname to listen on localhost No SERVICE_PORT Port to listen on 8880 No Database Configuration# Variable Description Default Required SERVICE_DBHOST Database hostname localhost Yes SERVICE_DBPORT Database port 5432 No SERVICE_DBUSER Database username postgres Yes SERVICE_DBPASSWORD Database password password Yes SERVICE_DBNAME Database name postgres Yes Security Configuration# Variable Description Default Required SERVICE_ADMINKEY Admin API key for administrative operations - Yes ENCRYPTION_KEY Encryption key for API keys (32+ characters) - Yes Configuration File# Create a .env file in the project root:\n# Service Configuration SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 # Database Configuration SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdb # Security SERVICE_ADMINKEY=your-secure-admin-key-here ENCRYPTION_KEY=your-32-character-encryption-key-minimumCommand-Line Options# You can also provide configuration via command-line flags:\n./dhamps-vdb \\ --debug \\ -p 8880 \\ --db-host localhost \\ --db-port 5432 \\ --db-user dhamps_user \\ --db-password secure_password \\ --db-name dhamps_vdb \\ --admin-key your-admin-keyGenerating Secure Keys# Admin Key# Generate a secure admin key:\nopenssl rand -base64 32Encryption Key# Generate a secure encryption key (minimum 32 characters):\nopenssl rand -hex 32Configuration Priority# Configuration is loaded in the following order (later sources override earlier ones):\nDefault values (from options.go) Environment variables .env file Command-line flags Security Best Practices# Never commit .env files to version control Use strong, randomly generated keys for production Ensure .env file permissions are restrictive (chmod 600 .env) Store encryption key securely - losing it means losing access to encrypted API keys Use different keys for development and production environments Example Configuration# Development# # .env (development) SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=password SERVICE_DBNAME=dhamps_vdb_dev SERVICE_ADMINKEY=dev-admin-key-change-me ENCRYPTION_KEY=dev-encryption-key-32-chars-minProduction# # .env (production) SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=prod-db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod SERVICE_DBPASSWORD=$(cat /run/secrets/db_password) SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=$(cat /run/secrets/admin_key) ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)Validation# The service validates configuration on startup and will exit with an error if required variables are missing.\nNext Steps# After configuration:\nRun the Quick Start tutorial Create your first project Review deployment options "},{"id":12,"href":"/dhamps-vdb/development/contributing/","title":"Contributing","section":"Development","content":"Contributing Guide# Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.\nDevelopment Setup# Prerequisites# Go 1.21+: Download Go PostgreSQL 16+: With pgvector extension sqlc: For generating type-safe database code Docker/Podman: For running tests Git: For version control Clone and Build# # Clone repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Install dependencies go get ./... # Generate sqlc code sqlc generate --no-remote # Build application go build -o build/dhamps-vdb main.go # Or run directly go run main.goEnvironment Setup# Create a .env file for local development:\n# Copy template cp template.env .env # Edit with your settings SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_ADMINKEY=your-secure-admin-key-here # Database settings SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=password SERVICE_DBNAME=dhamps_vdb_dev # Encryption key (32+ characters) ENCRYPTION_KEY=your-secure-encryption-key-min-32-charsImportant: Never commit .env files (already in .gitignore)\nDatabase Setup# For local development:\n# Start PostgreSQL with pgvector podman run -p 5432:5432 \\ -e POSTGRES_PASSWORD=password \\ -e POSTGRES_DB=dhamps_vdb_dev \\ pgvector/pgvector:0.7.4-pg16 # Or use docker-compose docker-compose up -d # Application auto-migrates on startup go run main.goVerify Setup# # Check application starts go run main.go # In another terminal, test API curl http://localhost:8880/docs # Run tests go test -v ./...Code Style# Go Formatting# dhamps-vdb follows standard Go conventions:\n# Format all code go fmt ./... # Check for common issues go vet ./... # Run linter (if installed) golangci-lint runCode Organization# Follow existing patterns:\n// Package comment at top of file package handlers import ( // Standard library first \u0026#34;context\u0026#34; \u0026#34;fmt\u0026#34; // External packages \u0026#34;github.com/danielgtaylor/huma/v2\u0026#34; \u0026#34;github.com/jackc/pgx/v5/pgxpool\u0026#34; // Internal packages \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/models\u0026#34; ) // Exported function with doc comment // GetUsers retrieves all users from the database func GetUsers(ctx context.Context, pool *pgxpool.Pool) ([]models.User, error) { // Implementation }Naming Conventions# Files:\nhandlers/users.go - Implementation handlers/users_test.go - Tests handlers/users_sharing_test.go - Specific feature tests Functions:\nGetUsers() - List/retrieve multiple GetUser() - Retrieve single CreateUser() - Create new UpdateUser() - Update existing DeleteUser() - Delete LinkUserToProject() - Create association IsProjectOwner() - Boolean check Database Queries (in queries.sql):\n-- name: GetAllUsers :many -- name: RetrieveUserByHandle :one -- name: UpsertUser :one -- name: DeleteUser :exec Error Handling# // Return errors, don\u0026#39;t panic func CreateUser(ctx context.Context, pool *pgxpool.Pool, user models.User) error { if user.Handle == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;user handle is required\u0026#34;) } // Wrap errors with context err := db.InsertUser(ctx, user) if err != nil { return fmt.Errorf(\u0026#34;failed to insert user: %w\u0026#34;, err) } return nil } // Use specific error responses in handlers func handleCreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { err := CreateUser(ctx, pool, input.Body) if err != nil { return nil, huma.Error400BadRequest(\u0026#34;invalid user data\u0026#34;, err) } return \u0026amp;CreateUserOutput{Body: result}, nil }Comments# Comment public APIs and complex logic:\n// GetAccessibleProjects returns all projects the user can access. // This includes projects owned by the user and projects shared with them. // Results are paginated using limit and offset. func GetAccessibleProjects(ctx context.Context, pool *pgxpool.Pool, userHandle string, limit, offset int) ([]models.Project, error) { // Use UNION ALL for better query performance // See docs/PERFORMANCE_OPTIMIZATION.md for details query := ` SELECT * FROM projects WHERE owner = $1 UNION ALL SELECT p.* FROM projects p INNER JOIN projects_shared_with ps ON p.project_id = ps.project_id WHERE ps.user_handle = $1 ` // Implementation... }Don\u0026rsquo;t over-comment obvious code:\n// Bad - obvious // i is set to 0 i := 0 // Good - explains why // Start from second element (first is header) i := 1Git Workflow# Branching Strategy# # Create feature branch from main git checkout main git pull origin main git checkout -b feature/your-feature-name # Create fix branch git checkout -b fix/issue-description # Create docs branch git checkout -b docs/update-contributing-guideBranch naming:\nfeature/* - New features fix/* - Bug fixes docs/* - Documentation updates test/* - Test improvements refactor/* - Code refactoring Commit Messages# Write clear, descriptive commit messages:\n# Good commit messages git commit -m \u0026#34;Add project sharing functionality\u0026#34; git commit -m \u0026#34;Fix dimension validation for embeddings\u0026#34; git commit -m \u0026#34;Update contributing guide with git workflow\u0026#34; # Multi-line for complex changes git commit -m \u0026#34;Refactor similarity search query - Use UNION ALL for better performance - Add dimension filtering to subqueries - Update tests to verify performance improvement Closes #123\u0026#34;Commit message format:\nFirst line: Brief summary (50 chars or less) Blank line Detailed explanation if needed Reference issues: Closes #123 or Fixes #456 Pull Request Process# Create feature branch\ngit checkout -b feature/my-feature Make changes and commit\ngit add . git commit -m \u0026#34;Add feature description\u0026#34; Keep branch updated\ngit fetch origin git rebase origin/main Push to your fork\ngit push origin feature/my-feature Create Pull Request\nGo to GitHub repository Click \u0026ldquo;New Pull Request\u0026rdquo; Select your branch Fill in PR template PR Review Process\nAutomated tests run Code review by maintainers Address feedback Merge when approved PR Title Format# [Type] Brief description Examples: [Feature] Add project ownership transfer [Fix] Correct dimension validation in embeddings [Docs] Update API documentation for similarity search [Test] Add integration tests for sharing workflow [Refactor] Simplify authentication middlewarePR Description Template# ## Description Brief description of changes ## Motivation Why is this change needed? ## Changes - Change 1 - Change 2 - Change 3 ## Testing How was this tested? - [ ] Unit tests pass - [ ] Integration tests pass - [ ] Manual testing performed ## Related Issues Closes #123 Relates to #456 ## Checklist - [ ] Code follows style guidelines - [ ] Tests added/updated - [ ] Documentation updated - [ ] No breaking changes (or clearly documented)Testing Requirements# All contributions must include tests:\nFor New Features# // Add tests in same package // File: handlers/projects.go func CreateProject(...) { ... } // File: handlers/projects_test.go func TestCreateProject(t *testing.T) { // Test happy path // Test error cases // Test edge cases }For Bug Fixes# // Add regression test func TestBugFix_Issue123(t *testing.T) { // Reproduce the bug // Verify it\u0026#39;s fixed }Test Coverage# Aim for reasonable coverage:\n# Check coverage go test -cover ./... # Generate coverage report go test -coverprofile=coverage.out ./... go tool cover -html=coverage.outTarget coverage: 70%+ for new code\nRunning Tests# # Before submitting PR go test -v ./... # With race detection go test -race ./... # Specific package go test -v ./internal/handlersSee Testing Guide for detailed information.\nDocumentation Updates# When to Update Docs# Update documentation for:\nNew features: Add usage examples API changes: Update endpoint documentation Breaking changes: Clearly document migration path Configuration: New environment variables or options Documentation Structure# docs/content/ ├── getting-started/ # Installation, quickstart ├── concepts/ # Core concepts ├── guides/ # How-to guides ├── api/ # API reference └── development/ # Development docs (this section)Adding Documentation# # Create new doc file cd docs/content/guides cat \u0026gt; new-guide.md \u0026lt;\u0026lt;EOF --- title: \u0026#34;Your Guide Title\u0026#34; weight: 5 --- # Your Guide Content here... EOFHugo Front Matter# All docs need front matter:\n--- title: \u0026#34;Page Title\u0026#34; weight: 1 # Determines order in menu draft: false # Set true for work in progress ---Code Examples in Docs# Include working examples:\n```bash # Example command curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer admin-key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;}\u0026#39; ``` ```go // Example Go code user := models.User{ Handle: \u0026#34;alice\u0026#34;, Name: \u0026#34;Alice Smith\u0026#34;, } err := CreateUser(ctx, pool, user) ```Issue Reporting# Before Creating an Issue# Search existing issues Check documentation Try latest version Prepare reproduction steps Bug Report Template# ## Bug Description Clear description of the bug ## Steps to Reproduce 1. Start application with these settings... 2. Send this request... 3. Observe error... ## Expected Behavior What should happen ## Actual Behavior What actually happens ## Environment - dhamps-vdb version: v0.1.0 - Go version: 1.21.5 - PostgreSQL version: 16.1 - OS: Ubuntu 22.04 ## LogsRelevant error logs here\n## Additional Context Any other relevant informationFeature Request Template# ## Feature Description Clear description of proposed feature ## Use Case Why is this needed? Who benefits? ## Proposed Solution How should it work? ## Alternatives Considered Other approaches you\u0026#39;ve thought about ## Additional Context Examples, mockups, related featuresCode Review Guidelines# For Reviewers# Be constructive: Suggest improvements, don\u0026rsquo;t just criticize Ask questions: \u0026ldquo;Could we handle this case?\u0026rdquo; vs \u0026ldquo;This is wrong\u0026rdquo; Explain reasoning: Help author understand why Approve when ready: Don\u0026rsquo;t be too pedantic on style For Authors# Respond to feedback: Address all comments Ask for clarification: If feedback unclear Don\u0026rsquo;t take it personally: Focus on improving code Update PR: Push changes after addressing feedback What Reviewers Check# Code follows style guidelines Tests are comprehensive Documentation is updated No obvious bugs or security issues Error handling is appropriate Performance considerations addressed Breaking changes documented Release Process# Maintainers handle releases, but contributors should:\nDocument breaking changes in PR description Update CHANGELOG if applicable Tag related issues with milestone Development Best Practices# 1. Start Small# Small PRs are easier to review Focus on one feature/fix per PR Break large changes into multiple PRs 2. Write Tests First# // Write test first (TDD approach) func TestNewFeature(t *testing.T) { // This will fail initially result := NewFeature() assert.Equal(t, expected, result) } // Then implement func NewFeature() Result { // Implementation }3. Use Type Safety# // Generate type-safe queries with sqlc // Edit: internal/database/queries/queries.sql -- name: GetUserByHandle :one SELECT * FROM users WHERE user_handle = $1; // Then regenerate sqlc generate --no-remote // Use generated code user, err := db.GetUserByHandle(ctx, handle)4. Handle Errors Properly# // Don\u0026#39;t ignore errors result, err := SomeFunction() if err != nil { return fmt.Errorf(\u0026#34;operation failed: %w\u0026#34;, err) } // Provide context if err := ValidateInput(input); err != nil { return huma.Error400BadRequest(\u0026#34;invalid input\u0026#34;, err) }5. Keep It Simple# Prefer clarity over cleverness Use standard library when possible Don\u0026rsquo;t over-engineer solutions Getting Help# Resources# Documentation: Browse /docs folder API Docs: Run locally and visit /docs endpoint Code Examples: Check testdata/ for examples Test Files: See how features are tested Communication# GitHub Issues: For bugs and feature requests Pull Requests: For code discussions Code Comments: For implementation questions Asking Questions# Good questions include:\nWhat you\u0026rsquo;re trying to accomplish What you\u0026rsquo;ve already tried Relevant code snippets Error messages (full stack trace) License# By contributing, you agree that your contributions will be licensed under the MIT License.\nRecognition# Contributors are acknowledged in:\nGit commit history GitHub contributors page Release notes (for significant contributions) Thank you for contributing to dhamps-vdb! 🎉\n"},{"id":13,"href":"/dhamps-vdb/reference/database-schema/","title":"Database Schema Reference","section":"Reference","content":"Database Schema Reference# Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.\nOverview# The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in internal/database/migrations/.\nKey Features:\nVector embeddings stored as halfvec for efficient storage HNSW indexes for fast approximate nearest neighbor search Automatic timestamp tracking (created_at, updated_at) Foreign key constraints with CASCADE deletion Role-based access control through association tables Multi-tenancy support (user-owned resources) Schema Migrations# Current schema version is defined by 4 migration files:\n001_create_initial_scheme.sql - Core tables and relationships 002_create_emb_index.sql - HNSW vector indexes 003_add_public_read_flag.sql - Public access support 004_refactor_llm_services_architecture.sql - LLM service architecture refactor Core Tables# users# Stores user accounts with API authentication.\nColumn Type Constraints Description user_handle VARCHAR(20) PRIMARY KEY Unique user identifier (username) name TEXT Full name or display name email TEXT UNIQUE, NOT NULL Email address vdb_key CHAR(64) UNIQUE, NOT NULL API key (64-character hex) created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Indexes:\nPrimary key on user_handle Unique constraint on email Unique constraint on vdb_key Special Users:\n_system - Reserved system user for global LLM service definitions Relationships:\nOwns projects (1:N) Owns LLM service instances (1:N) Owns embeddings (1:N) Can share projects (N:M via users_projects) Can share LLM service instances (N:M via instances_shared_with) Notes:\nvdb_key is generated during user creation and returned once Cannot be recovered if lost Transmitted as Authorization: Bearer token projects# Stores embedding projects owned by users.\nColumn Type Constraints Description project_id SERIAL PRIMARY KEY Auto-incrementing project ID project_handle VARCHAR(20) NOT NULL Project identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Project owner user handle description TEXT Project description metadata_scheme TEXT JSON Schema for validating embedding metadata public_read BOOLEAN DEFAULT FALSE Allow unauthenticated read access instance_id INTEGER FK→instances LLM service instance used for embeddings created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, project_handle) - Project handles unique per owner ON DELETE CASCADE - Delete project when owner deleted ON DELETE RESTRICT - Prevent instance deletion if used by project Relationships:\nOwned by one user (N:1) Uses one LLM service instance (N:1) Has many embeddings (1:N) Can be shared with users (N:M via users_projects) Metadata Schema:\nStored as JSON Schema string Used to validate embedding metadata Optional (can be NULL) See Data Validation for details Public Access:\nWhen public_read=TRUE, allows unauthenticated embedding queries Controlled via API or by setting shared_with to [\u0026quot;*\u0026quot;] embeddings# Stores vector embeddings with text identifiers and metadata.\nColumn Type Constraints Description embeddings_id SERIAL PRIMARY KEY Auto-incrementing embedding ID text_id TEXT INDEXED Text identifier (URL, DOI, custom ID) owner VARCHAR(20) NOT NULL, FK→users Embedding owner user handle project_id SERIAL NOT NULL, FK→projects Project the embedding belongs to instance_id SERIAL NOT NULL, FK→instances LLM service instance used text TEXT Optional full text of the embedded content vector halfvec NOT NULL Embedding vector (half-precision float) vector_dim INTEGER NOT NULL Vector dimensionality metadata jsonb Optional metadata (validated if schema defined) created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (text_id, owner, project_id, instance_id) - Unique text IDs per project/instance ON DELETE CASCADE - Delete embeddings when owner, project, or instance deleted Indexes:\nPrimary key on embeddings_id B-tree index on text_id HNSW vector indexes for dimensions: 384, 768, 1024, 1536, 3072 (see Vector Indexes) Vector Storage:\nUses halfvec type (16-bit floating point) for efficient storage Dimensions must match LLM service instance configuration Validated on upload against instance dimensions Relationships:\nOwned by one user (N:1) Belongs to one project (N:1) Created with one LLM service instance (N:1) LLM Service Architecture# The LLM service architecture separates service definitions (templates) from user-specific instances.\ndefinitions# Templates for LLM embedding services (shared or user-specific).\nColumn Type Constraints Description definition_id SERIAL PRIMARY KEY Auto-incrementing definition ID definition_handle VARCHAR(20) NOT NULL Definition identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Definition owner (_system for global) endpoint TEXT NOT NULL API endpoint URL description TEXT Service description api_standard VARCHAR(20) NOT NULL, FK→api_standards API standard handle model TEXT NOT NULL Model name (e.g., text-embedding-3-large) dimensions INTEGER NOT NULL Vector dimensions produced by model context_limit INTEGER NOT NULL Maximum context length (tokens/chars) is_public BOOLEAN NOT NULL, DEFAULT FALSE Share with all users if true created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, definition_handle) - Definition handles unique per owner ON DELETE CASCADE - Delete definition when owner deleted Built-in Definitions:\nSystem-provided definitions (owned by _system, is_public=TRUE):\nHandle Model Dimensions Context Limit API Standard openai-large text-embedding-3-large 3072 8192 openai openai-small text-embedding-3-small 1536 8191 openai cohere-v4 embed-v4.0 1536 128000 cohere gemini-embedding-001 gemini-embedding-001 3072 2048 gemini Relationships:\nOwned by one user (N:1) References one API standard (N:1) Can be shared with users (N:M via definitions_shared_with) Used by instances (1:N) instances# User-specific configurations of LLM services with API keys.\nColumn Type Constraints Description instance_id SERIAL PRIMARY KEY Auto-incrementing instance ID instance_handle VARCHAR(20) NOT NULL Instance identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Instance owner user handle endpoint TEXT NOT NULL API endpoint URL description TEXT Instance description api_standard VARCHAR(20) NOT NULL, FK→api_standards API standard handle model TEXT NOT NULL Model name dimensions INTEGER NOT NULL Vector dimensions context_limit INTEGER NOT NULL Maximum context length definition_id INTEGER FK→definitions Reference to definition template api_key_encrypted BYTEA Encrypted API key for service authentication created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, instance_handle) - Instance handles unique per owner ON DELETE CASCADE - Delete instance when owner deleted ON DELETE SET NULL - Keep instance if definition deleted Indexes:\nComposite index on (owner, instance_handle) API Key Encryption:\nEncrypted using AES-256-GCM Encryption key from ENCRYPTION_KEY environment variable Cannot be recovered if encryption key is lost Stored as base64-encoded BYTEA Relationships:\nOwned by one user (N:1) References one API standard (N:1) Based on one definition template (N:1, optional) Used by projects (1:N) Used by embeddings (1:N) Can be shared with users (N:M via instances_shared_with) api_standards# Defines API specifications for LLM embedding services.\nColumn Type Constraints Description api_standard_handle VARCHAR(20) PRIMARY KEY Standard identifier (e.g., openai, cohere) description TEXT API description and version info key_method VARCHAR(20) NOT NULL, FK→key_methods Authentication method key_field VARCHAR(20) Header/field name for API key created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Built-in Standards:\nHandle Description Key Method Key Field openai OpenAI Embeddings API v1 auth_bearer Authorization cohere Cohere Embed API v2 auth_bearer Authorization gemini Gemini Embeddings API auth_bearer x-goog-api-key Relationships:\nUsed by definitions (1:N) Used by instances (1:N) References one key_method (N:1) Association Tables# users_projects# Defines project sharing and access control.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access project_id SERIAL FK→projects, PK Project being shared role VARCHAR(20) NOT NULL, FK→vdb_roles Access level (owner/editor/reader) created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, project_id) - One role per user per project ON DELETE CASCADE - Remove sharing when user or project deleted Roles:\nowner - Full control (only project creator) editor - Can add/modify/delete embeddings reader - Read-only access to embeddings instances_shared_with# Defines LLM service instance sharing.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access instance_id INTEGER FK→instances, PK Instance being shared role VARCHAR(20) NOT NULL, FK→vdb_roles Access level created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, instance_id) - One role per user per instance ON DELETE CASCADE - Remove sharing when user or instance deleted definitions_shared_with# Defines LLM service definition sharing.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access definition_id INTEGER FK→definitions, PK Definition being shared created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, definition_id) - One share per user per definition ON DELETE CASCADE - Remove sharing when user or definition deleted Indexes:\nIndex on user_handle for efficient user lookups Index on definition_id for efficient definition lookups Reference Tables# vdb_roles# Enumeration of valid access roles.\nColumn Type Constraints Description vdb_role VARCHAR(20) PRIMARY KEY Role name Values:\nowner - Full control over resource editor - Read and write access reader - Read-only access key_methods# Enumeration of API authentication methods.\nColumn Type Constraints Description key_method VARCHAR(20) PRIMARY KEY Authentication method Values:\nauth_bearer - Bearer token in Authorization header body_form - API key in request body query_param - API key in URL query parameter custom_header - API key in custom header Vector Indexes# HNSW (Hierarchical Navigable Small World) indexes for fast approximate nearest neighbor search.\nIndex Configuration# All vector indexes use HNSW with these parameters:\nm = 24 - Number of neighbors per node ef_construction = 200 - Build-time accuracy parameter ef_search = 100 - Query-time accuracy parameter Expected recall: ~99.8% Dimension-Specific Indexes# Index Name Dimensions Common Models embeddings_vector_384 384 Cohere embed-multilingual-light-v3.0, embed-english-light-v3.0 embeddings_vector_768 768 BERT base, Cohere embed-multilingual-v2.0, Gemini Embeddings embeddings_vector_1024 1024 BERT large, SBERT, Cohere embed-multilingual-v3.0, embed-english-v3.0 embeddings_vector_1536 1536 OpenAI text-embedding-ada-002, text-embedding-3-small, Cohere embed-v4.0 embeddings_vector_3072 3072 OpenAI text-embedding-3-large, Gemini embedding-001 Index Structure:\nCREATE INDEX embeddings_vector_1536 ON embeddings USING hnsw ((vector::halfvec(1536)) halfvec_cosine_ops) WITH (m = 24, ef_construction = 200) WHERE (vector_dim = 1536);Usage:\nIndexes are partial - only include vectors of matching dimension Automatically used for similarity queries with matching dimensions Use cosine distance for similarity calculation Relationships Diagram# users (1) ──owns──\u0026gt; (N) projects (1) ──contains──\u0026gt; (N) embeddings │ │ │ │ └─\u0026gt; uses (1) instances (N) \u0026lt;───┘ │ │ │ └─\u0026gt; based on (1) definitions │ │ ├──owns──\u0026gt; (N) instances ──uses──\u0026gt; (1) api_standards │ │ │ │ └─\u0026gt; references (1) definitions │ └──owns──\u0026gt; (N) definitions ──references──\u0026gt; (1) api_standards Sharing: users (N) \u0026lt;──shares─\u0026gt; (M) projects (via users_projects) users (N) \u0026lt;──shares─\u0026gt; (M) instances (via instances_shared_with) users (N) \u0026lt;──shares─\u0026gt; (M) definitions (via definitions_shared_with)Data Validation# Dimension Validation# Embeddings must have dimensions matching their LLM service instance:\nembeddings.vector_dim must equal instances.dimensions Enforced at API level during upload Similarity queries automatically filter by matching dimensions Metadata Validation# Projects can define JSON Schema in metadata_scheme:\nValidates all embedding metadata on upload Optional - if NULL, metadata not validated Enforced at API level Admin sanity check validates all existing metadata Sanity Check Queries# The /v1/admin/sanity-check endpoint verifies:\nAll embeddings have dimensions matching their instance All metadata conforms to project schemas (if defined) Common Queries# Find User\u0026rsquo;s Projects# SELECT p.project_handle, p.description, p.created_at FROM projects p WHERE p.owner = \u0026#39;alice\u0026#39; ORDER BY p.created_at DESC;Find Shared Projects# SELECT p.project_handle, p.owner, up.role FROM users_projects up JOIN projects p ON up.project_id = p.project_id WHERE up.user_handle = \u0026#39;bob\u0026#39; ORDER BY p.owner, p.project_handle;Find Similar Embeddings# SELECT text_id, vector \u0026lt;-\u0026gt; \u0026#39;[0.1, 0.2, ...]\u0026#39;::vector AS distance FROM embeddings WHERE project_id = 123 AND vector_dim = 1536 ORDER BY vector \u0026lt;-\u0026gt; \u0026#39;[0.1, 0.2, ...]\u0026#39;::vector LIMIT 10;Count Embeddings by Project# SELECT p.project_handle, COUNT(e.embeddings_id) AS embedding_count FROM projects p LEFT JOIN embeddings e ON p.project_id = e.project_id WHERE p.owner = \u0026#39;alice\u0026#39; GROUP BY p.project_id, p.project_handle ORDER BY embedding_count DESC;Database Maintenance# Backup Recommendations# Critical Data:\nUser accounts (users) API keys (vdb_key in users, api_key_encrypted in instances) ENCRYPTION_KEY environment variable (backup separately!) Projects and embeddings Backup Strategy:\n# Full database backup pg_dump -U postgres dhamps_vdb \u0026gt; backup.sql # Backup encryption key separately echo \u0026#34;$ENCRYPTION_KEY\u0026#34; \u0026gt; encryption_key.backup chmod 400 encryption_key.backupVacuum and Analyze# -- Regular maintenance VACUUM ANALYZE embeddings; VACUUM ANALYZE projects; -- Rebuild vector indexes if needed REINDEX INDEX embeddings_vector_1536;Monitoring Queries# -- Check index usage SELECT schemaname, tablename, indexname, idx_scan FROM pg_stat_user_indexes WHERE tablename = \u0026#39;embeddings\u0026#39; ORDER BY idx_scan DESC; -- Check table sizes SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) FROM pg_class WHERE relname IN (\u0026#39;embeddings\u0026#39;, \u0026#39;projects\u0026#39;, \u0026#39;users\u0026#39;) ORDER BY pg_total_relation_size(oid) DESC;Related Documentation# Concepts - Architecture Concepts - Projects Concepts - Metadata Deployment - Database Setup Reference - Configuration API - Endpoints "},{"id":14,"href":"/dhamps-vdb/deployment/database/","title":"Database Setup","section":"Deployment","content":"Database Setup# dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.\nRequirements# PostgreSQL: Version 11 or higher pgvector: Extension for vector similarity search Storage: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count) Installing PostgreSQL with pgvector# Using Docker (Recommended)# The easiest way to get PostgreSQL with pgvector:\ndocker run -d \\ --name postgres-pgvector \\ -p 5432:5432 \\ -e POSTGRES_PASSWORD=secure_password \\ -v postgres_data:/var/lib/postgresql/data \\ pgvector/pgvector:0.7.4-pg16On Ubuntu/Debian# # Add PostgreSQL APT repository sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \\ https://www.postgresql.org/media/keys/ACCC4CF8.asc echo \u0026#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \\ https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\u0026#34; | \\ sudo tee /etc/apt/sources.list.d/pgdg.list # Install PostgreSQL sudo apt update sudo apt install postgresql-16 postgresql-contrib-16 # Install pgvector sudo apt install postgresql-16-pgvectorOn macOS# # Using Homebrew brew install postgresql@16 brew install pgvector # Start PostgreSQL brew services start postgresql@16On RHEL/CentOS/Fedora# # Install PostgreSQL sudo dnf install postgresql16-server postgresql16-contrib # Install pgvector (build from source) sudo dnf install postgresql16-devel git gcc make git clone https://github.com/pgvector/pgvector.git cd pgvector make sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_configDatabase Configuration# Step 1: Create Database# Connect to PostgreSQL as superuser:\n# Local connection sudo -u postgres psql # Remote connection psql -h db.example.com -U postgresCreate the database:\n-- Create database CREATE DATABASE dhamps_vdb;Step 2: Create User# Create a dedicated user for dhamps-vdb:\n-- Create user with password CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password_here\u0026#39;;Best practices:\nUse strong, randomly generated password (e.g., openssl rand -base64 32) Store password securely (password manager, secrets management) Rotate passwords regularly Step 3: Grant Privileges# Grant necessary permissions:\n-- Grant database privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; -- Connect to the database \\c dhamps_vdb -- Grant schema privileges GRANT ALL ON SCHEMA public TO dhamps_user; -- For PostgreSQL 15+, also grant: GRANT CREATE ON DATABASE dhamps_vdb TO dhamps_user;Step 4: Enable pgvector Extension# Still connected to the dhamps_vdb database:\n-- Enable pgvector extension CREATE EXTENSION IF NOT EXISTS vector; -- Verify extension is installed \\dxExpected output should include:\nList of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ vector | 0.7.4 | public | vector data type and ivfflat and hnsw access methodsStep 5: Verify Setup# Test the setup:\n-- Test vector creation SELECT \u0026#39;[1,2,3]\u0026#39;::vector; -- Should return: [1,2,3] -- Test vector distance SELECT \u0026#39;[1,2,3]\u0026#39;::vector \u0026lt;=\u0026gt; \u0026#39;[4,5,6]\u0026#39;::vector AS distance; -- Should return a float (distance value)Exit psql:\n\\qConnection String Format# dhamps-vdb connects using these environment variables:\nSERVICE_DBHOST=localhost # Database hostname SERVICE_DBPORT=5432 # Database port SERVICE_DBUSER=dhamps_user # Database username SERVICE_DBPASSWORD=password # Database password SERVICE_DBNAME=dhamps_vdb # Database nameThe connection string format used internally:\npostgresql://username:password@host:port/database?sslmode=disableProduction Configuration# PostgreSQL Tuning# Edit postgresql.conf for better vector search performance:\n# Memory settings shared_buffers = 4GB # 25% of RAM effective_cache_size = 12GB # 75% of RAM maintenance_work_mem = 1GB work_mem = 50MB # Parallel query settings max_parallel_workers_per_gather = 4 max_parallel_workers = 8 # Connection settings max_connections = 100 # For pgvector specifically shared_preload_libraries = \u0026#39;vector\u0026#39; # Add if not present # Write-ahead log wal_level = replica # For replication max_wal_senders = 3 # For replicasRestart PostgreSQL after changes:\n# On systemd systems sudo systemctl restart postgresql # On Docker docker restart postgres-containerConnection Pooling# For high-load scenarios, use connection pooling with PgBouncer:\n# Install PgBouncer sudo apt install pgbouncer # Configure /etc/pgbouncer/pgbouncer.ini [databases] dhamps_vdb = host=localhost port=5432 dbname=dhamps_vdb [pgbouncer] listen_addr = 127.0.0.1 listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 20Connect dhamps-vdb to PgBouncer instead of PostgreSQL directly.\nSSL/TLS Encryption# Enable SSL in postgresql.conf:\nssl = on ssl_cert_file = \u0026#39;/etc/postgresql/server.crt\u0026#39; ssl_key_file = \u0026#39;/etc/postgresql/server.key\u0026#39; ssl_ca_file = \u0026#39;/etc/postgresql/ca.crt\u0026#39;Update connection string:\n# Update dhamps-vdb configuration SERVICE_DBHOST=db.example.com # Change connection to use SSL (requires code modification or PostgreSQL parameter)Network Security# Restrict access in pg_hba.conf:\n# TYPE DATABASE USER ADDRESS METHOD # Allow dhamps_user from application server only host dhamps_vdb dhamps_user 10.0.1.0/24 md5 # Allow localhost connections local all all peer host all all 127.0.0.1/32 md5 host all all ::1/128 md5Reload PostgreSQL:\nsudo systemctl reload postgresqlBackup and Recovery# Automated Backups# Daily backup script:\n#!/bin/bash # /usr/local/bin/backup-dhamps-vdb.sh BACKUP_DIR=\u0026#34;/backups/dhamps-vdb\u0026#34; DATE=$(date +%Y%m%d_%H%M%S) DB_NAME=\u0026#34;dhamps_vdb\u0026#34; # Create backup pg_dump -U dhamps_user -h localhost $DB_NAME | gzip \u0026gt; \u0026#34;$BACKUP_DIR/dhamps-vdb-$DATE.sql.gz\u0026#34; # Keep last 30 days find $BACKUP_DIR -name \u0026#34;dhamps-vdb-*.sql.gz\u0026#34; -mtime +30 -delete # Verify backup if [ $? -eq 0 ]; then echo \u0026#34;Backup successful: $DATE\u0026#34; else echo \u0026#34;Backup failed: $DATE\u0026#34; \u0026gt;\u0026amp;2 exit 1 fiSet up cron job:\n# Run daily at 2 AM 0 2 * * * /usr/local/bin/backup-dhamps-vdb.shRestore from Backup# # Decompress and restore gunzip -c /backups/dhamps-vdb/dhamps-vdb-20240208.sql.gz | \\ psql -U dhamps_user -h localhost dhamps_vdbPoint-in-Time Recovery (PITR)# Enable WAL archiving in postgresql.conf:\nwal_level = replica archive_mode = on archive_command = \u0026#39;test ! -f /archive/%f \u0026amp;\u0026amp; cp %p /archive/%f\u0026#39;Monitoring# Check Database Size# -- Database size SELECT pg_size_pretty(pg_database_size(\u0026#39;dhamps_vdb\u0026#39;)); -- Table sizes SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||\u0026#39;.\u0026#39;||tablename)) AS size FROM pg_tables WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY pg_total_relation_size(schemaname||\u0026#39;.\u0026#39;||tablename) DESC;Check Connection Status# -- Active connections SELECT count(*) FROM pg_stat_activity WHERE datname = \u0026#39;dhamps_vdb\u0026#39;; -- Connection details SELECT pid, usename, application_name, client_addr, state, query FROM pg_stat_activity WHERE datname = \u0026#39;dhamps_vdb\u0026#39;;Monitor Performance# -- Enable pg_stat_statements CREATE EXTENSION IF NOT EXISTS pg_stat_statements; -- View slow queries SELECT query, calls, total_time, mean_time, max_time FROM pg_stat_statements WHERE query NOT LIKE \u0026#39;%pg_stat_statements%\u0026#39; ORDER BY mean_time DESC LIMIT 10;Troubleshooting# Cannot Connect to Database# # Check if PostgreSQL is running sudo systemctl status postgresql # Check PostgreSQL logs sudo tail -f /var/log/postgresql/postgresql-16-main.log # Test connection psql -h localhost -U dhamps_user -d dhamps_vdbpgvector Extension Not Found# -- Check available extensions SELECT * FROM pg_available_extensions WHERE name = \u0026#39;vector\u0026#39;; -- If not listed, install pgvector package -- See installation section abovePermission Denied# -- Reconnect as superuser \\c dhamps_vdb postgres -- Re-grant privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; GRANT ALL ON SCHEMA public TO dhamps_user; GRANT ALL ON ALL TABLES IN SCHEMA public TO dhamps_user; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO dhamps_user; -- For future objects ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO dhamps_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO dhamps_user;Out of Disk Space# # Check disk usage df -h # Check PostgreSQL data directory du -sh /var/lib/postgresql/16/main/ # Clean up old WAL files (if safe) # Check archive status firstSlow Queries# -- Check missing indexes SELECT schemaname, tablename, attname, n_distinct, correlation FROM pg_stats WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY n_distinct DESC; -- Analyze tables ANALYZE; -- Vacuum tables VACUUM ANALYZE;Migration from Other Databases# dhamps-vdb is designed specifically for PostgreSQL with pgvector. Migration from other databases requires:\nExport data from source database Set up PostgreSQL with pgvector Transform data to match dhamps-vdb schema Import using dhamps-vdb API or direct SQL Further Reading# PostgreSQL Documentation pgvector GitHub PostgreSQL Tuning Guide Environment Variables Docker Deployment Security Guide "},{"id":15,"href":"/dhamps-vdb/getting-started/docker/","title":"Docker Deployment","section":"Getting Started","content":"Docker Deployment# Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.\nQuick Start# The fastest way to get dhamps-vdb running with Docker:\n# Clone the repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Run automated setup (generates secure keys) ./docker-setup.sh # Start services with docker-compose docker-compose up -d # Check logs docker-compose logs -f dhamps-vdb # Access the API curl http://localhost:8880/docsWhat\u0026rsquo;s Included# The Docker Compose setup includes:\ndhamps-vdb: The vector database API service PostgreSQL 16: Database with pgvector extension Persistent storage: Named volume for database data Configuration Files# .env File# All configuration is managed through environment variables. Copy the template:\ncp .env.docker.template .envEdit .env to set required values:\n# Admin API key for administrative operations SERVICE_ADMINKEY=your-secure-admin-key-here # Encryption key for API keys (32+ characters) ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars # Database password SERVICE_DBPASSWORD=secure-database-password # Optional: Debug mode SERVICE_DEBUG=false # Optional: Change ports API_PORT=8880 POSTGRES_PORT=5432docker-compose.yml# The compose file defines two services:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 # PostgreSQL with pgvector support dhamps-vdb: build: . # The API service depends_on: - postgresDeployment Options# Option 1: Docker Compose with Included Database (Recommended)# Use the provided docker-compose.yml:\ndocker-compose up -dAdvantages:\nEverything included Automatic networking Data persistence Easy to manage Use when:\nGetting started Development/testing Small to medium deployments Option 2: Standalone Container with External Database# Run only the dhamps-vdb container:\n# Build the image docker build -t dhamps-vdb:latest . # Run the container docker run -d \\ --name dhamps-vdb \\ -p 8880:8880 \\ -e SERVICE_DBHOST=your-db-host \\ -e SERVICE_DBPORT=5432 \\ -e SERVICE_DBUSER=dbuser \\ -e SERVICE_DBPASSWORD=dbpass \\ -e SERVICE_DBNAME=dhamps_vdb \\ -e SERVICE_ADMINKEY=admin-key \\ -e ENCRYPTION_KEY=encryption-key \\ dhamps-vdb:latestUse when:\nYou have an existing PostgreSQL server Production deployments Need database separation Option 3: Docker Compose with External Database# Modify docker-compose.yml to remove the postgres service:\nservices: dhamps-vdb: build: . ports: - \u0026#34;${API_PORT:-8880}:8880\u0026#34; environment: SERVICE_DBHOST: external-db.example.com # ... other variablesBuilding the Image# Standard Build# docker build -t dhamps-vdb:latest .Custom Tag# docker build -t dhamps-vdb:v0.1.0 .Clean Build (No Cache)# docker build --no-cache -t dhamps-vdb:latest .Multi-Stage Build Details# The Dockerfile uses multi-stage builds for efficiency:\nBuilder stage: Compiles Go code with sqlc generation Runtime stage: Minimal Alpine image with only the binary Result: Small, secure image (~20MB vs 800MB+)\nManaging Services# Start Services# # Start in background docker-compose up -d # Start with logs visible docker-compose up # Rebuild and start docker-compose up -d --buildView Logs# # All logs docker-compose logs # Follow logs in real-time docker-compose logs -f # Specific service docker-compose logs -f dhamps-vdb docker-compose logs -f postgresStop Services# # Stop containers (keeps data) docker-compose stop # Stop and remove containers (keeps data) docker-compose down # Stop and remove everything including data docker-compose down -vRestart Services# # Restart all docker-compose restart # Restart specific service docker-compose restart dhamps-vdbData Persistence# Docker Volumes# The compose file creates a named volume:\nvolumes: postgres_data:This ensures database data persists across container restarts.\nView Volumes# docker volume lsInspect Volume# docker volume inspect dhamps-vdb_postgres_dataBackup Database# # Create backup docker-compose exec postgres pg_dump -U postgres dhamps_vdb \u0026gt; backup.sql # Restore from backup docker-compose exec -T postgres psql -U postgres dhamps_vdb \u0026lt; backup.sqlNetworking# Access from Host# The API is accessible at:\nhttp://localhost:8880Access from Other Containers# Use the service name as hostname:\nhttp://dhamps-vdb:8880Custom Network# To use an existing Docker network:\nnetworks: default: external: name: your-network-nameSecurity# Required Environment Variables# Two critical environment variables must be set:\nSERVICE_ADMINKEY: Admin API key ENCRYPTION_KEY: For encrypting user API keys (32+ chars) Generating Secure Keys# # Admin key openssl rand -base64 32 # Encryption key openssl rand -hex 32Production Checklist# Use strong, randomly generated keys Never commit .env to version control Run behind reverse proxy (nginx, Traefik) Enable HTTPS/TLS Restrict database network access Set resource limits Enable logging and monitoring Use specific image tags (not latest) Regular security updates Backup database regularly Verification# Check Service Status# # Check if containers are running docker-compose ps # Expected: both services \u0026#34;running\u0026#34; or \u0026#34;healthy\u0026#34;Test API Access# # Get OpenAPI documentation curl http://localhost:8880/docs # Should return HTML pageTest Database Connection# # Connect to PostgreSQL docker-compose exec postgres psql -U postgres -d dhamps_vdb # Check pgvector extension \\dx # Should show vector extensionCreate Test User# curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;testuser\u0026#34;, \u0026#34;full_name\u0026#34;: \u0026#34;Test User\u0026#34; }\u0026#39;Troubleshooting# Container Won\u0026rsquo;t Start# Check logs:\ndocker-compose logs dhamps-vdbCommon issues:\nMissing SERVICE_ADMINKEY or ENCRYPTION_KEY Database connection failure Port already in use Database Connection Errors# # Check postgres health docker-compose ps # Check database logs docker-compose logs postgres # Test connection docker-compose exec postgres psql -U postgres -d dhamps_vdb -c \u0026#34;SELECT 1;\u0026#34;Can\u0026rsquo;t Connect to API# # Check if container is running docker ps # Check port mapping docker port dhamps-vdb # Test from inside container docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs # Test from host curl http://localhost:8880/docsPermission Issues# The container runs as non-root user appuser (UID 1000). If you have permission errors:\n# Check volume permissions docker volume inspect dhamps-vdb_postgres_dataReset Everything# # Stop and remove everything docker-compose down -v # Remove images docker rmi dhamps-vdb:latest docker rmi pgvector/pgvector:0.7.4-pg16 # Start fresh docker-compose up -d --buildBuild Failures# If Docker build fails with network errors:\n# Try with host network docker build --network=host -t dhamps-vdb:latest .Advanced Configuration# Resource Limits# Add to docker-compose.yml:\nservices: dhamps-vdb: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 2G reservations: cpus: \u0026#39;0.5\u0026#39; memory: 512MHealth Checks# The Dockerfile includes a health check:\nHEALTHCHECK --interval=30s --timeout=3s \\ CMD wget --no-verbose --tries=1 --spider http://localhost:8880/ || exit 1View health status:\ndocker inspect --format=\u0026#39;{{.State.Health.Status}}\u0026#39; dhamps-vdbCustom Dockerfile Builds# You can customize the build:\ndocker build \\ --build-arg GO_VERSION=1.24 \\ -t dhamps-vdb:custom .External Database Setup# If using an external PostgreSQL database:\nPrepare Database# -- Create database CREATE DATABASE dhamps_vdb; -- Create user CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password\u0026#39;; -- Grant privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; -- Connect to database \\c dhamps_vdb -- Grant schema permissions GRANT ALL ON SCHEMA public TO dhamps_user; -- Enable pgvector CREATE EXTENSION IF NOT EXISTS vector;Configure dhamps-vdb# Update .env:\nSERVICE_DBHOST=external-db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdbThen run only the dhamps-vdb service or use a standalone container.\nNext Steps# After successful deployment:\nConfigure the service Create your first user Set up a project Review security best practices "},{"id":16,"href":"/dhamps-vdb/guides/project-sharing/","title":"Project Sharing Guide","section":"Guides","content":"Project Sharing Guide# This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.\nOverview# Project sharing allows you to grant other users access to your projects with different permission levels:\nreader: Read-only access to embeddings and similar documents editor: Read and write access to embeddings (can add/modify/delete embeddings) Only the project owner can manage sharing settings and delete the project.\nSharing During Project Creation# You can specify users to share with when creating a new project using the shared_with field:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;A project shared with team members\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }\u0026#39;In this example:\nbob can read embeddings and search for similar documents charlie can read embeddings, search, and also add/modify/delete embeddings alice (the owner) has full control including managing sharing and deleting the project Managing Sharing After Creation# Share a Project with a User# Add a user to an existing project:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project shared successfully\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Update User\u0026rsquo;s Role# To change a user\u0026rsquo;s role, simply share again with the new role:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }\u0026#39;This updates David\u0026rsquo;s access from reader to editor.\nUnshare a Project from a User# Remove a user\u0026rsquo;s access to a project:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share/david\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project unshared successfully\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;david\u0026#34; }List Shared Users# View all users a project is shared with:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }Note: Only the project owner can view the list of shared users. Users who have been granted access cannot see which other users also have access.\nWhat Shared Users Can Do# As a Reader# Bob (with reader access) can:\n# View project metadata curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Retrieve embeddings curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Get a specific embedding curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Search for similar documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/collaborative-project/doc123?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34;As an Editor# Charlie (with editor access) can do everything a reader can, plus:\n# Upload new embeddings curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Charlie\u0026#34;} }] }\u0026#39; # Delete specific embeddings curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project/doc456\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; # Delete all embeddings curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34;What Shared Users Cannot Do# Even with editor access, shared users cannot:\nDelete the project Change project settings (description, instance, metadata schema) Manage sharing (add/remove other users) View the list of other shared users Transfer project ownership These operations require owner privileges.\nPermission Summary Table# Operation Owner Editor Reader View project metadata ✅ ✅ ✅ Retrieve embeddings ✅ ✅ ✅ Search similar documents ✅ ✅ ✅ Add embeddings ✅ ✅ ❌ Modify embeddings ✅ ✅ ❌ Delete embeddings ✅ ✅ ❌ Update project settings ✅ ❌ ❌ Delete project ✅ ❌ ❌ Manage sharing ✅ ❌ ❌ View shared users list ✅ ❌ ❌ Transfer ownership ✅ ❌ ❌ Use Cases# Research Team Collaboration# A research team can share a project where:\nThe principal investigator (PI) is the owner Research assistants have editor access to upload new data External collaborators have reader access to query the data # PI creates and shares the project curl -X PUT \u0026#34;https://api.example.com/v1/projects/pi/research-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer pi_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research team corpus\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;assistant1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;assistant2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;external_collab\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }\u0026#39;Data Pipeline with Read-Only Access# Share processed embeddings with downstream consumers:\n# Data processor creates project curl -X PUT \u0026#34;https://api.example.com/v1/projects/processor/processed-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer processor_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;processed-data\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Processed embeddings for consumption\u0026#34;, \u0026#34;instance_id\u0026#34;: 456, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;app_backend\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;analytics_team\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }\u0026#39;Temporary Access# Grant temporary access to a consultant and revoke it later:\n# Grant access curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/sensitive-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;consultant\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}\u0026#39; # Revoke access when consultation is complete curl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/sensitive-project/share/consultant\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining with Public Access# You can combine user-specific sharing with public access (see Public Projects Guide):\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/mixed-access-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;mixed-access-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Public read, specific editors\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;} ] }\u0026#39;In this case:\nAnyone can read the project (no authentication required) bob can also edit (add/modify/delete embeddings) alice retains full owner privileges Security Considerations# Choose Roles Carefully: Only grant editor access to trusted users who need to modify data Audit Access: Regularly review the shared users list to ensure appropriate access levels Revoke Promptly: Remove access immediately when users no longer need it Use Reader by Default: Start with reader access and upgrade to editor only when necessary Consider Public Access: For truly open data, use public_read: true instead of sharing with many users Related Documentation# Ownership Transfer Guide - Transfer project ownership Public Projects Guide - Make projects publicly accessible Instance Management Guide - Share LLM service instances Troubleshooting# Cannot Share Project# Error: \u0026ldquo;Only the owner can share projects\u0026rdquo;\nSolution: Only the project owner can manage sharing. If you need to share the project, ask the owner to add you, or consider transferring ownership.\nUser Not Found# Error: \u0026ldquo;User not found\u0026rdquo;\nSolution: The user must exist in the system before you can share a project with them. Ask the admin to create the user first.\nCannot View Shared Users List# Error: \u0026ldquo;Forbidden\u0026rdquo;\nSolution: Only the project owner can view the list of shared users. Shared users cannot see other shared users for privacy reasons.\n"},{"id":17,"href":"/dhamps-vdb/api/endpoints/projects/","title":"Projects","section":"Endpoints","content":"Projects Endpoint# Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.\nEndpoints# List User\u0026rsquo;s Projects# Get all projects owned by a user.\nEndpoint: GET /v1/projects/{username}\nAuthentication: Admin, the user themselves, or users with shared access\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;projects\u0026#34;: [ { \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } ] } Create Project# Register a new project for a user.\nEndpoint: POST /v1/projects/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Parameters:\nproject_handle (string, required): Unique project identifier within the user\u0026rsquo;s namespace description (string, optional): Project description instance_owner (string, required): Owner of the LLM service instance instance_handle (string, required): Handle of the LLM service instance to use public_read (boolean, optional): Allow unauthenticated read access (default: false) metadataScheme (string, optional): JSON Schema for validating embedding metadata shared_with (array, optional): List of users to share the project with Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false } Get Project Information# Retrieve information about a specific project.\nEndpoint: GET /v1/projects/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } Update Project (PUT)# Create or update a project with the specified handle.\nEndpoint: PUT /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nRequest Body: Same as POST endpoint\nExample:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34; }\u0026#39; Delete Project# Delete a project and all its embeddings.\nEndpoint: DELETE /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project alice/research-docs deleted successfully\u0026#34; }⚠️ Warning: This operation is irreversible and will delete all embeddings in the project.\nPartial Update (PATCH)# Update specific project fields without providing all data.\nEndpoint: PATCH /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nExample - Enable public read access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Example - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34; }\u0026#39;See PATCH Updates for more details.\nProject Sharing# Share Project# Share a project with another user, granting them read or edit access.\nEndpoint: POST /v1/projects/{owner}/{project}/share\nAuthentication: Admin or the project owner\nRequest Body:\n{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Roles:\nreader: Read-only access to embeddings and similarity search editor: Read and write access to embeddings Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-docs/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project shared successfully\u0026#34;, \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;shared_with\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } Unshare Project# Remove a user\u0026rsquo;s access to a shared project.\nEndpoint: DELETE /v1/projects/{owner}/{project}/share/{user_handle}\nAuthentication: Admin or the project owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/research-docs/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project unshared successfully\u0026#34;, \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;removed_user\u0026#34;: \u0026#34;bob\u0026#34; } List Shared Users# Get a list of users the project is shared with.\nEndpoint: GET /v1/projects/{owner}/{project}/shared-with\nAuthentication: Admin or the project owner\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/research-docs/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }Note: Only the project owner can view this list. Users with shared access cannot see who else has access.\nProject Ownership Transfer# Transfer Ownership# Transfer ownership of a project to another user.\nEndpoint: POST /v1/projects/{owner}/{project}/transfer-ownership\nAuthentication: Admin or the project owner\nRequest Body:\n{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-docs/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project ownership transferred successfully\u0026#34;, \u0026#34;old_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;new_owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;new_path\u0026#34;: \u0026#34;/v1/projects/bob/research-docs\u0026#34; }Important Notes:\nOnly the current owner can transfer ownership The new owner must be an existing user The new owner cannot already have a project with the same handle After transfer, the old owner loses all access to the project All embeddings and project data remain intact Query Parameters# List Projects# When listing projects, the following query parameters are available:\nlimit (integer, default: 10, max: 200): Maximum number of results to return offset (integer, default: 0): Pagination offset Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice?limit=20\u0026amp;offset=40\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Project Properties# Field Type Required Description project_handle string Yes Unique identifier within user\u0026rsquo;s namespace owner string Read-only Project owner\u0026rsquo;s user handle description string No Project description instance_owner string Yes Owner of the LLM service instance instance_handle string Yes Handle of the LLM service instance instance_id integer Read-only Internal ID of the LLM service instance public_read boolean No Allow unauthenticated read access metadataScheme string No JSON Schema for metadata validation created_at timestamp Read-only Project creation timestamp Metadata Schema Validation# Projects can define a JSON Schema to validate metadata attached to embeddings. See the main README for examples.\nExample Schema:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }When uploading embeddings, metadata will be validated against this schema. Invalid metadata will result in a 400 Bad Request error.\nCommon Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Project must have instance_id\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify this project\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; already exists\u0026#34; } Related Documentation# LLM Services - Managing LLM service instances Embeddings - Adding and retrieving embeddings Similars - Similarity search Public Access - Public project configuration "},{"id":18,"href":"/dhamps-vdb/concepts/users-and-auth/","title":"Users and Authentication","section":"Concepts","content":"Users and Authentication# dhamps-vdb uses token-based authentication with API keys for all operations.\nUser Model# User Properties# user_handle: Unique identifier (3-20 characters, alphanumeric + underscore) name: Full name (optional) email: Email address (unique, required) vdb_key: API key (SHA-256 hash, 64 characters) created_at: Timestamp of creation updated_at: Timestamp of last update Special Users# _system User\nCreated automatically during database migration Owns system-wide LLM service definitions Cannot be used for authentication Provides default configurations for all users Authentication Flow# API Key Authentication# All requests (except public endpoints) require authentication:\nGET /v1/projects/alice/my-project Authorization: Bearer 024v2013621509245f2e24...Authentication Process# Client sends API key in Authorization header with Bearer prefix Server extracts key and looks up user in database If user found, request proceeds with user context If not found or missing, returns 401 Unauthorized Admin Authentication# Administrative operations require the admin API key:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;,\u0026#34;email\u0026#34;:\u0026#34;alice@example.com\u0026#34;}\u0026#39;Admin key is set via SERVICE_ADMINKEY environment variable.\nUser Creation# By Admin# Only admin users can create new users:\nPOST /v1/users Authorization: Bearer ADMIN_KEY { \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34; }Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34;, \u0026#34;vdb_key\u0026#34;: \u0026#34;024v2013621509245f2e24abcdef...\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; }Important: Save the vdb_key immediately - it cannot be recovered later.\nUser Handle Restrictions# Must be 3-20 characters Alphanumeric characters and underscores only Must be unique Cannot be _system User Management# Retrieve User Information# Users can view their own information:\nGET /v1/users/alice Authorization: Bearer alice_vdb_keyAdmins can view any user:\nGET /v1/users/alice Authorization: Bearer ADMIN_KEYList All Users# Only admins can list all users:\nGET /v1/users Authorization: Bearer ADMIN_KEYReturns array of user handles (not full user objects).\nUpdate User# Users can update their own information:\nPATCH /v1/users/alice Authorization: Bearer alice_vdb_key { \u0026#34;name\u0026#34;: \u0026#34;Alice Smith-Jones\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34; }Delete User# Users can delete their own account:\nDELETE /v1/users/alice Authorization: Bearer alice_vdb_keyAdmins can delete any user:\nDELETE /v1/users/alice Authorization: Bearer ADMIN_KEYCascading Deletion:\nAll user\u0026rsquo;s projects are deleted All user\u0026rsquo;s LLM service instances are deleted All embeddings in user\u0026rsquo;s projects are deleted Sharing grants from this user to others are removed Authorization Model# Resource Ownership# Users own three types of resources:\nProjects: Collections of embeddings LLM Service Instances: Embedding configurations with API keys LLM Service Definitions: Reusable configuration templates (optional) Access Levels# Owner\nFull control over resource Can read, write, delete Can share with others Can transfer ownership (projects only) Editor (via sharing)\nRead and write access Cannot delete resource Cannot modify sharing Cannot change project settings Reader (via sharing)\nRead-only access Can view embeddings Can search for similar documents Cannot modify anything Public (if project.public_read = true)\nUnauthenticated read access Can view embeddings Can search for similar documents Cannot write or modify Security Best Practices# API Key Management# Storage\nStore API keys securely (e.g., environment variables, secret managers) Never commit API keys to version control Use different keys for development and production Rotation\nCurrently, API keys cannot be rotated To change a key, delete and recreate the user Plan key rotation strategy before production deployment Transmission\nAlways use HTTPS in production API keys are transmitted in Authorization header Never pass API keys in URL query parameters User Key vs. LLM API Keys# dhamps-vdb handles two types of keys:\nUser API keys (vdb_key): Authenticate users to dhamps-vdb\nStored as SHA-256 hash in database Never encrypted (one-way hash) Returned only once on user creation LLM API keys (api_key_encrypted): Authenticate to LLM services\nStored encrypted (AES-256-GCM) in database Never returned in API responses Used internally for LLM processing Multi-User Workflows# Collaboration Pattern# Admin creates user accounts for team members Project Owner creates project with embeddings Owner shares project with collaborators Readers can search and view embeddings Editors can add/modify embeddings Organization Pattern# Admin creates organizational users Each user creates LLM service instances with their own API keys Users create projects using their instances Projects shared within organization as needed Public Access Pattern# User creates project with research data User sets public_read: true Anyone can access embeddings and search without authentication Only owner can modify project User Limits# Current Implementation# No enforced limits on:\nNumber of projects per user Number of embeddings per project Number of LLM service instances per user Storage size per user Recommended Limits# For production deployments, consider implementing:\nRate limiting per API key Storage quotas per user Maximum project count per user Example Workflows# Create and Use User Account# # Admin creates user curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34; }\u0026#39; # Save returned vdb_key export USER_KEY=\u0026#34;returned-vdb-key\u0026#34; # User verifies access curl -X GET http://localhost:8880/v1/users/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; # User creates project curl -X POST http://localhost:8880/v1/projects/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My research project\u0026#34; }\u0026#39;Share Resources# # User shares project with colleague curl -X POST http://localhost:8880/v1/projects/researcher1/my-project/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39; # Colleague accesses shared project curl -X GET http://localhost:8880/v1/projects/researcher1/my-project \\ -H \u0026#34;Authorization: Bearer $COLLEAGUE_KEY\u0026#34;Troubleshooting# 401 Unauthorized# Possible causes:\nMissing Authorization header Incorrect API key Expired or invalid key Using user key instead of admin key (or vice versa) Solution:\nVerify API key is correct Check Authorization header format: Bearer KEY Ensure operation matches key type (admin vs. user) 403 Forbidden# Possible causes:\nUser doesn\u0026rsquo;t own resource User not granted access to shared resource Insufficient permissions (reader trying to edit) Solution:\nVerify resource ownership Check sharing grants Ensure user has required role (editor for writes) User Creation Failed# Possible causes:\nUser handle already exists Email already registered Invalid user handle format Not using admin key Solution:\nChoose different user handle Use unique email address Check user handle format (3-20 chars, alphanumeric + underscore) Verify using admin API key Next Steps# Learn about projects Understand LLM services Explore project sharing "},{"id":19,"href":"/dhamps-vdb/development/architecture/","title":"Architecture","section":"Development","content":"Technical Architecture# This document provides a technical deep-dive into dhamps-vdb\u0026rsquo;s architecture for developers who want to understand or modify the codebase.\nProject Structure# dhamps-vdb/ ├── main.go # Application entry point ├── go.mod # Go module definition ├── go.sum # Dependency checksums ├── sqlc.yaml # sqlc configuration ├── template.env # Environment template ├── .env # Local config (gitignored) │ ├── api/ │ └── openapi.yml # OpenAPI spec (not actively maintained) │ ├── internal/ # Internal packages (non-importable) │ ├── auth/ # Authentication logic │ │ └── authenticate.go # Bearer token validation │ │ │ ├── crypto/ # Encryption utilities │ │ └── crypto.go # AES-256-GCM encryption │ │ │ ├── database/ # Database layer │ │ ├── database.go # Connection pool management │ │ ├── migrations.go # Migration runner │ │ ├── db.go # Generated by sqlc │ │ ├── models.go # Generated by sqlc │ │ ├── queries.sql.go # Generated by sqlc │ │ │ │ │ ├── migrations/ # SQL migrations │ │ │ ├── 001_create_initial_scheme.sql │ │ │ ├── 002_create_emb_index.sql │ │ │ ├── 003_add_public_read_flag.sql │ │ │ ├── 004_refactor_llm_services_architecture.sql │ │ │ ├── tern.conf.tpl # Template for tern │ │ │ └── tern.conf # Generated (gitignored) │ │ │ │ │ └── queries/ # SQL queries for sqlc │ │ └── queries.sql # All database queries │ │ │ ├── handlers/ # HTTP request handlers │ │ ├── handlers.go # Common handler utilities │ │ ├── users.go # User endpoints │ │ ├── projects.go # Project endpoints │ │ ├── llm_services.go # LLM service endpoints │ │ ├── api_standards.go # API standard endpoints │ │ ├── embeddings.go # Embedding endpoints │ │ ├── similars.go # Similarity search endpoints │ │ ├── admin.go # Admin endpoints │ │ │ │ │ └── *_test.go # Test files │ │ ├── users_test.go │ │ ├── projects_test.go │ │ ├── projects_sharing_test.go │ │ ├── embeddings_test.go │ │ ├── llm_services_test.go │ │ ├── editor_permissions_test.go │ │ └── handlers_test.go │ │ │ └── models/ # Data models and options │ ├── options.go # CLI/environment options │ ├── users.go # User models │ ├── projects.go # Project models │ ├── instances.go # LLM instance models (new) │ ├── api_standards.go # API standard models │ ├── embeddings.go # Embedding models │ ├── similars.go # Similarity search models │ └── admin.go # Admin operation models │ ├── testdata/ # Test fixtures │ ├── postgres/ # PostgreSQL test data │ │ ├── enable-vector.sql │ │ └── users.yml │ │ │ └── *.json # JSON test fixtures │ ├── valid_user.json │ ├── valid_embeddings.json │ ├── valid_api_standard_*.json │ └── valid_llm_service_*.json │ └── docs/ # Documentation ├── content/ # Hugo content └── *.md # Additional docsCode Organization# 1. Entry Point (main.go)# The application entry point handles:\nfunc main() { // 1. Parse CLI options and environment variables cli := huma.NewCLI(func(hooks huma.Hooks, opts *models.Options) { // 2. Initialize database connection pool pool := database.InitDB(opts) defer pool.Close() // 3. Run database migrations database.RunMigrations(pool, opts) // 4. Create HTTP router and Huma API router := http.NewServeMux() api := humago.New(router, huma.DefaultConfig(\u0026#34;dhamps-vdb\u0026#34;, \u0026#34;0.1.0\u0026#34;)) // 5. Register all routes handlers.AddRoutes(pool, keyGen, api) // 6. Start HTTP server server := \u0026amp;http.Server{ Addr: fmt.Sprintf(\u0026#34;%s:%d\u0026#34;, opts.Host, opts.Port), Handler: router, } server.ListenAndServe() }) cli.Run() }2. Handlers (internal/handlers/)# Handlers process HTTP requests using the Huma framework pattern:\n// Example: Create User Handler func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { // Define request/response types type CreateUserInput struct { Body models.CreateUserRequest } type CreateUserOutput struct { Body models.User } // Register operation with Huma huma.Register(api, huma.Operation{ OperationID: \u0026#34;create-user\u0026#34;, Method: http.MethodPost, Path: \u0026#34;/v1/users\u0026#34;, Summary: \u0026#34;Create a new user\u0026#34;, Description: \u0026#34;Admin only. Creates user and returns API key.\u0026#34;, Security: []map[string][]string{{\u0026#34;bearer\u0026#34;: {}}}, }, func(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { // 1. Get authenticated user from context authUser := auth.GetAuthenticatedUser(ctx) // 2. Check authorization (admin only) if !authUser.IsAdmin { return nil, huma.Error403Forbidden(\u0026#34;admin access required\u0026#34;) } // 3. Validate input if err := input.Body.Validate(); err != nil { return nil, huma.Error400BadRequest(\u0026#34;invalid input\u0026#34;, err) } // 4. Business logic user, apiKey, err := createUserWithKey(ctx, pool, keyGen, \u0026amp;input.Body) if err != nil { return nil, handleDatabaseError(err) } // 5. Return response return \u0026amp;CreateUserOutput{Body: *user}, nil }) }Handler file organization:\nhandlers.go - Common utilities (context keys, error handling) users.go - User CRUD operations projects.go - Project CRUD and sharing llm_services.go - LLM service/instance management embeddings.go - Embedding CRUD operations similars.go - Similarity search admin.go - Administrative operations 3. Models (internal/models/)# Models define request/response structures:\n// User model type User struct { UserHandle string `json:\u0026#34;user_handle\u0026#34; example:\u0026#34;alice\u0026#34;` Name string `json:\u0026#34;name\u0026#34; example:\u0026#34;Alice Smith\u0026#34;` Email string `json:\u0026#34;email\u0026#34; example:\u0026#34;alice@example.com\u0026#34;` CreatedAt time.Time `json:\u0026#34;created_at\u0026#34;` UpdatedAt time.Time `json:\u0026#34;updated_at\u0026#34;` } // Request model with validation type CreateUserRequest struct { UserHandle string `json:\u0026#34;user_handle\u0026#34; minLength:\u0026#34;1\u0026#34; maxLength:\u0026#34;50\u0026#34; pattern:\u0026#34;^[a-z0-9_-]+$\u0026#34;` Name string `json:\u0026#34;name\u0026#34; minLength:\u0026#34;1\u0026#34; maxLength:\u0026#34;100\u0026#34;` Email string `json:\u0026#34;email\u0026#34; format:\u0026#34;email\u0026#34;` } func (r *CreateUserRequest) Validate() error { if r.UserHandle == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;user_handle is required\u0026#34;) } if r.UserHandle == \u0026#34;_system\u0026#34; { return fmt.Errorf(\u0026#34;_system is a reserved handle\u0026#34;) } return nil }Model conventions:\nRequest models: Create*Request, Update*Request Response models: *Response, *Output Database models: Match database schema (generated by sqlc) 4. Database Layer (internal/database/)# Connection Management (database.go)# func InitDB(opts *models.Options) *pgxpool.Pool { connString := fmt.Sprintf( \u0026#34;postgres://%s:%s@%s:%d/%s\u0026#34;, opts.DBUser, opts.DBPassword, opts.DBHost, opts.DBPort, opts.DBName, ) config, err := pgxpool.ParseConfig(connString) if err != nil { log.Fatal(err) } // Configure connection pool config.MaxConns = 20 config.MinConns = 5 config.MaxConnIdleTime = time.Minute * 5 pool, err := pgxpool.NewWithConfig(context.Background(), config) if err != nil { log.Fatal(err) } return pool }Migrations (migrations.go)# Uses tern for versioned migrations:\nfunc RunMigrations(pool *pgxpool.Pool, opts *models.Options) error { // Create tern configuration config := createTernConfig(opts) // Initialize migrator migrator, err := migrate.NewMigrator(context.Background(), pool, \u0026#34;schema_version\u0026#34;) if err != nil { return err } // Run pending migrations err = migrator.Migrate(context.Background()) if err != nil { return fmt.Errorf(\u0026#34;migration failed: %w\u0026#34;, err) } return nil }Migration files are numbered sequentially:\n-- 001_create_initial_scheme.sql CREATE TABLE users ( user_id SERIAL PRIMARY KEY, user_handle TEXT UNIQUE NOT NULL, vdb_key TEXT UNIQUE NOT NULL, ... ); CREATE TABLE projects ( project_id SERIAL PRIMARY KEY, project_handle TEXT NOT NULL, owner TEXT NOT NULL REFERENCES users(user_handle), ... ); -- 002_create_emb_index.sql CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);SQLC Queries (queries/queries.sql)# Write SQL, generate type-safe Go code:\n-- name: UpsertUser :one INSERT INTO users ( user_handle, name, email, vdb_key, created_at, updated_at ) VALUES ( $1, $2, $3, $4, NOW(), NOW() ) ON CONFLICT (user_handle) DO UPDATE SET name = EXCLUDED.name, email = EXCLUDED.email, updated_at = NOW() RETURNING *; -- name: GetUserByHandle :one SELECT * FROM users WHERE user_handle = $1; -- name: GetAllUsers :many SELECT user_handle, name, email, created_at, updated_at FROM users ORDER BY user_handle ASC; -- name: DeleteUser :exec DELETE FROM users WHERE user_handle = $1;Generated Go code (queries.sql.go):\n// Generated by sqlc func (q *Queries) UpsertUser(ctx context.Context, arg UpsertUserParams) (User, error) { row := q.db.QueryRow(ctx, upsertUser, arg.UserHandle, arg.Name, arg.Email, arg.VdbKey, ) var i User err := row.Scan( \u0026amp;i.UserID, \u0026amp;i.UserHandle, \u0026amp;i.Name, \u0026amp;i.Email, \u0026amp;i.VdbKey, \u0026amp;i.CreatedAt, \u0026amp;i.UpdatedAt, ) return i, err }sqlc configuration (sqlc.yaml):\nversion: \u0026#34;2\u0026#34; sql: - engine: \u0026#34;postgresql\u0026#34; queries: \u0026#34;internal/database/queries/queries.sql\u0026#34; schema: \u0026#34;internal/database/migrations/\u0026#34; gen: go: package: \u0026#34;database\u0026#34; out: \u0026#34;internal/database\u0026#34; emit_json_tags: true emit_db_tags: true emit_prepared_queries: false emit_interface: falseRegenerate code after query changes:\nsqlc generate --no-remote5. Authentication (internal/auth/)# Token-based authentication using Bearer tokens:\n// Middleware checks Authorization header func AuthMiddleware(pool *pgxpool.Pool, adminKey string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Extract Bearer token authHeader := r.Header.Get(\u0026#34;Authorization\u0026#34;) token := strings.TrimPrefix(authHeader, \u0026#34;Bearer \u0026#34;) if token == \u0026#34;\u0026#34; { // Allow public access for certain endpoints ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, nil) next.ServeHTTP(w, r.WithContext(ctx)) return } // Check admin key if token == adminKey { user := \u0026amp;AuthUser{Handle: \u0026#34;_admin\u0026#34;, IsAdmin: true} ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, user) next.ServeHTTP(w, r.WithContext(ctx)) return } // Look up user by API key hash hash := hashAPIKey(token) user, err := db.GetUserByKeyHash(r.Context(), pool, hash) if err != nil { http.Error(w, \u0026#34;Unauthorized\u0026#34;, http.StatusUnauthorized) return } authUser := \u0026amp;AuthUser{Handle: user.UserHandle, IsAdmin: false} ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, authUser) next.ServeHTTP(w, r.WithContext(ctx)) }) } } // Helper to get authenticated user from context func GetAuthenticatedUser(ctx context.Context) *AuthUser { user, _ := ctx.Value(\u0026#34;user\u0026#34;).(*AuthUser) return user }6. Encryption (internal/crypto/)# AES-256-GCM encryption for sensitive data (API keys):\n// Encrypt data with AES-256-GCM func Encrypt(plaintext []byte, key []byte) ([]byte, error) { // Ensure key is 32 bytes keyHash := sha256.Sum256(key) // Create AES cipher block, err := aes.NewCipher(keyHash[:]) if err != nil { return nil, err } // Create GCM gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } // Generate random nonce nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err } // Encrypt and append nonce ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) return ciphertext, nil } func Decrypt(ciphertext []byte, key []byte) ([]byte, error) { // Derive key keyHash := sha256.Sum256(key) block, err := aes.NewCipher(keyHash[:]) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } // Extract nonce nonceSize := gcm.NonceSize() nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] // Decrypt plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, err } return plaintext, nil }Huma Framework Integration# dhamps-vdb uses Huma for API development:\nBenefits# Automatic OpenAPI generation - No manual spec maintenance Request/response validation - Type-safe with JSON schema Error handling - Standardized error responses Documentation - Interactive docs at /docs Operation Registration Pattern# huma.Register(api, huma.Operation{ OperationID: \u0026#34;get-project\u0026#34;, Method: http.MethodGet, Path: \u0026#34;/v1/projects/{owner}/{project}\u0026#34;, Summary: \u0026#34;Get project details\u0026#34;, Description: \u0026#34;Returns full project information including metadata schema\u0026#34;, Tags: []string{\u0026#34;Projects\u0026#34;}, Security: []map[string][]string{{\u0026#34;bearer\u0026#34;: {}}}, MaxBodyBytes: 1024, // Limit request size DefaultStatus: http.StatusOK, Errors: []int{400, 401, 403, 404, 500}, }, handlerFunction)Input/Output Patterns# // Path parameters, query parameters, and body type GetSimilarInput struct { Owner string `path:\u0026#34;owner\u0026#34; doc:\u0026#34;Project owner\u0026#34;` Project string `path:\u0026#34;project\u0026#34; doc:\u0026#34;Project handle\u0026#34;` TextID string `path:\u0026#34;text_id\u0026#34; doc:\u0026#34;Text identifier\u0026#34;` Threshold float32 `query:\u0026#34;threshold\u0026#34; default:\u0026#34;0.5\u0026#34; doc:\u0026#34;Similarity threshold\u0026#34;` Limit int `query:\u0026#34;limit\u0026#34; default:\u0026#34;10\u0026#34; maximum:\u0026#34;200\u0026#34; doc:\u0026#34;Max results\u0026#34;` } // Response with status code type GetSimilarOutput struct { Status int Body models.SimilarResponse }Error Response Pattern# // Standard error responses return nil, huma.Error400BadRequest(\u0026#34;validation failed\u0026#34;, err) return nil, huma.Error401Unauthorized(\u0026#34;invalid credentials\u0026#34;) return nil, huma.Error403Forbidden(\u0026#34;insufficient permissions\u0026#34;) return nil, huma.Error404NotFound(\u0026#34;project not found\u0026#34;) return nil, huma.Error500InternalServerError(\u0026#34;database error\u0026#34;, err) // Custom error with details return nil, huma.NewError(400, \u0026#34;Dimension Mismatch\u0026#34;, fmt.Sprintf(\u0026#34;expected %d dimensions, got %d\u0026#34;, expected, actual))Design Patterns# 1. Repository Pattern (via sqlc)# Database access is centralized in generated queries:\n// Don\u0026#39;t write SQL in handlers // Bad: rows, err := pool.Query(ctx, \u0026#34;SELECT * FROM users\u0026#34;) // Good: Use generated functions users, err := db.GetAllUsers(ctx)2. Dependency Injection# Pass dependencies explicitly:\n// Inject pool into handlers func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { // Routes have access to pool } // Store in context for handler access ctx = context.WithValue(ctx, PoolKey, pool)3. Interface-Based Testing# Use interfaces for testability:\n// Production: Real random key generator type StandardKeyGen struct{} func (s StandardKeyGen) RandomKey(len int) (string, error) { b := make([]byte, len) _, err := rand.Read(b) return hex.EncodeToString(b), err } // Testing: Deterministic key generator type MockKeyGen struct { Keys []string idx int } func (m *MockKeyGen) RandomKey(len int) (string, error) { key := m.Keys[m.idx] m.idx++ return key, nil }4. Validation at Multiple Layers# // 1. Huma validates request structure type CreateEmbeddingInput struct { Body models.Embedding `maxLength:\u0026#34;1000000\u0026#34;` } // 2. Model validates business rules func (e *Embedding) Validate() error { if e.TextID == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;text_id required\u0026#34;) } return nil } // 3. Handler validates against database state func CreateEmbedding(ctx context.Context, input *CreateEmbeddingInput) error { // Check project exists // Validate dimensions match LLM service // Validate metadata against schema // Then insert }5. Error Wrapping# Provide context while preserving original error:\nuser, err := db.GetUserByHandle(ctx, handle) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, huma.Error404NotFound(\u0026#34;user not found\u0026#34;) } return nil, fmt.Errorf(\u0026#34;failed to retrieve user %s: %w\u0026#34;, handle, err) }Internal Packages# Go\u0026rsquo;s internal/ directory enforces package privacy:\n// This import works within dhamps-vdb import \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; // This import would FAIL from external projects // Enforced by Go compilerBenefits:\nClear API boundaries Implementation details hidden Refactoring without breaking external users Performance Considerations# Connection Pooling# config.MaxConns = 20 // Max concurrent connections config.MinConns = 5 // Keep-alive connections config.MaxConnIdleTime = 5 * time.MinuteQuery Optimization# Use UNION ALL for better performance:\n// Instead of LEFT JOIN with OR conditions query := ` SELECT * FROM projects WHERE owner = $1 UNION ALL SELECT p.* FROM projects p INNER JOIN projects_shared_with ps USING (project_id) WHERE ps.user_handle = $1 ORDER BY owner, project_handle `Index Strategy# -- Dimension filtering (very important) CREATE INDEX ON embeddings(project_id, vector_dim); -- Vector similarity (HNSW for accuracy) CREATE INDEX ON embeddings USING hnsw (vector vector_cosine_ops); -- Access lookups CREATE INDEX ON projects_shared_with(user_handle); CREATE INDEX ON projects(owner, project_handle);See Performance Guide for detailed optimization strategies.\nTesting Architecture# Test Organization# // handlers_test.go - Setup and utilities func setupTestDB(t *testing.T) *pgxpool.Pool { } func createTestUser(t *testing.T, pool *pgxpool.Pool) *models.User { } // users_test.go - User-specific tests func TestCreateUser(t *testing.T) { } func TestGetUser(t *testing.T) { } // projects_sharing_test.go - Sharing feature tests func TestShareProject(t *testing.T) { }Testcontainers Integration# func setupTestDB(t *testing.T) *pgxpool.Pool { ctx := context.Background() // Start PostgreSQL with pgvector req := testcontainers.ContainerRequest{ Image: \u0026#34;pgvector/pgvector:0.7.4-pg16\u0026#34;, ExposedPorts: []string{\u0026#34;5432/tcp\u0026#34;}, Env: map[string]string{ \u0026#34;POSTGRES_PASSWORD\u0026#34;: \u0026#34;password\u0026#34;, \u0026#34;POSTGRES_DB\u0026#34;: \u0026#34;testdb\u0026#34;, }, } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) require.NoError(t, err) // Connect and migrate pool := connectAndMigrate(ctx, container) return pool }See Testing Guide for comprehensive testing documentation.\nBuild and Deployment# Building# # Development build go build -o dhamps-vdb main.go # Production build with optimizations go build -ldflags=\u0026#34;-s -w\u0026#34; -o dhamps-vdb main.go # Cross-compilation GOOS=linux GOARCH=amd64 go build -o dhamps-vdb-linux main.goDocker Build# Multi-stage build for minimal image:\n# Build stage FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o dhamps-vdb main.go # Runtime stage FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/dhamps-vdb . EXPOSE 8880 CMD [\u0026#34;./dhamps-vdb\u0026#34;]Configuration# Application reads configuration from:\nCommand line flags: --port 8080 Environment variables: SERVICE_PORT=8080 .env file: SERVICE_PORT=8080 Priority: CLI flags \u0026gt; Environment \u0026gt; .env file \u0026gt; Defaults\nNext Steps# Testing Guide - Learn how to test changes Contributing Guide - Start contributing Performance Guide - Optimize queries and indexes "},{"id":20,"href":"/dhamps-vdb/deployment/environment-variables/","title":"Environment Variables","section":"Deployment","content":"Environment Variables# Complete reference for all environment variables used by dhamps-vdb.\nOverview# dhamps-vdb is configured entirely through environment variables. These can be set:\nIn a .env file (recommended for Docker) As system environment variables Via command-line flags (some variables only) Required Variables# These variables must be set for dhamps-vdb to function:\nSERVICE_ADMINKEY# Admin API key for administrative operations.\nType: String Required: Yes Default: None Environment Variable: SERVICE_ADMINKEY Command-line Flag: --admin-key Description: Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.\nExample:\nSERVICE_ADMINKEY=Ch4ngeM3SecureAdminKey!Security:\nGenerate with: openssl rand -base64 32 Never commit to version control Rotate regularly Store securely (password manager, secrets vault) Usage:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $SERVICE_ADMINKEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;full_name\u0026#34;: \u0026#34;Alice Smith\u0026#34;}\u0026#39;ENCRYPTION_KEY# Encryption key for protecting user API keys in the database.\nType: String (32+ characters) Required: Yes Default: None Environment Variable: ENCRYPTION_KEY Description: AES-256 encryption key used to encrypt user API keys before storing them in the database. Must be at least 32 characters. The key is hashed with SHA-256 to ensure exactly 32 bytes for AES-256 encryption.\nExample:\nENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6Security:\nGenerate with: openssl rand -hex 32 Minimum 32 characters required Never commit to version control CRITICAL: If lost, all stored API keys become unrecoverable Backup securely and separately from database Never change in production (will invalidate all existing API keys) Technical Details:\nUses AES-256-GCM for encryption SHA-256 hash ensures correct key length Each encryption uses unique nonce Encrypted keys stored as base64 in database Optional Variables# SERVICE_DEBUG# Enable debug logging.\nType: Boolean Required: No Default: true Environment Variable: SERVICE_DEBUG Command-line Flag: -d, --debug Description: Enables verbose debug logging including request details, SQL queries, and internal operations.\nExample:\nSERVICE_DEBUG=false # Production (less verbose) SERVICE_DEBUG=true # Development (verbose)Impact:\ntrue: Detailed logs, useful for debugging false: Minimal logs, recommended for production SERVICE_HOST# Hostname or IP address to bind the service to.\nType: String Required: No Default: localhost Environment Variable: SERVICE_HOST Command-line Flag: --host Description: Network interface to listen on. Use 0.0.0.0 to listen on all interfaces (required for Docker).\nExamples:\nSERVICE_HOST=localhost # Local development only SERVICE_HOST=0.0.0.0 # Listen on all interfaces (Docker) SERVICE_HOST=10.0.1.5 # Specific interfaceSecurity:\nUse localhost for development Use 0.0.0.0 for Docker/production with firewall Never expose directly to internet without reverse proxy SERVICE_PORT# Port number for the API service.\nType: Integer Required: No Default: 8880 Environment Variable: SERVICE_PORT Command-line Flag: -p, --port Description: TCP port the service listens on.\nExample:\nSERVICE_PORT=8880 # Default SERVICE_PORT=8080 # Alternative SERVICE_PORT=3000 # CustomNotes:\nPorts below 1024 require root/admin privileges Ensure port is not already in use Update firewall rules accordingly Database Variables# SERVICE_DBHOST# Database hostname or IP address.\nType: String Required: No Default: localhost Environment Variable: SERVICE_DBHOST Command-line Flag: --db-host Description: PostgreSQL server hostname.\nExamples:\nSERVICE_DBHOST=localhost # Local PostgreSQL SERVICE_DBHOST=postgres # Docker Compose service name SERVICE_DBHOST=db.example.com # Remote database SERVICE_DBHOST=10.0.1.100 # Database IP addressSERVICE_DBPORT# Database port number.\nType: Integer Required: No Default: 5432 Environment Variable: SERVICE_DBPORT Command-line Flag: --db-port Description: PostgreSQL server port.\nExample:\nSERVICE_DBPORT=5432 # Default PostgreSQL port SERVICE_DBPORT=5433 # Alternative portSERVICE_DBUSER# Database username.\nType: String Required: No Default: postgres Environment Variable: SERVICE_DBUSER Command-line Flag: --db-user Description: PostgreSQL user for database connections.\nExample:\nSERVICE_DBUSER=postgres # Default superuser SERVICE_DBUSER=dhamps_user # Dedicated user (recommended)Security:\nCreate dedicated user (not superuser) for production Use principle of least privilege See Database Setup for user creation SERVICE_DBPASSWORD# Database password.\nType: String Required: No Default: password Environment Variable: SERVICE_DBPASSWORD Command-line Flag: --db-password Description: Password for database authentication.\nExample:\nSERVICE_DBPASSWORD=secure_database_password_hereSecurity:\nUse strong, randomly generated password Never use default password in production Never commit to version control Store in secrets management system Rotate regularly SERVICE_DBNAME# Database name.\nType: String Required: No Default: postgres Environment Variable: SERVICE_DBNAME Command-line Flag: --db-name Description: Name of the PostgreSQL database.\nExample:\nSERVICE_DBNAME=dhamps_vdb # Production database SERVICE_DBNAME=dhamps_test # Testing databaseConfiguration Examples# Development Setup# # .env file for development SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=dev-admin-key-not-for-production ENCRYPTION_KEY=dev-encryption-key-min-32-chars-longDocker Compose Setup# # .env file for Docker Compose SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=postgres SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=secure_db_password_here SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=generated_admin_key_from_setup_script ENCRYPTION_KEY=generated_encryption_key_from_setup_scriptProduction Setup# # .env file for production (or use secrets management) SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=db.internal.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod_user SERVICE_DBPASSWORD=\u0026lt;from-secrets-manager\u0026gt; SERVICE_DBNAME=dhamps_vdb_prod SERVICE_ADMINKEY=\u0026lt;from-secrets-manager\u0026gt; ENCRYPTION_KEY=\u0026lt;from-secrets-manager\u0026gt;Setting Environment Variables# Using .env File (Recommended)# Create a .env file in the project root:\n# Copy template cp template.env .env # Edit with your values nano .envThe application automatically loads .env on startup.\nUsing System Environment Variables# # Linux/macOS export SERVICE_ADMINKEY=\u0026#34;your-admin-key\u0026#34; export ENCRYPTION_KEY=\u0026#34;your-encryption-key\u0026#34; # Windows PowerShell $env:SERVICE_ADMINKEY = \u0026#34;your-admin-key\u0026#34; $env:ENCRYPTION_KEY = \u0026#34;your-encryption-key\u0026#34; # Windows Command Prompt set SERVICE_ADMINKEY=your-admin-key set ENCRYPTION_KEY=your-encryption-keyUsing Docker# With docker run:\ndocker run -d \\ -e SERVICE_ADMINKEY=admin-key \\ -e ENCRYPTION_KEY=encryption-key \\ -e SERVICE_DBHOST=db-host \\ dhamps-vdb:latestWith docker-compose.yml:\nservices: dhamps-vdb: image: dhamps-vdb:latest environment: SERVICE_DEBUG: \u0026#34;false\u0026#34; SERVICE_HOST: \u0026#34;0.0.0.0\u0026#34; SERVICE_PORT: \u0026#34;8880\u0026#34; SERVICE_DBHOST: \u0026#34;postgres\u0026#34; env_file: - .env # Load additional variables from fileUsing Command-Line Flags# Some variables support command-line flags:\n./dhamps-vdb \\ --debug \\ --host 0.0.0.0 \\ --port 8880 \\ --admin-key your-admin-key \\ --db-host localhost \\ --db-port 5432 \\ --db-user postgres \\ --db-password password \\ --db-name dhamps_vdbNote: ENCRYPTION_KEY must be set as environment variable, not flag.\nValidation and Troubleshooting# Missing Required Variables# If required variables are not set, the service will fail to start:\nError: SERVICE_ADMINKEY environment variable is not setSolution: Set the missing variable.\nInvalid ENCRYPTION_KEY# If ENCRYPTION_KEY is too short or invalid:\nError: ENCRYPTION_KEY environment variable is not setSolution: Ensure key is at least 32 characters:\nopenssl rand -hex 32Database Connection Failure# Error: failed to connect to databaseCheck:\nSERVICE_DBHOST is correct and reachable SERVICE_DBPORT is correct SERVICE_DBUSER and SERVICE_DBPASSWORD are valid SERVICE_DBNAME exists PostgreSQL is running Firewall allows connection Testing Configuration# # Start service with debug logging SERVICE_DEBUG=true ./dhamps-vdb # Check if service starts successfully curl http://localhost:8880/docs # Test admin authentication curl -X GET http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $SERVICE_ADMINKEY\u0026#34;Security Best Practices# Never commit .env files to version control\nAlready in .gitignore Use .env.example templates Generate secure random keys\nopenssl rand -base64 32 # Admin key openssl rand -hex 32 # Encryption key Use secrets management in production\nHashiCorp Vault AWS Secrets Manager Azure Key Vault Docker Secrets (Swarm) Kubernetes Secrets Rotate keys regularly\nAdmin key: Every 90 days Database password: Every 90 days Encryption key: Cannot be rotated without re-encrypting all API keys Principle of least privilege\nUse dedicated database user (not superuser) Grant only necessary permissions Restrict network access Monitor and audit\nLog admin key usage Monitor failed authentication attempts Review access patterns Further Reading# Docker Deployment Guide Database Setup Security Best Practices Configuration Guide Quick Start "},{"id":21,"href":"/dhamps-vdb/guides/","title":"Guides","section":"dhamps-vdb Documentation","content":"User Guides# Step-by-step guides for common tasks and workflows with dhamps-vdb.\nAvailable Guides# This section contains practical guides for using dhamps-vdb in real-world scenarios:\nRAG Workflows - Implement Retrieval Augmented Generation Project Sharing - Collaborate with other users Public Projects - Enable unauthenticated access Ownership Transfer - Move projects between users Metadata Validation - Ensure data quality with schemas Metadata Filtering - Exclude documents from similarity search Batch Operations - Work with multiple embeddings efficiently Instance Management - Configure LLM service instances These guides complement the API reference by providing context and best practices for common use cases.\n"},{"id":22,"href":"/dhamps-vdb/api/endpoints/llm-services/","title":"LLM Services","section":"Endpoints","content":"LLM Services Endpoint# Manage LLM service instances and definitions. The system supports two types of LLM service resources:\nDefinitions: Reusable templates owned by _system or individual users Instances: User-specific configurations with API keys that reference definitions or stand alone Architecture Overview# definitions (templates) └── owned by _system or users └── contain: endpoint, model, dimensions, api_standard └── no API keys instances (user-specific) └── owned by individual users └── reference a definition (optional) └── contain encrypted API keys └── can be shared with other usersFor complete details, see LLM Service Refactoring Documentation.\nInstance Endpoints# List User\u0026rsquo;s Instances# Get all LLM service instances owned by or shared with a user.\nEndpoint: GET /v1/llm-services/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;definition_id\u0026#34;: 1 }, { \u0026#34;instance_id\u0026#34;: 2, \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom.api.example.com/embed\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed-v1\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ] }Note: API keys are never returned in GET responses for security.\nCreate or Update Instance (PUT)# Create a new LLM service instance or update an existing one.\nEndpoint: PUT /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the user themselves\nRequest Body (Standalone Instance):\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Request Body (From Definition):\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Parameters:\ninstance_handle (string, required): Unique identifier within user\u0026rsquo;s namespace endpoint (string, required for standalone): API endpoint URL description (string, optional): Instance description api_standard (string, required for standalone): Reference to API standard (e.g., \u0026ldquo;openai\u0026rdquo;, \u0026ldquo;cohere\u0026rdquo;) model (string, required for standalone): Model name dimensions (integer, required for standalone): Vector dimensions api_key_encrypted (string, optional): API key (encrypted if ENCRYPTION_KEY is set) definition_owner (string, optional): Owner of the definition template definition_handle (string, optional): Handle of the definition template Example - Standalone:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }\u0026#39;Example - From _system Definition:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }Security Note: API keys are encrypted using AES-256-GCM if the ENCRYPTION_KEY environment variable is set. Keys are never returned in responses.\nGet Instance Information# Retrieve information about a specific LLM service instance.\nEndpoint: GET /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin, owner, or users with shared access\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;definition_id\u0026#34;: 1 } Delete Instance# Delete an LLM service instance.\nEndpoint: DELETE /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;LLM service instance alice/openai-large deleted successfully\u0026#34; }⚠️ Warning: Cannot delete instances that are in use by projects.\nPartial Update (PATCH)# Update specific instance fields without providing all data.\nEndpoint: PATCH /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the owner\nExample - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }\u0026#39;See PATCH Updates for more details.\nInstance Sharing# Share Instance# Share an LLM service instance with another user.\nEndpoint: POST /v1/llm-services/{owner}/{instance}/share\nAuthentication: Admin or the instance owner\nRequest Body:\n{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Roles:\nreader: Can use the instance but cannot see API keys editor: Can use the instance (owner can still modify) owner: Full control (cannot be granted via sharing) Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Important: Shared users can USE the instance but cannot see the API key.\nUnshare Instance# Remove a user\u0026rsquo;s access to a shared instance.\nEndpoint: DELETE /v1/llm-services/{owner}/{instance}/share/{user_handle}\nAuthentication: Admin or the instance owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; List Shared Users# Get a list of users the instance is shared with.\nEndpoint: GET /v1/llm-services/{owner}/{instance}/shared-with\nAuthentication: Admin or the instance owner\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance\u0026#34;: \u0026#34;alice/openai-large\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] } Definition Endpoints# List System Definitions# Get all LLM service definitions owned by _system.\nEndpoint: GET /v1/llm-service-definitions/_system\nAuthentication: Any authenticated user\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-service-definitions/_system\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;definitions\u0026#34;: [ { \u0026#34;definition_id\u0026#34;: 1, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI text-embedding-3-large\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }, { \u0026#34;definition_id\u0026#34;: 2, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI text-embedding-3-small\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-small\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ] }Pre-seeded System Definitions:\nopenai-large: OpenAI text-embedding-3-large (3072 dimensions) openai-small: OpenAI text-embedding-3-small (1536 dimensions) cohere-v4: Cohere embed-english-v4.0 (1536 dimensions) gemini-embedding-001: Google Gemini embedding-001 (768 dimensions) Create User Definition# Create a reusable LLM service definition template.\nEndpoint: POST /v1/llm-service-definitions/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;definition_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom.api.example.com/embed\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom embedding model\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed-v1\u0026#34;, \u0026#34;dimensions\u0026#34;: 1024 }Note: Only admin users can create _system definitions.\nInstance Properties# Field Type Required Description instance_handle string Yes Unique identifier within user\u0026rsquo;s namespace owner string Read-only Instance owner\u0026rsquo;s user handle endpoint string Yes* API endpoint URL description string No Instance description api_standard string Yes* Reference to API standard model string Yes* Model name dimensions integer Yes* Vector dimensions api_key_encrypted string Write-only API key (never returned) definition_id integer Read-only Reference to definition template * Required for standalone instances; inherited from definition if using template\nSecurity Features# API Key Encryption# Algorithm: AES-256-GCM Key Source: ENCRYPTION_KEY environment variable Storage: Encrypted in api_key_encrypted column Retrieval: Never returned in API responses API Key Protection# API keys are write-only:\nProvided during instance creation/update Encrypted before storage Never returned in GET/list responses Shared users cannot see API keys Shared Instance Access# When an instance is shared:\nShared users can USE the instance for projects Shared users CANNOT see the API key Shared users CANNOT modify the instance Only owner can manage sharing Common Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Instance must specify either all configuration fields or reference a definition\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create _system definitions\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;LLM service instance \u0026#39;alice/openai-large\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete instance: in use by 3 projects\u0026#34; } Related Documentation# API Standards - Managing API standard definitions Projects - Projects require an LLM service instance LLM Service Refactoring - Complete architecture documentation "},{"id":23,"href":"/dhamps-vdb/reference/roadmap/","title":"Product Roadmap","section":"Reference","content":"Product Roadmap# Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.\nOverview# This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.\nCompleted Features# Core Functionality# User authentication \u0026amp; restrictions on some API calls\nBearer token authentication Role-based access control Admin vs user permissions API versioning\nVersion 1 API with /v1/ prefix Backward compatibility support Better options handling\nCommand-line flags via Huma CLI Environment variable configuration .env file support Handle metadata\nJSONB storage for flexible metadata Metadata attached to embeddings Validation with metadata schema\nJSON Schema validation for embedding metadata Project-level schema definitions Automatic validation on upload Filter similar passages by metadata field\nMetadata-based filtering in similarity queries Exclude documents by metadata value Query parameters: metadata_path and metadata_value Data Management# Use transactions\nAtomic operations for multi-step actions Consistency for project creation with sharing Rollback on errors Catch POST to existing resources\nPrevent duplicate creation Return appropriate error codes Suggest using PUT for updates Always use specific error messages\nDetailed error descriptions Helpful troubleshooting information Consistent error response format Testing \u0026amp; Quality# Tests\nIntegration tests for all major operations Testcontainers for isolated database testing Cleanup verification queries When testing, check cleanup by adding a new query/function to see if all tables are empty\nVerify test isolation Ensure no data leakage between tests Make sure input is validated consistently\nDimension validation for embeddings Schema validation for metadata Request validation via Huma Collaboration Features# Add project sharing/unsharing functions \u0026amp; API paths\nShare projects with specific users Define roles: owner, editor, reader API endpoints for managing sharing Add mechanism to allow anonymous/public reading access to embeddings\npublic_read flag on projects Wildcard sharing via \u0026quot;*\u0026quot; in shared_with Unauthenticated access to public embeddings Transfer of projects from one owner to another as new operation\nOwner-initiated project transfers Ownership verification Automatic cleanup of old owner associations Service Architecture# Add definition creation/listing/deletion functions \u0026amp; paths LLM service definitions (templates) Instances (user-specific configurations) System-provided global definitions Deployment \u0026amp; Operations# Dockerization\nMulti-stage Dockerfile Docker Compose with PostgreSQL External database support Automated setup script Make sure pagination is supported consistently\nLimit and offset parameters Consistent across all list endpoints Documented pagination behavior Security# Prevent acceptance of requests as user \u0026ldquo;_system\u0026rdquo; Reserved system user for internal use Blocked from external authentication Protected system-owned resources In Progress# Documentation# Revisit all documentation\nComprehensive reference documentation Updated API examples Docker deployment guides Add documentation for metadata filtering of similars\nDocument metadata_path and metadata_value parameters Provide usage examples Explain use cases (exclude same author, etc.) Note: Query parameters are: metadata_path and metadata_value as in: https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7\u0026amp;limit=5\u0026amp;metadata_path=author_id\u0026amp;metadata_value=A0083 Planned Features# High Priority# Network Connectivity# Implement and make consequent use of max_idle (5), max_concurr (5), timeouts, and cancellations\nConnection pool management Maximum idle connections: 5 Maximum concurrent connections: 5 Request timeouts Context cancellation support Concurrency (leaky bucket approach) and Rate limiting\nLeaky bucket algorithm for concurrency control Rate limiting using Redis Sliding window implementation Standard rate limit headers See Huma request limits for implementation Caching\nResponse caching for frequently accessed data Cache invalidation strategies Redis or in-memory caching Configurable TTL API Standards# Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio Anthropic embeddings API Mistral embeddings API llama.cpp server API Ollama embeddings API vLLM embeddings API LM Studio embeddings API Standard authentication methods Example definitions in testdata Medium Priority# User Experience# HTML UI\nWeb-based interface for API management User-friendly project creation Visual embedding explorer API key management Alternative to CLI/API usage Allow to request verbose information even in list outputs\nverbose=yes query parameter Full object details in list endpoints Optional vs default minimal output Performance considerations Add possibility to use PATCH method to change existing resources\nPartial updates without full replacement PATCH support for users, projects, instances Merge semantics for nested objects Validation of partial updates Status: Partially implemented via automatic PATCH handler Logging and Monitoring# Proper logging with --verbose and --quiet modes Structured logging (JSON format) Log levels: ERROR, WARN, INFO, DEBUG, TRACE --verbose flag for detailed logs --quiet flag for minimal logs Request/response logging Performance metrics logging Integration with log aggregation systems Future Enhancements# Advanced Features# Bulk Operations\nBatch embedding upload Bulk deletion Transaction support for large operations Advanced Search\nCombined vector + metadata filtering Hybrid search (vector + keyword) Multi-vector search Weighted search results Embeddings Management\nUpdate embeddings in place Re-embedding workflows Embedding versioning Dimension conversion utilities Performance# Query Optimization\nQuery plan analysis Index optimization Materialized views for common queries Database connection pooling improvements Scaling\nHorizontal scaling support Read replicas for query load Partitioning strategies for large datasets Distributed vector search Security \u0026amp; Access Control# Fine-grained Permissions\nCustom roles beyond owner/editor/reader Permission inheritance Temporary access grants IP-based access control Audit Logging\nTrack all API operations User action history Security event logging Compliance reporting OAuth/SAML Integration\nOAuth 2.0 authentication SAML SSO support Identity provider integration External authentication services Integration# Webhooks\nEvent notifications for embeddings changes Project updates notifications Configurable webhook endpoints Retry logic and delivery guarantees Export/Import\nProject export to standard formats Bulk embedding export Import from other vector databases Migration utilities SDK Support\nPython SDK JavaScript/TypeScript SDK Go SDK CLI improvements Development Process# Release Cycle# Minor versions (0.x.0): New features, API additions Patch versions (0.0.x): Bug fixes, documentation updates Major versions (x.0.0): Breaking API changes (future) Feature Requests# To request a feature or suggest improvements:\nCheck existing issues on GitHub Open a new issue with: Clear description of the feature Use cases and motivation Proposed implementation (if any) Engage in discussion with maintainers Contribution Guidelines# Contributions are welcome! See the main repository for:\nDevelopment setup instructions Code style guidelines Testing requirements Pull request process Version History# v0.1.0 (2026-02-08)# Fix many things Add many things Still API v1 on the way to stable v0.0.1 (2024-12-10)# Initial public release API v1 (work in progress) Core functionality implemented Docker support Project sharing Metadata validation Feedback# We value your feedback! Please share:\nFeature requests - What would make dhamps-vdb more useful? Bug reports - Help us improve quality Use cases - How are you using dhamps-vdb? Documentation - What needs clarification? Open an issue on GitHub or contact the maintainers directly.\nRelated Documentation# Getting Started API Documentation Deployment Guide Reference - Configuration Reference - Database Schema GitHub Repository "},{"id":24,"href":"/dhamps-vdb/concepts/projects/","title":"Projects","section":"Concepts","content":"Projects# Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.\nWhat is a Project?# A project is a collection of document embeddings that share:\nA single LLM service instance (embedding configuration) Optional metadata schema for validation Access control (ownership and sharing) Consistent vector dimensions Project Properties# Core Fields# project_handle: Unique identifier within owner\u0026rsquo;s namespace (3-20 characters) owner: User who owns the project description: Human-readable project description instance_id: Reference to LLM service instance (required, 1:1 relationship) metadataScheme: Optional JSON Schema for metadata validation public_read: Boolean flag for public read access created_at: Creation timestamp updated_at: Last modification timestamp Unique Constraints# Projects are uniquely identified by (owner, project_handle):\nUser \u0026ldquo;alice\u0026rdquo; can have project \u0026ldquo;research\u0026rdquo; User \u0026ldquo;bob\u0026rdquo; can also have project \u0026ldquo;research\u0026rdquo; Same user cannot have two projects with same handle Creating Projects# Basic Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;literature-study\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary text analysis\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }Project with Metadata Schema# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;research-papers\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Academic papers with structured metadata\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;doi\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }Public Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;open-dataset\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible research data\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;public_read\u0026#34;: true }Shared Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Team collaboration project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Project-Instance Relationship# One-to-One Constraint# Each project references exactly one LLM service instance:\nProject → Instance (1:1) ├── Defines vector dimensions ├── Specifies embedding model └── Contains API configurationWhy 1:1?\nEnsures consistent dimensions across all embeddings Prevents dimension mismatches in similarity searches Simplifies validation and error handling Specifying Instance# Use owner and handle to reference an instance:\n{ \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }The instance can be:\nOwned by project owner: \u0026quot;instance_owner\u0026quot;: \u0026quot;alice\u0026quot; Shared with project owner: \u0026quot;instance_owner\u0026quot;: \u0026quot;bob\u0026quot; (if bob shared with alice) Metadata Schemas# Purpose# Metadata schemas ensure consistent, structured metadata across all embeddings in a project.\nSchema Format# Use JSON Schema (draft-07 or later):\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1000, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;fiction\u0026#34;, \u0026#34;non-fiction\u0026#34;, \u0026#34;poetry\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;, \u0026#34;title\u0026#34;, \u0026#34;year\u0026#34;] }Validation Behavior# With schema: All embeddings validated on upload Without schema: Any JSON metadata accepted Validation failure: Upload rejected with detailed error Schema updates: Only apply to new/updated embeddings Example Schemas# See Metadata Validation Guide for detailed examples.\nAccess Control# Ownership# Owner: User who created the project Full control: Read, write, delete, share, transfer Cannot be removed: Owner always has access Sharing# Projects can be shared with specific users:\nReader Role\nView embeddings Search for similar documents View project metadata Cannot modify anything Editor Role\nAll reader permissions Add embeddings Modify embeddings Delete embeddings Cannot delete project or change settings Managing Sharing:\n# Share with user POST /v1/projects/alice/my-project/share { \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } # Unshare from user DELETE /v1/projects/alice/my-project/share/bob # List shared users GET /v1/projects/alice/my-project/shared-withPublic Access# Projects can allow unauthenticated read access:\nPATCH /v1/projects/alice/my-project { \u0026#34;public_read\u0026#34;: true }With public_read: true:\nAnyone can view embeddings (no authentication) Anyone can search for similar documents Write operations still require authentication See Public Projects Guide for details.\nProject Operations# List Projects# List all projects owned by a user:\nGET /v1/projects/alice Authorization: Bearer alice_vdb_keyReturns array of project objects.\nGet Project Details# GET /v1/projects/alice/research Authorization: Bearer alice_vdb_keyReturns full project object including:\nConfiguration Instance reference Metadata schema Sharing information (owner only) Update Project# Use PATCH for partial updates:\nPATCH /v1/projects/alice/research { \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }Use PUT for full replacement:\nPUT /v1/projects/alice/research { \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Complete project configuration\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...}\u0026#34; }Delete Project# DELETE /v1/projects/alice/research Authorization: Bearer alice_vdb_keyCascading deletion:\nAll embeddings in project deleted All sharing grants removed Project metadata removed Ownership Transfer# Transfer project to another user:\nPOST /v1/projects/alice/research/transfer-ownership { \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }Effects:\nProject owner changes to bob Project URL changes: /v1/projects/bob/research Alice loses all access (unless re-shared) All embeddings transferred Bob cannot already have project with same handle See Ownership Transfer Guide for details.\nProject Limits# Current Implementation# No enforced limits on:\nNumber of embeddings per project Project storage size Number of shared users Recommended Practices# For large projects:\nUse pagination when listing embeddings Batch upload embeddings Monitor database size Consider archiving old projects Common Patterns# Research Project Workflow# # 1. Create project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;study-2024\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;2024 Research Study\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34; } # 2. Upload data POST /v1/embeddings/alice/study-2024 { ... embeddings ... } # 3. Share with team POST /v1/projects/alice/study-2024/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} # 4. Make public when published PATCH /v1/projects/alice/study-2024 {\u0026#34;public_read\u0026#34;: true}Multi-Project Organization# # Development project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;dev-experiments\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;dev-embeddings\u0026#34; } # Production project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;prod-dataset\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;prod-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...}\u0026#34; } # Archive project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;archive-2023\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;archive-embeddings\u0026#34;, \u0026#34;public_read\u0026#34;: true }Troubleshooting# Cannot Create Project# Possible causes:\nProject handle already exists for this user Invalid project handle format Instance doesn\u0026rsquo;t exist or not accessible Missing required fields Solutions:\nChoose different project handle Verify instance exists: GET /v1/llm-services/owner Check instance is owned or shared with you Include all required fields (instance_owner, instance_handle) Metadata Validation Fails# Possible causes:\nMetadata doesn\u0026rsquo;t match schema Invalid JSON Schema format Schema too restrictive Solutions:\nTest schema with online validator Verify embedding metadata matches schema Update schema or metadata as needed Cannot Share Project# Possible causes:\nNot project owner Target user doesn\u0026rsquo;t exist Invalid role specified Solutions:\nOnly owner can share projects Verify user exists: GET /v1/users/target Use valid role: \u0026ldquo;reader\u0026rdquo; or \u0026ldquo;editor\u0026rdquo; Next Steps# Learn about embeddings Explore metadata validation Understand project sharing "},{"id":25,"href":"/dhamps-vdb/guides/public-projects/","title":"Public Projects Guide","section":"Guides","content":"Public Projects Guide# This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.\nOverview# Projects can be configured to allow unauthenticated (public) read access by setting the public_read field to true. This is useful for:\nOpen datasets and research data Public APIs and services Shared knowledge bases Educational resources Important: Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.\nCreating a Public Project# Set public_read to true when creating a project:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }\u0026#39;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }Making an Existing Project Public# Update an existing project using PATCH:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39;Making a Public Project Private# To disable public access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;Accessing Public Projects Without Authentication# Once a project has public_read enabled, anyone can access it without providing an API key.\nGet Project Metadata# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }Retrieve All Embeddings# curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge?limit=100\u0026#34;Response:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Public document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072 }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Another public document\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;history\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072 } ] }Get a Specific Embedding# curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge/doc001\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Public document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;vector\u0026#34;: [0.021, -0.015, 0.043, ...] }Search for Similar Documents# # Search by existing document ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/public-knowledge/doc001?count=5\u0026amp;threshold=0.7\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;results\u0026#34;: [ {\u0026#34;id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;similarity\u0026#34;: 0.92}, {\u0026#34;id\u0026#34;: \u0026#34;doc003\u0026#34;, \u0026#34;similarity\u0026#34;: 0.85}, {\u0026#34;id\u0026#34;: \u0026#34;doc004\u0026#34;, \u0026#34;similarity\u0026#34;: 0.78} ] }Search with Raw Embeddings# curl -X POST \u0026#34;https://api.example.com/v1/similars/alice/public-knowledge?count=5\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;Operations Still Requiring Authentication# Even for public projects, these operations require authentication:\nCreating Embeddings (Requires Auth)# # This will fail with 401 Unauthorized curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;embeddings\u0026#34;: [...]}\u0026#39; # This succeeds with valid API key curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072 }] }\u0026#39;Deleting Embeddings (Requires Auth)# # Delete specific embedding (requires auth) curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge/doc001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Delete all embeddings (requires auth) curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Modifying Project Settings (Requires Auth)# # Update project description (requires auth) curl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;}\u0026#39;Deleting Project (Requires Auth)# curl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining Public Access with User Sharing# You can combine public read access with user-specific editor permissions:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/collaborative-public\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-public\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Public read, restricted write\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }\u0026#39;In this configuration:\nAnyone can read embeddings and search (no auth required) bob and charlie can add/modify/delete embeddings (with auth) alice (owner) has full control (with auth) Use Cases# Open Research Dataset# Share research data publicly while maintaining write control:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/university/research-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer university_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Open research corpus for academic use\u0026#34;, \u0026#34;instance_id\u0026#34;: 456, \u0026#34;public_read\u0026#34;: true, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;doi\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;doi\\\u0026#34;]}\u0026#34; }\u0026#39;Researchers worldwide can access the data without credentials, but only authorized users can add new data.\nPublic API Backend# Build a public search API on top of dhamps-vdb:\nimport requests def public_search_api(query_vector, count=10): \u0026#34;\u0026#34;\u0026#34;Public search function requiring no authentication\u0026#34;\u0026#34;\u0026#34; response = requests.post( \u0026#34;https://api.example.com/v1/similars/company/product-docs\u0026#34;, json={\u0026#34;vector\u0026#34;: query_vector}, params={\u0026#34;count\u0026#34;: count, \u0026#34;threshold\u0026#34;: 0.6} ) return response.json() # No API key needed for public projects! results = public_search_api(query_embedding)Educational Resources# Share educational content publicly:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/edu/learning-materials\u0026#34; \\ -H \u0026#34;Authorization: Bearer edu_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;learning-materials\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Free educational content embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 789, \u0026#34;public_read\u0026#34;: true }\u0026#39;Students and educators can access the materials without creating accounts.\nCommunity-Driven Knowledge Base# Open knowledge base with restricted editors:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/community/wiki-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer community_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;wiki-embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Community wiki embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 321, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;moderator1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;moderator2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;} ] }\u0026#39;Security Considerations# What is Publicly Visible# When public_read is enabled:\n✅ Project metadata (name, description, owner) ✅ All embedding vectors and text content ✅ All embedding metadata ✅ Vector dimensions and instance references ❌ API keys (never exposed) ❌ User passwords or credentials Best Practices# Review Content First: Ensure no sensitive information is in embeddings or metadata before enabling public access Use Metadata Schemas: Enforce consistent metadata structure with validation Monitor Usage: Track access patterns to your public projects Set Clear Descriptions: Provide clear project descriptions explaining the data\u0026rsquo;s purpose and licensing Consider Rate Limiting: For high-traffic public APIs, implement rate limiting at the application level What to Avoid# ❌ Don\u0026rsquo;t make projects public that contain:\nPersonal identifiable information (PII) Proprietary or confidential data Sensitive research data not yet published Internal company information ✅ Do make projects public that contain:\nAlready-published research data Open educational resources Public domain content Creative Commons licensed materials Disabling Public Access# If you need to make a public project private again:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;After this change:\nAll read operations require authentication Existing anonymous access is immediately revoked No data is deleted, just access is restricted Checking if a Project is Public# View project metadata to check the public_read flag:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34;Look for \u0026quot;public_read\u0026quot;: true in the response.\nRelated Documentation# Project Sharing Guide - Share with specific users RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Enforce data quality Troubleshooting# Public Access Not Working# Symptom: Still getting 401 Unauthorized for public project\nSolutions:\nVerify public_read: true is set: curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; Check you\u0026rsquo;re using GET/POST for similars (not other methods) Ensure the project exists and handle is correct Accidentally Made Project Public# Solution: Immediately disable public access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;Want to Track Public Usage# Solution: Anonymous requests are logged with user set to \u0026ldquo;public\u0026rdquo;. Review server logs to monitor public access patterns.\n"},{"id":26,"href":"/dhamps-vdb/getting-started/quick-start/","title":"Quick Start","section":"Getting Started","content":"Quick Start# Complete walkthrough from installation to searching similar documents using curl.\nPrerequisites# dhamps-vdb installed and running Admin API key configured PostgreSQL with pgvector ready 1. Create a User# Create a new user with the admin API key:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;vdb_key\u0026#34;: \u0026#34;024v2013621509245f2e24...\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; }Save the vdb_key - it cannot be recovered later.\n2. Create an LLM Service Instance# Create an LLM service configuration:\ncurl -X PUT http://localhost:8880/v1/llm-services/alice/my-openai \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }3. Create a Project# Create a project to organize your embeddings:\ncurl -X POST http://localhost:8880/v1/projects/alice \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 1, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:35:00Z\u0026#34; }4. Upload Embeddings# Upload document embeddings to your project:\ncurl -X POST http://localhost:8880/v1/embeddings/alice/research-docs \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Introduction to machine learning\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ..., 0.5], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;ML Intro\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Deep learning fundamentals\u0026#34;, \u0026#34;vector\u0026#34;: [0.15, 0.25, 0.35, ..., 0.55], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;DL Fundamentals\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Bob\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;2 embeddings uploaded successfully\u0026#34; }5. Search for Similar Documents# Option A: Search Using Stored Document# Find documents similar to an already-stored document:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;similarity\u0026#34;: 0.92 }, { \u0026#34;id\u0026#34;: \u0026#34;doc5\u0026#34;, \u0026#34;similarity\u0026#34;: 0.85 } ] }Option B: Search Using Raw Embeddings# Search without storing the query embedding:\ncurl -X POST \u0026#34;http://localhost:8880/v1/similars/alice/research-docs?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.12, 0.22, 0.32, ..., 0.52] }\u0026#39;6. Filter by Metadata# Exclude documents from a specific author when searching:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5\u0026amp;metadata_path=author\u0026amp;metadata_value=Alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;This excludes all documents where metadata.author equals \u0026ldquo;Alice\u0026rdquo;.\n7. Retrieve Embeddings# Get all embeddings in your project:\ncurl -X GET \u0026#34;http://localhost:8880/v1/embeddings/alice/research-docs?limit=10\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Get a specific embedding:\ncurl -X GET http://localhost:8880/v1/embeddings/alice/research-docs/doc1 \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Complete Workflow Example# Here\u0026rsquo;s a complete script to get started:\n#!/bin/bash # Configuration API_URL=\u0026#34;http://localhost:8880\u0026#34; ADMIN_KEY=\u0026#34;your-admin-key\u0026#34; # 1. Create user USER_RESPONSE=$(curl -s -X POST \u0026#34;$API_URL/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer $ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;,\u0026#34;name\u0026#34;:\u0026#34;Alice Smith\u0026#34;,\u0026#34;email\u0026#34;:\u0026#34;alice@example.com\u0026#34;}\u0026#39;) USER_KEY=$(echo $USER_RESPONSE | jq -r \u0026#39;.vdb_key\u0026#39;) echo \u0026#34;User created with key: $USER_KEY\u0026#34; # 2. Create LLM service instance curl -X PUT \u0026#34;$API_URL/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-your-key\u0026#34; }\u0026#39; # 3. Create project curl -X POST \u0026#34;$API_URL/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research documents\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39; # 4. Upload embeddings curl -X POST \u0026#34;$API_URL/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @embeddings.json # 5. Search similar curl -X GET \u0026#34;$API_URL/v1/similars/alice/research-docs/doc1?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; echo \u0026#34;Setup complete!\u0026#34;API Documentation# For complete API documentation, visit:\ncurl http://localhost:8880/docsOr open http://localhost:8880/docs in your browser.\nNext Steps# Learn about projects Understand embeddings Explore sharing projects Set up metadata validation "},{"id":27,"href":"/dhamps-vdb/api/","title":"API Reference","section":"dhamps-vdb Documentation","content":"API Reference# Complete reference for the dhamps-vdb REST API.\nAPI Version# Current version: v1\nAll endpoints are prefixed with /v1/ (e.g., POST /v1/embeddings/{user}/{project}).\nAPI Documentation# The complete, always up-to-date API specification is available at:\nOpenAPI YAML: /openapi.yaml Interactive Documentation: /docs Reference Sections# Authentication - API key authentication Endpoints - All available API endpoints Query Parameters - Filtering and pagination PATCH Updates - Partial resource updates Error Handling - Error responses and codes Quick Example# # Authenticate with API key curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer your_api_key_here\u0026#34;All API requests require authentication except for public project read operations.\n"},{"id":28,"href":"/dhamps-vdb/api/endpoints/api-standards/","title":"API Standards","section":"Endpoints","content":"API Standards Endpoint# Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.\nOverview# API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:\nOpenAI: Bearer token in Authorization header Cohere: API key in Authorization header with Bearer prefix Google Gemini: API key as query parameter Ollama: No authentication required Pre-seeded standards are available for common providers. See testdata/valid_api_standard_*.json for examples.\nEndpoints# List All API Standards# Get all defined API standards. This endpoint is publicly accessible (no authentication required).\nEndpoint: GET /v1/api-standards\nAuthentication: Public (no authentication required)\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/api-standards\u0026#34;Response:\n{ \u0026#34;standards\u0026#34;: [ { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }, { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }, { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; } ] } Get API Standard# Retrieve information about a specific API standard. This endpoint is publicly accessible.\nEndpoint: GET /v1/api-standards/{standardname}\nAuthentication: Public (no authentication required)\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34;Response:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; } Create API Standard# Register a new API standard definition. Admin-only operation.\nEndpoint: POST /v1/api-standards\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom-provider\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom provider embedding API\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }Parameters:\napi_standard_handle (string, required): Unique identifier for the standard description (string, required): Description including API documentation URL key_method (string, required): Authentication method auth_bearer: Bearer token in header auth_apikey: API key in header query_param: API key as query parameter none: No authentication key_field (string, required): Field name for the API key For headers: typically \u0026quot;Authorization\u0026quot; or \u0026quot;X-API-Key\u0026quot; For query params: parameter name like \u0026quot;key\u0026quot; or \u0026quot;api_key\u0026quot; Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/api-standards\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;ollama\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Ollama local embedding API, no authentication required\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; }\u0026#39;Response:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;ollama\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Ollama local embedding API, no authentication required\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; } Update API Standard (PUT)# Create or update an API standard with a specific handle. Admin-only operation.\nEndpoint: PUT /v1/api-standards/{standardname}\nAuthentication: Admin only\nRequest Body: Same as POST endpoint\nExample:\ncurl -X PUT \u0026#34;https://api.example.com/v1/api-standards/custom-provider\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom-provider\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description for custom provider\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }\u0026#39; Delete API Standard# Delete an API standard definition. Admin-only operation.\nEndpoint: DELETE /v1/api-standards/{standardname}\nAuthentication: Admin only\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/api-standards/custom-provider\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;API standard \u0026#39;custom-provider\u0026#39; deleted successfully\u0026#34; }⚠️ Warning: Cannot delete API standards that are referenced by LLM service instances.\nPartial Update (PATCH)# Update specific API standard fields without providing all data. Admin-only operation.\nEndpoint: PATCH /v1/api-standards/{standardname}\nAuthentication: Admin only\nExample - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API v1 - Updated documentation link\u0026#34; }\u0026#39;See PATCH Updates for more details.\nAPI Standard Properties# Field Type Required Description api_standard_handle string Yes Unique identifier (e.g., \u0026ldquo;openai\u0026rdquo;, \u0026ldquo;cohere\u0026rdquo;) description string Yes Description with API documentation URL key_method string Yes Authentication method key_field string Yes Field name for API key/token Authentication Methods# auth_bearer# Bearer token authentication in the Authorization header.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }HTTP Request:\nAuthorization: Bearer sk-proj-abc123...Used by: OpenAI, Cohere, Anthropic\nauth_apikey# API key in a custom header field.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;auth_apikey\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;X-API-Key\u0026#34; }HTTP Request:\nX-API-Key: abc123...Used by: Some custom API providers\nquery_param# API key passed as a URL query parameter.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; }HTTP Request:\nGET https://api.example.com/embed?key=abc123...Used by: Google Gemini, some older APIs\nnone# No authentication required.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; }Used by: Ollama (local), self-hosted models without auth\nPre-seeded API Standards# The following API standards are created during database migration:\nopenai# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }cohere# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }gemini# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; } Use Cases# Creating a Custom API Standard# For self-hosted or custom LLM services:\ncurl -X POST \u0026#34;https://api.example.com/v1/api-standards\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;vllm-local\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;vLLM local deployment with custom auth\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_apikey\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;X-API-Key\u0026#34; }\u0026#39;Referencing in LLM Service Instance# Once created, reference the API standard in your LLM service instance:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-vllm\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-vllm\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://vllm.local/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;vllm-local\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed\u0026#34;, \u0026#34;dimensions\u0026#34;: 768, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;my-secret-key\u0026#34; }\u0026#39; Common Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid key_method: must be one of auth_bearer, auth_apikey, query_param, none\u0026#34; }401 Unauthorized (Admin Operations)# { \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden (Admin Operations)# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create/modify/delete API standards\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;API standard \u0026#39;custom-provider\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete API standard: referenced by 5 LLM service instances\u0026#34; } Related Documentation# LLM Services - LLM service instances reference API standards Authentication - User authentication methods Testdata Examples - Example API standard definitions "},{"id":29,"href":"/dhamps-vdb/concepts/embeddings/","title":"Embeddings","section":"Concepts","content":"Embeddings# Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.\nWhat are Embeddings?# Embeddings are numerical representations (vectors) of text that capture semantic meaning:\nVector: Array of floating-point numbers (e.g., 1536 or 3072 dimensions) Dimensions: Fixed length determined by LLM model Similarity: Vectors of similar text are close in vector space Purpose: Enable semantic search and retrieval Embedding Structure# Required Fields# text_id: Unique identifier for the document (max 300 characters) instance_handle: LLM service instance that generated the embedding vector: Array of float32 values (embedding vector) vector_dim: Declared dimension count (must match vector length) Optional Fields# text: Original text content (for reference) metadata: Structured JSON data about the document Example# { \u0026#34;text_id\u0026#34;: \u0026#34;doc-123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Introduction to machine learning concepts\u0026#34;, \u0026#34;vector\u0026#34;: [0.023, -0.015, 0.087, ..., 0.042], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;ML Introduction\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;category\u0026#34;: \u0026#34;tutorial\u0026#34; } }Creating Embeddings# Single Embedding# POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ..., 0.3], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;} } ] }Batch Upload# POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072 }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072 }, ... ] }Batch upload tips:\nUpload 100-1000 embeddings per request Use consistent instance_handle Ensure all vectors have same dimensions Include metadata for searchability Text Identifiers# Format# Text IDs can be any string up to 300 characters:\nCommon patterns:\nURLs: https://id.example.com/doc/123 URNs: urn:example:doc:123 Paths: /corpus/section1/doc123 IDs: doc-abc-123-xyz URL Encoding# URL-encode text IDs when using them in API paths:\n# Original ID text_id=\u0026#34;https://id.example.com/texts/W0017:1.3.1\u0026#34; # URL-encoded for API encoded=\u0026#34;https%3A%2F%2Fid.example.com%2Ftexts%2FW0017%3A1.3.1\u0026#34; # Use in API call GET /v1/embeddings/alice/project/$encodedUniqueness# Text IDs must be unique within a project:\nSame ID in different projects: ✅ Allowed Same ID twice in one project: ❌ Conflict error Validation# Dimension Validation# The system automatically validates vector dimensions:\nChecks performed:\nvector_dim matches declared instance dimensions Actual vector array length matches vector_dim All embeddings in project have consistent dimensions Example error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;my-openai\u0026#39; expects 1536 dimensions\u0026#34; }Metadata Validation# If project has a metadata schema, all embeddings are validated:\nExample error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc1\u0026#39;: metadata validation failed:\\n - author is required\\n - year must be integer\u0026#34; }See Metadata Validation Guide for details.\nRetrieving Embeddings# List All Embeddings# GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=0Returns paginated list of embeddings with:\ntext_id metadata vector_dim created_at Vectors are included by default (can be large).\nGet Single Embedding# GET /v1/embeddings/alice/research-docs/doc1Returns complete embedding including vector.\nPagination# Use limit and offset for large projects:\n# First page (0-99) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=0 # Second page (100-199) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=100 # Third page (200-299) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=200Updating Embeddings# Currently, embeddings cannot be updated directly. To modify:\nDelete existing embedding Upload new version with same text_id # Delete old version DELETE /v1/embeddings/alice/research-docs/doc1 # Upload new version POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...new vector...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {...updated metadata...} }] }Deleting Embeddings# Delete Single Embedding# DELETE /v1/embeddings/alice/research-docs/doc1Delete All Embeddings# DELETE /v1/embeddings/alice/research-docsWarning: This deletes all embeddings in the project permanently.\nMetadata# Purpose# Metadata provides structured information about documents:\nFiltering: Exclude documents in similarity searches Organization: Categorize and group documents Context: Store additional document information Validation: Ensure consistent structure (with schema) Structure# Metadata is stored as JSONB in PostgreSQL:\n{ \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;act\u0026#34;: 1, \u0026#34;scene\u0026#34;: 1, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; }Nested Metadata# Complex structures are supported:\n{ \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;birth_year\u0026#34;: 1564, \u0026#34;nationality\u0026#34;: \u0026#34;English\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 1603, \u0026#34;publisher\u0026#34;: \u0026#34;First Folio\u0026#34;, \u0026#34;edition\u0026#34;: 1 }, \u0026#34;tags\u0026#34;: [\u0026#34;tragedy\u0026#34;, \u0026#34;revenge\u0026#34;, \u0026#34;madness\u0026#34;] }Filtering by Metadata# Use metadata to exclude documents from similarity searches:\n# Exclude documents from same author GET /v1/similars/alice/project/doc1?metadata_path=author\u0026amp;metadata_value=ShakespeareSee Metadata Filtering Guide for details.\nStorage Considerations# Vector Storage# Vectors are stored using pgvector extension:\nType: vector(N) where N is dimension count Size: 4 bytes per dimension + overhead Example: 3072-dimension vector ≈ 12KB Storage Calculation# Estimate storage per embedding:\nVector: 4 bytes × dimensions Text ID: length in bytes (avg ~50 bytes) Text: length in bytes (optional) Metadata: JSON size (varies, avg ~500 bytes) Overhead: ~100 bytes (indexes, etc.) Example (3072-dim with metadata): 4 × 3072 + 50 + 500 + 100 ≈ 13KB per embeddingLarge Projects# For projects with millions of embeddings:\nUse pagination when listing Consider partial indexes for metadata Monitor database size Plan backup strategy Performance# Upload Performance# Small batches (1-10): ~100ms per request Medium batches (100-500): ~500ms-2s per request Large batches (1000+): ~2-10s per request Retrieval Performance# Single embedding: \u0026lt;10ms Paginated list (100 items): ~50ms Large project scan: Use pagination Optimization Tips# Batch uploads when possible Use appropriate page sizes Include only needed fields Monitor query performance Common Patterns# Document Chunking# Split long documents into chunks:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:chunk1\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;First part of document...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;chunk\u0026#34;: 1} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:chunk2\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Second part of document...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;chunk\u0026#34;: 2} } ] }Versioned Documents# Track document versions:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1:v2\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: { \u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;version\u0026#34;: 2, \u0026#34;updated_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } }Multi-Language Documents# Store embeddings for different languages:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:en\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;English version...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;en\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:de\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Deutsche Version...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;de\u0026#34;} } ] }Troubleshooting# Dimension Mismatch# Error: \u0026ldquo;vector dimension mismatch\u0026rdquo;\nCause: Vector dimensions don\u0026rsquo;t match instance configuration\nSolution:\nCheck instance dimensions: GET /v1/llm-services/owner/instance Regenerate embeddings with correct model Ensure vector_dim matches actual vector length Metadata Validation Failed# Error: \u0026ldquo;metadata validation failed\u0026rdquo;\nCause: Metadata doesn\u0026rsquo;t match project schema\nSolution:\nCheck project schema: GET /v1/projects/owner/project Update metadata to match schema Or update schema to accept metadata Text ID Conflict# Error: \u0026ldquo;embedding with text_id already exists\u0026rdquo;\nCause: Attempting to upload duplicate text_id\nSolution:\nUse different text_id Delete existing embedding first Check for unintended duplicates Next Steps# Learn about similarity search Explore metadata filtering Understand LLM services "},{"id":30,"href":"/dhamps-vdb/getting-started/first-project/","title":"First Project","section":"Getting Started","content":"First Project# Step-by-step guide to creating your first complete project in dhamps-vdb.\nOverview# This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:\nSet up authentication Configure an LLM service Create a project with metadata validation Upload document embeddings Search for similar documents Share your project with collaborators Step 1: Authentication Setup# Get Your API Key# If you\u0026rsquo;re an admin, create your first user:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34; }\u0026#39;Save the returned vdb_key to a variable:\nexport USER_KEY=\u0026#34;your-returned-vdb-key\u0026#34;Verify Authentication# Test your API key:\ncurl -X GET http://localhost:8880/v1/users/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 2: Configure LLM Service# Option A: Use System Definition# List available system definitions:\ncurl -X GET http://localhost:8880/v1/llm-services/_system \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Create an instance from a system definition:\ncurl -X PUT http://localhost:8880/v1/llm-services/researcher1/my-embeddings \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My OpenAI embeddings instance\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key\u0026#34; }\u0026#39;Option B: Create Custom Instance# Create a standalone instance with custom configuration:\ncurl -X PUT http://localhost:8880/v1/llm-services/researcher1/custom-embeddings \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-small\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536, \u0026#34;description\u0026#34;: \u0026#34;Custom OpenAI small embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-api-key\u0026#34; }\u0026#39;Step 3: Create Project with Metadata Schema# Define a metadata schema to ensure consistent document metadata:\ncurl -X POST http://localhost:8880/v1/projects/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literature-analysis\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary texts for research analysis\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;genre\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;,\\\u0026#34;enum\\\u0026#34;:[\\\u0026#34;poetry\\\u0026#34;,\\\u0026#34;prose\\\u0026#34;,\\\u0026#34;drama\\\u0026#34;]},\\\u0026#34;language\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;title\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }\u0026#39;This schema requires author, title, and year fields, with optional genre and language fields.\nStep 4: Upload Document Embeddings# Prepare Your Data# Create a file embeddings.json with your document embeddings:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;hamlet-act1-scene1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Who\u0026#39;s there? Nay, answer me: stand, and unfold yourself.\u0026#34;, \u0026#34;vector\u0026#34;: [0.023, -0.015, 0.087, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; } }, { \u0026#34;text_id\u0026#34;: \u0026#34;paradise-lost-book1-line1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Of Man\u0026#39;s first disobedience, and the fruit...\u0026#34;, \u0026#34;vector\u0026#34;: [0.045, -0.032, 0.091, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Milton\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Paradise Lost\u0026#34;, \u0026#34;year\u0026#34;: 1667, \u0026#34;genre\u0026#34;: \u0026#34;poetry\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; } } ] }Upload Embeddings# curl -X POST http://localhost:8880/v1/embeddings/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @embeddings.jsonVerify Upload# List all embeddings:\ncurl -X GET \u0026#34;http://localhost:8880/v1/embeddings/researcher1/literature-analysis?limit=10\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Get a specific embedding:\ncurl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 5: Search Similar Documents# Basic Similarity Search# Find passages similar to Hamlet Act 1:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;literature-analysis\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;hamlet-act2-scene1\u0026#34;, \u0026#34;similarity\u0026#34;: 0.89 }, { \u0026#34;id\u0026#34;: \u0026#34;macbeth-act1-scene3\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 }, { \u0026#34;id\u0026#34;: \u0026#34;othello-act3-scene3\u0026#34;, \u0026#34;similarity\u0026#34;: 0.76 } ] }Search with Metadata Filtering# Exclude passages from the same work:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5\u0026amp;metadata_path=title\u0026amp;metadata_value=Hamlet\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;This excludes all documents where metadata.title equals \u0026ldquo;Hamlet\u0026rdquo;.\nSearch with Raw Embeddings# Search using a new embedding without storing it:\ncurl -X POST \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.034, -0.021, 0.092, ...] }\u0026#39;Step 6: Share Your Project# Share with Collaborators# Grant read-only access to another user:\ncurl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Grant edit access:\ncurl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }\u0026#39;Make Project Public# Enable public read access (no authentication required):\ncurl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Now anyone can read embeddings and search without authentication:\n# No Authorization header needed curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1View Shared Users# List all users with access to your project:\ncurl -X GET http://localhost:8880/v1/projects/researcher1/literature-analysis/shared-with \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 7: Manage Your Project# Update Project Description# curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated: Shakespearean and Renaissance literature analysis\u0026#34; }\u0026#39;Update Metadata Schema# curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;genre\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;language\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;act\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;scene\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;title\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }\u0026#39;Delete Specific Embeddings# curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Delete All Embeddings# curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Common Patterns# Batch Upload Script# #!/bin/bash USER_KEY=\u0026#34;your-vdb-key\u0026#34; PROJECT=\u0026#34;researcher1/literature-analysis\u0026#34; API_URL=\u0026#34;http://localhost:8880\u0026#34; # Process multiple files for file in data/*.json; do echo \u0026#34;Uploading $file...\u0026#34; curl -X POST \u0026#34;$API_URL/v1/embeddings/$PROJECT\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @\u0026#34;$file\u0026#34; doneSearch and Filter Workflow# # 1. Find similar documents SIMILAR=$(curl -s -X GET \u0026#34;$API_URL/v1/similars/$PROJECT/doc1?count=20\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;) # 2. Extract IDs IDS=$(echo $SIMILAR | jq -r \u0026#39;.results[].id\u0026#39;) # 3. Retrieve full embeddings for similar documents for id in $IDS; do curl -X GET \u0026#34;$API_URL/v1/embeddings/$PROJECT/$id\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; doneTroubleshooting# Validation Errors# If metadata validation fails:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc1\u0026#39;: year is required\u0026#34; }Check your metadata schema and ensure all required fields are present.\nDimension Mismatches# If vector dimensions don\u0026rsquo;t match:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: expected 3072 dimensions, got 1536\u0026#34; }Verify your LLM service configuration and embedding dimensions.\nAuthentication Errors# If you get 401 Unauthorized:\nCheck your API key is correct Ensure Authorization: Bearer prefix is included Verify the user owns the resource or has been granted access Next Steps# Learn about metadata validation Explore batch operations Understand similarity search Review API documentation "},{"id":31,"href":"/dhamps-vdb/guides/ownership-transfer/","title":"Ownership Transfer Guide","section":"Guides","content":"Ownership Transfer Guide# This guide explains how to transfer project ownership between users in dhamps-vdb.\nOverview# Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:\nA project maintainer is leaving and wants to hand over control Organizational changes require reassigning project ownership Consolidating projects under a different user account Transferring stewardship of research data to a new PI Important Constraints# Before transferring ownership, understand these constraints:\nOnly the current owner can transfer - Editors and readers cannot initiate transfers New owner must exist - The target user must already be registered in the system No handle conflicts - The new owner cannot already have a project with the same handle Old owner loses access - After transfer, the original owner has no access to the project Data remains intact - All embeddings and metadata are preserved during transfer Shared users remain - Existing sharing relationships are maintained Transferring Ownership# Basic Transfer# Transfer a project to another user:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project ownership transferred successfully\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-data\u0026#34;, \u0026#34;old_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;new_owner\u0026#34;: \u0026#34;bob\u0026#34; }After this operation:\nThe project is now accessible at /v1/projects/bob/research-data Bob has full owner privileges Alice no longer has any access to the project All embeddings remain unchanged Complete Transfer Example# Here\u0026rsquo;s a complete workflow showing before and after transfer:\n# Before transfer - Alice is the owner curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Response { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research project\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 } # Alice transfers to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # After transfer - Bob is now the owner curl -X GET \u0026#34;https://api.example.com/v1/projects/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Response { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research project\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 } # Alice can no longer access it curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Returns: 404 Not FoundEffects of Transfer# Project Access Path Changes# The project URL changes to reflect the new owner:\nBefore:\n/v1/projects/alice/research-data /v1/embeddings/alice/research-data /v1/similars/alice/research-data/doc123After:\n/v1/projects/bob/research-data /v1/embeddings/bob/research-data /v1/similars/bob/research-data/doc123Important: Update all client code and bookmarks to use the new owner\u0026rsquo;s handle.\nNew Owner Gains Full Control# Bob (new owner) can now:\nView and modify all embeddings Update project settings (description, instance, metadata schema) Manage sharing (add/remove shared users) Transfer ownership again to someone else Delete the project Old Owner Loses All Access# Alice (old owner) can no longer:\nAccess the project in any way View or modify embeddings See project metadata Manage sharing Transfer ownership back Note: If Alice needs continued access, Bob should share the project with her after the transfer.\nShared Users Remain# If the project was shared with other users, those sharing relationships are preserved:\n# Before transfer - Alice shares with Charlie (editor) curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Transfer to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # After transfer - Charlie still has editor access curl -X GET \u0026#34;https://api.example.com/v1/projects/bob/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; # Works! Charlie can still access as editorUpgrading Shared User to Owner# If the new owner was previously a shared user, their role is automatically upgraded:\n# Alice shares project with Bob (editor) curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Alice transfers ownership to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # Bob\u0026#39;s previous \u0026#34;editor\u0026#34; sharing role is removed # Bob now has full owner privileges insteadUse Cases# PI Leaving Institution# A principal investigator leaving an institution transfers project ownership to a colleague:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/prof_jones/lab_data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer prof_jones_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;prof_smith\u0026#34;}\u0026#39;Account Consolidation# Consolidate multiple projects under a single organizational account:\n# Transfer Alice\u0026#39;s personal projects to organization account curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/project1/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;org_datascience\u0026#34;}\u0026#39; curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/project2/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;org_datascience\u0026#34;}\u0026#39;Graduated Student Handoff# A graduating student transfers their research project to their advisor:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/student_bob/thesis_embeddings/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer student_bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;advisor_carol\u0026#34;}\u0026#39; # Advisor can then share it back with the student if needed curl -X POST \u0026#34;https://api.example.com/v1/projects/advisor_carol/thesis_embeddings/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer advisor_carol_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;student_bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}\u0026#39;Department Reorganization# Projects move to a new department owner:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/old_dept/resource_library/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer old_dept_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;new_dept\u0026#34;}\u0026#39;Error Conditions# New Owner Doesn\u0026rsquo;t Exist# curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;nonexistent_user\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;nonexistent_user\u0026#39; does not exist\u0026#34; }Solution: Ensure the target user is registered first. Contact admin to create the user.\nHandle Conflict# # Bob already has a project called \u0026#34;research-data\u0026#34; curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;bob\u0026#39; already has a project with handle \u0026#39;research-data\u0026#39;\u0026#34; }Solution: Either:\nRename Alice\u0026rsquo;s project before transferring: curl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;project_handle\u0026#34;: \u0026#34;research-data-alice\u0026#34;}\u0026#39; Ask Bob to rename or delete their existing project Choose a different target user Not the Owner# # Charlie tries to transfer Alice\u0026#39;s project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only the project owner can transfer ownership\u0026#34; }Solution: Only the current owner (Alice) can initiate the transfer.\nBest Practices# Before Transferring# Communicate with New Owner: Ensure they\u0026rsquo;re willing to accept ownership Document Current State: Export or document current embeddings and metadata Review Shared Users: Check who has access and whether sharing should continue Update Client Code: Identify all systems accessing the project that need updating Backup Data: Consider exporting important data before transfer During Transfer# Transfer at Low-Activity Time: Minimize disruption by transferring during quiet periods Test Access First: Verify new owner can access their other projects Use Correct Handle: Double-check the new owner\u0026rsquo;s handle before submitting After Transferring# Verify New Ownership: Confirm the transfer succeeded Update Client Applications: Change all API calls to use new owner handle Grant Back Access if Needed: New owner can share project back to old owner Update Documentation: Update any documentation referencing the project path Notify Shared Users: Inform shared users about the path change Maintaining Access After Transfer# If the original owner needs continued access, the new owner should share the project:\n# Step 1: Alice transfers to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # Step 2: Bob shares back with Alice as editor curl -X POST \u0026#34;https://api.example.com/v1/projects/bob/research-data/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Now Alice can still access (but as editor, not owner) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/bob/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Checking Current Owner# To verify current project ownership:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/{owner}/{project}\u0026#34; \\ -H \u0026#34;Authorization: Bearer your_api_key\u0026#34;The owner field in the response shows the current owner.\nRelated Documentation# Project Sharing Guide - Share projects with specific users Public Projects Guide - Make projects publicly accessible Troubleshooting# Cannot Find Project After Transfer# Problem: Getting 404 after transfer\nSolution: Update the owner in your API calls:\nOld: /v1/projects/alice/my-project New: /v1/projects/bob/my-project Need to Reverse Transfer# Problem: Transferred by mistake, need to reverse\nSolution: New owner must transfer back:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/bob/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;alice\u0026#34;}\u0026#39;Client Applications Failing# Problem: Applications can\u0026rsquo;t access project after transfer\nSolution: Update all hardcoded owner references in your code to use the new owner\u0026rsquo;s handle.\n"},{"id":32,"href":"/dhamps-vdb/development/performance/","title":"Performance","section":"Development","content":"Performance Optimization Guide# This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.\nQuery Optimization# GetAllAccessibleInstances Query# Problem: The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.\nCurrent Implementation:\nSELECT instances.*, COALESCE(instances_shared_with.role, \u0026#39;owner\u0026#39;) as role, (instances.owner = $1) as is_owner FROM instances LEFT JOIN instances_shared_with ON instances.instance_id = instances_shared_with.instance_id WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1 ORDER BY instances.owner ASC, instances.instance_handle ASC LIMIT $2 OFFSET $3;Issue: The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.\nRecommended: UNION ALL Pattern# Use UNION ALL to separate owned instances from shared instances:\n-- Get owned instances SELECT instances.*, \u0026#39;owner\u0026#39; as role, true as is_owner FROM instances WHERE instances.owner = $1 UNION ALL -- Get shared instances SELECT instances.*, instances_shared_with.role, false as is_owner FROM instances INNER JOIN instances_shared_with ON instances.instance_id = instances_shared_with.instance_id WHERE instances_shared_with.user_handle = $1 AND instances.owner != $1 -- Avoid duplicates ORDER BY owner ASC, instance_handle ASC LIMIT $2 OFFSET $3;Benefits:\nSeparate index scans: Query planner can use different indexes for each UNION branch Owned instances: Can use index on (owner) Shared instances: Can use index on (user_handle) Clearer execution plan: Easier to understand and optimize Better performance: Especially noticeable with large datasets Trade-offs:\nSlightly more complex SQL Need to deduplicate if user somehow has instance both owned and shared (unlikely scenario) Both queries must have same column structure Implementation Example# Before (queries.sql):\n-- name: GetAllAccessibleInstances :many SELECT instances.*, ... FROM instances LEFT JOIN instances_shared_with ON ... WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1After (queries.sql):\n-- name: GetAllAccessibleInstances :many SELECT instances.*, \u0026#39;owner\u0026#39; as role, true as is_owner FROM instances WHERE instances.owner = $1 UNION ALL SELECT instances.*, isw.role, false as is_owner FROM instances INNER JOIN instances_shared_with isw ON instances.instance_id = isw.instance_id WHERE isw.user_handle = $1 AND instances.owner != $1 ORDER BY owner, instance_handle LIMIT $2 OFFSET $3;When to optimize:\nCurrent implementation is correct and works well for small-medium datasets Consider optimization if performance becomes an issue with: Large numbers of instances (\u0026gt;1000) Many shared relationships (\u0026gt;100 shares per user) Query time consistently \u0026gt;100ms Always profile first:\nEXPLAIN ANALYZE SELECT instances.*, ... FROM instances LEFT JOIN instances_shared_with ON ... WHERE instances.owner = \u0026#39;alice\u0026#39; OR instances_shared_with.user_handle = \u0026#39;alice\u0026#39;;Index Optimization# Current Indexes# From migration 004_refactor_llm_services_architecture.sql:\n-- API Standards / Definitions CREATE INDEX idx_definitions_handle ON definitions(definition_handle); CREATE INDEX idx_definitions_owner_handle ON definitions(owner, definition_handle); -- Instances CREATE INDEX idx_instances_handle ON instances(instance_handle); -- Sharing (implicit from PRIMARY KEY) -- instances_shared_with(instance_id, user_handle)Recommended Additional Indexes# 1. Owner Lookups# -- For queries: WHERE instances.owner = ? CREATE INDEX idx_instances_owner ON instances(owner);Benefit: Fast retrieval of user\u0026rsquo;s owned instances\nUse case:\nSELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39;;2. Shared Instance Lookups# -- For queries: WHERE user_handle = ? CREATE INDEX idx_instances_shared_user ON instances_shared_with(user_handle);Benefit: Fast retrieval of instances shared with user\nUse case:\nSELECT i.* FROM instances i INNER JOIN instances_shared_with isw ON i.instance_id = isw.instance_id WHERE isw.user_handle = \u0026#39;bob\u0026#39;;3. Composite Owner+Handle Index# -- For unique constraint and lookups CREATE UNIQUE INDEX idx_instances_owner_handle ON instances(owner, instance_handle);Benefit: Enforces uniqueness and enables index-only scans\nUse case:\nSELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39; AND instance_handle = \u0026#39;my-service\u0026#39;;4. Embedding Dimension Filtering# -- Critical for similarity search performance CREATE INDEX idx_embeddings_project_dim ON embeddings(project_id, vector_dim);Benefit: Filters embeddings by dimension before vector comparison\nUse case:\nSELECT * FROM embeddings WHERE project_id = 123 AND vector_dim = 1536 ORDER BY vector \u0026lt;=\u0026gt; $1::vector LIMIT 10;5. Project Ownership# CREATE INDEX idx_projects_owner ON projects(owner); CREATE UNIQUE INDEX idx_projects_owner_handle ON projects(owner, project_handle);Index Analysis# Check if indexes are being used:\n-- Analyze query plan EXPLAIN ANALYZE SELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39;; -- Check index usage statistics SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch FROM pg_stat_user_indexes WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY idx_scan DESC; -- Find unused indexes SELECT schemaname, tablename, indexname FROM pg_stat_user_indexes WHERE idx_scan = 0 AND schemaname = \u0026#39;public\u0026#39;;Index Maintenance# -- Update statistics for query planner ANALYZE instances; ANALYZE instances_shared_with; ANALYZE embeddings; -- Rebuild index if fragmented REINDEX INDEX idx_instances_owner; -- Check index size SELECT indexname, pg_size_pretty(pg_relation_size(indexrelid)) AS size FROM pg_stat_user_indexes WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY pg_relation_size(indexrelid) DESC;Vector Index Optimization# HNSW vs IVFFlat# Current implementation uses HNSW:\nCREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);HNSW (Hierarchical Navigable Small World)# Pros:\nBetter recall (finds more similar results) Better query performance No training required Cons:\nSlower index build time Higher memory usage Larger index size Configuration options:\n-- Default: m=16, ef_construction=64 CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops) WITH (m = 16, ef_construction = 64); -- Higher quality (slower build): m=32, ef_construction=128 CREATE INDEX embedding_vector_idx_hq ON embeddings USING hnsw (vector vector_cosine_ops) WITH (m = 32, ef_construction = 128);Parameters:\nm: Number of connections per layer (default 16, range 2-100) ef_construction: Size of candidate list during build (default 64, range 4-1000) Higher values = better recall but slower build and more memory IVFFlat (Inverted File with Flat compression)# Alternative for very large datasets:\nCREATE INDEX embedding_vector_idx_ivf ON embeddings USING ivfflat (vector vector_cosine_ops) WITH (lists = 100);Pros:\nFaster index build Lower memory usage Smaller index size Cons:\nRequires training (ANALYZE before creating index) Lower recall than HNSW Need to tune lists parameter When to use:\nDataset \u0026gt;1M embeddings Build time is critical Memory constrained environment Configuration:\n-- Rule of thumb: lists = sqrt(total_rows) -- For 100K embeddings: lists = 316 -- For 1M embeddings: lists = 1000 -- Train the index ANALYZE embeddings; -- Create with appropriate lists CREATE INDEX embedding_vector_idx_ivf ON embeddings USING ivfflat (vector vector_cosine_ops) WITH (lists = 1000); -- Set probes at query time SET ivfflat.probes = 10; -- Default is 1, higher = better recallQuery-Time Optimization# For HNSW, set hnsw.ef_search:\n-- Default: ef_search = 40 -- Higher = better recall but slower queries SET hnsw.ef_search = 100; SELECT vector \u0026lt;=\u0026gt; $1::vector AS distance FROM embeddings WHERE project_id = 123 ORDER BY distance LIMIT 10;Dimension-Specific Indexes# For multi-dimensional projects:\n-- Separate indexes per common dimension CREATE INDEX idx_embeddings_768_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 768; CREATE INDEX idx_embeddings_1536_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 1536; CREATE INDEX idx_embeddings_3072_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 3072;Benefit: Smaller indexes = faster queries for specific dimensions\nCaching Strategies# 1. System Definitions Cache# System definitions rarely change:\nvar ( systemDefsCache []models.Definition systemDefsCacheMu sync.RWMutex systemDefsCacheTTL = 5 * time.Minute systemDefsCacheExp time.Time ) func GetSystemDefinitions(ctx context.Context, pool *pgxpool.Pool) ([]models.Definition, error) { systemDefsCacheMu.RLock() if time.Now().Before(systemDefsCacheExp) \u0026amp;\u0026amp; systemDefsCache != nil { defer systemDefsCacheMu.RUnlock() return systemDefsCache, nil } systemDefsCacheMu.RUnlock() // Fetch from database defs, err := db.GetDefinitionsByOwner(ctx, \u0026#34;_system\u0026#34;) if err != nil { return nil, err } // Update cache systemDefsCacheMu.Lock() systemDefsCache = defs systemDefsCacheExp = time.Now().Add(systemDefsCacheTTL) systemDefsCacheMu.Unlock() return defs, nil }2. User Instances Cache# Cache user\u0026rsquo;s instance list with short TTL:\ntype InstanceCache struct { data map[string][]models.Instance mu sync.RWMutex ttl time.Duration exp map[string]time.Time } func (c *InstanceCache) Get(userHandle string) ([]models.Instance, bool) { c.mu.RLock() defer c.mu.RUnlock() if exp, ok := c.exp[userHandle]; ok \u0026amp;\u0026amp; time.Now().Before(exp) { return c.data[userHandle], true } return nil, false } func (c *InstanceCache) Set(userHandle string, instances []models.Instance) { c.mu.Lock() defer c.mu.Unlock() c.data[userHandle] = instances c.exp[userHandle] = time.Now().Add(c.ttl) } func (c *InstanceCache) Invalidate(userHandle string) { c.mu.Lock() defer c.mu.Unlock() delete(c.data, userHandle) delete(c.exp, userHandle) }Usage:\nvar instanceCache = \u0026amp;InstanceCache{ data: make(map[string][]models.Instance), exp: make(map[string]time.Time), ttl: 30 * time.Second, } func GetUserInstances(ctx context.Context, pool *pgxpool.Pool, userHandle string) ([]models.Instance, error) { // Check cache if instances, ok := instanceCache.Get(userHandle); ok { return instances, nil } // Query database instances, err := db.GetAccessibleInstances(ctx, userHandle) if err != nil { return nil, err } // Cache results instanceCache.Set(userHandle, instances) return instances, nil }3. Project Metadata Cache# Cache project metadata including schema:\ntype ProjectCache struct { projects map[string]*models.Project // key: \u0026#34;owner/handle\u0026#34; mu sync.RWMutex ttl time.Duration } func (c *ProjectCache) Get(owner, handle string) (*models.Project, bool) { key := fmt.Sprintf(\u0026#34;%s/%s\u0026#34;, owner, handle) c.mu.RLock() defer c.mu.RUnlock() project, ok := c.projects[key] return project, ok }4. Redis-Based Caching# For distributed deployments:\nimport \u0026#34;github.com/go-redis/redis/v8\u0026#34; type RedisCache struct { client *redis.Client ttl time.Duration } func (c *RedisCache) GetProject(ctx context.Context, owner, handle string) (*models.Project, error) { key := fmt.Sprintf(\u0026#34;project:%s:%s\u0026#34;, owner, handle) data, err := c.client.Get(ctx, key).Bytes() if err == redis.Nil { return nil, nil // Not in cache } else if err != nil { return nil, err } var project models.Project err = json.Unmarshal(data, \u0026amp;project) return \u0026amp;project, err } func (c *RedisCache) SetProject(ctx context.Context, project *models.Project) error { key := fmt.Sprintf(\u0026#34;project:%s:%s\u0026#34;, project.Owner, project.Handle) data, err := json.Marshal(project) if err != nil { return err } return c.client.Set(ctx, key, data, c.ttl).Err() }Cache Invalidation# Always invalidate cache on updates:\nfunc UpdateProject(ctx context.Context, pool *pgxpool.Pool, project *models.Project) error { // Update database err := db.UpdateProject(ctx, project) if err != nil { return err } // Invalidate cache projectCache.Invalidate(project.Owner, project.Handle) return nil }Connection Pool Optimization# Pool Configuration# func InitDB(opts *models.Options) *pgxpool.Pool { config, err := pgxpool.ParseConfig(connString) if err != nil { log.Fatal(err) } // Connection pool settings config.MaxConns = 20 // Max concurrent connections config.MinConns = 5 // Keep-alive connections config.MaxConnLifetime = time.Hour // Recycle connections config.MaxConnIdleTime = 5 * time.Minute // Close idle connections config.HealthCheckPeriod = time.Minute // Health check frequency // Statement cache config.ConnConfig.StatementCacheCapacity = 100 pool, err := pgxpool.NewWithConfig(context.Background(), config) return pool }Pool Sizing# General rule:\nMaxConns = (available_cores * 2) + effective_spindle_countExample scenarios:\n4-core CPU, SSD: MaxConns = 10-20 8-core CPU, SSD: MaxConns = 20-40 Under heavy load: Start conservative, increase based on monitoring Monitor Pool Usage# func monitorPool(pool *pgxpool.Pool) { ticker := time.NewTicker(30 * time.Second) for range ticker.C { stat := pool.Stat() log.Printf(\u0026#34;Pool stats: total=%d, idle=%d, acquired=%d, waiting=%d\u0026#34;, stat.TotalConns(), stat.IdleConns(), stat.AcquiredConns(), stat.MaxConns()-stat.TotalConns(), ) } }Performance Testing# Load Testing Setup# Use vegeta for HTTP load testing:\n# Install vegeta go install github.com/tsenart/vegeta@latest # Create targets file cat \u0026gt; targets.txt \u0026lt;\u0026lt;EOF GET http://localhost:8880/v1/projects/alice Authorization: Bearer alice_api_key POST http://localhost:8880/v1/similars/alice/project1/doc1 Authorization: Bearer alice_api_key Content-Type: application/json GET http://localhost:8880/v1/embeddings/alice/project1?limit=100 Authorization: Bearer alice_api_key EOF # Run load test echo \u0026#34;GET http://localhost:8880/v1/projects/alice\u0026#34; | \\ vegeta attack -duration=60s -rate=100 -header=\u0026#34;Authorization: Bearer key\u0026#34; | \\ vegeta reportBenchmark Tests# Create Go benchmarks:\nfunc BenchmarkGetAccessibleInstances(b *testing.B) { pool := setupBenchmarkDB(b) defer pool.Close() // Create test data createTestInstances(b, pool, 1000) ctx := context.Background() b.ResetTimer() for i := 0; i \u0026lt; b.N; i++ { _, err := db.GetAllAccessibleInstances(ctx, \u0026#34;testuser\u0026#34;, 10, 0) if err != nil { b.Fatal(err) } } } func BenchmarkSimilaritySearch(b *testing.B) { pool := setupBenchmarkDB(b) defer pool.Close() // Create embeddings createTestEmbeddings(b, pool, 10000) ctx := context.Background() queryVector := generateRandomVector(1536) b.ResetTimer() for i := 0; i \u0026lt; b.N; i++ { _, err := SearchSimilar(ctx, pool, \u0026#34;alice\u0026#34;, \u0026#34;project1\u0026#34;, queryVector, 10, 0.5) if err != nil { b.Fatal(err) } } }Run benchmarks:\n# Run all benchmarks go test -bench=. -benchmem ./... # Run specific benchmark go test -bench=BenchmarkSimilaritySearch -benchmem ./internal/handlers # Compare before/after go test -bench=. -benchmem ./... \u0026gt; old.txt # Make changes go test -bench=. -benchmem ./... \u0026gt; new.txt benchcmp old.txt new.txtDatabase Performance Testing# Test with realistic data:\n-- Generate test data INSERT INTO embeddings (project_id, text_id, vector, vector_dim, metadata) SELECT 1, \u0026#39;doc_\u0026#39; || generate_series, array_fill(random()::real, ARRAY[1536])::vector, 1536, \u0026#39;{\u0026#34;author\u0026#34;: \u0026#34;test\u0026#34;}\u0026#39;::jsonb FROM generate_series(1, 100000); -- Test query performance EXPLAIN (ANALYZE, BUFFERS) SELECT text_id, vector \u0026lt;=\u0026gt; $1::vector AS distance FROM embeddings WHERE project_id = 1 AND vector_dim = 1536 ORDER BY distance LIMIT 10;Metrics and Monitoring# Application Metrics# Track key metrics:\ntype Metrics struct { QueryDuration prometheus.Histogram QueryCount prometheus.Counter CacheHits prometheus.Counter CacheMisses prometheus.Counter PoolWaitDuration prometheus.Histogram } func recordQueryMetrics(start time.Time, query string) { duration := time.Since(start).Seconds() metrics.QueryDuration.Observe(duration) metrics.QueryCount.Inc() }PostgreSQL Metrics# Monitor database performance:\n-- Slow queries SELECT query, calls, total_time, mean_time, max_time FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 10; -- Table statistics SELECT schemaname, tablename, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup FROM pg_stat_user_tables; -- Index usage SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch FROM pg_stat_user_indexes ORDER BY idx_scan DESC;Performance Targets# Based on typical usage:\nOperation Target Acceptable Action Required Single instance lookup \u0026lt; 10ms \u0026lt; 50ms \u0026gt; 50ms List accessible instances (\u0026lt;100) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Create/update instance \u0026lt; 100ms \u0026lt; 200ms \u0026gt; 200ms Similarity search (10 results) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Similarity search (100 results) \u0026lt; 100ms \u0026lt; 200ms \u0026gt; 200ms Embedding insert (single) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Embedding batch (100) \u0026lt; 500ms \u0026lt; 1000ms \u0026gt; 1000ms Implementation Priority# High Priority# Profile current performance with realistic data Add dimension filtering index: idx_embeddings_project_dim Monitor slow queries with pg_stat_statements Medium Priority# Implement UNION ALL optimization if GetAllAccessibleInstances \u0026gt; 100ms Add caching for system definitions Optimize connection pool settings based on load Low Priority# Add Redis caching layer for high-traffic deployments Implement application metrics with Prometheus Add additional indexes based on actual query patterns Tune HNSW parameters for specific use cases General Best Practices# 1. Measure Before Optimizing# # Profile in production EXPLAIN ANALYZE your_query; # Load test vegeta attack -duration=60s -rate=100 # Benchmark go test -bench=. -benchmem2. Start Conservative# Don\u0026rsquo;t optimize prematurely Use simple queries first Add complexity only when needed 3. Monitor Continuously# Track query performance Monitor connection pool Watch index usage Alert on slow queries 4. Document Optimizations# Note why optimization was needed Include before/after metrics Document trade-offs made Further Reading# PostgreSQL Performance Tuning pgvector Performance Guide Go Database/SQL Tutorial Connection Pool Best Practices "},{"id":33,"href":"/dhamps-vdb/deployment/security/","title":"Security Best Practices","section":"Deployment","content":"Security Best Practices# Comprehensive guide for securing your dhamps-vdb production deployment.\nSecurity Overview# dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.\nHTTPS/TLS Configuration# Why HTTPS is Required# Encryption in transit: Protects API keys and data from interception Authentication: Verifies server identity Compliance: Required by most security standards Using a Reverse Proxy# Never expose dhamps-vdb directly to the internet. Always use a reverse proxy with TLS termination.\nNginx with Let\u0026rsquo;s Encrypt# Install Certbot:\nsudo apt install nginx certbot python3-certbot-nginxConfigure nginx (/etc/nginx/sites-available/dhamps-vdb):\nupstream dhamps_backend { server 127.0.0.1:8880; keepalive 32; } server { listen 80; server_name api.example.com; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name api.example.com; # SSL certificates (managed by Certbot) ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # Modern SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers \u0026#39;ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384\u0026#39;; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # HSTS (HTTP Strict Transport Security) add_header Strict-Transport-Security \u0026#34;max-age=31536000; includeSubDomains\u0026#34; always; # Security headers add_header X-Frame-Options \u0026#34;DENY\u0026#34; always; add_header X-Content-Type-Options \u0026#34;nosniff\u0026#34; always; add_header X-XSS-Protection \u0026#34;1; mode=block\u0026#34; always; add_header Referrer-Policy \u0026#34;strict-origin-when-cross-origin\u0026#34; always; # Proxy settings location / { proxy_pass http://dhamps_backend; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection \u0026#34;\u0026#34;; # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Buffer settings proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; } # Rate limiting (optional, see below) limit_req zone=api_limit burst=20 nodelay; limit_req_status 429; }Enable site and get certificate:\nsudo ln -s /etc/nginx/sites-available/dhamps-vdb /etc/nginx/sites-enabled/ sudo certbot --nginx -d api.example.com sudo systemctl reload nginxAuto-renewal:\n# Certbot creates a systemd timer automatically sudo systemctl status certbot.timer # Test renewal sudo certbot renew --dry-runTraefik (Docker)# docker-compose.yml:\nversion: \u0026#39;3.8\u0026#39; services: traefik: image: traefik:v2.10 command: - \u0026#34;--providers.docker=true\u0026#34; - \u0026#34;--entrypoints.web.address=:80\u0026#34; - \u0026#34;--entrypoints.websecure.address=:443\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.email=admin@example.com\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\u0026#34; ports: - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt dhamps-vdb: build: . labels: - \u0026#34;traefik.enable=true\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.rule=Host(`api.example.com`)\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.entrypoints=websecure\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.tls.certresolver=letsencrypt\u0026#34; # Redirect HTTP to HTTPS - \u0026#34;traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.rule=Host(`api.example.com`)\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.entrypoints=web\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.middlewares=redirect-to-https\u0026#34;Caddy (Automatic HTTPS)# Caddyfile:\napi.example.com { reverse_proxy localhost:8880 # Automatic HTTPS via Let\u0026#39;s Encrypt tls admin@example.com # Security headers header { Strict-Transport-Security \u0026#34;max-age=31536000; includeSubDomains\u0026#34; X-Frame-Options \u0026#34;DENY\u0026#34; X-Content-Type-Options \u0026#34;nosniff\u0026#34; X-XSS-Protection \u0026#34;1; mode=block\u0026#34; } }API Key Management# Admin Key Security# The SERVICE_ADMINKEY has full control over the system.\nBest practices:\nGenerate securely:\nopenssl rand -base64 32 Store securely:\nPassword manager (1Password, Bitwarden) Secrets manager (Vault, AWS Secrets Manager) Never in version control Never in logs or error messages Rotate regularly:\nEvery 90 days minimum After team member departure After suspected compromise Audit usage:\nLog all admin operations Monitor for unusual activity Review regularly User API Keys# User API keys are automatically generated and encrypted before database storage.\nSecurity features:\nOne-time display: Keys shown only at creation Encrypted storage: AES-256-GCM encryption Non-recoverable: Lost keys cannot be retrieved For users:\nSecure storage:\nUse environment variables Never hardcode in applications Never commit to repositories Use HTTPS:\nAlways transmit over TLS Validate server certificates Rotate if compromised:\nDelete old user and create new one Update all client applications Bearer Token Authentication# All API requests require authentication:\ncurl -X GET https://api.example.com/v1/projects/alice \\ -H \u0026#34;Authorization: Bearer your-api-key-here\u0026#34;Security:\nUse Authorization header (not query parameters) Never log full API keys Validate on every request Use HTTPS to prevent interception Encryption Key Security# The ENCRYPTION_KEY protects all user API keys in the database.\nCritical Security Points# ⚠️ CRITICAL: If the encryption key is lost or changed, all user API keys become permanently unrecoverable.\nBest practices:\nGenerate securely:\nopenssl rand -hex 32 Backup separately:\nStore in multiple secure locations Separate from database backups Document recovery procedure Test recovery process Never rotate in production:\nCannot be changed without re-encrypting all keys Requires database migration Risk of data loss Protect at rest:\nEncrypt .env files: gpg --encrypt .env Use secrets management (Vault, AWS Secrets Manager) Restrict file permissions: chmod 600 .env Protect in transit:\nNever send over unencrypted channels Use secure channels for team sharing Avoid email/chat Encryption Details# Algorithm: AES-256-GCM Key derivation: SHA-256 hash of input key Nonce: Unique per encryption Authentication: GCM provides authentication Storage format: Base64-encoded ciphertext Disaster Recovery# Document and test recovery procedure:\n## Encryption Key Recovery Procedure 1. Retrieve backup encryption key from [location] 2. Verify key integrity: [checksum/hash] 3. Update deployment configuration 4. Restart services 5. Verify user authentication works 6. Document incidentDatabase Security# Network Security# Restrict access:\n-- In pg_hba.conf # Allow only from application server host dhamps_vdb dhamps_user 10.0.1.0/24 md5 Firewall rules:\n# UFW example sudo ufw allow from 10.0.1.0/24 to any port 5432 sudo ufw deny 5432 Use VPC/private network:\nKeep database on private network No public internet exposure VPN for remote administration Database Authentication# Strong passwords:\n# Generate secure password openssl rand -base64 32 Dedicated user:\n-- Not superuser CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password\u0026#39;; GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; SSL/TLS connections:\n# postgresql.conf ssl = on ssl_cert_file = \u0026#39;server.crt\u0026#39; ssl_key_file = \u0026#39;server.key\u0026#39; ssl_ca_file = \u0026#39;ca.crt\u0026#39; Database Encryption# Encryption at rest:\nUse encrypted filesystems (LUKS, dm-crypt) Cloud provider encryption (AWS RDS encryption) Transparent Data Encryption (TDE) Backup encryption:\n# Encrypt backup pg_dump -U postgres dhamps_vdb | gzip | \\ gpg --encrypt --recipient admin@example.com \u0026gt; backup.sql.gz.gpg Database Auditing# Enable audit logging:\n-- Install pgaudit CREATE EXTENSION pgaudit; -- Configure logging ALTER SYSTEM SET pgaudit.log = \u0026#39;write, ddl\u0026#39;; ALTER SYSTEM SET pgaudit.log_catalog = off; ALTER SYSTEM SET pgaudit.log_parameter = on; -- Reload config SELECT pg_reload_conf();Network Security# Firewall Configuration# # UFW example sudo ufw default deny incoming sudo ufw default allow outgoing # Allow SSH sudo ufw allow 22/tcp # Allow HTTP/HTTPS (reverse proxy) sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Application port (if not behind proxy) # sudo ufw allow from trusted_network to any port 8880 # Database (from app server only) sudo ufw allow from 10.0.1.0/24 to any port 5432 sudo ufw enableNetwork Segmentation# Deploy in isolated networks:\nInternet ↓ [Reverse Proxy] ← (DMZ/Public subnet) ↓ [dhamps-vdb] ← (Application subnet) ↓ [PostgreSQL] ← (Database subnet)Rate Limiting# Protect against abuse and DoS attacks.\nNginx:\n# Define rate limit zone http { limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=api_burst:10m rate=100r/s; } server { location /v1/ { limit_req zone=api_limit burst=20 nodelay; limit_req_status 429; proxy_pass http://dhamps_backend; } }Application-level (future enhancement):\nImplement token bucket or leaky bucket Per-user rate limits Different limits for different endpoints Backup Strategies# Database Backups# Automated daily backups:\n#!/bin/bash # /usr/local/bin/backup-dhamps.sh DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR=\u0026#34;/backups/dhamps-vdb\u0026#34; # Create backup pg_dump -U dhamps_user dhamps_vdb | gzip \u0026gt; \\ \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Encrypt backup gpg --encrypt --recipient admin@example.com \\ \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Remove unencrypted backup rm \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Verify backup gpg --decrypt \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz.gpg\u0026#34; | gunzip | head -n 5 # Upload to offsite storage aws s3 cp \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz.gpg\u0026#34; \\ s3://backups/dhamps-vdb/ --storage-class GLACIER # Cleanup old local backups (keep 7 days) find $BACKUP_DIR -name \u0026#34;db-*.sql.gz.gpg\u0026#34; -mtime +7 -delete Cron schedule:\n0 2 * * * /usr/local/bin/backup-dhamps.sh Test restores regularly:\n# Monthly restore test 0 3 1 * * /usr/local/bin/test-restore.sh Configuration Backups# # Backup environment configuration cp .env .env.backup gpg --encrypt --recipient admin@example.com .env.backup # Backup with timestamp tar czf config-$(date +%Y%m%d).tar.gz .env docker-compose.yml gpg --encrypt --recipient admin@example.com config-*.tar.gzBackup Retention Policy# Daily backups: Keep 7 days locally Weekly backups: Keep 4 weeks offsite Monthly backups: Keep 12 months in cold storage Yearly backups: Keep 7 years (compliance dependent) Offsite Backups# Always maintain offsite backups:\nCloud storage: AWS S3, Azure Blob Storage, GCP Cloud Storage Different geographic region Encrypted before upload Test restoration procedures Monitoring and Alerting# What to Monitor# Authentication failures:\n# Parse logs for 401 responses grep \u0026#34;401\u0026#34; /var/log/nginx/access.log | wc -l Unusual API usage:\nSpike in requests Requests to non-existent endpoints Large data transfers Database health:\nConnection count Query performance Disk usage Replication lag (if applicable) System resources:\nCPU usage Memory usage Disk I/O Network throughput Log Management# Centralized logging:\nELK Stack (Elasticsearch, Logstash, Kibana) Splunk Graylog CloudWatch Logs (AWS) Log retention:\nApplication logs: 30 days minimum Access logs: 90 days minimum Audit logs: 1 year minimum (compliance dependent) Log security:\nNever log API keys in full (mask: api_key=abc...xyz) Never log passwords Encrypt archived logs Restrict access to logs Alerting# Set up alerts for:\nFailed authentication attempts (\u0026gt;10/minute) Database connection failures Disk space \u0026gt;80% full Service downtime Unusual network traffic SSL certificate expiration (30 days before) Security Checklist# Use this checklist for production deployments:\nPre-Deployment# Strong, random SERVICE_ADMINKEY generated Strong, random ENCRYPTION_KEY generated (32+ chars) Strong database password set .env file encrypted or in secrets manager .env not in version control Encryption key backed up separately from database Network \u0026amp; Access# HTTPS/TLS configured with valid certificate Reverse proxy deployed (nginx/Traefik/Caddy) Firewall configured and enabled Database on private network only Rate limiting configured HSTS header enabled Security headers configured Database# PostgreSQL 11+ with pgvector installed Dedicated database user (not superuser) Strong database password SSL/TLS for database connections Database firewall rules configured pg_hba.conf restricts access by IP Regular backups configured Backup encryption enabled Restore procedure tested Application# Service runs as non-root user Debug logging disabled (SERVICE_DEBUG=false) Resource limits configured Health checks enabled Logging configured Monitoring configured Alerting configured Operations# Backup procedure documented Restore procedure documented and tested Disaster recovery plan created Security incident response plan created Key rotation schedule defined Access control documented (who has admin key) Regular security updates scheduled Compliance# Data retention policy defined Privacy policy reviewed Terms of service reviewed GDPR compliance (if applicable) Data processing agreements in place Audit logging enabled Incident Response# Suspected API Key Compromise# Immediate actions:\nIdentify compromised user Delete user (invalidates API key) Create new user with new API key Review access logs for unauthorized access Investigation:\nDetermine scope of compromise Check for data exfiltration Document incident Notification:\nNotify affected parties (if required) Document lessons learned Update security procedures Database Breach# Immediate actions:\nIsolate database server Revoke network access Change all database credentials Activate incident response team Assessment:\nDetermine data accessed Check encryption effectiveness Review audit logs Recovery:\nRestore from clean backup Apply security patches Update firewall rules Notify affected parties (if required) Document and learn Encryption Key Loss# ⚠️ CRITICAL SITUATION: If encryption key is lost, all user API keys are unrecoverable.\nRecovery attempt:\nCheck all backup locations Review documentation Contact all team members If unrecoverable:\nAll users must be deleted and recreated New API keys issued to all users All client applications must be updated Communicate timeline to users Prevention:\nReview backup procedures Add redundant backup locations Document key locations Test recovery process Security Updates# Regular Updates# Weekly: Review security advisories Monthly: Apply security patches Quarterly: Security audit and penetration testing Yearly: Full security review and compliance audit Update Procedure# Test in staging environment Backup production database and configuration Schedule maintenance window Apply updates Verify functionality Monitor for issues Subscribe to Security Advisories# PostgreSQL security announcements pgvector security updates Docker security advisories Go security advisories Operating system security updates Further Reading# OWASP Top 10 PostgreSQL Security Docker Security Best Practices Let\u0026rsquo;s Encrypt Documentation Environment Variables Reference Database Setup Guide Docker Deployment "},{"id":34,"href":"/dhamps-vdb/deployment/","title":"Deployment","section":"dhamps-vdb Documentation","content":"Deployment Guide# Deploy dhamps-vdb to production environments.\nDeployment Options# dhamps-vdb can be deployed in several ways:\nDocker Compose - Simplest option, includes PostgreSQL Docker with External Database - Production-ready setup Standalone Binary - For custom environments Kubernetes - For orchestrated deployments Production Considerations# When deploying to production:\nUse strong, randomly generated keys Enable HTTPS/TLS for all API endpoints Configure database backups Set up monitoring and logging Restrict network access to database Use environment variables for sensitive configuration Guides# Docker Deployment - Complete Docker guide Database Setup - PostgreSQL configuration Environment Variables - All configuration options Security - Security best practices "},{"id":35,"href":"/dhamps-vdb/api/endpoints/embeddings/","title":"Embeddings","section":"Endpoints","content":"Embeddings Endpoint# Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project\u0026rsquo;s LLM service instance dimensions.\nEndpoints# List Embeddings# Get all embeddings for a project with pagination support.\nEndpoint: GET /v1/embeddings/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters:\nlimit (integer, default: 10, max: 200): Maximum number of results to return offset (integer, default: 0): Pagination offset Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;This is a research document about machine learning.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ], \u0026#34;total_count\u0026#34;: 150, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 0 } Upload Embeddings (Batch)# Upload one or more embeddings to a project. Supports batch upload for efficiency.\nEndpoint: POST /v1/embeddings/{username}/{projectname}\nAuthentication: Admin, owner, or authorized editors\nRequest Body:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;This is a research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc124\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Another research document.\u0026#34;, \u0026#34;vector\u0026#34;: [0.012345, -0.054321, 0.098765, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Bob Smith\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }Parameters:\nembeddings (array, required): Array of embedding objects text_id (string, required): Unique identifier for the text (URL-encoded recommended) instance_handle (string, required): Handle of the LLM service instance used vector (array of floats, required): Embedding vector vector_dim (integer, required): Number of dimensions in the vector text (string, optional): The original text metadata (object, optional): Additional metadata (validated against project schema if defined) Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Machine learning research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270], \u0026#34;vector_dim\u0026#34;: 3, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;1 embedding(s) uploaded successfully\u0026#34;, \u0026#34;uploaded\u0026#34;: [\u0026#34;doc123\u0026#34;] } Get Single Embedding# Retrieve information about a specific embedding by its text identifier.\nEndpoint: GET /v1/embeddings/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;project_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Machine learning research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }Note: URL-encode the identifier if it contains special characters (e.g., URLs).\nExample with URL identifier:\n# URL-encoded identifier curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/https%3A%2F%2Fexample.com%2Fdoc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Delete Single Embedding# Delete a specific embedding by its text identifier.\nEndpoint: DELETE /v1/embeddings/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, or authorized editors\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; deleted successfully\u0026#34; } Delete All Embeddings# Delete all embeddings in a project.\nEndpoint: DELETE /v1/embeddings/{username}/{projectname}\nAuthentication: Admin or owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;All embeddings deleted from project alice/research-docs\u0026#34;, \u0026#34;deleted_count\u0026#34;: 150 }⚠️ Warning: This operation is irreversible.\nRequest Format Details# Text Identifiers# Text identifiers (text_id) should be:\nUnique within a project URL-encoded if they contain special characters Descriptive for easier retrieval Examples:\nSimple: \u0026quot;doc123\u0026quot;, \u0026quot;article-456\u0026quot; URL-based: \u0026quot;https://example.com/docs/123\u0026quot; (URL-encode in requests) Path-based: \u0026quot;books/chapter1/section2\u0026quot; Vector Format# Vectors must be:\nArrays of floats (float32 or float64) Matching dimensions specified in vector_dim Consistent dimensions with the project\u0026rsquo;s LLM service instance Example:\n{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003], \u0026#34;vector_dim\u0026#34;: 5 }Metadata Format# Metadata is a flexible JSON object that can contain any valid JSON data:\nSimple metadata:\n{ \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;category\u0026#34;: \u0026#34;research\u0026#34; } }Nested metadata:\n{ \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;author-123\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 2024, \u0026#34;title\u0026#34;: \u0026#34;Machine Learning Research\u0026#34; }, \u0026#34;tags\u0026#34;: [\u0026#34;AI\u0026#34;, \u0026#34;ML\u0026#34;, \u0026#34;embeddings\u0026#34;] } } Validation# Dimension Validation# The API automatically validates that:\nVector dimension consistency: The vector_dim field must match the dimensions configured in the LLM service instance Vector length verification: The actual number of elements in the vector array must match the declared vector_dim Error example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }Metadata Schema Validation# If the project has a metadataScheme defined, all uploaded embeddings\u0026rsquo; metadata will be validated against it.\nExample project schema:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Valid metadata:\n{ \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 }Invalid metadata (missing required field):\n{ \u0026#34;year\u0026#34;: 2024 }Error response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; } Response Format# List Response# { \u0026#34;embeddings\u0026#34;: [...], \u0026#34;total_count\u0026#34;: 150, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 0 }Single Embedding Response# { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;project_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {...} }Upload Response# { \u0026#34;message\u0026#34;: \u0026#34;3 embedding(s) uploaded successfully\u0026#34;, \u0026#34;uploaded\u0026#34;: [\u0026#34;doc123\u0026#34;, \u0026#34;doc124\u0026#34;, \u0026#34;doc125\u0026#34;] } Common Errors# 400 Bad Request - Dimension Mismatch# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }400 Bad Request - Invalid Vector# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector length (1536) does not match declared vector_dim (3072)\u0026#34; }400 Bad Request - Metadata Schema Violation# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to upload embeddings to this project\u0026#34; }404 Not Found - Project# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }404 Not Found - Embedding# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; already exists in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; } Best Practices# Batch Uploads# Upload multiple embeddings in a single request for better performance:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ {...}, {...}, {...} ] }\u0026#39;URL-Encoded Identifiers# Use URL encoding for identifiers with special characters:\nimport urllib.parse text_id = \u0026#34;https://example.com/docs/123\u0026#34; encoded_id = urllib.parse.quote(text_id, safe=\u0026#39;\u0026#39;) # Result: \u0026#34;https%3A%2F%2Fexample.com%2Fdocs%2F123\u0026#34;Metadata Design# Design metadata schemas that:\nInclude commonly queried fields Use consistent data types Validate required fields Support your similarity search filtering needs Related Documentation# Projects - Project management and configuration Similars - Similarity search using embeddings Query Parameters - Pagination and filtering options Error Handling - Complete error reference "},{"id":36,"href":"/dhamps-vdb/concepts/llm-services/","title":"LLM Services","section":"Concepts","content":"LLM Services# LLM Services configure embedding generation, defining models, dimensions, and API access.\nArchitecture# dhamps-vdb separates LLM services into two concepts:\nLLM Service Definitions# Reusable configuration templates owned by _system or users:\nPurpose: Provide standard configurations Ownership: _system (global) or individual users Contents: Endpoint, model, dimensions, API standard API Keys: Not stored (templates only) Usage: Templates for creating instances LLM Service Instances# User-specific configurations with encrypted API keys:\nPurpose: Actual service configurations users employ Ownership: Individual users Contents: Endpoint, model, dimensions, API key (encrypted) Sharing: Can be shared with other users Projects: Each project references exactly one instance System Definitions# Available Definitions# The _system user provides default definitions:\nHandle Model Dimensions API Standard openai-large text-embedding-3-large 3072 openai openai-small text-embedding-3-small 1536 openai cohere-v4 embed-multilingual-v4.0 1536 cohere gemini-embedding-001 text-embedding-004 3072 gemini Viewing System Definitions# GET /v1/llm-services/_system Authorization: Bearer user_vdb_keyReturns list of available system definitions.\nCreating Instances# From System Definition# Use a predefined system configuration:\nPUT /v1/llm-services/alice/my-openai { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My OpenAI embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }Inherits endpoint, model, dimensions from system definition.\nFrom User Definition# Reference a user-created definition:\nPUT /v1/llm-services/alice/custom-instance { \u0026#34;definition_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-api-key\u0026#34; }Standalone Instance# Create without a definition:\nPUT /v1/llm-services/alice/standalone { \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;Standalone OpenAI instance\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-key\u0026#34; }All fields must be specified.\nInstance Properties# Core Fields# instance_handle: Unique identifier (3-20 characters) owner: User who owns the instance endpoint: API endpoint URL api_standard: Authentication mechanism (openai, cohere, gemini) model: Model identifier dimensions: Vector dimensionality description: Human-readable description (optional) definition_id: Reference to definition (optional) API Key Storage# Write-only: Provided on create/update Encrypted: AES-256-GCM encryption Never returned: Not included in GET responses Secure: Cannot be retrieved after creation API Standards# Supported Standards# Standard Key Method Documentation openai Authorization: Bearer OpenAI Docs cohere Authorization: Bearer Cohere Docs gemini x-goog-api-key header Gemini Docs Creating API Standards# Admins can add new standards:\nPOST /v1/api-standards Authorization: Bearer ADMIN_KEY { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom LLM API\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: null }Instance Management# List Instances# List all accessible instances (owned + shared):\nGET /v1/llm-services/alice Authorization: Bearer alice_vdb_keyReturns instances where alice is owner or has been granted access.\nGet Instance Details# GET /v1/llm-services/alice/my-openai Authorization: Bearer alice_vdb_keyReturns instance configuration (API key not included).\nUpdate Instance# PATCH /v1/llm-services/alice/my-openai { \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;new-api-key\u0026#34; }Only owner can update instances.\nDelete Instance# DELETE /v1/llm-services/alice/my-openai Authorization: Bearer alice_vdb_keyConstraints:\nCannot delete instance used by projects Delete projects first, then instance Instance Sharing# Share with User# POST /v1/llm-services/alice/my-openai/share { \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Shared users can:\nUse instance in their projects View instance configuration Cannot: See API key Modify instance Delete instance Unshare from User# DELETE /v1/llm-services/alice/my-openai/share/bobList Shared Users# GET /v1/llm-services/alice/my-openai/shared-withOnly owner can view shared users.\nInstance References# In Projects# Projects reference instances by owner and handle:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }In Embeddings# Embeddings reference instances by handle:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...] }The instance owner is inferred from the project.\nShared Instance Format# When using shared instances:\nOwn instance: \u0026quot;instance_handle\u0026quot;: \u0026quot;my-openai\u0026quot; Shared instance: Reference via project configuration\nEncryption# API Key Encryption# API keys are encrypted using AES-256-GCM:\nEncryption process:\nUser provides plaintext API key Server encrypts using ENCRYPTION_KEY from environment Encrypted bytes stored in database Key derivation: SHA-256 hash ensures 32-byte key Decryption:\nOnly occurs internally for LLM API calls Never exposed via API responses Requires same ENCRYPTION_KEY Security Notes# Encryption key: Set via ENCRYPTION_KEY environment variable Key loss: Losing encryption key means losing access to API keys Key rotation: Not currently supported Backup: Back up encryption key securely LLM Processing# Current Status# LLM processing (generating embeddings) is not yet implemented.\nFuture Implementation# Planned features:\nProcess text to generate embeddings Call external LLM APIs Store generated embeddings Batch processing support Current Workflow# Users must generate embeddings externally:\nGenerate embeddings using LLM API (OpenAI, Cohere, etc.) Upload pre-generated embeddings to dhamps-vdb Use dhamps-vdb for storage and similarity search Common Patterns# Per-Environment Instances# # Development instance PUT /v1/llm-services/alice/dev-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;dev-api-key\u0026#34; } # Production instance PUT /v1/llm-services/alice/prod-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;prod-api-key\u0026#34; }Team Shared Instance# # Owner creates instance PUT /v1/llm-services/team-lead/team-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;team-api-key\u0026#34; } # Share with team members POST /v1/llm-services/team-lead/team-embeddings/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;member1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} POST /v1/llm-services/team-lead/team-embeddings/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;member2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} # Members use in their projects POST /v1/projects/member1 { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;team-lead\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;team-embeddings\u0026#34; }Multi-Model Setup# # Large model for important documents PUT /v1/llm-services/alice/high-quality { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;api-key\u0026#34; } # Small model for drafts PUT /v1/llm-services/alice/fast-processing { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;api-key\u0026#34; }Troubleshooting# Cannot Create Instance# Possible causes:\nInstance handle already exists Referenced definition doesn\u0026rsquo;t exist Missing required fields Invalid API standard Solutions:\nChoose different handle Verify definition: GET /v1/llm-services/_system Include all required fields Use valid API standard: GET /v1/api-standards Cannot Use Instance in Project# Possible causes:\nInstance doesn\u0026rsquo;t exist Instance not owned or shared with user Incorrect owner/handle reference Solutions:\nVerify instance exists Check instance is accessible Confirm spelling of owner and handle Dimension Mismatch# Error: \u0026ldquo;dimension validation failed\u0026rdquo;\nCause: Embedding dimensions don\u0026rsquo;t match instance\nSolutions:\nCheck instance dimensions Regenerate embeddings with correct model Create instance with correct dimensions Next Steps# Understand projects Learn about embeddings Explore instance management "},{"id":37,"href":"/dhamps-vdb/guides/metadata-validation/","title":"Metadata Validation Guide","section":"Guides","content":"Metadata Validation Guide# This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.\nOverview# dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.\nBenefits:\nEnforce consistent metadata structure across all embeddings Catch data entry errors early Document expected metadata fields Enable reliable metadata-based filtering Defining a Metadata Schema# When Creating a Project# Include a metadataScheme field with a valid JSON Schema when creating a project:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/validated-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;validated-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Project with metadata validation\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Updating an Existing Project# Add or update a metadata schema using PATCH:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;title\\\u0026#34;,\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Note: Schema updates only affect new or updated embeddings. Existing embeddings are not retroactively validated.\nCommon Schema Patterns# Simple Required Fields# Require specific fields with basic types:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Example usage:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literary-texts\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary texts with structured metadata\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Using Enums for Controlled Values# Restrict fields to specific allowed values:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;prose\u0026#34;, \u0026#34;drama\u0026#34;, \u0026#34;essay\u0026#34;] }, \u0026#34;language\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;en\u0026#34;, \u0026#34;de\u0026#34;, \u0026#34;fr\u0026#34;, \u0026#34;es\u0026#34;, \u0026#34;la\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;genre\u0026#34;] }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;hamlet-soliloquy\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34; } }] }\u0026#39;Nested Objects# Define structured metadata with nested objects:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;birth_year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;nationality\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;name\u0026#34;] }, \u0026#34;publication\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;publisher\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;city\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/academic-papers\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;paper001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Jane Smith\u0026#34;, \u0026#34;birth_year\u0026#34;: 1975, \u0026#34;nationality\u0026#34;: \u0026#34;USA\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 2023, \u0026#34;publisher\u0026#34;: \u0026#34;Academic Press\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Boston\u0026#34; } } }] }\u0026#39;Arrays and Lists# Define arrays of values:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;keywords\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1, \u0026#34;maxItems\u0026#34;: 10 }, \u0026#34;categories\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;philosophy\u0026#34;, \u0026#34;literature\u0026#34;, \u0026#34;science\u0026#34;, \u0026#34;history\u0026#34;] } } } }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;keywords\u0026#34;: [\u0026#34;machine learning\u0026#34;, \u0026#34;embeddings\u0026#34;, \u0026#34;NLP\u0026#34;], \u0026#34;categories\u0026#34;: [\u0026#34;science\u0026#34;, \u0026#34;literature\u0026#34;] } }] }\u0026#39;Numeric Constraints# Apply minimum, maximum, and range constraints:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;rating\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0, \u0026#34;maximum\u0026#34;: 5 }, \u0026#34;page_count\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1 }, \u0026#34;confidence\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0.0, \u0026#34;maximum\u0026#34;: 1.0 } } }String Constraints# Apply length and pattern constraints:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 200 }, \u0026#34;isbn\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^[0-9]{13}$\u0026#34; }, \u0026#34;doi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^10\\\\.\\\\d{4,}/[\\\\w\\\\-\\\\.]+$\u0026#34; } } }Validation Examples# Valid Upload# When metadata conforms to the schema:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;kant-critique\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Immanuel Kant\u0026#34;, \u0026#34;year\u0026#34;: 1781, \u0026#34;genre\u0026#34;: \u0026#34;prose\u0026#34; } }] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embeddings uploaded successfully\u0026#34;, \u0026#34;count\u0026#34;: 1 }Validation Error: Missing Required Field# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;year\u0026#34;: 1781 } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - author is required\u0026#34; }Validation Error: Wrong Type# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;year\u0026#34;: \u0026#34;1781\u0026#34; } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - year: expected integer, got string\u0026#34; }Validation Error: Invalid Enum Value# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;year\u0026#34;: 1781, \u0026#34;genre\u0026#34;: \u0026#34;novel\u0026#34; } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - genre: value must be one of: poetry, prose, drama, essay\u0026#34; }Validation Error: Value Out of Range# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/rated-content\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;review001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;rating\u0026#34;: 7.5 } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;review001\u0026#39;: metadata validation failed:\\n - rating: must be \u0026lt;= 5\u0026#34; }Real-World Schema Examples# Academic Publications# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;doi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^10\\\\.\\\\d{4,}/[\\\\w\\\\-\\\\.]+$\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 500 }, \u0026#34;authors\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1 }, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1900, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;journal\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;volume\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;pages\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;keywords\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;doi\u0026#34;, \u0026#34;title\u0026#34;, \u0026#34;authors\u0026#34;, \u0026#34;year\u0026#34;] }Legal Documents# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;case_number\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;court\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;date\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^\\\\d{4}-\\\\d{2}-\\\\d{2}$\u0026#34; }, \u0026#34;jurisdiction\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;federal\u0026#34;, \u0026#34;state\u0026#34;, \u0026#34;local\u0026#34;] }, \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;civil\u0026#34;, \u0026#34;criminal\u0026#34;, \u0026#34;administrative\u0026#34;] }, \u0026#34;parties\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;case_number\u0026#34;, \u0026#34;court\u0026#34;, \u0026#34;date\u0026#34;] }Product Catalog# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;sku\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^[A-Z]{3}-\\\\d{6}$\u0026#34; }, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;electronics\u0026#34;, \u0026#34;clothing\u0026#34;, \u0026#34;books\u0026#34;, \u0026#34;home\u0026#34;, \u0026#34;toys\u0026#34;] }, \u0026#34;price\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0 }, \u0026#34;in_stock\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34;}, \u0026#34;tags\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;sku\u0026#34;, \u0026#34;name\u0026#34;, \u0026#34;category\u0026#34;, \u0026#34;price\u0026#34;] }Admin Sanity Check# Administrators can verify database integrity using the /v1/admin/sanity-check endpoint:\ncurl -X GET \u0026#34;https://api.example.com/v1/admin/sanity-check\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;status\u0026#34;: \u0026#34;PASSED\u0026#34;, \u0026#34;total_projects\u0026#34;: 5, \u0026#34;issues_count\u0026#34;: 0, \u0026#34;warnings_count\u0026#34;: 1, \u0026#34;warnings\u0026#34;: [ \u0026#34;Project alice/project1 has 100 embeddings but no metadata schema defined\u0026#34; ] }Status Values:\nPASSED: No issues or warnings found WARNING: No critical issues, but warnings exist FAILED: Validation issues found that need attention The sanity check:\nValidates all embeddings have dimensions matching their LLM service Validates all metadata against project schemas (if defined) Reports projects without schemas as warnings Best Practices# 1. Start Simple, Add Complexity Later# Begin with basic required fields:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;source\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;source\u0026#34;] }Add more constraints as your needs evolve.\n2. Test Schemas Before Deployment# Use online JSON Schema validators like jsonschemavalidator.net to test your schemas before deploying them.\n3. Document Your Schema# Include a description in your project:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Project with metadata schema: author (required string), year (integer), genre (enum)\u0026#34; }\u0026#39;4. Version Your Schemas# If you need to change a schema significantly, consider creating a new project rather than updating the existing one.\n5. Optional vs Required# Be judicious with required fields. Too many required fields can make uploads cumbersome.\n6. Escape JSON Properly# When passing JSON schemas in curl commands, escape quotes properly or use single quotes for the outer JSON.\nProjects Without Schemas# If you don\u0026rsquo;t provide a metadataScheme when creating a project:\nMetadata validation is skipped You can upload any valid JSON metadata This is useful for exploratory work or heterogeneous data Schema Updates and Existing Data# When you update a project\u0026rsquo;s metadata schema:\nExisting embeddings are not revalidated The new schema only applies to new or updated embeddings Use the admin sanity check to find existing embeddings that don\u0026rsquo;t conform Removing a Schema# To remove metadata validation from a project:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;metadataScheme\u0026#34;: null}\u0026#39;After this, new embeddings can have any metadata structure.\nRelated Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Filtering Guide - Filter search results by metadata Batch Operations Guide - Upload large datasets efficiently Troubleshooting# Schema Syntax Errors# Error: \u0026ldquo;Invalid JSON Schema\u0026rdquo;\nSolution: Validate your schema syntax using an online validator. Common issues:\nMissing commas between properties Unescaped quotes Invalid JSON structure Uploads Failing After Schema Change# Problem: Uploads worked before, now failing with validation errors\nSolution: Check that your metadata matches the new schema requirements. Review the error message for specific validation failures.\nWant to Fix Non-Conforming Data# Problem: Sanity check shows validation errors in existing data\nSolution: Either:\nUpdate the schema to accept existing data Re-upload conforming data to replace non-conforming embeddings Delete and re-upload the project with correct metadata "},{"id":38,"href":"/dhamps-vdb/development/","title":"Development","section":"dhamps-vdb Documentation","content":"Development Guide# Information for developers contributing to dhamps-vdb.\nGetting Started with Development# This section covers:\nSetting up a development environment Running tests Understanding the codebase architecture Contributing guidelines Performance optimization Project Structure# dhamps-vdb/ ├── main.go # Application entry point ├── internal/ │ ├── auth/ # Authentication logic │ ├── database/ # Database layer (sqlc) │ ├── handlers/ # HTTP handlers │ └── models/ # Data models ├── testdata/ # Test fixtures └── docs/ # DocumentationDevelopment Workflow# Make changes to code Generate sqlc code if database queries changed: sqlc generate Run tests: go test -v ./... Build: go build -o dhamps-vdb main.go Submit pull request Resources# Testing - How to run tests Contributing - Contribution guidelines Architecture - Technical deep-dive Performance - Optimization notes "},{"id":39,"href":"/dhamps-vdb/guides/metadata-filtering/","title":"Metadata Filtering Guide","section":"Guides","content":"Metadata Filtering Guide# This guide explains how to use metadata filtering to exclude specific documents from similarity search results.\nOverview# When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:\nExclude documents from the same author when finding similar writing styles Filter out documents from the same source when finding related content Exclude documents with the same category when exploring diversity dhamps-vdb provides metadata filtering using query parameters that perform negative matching - they exclude documents where the metadata field matches the specified value.\nQuery Parameters# Both similarity search endpoints support metadata filtering:\nmetadata_path: The JSON path to the metadata field (e.g., author, source.id, tags[0]) metadata_value: The value to exclude from results Both parameters must be used together. If you specify one without the other, the API returns an error.\nBasic Filtering Examples# Exclude Documents by Author# Find similar documents but exclude those from the same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/literary-corpus/hamlet-soliloquy?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=William%20Shakespeare\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This returns similar documents, excluding any with metadata.author == \u0026quot;William Shakespeare\u0026quot;.\nExclude Documents from Same Source# Find similar content from different sources:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/news-articles/article123?count=10\u0026amp;metadata_path=source\u0026amp;metadata_value=NYTimes\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This excludes any documents with metadata.source == \u0026quot;NYTimes\u0026quot;.\nExclude by Category# Find documents in different categories:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/products/product456?count=10\u0026amp;metadata_path=category\u0026amp;metadata_value=electronics\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This excludes any documents with metadata.category == \u0026quot;electronics\u0026quot;.\nFiltering with Raw Embeddings# Metadata filtering also works when searching with raw embedding vectors:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/literary-corpus?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=William%20Shakespeare\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;This searches using the provided vector but excludes documents where metadata.author == \u0026quot;William Shakespeare\u0026quot;.\nNested Metadata Paths# For nested metadata objects, use dot notation:\nExample Metadata Structure# { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Jane Doe\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;author123\u0026#34;, \u0026#34;affiliation\u0026#34;: \u0026#34;University\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;journal\u0026#34;: \u0026#34;Science\u0026#34;, \u0026#34;year\u0026#34;: 2023 } }Filter by Nested Field# # Exclude documents from same author ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/papers/paper001?count=10\u0026amp;metadata_path=author.id\u0026amp;metadata_value=author123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Exclude documents from same journal curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/papers/paper001?count=10\u0026amp;metadata_path=publication.journal\u0026amp;metadata_value=Science\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining with Other Parameters# Metadata filtering works seamlessly with other search parameters:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/documents/doc123?count=20\u0026amp;threshold=0.8\u0026amp;limit=10\u0026amp;offset=0\u0026amp;metadata_path=source_id\u0026amp;metadata_value=src_456\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Parameters:\ncount=20: Consider top 20 similar documents threshold=0.8: Only include documents with similarity ≥ 0.8 limit=10: Return at most 10 results offset=0: Start from first result (for pagination) metadata_path=source_id: Filter on this metadata field metadata_value=src_456: Exclude documents with this value Use Cases# 1. Finding Similar Writing Styles Across Authors# When analyzing writing styles, you want similar texts from different authors:\n# Upload documents with author metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/writing-styles\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy-passage-1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Happy families are all alike...\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Leo Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Anna Karenina\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;Russian\u0026#34; } }] }\u0026#39; # Find similar writing styles from other authors curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/writing-styles/tolstoy-passage-1?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=Leo%20Tolstoy\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;2. Cross-Source Content Discovery# Find related news articles from different sources:\n# Search for similar content, excluding same source curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/news-corpus/nyt-article-456?count=15\u0026amp;metadata_path=source\u0026amp;metadata_value=New%20York%20Times\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This helps discover how different outlets cover similar topics.\n3. Product Recommendations Across Categories# Find similar products in different categories:\n# User is viewing a laptop curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/product-catalog/laptop-001?count=10\u0026amp;threshold=0.7\u0026amp;metadata_path=category\u0026amp;metadata_value=electronics\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This could recommend accessories, furniture (for home office), or other complementary items.\n4. Research Paper Discovery# Find related papers from different research groups:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-papers/paper123?count=20\u0026amp;metadata_path=lab_id\u0026amp;metadata_value=lab_abc_001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Helps researchers discover related work from other institutions.\n5. Avoiding Duplicate Content# When building a diverse content feed, exclude items from the same collection:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/blog-posts/post789?count=5\u0026amp;metadata_path=collection_id\u0026amp;metadata_value=series_xyz\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;6. Cross-Language Document Discovery# Find similar documents in other languages:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/multilingual-docs/doc_en_123?count=10\u0026amp;metadata_path=language\u0026amp;metadata_value=en\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This finds semantically similar documents in languages other than English.\nWorking with Multiple Values# Currently, you can only filter by one metadata field at a time. To exclude multiple values, you need to:\nMake multiple requests and merge results in your application Use more specific metadata fields that combine multiple attributes Post-process results on the client side Example: Excluding Multiple Authors# import requests def find_similar_excluding_authors(doc_id, exclude_authors): \u0026#34;\u0026#34;\u0026#34;Find similar docs excluding multiple authors\u0026#34;\u0026#34;\u0026#34; all_results = [] for author in exclude_authors: response = requests.get( f\u0026#34;https://api.example.com/v1/similars/alice/corpus/{doc_id}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;}, params={ \u0026#34;count\u0026#34;: 20, \u0026#34;metadata_path\u0026#34;: \u0026#34;author\u0026#34;, \u0026#34;metadata_value\u0026#34;: author } ) results = response.json()[\u0026#39;results\u0026#39;] all_results.extend(results) # Deduplicate and sort by similarity seen = set() unique_results = [] for r in sorted(all_results, key=lambda x: x[\u0026#39;similarity\u0026#39;], reverse=True): if r[\u0026#39;id\u0026#39;] not in seen: seen.add(r[\u0026#39;id\u0026#39;]) unique_results.append(r) return unique_results[:10] # Usage similar = find_similar_excluding_authors( \u0026#34;doc123\u0026#34;, [\u0026#34;Author A\u0026#34;, \u0026#34;Author B\u0026#34;, \u0026#34;Author C\u0026#34;] )Combining with Metadata Validation# For reliable filtering, combine with metadata schema validation:\n# Step 1: Create project with metadata schema curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/validated-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;validated-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Corpus with validated metadata\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;source_id\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;source_id\\\u0026#34;]}\u0026#34; }\u0026#39; # Step 2: Upload embeddings with metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/validated-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;source_id\u0026#34;: \u0026#34;source_123\u0026#34; } }] }\u0026#39; # Step 3: Search with guaranteed metadata field existence curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/validated-corpus/doc001?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;See the Metadata Validation Guide for more details.\nUnderstanding the Filter Logic# The metadata filter uses negative matching:\nINCLUDE document IF: - document.similarity \u0026gt;= threshold AND - document.metadata[metadata_path] != metadata_valueImportant: Documents without the specified metadata field are included (not filtered out).\nExample# Given this query:\n?metadata_path=author\u0026amp;metadata_value=AliceIncluded:\nDocuments where metadata.author == \u0026quot;Bob\u0026quot; Documents where metadata.author == \u0026quot;Charlie\u0026quot; Documents without an author field in metadata Excluded:\nDocuments where metadata.author == \u0026quot;Alice\u0026quot; Performance Considerations# Metadata filtering is performed at the database level using efficient indexing:\nVector similarity is computed first Metadata filter is applied to the similarity results Results are sorted and limited For best performance:\nUse indexed metadata fields when possible Keep metadata values relatively small (under 1KB per document) Consider using IDs instead of full names for filtering Error Handling# Missing One Parameter# # Missing metadata_value curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata_path and metadata_value must be used together\u0026#34; }Non-Existent Metadata Field# # Filtering on field that doesn\u0026#39;t exist in documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?count=10\u0026amp;metadata_path=nonexistent_field\u0026amp;metadata_value=some_value\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Result: Returns all matching documents (since none have the field, none are excluded).\nURL Encoding# Remember to URL-encode metadata values with special characters:\n# Correct: URL-encoded value curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026amp;metadata_value=John%20Doe%20%26%20Jane%20Smith\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Incorrect: Unencoded special characters curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026amp;metadata_value=John Doe \u0026amp; Jane Smith\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Complete Example# Here\u0026rsquo;s a complete workflow demonstrating metadata filtering:\n# 1. Create project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/literature\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literature\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39; # 2. Upload documents with metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literature\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy_1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;All happy families...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Anna Karenina\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy_2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.11, 0.21, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;It was the best of times...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;War and Peace\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;dickens_1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.12, 0.19, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;It was the age of wisdom...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Dickens\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Tale of Two Cities\u0026#34;} } ] }\u0026#39; # 3. Find similar to tolstoy_1, excluding Tolstoy\u0026#39;s works curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/literature/tolstoy_1?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=Tolstoy\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Result: Returns dickens_1, excludes tolstoy_2Related Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Schema validation Batch Operations Guide - Upload large datasets Troubleshooting# No Results Returned# Problem: Filter excludes all results\nSolution:\nVerify the metadata field exists in your documents Check that the metadata value matches exactly (case-sensitive) Try without the filter to ensure there are similar documents Filter Not Working# Problem: Still seeing documents you want to exclude\nSolution:\nCheck URL encoding of the metadata value Verify the metadata path is correct (use dot notation for nested fields) Ensure both metadata_path and metadata_value are specified Want Positive Matching# Problem: Want to include only specific values, not exclude them\nSolution: Currently, only negative matching (exclusion) is supported. For positive matching, retrieve all results and filter on the client side, or use multiple negative filters to exclude everything except your target values.\n"},{"id":40,"href":"/dhamps-vdb/concepts/similarity-search/","title":"Similarity Search","section":"Concepts","content":"Similarity Search# Find documents with similar semantic meaning using vector similarity.\nHow it Works# Similarity search compares embedding vectors using cosine distance:\nQuery vector: Either from stored embedding or raw vector Comparison: Calculate cosine similarity with all project embeddings Filtering: Apply threshold and metadata filters Ranking: Sort by similarity score (highest first) Return: Top N most similar documents Search Methods# Stored Document Search (GET)# Find documents similar to an already-stored embedding:\nGET /v1/similars/alice/research/doc1?count=10\u0026amp;threshold=0.7Use cases:\nFind related documents Discover similar passages Identify duplicates Raw Vector Search (POST)# Search using a new embedding without storing it:\nPOST /v1/similars/alice/research?count=10\u0026amp;threshold=0.7 { \u0026#34;vector\u0026#34;: [0.023, -0.015, ..., 0.042] }Use cases:\nQuery without saving Test embeddings Real-time search Query Parameters# count# Number of similar documents to return.\nType: Integer Range: 1-200 Default: 10 GET /v1/similars/alice/project/doc1?count=5threshold# Minimum similarity score (0-1).\nType: Float Range: 0.0-1.0 Default: 0.5 Meaning: 1.0 = identical, 0.0 = unrelated GET /v1/similars/alice/project/doc1?threshold=0.8limit# Maximum number of results (same as count).\nType: Integer Range: 1-200 Default: 10 offset# Skip first N results (pagination).\nType: Integer Minimum: 0 Default: 0 # First page GET /v1/similars/alice/project/doc1?limit=10\u0026amp;offset=0 # Second page GET /v1/similars/alice/project/doc1?limit=10\u0026amp;offset=10metadata_path# JSON path to metadata field for filtering.\nType: String Purpose: Specify metadata field to filter Must be used with: metadata_value ?metadata_path=authormetadata_value# Value to exclude from results.\nType: String Purpose: Exclude documents matching this value Must be used with: metadata_path ?metadata_path=author\u0026amp;metadata_value=ShakespeareImportant: Excludes matches, doesn\u0026rsquo;t include them.\nSimilarity Scores# Cosine Similarity# dhamps-vdb uses cosine similarity:\nsimilarity = 1 - cosine_distanceScore ranges:\n1.0: Identical vectors 0.9-1.0: Very similar 0.7-0.9: Similar 0.5-0.7: Somewhat similar \u0026lt;0.5: Not similar Interpreting Scores# Typical thresholds:\n0.9+: Duplicates or near-duplicates 0.8+: Strong semantic similarity 0.7+: Related topics 0.5-0.7: Weak relation \u0026lt;0.5: Unrelated Optimal threshold depends on your use case and model.\nMetadata Filtering# Exclude by Field# Exclude documents where metadata field matches value:\n# Exclude documents from same author GET /v1/similars/alice/lit-study/hamlet-act1?metadata_path=author\u0026amp;metadata_value=ShakespeareResult: Returns similar documents, excluding those with metadata.author == \u0026quot;Shakespeare\u0026quot;.\nNested Fields# Use dot notation for nested metadata:\n# Exclude documents from same author.name GET /v1/similars/alice/project/doc1?metadata_path=author.name\u0026amp;metadata_value=John%20DoeCommon Patterns# Exclude same work:\n?metadata_path=title\u0026amp;metadata_value=HamletExclude same source:\n?metadata_path=source_id\u0026amp;metadata_value=corpus-AExclude same category:\n?metadata_path=category\u0026amp;metadata_value=tutorialSee Metadata Filtering Guide for details.\nResponse Format# { \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc5\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc8\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Fields:\nuser_handle: Project owner project_handle: Project identifier results: Array of similar documents id: Document text_id similarity: Similarity score (0-1) Results are sorted by similarity (highest first).\nPerformance# Query Speed# Typical performance:\n\u0026lt;10K embeddings: \u0026lt;10ms 10K-100K embeddings: 10-50ms 100K-1M embeddings: 50-200ms \u0026gt;1M embeddings: 200-1000ms Optimization# HNSW Index:\nFaster queries than IVFFlat Better recall Larger index size Query optimization:\nUse appropriate threshold (higher = fewer results) Limit result count (lower = faster) Consider dimension reduction for large projects Scaling# For large datasets:\nMonitor query performance Consider read replicas Use connection pooling Cache frequent queries (application level) Common Use Cases# RAG Workflow# Retrieval Augmented Generation:\n# 1. User query query=\u0026#34;What is machine learning?\u0026#34; # 2. Generate query embedding (external) query_vector=[...] # 3. Find similar documents POST /v1/similars/alice/knowledge-base?count=5\u0026amp;threshold=0.7 {\u0026#34;vector\u0026#34;: $query_vector} # 4. Retrieve full text for top results for each result: GET /v1/embeddings/alice/knowledge-base/$result_id # 5. Send context to LLM for generationDuplicate Detection# Find near-duplicate documents:\n# High threshold for duplicates GET /v1/similars/alice/corpus/doc1?count=10\u0026amp;threshold=0.95Documents with similarity \u0026gt; 0.95 are likely duplicates.\nContent Discovery# Find related content:\n# Moderate threshold for recommendations GET /v1/similars/alice/articles/article1?count=10\u0026amp;threshold=0.7\u0026amp;metadata_path=article_id\u0026amp;metadata_value=article1Excludes the source article itself.\nTopic Clustering# Find documents on similar topics:\n# For each document, find similar ones for doc in documents: GET /v1/similars/alice/corpus/$doc?count=20\u0026amp;threshold=0.8Group documents by similarity for clustering.\nDimension Consistency# Automatic Filtering# Similarity queries only compare embeddings with matching dimensions:\nProject embeddings: - doc1: 3072 dimensions - doc2: 3072 dimensions - doc3: 1536 dimensions (different model) Query for doc1 similars: → Only compares with doc2 → Ignores doc3 (dimension mismatch)Multiple Instances# Projects can have embeddings from multiple instances (if dimensions match):\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector_dim\u0026#34;: 3072 } { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;vector_dim\u0026#34;: 3072 }Both searchable together (same dimensions).\nAccess Control# Authentication# Similarity search respects project access control:\nOwner: Full access Editor: Can search (read permission) Reader: Can search (read permission) Public (if public_read=true): Can search (no auth required)\nPublic Projects# Public projects allow unauthenticated similarity search:\n# No Authorization header needed GET /v1/similars/alice/public-project/doc1?count=10See Public Projects Guide.\nLimitations# Current Constraints# No cross-project search: Similarity search is per-project only No filtering by multiple metadata fields: One field at a time No custom distance metrics: Cosine similarity only No approximate search tuning: Uses default HNSW parameters Workarounds# Cross-project search:\nQuery each project separately Merge results in application Multiple metadata filters:\nFilter by one field in query Apply additional filters in application Troubleshooting# No Results Returned# Possible causes:\nThreshold too high No embeddings in project Dimension mismatch All results filtered by metadata Solutions:\nLower threshold (try 0.5) Verify embeddings exist Check dimensions match Remove metadata filter Unexpected Results# Possible causes:\nThreshold too low Poor quality embeddings Incorrect model used Metadata filter excluding desired results Solutions:\nIncrease threshold Regenerate embeddings Verify correct model/dimensions Adjust metadata filter Slow Queries# Possible causes:\nLarge dataset (\u0026gt;100K embeddings) No vector index High result count Complex metadata filtering Solutions:\nReduce result count Check index exists Optimize database Use read replicas Next Steps# Learn about metadata filtering Understand RAG workflows Explore embeddings "},{"id":41,"href":"/dhamps-vdb/api/endpoints/similars/","title":"Similars","section":"Endpoints","content":"Similarity Search Endpoints# Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.\nEndpoints# GET Similar Documents (from stored embeddings)# Find documents similar to an already-stored document by its text identifier.\nEndpoint: GET /v1/similars/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters:\ncount (integer, optional, default: 10, max: 200): Number of similar documents to return threshold (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold limit (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for count) offset (integer, optional, default: 0): Pagination offset metadata_path (string, optional): Metadata field path for filtering (must be used with metadata_value) metadata_value (string, optional): Metadata value to exclude from results (must be used with metadata_path) Example - Basic search:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Example - With metadata filtering:\n# Exclude documents with author=\u0026#34;John Doe\u0026#34; curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/SimilarResponseBody.json\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc321\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] } POST Similar Documents (from raw embeddings)# Find similar documents by submitting a raw embedding vector without storing it in the database. Useful for one-time queries or testing.\nEndpoint: POST /v1/similars/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters: Same as GET endpoint above\nRequest Body:\n{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003, ...] }The vector must be an array of float values with dimensions matching the project\u0026rsquo;s LLM service instance configuration.\nExample - Basic search:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026amp;threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] }\u0026#39;Example - With metadata filtering:\n# Exclude documents from the same category curl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=5\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...] }\u0026#39;Response: Same format as GET endpoint\nQuery Parameters Reference# count / limit# Maximum number of similar documents to return.\nType: Integer Default: 10 Max: 200 Note: count and limit are aliases; use either one Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026#34; threshold# Minimum similarity score threshold. Only documents with similarity scores \u0026gt;= threshold are returned.\nType: Float Default: 0.5 Range: 0.0 to 1.0 (where 1.0 is most similar) Example:\n# Only return very similar documents (\u0026gt;= 0.8) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8\u0026#34; offset# Pagination offset for large result sets.\nType: Integer Default: 0 Use: Skip the first N results Example:\n# Get results 21-40 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=20\u0026#34; metadata_path# Metadata field path for filtering results. Must be used together with metadata_value.\nType: String Format: JSON path notation (e.g., \u0026quot;author\u0026quot;, \u0026quot;author.name\u0026quot;, \u0026quot;publication.year\u0026quot;) Use: Exclude documents where metadata field matches a specific value Examples:\n# Simple field metadata_path=author # Nested field metadata_path=author.name # Deeply nested field metadata_path=publication.journal.name metadata_value# Metadata value to exclude from results. Must be used together with metadata_path.\nType: String Use: Excludes documents where the metadata field at metadata_path equals this value Example - Exclude same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=Alice%20Doe\u0026#34;Example - Exclude same category:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=research\u0026#34;Example - Nested field:\n# Exclude documents from same author ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id\u0026amp;metadata_value=A0083\u0026#34; Response Format# Both GET and POST endpoints return the same response format:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/SimilarResponseBody.json\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc321\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Response Fields:\n$schema (string): JSON schema reference user_handle (string): Project owner\u0026rsquo;s username project_handle (string): Project identifier results (array): Array of similar documents, ordered by similarity (highest first) id (string): Document text identifier similarity (float): Cosine similarity score (0-1, where 1 is most similar) Similarity Calculation# Cosine Distance# The API uses cosine distance (or equivalently, cosine similarity) to calculate vector similarity:\nRange: 0 to 1 1.0: Identical vectors 0.0: Orthogonal vectors (completely dissimilar) Higher values: More similar documents Dimension Filtering# The system automatically filters results to only include embeddings with matching dimensions. This ensures:\nOnly embeddings with matching vector_dim are compared Only embeddings from the same project are considered Invalid comparisons are prevented Dimension Validation (POST only)# When using the POST endpoint with raw embeddings, the API validates:\nThe project has an associated LLM service instance The submitted vector dimensions match the instance\u0026rsquo;s configured dimensions If dimensions don\u0026rsquo;t match, a 400 Bad Request error is returned Error example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector dimension mismatch: expected 1536 dimensions, got 768\u0026#34; } Metadata Filtering# Both endpoints support metadata filtering to exclude documents based on metadata field values. This uses negative matching (excludes documents where the field matches the value).\nUse Cases# Exclude documents from the same source:\n# When finding similar documents to doc123, exclude others from the same author curl -X GET \u0026#34;.../similars/alice/research-docs/doc123?metadata_path=author_id\u0026amp;metadata_value=A0083\u0026#34;Exclude documents from the same category:\n# Find similar documents in other categories curl -X GET \u0026#34;.../similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=biology\u0026#34;Exclude documents with the same tag:\n# Find documents with similar content but different tags curl -X POST \u0026#34;.../similars/alice/research-docs?metadata_path=primary_tag\u0026amp;metadata_value=machine-learning\u0026#34; \\ -d \u0026#39;{\u0026#34;vector\u0026#34;: [...]}\u0026#39;Nested Field Access# Use dot notation for nested metadata fields:\n# Exclude documents from the same author (nested field) metadata_path=author.id\u0026amp;metadata_value=author-123 # Exclude documents from the same publication year metadata_path=publication.year\u0026amp;metadata_value=2024 # Deeply nested field metadata_path=source.journal.publisher\u0026amp;metadata_value=Springer Examples# Basic Similarity Search# Find 5 most similar documents with at least 0.7 similarity:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Search with Raw Vector# Submit a vector without storing it:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] }\u0026#39; Search with Metadata Filtering# Find similar documents but exclude those from the same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Paginated Results# Get the next page of results:\n# Page 1 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=0\u0026#34; # Page 2 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=20\u0026#34; # Page 3 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=40\u0026#34; Complex Query# High threshold, metadata filtering, and pagination:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=50\u0026amp;threshold=0.9\u0026amp;offset=0\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Common Errors# 400 Bad Request - Dimension Mismatch (POST only)# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector dimension mismatch: expected 1536 dimensions, got 768\u0026#34; }400 Bad Request - Missing metadata_value# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata_path requires metadata_value to be specified\u0026#34; }400 Bad Request - Invalid threshold# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;threshold must be between 0.0 and 1.0\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to search this project\u0026#34; }404 Not Found - Project# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }404 Not Found - Embedding (GET only)# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; } Performance Considerations# Indexing# The database uses vector indexes for efficient similarity search. See the database migrations for index configuration.\nResult Limits# Default limit: 10 results Maximum limit: 200 results Use pagination for large result sets Threshold Optimization# Higher thresholds reduce result set size and improve performance:\n0.5-0.7: Broad similarity (default) 0.7-0.85: Moderate similarity 0.85-0.95: High similarity 0.95-1.0: Near-identical documents Related Documentation# Embeddings - Storing embeddings for similarity search Projects - Project configuration Query Parameters - Complete parameter reference Error Handling - Error response format "},{"id":42,"href":"/dhamps-vdb/guides/batch-operations/","title":"Batch Operations Guide","section":"Guides","content":"Batch Operations Guide# This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.\nOverview# For production workloads and large datasets, efficient batch operations are essential. This guide covers:\nUploading multiple embeddings in a single request Pagination strategies for large result sets Best practices for performance and reliability Error handling in batch operations Batch Upload Basics# Single Request with Multiple Embeddings# Upload multiple embeddings in one API call using the embeddings array:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;First document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.11, 0.21, 0.31, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Second document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;history\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc003\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.12, 0.22, 0.32, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Third document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;literature\u0026#34;} } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embeddings uploaded successfully\u0026#34;, \u0026#34;count\u0026#34;: 3 }Optimal Batch Sizes# Recommended Batch Sizes# Based on typical embedding dimensions and network constraints:\nEmbedding Dimensions Recommended Batch Size Maximum Batch Size 384 (small models) 500-1000 2000 768 (BERT-base) 300-500 1000 1536 (OpenAI small) 100-300 500 3072 (OpenAI large) 50-100 200 Factors to consider:\nNetwork bandwidth and latency API gateway timeout limits Database transaction size Memory constraints Client-side serialization limits Finding Your Optimal Batch Size# Test different batch sizes to find the sweet spot:\nimport time import requests def test_batch_size(embeddings, batch_size): \u0026#34;\u0026#34;\u0026#34;Test upload performance with given batch size\u0026#34;\u0026#34;\u0026#34; start_time = time.time() for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status() elapsed = time.time() - start_time throughput = len(embeddings) / elapsed print(f\u0026#34;Batch size {batch_size}: {throughput:.1f} embeddings/sec\u0026#34;) # Test different batch sizes for size in [50, 100, 200, 500]: test_batch_size(my_embeddings, size)Pagination for Large Datasets# Retrieving All Embeddings with Pagination# Use limit and offset parameters to paginate through large result sets:\n# Get first page (embeddings 0-99) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get second page (embeddings 100-199) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=100\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get third page (embeddings 200-299) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=200\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Pagination Best Practices# Default Values:\nlimit: 10 (if not specified) offset: 0 (if not specified) Maximum limit: 200 Example: Download Entire Project\nimport requests def download_all_embeddings(owner, project): \u0026#34;\u0026#34;\u0026#34;Download all embeddings from a project\u0026#34;\u0026#34;\u0026#34; all_embeddings = [] offset = 0 limit = 100 while True: response = requests.get( f\u0026#34;https://api.example.com/v1/embeddings/{owner}/{project}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: \u0026#34;Bearer api_key\u0026#34;}, params={\u0026#34;limit\u0026#34;: limit, \u0026#34;offset\u0026#34;: offset} ) response.raise_for_status() batch = response.json()[\u0026#39;embeddings\u0026#39;] if not batch: break # No more results all_embeddings.extend(batch) offset += len(batch) print(f\u0026#34;Downloaded {len(all_embeddings)} embeddings...\u0026#34;) return all_embeddings # Usage embeddings = download_all_embeddings(\u0026#34;alice\u0026#34;, \u0026#34;my-project\u0026#34;) print(f\u0026#34;Total: {len(embeddings)} embeddings\u0026#34;)Efficient Batch Upload Strategies# Strategy 1: Simple Sequential Upload# Good for small to medium datasets (\u0026lt; 10,000 embeddings):\ndef upload_sequential(embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload embeddings sequentially in batches\u0026#34;\u0026#34;\u0026#34; for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status() print(f\u0026#34;Uploaded batch {i//batch_size + 1}, total: {i+len(batch)}\u0026#34;)Strategy 2: Parallel Upload with Threading# Good for larger datasets with stable network:\nimport concurrent.futures import requests def upload_batch(batch, batch_num): \u0026#34;\u0026#34;\u0026#34;Upload a single batch\u0026#34;\u0026#34;\u0026#34; try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return batch_num, True, None except Exception as e: return batch_num, False, str(e) def upload_parallel(embeddings, batch_size=100, max_workers=4): \u0026#34;\u0026#34;\u0026#34;Upload embeddings in parallel\u0026#34;\u0026#34;\u0026#34; batches = [ embeddings[i:i+batch_size] for i in range(0, len(embeddings), batch_size) ] failed = [] with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = { executor.submit(upload_batch, batch, i): i for i, batch in enumerate(batches) } for future in concurrent.futures.as_completed(futures): batch_num, success, error = future.result() if success: print(f\u0026#34;✓ Batch {batch_num+1}/{len(batches)} uploaded\u0026#34;) else: print(f\u0026#34;✗ Batch {batch_num+1} failed: {error}\u0026#34;) failed.append((batch_num, batches[batch_num])) return failed # Usage failed_batches = upload_parallel(my_embeddings, batch_size=100, max_workers=4) if failed_batches: print(f\u0026#34;Failed batches: {len(failed_batches)}\u0026#34;)Strategy 3: Retry with Exponential Backoff# Robust strategy for unreliable networks:\nimport time import random def upload_with_retry(batch, max_retries=3): \u0026#34;\u0026#34;\u0026#34;Upload batch with exponential backoff retry\u0026#34;\u0026#34;\u0026#34; for attempt in range(max_retries): try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return True except requests.exceptions.RequestException as e: if attempt \u0026lt; max_retries - 1: wait = (2 ** attempt) + random.uniform(0, 1) print(f\u0026#34;Retry attempt {attempt+1} after {wait:.1f}s: {e}\u0026#34;) time.sleep(wait) else: print(f\u0026#34;Failed after {max_retries} attempts: {e}\u0026#34;) return False def upload_robust(embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload with robust error handling\u0026#34;\u0026#34;\u0026#34; failed = [] for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] if not upload_with_retry(batch): failed.append((i, batch)) else: print(f\u0026#34;✓ Uploaded {i+batch_size}/{len(embeddings)}\u0026#34;) return failedProgress Tracking and Resumability# Checkpoint-Based Upload# For very large datasets, implement checkpointing to resume after failures:\nimport json import os class CheckpointUploader: def __init__(self, checkpoint_file=\u0026#34;upload_progress.json\u0026#34;): self.checkpoint_file = checkpoint_file self.progress = self.load_progress() def load_progress(self): \u0026#34;\u0026#34;\u0026#34;Load upload progress from checkpoint file\u0026#34;\u0026#34;\u0026#34; if os.path.exists(self.checkpoint_file): with open(self.checkpoint_file, \u0026#39;r\u0026#39;) as f: return json.load(f) return {\u0026#34;uploaded_count\u0026#34;: 0, \u0026#34;failed_batches\u0026#34;: []} def save_progress(self): \u0026#34;\u0026#34;\u0026#34;Save current progress\u0026#34;\u0026#34;\u0026#34; with open(self.checkpoint_file, \u0026#39;w\u0026#39;) as f: json.dump(self.progress, f) def upload(self, embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload with checkpointing\u0026#34;\u0026#34;\u0026#34; start_idx = self.progress[\u0026#34;uploaded_count\u0026#34;] for i in range(start_idx, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() self.progress[\u0026#34;uploaded_count\u0026#34;] = i + len(batch) self.save_progress() print(f\u0026#34;✓ Progress: {self.progress[\u0026#39;uploaded_count\u0026#39;]}/{len(embeddings)}\u0026#34;) except Exception as e: print(f\u0026#34;✗ Failed at index {i}: {e}\u0026#34;) self.progress[\u0026#34;failed_batches\u0026#34;].append(i) self.save_progress() raise # Usage uploader = CheckpointUploader() try: uploader.upload(my_embeddings, batch_size=100) print(\u0026#34;Upload complete!\u0026#34;) except: print(\u0026#34;Upload interrupted. Run again to resume.\u0026#34;)Error Handling# Validation Errors# If any embedding in a batch fails validation, the entire batch is rejected:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Bob\u0026#34;} } ] }\u0026#39;Error Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector length mismatch for text_id \u0026#39;doc002\u0026#39;: actual vector has 2 elements but vector_dim declares 3072\u0026#34; }Solution: Validate all embeddings before batching, or handle errors and retry failed items.\nPre-Upload Validation# def validate_embeddings(embeddings, expected_dim): \u0026#34;\u0026#34;\u0026#34;Validate embeddings before upload\u0026#34;\u0026#34;\u0026#34; errors = [] for i, emb in enumerate(embeddings): # Check vector length if len(emb[\u0026#39;vector\u0026#39;]) != expected_dim: errors.append(f\u0026#34;Index {i} (text_id: {emb[\u0026#39;text_id\u0026#39;]}): \u0026#34; f\u0026#34;vector length {len(emb[\u0026#39;vector\u0026#39;])} != {expected_dim}\u0026#34;) # Check declared dimension if emb.get(\u0026#39;vector_dim\u0026#39;) != expected_dim: errors.append(f\u0026#34;Index {i} (text_id: {emb[\u0026#39;text_id\u0026#39;]}): \u0026#34; f\u0026#34;vector_dim {emb.get(\u0026#39;vector_dim\u0026#39;)} != {expected_dim}\u0026#34;) # Check required fields if not emb.get(\u0026#39;text_id\u0026#39;): errors.append(f\u0026#34;Index {i}: missing text_id\u0026#34;) if not emb.get(\u0026#39;instance_handle\u0026#39;): errors.append(f\u0026#34;Index {i}: missing instance_handle\u0026#34;) return errors # Usage errors = validate_embeddings(my_embeddings, 3072) if errors: print(\u0026#34;Validation errors:\u0026#34;) for error in errors: print(f\u0026#34; - {error}\u0026#34;) else: print(\u0026#34;All embeddings valid, proceeding with upload...\u0026#34;)Performance Optimization Tips# 1. Minimize Payload Size# Exclude unnecessary fields:\n# Include text only if needed for retrieval embeddings_with_text = [ { \u0026#34;text_id\u0026#34;: doc_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: text, # Include if needed \u0026#34;metadata\u0026#34;: metadata } for doc_id, vector, text, metadata in documents ] # Exclude text if not needed (smaller payload) embeddings_without_text = [ { \u0026#34;text_id\u0026#34;: doc_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: metadata } for doc_id, vector, metadata in documents ]2. Compress Requests# Use gzip compression for large payloads:\nimport gzip import json def upload_compressed(embeddings): \u0026#34;\u0026#34;\u0026#34;Upload with gzip compression\u0026#34;\u0026#34;\u0026#34; payload = json.dumps({\u0026#34;embeddings\u0026#34;: embeddings}) compressed = gzip.compress(payload.encode(\u0026#39;utf-8\u0026#39;)) response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34;, \u0026#34;Content-Encoding\u0026#34;: \u0026#34;gzip\u0026#34; }, data=compressed ) return response3. Use Connection Pooling# Reuse HTTP connections for multiple requests:\nsession = requests.Session() session.headers.update({ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }) for batch in batches: response = session.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status()4. Monitor Upload Rate# Track and display upload progress:\nimport time class ProgressTracker: def __init__(self, total): self.total = total self.uploaded = 0 self.start_time = time.time() def update(self, count): self.uploaded += count elapsed = time.time() - self.start_time rate = self.uploaded / elapsed if elapsed \u0026gt; 0 else 0 percent = (self.uploaded / self.total) * 100 eta = (self.total - self.uploaded) / rate if rate \u0026gt; 0 else 0 print(f\u0026#34;\\rProgress: {self.uploaded}/{self.total} ({percent:.1f}%) \u0026#34; f\u0026#34;Rate: {rate:.1f} emb/s ETA: {eta:.0f}s\u0026#34;, end=\u0026#34;\u0026#34;) # Usage tracker = ProgressTracker(len(all_embeddings)) for batch in batches: upload_batch(batch) tracker.update(len(batch)) print() # New line after completionComplete Example: Production-Grade Uploader# import requests import time import json import logging from concurrent.futures import ThreadPoolExecutor, as_completed from typing import List, Dict, Tuple class ProductionUploader: def __init__(self, api_base: str, api_key: str, owner: str, project: str): self.api_base = api_base self.api_key = api_key self.owner = owner self.project = project self.session = requests.Session() self.session.headers.update({ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }) logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger(__name__) def upload_batch(self, batch: List[Dict], batch_num: int, max_retries: int = 3) -\u0026gt; Tuple[int, bool, str]: \u0026#34;\u0026#34;\u0026#34;Upload a single batch with retry logic\u0026#34;\u0026#34;\u0026#34; url = f\u0026#34;{self.api_base}/v1/embeddings/{self.owner}/{self.project}\u0026#34; for attempt in range(max_retries): try: response = self.session.post( url, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return batch_num, True, \u0026#34;\u0026#34; except Exception as e: if attempt \u0026lt; max_retries - 1: wait = 2 ** attempt self.logger.warning( f\u0026#34;Batch {batch_num} attempt {attempt+1} failed: {e}. \u0026#34; f\u0026#34;Retrying in {wait}s...\u0026#34; ) time.sleep(wait) else: return batch_num, False, str(e) def upload(self, embeddings: List[Dict], batch_size: int = 100, max_workers: int = 4) -\u0026gt; Dict: \u0026#34;\u0026#34;\u0026#34;Upload embeddings with parallel processing and progress tracking\u0026#34;\u0026#34;\u0026#34; batches = [ embeddings[i:i+batch_size] for i in range(0, len(embeddings), batch_size) ] results = { \u0026#34;total\u0026#34;: len(embeddings), \u0026#34;uploaded\u0026#34;: 0, \u0026#34;failed\u0026#34;: [], \u0026#34;start_time\u0026#34;: time.time() } self.logger.info(f\u0026#34;Uploading {len(embeddings)} embeddings in \u0026#34; f\u0026#34;{len(batches)} batches...\u0026#34;) with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = { executor.submit(self.upload_batch, batch, i): i for i, batch in enumerate(batches) } for future in as_completed(futures): batch_num, success, error = future.result() if success: results[\u0026#34;uploaded\u0026#34;] += len(batches[batch_num]) percent = (results[\u0026#34;uploaded\u0026#34;] / results[\u0026#34;total\u0026#34;]) * 100 self.logger.info( f\u0026#34;✓ Batch {batch_num+1}/{len(batches)} \u0026#34; f\u0026#34;({percent:.1f}% complete)\u0026#34; ) else: results[\u0026#34;failed\u0026#34;].append({ \u0026#34;batch_num\u0026#34;: batch_num, \u0026#34;error\u0026#34;: error, \u0026#34;embeddings\u0026#34;: batches[batch_num] }) self.logger.error(f\u0026#34;✗ Batch {batch_num+1} failed: {error}\u0026#34;) results[\u0026#34;elapsed\u0026#34;] = time.time() - results[\u0026#34;start_time\u0026#34;] results[\u0026#34;rate\u0026#34;] = results[\u0026#34;uploaded\u0026#34;] / results[\u0026#34;elapsed\u0026#34;] self.logger.info( f\u0026#34;\\nUpload complete: {results[\u0026#39;uploaded\u0026#39;]}/{results[\u0026#39;total\u0026#39;]} \u0026#34; f\u0026#34;in {results[\u0026#39;elapsed\u0026#39;]:.1f}s ({results[\u0026#39;rate\u0026#39;]:.1f} emb/s)\u0026#34; ) if results[\u0026#34;failed\u0026#34;]: self.logger.warning(f\u0026#34;Failed batches: {len(results[\u0026#39;failed\u0026#39;])}\u0026#34;) return results # Usage uploader = ProductionUploader( api_base=\u0026#34;https://api.example.com\u0026#34;, api_key=\u0026#34;alice_api_key\u0026#34;, owner=\u0026#34;alice\u0026#34;, project=\u0026#34;my-project\u0026#34; ) results = uploader.upload( embeddings=my_embeddings, batch_size=100, max_workers=4 ) # Save failed batches for retry if results[\u0026#34;failed\u0026#34;]: with open(\u0026#34;failed_batches.json\u0026#34;, \u0026#34;w\u0026#34;) as f: json.dump(results[\u0026#34;failed\u0026#34;], f)Best Practices Summary# Batch Size: Test to find optimal size (typically 50-500 depending on dimensions) Parallelism: Use 2-8 parallel workers for large uploads Retry Logic: Implement exponential backoff for network errors Validation: Pre-validate embeddings before upload Progress Tracking: Monitor upload rate and ETA Checkpointing: Save progress for resumable uploads Error Logging: Log all errors with sufficient context Connection Reuse: Use session objects for connection pooling Compression: Use gzip for large payloads Testing: Test with small batches before full upload Related Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Schema validation Instance Management Guide - Managing LLM instances Troubleshooting# Timeout Errors# Problem: Requests timing out with large batches\nSolution: Reduce batch size or increase timeout value\nMemory Issues# Problem: Out of memory when processing large datasets\nSolution: Process embeddings in streaming fashion, don\u0026rsquo;t load all into memory\nRate Limiting# Problem: Getting rate limited by API\nSolution: Reduce parallelism (max_workers) or add delays between requests\n"},{"id":43,"href":"/dhamps-vdb/concepts/metadata/","title":"Metadata","section":"Concepts","content":"Metadata# Structured JSON data attached to embeddings for organization, validation, and filtering.\nOverview# Metadata provides context and structure for your embeddings:\nOrganization: Categorize and group documents Filtering: Exclude documents in similarity searches Validation: Ensure consistent structure (optional) Context: Store additional document information Metadata Structure# Format# Metadata is JSON stored as JSONB in PostgreSQL:\n{ \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34; }Types# Supported JSON types:\nString: \u0026quot;author\u0026quot;: \u0026quot;Shakespeare\u0026quot; Number: \u0026quot;year\u0026quot;: 1603 Boolean: \u0026quot;published\u0026quot;: true Array: \u0026quot;tags\u0026quot;: [\u0026quot;tragedy\u0026quot;, \u0026quot;revenge\u0026quot;] Object: \u0026quot;author\u0026quot;: {\u0026quot;name\u0026quot;: \u0026quot;...\u0026quot;, \u0026quot;id\u0026quot;: \u0026quot;...\u0026quot;} Null: \u0026quot;notes\u0026quot;: null Nested Structure# Complex hierarchies are supported:\n{ \u0026#34;document\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;W0017\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;manuscript\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;John Milton\u0026#34;, \u0026#34;birth_year\u0026#34;: 1608, \u0026#34;nationality\u0026#34;: \u0026#34;English\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 1667, \u0026#34;publisher\u0026#34;: \u0026#34;First Edition\u0026#34;, \u0026#34;location\u0026#34;: \u0026#34;London\u0026#34; }, \u0026#34;tags\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;epic\u0026#34;, \u0026#34;religious\u0026#34;] }Metadata Schemas# Purpose# JSON Schema validation ensures consistent metadata across all project embeddings.\nDefining a Schema# Include metadataScheme when creating/updating project:\nPOST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }Schema Format# Use JSON Schema (draft-07+):\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1 }, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1000, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;prose\u0026#34;, \u0026#34;drama\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;, \u0026#34;year\u0026#34;] }Validation Behavior# With schema defined:\nAll embeddings validated on upload Invalid metadata rejected with detailed error Schema enforced consistently Without schema:\nAny JSON metadata accepted No validation performed Maximum flexibility Common Patterns# See Metadata Validation Guide for examples.\nUsing Metadata# On Upload# Include metadata with each embedding:\nPOST /v1/embeddings/alice/research { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603 } } ] }In Responses# Metadata returned when retrieving embeddings:\nGET /v1/embeddings/alice/research/doc1{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603 }, \u0026#34;vector\u0026#34;: [...], ... }Metadata Filtering# Exclusion Filter# Exclude documents where metadata matches value:\nGET /v1/similars/alice/research/doc1?metadata_path=author\u0026amp;metadata_value=ShakespeareResult: Returns similar documents excluding those with metadata.author == \u0026quot;Shakespeare\u0026quot;.\nPath Syntax# Use JSON path notation:\nSimple field:\nmetadata_path=authorNested field:\nmetadata_path=author.nameArray element (not currently supported):\nmetadata_path=tags[0]URL Encoding# Encode special characters:\n# Space metadata_value=John%20Doe # Quotes (if needed) metadata_value=%22quoted%20value%22Use Cases# Exclude same work:\n?metadata_path=title\u0026amp;metadata_value=HamletExclude same author:\n?metadata_path=author\u0026amp;metadata_value=ShakespeareExclude same source:\n?metadata_path=source_id\u0026amp;metadata_value=corpus-aExclude same category:\n?metadata_path=category\u0026amp;metadata_value=draftSee Metadata Filtering Guide for detailed examples.\nValidation Examples# Simple Schema# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Valid metadata:\n{\u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;year\u0026#34;: 1603} {\u0026#34;author\u0026#34;: \u0026#34;Milton\u0026#34;}Invalid metadata:\n{\u0026#34;year\u0026#34;: 1603} // Missing required \u0026#39;author\u0026#39; {\u0026#34;author\u0026#34;: 123} // Wrong type (should be string)Schema with Constraints# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 200 }, \u0026#34;rating\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0, \u0026#34;maximum\u0026#34;: 5 }, \u0026#34;tags\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1, \u0026#34;maxItems\u0026#34;: 10 } } }Schema with Enums# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;language\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;en\u0026#34;, \u0026#34;de\u0026#34;, \u0026#34;fr\u0026#34;, \u0026#34;es\u0026#34;, \u0026#34;la\u0026#34;] }, \u0026#34;status\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;draft\u0026#34;, \u0026#34;review\u0026#34;, \u0026#34;published\u0026#34;] } } }Storage and Performance# Storage# Metadata stored as JSONB in PostgreSQL:\nEfficient: Binary storage format Indexable: Can create indexes on fields Queryable: Use PostgreSQL JSON operators Size Considerations# Typical metadata sizes:\nSimple: 50-200 bytes Moderate: 200-1000 bytes Complex: 1-5KB Very large: \u0026gt;5KB (consider storing elsewhere) Performance# Metadata filtering:\nJSONB queries are efficient Add indexes for frequently filtered fields Keep metadata reasonably sized Example index (if needed):\nCREATE INDEX idx_embeddings_author ON embeddings ((metadata-\u0026gt;\u0026gt;\u0026#39;author\u0026#39;));Common Patterns# Document Provenance# Track document source and history:\n{ \u0026#34;source\u0026#34;: { \u0026#34;corpus\u0026#34;: \u0026#34;Shakespeare Works\u0026#34;, \u0026#34;collection\u0026#34;: \u0026#34;Tragedies\u0026#34;, \u0026#34;document_id\u0026#34;: \u0026#34;hamlet\u0026#34;, \u0026#34;version\u0026#34;: 2 }, \u0026#34;imported_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34;, \u0026#34;imported_by\u0026#34;: \u0026#34;researcher1\u0026#34; }Hierarchical Documents# Structure for nested documents:\n{ \u0026#34;work\u0026#34;: \u0026#34;Paradise Lost\u0026#34;, \u0026#34;book\u0026#34;: 1, \u0026#34;line\u0026#34;: 1, \u0026#34;chapter\u0026#34;: null, \u0026#34;section\u0026#34;: \u0026#34;Invocation\u0026#34; }Multi-Language Content# Track language and translation info:\n{ \u0026#34;language\u0026#34;: \u0026#34;en\u0026#34;, \u0026#34;original_language\u0026#34;: \u0026#34;la\u0026#34;, \u0026#34;translated_by\u0026#34;: \u0026#34;John Smith\u0026#34;, \u0026#34;translation_year\u0026#34;: 1850 }Research Metadata# Academic paper metadata:\n{ \u0026#34;doi\u0026#34;: \u0026#34;10.1234/example.2024.001\u0026#34;, \u0026#34;authors\u0026#34;: [\u0026#34;Alice Smith\u0026#34;, \u0026#34;Bob Jones\u0026#34;], \u0026#34;journal\u0026#34;: \u0026#34;Digital Humanities Review\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;keywords\u0026#34;: [\u0026#34;NLP\u0026#34;, \u0026#34;embeddings\u0026#34;, \u0026#34;RAG\u0026#34;] }Updating Metadata# Current Limitation# Metadata cannot be updated directly. To change:\nDelete embedding Re-upload with updated metadata # Delete DELETE /v1/embeddings/alice/project/doc1 # Re-upload with new metadata POST /v1/embeddings/alice/project { \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;metadata\u0026#34;: {...updated...}, ... }] }Schema Updates# Updating Project Schema# Use PATCH to update schema:\nPATCH /v1/projects/alice/research { \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...new schema...}\u0026#34; }Effect on Existing Embeddings# Existing embeddings: Not revalidated New embeddings: Validated against new schema Updates: Validated against current schema Migration Strategy# When updating schema:\nUpdate project schema Verify new embeddings work Optionally re-upload existing embeddings Validation Errors# Common Errors# Missing required field:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: author is required\u0026#34; }Wrong type:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: year must be integer\u0026#34; }Enum violation:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: genre must be one of [poetry, prose, drama]\u0026#34; }Debugging# To debug validation errors:\nCheck project schema: GET /v1/projects/owner/project Validate metadata with online tool: jsonschemavalidator.net Review error message for specific field Update metadata or schema as needed Best Practices# Schema Design# Start simple, add complexity as needed Use required fields for critical data Use enums for controlled vocabularies Document your schema Metadata Content# Keep metadata focused and relevant Avoid redundant data Use consistent field names Consider future queries and filters Performance# Keep metadata reasonably sized (\u0026lt;5KB) Index frequently queried fields Avoid deeply nested structures when possible Troubleshooting# Validation Fails# Problem: Metadata doesn\u0026rsquo;t validate\nSolutions:\nCheck project schema Verify metadata structure Test with JSON Schema validator Review error message details Filtering Not Working# Problem: Metadata filter doesn\u0026rsquo;t exclude documents\nSolutions:\nVerify field path is correct Check value matches exactly (case-sensitive) URL-encode special characters Confirm metadata field exists Schema Too Restrictive# Problem: Cannot upload valid documents\nSolutions:\nMake fields optional (remove from required) Broaden type constraints Use oneOf for multiple valid formats Remove unnecessary validations Next Steps# Learn about metadata validation Explore metadata filtering Understand similarity search "},{"id":44,"href":"/dhamps-vdb/api/query-parameters/","title":"Query Parameters","section":"API Reference","content":"Query Parameters Reference# Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.\nPagination Parameters# limit# Maximum number of results to return in a single response.\nType: Integer\nDefault: 10\nMaximum: 200\nMinimum: 1\nUsed by:\nGET /v1/embeddings/{user}/{project} - List embeddings GET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search GET /v1/projects/{user} - List projects Example:\n# Get 50 embeddings curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Aliases:\ncount - Used in similarity search endpoints (same behavior as limit) offset# Number of results to skip before returning data. Used for pagination.\nType: Integer\nDefault: 0\nMinimum: 0\nUsed by:\nGET /v1/embeddings/{user}/{project} - List embeddings GET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search GET /v1/projects/{user} - List projects Example:\n# Get results 21-40 (page 2) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=20\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get results 41-60 (page 3) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=40\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Pagination Formula:\nPage N: offset = (N - 1) * limit Similarity Search Parameters# count# Number of similar documents to return. Alias for limit in similarity search endpoints.\nType: Integer\nDefault: 10\nMaximum: 200\nMinimum: 1\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Find 5 most similar documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Note: count and limit can be used interchangeably in similarity endpoints.\nthreshold# Minimum similarity score threshold. Only results with similarity \u0026gt;= threshold are returned.\nType: Float\nDefault: 0.5\nRange: 0.0 to 1.0\nNote: 1.0 = most similar, 0.0 = least similar\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Only return highly similar documents (\u0026gt;= 0.8) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Return moderately similar documents (\u0026gt;= 0.6) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.6\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Threshold Guidelines:\nThreshold Interpretation Use Case 0.95-1.0 Near-identical Duplicate detection 0.85-0.95 Very similar Finding closely related documents 0.7-0.85 Moderately similar Broad similarity search 0.5-0.7 Loosely similar Exploratory search 0.0-0.5 Weakly similar Generally not useful Metadata Filtering Parameters# metadata_path# JSON path to a metadata field for filtering results. Must be used together with metadata_value.\nType: String\nFormat: JSON path notation (e.g., \u0026quot;author\u0026quot;, \u0026quot;author.name\u0026quot;, \u0026quot;publication.year\u0026quot;)\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Path Notation:\nSimple field: author Nested field: author.name Deeply nested: publication.journal.name Example:\n# Simple field path curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; # Nested field path curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id\u0026amp;metadata_value=A0083\u0026#34; metadata_value# Metadata value to exclude from similarity search results. Must be used together with metadata_path.\nType: String\nBehavior: Negative matching (excludes documents where field equals this value)\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Exclude documents from the same author curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=Alice%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Exclude documents from the same category curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;URL Encoding:\nAlways URL-encode metadata values that contain special characters:\n# Value: \u0026#34;John Doe\u0026#34; → \u0026#34;John%20Doe\u0026#34; # Value: \u0026#34;2024-01-15\u0026#34; → \u0026#34;2024-01-15\u0026#34; (no special chars) # Value: \u0026#34;author@example.com\u0026#34; → \u0026#34;author%40example.com\u0026#34; Parameter Combinations# Pagination with Filtering# Combine limit, offset, and threshold:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=40\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search with Metadata Filtering# Combine threshold and metadata filtering:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;threshold=0.8\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Complete Query with All Parameters# curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=50\u0026amp;offset=0\u0026amp;threshold=0.75\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Endpoint-Specific Parameters# List Embeddings# Endpoint: GET /v1/embeddings/{user}/{project}\nSupported Parameters:\nlimit (default: 10, max: 200) offset (default: 0) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=200\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; List Projects# Endpoint: GET /v1/projects/{user}\nSupported Parameters:\nlimit (default: 10, max: 200) offset (default: 0) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice?limit=50\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search (GET)# Endpoint: GET /v1/similars/{user}/{project}/{id}\nSupported Parameters:\ncount / limit (default: 10, max: 200) offset (default: 0) threshold (default: 0.5, range: 0.0-1.0) metadata_path (optional, requires metadata_value) metadata_value (optional, requires metadata_path) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;threshold=0.7\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search (POST)# Endpoint: POST /v1/similars/{user}/{project}\nSupported Parameters: Same as GET similarity search\nExample:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026amp;threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...] }\u0026#39; Parameter Validation# Invalid Parameter Values# Error Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;limit must be between 1 and 200\u0026#34; }Common Validation Errors:\nlimit exceeds maximum (200) limit less than minimum (1) offset is negative threshold outside range 0.0-1.0 metadata_path without metadata_value metadata_value without metadata_path Best Practices# Pagination# Do:\nUse consistent limit values across pages Start with offset=0 for the first page Increment offset by limit for each subsequent page Example pagination logic:\nlimit = 20 page = 1 # Page 1 offset = (page - 1) * limit # 0 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; # Page 2 page = 2 offset = (page - 1) * limit # 20 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; # Page 3 page = 3 offset = (page - 1) * limit # 40 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; Similarity Search# Do:\nUse higher thresholds (0.7-0.9) for focused searches Use lower thresholds (0.5-0.7) for exploratory searches Combine with count to limit result size Use metadata filtering to exclude unwanted results Don\u0026rsquo;t:\nRequest more results than needed (affects performance) Use very low thresholds (\u0026lt;0.5) unless necessary Metadata Filtering# Do:\nURL-encode metadata values with special characters Use specific field paths for nested metadata Test metadata paths with sample queries first Example:\n# Good: URL-encoded, specific path metadata_path=author.id\u0026amp;metadata_value=A0083 # Good: Simple field metadata_path=category\u0026amp;metadata_value=biology # Bad: Not URL-encoded metadata_path=author name\u0026amp;metadata_value=John Doe # Good: URL-encoded metadata_path=author%20name\u0026amp;metadata_value=John%20Doe Response Formats# Paginated Response# Endpoints that support pagination typically return:\n{ \u0026#34;items\u0026#34;: [...], \u0026#34;total_count\u0026#34;: 500, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 40, \u0026#34;has_more\u0026#34;: true }Fields:\nitems: Array of results total_count: Total number of items available limit: Number of items requested per page offset: Current offset has_more: Boolean indicating if more results exist Similarity Response# Similarity endpoints return:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 } ] }Notes:\nResults are ordered by similarity (highest first) Only results \u0026gt;= threshold are included Maximum of count/limit results returned Filtered by metadata_path/metadata_value if specified Related Documentation# Embeddings - Embedding storage and retrieval Similars - Similarity search details Projects - Project management Error Handling - Error responses "},{"id":45,"href":"/dhamps-vdb/reference/","title":"Reference","section":"dhamps-vdb Documentation","content":"Reference Documentation# Technical reference materials and specifications.\nContents# Configuration Reference - Complete configuration options Database Schema - Database structure Roadmap - Planned features and improvements Additional Resources# OpenAPI Specification: Available at /openapi.yaml on any running instance Go Package Documentation: Coming soon Source Code: github.com/mpilhlt/dhamps-vdb "},{"id":46,"href":"/dhamps-vdb/guides/instance-management/","title":"Instance Management Guide","section":"Guides","content":"Instance Management Guide# This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.\nOverview# LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:\nAPI endpoint and credentials Model name and version Vector dimensions API standard (protocol) Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.\nInstance Architecture# System Definitions# The system provides pre-configured templates for common LLM services:\n# List available system definitions (no auth required) curl -X GET \u0026#34;https://api.example.com/v1/llm-service-definitions/_system\u0026#34;Default System Definitions:\nopenai-large: OpenAI text-embedding-3-large (3072 dimensions) openai-small: OpenAI text-embedding-3-small (1536 dimensions) cohere-v4: Cohere Embed v4 (1536 dimensions) gemini-embedding-001: Google Gemini embedding-001 (3072 dimensions, default size) User Instances# Users create instances for their own use. Instances contain:\nConfiguration (endpoint, model, dimensions) Encrypted API keys (write-only, never returned) Optional reference to a definition template Creating LLM Service Instances# Option 1: Standalone Instance# Create an instance by specifying all configuration fields:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model for research\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key-here\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model for research\u0026#34; }Note: The api_key_encrypted field is not returned in the response for security reasons.\nOption 2: From System Definition# Create an instance based on a system template (only requires API key):\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key-here\u0026#34; }\u0026#39;This inherits configuration from the _system/openai-large definition and only requires you to provide your API key.\nOption 3: From User Definition# Users can create their own definitions as templates:\n# Step 1: Create a custom definition curl -X PUT \u0026#34;https://api.example.com/v1/llm-service-definitions/alice/my-custom-config\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom-api.example.com/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-model-v2\u0026#34;, \u0026#34;dimensions\u0026#34;: 2048, \u0026#34;description\u0026#34;: \u0026#34;Custom embedding service\u0026#34; }\u0026#39; # Step 2: Create instance from that definition curl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/custom-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-api-key-here\u0026#34; }\u0026#39;Managing Instances# List Your Instances# Get all instances you own or have access to:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;owned_instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }, { \u0026#34;instance_id\u0026#34;: 124, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-cohere\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.cohere.ai/v1/embed\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embed-english-v4.0\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ], \u0026#34;shared_instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 456, \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Get Instance Details# Retrieve details for a specific instance:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Update Instance# Update instance configuration (owner only):\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-new-api-key-here\u0026#34; }\u0026#39;Delete Instance# Delete an instance (owner only):\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Note: Cannot delete instances that are used by existing projects.\nAPI Key Encryption# How Encryption Works# API keys are encrypted using AES-256-GCM encryption:\nEncryption Key Source: ENCRYPTION_KEY environment variable Key Derivation: SHA256 hash of the environment variable (ensures 32-byte key) Algorithm: AES-256-GCM (authenticated encryption) Storage: Encrypted bytes stored in api_key_encrypted column Setting Up Encryption# Add to your environment configuration:\n# .env file ENCRYPTION_KEY=\u0026#34;your-secure-random-32-character-key-or-longer\u0026#34;Important Security Notes:\nKeep this key secure and backed up Losing the key means losing access to encrypted API keys Use a strong, random string (32+ characters) Never commit the key to version control Rotate the key periodically (requires re-encrypting all API keys) API Key Security# API keys are write-only in the API:\n# Upload API key (works) curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-...\u0026#34;}\u0026#39; # Retrieve instance (API key NOT returned) curl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Response does NOT include api_key_encrypted field { \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-instance\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 // No api_key_encrypted field! }This protects API keys from:\nAccidental exposure in logs Unauthorized access via shared instances Client-side data breaches Instance Sharing# Share an Instance# Grant another user access to your instance:\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Roles:\nreader: Can use the instance in projects (read-only) editor: Can use the instance (currently same as reader) owner: Full control (only one owner, the creator) List Shared Users# See who has access to your instance:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }Unshare an Instance# Revoke access:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Using Shared Instances# Bob can reference Alice\u0026rsquo;s shared instance in his projects:\n# Bob creates a project using Alice\u0026#39;s instance curl -X PUT \u0026#34;https://api.example.com/v1/projects/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Using shared instance\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39; # Bob uploads embeddings using the shared instance curl -X POST \u0026#34;https://api.example.com/v1/embeddings/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;alice/my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072 }] }\u0026#39;Important: Bob can use the instance but cannot see Alice\u0026rsquo;s API key.\nInstance Sharing Patterns# Team Shared Instance# A team lead creates and shares an instance for the team:\n# Team lead creates instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/team_lead/team-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer team_lead_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-team-api-key\u0026#34; }\u0026#39; # Share with team members for member in alice bob charlie; do curl -X POST \u0026#34;https://api.example.com/v1/llm-services/team_lead/team-openai/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer team_lead_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#34;{\\\u0026#34;share_with_handle\\\u0026#34;: \\\u0026#34;$member\\\u0026#34;, \\\u0026#34;role\\\u0026#34;: \\\u0026#34;reader\\\u0026#34;}\u0026#34; doneOrganization-Wide Instance# Create a shared instance for organization-wide use:\n# Organization admin creates instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/org_admin/org-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer org_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;org-embeddings\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;Organization-wide embedding service\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-org-api-key\u0026#34; }\u0026#39;Per-Project Instance# Each project maintainer creates their own instance:\n# Alice creates her own instance for her project curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/research-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;research-embeddings\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-alice-research-key\u0026#34; }\u0026#39;Common Configurations# OpenAI Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Cohere Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;cohere-english\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.cohere.ai/v1/embed\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embed-english-v4.0\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-cohere-api-key\u0026#34; }Google Gemini Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;gemini-embedding\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embedding-001\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-gemini-api-key\u0026#34; }Custom/Self-Hosted Service# { \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-service\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom-api.example.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-model-v2\u0026#34;, \u0026#34;dimensions\u0026#34;: 2048, \u0026#34;description\u0026#34;: \u0026#34;Self-hosted embedding service\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;custom-auth-token\u0026#34; }Projects and Instances# 1:1 Relationship# Each project must reference exactly one instance:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Project with instance\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39;Changing Instance# Update a project to use a different instance:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_id\u0026#34;: 456}\u0026#39;Note: Only switch to instances with matching dimensions, or you\u0026rsquo;ll get validation errors on future uploads.\nFinding Instance for Project# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;The response includes the instance_id field.\nBest Practices# 1. Use System Definitions# Start with system definitions for common services:\n# Easiest approach curl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-...\u0026#34; }\u0026#39;2. Descriptive Instance Names# Use clear, descriptive names:\n# Good names \u0026#34;research-openai-large\u0026#34; \u0026#34;prod-cohere-english\u0026#34; \u0026#34;test-gemini-embedding\u0026#34; # Avoid generic names \u0026#34;instance1\u0026#34; \u0026#34;my-instance\u0026#34; \u0026#34;test\u0026#34;3. Separate Production and Development# Create separate instances for different environments:\n# Development instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/dev-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_handle\u0026#34;: \u0026#34;dev-openai\u0026#34;, ...}\u0026#39; # Production instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/prod-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_handle\u0026#34;: \u0026#34;prod-openai\u0026#34;, ...}\u0026#39;4. Document Instance Purpose# Use the description field:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/team-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Shared OpenAI instance for research team. Contact alice@example.com for access.\u0026#34;, ... }\u0026#39;5. Regular Key Rotation# Periodically update API keys:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-new-key-here\u0026#34;}\u0026#39;6. Monitor Instance Usage# Track which projects use each instance to avoid deleting in-use instances.\nTroubleshooting# Cannot Delete Instance# Error: \u0026ldquo;Instance is in use by existing projects\u0026rdquo;\nSolution: Delete or update projects using this instance first.\nDimension Mismatch# Error: \u0026ldquo;vector dimension mismatch\u0026rdquo;\nSolution: Ensure embeddings match the instance\u0026rsquo;s configured dimensions.\nAPI Key Not Working# Problem: Embeddings uploads fail with authentication errors\nSolution:\nVerify API key is correct Check API key permissions with the LLM provider Update the API key in the instance Cannot Access Shared Instance# Problem: Getting \u0026ldquo;Instance not found\u0026rdquo; errors\nSolution: Verify you\u0026rsquo;ve been granted access. Contact the instance owner.\nRelated Documentation# RAG Workflow Guide - Complete RAG implementation Project Sharing Guide - Share projects with users Batch Operations Guide - Upload embeddings efficiently Security Summary# API keys are encrypted at rest using AES-256-GCM API keys are never returned via GET requests Shared users cannot see API keys (write-only field) Encryption key must be secured (loss means cannot decrypt keys) Regular key rotation recommended for production use "},{"id":47,"href":"/dhamps-vdb/api/patch-updates/","title":"PATCH Updates","section":"API Reference","content":"PATCH Method for Partial Updates# The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.\nOverview# PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:\nRetrieves the current resource state via GET Merges your changes with the existing data Applies the update via PUT This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.\nSupported Resources# PATCH is available for:\nUsers: /v1/users/{username} Projects: /v1/projects/{username}/{projectname} LLM Services: /v1/llm-services/{username}/{llm_servicename} API Standards: /v1/api-standards/{standardname} Request Format# Endpoint: PATCH {resource_url}\nContent-Type: application/json\nBody: JSON object containing only the fields to update\nExamples# Update Project Description# Change only the project description without affecting other fields.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false } Enable Public Read Access# Make a project publicly accessible without changing other settings.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: true } Update User Email# Change a user\u0026rsquo;s email address without affecting other user data.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;email\u0026#34;: \u0026#34;alice.new@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.new@example.com\u0026#34; } Update LLM Service Description# Change the description of an LLM service instance.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Production OpenAI embeddings service\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Production OpenAI embeddings service\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 } Update API Standard Documentation# Update the description of an API standard (admin only).\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1 - Updated 2024\u0026#34; }\u0026#39; Update Multiple Fields# You can update multiple fields in a single PATCH request.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;public_read\u0026#34;: true }\u0026#39; Add Project Metadata Schema# Add or update a project\u0026rsquo;s metadata validation schema.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39; Use Cases# Configuration Changes# Update configuration settings without rebuilding entire resource objects:\n# Enable/disable public access curl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39; # Update instance dimensions curl -X PATCH \u0026#34;.../llm-services/alice/custom-model\u0026#34; \\ -d \u0026#39;{\u0026#34;dimensions\u0026#34;: 1024}\u0026#39; Metadata Management# Update descriptive metadata:\n# Update project description curl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34;}\u0026#39; # Update user name curl -X PATCH \u0026#34;.../users/alice\u0026#34; \\ -d \u0026#39;{\u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;}\u0026#39; Schema Evolution# Add or update validation schemas:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;category\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34; }\u0026#39; Authentication# PATCH requests require the same authentication as PUT requests for the resource:\nResource Who Can PATCH Users Admin or the user themselves Projects Admin or project owner LLM Services Admin or instance owner API Standards Admin only Behavior Details# Merge Strategy# PATCH uses a shallow merge strategy:\nTop-level fields you specify replace the existing values Nested objects are replaced entirely (not deep-merged) Fields you don\u0026rsquo;t specify remain unchanged Example:\nExisting project:\n{ \u0026#34;description\u0026#34;: \u0026#34;Old description\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...old schema...}\u0026#34; }PATCH request:\n{ \u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34; }Result:\n{ \u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...old schema...}\u0026#34; } Validation# All field values are validated according to the resource\u0026rsquo;s schema:\nField types must be correct Required fields (if specified) must be valid Constraints (e.g., string length, enum values) are enforced Atomic Operations# PATCH operations are atomic:\nEither all changes succeed, or none are applied If validation fails, the resource remains unchanged Comparison: PATCH vs PUT# PUT (Complete Replacement)# Requires: All fields (except read-only ones)\ncurl -X PUT \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false }\u0026#39;Use when: Creating or completely replacing a resource\nPATCH (Partial Update)# Requires: Only fields to change\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }\u0026#39;Use when: Modifying one or a few fields of an existing resource\nError Handling# 400 Bad Request# Invalid field values or types:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid value for field \u0026#39;public_read\u0026#39;: expected boolean, got string\u0026#34; } 401 Unauthorized# Missing or invalid authentication:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; } 403 Forbidden# Insufficient permissions:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify this resource\u0026#34; } 404 Not Found# Resource doesn\u0026rsquo;t exist:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; } 422 Unprocessable Entity# Validation failed:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unprocessable Entity\u0026#34;, \u0026#34;status\u0026#34;: 422, \u0026#34;detail\u0026#34;: \u0026#34;metadataScheme is not valid JSON Schema\u0026#34; } Best Practices# Use PATCH for Single-Field Updates# Do:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39;Don\u0026rsquo;t:\n# Unnecessarily complex curl -X PUT \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research docs\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: true }\u0026#39; Group Related Changes# Update multiple related fields in one request:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project\u0026#34;, \u0026#34;public_read\u0026#34;: true, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...new schema...}\u0026#34; }\u0026#39; Validate Before Patching# When possible, validate changes locally before submitting:\n# Python example def update_project_description(project_path, new_description): if not new_description or len(new_description) \u0026gt; 500: raise ValueError(\u0026#34;Invalid description\u0026#34;) response = requests.patch( f\u0026#34;{API_BASE}/projects/{project_path}\u0026#34;, json={\u0026#34;description\u0026#34;: new_description}, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {API_KEY}\u0026#34;} ) return response.json() Handle Errors Gracefully# response = requests.patch( f\u0026#34;{API_BASE}/projects/alice/research-docs\u0026#34;, json={\u0026#34;public_read\u0026#34;: True}, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {API_KEY}\u0026#34;} ) if response.status_code == 200: print(\u0026#34;Updated successfully\u0026#34;) elif response.status_code == 403: print(\u0026#34;Permission denied\u0026#34;) elif response.status_code == 404: print(\u0026#34;Project not found\u0026#34;) else: print(f\u0026#34;Error: {response.json()[\u0026#39;detail\u0026#39;]}\u0026#34;) Limitations# Not Available For# PATCH is not available for:\nEndpoints that don\u0026rsquo;t support GET and PUT List endpoints (e.g., GET /v1/projects/alice) Action endpoints (e.g., /share, /transfer-ownership) Cannot Change Identifiers# You cannot use PATCH to change resource identifiers:\nuser_handle project_handle instance_handle api_standard_handle To rename a resource, you must create a new resource and delete the old one.\nRelated Documentation# Users - User management endpoints Projects - Project management endpoints LLM Services - LLM service instance endpoints API Standards - API standard endpoints Error Handling - Error response reference "},{"id":48,"href":"/dhamps-vdb/api/error-handling/","title":"Error Handling","section":"API Reference","content":"Error Handling# The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.\nError Response Format# All error responses follow this structure:\n{ \u0026#34;title\u0026#34;: \u0026#34;Error Title\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Detailed error message explaining what went wrong\u0026#34; }Fields:\ntitle (string): Human-readable error title status (integer): HTTP status code detail (string): Detailed description of the error HTTP Status Codes# 2xx Success# 200 OK# Request succeeded. Response body contains requested data.\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;projects\u0026#34;: [...] } 201 Created# Resource created successfully. Response body contains the new resource.\nExample:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;...\u0026#34; } 4xx Client Errors# 400 Bad Request# The request is invalid or contains malformed data.\nCommon causes:\nInvalid JSON syntax Missing required fields Invalid field values or types Dimension mismatches in embeddings Metadata schema violations Invalid query parameter values Examples:\nInvalid JSON:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid JSON: unexpected end of input\u0026#34; }Missing required field:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Missing required field: project_handle\u0026#34; }Dimension mismatch:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }Metadata validation:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }Invalid query parameter:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;limit must be between 1 and 200\u0026#34; } 401 Unauthorized# Authentication failed or credentials are missing.\nCommon causes:\nMissing Authorization header Invalid API key Expired API key Malformed Authorization header Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Troubleshooting:\nVerify the Authorization header is present Check the API key is correct Ensure the header format is Authorization: Bearer \u0026lt;api_key\u0026gt; Verify the user still exists 403 Forbidden# Authentication succeeded but authorization failed. The authenticated user lacks permission for the requested operation.\nCommon causes:\nUser attempting to access another user\u0026rsquo;s private resources Non-admin attempting admin-only operations User attempting to modify shared resources they don\u0026rsquo;t own Attempting to access resources with insufficient role (reader vs editor) Examples:\nAdmin-only operation:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }Accessing another user\u0026rsquo;s resource:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this project\u0026#34; }Insufficient role:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify embeddings in this project. Editor role required.\u0026#34; } 404 Not Found# The requested resource does not exist.\nCommon causes:\nResource was deleted Incorrect resource identifier Typo in URL path Resource never existed Examples:\nUser not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; not found\u0026#34; }Project not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }Embedding not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; }LLM service not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;LLM service instance \u0026#39;alice/openai-large\u0026#39; not found\u0026#34; } 409 Conflict# The request conflicts with the current state of the resource.\nCommon causes:\nCreating a resource that already exists Deleting a resource that is in use Concurrent modification conflicts Examples:\nResource already exists:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Resource in use:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete LLM service instance: in use by 3 projects\u0026#34; }Ownership transfer conflict:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;New owner already has a project with handle \u0026#39;research-docs\u0026#39;\u0026#34; } 422 Unprocessable Entity# The request is syntactically correct but semantically invalid.\nCommon causes:\nInvalid JSON Schema Logical validation failures Constraint violations Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unprocessable Entity\u0026#34;, \u0026#34;status\u0026#34;: 422, \u0026#34;detail\u0026#34;: \u0026#34;metadataScheme is not valid JSON Schema: invalid schema structure\u0026#34; } 5xx Server Errors# 500 Internal Server Error# An unexpected error occurred on the server.\nCommon causes:\nDatabase connection failures Unexpected exceptions Configuration errors Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Internal Server Error\u0026#34;, \u0026#34;status\u0026#34;: 500, \u0026#34;detail\u0026#34;: \u0026#34;An internal error occurred. Please try again later.\u0026#34; }Action: Contact support if the error persists.\n503 Service Unavailable# The service is temporarily unavailable.\nCommon causes:\nDatabase maintenance Service overload Network issues Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Service Unavailable\u0026#34;, \u0026#34;status\u0026#34;: 503, \u0026#34;detail\u0026#34;: \u0026#34;Service temporarily unavailable. Please try again later.\u0026#34; }Action: Retry the request after a delay.\nCommon Error Scenarios# Authentication Errors# Missing Authorization Header# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Solution: Include the Authorization header:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Invalid API Key# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer invalid_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Solution: Verify your API key is correct.\nPermission Errors# Non-Admin Creating Users# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }Solution: Use an admin API key.\nAccessing Another User\u0026rsquo;s Project# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/bob/private-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this project\u0026#34; }Solution: Request the project owner to share the project with you.\nValidation Errors# Invalid JSON# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid JSON: unexpected end of input\u0026#34; }Solution: Fix the JSON syntax.\nDimension Mismatch# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3], \u0026#34;vector_dim\u0026#34;: 3 }] }\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 3072 dimensions\u0026#34; }Solution: Ensure vector dimensions match the LLM service configuration.\nMetadata Schema Violation# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;year\u0026#34;: 2024 } }] }\u0026#39;Response (if project schema requires \u0026ldquo;author\u0026rdquo;):\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }Solution: Include all required metadata fields.\nResource Conflicts# Creating Duplicate Resource# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;}\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Solution: Use a different user handle or update the existing user.\nDeleting Resource In Use# Request:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete LLM service instance: in use by 3 projects\u0026#34; }Solution: Delete or update the projects using this instance first.\nError Handling Best Practices# Client-Side Error Handling# Python example:\nimport requests response = requests.get( \u0026#34;https://api.example.com/v1/projects/alice\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;} ) if response.status_code == 200: projects = response.json()[\u0026#34;projects\u0026#34;] print(f\u0026#34;Found {len(projects)} projects\u0026#34;) elif response.status_code == 401: print(\u0026#34;Authentication failed - check API key\u0026#34;) elif response.status_code == 403: print(\u0026#34;Permission denied\u0026#34;) elif response.status_code == 404: print(\u0026#34;User not found\u0026#34;) elif response.status_code \u0026gt;= 500: print(\u0026#34;Server error - retry later\u0026#34;) else: error = response.json() print(f\u0026#34;Error: {error[\u0026#39;detail\u0026#39;]}\u0026#34;) Retry Logic# For transient errors (5xx), implement exponential backoff:\nimport time import requests def api_request_with_retry(url, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers={...}) if response.status_code \u0026lt; 500: return response if attempt \u0026lt; max_retries - 1: wait_time = 2 ** attempt # Exponential backoff print(f\u0026#34;Retrying in {wait_time}s...\u0026#34;) time.sleep(wait_time) return response Validation Before Request# Validate data locally before sending to reduce 400 errors:\ndef create_embedding(text_id, vector, metadata): # Validate locally if not text_id: raise ValueError(\u0026#34;text_id is required\u0026#34;) if not isinstance(vector, list): raise ValueError(\u0026#34;vector must be a list\u0026#34;) if len(vector) != 3072: raise ValueError(\u0026#34;vector must have 3072 dimensions\u0026#34;) # Send request response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34;, json={ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: text_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: len(vector), \u0026#34;metadata\u0026#34;: metadata }] }, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;} ) return response.json() Troubleshooting# Check API Documentation# Always refer to the live API documentation:\nOpenAPI YAML: /openapi.yaml Interactive Docs: /docs Verify Request Format# Use tools like curl -v to inspect the full request:\ncurl -v -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; Check Status and Logs# For persistent 5xx errors, check service status and logs (if you have access).\nContact Support# If errors persist or the cause is unclear:\nNote the error message and status code Record the request details (method, URL, headers, body) Check if the issue is reproducible Contact support with this information Related Documentation# Authentication - API authentication guide Query Parameters - Valid parameter values Endpoints - Complete endpoint reference "}] \ No newline at end of file diff --git a/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js b/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js new file mode 100644 index 0000000..0b5c792 --- /dev/null +++ b/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js @@ -0,0 +1 @@ +"use strict";(function(){const o="/dhamps-vdb/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/docs/public/getting-started/configuration/index.html b/docs/public/getting-started/configuration/index.html new file mode 100644 index 0000000..9a1fec5 --- /dev/null +++ b/docs/public/getting-started/configuration/index.html @@ -0,0 +1,52 @@ +Configuration | dhamps-vdb Documentation + +

    Configuration#

    Configure dhamps-vdb using environment variables or command-line options.

    Environment Variables#

    All configuration can be set via environment variables. Use a .env file to keep sensitive information secure.

    Service Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_DEBUGEnable debug loggingtrueNo
    SERVICE_HOSTHostname to listen onlocalhostNo
    SERVICE_PORTPort to listen on8880No

    Database Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_DBHOSTDatabase hostnamelocalhostYes
    SERVICE_DBPORTDatabase port5432No
    SERVICE_DBUSERDatabase usernamepostgresYes
    SERVICE_DBPASSWORDDatabase passwordpasswordYes
    SERVICE_DBNAMEDatabase namepostgresYes

    Security Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_ADMINKEYAdmin API key for administrative operations-Yes
    ENCRYPTION_KEYEncryption key for API keys (32+ characters)-Yes

    Configuration File#

    Create a .env file in the project root:

    # Service Configuration
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +
    +# Database Configuration
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=secure_password
    +SERVICE_DBNAME=dhamps_vdb
    +
    +# Security
    +SERVICE_ADMINKEY=your-secure-admin-key-here
    +ENCRYPTION_KEY=your-32-character-encryption-key-minimum

    Command-Line Options#

    You can also provide configuration via command-line flags:

    ./dhamps-vdb \
    +  --debug \
    +  -p 8880 \
    +  --db-host localhost \
    +  --db-port 5432 \
    +  --db-user dhamps_user \
    +  --db-password secure_password \
    +  --db-name dhamps_vdb \
    +  --admin-key your-admin-key

    Generating Secure Keys#

    Admin Key#

    Generate a secure admin key:

    openssl rand -base64 32

    Encryption Key#

    Generate a secure encryption key (minimum 32 characters):

    openssl rand -hex 32

    Configuration Priority#

    Configuration is loaded in the following order (later sources override earlier ones):

    1. Default values (from options.go)
    2. Environment variables
    3. .env file
    4. Command-line flags

    Security Best Practices#

    • Never commit .env files to version control
    • Use strong, randomly generated keys for production
    • Ensure .env file permissions are restrictive (chmod 600 .env)
    • Store encryption key securely - losing it means losing access to encrypted API keys
    • Use different keys for development and production environments

    Example Configuration#

    Development#

    # .env (development)
    +SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=password
    +SERVICE_DBNAME=dhamps_vdb_dev
    +SERVICE_ADMINKEY=dev-admin-key-change-me
    +ENCRYPTION_KEY=dev-encryption-key-32-chars-min

    Production#

    # .env (production)
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=prod-db.example.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_prod
    +SERVICE_DBPASSWORD=$(cat /run/secrets/db_password)
    +SERVICE_DBNAME=dhamps_vdb
    +SERVICE_ADMINKEY=$(cat /run/secrets/admin_key)
    +ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)

    Validation#

    The service validates configuration on startup and will exit with an error if required variables are missing.

    Next Steps#

    After configuration:

    1. Run the Quick Start tutorial
    2. Create your first project
    3. Review deployment options
    \ No newline at end of file diff --git a/docs/public/getting-started/docker/index.html b/docs/public/getting-started/docker/index.html new file mode 100644 index 0000000..6ecc03b --- /dev/null +++ b/docs/public/getting-started/docker/index.html @@ -0,0 +1,183 @@ +Docker Deployment | dhamps-vdb Documentation + +

    Docker Deployment#

    Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.

    Quick Start#

    The fastest way to get dhamps-vdb running with Docker:

    # Clone the repository
    +git clone https://github.com/mpilhlt/dhamps-vdb.git
    +cd dhamps-vdb
    +
    +# Run automated setup (generates secure keys)
    +./docker-setup.sh
    +
    +# Start services with docker-compose
    +docker-compose up -d
    +
    +# Check logs
    +docker-compose logs -f dhamps-vdb
    +
    +# Access the API
    +curl http://localhost:8880/docs

    What’s Included#

    The Docker Compose setup includes:

    • dhamps-vdb: The vector database API service
    • PostgreSQL 16: Database with pgvector extension
    • Persistent storage: Named volume for database data

    Configuration Files#

    .env File#

    All configuration is managed through environment variables. Copy the template:

    cp .env.docker.template .env

    Edit .env to set required values:

    # Admin API key for administrative operations
    +SERVICE_ADMINKEY=your-secure-admin-key-here
    +
    +# Encryption key for API keys (32+ characters)
    +ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars
    +
    +# Database password
    +SERVICE_DBPASSWORD=secure-database-password
    +
    +# Optional: Debug mode
    +SERVICE_DEBUG=false
    +
    +# Optional: Change ports
    +API_PORT=8880
    +POSTGRES_PORT=5432

    docker-compose.yml#

    The compose file defines two services:

    services:
    +  postgres:
    +    image: pgvector/pgvector:0.7.4-pg16
    +    # PostgreSQL with pgvector support
    +    
    +  dhamps-vdb:
    +    build: .
    +    # The API service
    +    depends_on:
    +      - postgres

    Deployment Options#

    Use the provided docker-compose.yml:

    docker-compose up -d

    Advantages:

    • Everything included
    • Automatic networking
    • Data persistence
    • Easy to manage

    Use when:

    • Getting started
    • Development/testing
    • Small to medium deployments

    Option 2: Standalone Container with External Database#

    Run only the dhamps-vdb container:

    # Build the image
    +docker build -t dhamps-vdb:latest .
    +
    +# Run the container
    +docker run -d \
    +  --name dhamps-vdb \
    +  -p 8880:8880 \
    +  -e SERVICE_DBHOST=your-db-host \
    +  -e SERVICE_DBPORT=5432 \
    +  -e SERVICE_DBUSER=dbuser \
    +  -e SERVICE_DBPASSWORD=dbpass \
    +  -e SERVICE_DBNAME=dhamps_vdb \
    +  -e SERVICE_ADMINKEY=admin-key \
    +  -e ENCRYPTION_KEY=encryption-key \
    +  dhamps-vdb:latest

    Use when:

    • You have an existing PostgreSQL server
    • Production deployments
    • Need database separation

    Option 3: Docker Compose with External Database#

    Modify docker-compose.yml to remove the postgres service:

    services:
    +  dhamps-vdb:
    +    build: .
    +    ports:
    +      - "${API_PORT:-8880}:8880"
    +    environment:
    +      SERVICE_DBHOST: external-db.example.com
    +      # ... other variables

    Building the Image#

    Standard Build#

    docker build -t dhamps-vdb:latest .

    Custom Tag#

    docker build -t dhamps-vdb:v0.1.0 .

    Clean Build (No Cache)#

    docker build --no-cache -t dhamps-vdb:latest .

    Multi-Stage Build Details#

    The Dockerfile uses multi-stage builds for efficiency:

    1. Builder stage: Compiles Go code with sqlc generation
    2. Runtime stage: Minimal Alpine image with only the binary

    Result: Small, secure image (~20MB vs 800MB+)

    Managing Services#

    Start Services#

    # Start in background
    +docker-compose up -d
    +
    +# Start with logs visible
    +docker-compose up
    +
    +# Rebuild and start
    +docker-compose up -d --build

    View Logs#

    # All logs
    +docker-compose logs
    +
    +# Follow logs in real-time
    +docker-compose logs -f
    +
    +# Specific service
    +docker-compose logs -f dhamps-vdb
    +docker-compose logs -f postgres

    Stop Services#

    # Stop containers (keeps data)
    +docker-compose stop
    +
    +# Stop and remove containers (keeps data)
    +docker-compose down
    +
    +# Stop and remove everything including data
    +docker-compose down -v

    Restart Services#

    # Restart all
    +docker-compose restart
    +
    +# Restart specific service
    +docker-compose restart dhamps-vdb

    Data Persistence#

    Docker Volumes#

    The compose file creates a named volume:

    volumes:
    +  postgres_data:

    This ensures database data persists across container restarts.

    View Volumes#

    docker volume ls

    Inspect Volume#

    docker volume inspect dhamps-vdb_postgres_data

    Backup Database#

    # Create backup
    +docker-compose exec postgres pg_dump -U postgres dhamps_vdb > backup.sql
    +
    +# Restore from backup
    +docker-compose exec -T postgres psql -U postgres dhamps_vdb < backup.sql

    Networking#

    Access from Host#

    The API is accessible at:

    http://localhost:8880

    Access from Other Containers#

    Use the service name as hostname:

    http://dhamps-vdb:8880

    Custom Network#

    To use an existing Docker network:

    networks:
    +  default:
    +    external:
    +      name: your-network-name

    Security#

    Required Environment Variables#

    Two critical environment variables must be set:

    1. SERVICE_ADMINKEY: Admin API key
    2. ENCRYPTION_KEY: For encrypting user API keys (32+ chars)

    Generating Secure Keys#

    # Admin key
    +openssl rand -base64 32
    +
    +# Encryption key
    +openssl rand -hex 32

    Production Checklist#

    • Use strong, randomly generated keys
    • Never commit .env to version control
    • Run behind reverse proxy (nginx, Traefik)
    • Enable HTTPS/TLS
    • Restrict database network access
    • Set resource limits
    • Enable logging and monitoring
    • Use specific image tags (not latest)
    • Regular security updates
    • Backup database regularly

    Verification#

    Check Service Status#

    # Check if containers are running
    +docker-compose ps
    +
    +# Expected: both services "running" or "healthy"

    Test API Access#

    # Get OpenAPI documentation
    +curl http://localhost:8880/docs
    +
    +# Should return HTML page

    Test Database Connection#

    # Connect to PostgreSQL
    +docker-compose exec postgres psql -U postgres -d dhamps_vdb
    +
    +# Check pgvector extension
    +\dx
    +
    +# Should show vector extension

    Create Test User#

    curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "testuser",
    +    "full_name": "Test User"
    +  }'

    Troubleshooting#

    Container Won’t Start#

    Check logs:

    docker-compose logs dhamps-vdb

    Common issues:

    • Missing SERVICE_ADMINKEY or ENCRYPTION_KEY
    • Database connection failure
    • Port already in use

    Database Connection Errors#

    # Check postgres health
    +docker-compose ps
    +
    +# Check database logs
    +docker-compose logs postgres
    +
    +# Test connection
    +docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT 1;"

    Can’t Connect to API#

    # Check if container is running
    +docker ps
    +
    +# Check port mapping
    +docker port dhamps-vdb
    +
    +# Test from inside container
    +docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs
    +
    +# Test from host
    +curl http://localhost:8880/docs

    Permission Issues#

    The container runs as non-root user appuser (UID 1000). If you have permission errors:

    # Check volume permissions
    +docker volume inspect dhamps-vdb_postgres_data

    Reset Everything#

    # Stop and remove everything
    +docker-compose down -v
    +
    +# Remove images
    +docker rmi dhamps-vdb:latest
    +docker rmi pgvector/pgvector:0.7.4-pg16
    +
    +# Start fresh
    +docker-compose up -d --build

    Build Failures#

    If Docker build fails with network errors:

    # Try with host network
    +docker build --network=host -t dhamps-vdb:latest .

    Advanced Configuration#

    Resource Limits#

    Add to docker-compose.yml:

    services:
    +  dhamps-vdb:
    +    deploy:
    +      resources:
    +        limits:
    +          cpus: '2'
    +          memory: 2G
    +        reservations:
    +          cpus: '0.5'
    +          memory: 512M

    Health Checks#

    The Dockerfile includes a health check:

    HEALTHCHECK --interval=30s --timeout=3s \
    +  CMD wget --no-verbose --tries=1 --spider http://localhost:8880/ || exit 1

    View health status:

    docker inspect --format='{{.State.Health.Status}}' dhamps-vdb

    Custom Dockerfile Builds#

    You can customize the build:

    docker build \
    +  --build-arg GO_VERSION=1.24 \
    +  -t dhamps-vdb:custom .

    External Database Setup#

    If using an external PostgreSQL database:

    Prepare Database#

    -- Create database
    +CREATE DATABASE dhamps_vdb;
    +
    +-- Create user
    +CREATE USER dhamps_user WITH PASSWORD 'secure_password';
    +
    +-- Grant privileges
    +GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    +
    +-- Connect to database
    +\c dhamps_vdb
    +
    +-- Grant schema permissions
    +GRANT ALL ON SCHEMA public TO dhamps_user;
    +
    +-- Enable pgvector
    +CREATE EXTENSION IF NOT EXISTS vector;

    Configure dhamps-vdb#

    Update .env:

    SERVICE_DBHOST=external-db.example.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=secure_password
    +SERVICE_DBNAME=dhamps_vdb

    Then run only the dhamps-vdb service or use a standalone container.

    Next Steps#

    After successful deployment:

    1. Configure the service
    2. Create your first user
    3. Set up a project
    4. Review security best practices
    \ No newline at end of file diff --git a/docs/public/getting-started/first-project/index.html b/docs/public/getting-started/first-project/index.html new file mode 100644 index 0000000..39315c8 --- /dev/null +++ b/docs/public/getting-started/first-project/index.html @@ -0,0 +1,172 @@ +First Project | dhamps-vdb Documentation + +

    First Project#

    Step-by-step guide to creating your first complete project in dhamps-vdb.

    Overview#

    This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:

    1. Set up authentication
    2. Configure an LLM service
    3. Create a project with metadata validation
    4. Upload document embeddings
    5. Search for similar documents
    6. Share your project with collaborators

    Step 1: Authentication Setup#

    Get Your API Key#

    If you’re an admin, create your first user:

    curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "researcher1",
    +    "name": "Research User",
    +    "email": "researcher@example.com"
    +  }'

    Save the returned vdb_key to a variable:

    export USER_KEY="your-returned-vdb-key"

    Verify Authentication#

    Test your API key:

    curl -X GET http://localhost:8880/v1/users/researcher1 \
    +  -H "Authorization: Bearer $USER_KEY"

    Step 2: Configure LLM Service#

    Option A: Use System Definition#

    List available system definitions:

    curl -X GET http://localhost:8880/v1/llm-services/_system \
    +  -H "Authorization: Bearer $USER_KEY"

    Create an instance from a system definition:

    curl -X PUT http://localhost:8880/v1/llm-services/researcher1/my-embeddings \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "definition_owner": "_system",
    +    "definition_handle": "openai-large",
    +    "description": "My OpenAI embeddings instance",
    +    "api_key_encrypted": "sk-proj-your-openai-api-key"
    +  }'

    Option B: Create Custom Instance#

    Create a standalone instance with custom configuration:

    curl -X PUT http://localhost:8880/v1/llm-services/researcher1/custom-embeddings \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-small",
    +    "dimensions": 1536,
    +    "description": "Custom OpenAI small embeddings",
    +    "api_key_encrypted": "sk-proj-your-api-key"
    +  }'

    Step 3: Create Project with Metadata Schema#

    Define a metadata schema to ensure consistent document metadata:

    curl -X POST http://localhost:8880/v1/projects/researcher1 \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "literature-analysis",
    +    "description": "Literary texts for research analysis",
    +    "instance_owner": "researcher1",
    +    "instance_handle": "my-embeddings",
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\",\"enum\":[\"poetry\",\"prose\",\"drama\"]},\"language\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\",\"year\"]}"
    +  }'

    This schema requires author, title, and year fields, with optional genre and language fields.

    Step 4: Upload Document Embeddings#

    Prepare Your Data#

    Create a file embeddings.json with your document embeddings:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "hamlet-act1-scene1",
    +      "instance_handle": "my-embeddings",
    +      "text": "Who's there? Nay, answer me: stand, and unfold yourself.",
    +      "vector": [0.023, -0.015, 0.087, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "William Shakespeare",
    +        "title": "Hamlet",
    +        "year": 1603,
    +        "genre": "drama",
    +        "language": "English"
    +      }
    +    },
    +    {
    +      "text_id": "paradise-lost-book1-line1",
    +      "instance_handle": "my-embeddings",
    +      "text": "Of Man's first disobedience, and the fruit...",
    +      "vector": [0.045, -0.032, 0.091, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "John Milton",
    +        "title": "Paradise Lost",
    +        "year": 1667,
    +        "genre": "poetry",
    +        "language": "English"
    +      }
    +    }
    +  ]
    +}

    Upload Embeddings#

    curl -X POST http://localhost:8880/v1/embeddings/researcher1/literature-analysis \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d @embeddings.json

    Verify Upload#

    List all embeddings:

    curl -X GET "http://localhost:8880/v1/embeddings/researcher1/literature-analysis?limit=10" \
    +  -H "Authorization: Bearer $USER_KEY"

    Get a specific embedding:

    curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \
    +  -H "Authorization: Bearer $USER_KEY"

    Step 5: Search Similar Documents#

    Find passages similar to Hamlet Act 1:

    curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer $USER_KEY"

    Response:

    {
    +  "user_handle": "researcher1",
    +  "project_handle": "literature-analysis",
    +  "results": [
    +    {
    +      "id": "hamlet-act2-scene1",
    +      "similarity": 0.89
    +    },
    +    {
    +      "id": "macbeth-act1-scene3",
    +      "similarity": 0.82
    +    },
    +    {
    +      "id": "othello-act3-scene3",
    +      "similarity": 0.76
    +    }
    +  ]
    +}

    Search with Metadata Filtering#

    Exclude passages from the same work:

    curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&metadata_path=title&metadata_value=Hamlet" \
    +  -H "Authorization: Bearer $USER_KEY"

    This excludes all documents where metadata.title equals “Hamlet”.

    Search with Raw Embeddings#

    Search using a new embedding without storing it:

    curl -X POST "http://localhost:8880/v1/similars/researcher1/literature-analysis?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [0.034, -0.021, 0.092, ...]
    +  }'

    Step 6: Share Your Project#

    Share with Collaborators#

    Grant read-only access to another user:

    curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "colleague1",
    +    "role": "reader"
    +  }'

    Grant edit access:

    curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "colleague2",
    +    "role": "editor"
    +  }'

    Make Project Public#

    Enable public read access (no authentication required):

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "public_read": true
    +  }'

    Now anyone can read embeddings and search without authentication:

    # No Authorization header needed
    +curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1

    View Shared Users#

    List all users with access to your project:

    curl -X GET http://localhost:8880/v1/projects/researcher1/literature-analysis/shared-with \
    +  -H "Authorization: Bearer $USER_KEY"

    Step 7: Manage Your Project#

    Update Project Description#

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated: Shakespearean and Renaissance literature analysis"
    +  }'

    Update Metadata Schema#

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\"},\"language\":{\"type\":\"string\"},\"act\":{\"type\":\"integer\"},\"scene\":{\"type\":\"integer\"}},\"required\":[\"author\",\"title\",\"year\"]}"
    +  }'

    Delete Specific Embeddings#

    curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \
    +  -H "Authorization: Bearer $USER_KEY"

    Delete All Embeddings#

    curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis \
    +  -H "Authorization: Bearer $USER_KEY"

    Common Patterns#

    Batch Upload Script#

    #!/bin/bash
    +
    +USER_KEY="your-vdb-key"
    +PROJECT="researcher1/literature-analysis"
    +API_URL="http://localhost:8880"
    +
    +# Process multiple files
    +for file in data/*.json; do
    +  echo "Uploading $file..."
    +  curl -X POST "$API_URL/v1/embeddings/$PROJECT" \
    +    -H "Authorization: Bearer $USER_KEY" \
    +    -H "Content-Type: application/json" \
    +    -d @"$file"
    +done

    Search and Filter Workflow#

    # 1. Find similar documents
    +SIMILAR=$(curl -s -X GET "$API_URL/v1/similars/$PROJECT/doc1?count=20" \
    +  -H "Authorization: Bearer $USER_KEY")
    +
    +# 2. Extract IDs
    +IDS=$(echo $SIMILAR | jq -r '.results[].id')
    +
    +# 3. Retrieve full embeddings for similar documents
    +for id in $IDS; do
    +  curl -X GET "$API_URL/v1/embeddings/$PROJECT/$id" \
    +    -H "Authorization: Bearer $USER_KEY"
    +done

    Troubleshooting#

    Validation Errors#

    If metadata validation fails:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'doc1': year is required"
    +}

    Check your metadata schema and ensure all required fields are present.

    Dimension Mismatches#

    If vector dimensions don’t match:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: expected 3072 dimensions, got 1536"
    +}

    Verify your LLM service configuration and embedding dimensions.

    Authentication Errors#

    If you get 401 Unauthorized:

    • Check your API key is correct
    • Ensure Authorization: Bearer prefix is included
    • Verify the user owns the resource or has been granted access

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/getting-started/index.html b/docs/public/getting-started/index.html new file mode 100644 index 0000000..6335c13 --- /dev/null +++ b/docs/public/getting-started/index.html @@ -0,0 +1,9 @@ +Getting Started | dhamps-vdb Documentation + +

    Getting Started with dhamps-vdb#

    This section helps you get dhamps-vdb up and running quickly. Whether you’re using Docker or compiling from source, you’ll find everything you need to start using the vector database API.

    What You’ll Learn#

    • How to install and run dhamps-vdb
    • How to configure the service for your environment
    • Basic usage patterns and workflows
    • Creating your first project and embeddings

    Prerequisites#

    Before you begin, ensure you have:

    • PostgreSQL 11+ with pgvector extension (or use the provided Docker setup)
    • Go 1.21+ (if compiling from source)
    • Docker and Docker Compose (for containerized deployment)
    \ No newline at end of file diff --git a/docs/public/getting-started/index.xml b/docs/public/getting-started/index.xml new file mode 100644 index 0000000..52823bd --- /dev/null +++ b/docs/public/getting-started/index.xml @@ -0,0 +1,192 @@ +Getting Started on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/Recent content in Getting Started on dhamps-vdb DocumentationHugoen-usInstallationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/installation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/<h1 id="installation">Installation<a class="anchor" href="#installation">#</a></h1> +<p>Install dhamps-vdb by compiling from source.</p> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li><strong>Go 1.21 or later</strong></li> +<li><strong>PostgreSQL 11+</strong> with pgvector extension</li> +<li><strong>sqlc</strong> for code generation</li> +</ul> +<h2 id="quick-install">Quick Install<a class="anchor" href="#quick-install">#</a></h2> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies and generate code</span> +</span></span><span style="display:flex;"><span>go get ./... +</span></span><span style="display:flex;"><span>sqlc generate --no-remote +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build the binary</span> +</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go</span></span></code></pre></div><h2 id="detailed-steps">Detailed Steps<a class="anchor" href="#detailed-steps">#</a></h2> +<h3 id="1-install-dependencies">1. Install Dependencies<a class="anchor" href="#1-install-dependencies">#</a></h3> +<p>Download all Go module dependencies:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get ./...</span></span></code></pre></div><h3 id="2-generate-database-code">2. Generate Database Code<a class="anchor" href="#2-generate-database-code">#</a></h3> +<p>Generate type-safe database queries using sqlc:</p>Configurationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/<h1 id="configuration">Configuration<a class="anchor" href="#configuration">#</a></h1> +<p>Configure dhamps-vdb using environment variables or command-line options.</p> +<h2 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h2> +<p>All configuration can be set via environment variables. Use a <code>.env</code> file to keep sensitive information secure.</p> +<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_DEBUG</code></td> + <td>Enable debug logging</td> + <td><code>true</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_HOST</code></td> + <td>Hostname to listen on</td> + <td><code>localhost</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_PORT</code></td> + <td>Port to listen on</td> + <td><code>8880</code></td> + <td>No</td> + </tr> + </tbody> +</table> +<h3 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_DBHOST</code></td> + <td>Database hostname</td> + <td><code>localhost</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBPORT</code></td> + <td>Database port</td> + <td><code>5432</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_DBUSER</code></td> + <td>Database username</td> + <td><code>postgres</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBPASSWORD</code></td> + <td>Database password</td> + <td><code>password</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBNAME</code></td> + <td>Database name</td> + <td><code>postgres</code></td> + <td>Yes</td> + </tr> + </tbody> +</table> +<h3 id="security-configuration">Security Configuration<a class="anchor" href="#security-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_ADMINKEY</code></td> + <td>Admin API key for administrative operations</td> + <td>-</td> + <td>Yes</td> + </tr> + <tr> + <td><code>ENCRYPTION_KEY</code></td> + <td>Encryption key for API keys (32+ characters)</td> + <td>-</td> + <td>Yes</td> + </tr> + </tbody> +</table> +<h2 id="configuration-file">Configuration File<a class="anchor" href="#configuration-file">#</a></h2> +<p>Create a <code>.env</code> file in the project root:</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/getting-started/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> +<p>Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.</p> +<h2 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h2> +<p>The fastest way to get dhamps-vdb running with Docker:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Run automated setup (generates secure keys)</span> +</span></span><span style="display:flex;"><span>./docker-setup.sh +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start services with docker-compose</span> +</span></span><span style="display:flex;"><span>docker-compose up -d +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Check logs</span> +</span></span><span style="display:flex;"><span>docker-compose logs -f dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Access the API</span> +</span></span><span style="display:flex;"><span>curl http://localhost:8880/docs</span></span></code></pre></div><h2 id="whats-included">What&rsquo;s Included<a class="anchor" href="#whats-included">#</a></h2> +<p>The Docker Compose setup includes:</p>Quick Starthttps://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/<h1 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h1> +<p>Complete walkthrough from installation to searching similar documents using curl.</p> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li>dhamps-vdb installed and running</li> +<li>Admin API key configured</li> +<li>PostgreSQL with pgvector ready</li> +</ul> +<h2 id="1-create-a-user">1. Create a User<a class="anchor" href="#1-create-a-user">#</a></h2> +<p>Create a new user with the admin API key:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;alice&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Alice Smith&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;alice@example.com&#34; +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Smith&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vdb_key&#34;</span>: <span style="color:#e6db74">&#34;024v2013621509245f2e24...&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Save the <code>vdb_key</code></strong> - it cannot be recovered later.</p>First Projecthttps://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/<h1 id="first-project">First Project<a class="anchor" href="#first-project">#</a></h1> +<p>Step-by-step guide to creating your first complete project in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:</p> +<ol> +<li>Set up authentication</li> +<li>Configure an LLM service</li> +<li>Create a project with metadata validation</li> +<li>Upload document embeddings</li> +<li>Search for similar documents</li> +<li>Share your project with collaborators</li> +</ol> +<h2 id="step-1-authentication-setup">Step 1: Authentication Setup<a class="anchor" href="#step-1-authentication-setup">#</a></h2> +<h3 id="get-your-api-key">Get Your API Key<a class="anchor" href="#get-your-api-key">#</a></h3> +<p>If you&rsquo;re an admin, create your first user:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;researcher1&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Research User&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;researcher@example.com&#34; +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p>Save the returned <code>vdb_key</code> to a variable:</p> \ No newline at end of file diff --git a/docs/public/getting-started/installation/index.html b/docs/public/getting-started/installation/index.html new file mode 100644 index 0000000..84ab048 --- /dev/null +++ b/docs/public/getting-started/installation/index.html @@ -0,0 +1,21 @@ +Installation | dhamps-vdb Documentation + +

    Installation#

    Install dhamps-vdb by compiling from source.

    Prerequisites#

    • Go 1.21 or later
    • PostgreSQL 11+ with pgvector extension
    • sqlc for code generation

    Quick Install#

    # Clone the repository
    +git clone https://github.com/mpilhlt/dhamps-vdb.git
    +cd dhamps-vdb
    +
    +# Install dependencies and generate code
    +go get ./...
    +sqlc generate --no-remote
    +
    +# Build the binary
    +go build -o build/dhamps-vdb main.go

    Detailed Steps#

    1. Install Dependencies#

    Download all Go module dependencies:

    go get ./...

    2. Generate Database Code#

    Generate type-safe database queries using sqlc:

    sqlc generate --no-remote

    This creates Go code from SQL queries in internal/database/queries/.

    3. Build the Application#

    Compile the application:

    go build -o build/dhamps-vdb main.go

    The binary will be created at build/dhamps-vdb.

    Running Without Building#

    You can run the application directly without building a binary:

    go run main.go

    This is useful during development but slower than running a pre-built binary.

    Verify Installation#

    Check that the binary was created successfully:

    ./build/dhamps-vdb --help

    You should see the available command-line options.

    Next Steps#

    After installation, you need to:

    1. Set up the database
    2. Configure environment variables
    3. Run the service

    System Requirements#

    • Memory: Minimum 512MB RAM (2GB+ recommended for production)
    • Disk: Minimal (< 50MB for binary, database size varies)
    • CPU: Any modern CPU (multi-core recommended for concurrent requests)

    Troubleshooting#

    sqlc Command Not Found#

    Install sqlc:

    go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest

    Make sure $GOPATH/bin is in your PATH.

    Build Errors#

    Ensure you’re using Go 1.21 or later:

    go version

    Clean the build cache if you encounter issues:

    go clean -cache
    +go build -o build/dhamps-vdb main.go

    Missing Dependencies#

    Force update all dependencies:

    go mod download
    +go get -u ./...
    \ No newline at end of file diff --git a/docs/public/getting-started/quick-start/index.html b/docs/public/getting-started/quick-start/index.html new file mode 100644 index 0000000..f9f28ce --- /dev/null +++ b/docs/public/getting-started/quick-start/index.html @@ -0,0 +1,160 @@ +Quick Start | dhamps-vdb Documentation + +

    Quick Start#

    Complete walkthrough from installation to searching similar documents using curl.

    Prerequisites#

    • dhamps-vdb installed and running
    • Admin API key configured
    • PostgreSQL with pgvector ready

    1. Create a User#

    Create a new user with the admin API key:

    curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "user_handle": "alice",
    +    "name": "Alice Smith",
    +    "email": "alice@example.com"
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "name": "Alice Smith",
    +  "email": "alice@example.com",
    +  "vdb_key": "024v2013621509245f2e24...",
    +  "created_at": "2024-01-15T10:30:00Z"
    +}

    Save the vdb_key - it cannot be recovered later.

    2. Create an LLM Service Instance#

    Create an LLM service configuration:

    curl -X PUT http://localhost:8880/v1/llm-services/alice/my-openai \
    +  -H "Authorization: Bearer alice_vdb_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "description": "OpenAI large embeddings",
    +    "api_key_encrypted": "sk-proj-your-openai-key"
    +  }'

    Response:

    {
    +  "instance_id": 1,
    +  "instance_handle": "my-openai",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072
    +}

    3. Create a Project#

    Create a project to organize your embeddings:

    curl -X POST http://localhost:8880/v1/projects/alice \
    +  -H "Authorization: Bearer alice_vdb_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Research document embeddings",
    +    "instance_owner": "alice",
    +    "instance_handle": "my-openai"
    +  }'

    Response:

    {
    +  "project_id": 1,
    +  "project_handle": "research-docs",
    +  "owner": "alice",
    +  "description": "Research document embeddings",
    +  "instance_id": 1,
    +  "created_at": "2024-01-15T10:35:00Z"
    +}

    4. Upload Embeddings#

    Upload document embeddings to your project:

    curl -X POST http://localhost:8880/v1/embeddings/alice/research-docs \
    +  -H "Authorization: Bearer alice_vdb_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {
    +        "text_id": "doc1",
    +        "instance_handle": "my-openai",
    +        "text": "Introduction to machine learning",
    +        "vector": [0.1, 0.2, 0.3, ..., 0.5],
    +        "vector_dim": 3072,
    +        "metadata": {
    +          "title": "ML Intro",
    +          "author": "Alice",
    +          "year": 2024
    +        }
    +      },
    +      {
    +        "text_id": "doc2",
    +        "instance_handle": "my-openai",
    +        "text": "Deep learning fundamentals",
    +        "vector": [0.15, 0.25, 0.35, ..., 0.55],
    +        "vector_dim": 3072,
    +        "metadata": {
    +          "title": "DL Fundamentals",
    +          "author": "Bob",
    +          "year": 2024
    +        }
    +      }
    +    ]
    +  }'

    Response:

    {
    +  "message": "2 embeddings uploaded successfully"
    +}

    5. Search for Similar Documents#

    Option A: Search Using Stored Document#

    Find documents similar to an already-stored document:

    curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_vdb_key"

    Response:

    {
    +  "user_handle": "alice",
    +  "project_handle": "research-docs",
    +  "results": [
    +    {
    +      "id": "doc2",
    +      "similarity": 0.92
    +    },
    +    {
    +      "id": "doc5",
    +      "similarity": 0.85
    +    }
    +  ]
    +}

    Option B: Search Using Raw Embeddings#

    Search without storing the query embedding:

    curl -X POST "http://localhost:8880/v1/similars/alice/research-docs?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_vdb_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [0.12, 0.22, 0.32, ..., 0.52]
    +  }'

    6. Filter by Metadata#

    Exclude documents from a specific author when searching:

    curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&metadata_path=author&metadata_value=Alice" \
    +  -H "Authorization: Bearer alice_vdb_key"

    This excludes all documents where metadata.author equals “Alice”.

    7. Retrieve Embeddings#

    Get all embeddings in your project:

    curl -X GET "http://localhost:8880/v1/embeddings/alice/research-docs?limit=10&offset=0" \
    +  -H "Authorization: Bearer alice_vdb_key"

    Get a specific embedding:

    curl -X GET http://localhost:8880/v1/embeddings/alice/research-docs/doc1 \
    +  -H "Authorization: Bearer alice_vdb_key"

    Complete Workflow Example#

    Here’s a complete script to get started:

    #!/bin/bash
    +
    +# Configuration
    +API_URL="http://localhost:8880"
    +ADMIN_KEY="your-admin-key"
    +
    +# 1. Create user
    +USER_RESPONSE=$(curl -s -X POST "$API_URL/v1/users" \
    +  -H "Authorization: Bearer $ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle":"alice","name":"Alice Smith","email":"alice@example.com"}')
    +
    +USER_KEY=$(echo $USER_RESPONSE | jq -r '.vdb_key')
    +echo "User created with key: $USER_KEY"
    +
    +# 2. Create LLM service instance
    +curl -X PUT "$API_URL/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "api_key_encrypted": "sk-your-key"
    +  }'
    +
    +# 3. Create project
    +curl -X POST "$API_URL/v1/projects/alice" \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-docs",
    +    "description": "Research documents",
    +    "instance_owner": "alice",
    +    "instance_handle": "my-openai"
    +  }'
    +
    +# 4. Upload embeddings
    +curl -X POST "$API_URL/v1/embeddings/alice/research-docs" \
    +  -H "Authorization: Bearer $USER_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d @embeddings.json
    +
    +# 5. Search similar
    +curl -X GET "$API_URL/v1/similars/alice/research-docs/doc1?count=5" \
    +  -H "Authorization: Bearer $USER_KEY"
    +
    +echo "Setup complete!"

    API Documentation#

    For complete API documentation, visit:

    curl http://localhost:8880/docs

    Or open http://localhost:8880/docs in your browser.

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/guides/batch-operations/index.html b/docs/public/guides/batch-operations/index.html new file mode 100644 index 0000000..d58300d --- /dev/null +++ b/docs/public/guides/batch-operations/index.html @@ -0,0 +1,508 @@ +Batch Operations Guide | dhamps-vdb Documentation + +

    Batch Operations Guide#

    This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.

    Overview#

    For production workloads and large datasets, efficient batch operations are essential. This guide covers:

    • Uploading multiple embeddings in a single request
    • Pagination strategies for large result sets
    • Best practices for performance and reliability
    • Error handling in batch operations

    Batch Upload Basics#

    Single Request with Multiple Embeddings#

    Upload multiple embeddings in one API call using the embeddings array:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {
    +        "text_id": "doc001",
    +        "instance_handle": "openai-large",
    +        "vector": [0.1, 0.2, 0.3, ...],
    +        "vector_dim": 3072,
    +        "text": "First document content",
    +        "metadata": {"category": "science"}
    +      },
    +      {
    +        "text_id": "doc002",
    +        "instance_handle": "openai-large",
    +        "vector": [0.11, 0.21, 0.31, ...],
    +        "vector_dim": 3072,
    +        "text": "Second document content",
    +        "metadata": {"category": "history"}
    +      },
    +      {
    +        "text_id": "doc003",
    +        "instance_handle": "openai-large",
    +        "vector": [0.12, 0.22, 0.32, ...],
    +        "vector_dim": 3072,
    +        "text": "Third document content",
    +        "metadata": {"category": "literature"}
    +      }
    +    ]
    +  }'

    Response:

    {
    +  "message": "Embeddings uploaded successfully",
    +  "count": 3
    +}

    Optimal Batch Sizes#

    Based on typical embedding dimensions and network constraints:

    Embedding DimensionsRecommended Batch SizeMaximum Batch Size
    384 (small models)500-10002000
    768 (BERT-base)300-5001000
    1536 (OpenAI small)100-300500
    3072 (OpenAI large)50-100200

    Factors to consider:

    • Network bandwidth and latency
    • API gateway timeout limits
    • Database transaction size
    • Memory constraints
    • Client-side serialization limits

    Finding Your Optimal Batch Size#

    Test different batch sizes to find the sweet spot:

    import time
    +import requests
    +
    +def test_batch_size(embeddings, batch_size):
    +    """Test upload performance with given batch size"""
    +    start_time = time.time()
    +    
    +    for i in range(0, len(embeddings), batch_size):
    +        batch = embeddings[i:i+batch_size]
    +        response = requests.post(
    +            "https://api.example.com/v1/embeddings/alice/my-project",
    +            headers={
    +                "Authorization": "Bearer alice_api_key",
    +                "Content-Type": "application/json"
    +            },
    +            json={"embeddings": batch}
    +        )
    +        response.raise_for_status()
    +    
    +    elapsed = time.time() - start_time
    +    throughput = len(embeddings) / elapsed
    +    print(f"Batch size {batch_size}: {throughput:.1f} embeddings/sec")
    +
    +# Test different batch sizes
    +for size in [50, 100, 200, 500]:
    +    test_batch_size(my_embeddings, size)

    Pagination for Large Datasets#

    Retrieving All Embeddings with Pagination#

    Use limit and offset parameters to paginate through large result sets:

    # Get first page (embeddings 0-99)
    +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=0" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Get second page (embeddings 100-199)
    +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=100" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Get third page (embeddings 200-299)
    +curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=200" \
    +  -H "Authorization: Bearer alice_api_key"

    Pagination Best Practices#

    Default Values:

    • limit: 10 (if not specified)
    • offset: 0 (if not specified)
    • Maximum limit: 200

    Example: Download Entire Project

    import requests
    +
    +def download_all_embeddings(owner, project):
    +    """Download all embeddings from a project"""
    +    all_embeddings = []
    +    offset = 0
    +    limit = 100
    +    
    +    while True:
    +        response = requests.get(
    +            f"https://api.example.com/v1/embeddings/{owner}/{project}",
    +            headers={"Authorization": "Bearer api_key"},
    +            params={"limit": limit, "offset": offset}
    +        )
    +        response.raise_for_status()
    +        
    +        batch = response.json()['embeddings']
    +        if not batch:
    +            break  # No more results
    +        
    +        all_embeddings.extend(batch)
    +        offset += len(batch)
    +        
    +        print(f"Downloaded {len(all_embeddings)} embeddings...")
    +    
    +    return all_embeddings
    +
    +# Usage
    +embeddings = download_all_embeddings("alice", "my-project")
    +print(f"Total: {len(embeddings)} embeddings")

    Efficient Batch Upload Strategies#

    Strategy 1: Simple Sequential Upload#

    Good for small to medium datasets (< 10,000 embeddings):

    def upload_sequential(embeddings, batch_size=100):
    +    """Upload embeddings sequentially in batches"""
    +    for i in range(0, len(embeddings), batch_size):
    +        batch = embeddings[i:i+batch_size]
    +        response = requests.post(
    +            "https://api.example.com/v1/embeddings/alice/my-project",
    +            headers={
    +                "Authorization": "Bearer alice_api_key",
    +                "Content-Type": "application/json"
    +            },
    +            json={"embeddings": batch}
    +        )
    +        response.raise_for_status()
    +        print(f"Uploaded batch {i//batch_size + 1}, total: {i+len(batch)}")

    Strategy 2: Parallel Upload with Threading#

    Good for larger datasets with stable network:

    import concurrent.futures
    +import requests
    +
    +def upload_batch(batch, batch_num):
    +    """Upload a single batch"""
    +    try:
    +        response = requests.post(
    +            "https://api.example.com/v1/embeddings/alice/my-project",
    +            headers={
    +                "Authorization": "Bearer alice_api_key",
    +                "Content-Type": "application/json"
    +            },
    +            json={"embeddings": batch},
    +            timeout=60
    +        )
    +        response.raise_for_status()
    +        return batch_num, True, None
    +    except Exception as e:
    +        return batch_num, False, str(e)
    +
    +def upload_parallel(embeddings, batch_size=100, max_workers=4):
    +    """Upload embeddings in parallel"""
    +    batches = [
    +        embeddings[i:i+batch_size]
    +        for i in range(0, len(embeddings), batch_size)
    +    ]
    +    
    +    failed = []
    +    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
    +        futures = {
    +            executor.submit(upload_batch, batch, i): i
    +            for i, batch in enumerate(batches)
    +        }
    +        
    +        for future in concurrent.futures.as_completed(futures):
    +            batch_num, success, error = future.result()
    +            if success:
    +                print(f"✓ Batch {batch_num+1}/{len(batches)} uploaded")
    +            else:
    +                print(f"✗ Batch {batch_num+1} failed: {error}")
    +                failed.append((batch_num, batches[batch_num]))
    +    
    +    return failed
    +
    +# Usage
    +failed_batches = upload_parallel(my_embeddings, batch_size=100, max_workers=4)
    +if failed_batches:
    +    print(f"Failed batches: {len(failed_batches)}")

    Strategy 3: Retry with Exponential Backoff#

    Robust strategy for unreliable networks:

    import time
    +import random
    +
    +def upload_with_retry(batch, max_retries=3):
    +    """Upload batch with exponential backoff retry"""
    +    for attempt in range(max_retries):
    +        try:
    +            response = requests.post(
    +                "https://api.example.com/v1/embeddings/alice/my-project",
    +                headers={
    +                    "Authorization": "Bearer alice_api_key",
    +                    "Content-Type": "application/json"
    +                },
    +                json={"embeddings": batch},
    +                timeout=60
    +            )
    +            response.raise_for_status()
    +            return True
    +        except requests.exceptions.RequestException as e:
    +            if attempt < max_retries - 1:
    +                wait = (2 ** attempt) + random.uniform(0, 1)
    +                print(f"Retry attempt {attempt+1} after {wait:.1f}s: {e}")
    +                time.sleep(wait)
    +            else:
    +                print(f"Failed after {max_retries} attempts: {e}")
    +                return False
    +
    +def upload_robust(embeddings, batch_size=100):
    +    """Upload with robust error handling"""
    +    failed = []
    +    for i in range(0, len(embeddings), batch_size):
    +        batch = embeddings[i:i+batch_size]
    +        if not upload_with_retry(batch):
    +            failed.append((i, batch))
    +        else:
    +            print(f"✓ Uploaded {i+batch_size}/{len(embeddings)}")
    +    
    +    return failed

    Progress Tracking and Resumability#

    Checkpoint-Based Upload#

    For very large datasets, implement checkpointing to resume after failures:

    import json
    +import os
    +
    +class CheckpointUploader:
    +    def __init__(self, checkpoint_file="upload_progress.json"):
    +        self.checkpoint_file = checkpoint_file
    +        self.progress = self.load_progress()
    +    
    +    def load_progress(self):
    +        """Load upload progress from checkpoint file"""
    +        if os.path.exists(self.checkpoint_file):
    +            with open(self.checkpoint_file, 'r') as f:
    +                return json.load(f)
    +        return {"uploaded_count": 0, "failed_batches": []}
    +    
    +    def save_progress(self):
    +        """Save current progress"""
    +        with open(self.checkpoint_file, 'w') as f:
    +            json.dump(self.progress, f)
    +    
    +    def upload(self, embeddings, batch_size=100):
    +        """Upload with checkpointing"""
    +        start_idx = self.progress["uploaded_count"]
    +        
    +        for i in range(start_idx, len(embeddings), batch_size):
    +            batch = embeddings[i:i+batch_size]
    +            
    +            try:
    +                response = requests.post(
    +                    "https://api.example.com/v1/embeddings/alice/my-project",
    +                    headers={
    +                        "Authorization": "Bearer alice_api_key",
    +                        "Content-Type": "application/json"
    +                    },
    +                    json={"embeddings": batch},
    +                    timeout=60
    +                )
    +                response.raise_for_status()
    +                
    +                self.progress["uploaded_count"] = i + len(batch)
    +                self.save_progress()
    +                print(f"✓ Progress: {self.progress['uploaded_count']}/{len(embeddings)}")
    +                
    +            except Exception as e:
    +                print(f"✗ Failed at index {i}: {e}")
    +                self.progress["failed_batches"].append(i)
    +                self.save_progress()
    +                raise
    +
    +# Usage
    +uploader = CheckpointUploader()
    +try:
    +    uploader.upload(my_embeddings, batch_size=100)
    +    print("Upload complete!")
    +except:
    +    print("Upload interrupted. Run again to resume.")

    Error Handling#

    Validation Errors#

    If any embedding in a batch fails validation, the entire batch is rejected:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {
    +        "text_id": "doc001",
    +        "instance_handle": "openai-large",
    +        "vector": [0.1, 0.2, 0.3],
    +        "vector_dim": 3072,
    +        "metadata": {"author": "Alice"}
    +      },
    +      {
    +        "text_id": "doc002",
    +        "instance_handle": "openai-large",
    +        "vector": [0.1, 0.2],
    +        "vector_dim": 3072,
    +        "metadata": {"author": "Bob"}
    +      }
    +    ]
    +  }'

    Error Response:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector length mismatch for text_id 'doc002': actual vector has 2 elements but vector_dim declares 3072"
    +}

    Solution: Validate all embeddings before batching, or handle errors and retry failed items.

    Pre-Upload Validation#

    def validate_embeddings(embeddings, expected_dim):
    +    """Validate embeddings before upload"""
    +    errors = []
    +    
    +    for i, emb in enumerate(embeddings):
    +        # Check vector length
    +        if len(emb['vector']) != expected_dim:
    +            errors.append(f"Index {i} (text_id: {emb['text_id']}): "
    +                        f"vector length {len(emb['vector'])} != {expected_dim}")
    +        
    +        # Check declared dimension
    +        if emb.get('vector_dim') != expected_dim:
    +            errors.append(f"Index {i} (text_id: {emb['text_id']}): "
    +                        f"vector_dim {emb.get('vector_dim')} != {expected_dim}")
    +        
    +        # Check required fields
    +        if not emb.get('text_id'):
    +            errors.append(f"Index {i}: missing text_id")
    +        
    +        if not emb.get('instance_handle'):
    +            errors.append(f"Index {i}: missing instance_handle")
    +    
    +    return errors
    +
    +# Usage
    +errors = validate_embeddings(my_embeddings, 3072)
    +if errors:
    +    print("Validation errors:")
    +    for error in errors:
    +        print(f"  - {error}")
    +else:
    +    print("All embeddings valid, proceeding with upload...")

    Performance Optimization Tips#

    1. Minimize Payload Size#

    Exclude unnecessary fields:

    # Include text only if needed for retrieval
    +embeddings_with_text = [
    +    {
    +        "text_id": doc_id,
    +        "instance_handle": "openai-large",
    +        "vector": vector,
    +        "vector_dim": 3072,
    +        "text": text,  # Include if needed
    +        "metadata": metadata
    +    }
    +    for doc_id, vector, text, metadata in documents
    +]
    +
    +# Exclude text if not needed (smaller payload)
    +embeddings_without_text = [
    +    {
    +        "text_id": doc_id,
    +        "instance_handle": "openai-large",
    +        "vector": vector,
    +        "vector_dim": 3072,
    +        "metadata": metadata
    +    }
    +    for doc_id, vector, metadata in documents
    +]

    2. Compress Requests#

    Use gzip compression for large payloads:

    import gzip
    +import json
    +
    +def upload_compressed(embeddings):
    +    """Upload with gzip compression"""
    +    payload = json.dumps({"embeddings": embeddings})
    +    compressed = gzip.compress(payload.encode('utf-8'))
    +    
    +    response = requests.post(
    +        "https://api.example.com/v1/embeddings/alice/my-project",
    +        headers={
    +            "Authorization": "Bearer alice_api_key",
    +            "Content-Type": "application/json",
    +            "Content-Encoding": "gzip"
    +        },
    +        data=compressed
    +    )
    +    return response

    3. Use Connection Pooling#

    Reuse HTTP connections for multiple requests:

    session = requests.Session()
    +session.headers.update({
    +    "Authorization": "Bearer alice_api_key",
    +    "Content-Type": "application/json"
    +})
    +
    +for batch in batches:
    +    response = session.post(
    +        "https://api.example.com/v1/embeddings/alice/my-project",
    +        json={"embeddings": batch}
    +    )
    +    response.raise_for_status()

    4. Monitor Upload Rate#

    Track and display upload progress:

    import time
    +
    +class ProgressTracker:
    +    def __init__(self, total):
    +        self.total = total
    +        self.uploaded = 0
    +        self.start_time = time.time()
    +    
    +    def update(self, count):
    +        self.uploaded += count
    +        elapsed = time.time() - self.start_time
    +        rate = self.uploaded / elapsed if elapsed > 0 else 0
    +        percent = (self.uploaded / self.total) * 100
    +        eta = (self.total - self.uploaded) / rate if rate > 0 else 0
    +        
    +        print(f"\rProgress: {self.uploaded}/{self.total} ({percent:.1f}%) "
    +              f"Rate: {rate:.1f} emb/s ETA: {eta:.0f}s", end="")
    +
    +# Usage
    +tracker = ProgressTracker(len(all_embeddings))
    +for batch in batches:
    +    upload_batch(batch)
    +    tracker.update(len(batch))
    +print()  # New line after completion

    Complete Example: Production-Grade Uploader#

    import requests
    +import time
    +import json
    +import logging
    +from concurrent.futures import ThreadPoolExecutor, as_completed
    +from typing import List, Dict, Tuple
    +
    +class ProductionUploader:
    +    def __init__(self, api_base: str, api_key: str, 
    +                 owner: str, project: str):
    +        self.api_base = api_base
    +        self.api_key = api_key
    +        self.owner = owner
    +        self.project = project
    +        self.session = requests.Session()
    +        self.session.headers.update({
    +            "Authorization": f"Bearer {api_key}",
    +            "Content-Type": "application/json"
    +        })
    +        
    +        logging.basicConfig(level=logging.INFO)
    +        self.logger = logging.getLogger(__name__)
    +    
    +    def upload_batch(self, batch: List[Dict], batch_num: int, 
    +                    max_retries: int = 3) -> Tuple[int, bool, str]:
    +        """Upload a single batch with retry logic"""
    +        url = f"{self.api_base}/v1/embeddings/{self.owner}/{self.project}"
    +        
    +        for attempt in range(max_retries):
    +            try:
    +                response = self.session.post(
    +                    url,
    +                    json={"embeddings": batch},
    +                    timeout=60
    +                )
    +                response.raise_for_status()
    +                return batch_num, True, ""
    +            except Exception as e:
    +                if attempt < max_retries - 1:
    +                    wait = 2 ** attempt
    +                    self.logger.warning(
    +                        f"Batch {batch_num} attempt {attempt+1} failed: {e}. "
    +                        f"Retrying in {wait}s..."
    +                    )
    +                    time.sleep(wait)
    +                else:
    +                    return batch_num, False, str(e)
    +    
    +    def upload(self, embeddings: List[Dict], batch_size: int = 100,
    +               max_workers: int = 4) -> Dict:
    +        """Upload embeddings with parallel processing and progress tracking"""
    +        batches = [
    +            embeddings[i:i+batch_size]
    +            for i in range(0, len(embeddings), batch_size)
    +        ]
    +        
    +        results = {
    +            "total": len(embeddings),
    +            "uploaded": 0,
    +            "failed": [],
    +            "start_time": time.time()
    +        }
    +        
    +        self.logger.info(f"Uploading {len(embeddings)} embeddings in "
    +                        f"{len(batches)} batches...")
    +        
    +        with ThreadPoolExecutor(max_workers=max_workers) as executor:
    +            futures = {
    +                executor.submit(self.upload_batch, batch, i): i
    +                for i, batch in enumerate(batches)
    +            }
    +            
    +            for future in as_completed(futures):
    +                batch_num, success, error = future.result()
    +                
    +                if success:
    +                    results["uploaded"] += len(batches[batch_num])
    +                    percent = (results["uploaded"] / results["total"]) * 100
    +                    self.logger.info(
    +                        f"✓ Batch {batch_num+1}/{len(batches)} "
    +                        f"({percent:.1f}% complete)"
    +                    )
    +                else:
    +                    results["failed"].append({
    +                        "batch_num": batch_num,
    +                        "error": error,
    +                        "embeddings": batches[batch_num]
    +                    })
    +                    self.logger.error(f"✗ Batch {batch_num+1} failed: {error}")
    +        
    +        results["elapsed"] = time.time() - results["start_time"]
    +        results["rate"] = results["uploaded"] / results["elapsed"]
    +        
    +        self.logger.info(
    +            f"\nUpload complete: {results['uploaded']}/{results['total']} "
    +            f"in {results['elapsed']:.1f}s ({results['rate']:.1f} emb/s)"
    +        )
    +        
    +        if results["failed"]:
    +            self.logger.warning(f"Failed batches: {len(results['failed'])}")
    +        
    +        return results
    +
    +# Usage
    +uploader = ProductionUploader(
    +    api_base="https://api.example.com",
    +    api_key="alice_api_key",
    +    owner="alice",
    +    project="my-project"
    +)
    +
    +results = uploader.upload(
    +    embeddings=my_embeddings,
    +    batch_size=100,
    +    max_workers=4
    +)
    +
    +# Save failed batches for retry
    +if results["failed"]:
    +    with open("failed_batches.json", "w") as f:
    +        json.dump(results["failed"], f)

    Best Practices Summary#

    1. Batch Size: Test to find optimal size (typically 50-500 depending on dimensions)
    2. Parallelism: Use 2-8 parallel workers for large uploads
    3. Retry Logic: Implement exponential backoff for network errors
    4. Validation: Pre-validate embeddings before upload
    5. Progress Tracking: Monitor upload rate and ETA
    6. Checkpointing: Save progress for resumable uploads
    7. Error Logging: Log all errors with sufficient context
    8. Connection Reuse: Use session objects for connection pooling
    9. Compression: Use gzip for large payloads
    10. Testing: Test with small batches before full upload

    Troubleshooting#

    Timeout Errors#

    Problem: Requests timing out with large batches

    Solution: Reduce batch size or increase timeout value

    Memory Issues#

    Problem: Out of memory when processing large datasets

    Solution: Process embeddings in streaming fashion, don’t load all into memory

    Rate Limiting#

    Problem: Getting rate limited by API

    Solution: Reduce parallelism (max_workers) or add delays between requests

    \ No newline at end of file diff --git a/docs/public/guides/index.html b/docs/public/guides/index.html new file mode 100644 index 0000000..ea0bd44 --- /dev/null +++ b/docs/public/guides/index.html @@ -0,0 +1,10 @@ +Guides | dhamps-vdb Documentation + +

    User Guides#

    Step-by-step guides for common tasks and workflows with dhamps-vdb.

    Available Guides#

    This section contains practical guides for using dhamps-vdb in real-world scenarios:

    • RAG Workflows - Implement Retrieval Augmented Generation
    • Project Sharing - Collaborate with other users
    • Public Projects - Enable unauthenticated access
    • Ownership Transfer - Move projects between users
    • Metadata Validation - Ensure data quality with schemas
    • Metadata Filtering - Exclude documents from similarity search
    • Batch Operations - Work with multiple embeddings efficiently
    • Instance Management - Configure LLM service instances

    These guides complement the API reference by providing context and best practices for common use cases.

    \ No newline at end of file diff --git a/docs/public/guides/index.xml b/docs/public/guides/index.xml new file mode 100644 index 0000000..fe96114 --- /dev/null +++ b/docs/public/guides/index.xml @@ -0,0 +1,94 @@ +Guides on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/guides/Recent content in Guides on dhamps-vdb DocumentationHugoen-usRAG Workflow Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/<h1 id="complete-rag-workflow-guide">Complete RAG Workflow Guide<a class="anchor" href="#complete-rag-workflow-guide">#</a></h1> +<p>This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>A typical RAG workflow involves:</p> +<ol> +<li>Generate embeddings from your text content (using an external LLM service)</li> +<li>Upload embeddings to dhamps-vdb</li> +<li>Search for similar documents based on a query</li> +<li>Retrieve the relevant context</li> +<li>Use the context with an LLM to generate responses</li> +</ol> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li>Access to dhamps-vdb API with a valid API key</li> +<li>An external LLM service for generating embeddings (e.g., OpenAI, Cohere)</li> +<li>Text content you want to process</li> +</ul> +<h2 id="step-1-generate-embeddings-externally">Step 1: Generate Embeddings Externally<a class="anchor" href="#step-1-generate-embeddings-externally">#</a></h2> +<p>First, use your chosen LLM service to generate embeddings for your text content. Here&rsquo;s an example using OpenAI&rsquo;s API:</p>Project Sharing Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/<h1 id="project-sharing-guide">Project Sharing Guide<a class="anchor" href="#project-sharing-guide">#</a></h1> +<p>This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Project sharing allows you to grant other users access to your projects with different permission levels:</p> +<ul> +<li><strong>reader</strong>: Read-only access to embeddings and similar documents</li> +<li><strong>editor</strong>: Read and write access to embeddings (can add/modify/delete embeddings)</li> +</ul> +<p>Only the project owner can manage sharing settings and delete the project.</p> +<h2 id="sharing-during-project-creation">Sharing During Project Creation<a class="anchor" href="#sharing-during-project-creation">#</a></h2> +<p>You can specify users to share with when creating a new project using the <code>shared_with</code> field:</p>Public Projects Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/public-projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/<h1 id="public-projects-guide">Public Projects Guide<a class="anchor" href="#public-projects-guide">#</a></h1> +<p>This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Projects can be configured to allow unauthenticated (public) read access by setting the <code>public_read</code> field to <code>true</code>. This is useful for:</p> +<ul> +<li>Open datasets and research data</li> +<li>Public APIs and services</li> +<li>Shared knowledge bases</li> +<li>Educational resources</li> +</ul> +<p><strong>Important:</strong> Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.</p>Ownership Transfer Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/<h1 id="ownership-transfer-guide">Ownership Transfer Guide<a class="anchor" href="#ownership-transfer-guide">#</a></h1> +<p>This guide explains how to transfer project ownership between users in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:</p> +<ul> +<li>A project maintainer is leaving and wants to hand over control</li> +<li>Organizational changes require reassigning project ownership</li> +<li>Consolidating projects under a different user account</li> +<li>Transferring stewardship of research data to a new PI</li> +</ul> +<h2 id="important-constraints">Important Constraints<a class="anchor" href="#important-constraints">#</a></h2> +<p>Before transferring ownership, understand these constraints:</p>Metadata Validation Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/<h1 id="metadata-validation-guide">Metadata Validation Guide<a class="anchor" href="#metadata-validation-guide">#</a></h1> +<p>This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.</p> +<p>Benefits:</p> +<ul> +<li>Enforce consistent metadata structure across all embeddings</li> +<li>Catch data entry errors early</li> +<li>Document expected metadata fields</li> +<li>Enable reliable metadata-based filtering</li> +</ul> +<h2 id="defining-a-metadata-schema">Defining a Metadata Schema<a class="anchor" href="#defining-a-metadata-schema">#</a></h2> +<h3 id="when-creating-a-project">When Creating a Project<a class="anchor" href="#when-creating-a-project">#</a></h3> +<p>Include a <code>metadataScheme</code> field with a valid JSON Schema when creating a project:</p>Metadata Filtering Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/<h1 id="metadata-filtering-guide">Metadata Filtering Guide<a class="anchor" href="#metadata-filtering-guide">#</a></h1> +<p>This guide explains how to use metadata filtering to exclude specific documents from similarity search results.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:</p> +<ul> +<li>Exclude documents from the same author when finding similar writing styles</li> +<li>Filter out documents from the same source when finding related content</li> +<li>Exclude documents with the same category when exploring diversity</li> +</ul> +<p>dhamps-vdb provides metadata filtering using query parameters that perform <strong>negative matching</strong> - they exclude documents where the metadata field matches the specified value.</p>Batch Operations Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/<h1 id="batch-operations-guide">Batch Operations Guide<a class="anchor" href="#batch-operations-guide">#</a></h1> +<p>This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>For production workloads and large datasets, efficient batch operations are essential. This guide covers:</p> +<ul> +<li>Uploading multiple embeddings in a single request</li> +<li>Pagination strategies for large result sets</li> +<li>Best practices for performance and reliability</li> +<li>Error handling in batch operations</li> +</ul> +<h2 id="batch-upload-basics">Batch Upload Basics<a class="anchor" href="#batch-upload-basics">#</a></h2> +<h3 id="single-request-with-multiple-embeddings">Single Request with Multiple Embeddings<a class="anchor" href="#single-request-with-multiple-embeddings">#</a></h3> +<p>Upload multiple embeddings in one API call using the <code>embeddings</code> array:</p>Instance Management Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/instance-management/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/<h1 id="instance-management-guide">Instance Management Guide<a class="anchor" href="#instance-management-guide">#</a></h1> +<p>This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:</p> +<ul> +<li>API endpoint and credentials</li> +<li>Model name and version</li> +<li>Vector dimensions</li> +<li>API standard (protocol)</li> +</ul> +<p>Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.</p> \ No newline at end of file diff --git a/docs/public/guides/instance-management/index.html b/docs/public/guides/instance-management/index.html new file mode 100644 index 0000000..47b96de --- /dev/null +++ b/docs/public/guides/instance-management/index.html @@ -0,0 +1,273 @@ +Instance Management Guide | dhamps-vdb Documentation + +

    Instance Management Guide#

    This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.

    Overview#

    LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:

    • API endpoint and credentials
    • Model name and version
    • Vector dimensions
    • API standard (protocol)

    Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.

    Instance Architecture#

    System Definitions#

    The system provides pre-configured templates for common LLM services:

    # List available system definitions (no auth required)
    +curl -X GET "https://api.example.com/v1/llm-service-definitions/_system"

    Default System Definitions:

    • openai-large: OpenAI text-embedding-3-large (3072 dimensions)
    • openai-small: OpenAI text-embedding-3-small (1536 dimensions)
    • cohere-v4: Cohere Embed v4 (1536 dimensions)
    • gemini-embedding-001: Google Gemini embedding-001 (3072 dimensions, default size)

    User Instances#

    Users create instances for their own use. Instances contain:

    • Configuration (endpoint, model, dimensions)
    • Encrypted API keys (write-only, never returned)
    • Optional reference to a definition template

    Creating LLM Service Instances#

    Option 1: Standalone Instance#

    Create an instance by specifying all configuration fields:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "my-openai",
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "description": "OpenAI large embedding model for research",
    +    "api_key_encrypted": "sk-proj-your-openai-api-key-here"
    +  }'

    Response:

    {
    +  "instance_id": 123,
    +  "instance_handle": "my-openai",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072,
    +  "description": "OpenAI large embedding model for research"
    +}

    Note: The api_key_encrypted field is not returned in the response for security reasons.

    Option 2: From System Definition#

    Create an instance based on a system template (only requires API key):

    curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai-instance" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "my-openai-instance",
    +    "definition_owner": "_system",
    +    "definition_handle": "openai-large",
    +    "api_key_encrypted": "sk-proj-your-openai-api-key-here"
    +  }'

    This inherits configuration from the _system/openai-large definition and only requires you to provide your API key.

    Option 3: From User Definition#

    Users can create their own definitions as templates:

    # Step 1: Create a custom definition
    +curl -X PUT "https://api.example.com/v1/llm-service-definitions/alice/my-custom-config" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "definition_handle": "my-custom-config",
    +    "endpoint": "https://custom-api.example.com/embeddings",
    +    "api_standard": "openai",
    +    "model": "custom-model-v2",
    +    "dimensions": 2048,
    +    "description": "Custom embedding service"
    +  }'
    +
    +# Step 2: Create instance from that definition
    +curl -X POST "https://api.example.com/v1/llm-services/alice/custom-instance" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "custom-instance",
    +    "definition_owner": "alice",
    +    "definition_handle": "my-custom-config",
    +    "api_key_encrypted": "your-api-key-here"
    +  }'

    Managing Instances#

    List Your Instances#

    Get all instances you own or have access to:

    curl -X GET "https://api.example.com/v1/llm-services/alice" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "owned_instances": [
    +    {
    +      "instance_id": 123,
    +      "instance_handle": "my-openai",
    +      "endpoint": "https://api.openai.com/v1/embeddings",
    +      "model": "text-embedding-3-large",
    +      "dimensions": 3072
    +    },
    +    {
    +      "instance_id": 124,
    +      "instance_handle": "my-cohere",
    +      "endpoint": "https://api.cohere.ai/v1/embed",
    +      "model": "embed-english-v4.0",
    +      "dimensions": 1536
    +    }
    +  ],
    +  "shared_instances": [
    +    {
    +      "instance_id": 456,
    +      "instance_handle": "team-openai",
    +      "owner": "bob",
    +      "endpoint": "https://api.openai.com/v1/embeddings",
    +      "model": "text-embedding-3-large",
    +      "dimensions": 3072,
    +      "role": "reader"
    +    }
    +  ]
    +}

    Get Instance Details#

    Retrieve details for a specific instance:

    curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key"

    Update Instance#

    Update instance configuration (owner only):

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Updated description",
    +    "api_key_encrypted": "sk-proj-new-api-key-here"
    +  }'

    Delete Instance#

    Delete an instance (owner only):

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key"

    Note: Cannot delete instances that are used by existing projects.

    API Key Encryption#

    How Encryption Works#

    API keys are encrypted using AES-256-GCM encryption:

    1. Encryption Key Source: ENCRYPTION_KEY environment variable
    2. Key Derivation: SHA256 hash of the environment variable (ensures 32-byte key)
    3. Algorithm: AES-256-GCM (authenticated encryption)
    4. Storage: Encrypted bytes stored in api_key_encrypted column

    Setting Up Encryption#

    Add to your environment configuration:

    # .env file
    +ENCRYPTION_KEY="your-secure-random-32-character-key-or-longer"

    Important Security Notes:

    • Keep this key secure and backed up
    • Losing the key means losing access to encrypted API keys
    • Use a strong, random string (32+ characters)
    • Never commit the key to version control
    • Rotate the key periodically (requires re-encrypting all API keys)

    API Key Security#

    API keys are write-only in the API:

    # Upload API key (works)
    +curl -X PUT "https://api.example.com/v1/llm-services/alice/my-instance" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"api_key_encrypted": "sk-..."}'
    +
    +# Retrieve instance (API key NOT returned)
    +curl -X GET "https://api.example.com/v1/llm-services/alice/my-instance" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Response does NOT include api_key_encrypted field
    +{
    +  "instance_id": 123,
    +  "instance_handle": "my-instance",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072
    +  // No api_key_encrypted field!
    +}

    This protects API keys from:

    • Accidental exposure in logs
    • Unauthorized access via shared instances
    • Client-side data breaches

    Instance Sharing#

    Share an Instance#

    Grant another user access to your instance:

    curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "bob",
    +    "role": "reader"
    +  }'

    Roles:

    • reader: Can use the instance in projects (read-only)
    • editor: Can use the instance (currently same as reader)
    • owner: Full control (only one owner, the creator)

    List Shared Users#

    See who has access to your instance:

    curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai/shared-with" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "instance_handle": "my-openai",
    +  "owner": "alice",
    +  "shared_with": [
    +    {"user_handle": "bob", "role": "reader"},
    +    {"user_handle": "charlie", "role": "reader"}
    +  ]
    +}

    Unshare an Instance#

    Revoke access:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai/share/bob" \
    +  -H "Authorization: Bearer alice_api_key"

    Using Shared Instances#

    Bob can reference Alice’s shared instance in his projects:

    # Bob creates a project using Alice's instance
    +curl -X PUT "https://api.example.com/v1/projects/bob/my-project" \
    +  -H "Authorization: Bearer bob_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "my-project",
    +    "description": "Using shared instance",
    +    "instance_owner": "alice",
    +    "instance_handle": "my-openai"
    +  }'
    +
    +# Bob uploads embeddings using the shared instance
    +curl -X POST "https://api.example.com/v1/embeddings/bob/my-project" \
    +  -H "Authorization: Bearer bob_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc001",
    +      "instance_handle": "alice/my-openai",
    +      "vector": [0.1, 0.2, ...],
    +      "vector_dim": 3072
    +    }]
    +  }'

    Important: Bob can use the instance but cannot see Alice’s API key.

    Instance Sharing Patterns#

    Team Shared Instance#

    A team lead creates and shares an instance for the team:

    # Team lead creates instance
    +curl -X PUT "https://api.example.com/v1/llm-services/team_lead/team-openai" \
    +  -H "Authorization: Bearer team_lead_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "team-openai",
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "api_key_encrypted": "sk-proj-team-api-key"
    +  }'
    +
    +# Share with team members
    +for member in alice bob charlie; do
    +  curl -X POST "https://api.example.com/v1/llm-services/team_lead/team-openai/share" \
    +    -H "Authorization: Bearer team_lead_api_key" \
    +    -H "Content-Type: application/json" \
    +    -d "{\"share_with_handle\": \"$member\", \"role\": \"reader\"}"
    +done

    Organization-Wide Instance#

    Create a shared instance for organization-wide use:

    # Organization admin creates instance
    +curl -X PUT "https://api.example.com/v1/llm-services/org_admin/org-embeddings" \
    +  -H "Authorization: Bearer org_admin_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "org-embeddings",
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "description": "Organization-wide embedding service",
    +    "api_key_encrypted": "sk-proj-org-api-key"
    +  }'

    Per-Project Instance#

    Each project maintainer creates their own instance:

    # Alice creates her own instance for her project
    +curl -X PUT "https://api.example.com/v1/llm-services/alice/research-embeddings" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "research-embeddings",
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "api_key_encrypted": "sk-proj-alice-research-key"
    +  }'

    Common Configurations#

    OpenAI Configuration#

    {
    +  "instance_handle": "openai-large",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "api_standard": "openai",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072,
    +  "api_key_encrypted": "sk-proj-..."
    +}

    Cohere Configuration#

    {
    +  "instance_handle": "cohere-english",
    +  "endpoint": "https://api.cohere.ai/v1/embed",
    +  "api_standard": "cohere",
    +  "model": "embed-english-v4.0",
    +  "dimensions": 1536,
    +  "api_key_encrypted": "your-cohere-api-key"
    +}

    Google Gemini Configuration#

    {
    +  "instance_handle": "gemini-embedding",
    +  "endpoint": "https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent",
    +  "api_standard": "gemini",
    +  "model": "embedding-001",
    +  "dimensions": 3072,
    +  "api_key_encrypted": "your-gemini-api-key"
    +}

    Custom/Self-Hosted Service#

    {
    +  "instance_handle": "custom-service",
    +  "endpoint": "https://custom-api.example.com/v1/embeddings",
    +  "api_standard": "openai",
    +  "model": "custom-model-v2",
    +  "dimensions": 2048,
    +  "description": "Self-hosted embedding service",
    +  "api_key_encrypted": "custom-auth-token"
    +}

    Projects and Instances#

    1:1 Relationship#

    Each project must reference exactly one instance:

    curl -X PUT "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "my-project",
    +    "description": "Project with instance",
    +    "instance_id": 123
    +  }'

    Changing Instance#

    Update a project to use a different instance:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"instance_id": 456}'

    Note: Only switch to instances with matching dimensions, or you’ll get validation errors on future uploads.

    Finding Instance for Project#

    curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key"

    The response includes the instance_id field.

    Best Practices#

    1. Use System Definitions#

    Start with system definitions for common services:

    # Easiest approach
    +curl -X POST "https://api.example.com/v1/llm-services/alice/my-instance" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "my-instance",
    +    "definition_owner": "_system",
    +    "definition_handle": "openai-large",
    +    "api_key_encrypted": "sk-..."
    +  }'

    2. Descriptive Instance Names#

    Use clear, descriptive names:

    # Good names
    +"research-openai-large"
    +"prod-cohere-english"
    +"test-gemini-embedding"
    +
    +# Avoid generic names
    +"instance1"
    +"my-instance"
    +"test"

    3. Separate Production and Development#

    Create separate instances for different environments:

    # Development instance
    +curl -X PUT "https://api.example.com/v1/llm-services/alice/dev-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"instance_handle": "dev-openai", ...}'
    +
    +# Production instance
    +curl -X PUT "https://api.example.com/v1/llm-services/alice/prod-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"instance_handle": "prod-openai", ...}'

    4. Document Instance Purpose#

    Use the description field:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/team-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "instance_handle": "team-openai",
    +    "description": "Shared OpenAI instance for research team. Contact alice@example.com for access.",
    +    ...
    +  }'

    5. Regular Key Rotation#

    Periodically update API keys:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"api_key_encrypted": "sk-proj-new-key-here"}'

    6. Monitor Instance Usage#

    Track which projects use each instance to avoid deleting in-use instances.

    Troubleshooting#

    Cannot Delete Instance#

    Error: “Instance is in use by existing projects”

    Solution: Delete or update projects using this instance first.

    Dimension Mismatch#

    Error: “vector dimension mismatch”

    Solution: Ensure embeddings match the instance’s configured dimensions.

    API Key Not Working#

    Problem: Embeddings uploads fail with authentication errors

    Solution:

    1. Verify API key is correct
    2. Check API key permissions with the LLM provider
    3. Update the API key in the instance

    Cannot Access Shared Instance#

    Problem: Getting “Instance not found” errors

    Solution: Verify you’ve been granted access. Contact the instance owner.

    Security Summary#

    1. API keys are encrypted at rest using AES-256-GCM
    2. API keys are never returned via GET requests
    3. Shared users cannot see API keys (write-only field)
    4. Encryption key must be secured (loss means cannot decrypt keys)
    5. Regular key rotation recommended for production use
    \ No newline at end of file diff --git a/docs/public/guides/metadata-filtering/index.html b/docs/public/guides/metadata-filtering/index.html new file mode 100644 index 0000000..27f59ab --- /dev/null +++ b/docs/public/guides/metadata-filtering/index.html @@ -0,0 +1,189 @@ +Metadata Filtering Guide | dhamps-vdb Documentation + +

    Metadata Filtering Guide#

    This guide explains how to use metadata filtering to exclude specific documents from similarity search results.

    Overview#

    When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:

    • Exclude documents from the same author when finding similar writing styles
    • Filter out documents from the same source when finding related content
    • Exclude documents with the same category when exploring diversity

    dhamps-vdb provides metadata filtering using query parameters that perform negative matching - they exclude documents where the metadata field matches the specified value.

    Query Parameters#

    Both similarity search endpoints support metadata filtering:

    • metadata_path: The JSON path to the metadata field (e.g., author, source.id, tags[0])
    • metadata_value: The value to exclude from results

    Both parameters must be used together. If you specify one without the other, the API returns an error.

    Basic Filtering Examples#

    Exclude Documents by Author#

    Find similar documents but exclude those from the same author:

    curl -X GET "https://api.example.com/v1/similars/alice/literary-corpus/hamlet-soliloquy?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \
    +  -H "Authorization: Bearer alice_api_key"

    This returns similar documents, excluding any with metadata.author == "William Shakespeare".

    Exclude Documents from Same Source#

    Find similar content from different sources:

    curl -X GET "https://api.example.com/v1/similars/alice/news-articles/article123?count=10&metadata_path=source&metadata_value=NYTimes" \
    +  -H "Authorization: Bearer alice_api_key"

    This excludes any documents with metadata.source == "NYTimes".

    Exclude by Category#

    Find documents in different categories:

    curl -X GET "https://api.example.com/v1/similars/alice/products/product456?count=10&metadata_path=category&metadata_value=electronics" \
    +  -H "Authorization: Bearer alice_api_key"

    This excludes any documents with metadata.category == "electronics".

    Filtering with Raw Embeddings#

    Metadata filtering also works when searching with raw embedding vectors:

    curl -X POST "https://api.example.com/v1/similars/alice/literary-corpus?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [0.032, -0.018, 0.056, ...]
    +  }'

    This searches using the provided vector but excludes documents where metadata.author == "William Shakespeare".

    Nested Metadata Paths#

    For nested metadata objects, use dot notation:

    Example Metadata Structure#

    {
    +  "author": {
    +    "name": "Jane Doe",
    +    "id": "author123",
    +    "affiliation": "University"
    +  },
    +  "publication": {
    +    "journal": "Science",
    +    "year": 2023
    +  }
    +}

    Filter by Nested Field#

    # Exclude documents from same author ID
    +curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=author.id&metadata_value=author123" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Exclude documents from same journal
    +curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=publication.journal&metadata_value=Science" \
    +  -H "Authorization: Bearer alice_api_key"

    Combining with Other Parameters#

    Metadata filtering works seamlessly with other search parameters:

    curl -X GET "https://api.example.com/v1/similars/alice/documents/doc123?count=20&threshold=0.8&limit=10&offset=0&metadata_path=source_id&metadata_value=src_456" \
    +  -H "Authorization: Bearer alice_api_key"

    Parameters:

    • count=20: Consider top 20 similar documents
    • threshold=0.8: Only include documents with similarity ≥ 0.8
    • limit=10: Return at most 10 results
    • offset=0: Start from first result (for pagination)
    • metadata_path=source_id: Filter on this metadata field
    • metadata_value=src_456: Exclude documents with this value

    Use Cases#

    1. Finding Similar Writing Styles Across Authors#

    When analyzing writing styles, you want similar texts from different authors:

    # Upload documents with author metadata
    +curl -X POST "https://api.example.com/v1/embeddings/alice/writing-styles" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "tolstoy-passage-1",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, ...],
    +      "vector_dim": 3072,
    +      "text": "Happy families are all alike...",
    +      "metadata": {
    +        "author": "Leo Tolstoy",
    +        "work": "Anna Karenina",
    +        "language": "Russian"
    +      }
    +    }]
    +  }'
    +
    +# Find similar writing styles from other authors
    +curl -X GET "https://api.example.com/v1/similars/alice/writing-styles/tolstoy-passage-1?count=10&metadata_path=author&metadata_value=Leo%20Tolstoy" \
    +  -H "Authorization: Bearer alice_api_key"

    2. Cross-Source Content Discovery#

    Find related news articles from different sources:

    # Search for similar content, excluding same source
    +curl -X GET "https://api.example.com/v1/similars/alice/news-corpus/nyt-article-456?count=15&metadata_path=source&metadata_value=New%20York%20Times" \
    +  -H "Authorization: Bearer alice_api_key"

    This helps discover how different outlets cover similar topics.

    3. Product Recommendations Across Categories#

    Find similar products in different categories:

    # User is viewing a laptop
    +curl -X GET "https://api.example.com/v1/similars/alice/product-catalog/laptop-001?count=10&threshold=0.7&metadata_path=category&metadata_value=electronics" \
    +  -H "Authorization: Bearer alice_api_key"

    This could recommend accessories, furniture (for home office), or other complementary items.

    4. Research Paper Discovery#

    Find related papers from different research groups:

    curl -X GET "https://api.example.com/v1/similars/alice/research-papers/paper123?count=20&metadata_path=lab_id&metadata_value=lab_abc_001" \
    +  -H "Authorization: Bearer alice_api_key"

    Helps researchers discover related work from other institutions.

    5. Avoiding Duplicate Content#

    When building a diverse content feed, exclude items from the same collection:

    curl -X GET "https://api.example.com/v1/similars/alice/blog-posts/post789?count=5&metadata_path=collection_id&metadata_value=series_xyz" \
    +  -H "Authorization: Bearer alice_api_key"

    6. Cross-Language Document Discovery#

    Find similar documents in other languages:

    curl -X GET "https://api.example.com/v1/similars/alice/multilingual-docs/doc_en_123?count=10&metadata_path=language&metadata_value=en" \
    +  -H "Authorization: Bearer alice_api_key"

    This finds semantically similar documents in languages other than English.

    Working with Multiple Values#

    Currently, you can only filter by one metadata field at a time. To exclude multiple values, you need to:

    1. Make multiple requests and merge results in your application
    2. Use more specific metadata fields that combine multiple attributes
    3. Post-process results on the client side

    Example: Excluding Multiple Authors#

    import requests
    +
    +def find_similar_excluding_authors(doc_id, exclude_authors):
    +    """Find similar docs excluding multiple authors"""
    +    all_results = []
    +    
    +    for author in exclude_authors:
    +        response = requests.get(
    +            f"https://api.example.com/v1/similars/alice/corpus/{doc_id}",
    +            headers={"Authorization": "Bearer alice_api_key"},
    +            params={
    +                "count": 20,
    +                "metadata_path": "author",
    +                "metadata_value": author
    +            }
    +        )
    +        results = response.json()['results']
    +        all_results.extend(results)
    +    
    +    # Deduplicate and sort by similarity
    +    seen = set()
    +    unique_results = []
    +    for r in sorted(all_results, key=lambda x: x['similarity'], reverse=True):
    +        if r['id'] not in seen:
    +            seen.add(r['id'])
    +            unique_results.append(r)
    +    
    +    return unique_results[:10]
    +
    +# Usage
    +similar = find_similar_excluding_authors(
    +    "doc123",
    +    ["Author A", "Author B", "Author C"]
    +)

    Combining with Metadata Validation#

    For reliable filtering, combine with metadata schema validation:

    # Step 1: Create project with metadata schema
    +curl -X POST "https://api.example.com/v1/projects/alice/validated-corpus" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "validated-corpus",
    +    "description": "Corpus with validated metadata",
    +    "instance_id": 123,
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"source_id\":{\"type\":\"string\"}},\"required\":[\"author\",\"source_id\"]}"
    +  }'
    +
    +# Step 2: Upload embeddings with metadata
    +curl -X POST "https://api.example.com/v1/embeddings/alice/validated-corpus" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc001",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "John Doe",
    +        "source_id": "source_123"
    +      }
    +    }]
    +  }'
    +
    +# Step 3: Search with guaranteed metadata field existence
    +curl -X GET "https://api.example.com/v1/similars/alice/validated-corpus/doc001?count=10&metadata_path=author&metadata_value=John%20Doe" \
    +  -H "Authorization: Bearer alice_api_key"

    See the Metadata Validation Guide for more details.

    Understanding the Filter Logic#

    The metadata filter uses negative matching:

    INCLUDE document IF:
    +  - document.similarity >= threshold
    +  AND
    +  - document.metadata[metadata_path] != metadata_value

    Important: Documents without the specified metadata field are included (not filtered out).

    Example#

    Given this query:

    ?metadata_path=author&metadata_value=Alice

    Included:

    • Documents where metadata.author == "Bob"
    • Documents where metadata.author == "Charlie"
    • Documents without an author field in metadata

    Excluded:

    • Documents where metadata.author == "Alice"

    Performance Considerations#

    Metadata filtering is performed at the database level using efficient indexing:

    1. Vector similarity is computed first
    2. Metadata filter is applied to the similarity results
    3. Results are sorted and limited

    For best performance:

    • Use indexed metadata fields when possible
    • Keep metadata values relatively small (under 1KB per document)
    • Consider using IDs instead of full names for filtering

    Error Handling#

    Missing One Parameter#

    # Missing metadata_value
    +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author" \
    +  -H "Authorization: Bearer alice_api_key"

    Error:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata_path and metadata_value must be used together"
    +}

    Non-Existent Metadata Field#

    # Filtering on field that doesn't exist in documents
    +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?count=10&metadata_path=nonexistent_field&metadata_value=some_value" \
    +  -H "Authorization: Bearer alice_api_key"

    Result: Returns all matching documents (since none have the field, none are excluded).

    URL Encoding#

    Remember to URL-encode metadata values with special characters:

    # Correct: URL-encoded value
    +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John%20Doe%20%26%20Jane%20Smith" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Incorrect: Unencoded special characters
    +curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John Doe & Jane Smith" \
    +  -H "Authorization: Bearer alice_api_key"

    Complete Example#

    Here’s a complete workflow demonstrating metadata filtering:

    # 1. Create project
    +curl -X POST "https://api.example.com/v1/projects/alice/literature" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "literature",
    +    "instance_id": 123
    +  }'
    +
    +# 2. Upload documents with metadata
    +curl -X POST "https://api.example.com/v1/embeddings/alice/literature" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [
    +      {
    +        "text_id": "tolstoy_1",
    +        "instance_handle": "openai-large",
    +        "vector": [0.1, 0.2, ...],
    +        "vector_dim": 3072,
    +        "text": "All happy families...",
    +        "metadata": {"author": "Tolstoy", "work": "Anna Karenina"}
    +      },
    +      {
    +        "text_id": "tolstoy_2",
    +        "instance_handle": "openai-large",
    +        "vector": [0.11, 0.21, ...],
    +        "vector_dim": 3072,
    +        "text": "It was the best of times...",
    +        "metadata": {"author": "Tolstoy", "work": "War and Peace"}
    +      },
    +      {
    +        "text_id": "dickens_1",
    +        "instance_handle": "openai-large",
    +        "vector": [0.12, 0.19, ...],
    +        "vector_dim": 3072,
    +        "text": "It was the age of wisdom...",
    +        "metadata": {"author": "Dickens", "work": "Tale of Two Cities"}
    +      }
    +    ]
    +  }'
    +
    +# 3. Find similar to tolstoy_1, excluding Tolstoy's works
    +curl -X GET "https://api.example.com/v1/similars/alice/literature/tolstoy_1?count=10&metadata_path=author&metadata_value=Tolstoy" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Result: Returns dickens_1, excludes tolstoy_2

    Troubleshooting#

    No Results Returned#

    Problem: Filter excludes all results

    Solution:

    • Verify the metadata field exists in your documents
    • Check that the metadata value matches exactly (case-sensitive)
    • Try without the filter to ensure there are similar documents

    Filter Not Working#

    Problem: Still seeing documents you want to exclude

    Solution:

    • Check URL encoding of the metadata value
    • Verify the metadata path is correct (use dot notation for nested fields)
    • Ensure both metadata_path and metadata_value are specified

    Want Positive Matching#

    Problem: Want to include only specific values, not exclude them

    Solution: Currently, only negative matching (exclusion) is supported. For positive matching, retrieve all results and filter on the client side, or use multiple negative filters to exclude everything except your target values.

    \ No newline at end of file diff --git a/docs/public/guides/metadata-validation/index.html b/docs/public/guides/metadata-validation/index.html new file mode 100644 index 0000000..07c32ce --- /dev/null +++ b/docs/public/guides/metadata-validation/index.html @@ -0,0 +1,372 @@ +Metadata Validation Guide | dhamps-vdb Documentation + +

    Metadata Validation Guide#

    This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.

    Overview#

    dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.

    Benefits:

    • Enforce consistent metadata structure across all embeddings
    • Catch data entry errors early
    • Document expected metadata fields
    • Enable reliable metadata-based filtering

    Defining a Metadata Schema#

    When Creating a Project#

    Include a metadataScheme field with a valid JSON Schema when creating a project:

    curl -X POST "https://api.example.com/v1/projects/alice/validated-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "validated-project",
    +    "description": "Project with metadata validation",
    +    "instance_id": 123,
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    +  }'

    Updating an Existing Project#

    Add or update a metadata schema using PATCH:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"},\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"title\",\"author\"]}"
    +  }'

    Note: Schema updates only affect new or updated embeddings. Existing embeddings are not retroactively validated.

    Common Schema Patterns#

    Simple Required Fields#

    Require specific fields with basic types:

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {"type": "string"},
    +    "year": {"type": "integer"}
    +  },
    +  "required": ["author"]
    +}

    Example usage:

    curl -X POST "https://api.example.com/v1/projects/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "literary-texts",
    +    "description": "Literary texts with structured metadata",
    +    "instance_id": 123,
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    +  }'

    Using Enums for Controlled Values#

    Restrict fields to specific allowed values:

    {
    +  "type": "object",
    +  "properties": {
    +    "genre": {
    +      "type": "string",
    +      "enum": ["poetry", "prose", "drama", "essay"]
    +    },
    +    "language": {
    +      "type": "string",
    +      "enum": ["en", "de", "fr", "es", "la"]
    +    }
    +  },
    +  "required": ["genre"]
    +}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "hamlet-soliloquy",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "William Shakespeare",
    +        "year": 1603,
    +        "genre": "drama"
    +      }
    +    }]
    +  }'

    Nested Objects#

    Define structured metadata with nested objects:

    {
    +  "type": "object",
    +  "properties": {
    +    "author": {
    +      "type": "object",
    +      "properties": {
    +        "name": {"type": "string"},
    +        "birth_year": {"type": "integer"},
    +        "nationality": {"type": "string"}
    +      },
    +      "required": ["name"]
    +    },
    +    "publication": {
    +      "type": "object",
    +      "properties": {
    +        "year": {"type": "integer"},
    +        "publisher": {"type": "string"},
    +        "city": {"type": "string"}
    +      }
    +    }
    +  },
    +  "required": ["author"]
    +}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/academic-papers" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "paper001",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": {
    +          "name": "Jane Smith",
    +          "birth_year": 1975,
    +          "nationality": "USA"
    +        },
    +        "publication": {
    +          "year": 2023,
    +          "publisher": "Academic Press",
    +          "city": "Boston"
    +        }
    +      }
    +    }]
    +  }'

    Arrays and Lists#

    Define arrays of values:

    {
    +  "type": "object",
    +  "properties": {
    +    "keywords": {
    +      "type": "array",
    +      "items": {"type": "string"},
    +      "minItems": 1,
    +      "maxItems": 10
    +    },
    +    "categories": {
    +      "type": "array",
    +      "items": {
    +        "type": "string",
    +        "enum": ["philosophy", "literature", "science", "history"]
    +      }
    +    }
    +  }
    +}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc001",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "keywords": ["machine learning", "embeddings", "NLP"],
    +        "categories": ["science", "literature"]
    +      }
    +    }]
    +  }'

    Numeric Constraints#

    Apply minimum, maximum, and range constraints:

    {
    +  "type": "object",
    +  "properties": {
    +    "rating": {
    +      "type": "number",
    +      "minimum": 0,
    +      "maximum": 5
    +    },
    +    "page_count": {
    +      "type": "integer",
    +      "minimum": 1
    +    },
    +    "confidence": {
    +      "type": "number",
    +      "minimum": 0.0,
    +      "maximum": 1.0
    +    }
    +  }
    +}

    String Constraints#

    Apply length and pattern constraints:

    {
    +  "type": "object",
    +  "properties": {
    +    "title": {
    +      "type": "string",
    +      "minLength": 1,
    +      "maxLength": 200
    +    },
    +    "isbn": {
    +      "type": "string",
    +      "pattern": "^[0-9]{13}$"
    +    },
    +    "doi": {
    +      "type": "string",
    +      "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$"
    +    }
    +  }
    +}

    Validation Examples#

    Valid Upload#

    When metadata conforms to the schema:

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "kant-critique",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "Immanuel Kant",
    +        "year": 1781,
    +        "genre": "prose"
    +      }
    +    }]
    +  }'

    Response:

    {
    +  "message": "Embeddings uploaded successfully",
    +  "count": 1
    +}

    Validation Error: Missing Required Field#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "some-text",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "year": 1781
    +      }
    +    }]
    +  }'

    Error Response:

    {
    +  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - author is required"
    +}

    Validation Error: Wrong Type#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "some-text",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "John Doe",
    +        "year": "1781"
    +      }
    +    }]
    +  }'

    Error Response:

    {
    +  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - year: expected integer, got string"
    +}

    Validation Error: Invalid Enum Value#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "some-text",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "author": "John Doe",
    +        "year": 1781,
    +        "genre": "novel"
    +      }
    +    }]
    +  }'

    Error Response:

    {
    +  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - genre: value must be one of: poetry, prose, drama, essay"
    +}

    Validation Error: Value Out of Range#

    curl -X POST "https://api.example.com/v1/embeddings/alice/rated-content" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "review001",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {
    +        "rating": 7.5
    +      }
    +    }]
    +  }'

    Error Response:

    {
    +  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "metadata validation failed for text_id 'review001': metadata validation failed:\n  - rating: must be <= 5"
    +}

    Real-World Schema Examples#

    Academic Publications#

    {
    +  "type": "object",
    +  "properties": {
    +    "doi": {
    +      "type": "string",
    +      "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$"
    +    },
    +    "title": {
    +      "type": "string",
    +      "minLength": 1,
    +      "maxLength": 500
    +    },
    +    "authors": {
    +      "type": "array",
    +      "items": {"type": "string"},
    +      "minItems": 1
    +    },
    +    "year": {
    +      "type": "integer",
    +      "minimum": 1900,
    +      "maximum": 2100
    +    },
    +    "journal": {"type": "string"},
    +    "volume": {"type": "integer"},
    +    "pages": {"type": "string"},
    +    "keywords": {
    +      "type": "array",
    +      "items": {"type": "string"}
    +    }
    +  },
    +  "required": ["doi", "title", "authors", "year"]
    +}
    {
    +  "type": "object",
    +  "properties": {
    +    "case_number": {"type": "string"},
    +    "court": {"type": "string"},
    +    "date": {
    +      "type": "string",
    +      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    +    },
    +    "jurisdiction": {
    +      "type": "string",
    +      "enum": ["federal", "state", "local"]
    +    },
    +    "category": {
    +      "type": "string",
    +      "enum": ["civil", "criminal", "administrative"]
    +    },
    +    "parties": {
    +      "type": "array",
    +      "items": {"type": "string"}
    +    }
    +  },
    +  "required": ["case_number", "court", "date"]
    +}

    Product Catalog#

    {
    +  "type": "object",
    +  "properties": {
    +    "sku": {
    +      "type": "string",
    +      "pattern": "^[A-Z]{3}-\\d{6}$"
    +    },
    +    "name": {"type": "string"},
    +    "category": {
    +      "type": "string",
    +      "enum": ["electronics", "clothing", "books", "home", "toys"]
    +    },
    +    "price": {
    +      "type": "number",
    +      "minimum": 0
    +    },
    +    "in_stock": {"type": "boolean"},
    +    "tags": {
    +      "type": "array",
    +      "items": {"type": "string"}
    +    }
    +  },
    +  "required": ["sku", "name", "category", "price"]
    +}

    Admin Sanity Check#

    Administrators can verify database integrity using the /v1/admin/sanity-check endpoint:

    curl -X GET "https://api.example.com/v1/admin/sanity-check" \
    +  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    +  "status": "PASSED",
    +  "total_projects": 5,
    +  "issues_count": 0,
    +  "warnings_count": 1,
    +  "warnings": [
    +    "Project alice/project1 has 100 embeddings but no metadata schema defined"
    +  ]
    +}

    Status Values:

    • PASSED: No issues or warnings found
    • WARNING: No critical issues, but warnings exist
    • FAILED: Validation issues found that need attention

    The sanity check:

    • Validates all embeddings have dimensions matching their LLM service
    • Validates all metadata against project schemas (if defined)
    • Reports projects without schemas as warnings

    Best Practices#

    1. Start Simple, Add Complexity Later#

    Begin with basic required fields:

    {
    +  "type": "object",
    +  "properties": {
    +    "source": {"type": "string"}
    +  },
    +  "required": ["source"]
    +}

    Add more constraints as your needs evolve.

    2. Test Schemas Before Deployment#

    Use online JSON Schema validators like jsonschemavalidator.net to test your schemas before deploying them.

    3. Document Your Schema#

    Include a description in your project:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "description": "Project with metadata schema: author (required string), year (integer), genre (enum)"
    +  }'

    4. Version Your Schemas#

    If you need to change a schema significantly, consider creating a new project rather than updating the existing one.

    5. Optional vs Required#

    Be judicious with required fields. Too many required fields can make uploads cumbersome.

    6. Escape JSON Properly#

    When passing JSON schemas in curl commands, escape quotes properly or use single quotes for the outer JSON.

    Projects Without Schemas#

    If you don’t provide a metadataScheme when creating a project:

    • Metadata validation is skipped
    • You can upload any valid JSON metadata
    • This is useful for exploratory work or heterogeneous data

    Schema Updates and Existing Data#

    When you update a project’s metadata schema:

    • Existing embeddings are not revalidated
    • The new schema only applies to new or updated embeddings
    • Use the admin sanity check to find existing embeddings that don’t conform

    Removing a Schema#

    To remove metadata validation from a project:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"metadataScheme": null}'

    After this, new embeddings can have any metadata structure.

    Troubleshooting#

    Schema Syntax Errors#

    Error: “Invalid JSON Schema”

    Solution: Validate your schema syntax using an online validator. Common issues:

    • Missing commas between properties
    • Unescaped quotes
    • Invalid JSON structure

    Uploads Failing After Schema Change#

    Problem: Uploads worked before, now failing with validation errors

    Solution: Check that your metadata matches the new schema requirements. Review the error message for specific validation failures.

    Want to Fix Non-Conforming Data#

    Problem: Sanity check shows validation errors in existing data

    Solution: Either:

    1. Update the schema to accept existing data
    2. Re-upload conforming data to replace non-conforming embeddings
    3. Delete and re-upload the project with correct metadata
    \ No newline at end of file diff --git a/docs/public/guides/ownership-transfer/index.html b/docs/public/guides/ownership-transfer/index.html new file mode 100644 index 0000000..fe3aa0b --- /dev/null +++ b/docs/public/guides/ownership-transfer/index.html @@ -0,0 +1,153 @@ +Ownership Transfer Guide | dhamps-vdb Documentation + +

    Ownership Transfer Guide#

    This guide explains how to transfer project ownership between users in dhamps-vdb.

    Overview#

    Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:

    • A project maintainer is leaving and wants to hand over control
    • Organizational changes require reassigning project ownership
    • Consolidating projects under a different user account
    • Transferring stewardship of research data to a new PI

    Important Constraints#

    Before transferring ownership, understand these constraints:

    1. Only the current owner can transfer - Editors and readers cannot initiate transfers
    2. New owner must exist - The target user must already be registered in the system
    3. No handle conflicts - The new owner cannot already have a project with the same handle
    4. Old owner loses access - After transfer, the original owner has no access to the project
    5. Data remains intact - All embeddings and metadata are preserved during transfer
    6. Shared users remain - Existing sharing relationships are maintained

    Transferring Ownership#

    Basic Transfer#

    Transfer a project to another user:

    curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "new_owner_handle": "bob"
    +  }'

    Response:

    {
    +  "message": "Project ownership transferred successfully",
    +  "project_handle": "research-data",
    +  "old_owner": "alice",
    +  "new_owner": "bob"
    +}

    After this operation:

    • The project is now accessible at /v1/projects/bob/research-data
    • Bob has full owner privileges
    • Alice no longer has any access to the project
    • All embeddings remain unchanged

    Complete Transfer Example#

    Here’s a complete workflow showing before and after transfer:

    # Before transfer - Alice is the owner
    +curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Response
    +{
    +  "project_handle": "my-project",
    +  "owner": "alice",
    +  "description": "Research project",
    +  "instance_id": 123
    +}
    +
    +# Alice transfers to Bob
    +curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'
    +
    +# After transfer - Bob is now the owner
    +curl -X GET "https://api.example.com/v1/projects/bob/my-project" \
    +  -H "Authorization: Bearer bob_api_key"
    +
    +# Response
    +{
    +  "project_handle": "my-project",
    +  "owner": "bob",
    +  "description": "Research project",
    +  "instance_id": 123
    +}
    +
    +# Alice can no longer access it
    +curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key"
    +# Returns: 404 Not Found

    Effects of Transfer#

    Project Access Path Changes#

    The project URL changes to reflect the new owner:

    Before:

    /v1/projects/alice/research-data
    +/v1/embeddings/alice/research-data
    +/v1/similars/alice/research-data/doc123

    After:

    /v1/projects/bob/research-data
    +/v1/embeddings/bob/research-data
    +/v1/similars/bob/research-data/doc123

    Important: Update all client code and bookmarks to use the new owner’s handle.

    New Owner Gains Full Control#

    Bob (new owner) can now:

    • View and modify all embeddings
    • Update project settings (description, instance, metadata schema)
    • Manage sharing (add/remove shared users)
    • Transfer ownership again to someone else
    • Delete the project

    Old Owner Loses All Access#

    Alice (old owner) can no longer:

    • Access the project in any way
    • View or modify embeddings
    • See project metadata
    • Manage sharing
    • Transfer ownership back

    Note: If Alice needs continued access, Bob should share the project with her after the transfer.

    Shared Users Remain#

    If the project was shared with other users, those sharing relationships are preserved:

    # Before transfer - Alice shares with Charlie (editor)
    +curl -X POST "https://api.example.com/v1/projects/alice/research-data/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"share_with_handle": "charlie", "role": "editor"}'
    +
    +# Transfer to Bob
    +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'
    +
    +# After transfer - Charlie still has editor access
    +curl -X GET "https://api.example.com/v1/projects/bob/research-data" \
    +  -H "Authorization: Bearer charlie_api_key"
    +# Works! Charlie can still access as editor

    Upgrading Shared User to Owner#

    If the new owner was previously a shared user, their role is automatically upgraded:

    # Alice shares project with Bob (editor)
    +curl -X POST "https://api.example.com/v1/projects/alice/my-project/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"share_with_handle": "bob", "role": "editor"}'
    +
    +# Alice transfers ownership to Bob
    +curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'
    +
    +# Bob's previous "editor" sharing role is removed
    +# Bob now has full owner privileges instead

    Use Cases#

    PI Leaving Institution#

    A principal investigator leaving an institution transfers project ownership to a colleague:

    curl -X POST "https://api.example.com/v1/projects/prof_jones/lab_data/transfer-ownership" \
    +  -H "Authorization: Bearer prof_jones_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "prof_smith"}'

    Account Consolidation#

    Consolidate multiple projects under a single organizational account:

    # Transfer Alice's personal projects to organization account
    +curl -X POST "https://api.example.com/v1/projects/alice/project1/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "org_datascience"}'
    +
    +curl -X POST "https://api.example.com/v1/projects/alice/project2/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "org_datascience"}'

    Graduated Student Handoff#

    A graduating student transfers their research project to their advisor:

    curl -X POST "https://api.example.com/v1/projects/student_bob/thesis_embeddings/transfer-ownership" \
    +  -H "Authorization: Bearer student_bob_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "advisor_carol"}'
    +
    +# Advisor can then share it back with the student if needed
    +curl -X POST "https://api.example.com/v1/projects/advisor_carol/thesis_embeddings/share" \
    +  -H "Authorization: Bearer advisor_carol_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"share_with_handle": "student_bob", "role": "reader"}'

    Department Reorganization#

    Projects move to a new department owner:

    curl -X POST "https://api.example.com/v1/projects/old_dept/resource_library/transfer-ownership" \
    +  -H "Authorization: Bearer old_dept_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "new_dept"}'

    Error Conditions#

    New Owner Doesn’t Exist#

    curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "nonexistent_user"}'

    Error:

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "User 'nonexistent_user' does not exist"
    +}

    Solution: Ensure the target user is registered first. Contact admin to create the user.

    Handle Conflict#

    # Bob already has a project called "research-data"
    +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'

    Error:

    {
    +  "title": "Conflict",
    +  "status": 409,
    +  "detail": "User 'bob' already has a project with handle 'research-data'"
    +}

    Solution: Either:

    1. Rename Alice’s project before transferring:
      curl -X PATCH "https://api.example.com/v1/projects/alice/research-data" \
      +  -H "Authorization: Bearer alice_api_key" \
      +  -H "Content-Type: application/json" \
      +  -d '{"project_handle": "research-data-alice"}'
    2. Ask Bob to rename or delete their existing project
    3. Choose a different target user

    Not the Owner#

    # Charlie tries to transfer Alice's project
    +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    +  -H "Authorization: Bearer charlie_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'

    Error:

    {
    +  "title": "Forbidden",
    +  "status": 403,
    +  "detail": "Only the project owner can transfer ownership"
    +}

    Solution: Only the current owner (Alice) can initiate the transfer.

    Best Practices#

    Before Transferring#

    1. Communicate with New Owner: Ensure they’re willing to accept ownership
    2. Document Current State: Export or document current embeddings and metadata
    3. Review Shared Users: Check who has access and whether sharing should continue
    4. Update Client Code: Identify all systems accessing the project that need updating
    5. Backup Data: Consider exporting important data before transfer

    During Transfer#

    1. Transfer at Low-Activity Time: Minimize disruption by transferring during quiet periods
    2. Test Access First: Verify new owner can access their other projects
    3. Use Correct Handle: Double-check the new owner’s handle before submitting

    After Transferring#

    1. Verify New Ownership: Confirm the transfer succeeded
    2. Update Client Applications: Change all API calls to use new owner handle
    3. Grant Back Access if Needed: New owner can share project back to old owner
    4. Update Documentation: Update any documentation referencing the project path
    5. Notify Shared Users: Inform shared users about the path change

    Maintaining Access After Transfer#

    If the original owner needs continued access, the new owner should share the project:

    # Step 1: Alice transfers to Bob
    +curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "bob"}'
    +
    +# Step 2: Bob shares back with Alice as editor
    +curl -X POST "https://api.example.com/v1/projects/bob/research-data/share" \
    +  -H "Authorization: Bearer bob_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"share_with_handle": "alice", "role": "editor"}'
    +
    +# Now Alice can still access (but as editor, not owner)
    +curl -X GET "https://api.example.com/v1/embeddings/bob/research-data" \
    +  -H "Authorization: Bearer alice_api_key"

    Checking Current Owner#

    To verify current project ownership:

    curl -X GET "https://api.example.com/v1/projects/{owner}/{project}" \
    +  -H "Authorization: Bearer your_api_key"

    The owner field in the response shows the current owner.

    Troubleshooting#

    Cannot Find Project After Transfer#

    Problem: Getting 404 after transfer

    Solution: Update the owner in your API calls:

    • Old: /v1/projects/alice/my-project
    • New: /v1/projects/bob/my-project

    Need to Reverse Transfer#

    Problem: Transferred by mistake, need to reverse

    Solution: New owner must transfer back:

    curl -X POST "https://api.example.com/v1/projects/bob/my-project/transfer-ownership" \
    +  -H "Authorization: Bearer bob_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"new_owner_handle": "alice"}'

    Client Applications Failing#

    Problem: Applications can’t access project after transfer

    Solution: Update all hardcoded owner references in your code to use the new owner’s handle.

    \ No newline at end of file diff --git a/docs/public/guides/project-sharing/index.html b/docs/public/guides/project-sharing/index.html new file mode 100644 index 0000000..5a54d9a --- /dev/null +++ b/docs/public/guides/project-sharing/index.html @@ -0,0 +1,142 @@ +Project Sharing Guide | dhamps-vdb Documentation + +

    Project Sharing Guide#

    This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.

    Overview#

    Project sharing allows you to grant other users access to your projects with different permission levels:

    • reader: Read-only access to embeddings and similar documents
    • editor: Read and write access to embeddings (can add/modify/delete embeddings)

    Only the project owner can manage sharing settings and delete the project.

    Sharing During Project Creation#

    You can specify users to share with when creating a new project using the shared_with field:

    curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "collaborative-project",
    +    "description": "A project shared with team members",
    +    "instance_id": 123,
    +    "shared_with": [
    +      {
    +        "user_handle": "bob",
    +        "role": "reader"
    +      },
    +      {
    +        "user_handle": "charlie",
    +        "role": "editor"
    +      }
    +    ]
    +  }'

    In this example:

    • bob can read embeddings and search for similar documents
    • charlie can read embeddings, search, and also add/modify/delete embeddings
    • alice (the owner) has full control including managing sharing and deleting the project

    Managing Sharing After Creation#

    Share a Project with a User#

    Add a user to an existing project:

    curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "david",
    +    "role": "reader"
    +  }'

    Response:

    {
    +  "message": "Project shared successfully",
    +  "user": "david",
    +  "role": "reader"
    +}

    Update User’s Role#

    To change a user’s role, simply share again with the new role:

    curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "share_with_handle": "david",
    +    "role": "editor"
    +  }'

    This updates David’s access from reader to editor.

    Unshare a Project from a User#

    Remove a user’s access to a project:

    curl -X DELETE "https://api.example.com/v1/projects/alice/collaborative-project/share/david" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "message": "Project unshared successfully",
    +  "user": "david"
    +}

    List Shared Users#

    View all users a project is shared with:

    curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project/shared-with" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "project_handle": "collaborative-project",
    +  "owner": "alice",
    +  "shared_with": [
    +    {
    +      "user_handle": "bob",
    +      "role": "reader"
    +    },
    +    {
    +      "user_handle": "charlie",
    +      "role": "editor"
    +    }
    +  ]
    +}

    Note: Only the project owner can view the list of shared users. Users who have been granted access cannot see which other users also have access.

    What Shared Users Can Do#

    As a Reader#

    Bob (with reader access) can:

    # View project metadata
    +curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project" \
    +  -H "Authorization: Bearer bob_api_key"
    +
    +# Retrieve embeddings
    +curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    +  -H "Authorization: Bearer bob_api_key"
    +
    +# Get a specific embedding
    +curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project/doc123" \
    +  -H "Authorization: Bearer bob_api_key"
    +
    +# Search for similar documents
    +curl -X GET "https://api.example.com/v1/similars/alice/collaborative-project/doc123?count=5" \
    +  -H "Authorization: Bearer bob_api_key"

    As an Editor#

    Charlie (with editor access) can do everything a reader can, plus:

    # Upload new embeddings
    +curl -X POST "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    +  -H "Authorization: Bearer charlie_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc456",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072,
    +      "metadata": {"author": "Charlie"}
    +    }]
    +  }'
    +
    +# Delete specific embeddings
    +curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project/doc456" \
    +  -H "Authorization: Bearer charlie_api_key"
    +
    +# Delete all embeddings
    +curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    +  -H "Authorization: Bearer charlie_api_key"

    What Shared Users Cannot Do#

    Even with editor access, shared users cannot:

    • Delete the project
    • Change project settings (description, instance, metadata schema)
    • Manage sharing (add/remove other users)
    • View the list of other shared users
    • Transfer project ownership

    These operations require owner privileges.

    Permission Summary Table#

    OperationOwnerEditorReader
    View project metadata
    Retrieve embeddings
    Search similar documents
    Add embeddings
    Modify embeddings
    Delete embeddings
    Update project settings
    Delete project
    Manage sharing
    View shared users list
    Transfer ownership

    Use Cases#

    Research Team Collaboration#

    A research team can share a project where:

    • The principal investigator (PI) is the owner
    • Research assistants have editor access to upload new data
    • External collaborators have reader access to query the data
    # PI creates and shares the project
    +curl -X PUT "https://api.example.com/v1/projects/pi/research-corpus" \
    +  -H "Authorization: Bearer pi_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-corpus",
    +    "description": "Research team corpus",
    +    "instance_id": 123,
    +    "shared_with": [
    +      {"user_handle": "assistant1", "role": "editor"},
    +      {"user_handle": "assistant2", "role": "editor"},
    +      {"user_handle": "external_collab", "role": "reader"}
    +    ]
    +  }'

    Data Pipeline with Read-Only Access#

    Share processed embeddings with downstream consumers:

    # Data processor creates project
    +curl -X PUT "https://api.example.com/v1/projects/processor/processed-data" \
    +  -H "Authorization: Bearer processor_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "processed-data",
    +    "description": "Processed embeddings for consumption",
    +    "instance_id": 456,
    +    "shared_with": [
    +      {"user_handle": "app_backend", "role": "reader"},
    +      {"user_handle": "analytics_team", "role": "reader"}
    +    ]
    +  }'

    Temporary Access#

    Grant temporary access to a consultant and revoke it later:

    # Grant access
    +curl -X POST "https://api.example.com/v1/projects/alice/sensitive-project/share" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"share_with_handle": "consultant", "role": "reader"}'
    +
    +# Revoke access when consultation is complete
    +curl -X DELETE "https://api.example.com/v1/projects/alice/sensitive-project/share/consultant" \
    +  -H "Authorization: Bearer alice_api_key"

    Combining with Public Access#

    You can combine user-specific sharing with public access (see Public Projects Guide):

    curl -X PUT "https://api.example.com/v1/projects/alice/mixed-access-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "mixed-access-project",
    +    "description": "Public read, specific editors",
    +    "instance_id": 123,
    +    "public_read": true,
    +    "shared_with": [
    +      {"user_handle": "bob", "role": "editor"}
    +    ]
    +  }'

    In this case:

    • Anyone can read the project (no authentication required)
    • bob can also edit (add/modify/delete embeddings)
    • alice retains full owner privileges

    Security Considerations#

    1. Choose Roles Carefully: Only grant editor access to trusted users who need to modify data
    2. Audit Access: Regularly review the shared users list to ensure appropriate access levels
    3. Revoke Promptly: Remove access immediately when users no longer need it
    4. Use Reader by Default: Start with reader access and upgrade to editor only when necessary
    5. Consider Public Access: For truly open data, use public_read: true instead of sharing with many users

    Troubleshooting#

    Cannot Share Project#

    Error: “Only the owner can share projects”

    Solution: Only the project owner can manage sharing. If you need to share the project, ask the owner to add you, or consider transferring ownership.

    User Not Found#

    Error: “User not found”

    Solution: The user must exist in the system before you can share a project with them. Ask the admin to create the user first.

    Cannot View Shared Users List#

    Error: “Forbidden”

    Solution: Only the project owner can view the list of shared users. Shared users cannot see other shared users for privacy reasons.

    \ No newline at end of file diff --git a/docs/public/guides/public-projects/index.html b/docs/public/guides/public-projects/index.html new file mode 100644 index 0000000..9e03df4 --- /dev/null +++ b/docs/public/guides/public-projects/index.html @@ -0,0 +1,162 @@ +Public Projects Guide | dhamps-vdb Documentation + +

    Public Projects Guide#

    This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.

    Overview#

    Projects can be configured to allow unauthenticated (public) read access by setting the public_read field to true. This is useful for:

    • Open datasets and research data
    • Public APIs and services
    • Shared knowledge bases
    • Educational resources

    Important: Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.

    Creating a Public Project#

    Set public_read to true when creating a project:

    curl -X PUT "https://api.example.com/v1/projects/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "public-knowledge",
    +    "description": "Publicly accessible knowledge base",
    +    "instance_id": 123,
    +    "public_read": true
    +  }'

    Response:

    {
    +  "project_handle": "public-knowledge",
    +  "owner": "alice",
    +  "description": "Publicly accessible knowledge base",
    +  "instance_id": 123,
    +  "public_read": true
    +}

    Making an Existing Project Public#

    Update an existing project using PATCH:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"public_read": true}'

    Making a Public Project Private#

    To disable public access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"public_read": false}'

    Accessing Public Projects Without Authentication#

    Once a project has public_read enabled, anyone can access it without providing an API key.

    Get Project Metadata#

    curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge"

    Response:

    {
    +  "project_handle": "public-knowledge",
    +  "owner": "alice",
    +  "description": "Publicly accessible knowledge base",
    +  "instance_id": 123,
    +  "public_read": true
    +}

    Retrieve All Embeddings#

    curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge?limit=100"

    Response:

    {
    +  "embeddings": [
    +    {
    +      "text_id": "doc001",
    +      "text": "Public document content",
    +      "metadata": {"category": "science"},
    +      "vector_dim": 3072
    +    },
    +    {
    +      "text_id": "doc002",
    +      "text": "Another public document",
    +      "metadata": {"category": "history"},
    +      "vector_dim": 3072
    +    }
    +  ]
    +}

    Get a Specific Embedding#

    curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001"

    Response:

    {
    +  "text_id": "doc001",
    +  "text": "Public document content",
    +  "metadata": {"category": "science"},
    +  "vector_dim": 3072,
    +  "vector": [0.021, -0.015, 0.043, ...]
    +}

    Search for Similar Documents#

    # Search by existing document ID
    +curl -X GET "https://api.example.com/v1/similars/alice/public-knowledge/doc001?count=5&threshold=0.7"

    Response:

    {
    +  "user_handle": "alice",
    +  "project_handle": "public-knowledge",
    +  "results": [
    +    {"id": "doc002", "similarity": 0.92},
    +    {"id": "doc003", "similarity": 0.85},
    +    {"id": "doc004", "similarity": 0.78}
    +  ]
    +}

    Search with Raw Embeddings#

    curl -X POST "https://api.example.com/v1/similars/alice/public-knowledge?count=5" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [0.032, -0.018, 0.056, ...]
    +  }'

    Operations Still Requiring Authentication#

    Even for public projects, these operations require authentication:

    Creating Embeddings (Requires Auth)#

    # This will fail with 401 Unauthorized
    +curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    +  -H "Content-Type: application/json" \
    +  -d '{"embeddings": [...]}'
    +
    +# This succeeds with valid API key
    +curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc123",
    +      "instance_handle": "openai-large",
    +      "vector": [0.1, 0.2, 0.3, ...],
    +      "vector_dim": 3072
    +    }]
    +  }'

    Deleting Embeddings (Requires Auth)#

    # Delete specific embedding (requires auth)
    +curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001" \
    +  -H "Authorization: Bearer alice_api_key"
    +
    +# Delete all embeddings (requires auth)
    +curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key"

    Modifying Project Settings (Requires Auth)#

    # Update project description (requires auth)
    +curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"description": "Updated description"}'

    Deleting Project (Requires Auth)#

    curl -X DELETE "https://api.example.com/v1/projects/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key"

    Combining Public Access with User Sharing#

    You can combine public read access with user-specific editor permissions:

    curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-public" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "collaborative-public",
    +    "description": "Public read, restricted write",
    +    "instance_id": 123,
    +    "public_read": true,
    +    "shared_with": [
    +      {
    +        "user_handle": "bob",
    +        "role": "editor"
    +      },
    +      {
    +        "user_handle": "charlie",
    +        "role": "editor"
    +      }
    +    ]
    +  }'

    In this configuration:

    • Anyone can read embeddings and search (no auth required)
    • bob and charlie can add/modify/delete embeddings (with auth)
    • alice (owner) has full control (with auth)

    Use Cases#

    Open Research Dataset#

    Share research data publicly while maintaining write control:

    curl -X PUT "https://api.example.com/v1/projects/university/research-corpus" \
    +  -H "Authorization: Bearer university_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "research-corpus",
    +    "description": "Open research corpus for academic use",
    +    "instance_id": 456,
    +    "public_read": true,
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"doi\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"doi\"]}"
    +  }'

    Researchers worldwide can access the data without credentials, but only authorized users can add new data.

    Public API Backend#

    Build a public search API on top of dhamps-vdb:

    import requests
    +
    +def public_search_api(query_vector, count=10):
    +    """Public search function requiring no authentication"""
    +    response = requests.post(
    +        "https://api.example.com/v1/similars/company/product-docs",
    +        json={"vector": query_vector},
    +        params={"count": count, "threshold": 0.6}
    +    )
    +    return response.json()
    +
    +# No API key needed for public projects!
    +results = public_search_api(query_embedding)

    Educational Resources#

    Share educational content publicly:

    curl -X PUT "https://api.example.com/v1/projects/edu/learning-materials" \
    +  -H "Authorization: Bearer edu_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "learning-materials",
    +    "description": "Free educational content embeddings",
    +    "instance_id": 789,
    +    "public_read": true
    +  }'

    Students and educators can access the materials without creating accounts.

    Community-Driven Knowledge Base#

    Open knowledge base with restricted editors:

    curl -X PUT "https://api.example.com/v1/projects/community/wiki-embeddings" \
    +  -H "Authorization: Bearer community_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "wiki-embeddings",
    +    "description": "Community wiki embeddings",
    +    "instance_id": 321,
    +    "public_read": true,
    +    "shared_with": [
    +      {"user_handle": "moderator1", "role": "editor"},
    +      {"user_handle": "moderator2", "role": "editor"}
    +    ]
    +  }'

    Security Considerations#

    What is Publicly Visible#

    When public_read is enabled:

    • ✅ Project metadata (name, description, owner)
    • ✅ All embedding vectors and text content
    • ✅ All embedding metadata
    • ✅ Vector dimensions and instance references
    • ❌ API keys (never exposed)
    • ❌ User passwords or credentials

    Best Practices#

    1. Review Content First: Ensure no sensitive information is in embeddings or metadata before enabling public access
    2. Use Metadata Schemas: Enforce consistent metadata structure with validation
    3. Monitor Usage: Track access patterns to your public projects
    4. Set Clear Descriptions: Provide clear project descriptions explaining the data’s purpose and licensing
    5. Consider Rate Limiting: For high-traffic public APIs, implement rate limiting at the application level

    What to Avoid#

    Don’t make projects public that contain:

    • Personal identifiable information (PII)
    • Proprietary or confidential data
    • Sensitive research data not yet published
    • Internal company information

    Do make projects public that contain:

    • Already-published research data
    • Open educational resources
    • Public domain content
    • Creative Commons licensed materials

    Disabling Public Access#

    If you need to make a public project private again:

    curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"public_read": false}'

    After this change:

    • All read operations require authentication
    • Existing anonymous access is immediately revoked
    • No data is deleted, just access is restricted

    Checking if a Project is Public#

    View project metadata to check the public_read flag:

    curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge"

    Look for "public_read": true in the response.

    Troubleshooting#

    Public Access Not Working#

    Symptom: Still getting 401 Unauthorized for public project

    Solutions:

    1. Verify public_read: true is set:
      curl -X GET "https://api.example.com/v1/projects/alice/my-project"
    2. Check you’re using GET/POST for similars (not other methods)
    3. Ensure the project exists and handle is correct

    Accidentally Made Project Public#

    Solution: Immediately disable public access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{"public_read": false}'

    Want to Track Public Usage#

    Solution: Anonymous requests are logged with user set to “public”. Review server logs to monitor public access patterns.

    \ No newline at end of file diff --git a/docs/public/guides/rag-workflow/index.html b/docs/public/guides/rag-workflow/index.html new file mode 100644 index 0000000..d00aa26 --- /dev/null +++ b/docs/public/guides/rag-workflow/index.html @@ -0,0 +1,228 @@ +RAG Workflow Guide | dhamps-vdb Documentation + +

    Complete RAG Workflow Guide#

    This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.

    Overview#

    A typical RAG workflow involves:

    1. Generate embeddings from your text content (using an external LLM service)
    2. Upload embeddings to dhamps-vdb
    3. Search for similar documents based on a query
    4. Retrieve the relevant context
    5. Use the context with an LLM to generate responses

    Prerequisites#

    • Access to dhamps-vdb API with a valid API key
    • An external LLM service for generating embeddings (e.g., OpenAI, Cohere)
    • Text content you want to process

    Step 1: Generate Embeddings Externally#

    First, use your chosen LLM service to generate embeddings for your text content. Here’s an example using OpenAI’s API:

    import openai
    +
    +# Initialize OpenAI client
    +client = openai.OpenAI(api_key="your-openai-key")
    +
    +# Generate embeddings for your text
    +text = "The quick brown fox jumps over the lazy dog"
    +response = client.embeddings.create(
    +    model="text-embedding-3-large",
    +    input=text,
    +    dimensions=3072
    +)
    +
    +embedding_vector = response.data[0].embedding

    Step 2: Create LLM Service Instance#

    Before uploading embeddings, create an LLM service instance in dhamps-vdb that matches your embedding configuration:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "endpoint": "https://api.openai.com/v1/embeddings",
    +    "api_standard": "openai",
    +    "model": "text-embedding-3-large",
    +    "dimensions": 3072,
    +    "description": "OpenAI large embedding model",
    +    "api_key_encrypted": "sk-proj-your-openai-key"
    +  }'

    Response:

    {
    +  "instance_id": 123,
    +  "instance_handle": "my-openai",
    +  "owner": "alice",
    +  "endpoint": "https://api.openai.com/v1/embeddings",
    +  "model": "text-embedding-3-large",
    +  "dimensions": 3072
    +}

    Step 3: Create a Project#

    Create a project to organize your embeddings:

    curl -X PUT "https://api.example.com/v1/projects/alice/my-documents" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "project_handle": "my-documents",
    +    "description": "Document embeddings for RAG",
    +    "instance_id": 123
    +  }'

    Step 4: Upload Embeddings to dhamps-vdb#

    Upload your pre-generated embeddings along with metadata and optional text content:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-documents" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "embeddings": [{
    +      "text_id": "doc001",
    +      "instance_handle": "my-openai",
    +      "vector": [0.021, -0.015, 0.043, ...],
    +      "vector_dim": 3072,
    +      "text": "The quick brown fox jumps over the lazy dog",
    +      "metadata": {
    +        "source": "example.txt",
    +        "author": "Alice",
    +        "category": "animals"
    +      }
    +    }]
    +  }'

    Tip: Upload multiple embeddings in batches for efficiency (see Batch Operations Guide).

    Step 5: Search for Similar Documents#

    When you need to retrieve relevant context for a query:

    Option A: Search by Stored Document ID#

    If you already have a document in your database that represents your query:

    curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_api_key"

    Option B: Search with Raw Query Embedding#

    Generate an embedding for your query and search without storing it:

    # Generate query embedding
    +query = "What animals are mentioned?"
    +query_response = client.embeddings.create(
    +    model="text-embedding-3-large",
    +    input=query,
    +    dimensions=3072
    +)
    +query_vector = query_response.data[0].embedding
    curl -X POST "https://api.example.com/v1/similars/alice/my-documents?count=5&threshold=0.7" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "vector": [0.032, -0.018, 0.056, ...]
    +  }'

    Response:

    {
    +  "user_handle": "alice",
    +  "project_handle": "my-documents",
    +  "results": [
    +    {
    +      "id": "doc001",
    +      "similarity": 0.95
    +    },
    +    {
    +      "id": "doc042",
    +      "similarity": 0.87
    +    },
    +    {
    +      "id": "doc103",
    +      "similarity": 0.82
    +    }
    +  ]
    +}

    Step 6: Retrieve Context Documents#

    Retrieve the full content and metadata for the most similar documents:

    curl -X GET "https://api.example.com/v1/embeddings/alice/my-documents/doc001" \
    +  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    +  "text_id": "doc001",
    +  "text": "The quick brown fox jumps over the lazy dog",
    +  "metadata": {
    +    "source": "example.txt",
    +    "author": "Alice",
    +    "category": "animals"
    +  },
    +  "vector_dim": 3072
    +}

    Step 7: Use Context with LLM#

    Combine the retrieved context with your original query to generate an informed response:

    # Collect context from similar documents
    +context_docs = []
    +for result in similarity_results['results'][:3]:
    +    doc = get_document(result['id'])  # Your function to fetch document
    +    context_docs.append(doc['text'])
    +
    +# Build context string
    +context = "\n\n".join(context_docs)
    +
    +# Generate response with context
    +response = client.chat.completions.create(
    +    model="gpt-4",
    +    messages=[
    +        {"role": "system", "content": "Answer based on the provided context."},
    +        {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
    +    ]
    +)
    +
    +answer = response.choices[0].message.content

    Complete Python Example#

    Here’s a complete example combining all steps:

    import openai
    +import requests
    +
    +# Configuration
    +DHAMPS_API = "https://api.example.com"
    +DHAMPS_KEY = "your-dhamps-api-key"
    +OPENAI_KEY = "your-openai-key"
    +
    +# Initialize OpenAI
    +client = openai.OpenAI(api_key=OPENAI_KEY)
    +
    +def embed_and_store(text_id, text, metadata=None):
    +    """Generate embedding and store in dhamps-vdb"""
    +    # Generate embedding
    +    response = client.embeddings.create(
    +        model="text-embedding-3-large",
    +        input=text,
    +        dimensions=3072
    +    )
    +    vector = response.data[0].embedding
    +    
    +    # Upload to dhamps-vdb
    +    requests.post(
    +        f"{DHAMPS_API}/v1/embeddings/alice/my-documents",
    +        headers={
    +            "Authorization": f"Bearer {DHAMPS_KEY}",
    +            "Content-Type": "application/json"
    +        },
    +        json={
    +            "embeddings": [{
    +                "text_id": text_id,
    +                "instance_handle": "my-openai",
    +                "vector": vector,
    +                "vector_dim": 3072,
    +                "text": text,
    +                "metadata": metadata or {}
    +            }]
    +        }
    +    )
    +
    +def search_similar(query, count=5):
    +    """Search for similar documents using query text"""
    +    # Generate query embedding
    +    response = client.embeddings.create(
    +        model="text-embedding-3-large",
    +        input=query,
    +        dimensions=3072
    +    )
    +    query_vector = response.data[0].embedding
    +    
    +    # Search in dhamps-vdb
    +    result = requests.post(
    +        f"{DHAMPS_API}/v1/similars/alice/my-documents?count={count}",
    +        headers={
    +            "Authorization": f"Bearer {DHAMPS_KEY}",
    +            "Content-Type": "application/json"
    +        },
    +        json={"vector": query_vector}
    +    )
    +    return result.json()['results']
    +
    +def retrieve_context(doc_ids):
    +    """Retrieve full document content"""
    +    docs = []
    +    for doc_id in doc_ids:
    +        response = requests.get(
    +            f"{DHAMPS_API}/v1/embeddings/alice/my-documents/{doc_id}",
    +            headers={"Authorization": f"Bearer {DHAMPS_KEY}"}
    +        )
    +        docs.append(response.json())
    +    return docs
    +
    +def rag_query(query):
    +    """Complete RAG workflow"""
    +    # Search for similar documents
    +    similar = search_similar(query, count=3)
    +    
    +    # Retrieve context
    +    context_docs = retrieve_context([r['id'] for r in similar])
    +    context = "\n\n".join([doc['text'] for doc in context_docs])
    +    
    +    # Generate answer with LLM
    +    response = client.chat.completions.create(
    +        model="gpt-4",
    +        messages=[
    +            {"role": "system", "content": "Answer based on the provided context."},
    +            {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
    +        ]
    +    )
    +    
    +    return response.choices[0].message.content
    +
    +# Usage
    +embed_and_store("doc001", "The quick brown fox jumps over the lazy dog", 
    +                {"category": "animals"})
    +answer = rag_query("What animals are mentioned?")
    +print(answer)

    Best Practices#

    1. Batch Upload: Upload embeddings in batches of 100-1000 for better performance
    2. Use Metadata: Include rich metadata for better filtering and organization
    3. Set Thresholds: Use similarity thresholds (e.g., 0.7) to filter low-quality matches
    4. Cache Embeddings: Cache generated embeddings to avoid redundant API calls
    5. Monitor Dimensions: Ensure all embeddings use consistent dimensions (3072 for text-embedding-3-large)

    Advanced Features#

    Metadata Filtering#

    Exclude certain documents from search results using metadata filters:

    # Exclude documents from the same author as the query
    +curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?metadata_path=author&metadata_value=Alice" \
    +  -H "Authorization: Bearer alice_api_key"

    See the Metadata Filtering Guide for more details.

    Metadata Validation#

    Enforce consistent metadata structure using JSON Schema validation:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-documents" \
    +  -H "Authorization: Bearer alice_api_key" \
    +  -H "Content-Type: application/json" \
    +  -d '{
    +    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"category\":{\"type\":\"string\"}},\"required\":[\"author\"]}"
    +  }'

    See the Metadata Validation Guide for more details.

    Troubleshooting#

    Dimension Mismatch Error#

    {
    +  "title": "Bad Request",
    +  "status": 400,
    +  "detail": "dimension validation failed: vector dimension mismatch"
    +}

    Solution: Ensure the vector_dim field matches the dimensions configured in your LLM service instance.

    No Similar Results#

    If searches return no results, try:

    • Lowering the similarity threshold (e.g., from 0.8 to 0.5)
    • Increasing the count parameter
    • Verifying embeddings are uploaded correctly
    • Checking that query embeddings use the same model and dimensions
    \ No newline at end of file diff --git a/docs/public/icons/toc.svg b/docs/public/icons/toc.svg new file mode 100644 index 0000000..ed75c4a --- /dev/null +++ b/docs/public/icons/toc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/index.html b/docs/public/index.html index 71df4c0..85137d4 100644 --- a/docs/public/index.html +++ b/docs/public/index.html @@ -1,3 +1,21 @@ -dhamps-vdb Documentation | dhamps-vdb Documentation - -
    \ No newline at end of file +dhamps-vdb Documentation | dhamps-vdb Documentation + +

    dhamps-vdb Documentation#

    Welcome to the documentation for dhamps-vdb, a vector database designed for Digital Humanities applications at the Max Planck Society initiative.

    What is dhamps-vdb?#

    dhamps-vdb is a PostgreSQL-backed vector database with pgvector support, providing a RESTful API for managing embeddings in Retrieval Augmented Generation (RAG) workflows. It offers multi-user support, project management, and flexible embedding configurations.

    Key Features#

    • Multi-user Support: Role-based access control (admin, owner, reader, editor)
    • Project Management: Organize embeddings into projects with sharing capabilities
    • LLM Service Management: Flexible service definitions and instances with encrypted API keys
    • Metadata Support: JSON Schema validation and filtering in similarity search
    • PostgreSQL Backend: Reliable storage with pgvector extension
    • RESTful API: OpenAPI-documented endpoints
    • Docker Ready: Easy deployment with Docker Compose

    Getting Help#

    Quick Example#

    # Start the service with Docker
    +./docker-setup.sh
    +docker-compose up -d
    +
    +# Create a user
    +curl -X POST http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    +  -H "Content-Type: application/json" \
    +  -d '{"user_handle": "alice", "name": "Alice Smith"}'
    +
    +# Create a project and start working with embeddings
    +# See the Getting Started guide for a complete walkthrough

    Ready to get started? Head over to the Installation Guide.

    \ No newline at end of file diff --git a/docs/public/index.xml b/docs/public/index.xml index 58d695d..a61f35a 100644 --- a/docs/public/index.xml +++ b/docs/public/index.xml @@ -1 +1,959 @@ -dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/Recent content on dhamps-vdb DocumentationHugoen-us \ No newline at end of file +dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/Recent content on dhamps-vdb DocumentationHugoen-usArchitecturehttps://mpilhlt.github.io/dhamps-vdb/concepts/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/<h1 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h1> +<p>dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.</p> +<h2 id="system-overview">System Overview<a class="anchor" href="#system-overview">#</a></h2> +<pre tabindex="0"><code>┌─────────────┐ +│ Client │ +│ Application │ +└──────┬──────┘ + │ HTTP/REST + │ +┌──────▼──────────────────────────┐ +│ dhamps-vdb API Server │ +│ ┌──────────────────────────┐ │ +│ │ Authentication Layer │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Request Handlers │ │ +│ │ (Users, Projects, etc) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ Validation Layer │ │ +│ │ (Dimensions, Metadata) │ │ +│ └────────┬─────────────────┘ │ +│ ┌────────▼─────────────────┐ │ +│ │ SQLC Queries │ │ +│ │ (Type-safe SQL) │ │ +│ └────────┬─────────────────┘ │ +└───────────┼──────────────────────┘ + │ + ┌───────▼──────────────┐ + │ PostgreSQL + 16 │ + │ with pgvector 0.7 │ + │ │ + │ ┌────────────────┐ │ + │ │ Vector Index │ │ + │ │ (HNSW/IVFFlat) │ │ + │ └────────────────┘ │ + └──────────────────────┘</code></pre><h2 id="core-components">Core Components<a class="anchor" href="#core-components">#</a></h2> +<h3 id="api-layer">API Layer<a class="anchor" href="#api-layer">#</a></h3> +<p>Built with <a href="https://huma.rocks/">Huma</a> framework on top of Go&rsquo;s <code>http.ServeMux</code>:</p>Authenticationhttps://mpilhlt.github.io/dhamps-vdb/api/authentication/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/authentication/<h1 id="api-authentication">API Authentication<a class="anchor" href="#api-authentication">#</a></h1> +<p>All API requests (except public project read operations) require authentication using API keys passed in the <code>Authorization</code> header with a <code>Bearer</code> prefix.</p> +<h2 id="authentication-method">Authentication Method<a class="anchor" href="#authentication-method">#</a></h2> +<p>Include your API key in the <code>Authorization</code> header of every request:</p> +<pre tabindex="0"><code>Authorization: Bearer your_api_key_here</code></pre><h2 id="api-key-types">API Key Types<a class="anchor" href="#api-key-types">#</a></h2> +<h3 id="admin-api-key">Admin API Key<a class="anchor" href="#admin-api-key">#</a></h3> +<ul> +<li>Full access to all API endpoints and resources</li> +<li>Can create and manage users</li> +<li>Can access all projects and resources across all users</li> +<li>Required for administrative operations</li> +<li>Set via <code>ADMIN_KEY</code> environment variable</li> +</ul> +<p><strong>Admin-only operations:</strong></p>Configuration Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/configuration/<h1 id="configuration-reference">Configuration Reference<a class="anchor" href="#configuration-reference">#</a></h1> +<p>Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb is configured through a combination of:</p> +<ol> +<li><strong>Environment variables</strong> (recommended)</li> +<li><strong>Command-line flags</strong> (overrides environment variables)</li> +<li><strong><code>.env</code> files</strong> (for Docker and local development)</li> +</ol> +<p>Configuration is loaded in the following priority order (highest to lowest):</p> +<ol> +<li>Command-line flags</li> +<li>Environment variables</li> +<li><code>.env</code> file values</li> +<li>Default values from <code>options.go</code></li> +</ol> +<h2 id="configuration-options">Configuration Options<a class="anchor" href="#configuration-options">#</a></h2> +<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> +<p>Options for controlling the API service behavior.</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/deployment/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> +<p>This guide covers production-focused Docker deployment for dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>For detailed Docker setup instructions, see <a href="../../getting-started/docker/">Getting Started with Docker</a>. This page focuses on production deployment considerations.</p> +<h2 id="production-deployment">Production Deployment<a class="anchor" href="#production-deployment">#</a></h2> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<ul> +<li>Docker Engine 20.10+</li> +<li>Docker Compose 2.0+ (or docker-compose 1.29+)</li> +<li>PostgreSQL 11+ with pgvector extension (included in compose setup)</li> +</ul> +<h3 id="quick-production-setup">Quick Production Setup<a class="anchor" href="#quick-production-setup">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate secure keys</span> +</span></span><span style="display:flex;"><span>./docker-setup.sh +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Review and customize .env</span> +</span></span><span style="display:flex;"><span>nano .env +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Deploy</span> +</span></span><span style="display:flex;"><span>docker-compose up -d</span></span></code></pre></div><h2 id="production-considerations">Production Considerations<a class="anchor" href="#production-considerations">#</a></h2> +<h3 id="use-reverse-proxy">Use Reverse Proxy<a class="anchor" href="#use-reverse-proxy">#</a></h3> +<p>Always run behind a reverse proxy (nginx, Traefik, Caddy) for:</p>Installationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/installation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/<h1 id="installation">Installation<a class="anchor" href="#installation">#</a></h1> +<p>Install dhamps-vdb by compiling from source.</p> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li><strong>Go 1.21 or later</strong></li> +<li><strong>PostgreSQL 11+</strong> with pgvector extension</li> +<li><strong>sqlc</strong> for code generation</li> +</ul> +<h2 id="quick-install">Quick Install<a class="anchor" href="#quick-install">#</a></h2> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies and generate code</span> +</span></span><span style="display:flex;"><span>go get ./... +</span></span><span style="display:flex;"><span>sqlc generate --no-remote +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build the binary</span> +</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go</span></span></code></pre></div><h2 id="detailed-steps">Detailed Steps<a class="anchor" href="#detailed-steps">#</a></h2> +<h3 id="1-install-dependencies">1. Install Dependencies<a class="anchor" href="#1-install-dependencies">#</a></h3> +<p>Download all Go module dependencies:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get ./...</span></span></code></pre></div><h3 id="2-generate-database-code">2. Generate Database Code<a class="anchor" href="#2-generate-database-code">#</a></h3> +<p>Generate type-safe database queries using sqlc:</p>RAG Workflow Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/<h1 id="complete-rag-workflow-guide">Complete RAG Workflow Guide<a class="anchor" href="#complete-rag-workflow-guide">#</a></h1> +<p>This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>A typical RAG workflow involves:</p> +<ol> +<li>Generate embeddings from your text content (using an external LLM service)</li> +<li>Upload embeddings to dhamps-vdb</li> +<li>Search for similar documents based on a query</li> +<li>Retrieve the relevant context</li> +<li>Use the context with an LLM to generate responses</li> +</ol> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li>Access to dhamps-vdb API with a valid API key</li> +<li>An external LLM service for generating embeddings (e.g., OpenAI, Cohere)</li> +<li>Text content you want to process</li> +</ul> +<h2 id="step-1-generate-embeddings-externally">Step 1: Generate Embeddings Externally<a class="anchor" href="#step-1-generate-embeddings-externally">#</a></h2> +<p>First, use your chosen LLM service to generate embeddings for your text content. Here&rsquo;s an example using OpenAI&rsquo;s API:</p>Testinghttps://mpilhlt.github.io/dhamps-vdb/development/testing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/testing/<h1 id="testing-guide">Testing Guide<a class="anchor" href="#testing-guide">#</a></h1> +<p>This guide covers how to run and write tests for dhamps-vdb.</p> +<h2 id="running-tests">Running Tests<a class="anchor" href="#running-tests">#</a></h2> +<p>dhamps-vdb uses integration tests that spin up real PostgreSQL containers using <a href="https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/">testcontainers</a>. This approach ensures tests run against actual database instances with pgvector support.</p> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<p><strong>Using Podman (Recommended for Linux):</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start podman socket</span> +</span></span><span style="display:flex;"><span>systemctl --user start podman.socket +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Export DOCKER_HOST for testcontainers</span> +</span></span><span style="display:flex;"><span>export DOCKER_HOST<span style="color:#f92672">=</span>unix://$XDG_RUNTIME_DIR/podman/podman.sock</span></span></code></pre></div><p><strong>Using Docker:</strong></p> +<p>Testcontainers works with Docker out of the box. Ensure Docker daemon is running.</p>Usershttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/<h1 id="users-endpoint">Users Endpoint<a class="anchor" href="#users-endpoint">#</a></h1> +<p>Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-all-users">List All Users<a class="anchor" href="#list-all-users">#</a></h3> +<p>Get a list of all registered user handles.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/users</code></p> +<p><strong>Authentication:</strong> Admin only</p> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/users&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer admin_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;users&#34;</span>: [<span style="color:#e6db74">&#34;alice&#34;</span>, <span style="color:#e6db74">&#34;bob&#34;</span>, <span style="color:#e6db74">&#34;charlie&#34;</span>] +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> +<h3 id="create-user">Create User<a class="anchor" href="#create-user">#</a></h3> +<p>Register a new user and generate their API key.</p> +<p><strong>Endpoint:</strong> <code>POST /v1/users</code></p> +<p><strong>Authentication:</strong> Admin only</p> +<p><strong>Request Body:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Doe&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Parameters:</strong></p>Configurationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/<h1 id="configuration">Configuration<a class="anchor" href="#configuration">#</a></h1> +<p>Configure dhamps-vdb using environment variables or command-line options.</p> +<h2 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h2> +<p>All configuration can be set via environment variables. Use a <code>.env</code> file to keep sensitive information secure.</p> +<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_DEBUG</code></td> + <td>Enable debug logging</td> + <td><code>true</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_HOST</code></td> + <td>Hostname to listen on</td> + <td><code>localhost</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_PORT</code></td> + <td>Port to listen on</td> + <td><code>8880</code></td> + <td>No</td> + </tr> + </tbody> +</table> +<h3 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_DBHOST</code></td> + <td>Database hostname</td> + <td><code>localhost</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBPORT</code></td> + <td>Database port</td> + <td><code>5432</code></td> + <td>No</td> + </tr> + <tr> + <td><code>SERVICE_DBUSER</code></td> + <td>Database username</td> + <td><code>postgres</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBPASSWORD</code></td> + <td>Database password</td> + <td><code>password</code></td> + <td>Yes</td> + </tr> + <tr> + <td><code>SERVICE_DBNAME</code></td> + <td>Database name</td> + <td><code>postgres</code></td> + <td>Yes</td> + </tr> + </tbody> +</table> +<h3 id="security-configuration">Security Configuration<a class="anchor" href="#security-configuration">#</a></h3> +<table> + <thead> + <tr> + <th>Variable</th> + <th>Description</th> + <th>Default</th> + <th>Required</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SERVICE_ADMINKEY</code></td> + <td>Admin API key for administrative operations</td> + <td>-</td> + <td>Yes</td> + </tr> + <tr> + <td><code>ENCRYPTION_KEY</code></td> + <td>Encryption key for API keys (32+ characters)</td> + <td>-</td> + <td>Yes</td> + </tr> + </tbody> +</table> +<h2 id="configuration-file">Configuration File<a class="anchor" href="#configuration-file">#</a></h2> +<p>Create a <code>.env</code> file in the project root:</p>Contributinghttps://mpilhlt.github.io/dhamps-vdb/development/contributing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/contributing/<h1 id="contributing-guide">Contributing Guide<a class="anchor" href="#contributing-guide">#</a></h1> +<p>Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.</p> +<h2 id="development-setup">Development Setup<a class="anchor" href="#development-setup">#</a></h2> +<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> +<ul> +<li><strong>Go 1.21+</strong>: <a href="https://go.dev/dl/">Download Go</a></li> +<li><strong>PostgreSQL 16+</strong>: With pgvector extension</li> +<li><strong>sqlc</strong>: For generating type-safe database code</li> +<li><strong>Docker/Podman</strong>: For running tests</li> +<li><strong>Git</strong>: For version control</li> +</ul> +<h3 id="clone-and-build">Clone and Build<a class="anchor" href="#clone-and-build">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies</span> +</span></span><span style="display:flex;"><span>go get ./... +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate sqlc code</span> +</span></span><span style="display:flex;"><span>sqlc generate --no-remote +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build application</span> +</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Or run directly</span> +</span></span><span style="display:flex;"><span>go run main.go</span></span></code></pre></div><h3 id="environment-setup">Environment Setup<a class="anchor" href="#environment-setup">#</a></h3> +<p>Create a <code>.env</code> file for local development:</p>Database Schema Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/database-schema/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/<h1 id="database-schema-reference">Database Schema Reference<a class="anchor" href="#database-schema-reference">#</a></h1> +<p>Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in <code>internal/database/migrations/</code>.</p> +<p><strong>Key Features:</strong></p> +<ul> +<li>Vector embeddings stored as <code>halfvec</code> for efficient storage</li> +<li>HNSW indexes for fast approximate nearest neighbor search</li> +<li>Automatic timestamp tracking (<code>created_at</code>, <code>updated_at</code>)</li> +<li>Foreign key constraints with CASCADE deletion</li> +<li>Role-based access control through association tables</li> +<li>Multi-tenancy support (user-owned resources)</li> +</ul> +<h2 id="schema-migrations">Schema Migrations<a class="anchor" href="#schema-migrations">#</a></h2> +<p>Current schema version is defined by 4 migration files:</p>Database Setuphttps://mpilhlt.github.io/dhamps-vdb/deployment/database/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/database/<h1 id="database-setup">Database Setup<a class="anchor" href="#database-setup">#</a></h1> +<p>dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.</p> +<h2 id="requirements">Requirements<a class="anchor" href="#requirements">#</a></h2> +<ul> +<li><strong>PostgreSQL</strong>: Version 11 or higher</li> +<li><strong>pgvector</strong>: Extension for vector similarity search</li> +<li><strong>Storage</strong>: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)</li> +</ul> +<h2 id="installing-postgresql-with-pgvector">Installing PostgreSQL with pgvector<a class="anchor" href="#installing-postgresql-with-pgvector">#</a></h2> +<h3 id="using-docker-recommended">Using Docker (Recommended)<a class="anchor" href="#using-docker-recommended">#</a></h3> +<p>The easiest way to get PostgreSQL with pgvector:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --name postgres-pgvector <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -p 5432:5432 <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>secure_password <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -v postgres_data:/var/lib/postgresql/data <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> pgvector/pgvector:0.7.4-pg16</span></span></code></pre></div><h3 id="on-ubuntudebian">On Ubuntu/Debian<a class="anchor" href="#on-ubuntudebian">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Add PostgreSQL APT repository</span> +</span></span><span style="display:flex;"><span>sudo apt install curl ca-certificates +</span></span><span style="display:flex;"><span>sudo install -d /usr/share/postgresql-common/pgdg +</span></span><span style="display:flex;"><span>sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> https://www.postgresql.org/media/keys/ACCC4CF8.asc +</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> https://apt.postgresql.org/pub/repos/apt </span><span style="color:#66d9ef">$(</span>lsb_release -cs<span style="color:#66d9ef">)</span><span style="color:#e6db74">-pgdg main&#34;</span> | <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> sudo tee /etc/apt/sources.list.d/pgdg.list +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> +</span></span><span style="display:flex;"><span>sudo apt update +</span></span><span style="display:flex;"><span>sudo apt install postgresql-16 postgresql-contrib-16 +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector</span> +</span></span><span style="display:flex;"><span>sudo apt install postgresql-16-pgvector</span></span></code></pre></div><h3 id="on-macos">On macOS<a class="anchor" href="#on-macos">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Using Homebrew</span> +</span></span><span style="display:flex;"><span>brew install postgresql@16 +</span></span><span style="display:flex;"><span>brew install pgvector +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start PostgreSQL</span> +</span></span><span style="display:flex;"><span>brew services start postgresql@16</span></span></code></pre></div><h3 id="on-rhelcentosfedora">On RHEL/CentOS/Fedora<a class="anchor" href="#on-rhelcentosfedora">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> +</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-server postgresql16-contrib +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector (build from source)</span> +</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-devel git gcc make +</span></span><span style="display:flex;"><span>git clone https://github.com/pgvector/pgvector.git +</span></span><span style="display:flex;"><span>cd pgvector +</span></span><span style="display:flex;"><span>make +</span></span><span style="display:flex;"><span>sudo make install PG_CONFIG<span style="color:#f92672">=</span>/usr/pgsql-16/bin/pg_config</span></span></code></pre></div><h2 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h2> +<h3 id="step-1-create-database">Step 1: Create Database<a class="anchor" href="#step-1-create-database">#</a></h3> +<p>Connect to PostgreSQL as superuser:</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/getting-started/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> +<p>Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.</p> +<h2 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h2> +<p>The fastest way to get dhamps-vdb running with Docker:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> +</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git +</span></span><span style="display:flex;"><span>cd dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Run automated setup (generates secure keys)</span> +</span></span><span style="display:flex;"><span>./docker-setup.sh +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start services with docker-compose</span> +</span></span><span style="display:flex;"><span>docker-compose up -d +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Check logs</span> +</span></span><span style="display:flex;"><span>docker-compose logs -f dhamps-vdb +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#75715e"># Access the API</span> +</span></span><span style="display:flex;"><span>curl http://localhost:8880/docs</span></span></code></pre></div><h2 id="whats-included">What&rsquo;s Included<a class="anchor" href="#whats-included">#</a></h2> +<p>The Docker Compose setup includes:</p>Project Sharing Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/<h1 id="project-sharing-guide">Project Sharing Guide<a class="anchor" href="#project-sharing-guide">#</a></h1> +<p>This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Project sharing allows you to grant other users access to your projects with different permission levels:</p> +<ul> +<li><strong>reader</strong>: Read-only access to embeddings and similar documents</li> +<li><strong>editor</strong>: Read and write access to embeddings (can add/modify/delete embeddings)</li> +</ul> +<p>Only the project owner can manage sharing settings and delete the project.</p> +<h2 id="sharing-during-project-creation">Sharing During Project Creation<a class="anchor" href="#sharing-during-project-creation">#</a></h2> +<p>You can specify users to share with when creating a new project using the <code>shared_with</code> field:</p>Projectshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/<h1 id="projects-endpoint">Projects Endpoint<a class="anchor" href="#projects-endpoint">#</a></h1> +<p>Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-users-projects">List User&rsquo;s Projects<a class="anchor" href="#list-users-projects">#</a></h3> +<p>Get all projects owned by a user.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/projects/{username}</code></p> +<p><strong>Authentication:</strong> Admin, the user themselves, or users with shared access</p> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/projects/alice&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;projects&#34;</span>: [ +</span></span><span style="display:flex;"><span> { +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_id&#34;</span>: <span style="color:#ae81ff">1</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_handle&#34;</span>: <span style="color:#e6db74">&#34;research-docs&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Research document embeddings&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_id&#34;</span>: <span style="color:#ae81ff">5</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;openai-large&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;public_read&#34;</span>: <span style="color:#66d9ef">false</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> +</span></span><span style="display:flex;"><span> } +</span></span><span style="display:flex;"><span> ] +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> +<h3 id="create-project">Create Project<a class="anchor" href="#create-project">#</a></h3> +<p>Register a new project for a user.</p>Users and Authenticationhttps://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/<h1 id="users-and-authentication">Users and Authentication<a class="anchor" href="#users-and-authentication">#</a></h1> +<p>dhamps-vdb uses token-based authentication with API keys for all operations.</p> +<h2 id="user-model">User Model<a class="anchor" href="#user-model">#</a></h2> +<h3 id="user-properties">User Properties<a class="anchor" href="#user-properties">#</a></h3> +<ul> +<li><strong>user_handle</strong>: Unique identifier (3-20 characters, alphanumeric + underscore)</li> +<li><strong>name</strong>: Full name (optional)</li> +<li><strong>email</strong>: Email address (unique, required)</li> +<li><strong>vdb_key</strong>: API key (SHA-256 hash, 64 characters)</li> +<li><strong>created_at</strong>: Timestamp of creation</li> +<li><strong>updated_at</strong>: Timestamp of last update</li> +</ul> +<h3 id="special-users">Special Users<a class="anchor" href="#special-users">#</a></h3> +<p><strong><code>_system</code> User</strong></p> +<ul> +<li>Created automatically during database migration</li> +<li>Owns system-wide LLM service definitions</li> +<li>Cannot be used for authentication</li> +<li>Provides default configurations for all users</li> +</ul> +<h2 id="authentication-flow">Authentication Flow<a class="anchor" href="#authentication-flow">#</a></h2> +<h3 id="api-key-authentication">API Key Authentication<a class="anchor" href="#api-key-authentication">#</a></h3> +<p>All requests (except public endpoints) require authentication:</p>Architecturehttps://mpilhlt.github.io/dhamps-vdb/development/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/architecture/<h1 id="technical-architecture">Technical Architecture<a class="anchor" href="#technical-architecture">#</a></h1> +<p>This document provides a technical deep-dive into dhamps-vdb&rsquo;s architecture for developers who want to understand or modify the codebase.</p> +<h2 id="project-structure">Project Structure<a class="anchor" href="#project-structure">#</a></h2> +<pre tabindex="0"><code>dhamps-vdb/ +├── main.go # Application entry point +├── go.mod # Go module definition +├── go.sum # Dependency checksums +├── sqlc.yaml # sqlc configuration +├── template.env # Environment template +├── .env # Local config (gitignored) +│ +├── api/ +│ └── openapi.yml # OpenAPI spec (not actively maintained) +│ +├── internal/ # Internal packages (non-importable) +│ ├── auth/ # Authentication logic +│ │ └── authenticate.go # Bearer token validation +│ │ +│ ├── crypto/ # Encryption utilities +│ │ └── crypto.go # AES-256-GCM encryption +│ │ +│ ├── database/ # Database layer +│ │ ├── database.go # Connection pool management +│ │ ├── migrations.go # Migration runner +│ │ ├── db.go # Generated by sqlc +│ │ ├── models.go # Generated by sqlc +│ │ ├── queries.sql.go # Generated by sqlc +│ │ │ +│ │ ├── migrations/ # SQL migrations +│ │ │ ├── 001_create_initial_scheme.sql +│ │ │ ├── 002_create_emb_index.sql +│ │ │ ├── 003_add_public_read_flag.sql +│ │ │ ├── 004_refactor_llm_services_architecture.sql +│ │ │ ├── tern.conf.tpl # Template for tern +│ │ │ └── tern.conf # Generated (gitignored) +│ │ │ +│ │ └── queries/ # SQL queries for sqlc +│ │ └── queries.sql # All database queries +│ │ +│ ├── handlers/ # HTTP request handlers +│ │ ├── handlers.go # Common handler utilities +│ │ ├── users.go # User endpoints +│ │ ├── projects.go # Project endpoints +│ │ ├── llm_services.go # LLM service endpoints +│ │ ├── api_standards.go # API standard endpoints +│ │ ├── embeddings.go # Embedding endpoints +│ │ ├── similars.go # Similarity search endpoints +│ │ ├── admin.go # Admin endpoints +│ │ │ +│ │ └── *_test.go # Test files +│ │ ├── users_test.go +│ │ ├── projects_test.go +│ │ ├── projects_sharing_test.go +│ │ ├── embeddings_test.go +│ │ ├── llm_services_test.go +│ │ ├── editor_permissions_test.go +│ │ └── handlers_test.go +│ │ +│ └── models/ # Data models and options +│ ├── options.go # CLI/environment options +│ ├── users.go # User models +│ ├── projects.go # Project models +│ ├── instances.go # LLM instance models (new) +│ ├── api_standards.go # API standard models +│ ├── embeddings.go # Embedding models +│ ├── similars.go # Similarity search models +│ └── admin.go # Admin operation models +│ +├── testdata/ # Test fixtures +│ ├── postgres/ # PostgreSQL test data +│ │ ├── enable-vector.sql +│ │ └── users.yml +│ │ +│ └── *.json # JSON test fixtures +│ ├── valid_user.json +│ ├── valid_embeddings.json +│ ├── valid_api_standard_*.json +│ └── valid_llm_service_*.json +│ +└── docs/ # Documentation + ├── content/ # Hugo content + └── *.md # Additional docs</code></pre><h2 id="code-organization">Code Organization<a class="anchor" href="#code-organization">#</a></h2> +<h3 id="1-entry-point-maingo">1. Entry Point (<code>main.go</code>)<a class="anchor" href="#1-entry-point-maingo">#</a></h3> +<p>The application entry point handles:</p>Environment Variableshttps://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/<h1 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h1> +<p>Complete reference for all environment variables used by dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb is configured entirely through environment variables. These can be set:</p> +<ol> +<li><strong>In a <code>.env</code> file</strong> (recommended for Docker)</li> +<li><strong>As system environment variables</strong></li> +<li><strong>Via command-line flags</strong> (some variables only)</li> +</ol> +<h2 id="required-variables">Required Variables<a class="anchor" href="#required-variables">#</a></h2> +<p>These variables <strong>must</strong> be set for dhamps-vdb to function:</p> +<h3 id="service_adminkey">SERVICE_ADMINKEY<a class="anchor" href="#service_adminkey">#</a></h3> +<p>Admin API key for administrative operations.</p> +<ul> +<li><strong>Type:</strong> String</li> +<li><strong>Required:</strong> Yes</li> +<li><strong>Default:</strong> None</li> +<li><strong>Environment Variable:</strong> <code>SERVICE_ADMINKEY</code></li> +<li><strong>Command-line Flag:</strong> <code>--admin-key</code></li> +</ul> +<p><strong>Description:</strong> Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.</p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/<h1 id="llm-services-endpoint">LLM Services Endpoint<a class="anchor" href="#llm-services-endpoint">#</a></h1> +<p>Manage LLM service instances and definitions. The system supports two types of LLM service resources:</p> +<ol> +<li><strong>Definitions</strong>: Reusable templates owned by <code>_system</code> or individual users</li> +<li><strong>Instances</strong>: User-specific configurations with API keys that reference definitions or stand alone</li> +</ol> +<h2 id="architecture-overview">Architecture Overview<a class="anchor" href="#architecture-overview">#</a></h2> +<pre tabindex="0"><code>definitions (templates) + └── owned by _system or users + └── contain: endpoint, model, dimensions, api_standard + └── no API keys + +instances (user-specific) + └── owned by individual users + └── reference a definition (optional) + └── contain encrypted API keys + └── can be shared with other users</code></pre><p>For complete details, see <a href="https://mpilhlt.github.io/dhamps-vdb/docs/LLM_SERVICE_REFACTORING.md">LLM Service Refactoring Documentation</a>.</p>Product Roadmaphttps://mpilhlt.github.io/dhamps-vdb/reference/roadmap/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/<h1 id="product-roadmap">Product Roadmap<a class="anchor" href="#product-roadmap">#</a></h1> +<p>Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.</p> +<h2 id="completed-features">Completed Features<a class="anchor" href="#completed-features">#</a></h2> +<h3 id="core-functionality">Core Functionality<a class="anchor" href="#core-functionality">#</a></h3> +<ul> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>User authentication &amp; restrictions on some API calls</strong></p> +<ul> +<li>Bearer token authentication</li> +<li>Role-based access control</li> +<li>Admin vs user permissions</li> +</ul> +</li> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>API versioning</strong></p> +<ul> +<li>Version 1 API with <code>/v1/</code> prefix</li> +<li>Backward compatibility support</li> +</ul> +</li> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>Better options handling</strong></p>Projectshttps://mpilhlt.github.io/dhamps-vdb/concepts/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/projects/<h1 id="projects">Projects<a class="anchor" href="#projects">#</a></h1> +<p>Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.</p> +<h2 id="what-is-a-project">What is a Project?<a class="anchor" href="#what-is-a-project">#</a></h2> +<p>A project is a collection of document embeddings that share:</p> +<ul> +<li>A single LLM service instance (embedding configuration)</li> +<li>Optional metadata schema for validation</li> +<li>Access control (ownership and sharing)</li> +<li>Consistent vector dimensions</li> +</ul> +<h2 id="project-properties">Project Properties<a class="anchor" href="#project-properties">#</a></h2> +<h3 id="core-fields">Core Fields<a class="anchor" href="#core-fields">#</a></h3> +<ul> +<li><strong>project_handle</strong>: Unique identifier within owner&rsquo;s namespace (3-20 characters)</li> +<li><strong>owner</strong>: User who owns the project</li> +<li><strong>description</strong>: Human-readable project description</li> +<li><strong>instance_id</strong>: Reference to LLM service instance (required, 1:1 relationship)</li> +<li><strong>metadataScheme</strong>: Optional JSON Schema for metadata validation</li> +<li><strong>public_read</strong>: Boolean flag for public read access</li> +<li><strong>created_at</strong>: Creation timestamp</li> +<li><strong>updated_at</strong>: Last modification timestamp</li> +</ul> +<h3 id="unique-constraints">Unique Constraints<a class="anchor" href="#unique-constraints">#</a></h3> +<p>Projects are uniquely identified by <code>(owner, project_handle)</code>:</p>Public Projects Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/public-projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/<h1 id="public-projects-guide">Public Projects Guide<a class="anchor" href="#public-projects-guide">#</a></h1> +<p>This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Projects can be configured to allow unauthenticated (public) read access by setting the <code>public_read</code> field to <code>true</code>. This is useful for:</p> +<ul> +<li>Open datasets and research data</li> +<li>Public APIs and services</li> +<li>Shared knowledge bases</li> +<li>Educational resources</li> +</ul> +<p><strong>Important:</strong> Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.</p>Quick Starthttps://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/<h1 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h1> +<p>Complete walkthrough from installation to searching similar documents using curl.</p> +<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> +<ul> +<li>dhamps-vdb installed and running</li> +<li>Admin API key configured</li> +<li>PostgreSQL with pgvector ready</li> +</ul> +<h2 id="1-create-a-user">1. Create a User<a class="anchor" href="#1-create-a-user">#</a></h2> +<p>Create a new user with the admin API key:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;alice&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Alice Smith&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;alice@example.com&#34; +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p><strong>Response:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Smith&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vdb_key&#34;</span>: <span style="color:#e6db74">&#34;024v2013621509245f2e24...&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Save the <code>vdb_key</code></strong> - it cannot be recovered later.</p>API Standardshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/<h1 id="api-standards-endpoint">API Standards Endpoint<a class="anchor" href="#api-standards-endpoint">#</a></h1> +<p>Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:</p> +<ul> +<li><strong>OpenAI</strong>: Bearer token in <code>Authorization</code> header</li> +<li><strong>Cohere</strong>: API key in <code>Authorization</code> header with <code>Bearer</code> prefix</li> +<li><strong>Google Gemini</strong>: API key as query parameter</li> +<li><strong>Ollama</strong>: No authentication required</li> +</ul> +<p>Pre-seeded standards are available for common providers. See <a href="https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata">testdata/valid_api_standard_*.json</a> for examples.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/<h1 id="embeddings">Embeddings<a class="anchor" href="#embeddings">#</a></h1> +<p>Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.</p> +<h2 id="what-are-embeddings">What are Embeddings?<a class="anchor" href="#what-are-embeddings">#</a></h2> +<p>Embeddings are numerical representations (vectors) of text that capture semantic meaning:</p> +<ul> +<li><strong>Vector</strong>: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)</li> +<li><strong>Dimensions</strong>: Fixed length determined by LLM model</li> +<li><strong>Similarity</strong>: Vectors of similar text are close in vector space</li> +<li><strong>Purpose</strong>: Enable semantic search and retrieval</li> +</ul> +<h2 id="embedding-structure">Embedding Structure<a class="anchor" href="#embedding-structure">#</a></h2> +<h3 id="required-fields">Required Fields<a class="anchor" href="#required-fields">#</a></h3> +<ul> +<li><strong>text_id</strong>: Unique identifier for the document (max 300 characters)</li> +<li><strong>instance_handle</strong>: LLM service instance that generated the embedding</li> +<li><strong>vector</strong>: Array of float32 values (embedding vector)</li> +<li><strong>vector_dim</strong>: Declared dimension count (must match vector length)</li> +</ul> +<h3 id="optional-fields">Optional Fields<a class="anchor" href="#optional-fields">#</a></h3> +<ul> +<li><strong>text</strong>: Original text content (for reference)</li> +<li><strong>metadata</strong>: Structured JSON data about the document</li> +</ul> +<h3 id="example">Example<a class="anchor" href="#example">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc-123&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text&#34;</span>: <span style="color:#e6db74">&#34;Introduction to machine learning concepts&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector&#34;</span>: [<span style="color:#ae81ff">0.023</span>, <span style="color:#ae81ff">-0.015</span>, <span style="color:#ae81ff">0.087</span>, <span style="color:#960050;background-color:#1e0010">...</span>, <span style="color:#ae81ff">0.042</span>], +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;metadata&#34;</span>: { +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;ML Introduction&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">2024</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;category&#34;</span>: <span style="color:#e6db74">&#34;tutorial&#34;</span> +</span></span><span style="display:flex;"><span> } +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h2 id="creating-embeddings">Creating Embeddings<a class="anchor" href="#creating-embeddings">#</a></h2> +<h3 id="single-embedding">Single Embedding<a class="anchor" href="#single-embedding">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>0.1, 0.2, ..., 0.3<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: 3072, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;metadata&#34;</span>: <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span><span style="color:#f92672">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><h3 id="batch-upload">Batch Upload<a class="anchor" href="#batch-upload">#</a></h3> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc2&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, +</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> +</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, +</span></span><span style="display:flex;"><span> ... +</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><p><strong>Batch upload tips:</strong></p>First Projecthttps://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/<h1 id="first-project">First Project<a class="anchor" href="#first-project">#</a></h1> +<p>Step-by-step guide to creating your first complete project in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:</p> +<ol> +<li>Set up authentication</li> +<li>Configure an LLM service</li> +<li>Create a project with metadata validation</li> +<li>Upload document embeddings</li> +<li>Search for similar documents</li> +<li>Share your project with collaborators</li> +</ol> +<h2 id="step-1-authentication-setup">Step 1: Authentication Setup<a class="anchor" href="#step-1-authentication-setup">#</a></h2> +<h3 id="get-your-api-key">Get Your API Key<a class="anchor" href="#get-your-api-key">#</a></h3> +<p>If you&rsquo;re an admin, create your first user:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;researcher1&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Research User&#34;, +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;researcher@example.com&#34; +</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p>Save the returned <code>vdb_key</code> to a variable:</p>Ownership Transfer Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/<h1 id="ownership-transfer-guide">Ownership Transfer Guide<a class="anchor" href="#ownership-transfer-guide">#</a></h1> +<p>This guide explains how to transfer project ownership between users in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:</p> +<ul> +<li>A project maintainer is leaving and wants to hand over control</li> +<li>Organizational changes require reassigning project ownership</li> +<li>Consolidating projects under a different user account</li> +<li>Transferring stewardship of research data to a new PI</li> +</ul> +<h2 id="important-constraints">Important Constraints<a class="anchor" href="#important-constraints">#</a></h2> +<p>Before transferring ownership, understand these constraints:</p>Performancehttps://mpilhlt.github.io/dhamps-vdb/development/performance/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/performance/<h1 id="performance-optimization-guide">Performance Optimization Guide<a class="anchor" href="#performance-optimization-guide">#</a></h1> +<p>This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.</p> +<h2 id="query-optimization">Query Optimization<a class="anchor" href="#query-optimization">#</a></h2> +<h3 id="getallaccessibleinstances-query">GetAllAccessibleInstances Query<a class="anchor" href="#getallaccessibleinstances-query">#</a></h3> +<p><strong>Problem:</strong> The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.</p> +<p><strong>Current Implementation:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> instances.<span style="color:#f92672">*</span>, +</span></span><span style="display:flex;"><span> COALESCE(instances_shared_with.<span style="color:#66d9ef">role</span>, <span style="color:#e6db74">&#39;owner&#39;</span>) <span style="color:#66d9ef">as</span> <span style="color:#66d9ef">role</span>, +</span></span><span style="display:flex;"><span> (instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span>) <span style="color:#66d9ef">as</span> is_owner +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> instances +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LEFT</span> <span style="color:#66d9ef">JOIN</span> instances_shared_with +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">ON</span> instances.instance_id <span style="color:#f92672">=</span> instances_shared_with.instance_id +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">OR</span> instances_shared_with.user_handle <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#66d9ef">ASC</span>, instances.instance_handle <span style="color:#66d9ef">ASC</span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LIMIT</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">2</span> <span style="color:#66d9ef">OFFSET</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">3</span>;</span></span></code></pre></div><p><strong>Issue:</strong> The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.</p>Security Best Practiceshttps://mpilhlt.github.io/dhamps-vdb/deployment/security/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/security/<h1 id="security-best-practices">Security Best Practices<a class="anchor" href="#security-best-practices">#</a></h1> +<p>Comprehensive guide for securing your dhamps-vdb production deployment.</p> +<h2 id="security-overview">Security Overview<a class="anchor" href="#security-overview">#</a></h2> +<p>dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.</p> +<h2 id="httpstls-configuration">HTTPS/TLS Configuration<a class="anchor" href="#httpstls-configuration">#</a></h2> +<h3 id="why-https-is-required">Why HTTPS is Required<a class="anchor" href="#why-https-is-required">#</a></h3> +<ul> +<li><strong>Encryption in transit</strong>: Protects API keys and data from interception</li> +<li><strong>Authentication</strong>: Verifies server identity</li> +<li><strong>Compliance</strong>: Required by most security standards</li> +</ul> +<h3 id="using-a-reverse-proxy">Using a Reverse Proxy<a class="anchor" href="#using-a-reverse-proxy">#</a></h3> +<p><strong>Never expose dhamps-vdb directly to the internet.</strong> Always use a reverse proxy with TLS termination.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/<h1 id="embeddings-endpoint">Embeddings Endpoint<a class="anchor" href="#embeddings-endpoint">#</a></h1> +<p>Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project&rsquo;s LLM service instance dimensions.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="list-embeddings">List Embeddings<a class="anchor" href="#list-embeddings">#</a></h3> +<p>Get all embeddings for a project with pagination support.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/embeddings/{username}/{projectname}</code></p> +<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> +<p><strong>Query Parameters:</strong></p> +<ul> +<li><code>limit</code> (integer, default: 10, max: 200): Maximum number of results to return</li> +<li><code>offset</code> (integer, default: 0): Pagination offset</li> +</ul> +<p><strong>Example:</strong></p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/<h1 id="llm-services">LLM Services<a class="anchor" href="#llm-services">#</a></h1> +<p>LLM Services configure embedding generation, defining models, dimensions, and API access.</p> +<h2 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h2> +<p>dhamps-vdb separates LLM services into two concepts:</p> +<h3 id="llm-service-definitions">LLM Service Definitions<a class="anchor" href="#llm-service-definitions">#</a></h3> +<p>Reusable configuration templates owned by <code>_system</code> or users:</p> +<ul> +<li><strong>Purpose</strong>: Provide standard configurations</li> +<li><strong>Ownership</strong>: <code>_system</code> (global) or individual users</li> +<li><strong>Contents</strong>: Endpoint, model, dimensions, API standard</li> +<li><strong>API Keys</strong>: Not stored (templates only)</li> +<li><strong>Usage</strong>: Templates for creating instances</li> +</ul> +<h3 id="llm-service-instances">LLM Service Instances<a class="anchor" href="#llm-service-instances">#</a></h3> +<p>User-specific configurations with encrypted API keys:</p> +<ul> +<li><strong>Purpose</strong>: Actual service configurations users employ</li> +<li><strong>Ownership</strong>: Individual users</li> +<li><strong>Contents</strong>: Endpoint, model, dimensions, API key (encrypted)</li> +<li><strong>Sharing</strong>: Can be shared with other users</li> +<li><strong>Projects</strong>: Each project references exactly one instance</li> +</ul> +<h2 id="system-definitions">System Definitions<a class="anchor" href="#system-definitions">#</a></h2> +<h3 id="available-definitions">Available Definitions<a class="anchor" href="#available-definitions">#</a></h3> +<p>The <code>_system</code> user provides default definitions:</p>Metadata Validation Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/<h1 id="metadata-validation-guide">Metadata Validation Guide<a class="anchor" href="#metadata-validation-guide">#</a></h1> +<p>This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.</p> +<p>Benefits:</p> +<ul> +<li>Enforce consistent metadata structure across all embeddings</li> +<li>Catch data entry errors early</li> +<li>Document expected metadata fields</li> +<li>Enable reliable metadata-based filtering</li> +</ul> +<h2 id="defining-a-metadata-schema">Defining a Metadata Schema<a class="anchor" href="#defining-a-metadata-schema">#</a></h2> +<h3 id="when-creating-a-project">When Creating a Project<a class="anchor" href="#when-creating-a-project">#</a></h3> +<p>Include a <code>metadataScheme</code> field with a valid JSON Schema when creating a project:</p>Metadata Filtering Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/<h1 id="metadata-filtering-guide">Metadata Filtering Guide<a class="anchor" href="#metadata-filtering-guide">#</a></h1> +<p>This guide explains how to use metadata filtering to exclude specific documents from similarity search results.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:</p> +<ul> +<li>Exclude documents from the same author when finding similar writing styles</li> +<li>Filter out documents from the same source when finding related content</li> +<li>Exclude documents with the same category when exploring diversity</li> +</ul> +<p>dhamps-vdb provides metadata filtering using query parameters that perform <strong>negative matching</strong> - they exclude documents where the metadata field matches the specified value.</p>Similarity Searchhttps://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/<h1 id="similarity-search">Similarity Search<a class="anchor" href="#similarity-search">#</a></h1> +<p>Find documents with similar semantic meaning using vector similarity.</p> +<h2 id="how-it-works">How it Works<a class="anchor" href="#how-it-works">#</a></h2> +<p>Similarity search compares embedding vectors using cosine distance:</p> +<ol> +<li><strong>Query vector</strong>: Either from stored embedding or raw vector</li> +<li><strong>Comparison</strong>: Calculate cosine similarity with all project embeddings</li> +<li><strong>Filtering</strong>: Apply threshold and metadata filters</li> +<li><strong>Ranking</strong>: Sort by similarity score (highest first)</li> +<li><strong>Return</strong>: Top N most similar documents</li> +</ol> +<h2 id="search-methods">Search Methods<a class="anchor" href="#search-methods">#</a></h2> +<h3 id="stored-document-search-get">Stored Document Search (GET)<a class="anchor" href="#stored-document-search-get">#</a></h3> +<p>Find documents similar to an already-stored embedding:</p>Similarshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/<h1 id="similarity-search-endpoints">Similarity Search Endpoints<a class="anchor" href="#similarity-search-endpoints">#</a></h1> +<p>Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.</p> +<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> +<h3 id="get-similar-documents-from-stored-embeddings">GET Similar Documents (from stored embeddings)<a class="anchor" href="#get-similar-documents-from-stored-embeddings">#</a></h3> +<p>Find documents similar to an already-stored document by its text identifier.</p> +<p><strong>Endpoint:</strong> <code>GET /v1/similars/{username}/{projectname}/{identifier}</code></p> +<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> +<p><strong>Query Parameters:</strong></p> +<ul> +<li><code>count</code> (integer, optional, default: 10, max: 200): Number of similar documents to return</li> +<li><code>threshold</code> (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold</li> +<li><code>limit</code> (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for <code>count</code>)</li> +<li><code>offset</code> (integer, optional, default: 0): Pagination offset</li> +<li><code>metadata_path</code> (string, optional): Metadata field path for filtering (must be used with <code>metadata_value</code>)</li> +<li><code>metadata_value</code> (string, optional): Metadata value to exclude from results (must be used with <code>metadata_path</code>)</li> +</ul> +<p><strong>Example - Basic search:</strong></p>Batch Operations Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/<h1 id="batch-operations-guide">Batch Operations Guide<a class="anchor" href="#batch-operations-guide">#</a></h1> +<p>This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>For production workloads and large datasets, efficient batch operations are essential. This guide covers:</p> +<ul> +<li>Uploading multiple embeddings in a single request</li> +<li>Pagination strategies for large result sets</li> +<li>Best practices for performance and reliability</li> +<li>Error handling in batch operations</li> +</ul> +<h2 id="batch-upload-basics">Batch Upload Basics<a class="anchor" href="#batch-upload-basics">#</a></h2> +<h3 id="single-request-with-multiple-embeddings">Single Request with Multiple Embeddings<a class="anchor" href="#single-request-with-multiple-embeddings">#</a></h3> +<p>Upload multiple embeddings in one API call using the <code>embeddings</code> array:</p>Metadatahttps://mpilhlt.github.io/dhamps-vdb/concepts/metadata/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/<h1 id="metadata">Metadata<a class="anchor" href="#metadata">#</a></h1> +<p>Structured JSON data attached to embeddings for organization, validation, and filtering.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>Metadata provides context and structure for your embeddings:</p> +<ul> +<li><strong>Organization</strong>: Categorize and group documents</li> +<li><strong>Filtering</strong>: Exclude documents in similarity searches</li> +<li><strong>Validation</strong>: Ensure consistent structure (optional)</li> +<li><strong>Context</strong>: Store additional document information</li> +</ul> +<h2 id="metadata-structure">Metadata Structure<a class="anchor" href="#metadata-structure">#</a></h2> +<h3 id="format">Format<a class="anchor" href="#format">#</a></h3> +<p>Metadata is JSON stored as JSONB in PostgreSQL:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;William Shakespeare&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Hamlet&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">1603</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;genre&#34;</span>: <span style="color:#e6db74">&#34;drama&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h3 id="types">Types<a class="anchor" href="#types">#</a></h3> +<p>Supported JSON types:</p> +<ul> +<li><strong>String</strong>: <code>&quot;author&quot;: &quot;Shakespeare&quot;</code></li> +<li><strong>Number</strong>: <code>&quot;year&quot;: 1603</code></li> +<li><strong>Boolean</strong>: <code>&quot;published&quot;: true</code></li> +<li><strong>Array</strong>: <code>&quot;tags&quot;: [&quot;tragedy&quot;, &quot;revenge&quot;]</code></li> +<li><strong>Object</strong>: <code>&quot;author&quot;: {&quot;name&quot;: &quot;...&quot;, &quot;id&quot;: &quot;...&quot;}</code></li> +<li><strong>Null</strong>: <code>&quot;notes&quot;: null</code></li> +</ul> +<h3 id="nested-structure">Nested Structure<a class="anchor" href="#nested-structure">#</a></h3> +<p>Complex hierarchies are supported:</p>Query Parametershttps://mpilhlt.github.io/dhamps-vdb/api/query-parameters/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/<h1 id="query-parameters-reference">Query Parameters Reference<a class="anchor" href="#query-parameters-reference">#</a></h1> +<p>Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.</p> +<h2 id="pagination-parameters">Pagination Parameters<a class="anchor" href="#pagination-parameters">#</a></h2> +<h3 id="limit">limit<a class="anchor" href="#limit">#</a></h3> +<p>Maximum number of results to return in a single response.</p> +<p><strong>Type:</strong> Integer<br> +<strong>Default:</strong> 10<br> +<strong>Maximum:</strong> 200<br> +<strong>Minimum:</strong> 1</p> +<p><strong>Used by:</strong></p> +<ul> +<li><code>GET /v1/embeddings/{user}/{project}</code> - List embeddings</li> +<li><code>GET /v1/similars/{user}/{project}/{id}</code> - Similarity search</li> +<li><code>POST /v1/similars/{user}/{project}</code> - Raw vector search</li> +<li><code>GET /v1/projects/{user}</code> - List projects</li> +</ul> +<p><strong>Example:</strong></p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get 50 embeddings</span> +</span></span><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50&#34;</span> <span style="color:#ae81ff">\ +</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Aliases:</strong></p>Instance Management Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/instance-management/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/<h1 id="instance-management-guide">Instance Management Guide<a class="anchor" href="#instance-management-guide">#</a></h1> +<p>This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:</p> +<ul> +<li>API endpoint and credentials</li> +<li>Model name and version</li> +<li>Vector dimensions</li> +<li>API standard (protocol)</li> +</ul> +<p>Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.</p>PATCH Updateshttps://mpilhlt.github.io/dhamps-vdb/api/patch-updates/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/<h1 id="patch-method-for-partial-updates">PATCH Method for Partial Updates<a class="anchor" href="#patch-method-for-partial-updates">#</a></h1> +<p>The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:</p> +<ol> +<li>Retrieves the current resource state via GET</li> +<li>Merges your changes with the existing data</li> +<li>Applies the update via PUT</li> +</ol> +<p>This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.</p>Error Handlinghttps://mpilhlt.github.io/dhamps-vdb/api/error-handling/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/error-handling/<h1 id="error-handling">Error Handling<a class="anchor" href="#error-handling">#</a></h1> +<p>The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.</p> +<h2 id="error-response-format">Error Response Format<a class="anchor" href="#error-response-format">#</a></h2> +<p>All error responses follow this structure:</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Error Title&#34;</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;status&#34;</span>: <span style="color:#ae81ff">400</span>, +</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;detail&#34;</span>: <span style="color:#e6db74">&#34;Detailed error message explaining what went wrong&#34;</span> +</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Fields:</strong></p> +<ul> +<li><code>title</code> (string): Human-readable error title</li> +<li><code>status</code> (integer): HTTP status code</li> +<li><code>detail</code> (string): Detailed description of the error</li> +</ul> +<h2 id="http-status-codes">HTTP Status Codes<a class="anchor" href="#http-status-codes">#</a></h2> +<h3 id="2xx-success">2xx Success<a class="anchor" href="#2xx-success">#</a></h3> +<h4 id="200-ok">200 OK<a class="anchor" href="#200-ok">#</a></h4> +<p>Request succeeded. Response body contains requested data.</p> \ No newline at end of file diff --git a/docs/public/reference/configuration/index.html b/docs/public/reference/configuration/index.html new file mode 100644 index 0000000..d41db60 --- /dev/null +++ b/docs/public/reference/configuration/index.html @@ -0,0 +1,200 @@ +Configuration Reference | dhamps-vdb Documentation + +

    Configuration Reference#

    Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.

    Overview#

    dhamps-vdb is configured through a combination of:

    1. Environment variables (recommended)
    2. Command-line flags (overrides environment variables)
    3. .env files (for Docker and local development)

    Configuration is loaded in the following priority order (highest to lowest):

    1. Command-line flags
    2. Environment variables
    3. .env file values
    4. Default values from options.go

    Configuration Options#

    Service Configuration#

    Options for controlling the API service behavior.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    DebugSERVICE_DEBUG-d, --debugBooleantrueNoEnable verbose debug logging
    HostSERVICE_HOST--hostStringlocalhostNoHostname or IP to bind to
    PortSERVICE_PORT-p, --portInteger8880NoPort number to listen on

    Debug Mode:

    • true - Detailed logs including SQL queries, request details, internal operations
    • false - Minimal logs for production use

    Host Configuration:

    • localhost - Local development only
    • 0.0.0.0 - Listen on all interfaces (required for Docker)
    • Specific IP - Bind to particular network interface

    Port Configuration:

    • Default: 8880
    • Ports below 1024 require elevated privileges
    • Ensure port is not in use by another service

    Database Configuration#

    Options for connecting to the PostgreSQL database with pgvector extension.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    DB HostSERVICE_DBHOST--db-hostStringlocalhostYesPostgreSQL server hostname
    DB PortSERVICE_DBPORT--db-portInteger5432NoPostgreSQL server port
    DB UserSERVICE_DBUSER--db-userStringpostgresYesDatabase username
    DB PasswordSERVICE_DBPASSWORD--db-passwordStringpasswordYesDatabase password
    DB NameSERVICE_DBNAME--db-nameStringpostgresYesDatabase name

    Database Requirements:

    • PostgreSQL 12+ (16+ recommended)
    • pgvector extension installed and enabled
    • User must have CREATE, ALTER, DROP, INSERT, SELECT, UPDATE, DELETE privileges
    • Database must exist before starting dhamps-vdb

    Common Database Hosts:

    • localhost - Local PostgreSQL instance
    • postgres - Docker Compose service name
    • db.example.com - Remote database server
    • IP address - Direct connection to database

    Security Configuration#

    Critical security settings for authentication and encryption.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    Admin KeySERVICE_ADMINKEY--admin-keyString-YesMaster API key for admin operations
    Encryption KeyENCRYPTION_KEY-String-YesAES-256 key for API key encryption

    Admin Key (SERVICE_ADMINKEY):

    • Master API key with full administrative privileges
    • Used to create users and manage global resources
    • Generate with: openssl rand -base64 32
    • Must be kept secure and rotated regularly
    • Transmitted via Authorization: Bearer header

    Encryption Key (ENCRYPTION_KEY):

    • Used to encrypt user API keys in the database
    • Minimum 32 characters required
    • Uses AES-256-GCM encryption with SHA-256 hashing
    • CRITICAL: If lost, all stored API keys become unrecoverable
    • Cannot be changed without re-encrypting all existing API keys
    • Generate with: openssl rand -hex 32
    • Must be backed up securely and separately from database

    Configuration Files#

    .env File#

    The recommended way to configure dhamps-vdb. Create a .env file in the project root:

    # Copy template
    +cp template.env .env
    +
    +# Edit with your values
    +nano .env

    Example .env file:

    # Service Configuration
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +
    +# Database Configuration
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=secure_password_here
    +SERVICE_DBNAME=dhamps_vdb
    +
    +# Security Configuration
    +SERVICE_ADMINKEY=generated_admin_key_here
    +ENCRYPTION_KEY=generated_encryption_key_min_32_chars

    Security Notes:

    • .env files are in .gitignore by default
    • Never commit .env files to version control
    • Set restrictive permissions: chmod 600 .env
    • Use different keys for dev/staging/production

    template.env#

    Starting template for configuration:

    #!/usr/bin/env bash
    +
    +SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8888
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=postgres
    +SERVICE_DBNAME=postgres
    +SERVICE_ADMINKEY=Ch4ngeM3!
    +
    +# Encryption key for API keys in LLM service instances
    +# Must be secure random string, at least 32 characters
    +# Generate with: openssl rand -hex 32
    +ENCRYPTION_KEY=ChangeThisToASecureRandomKey123456789012

    Docker Configuration#

    Docker Compose#

    The docker-compose.yml file defines the full stack including PostgreSQL:

    services:
    +  postgres:
    +    image: pgvector/pgvector:0.7.4-pg16
    +    environment:
    +      POSTGRES_USER: ${SERVICE_DBUSER:-postgres}
    +      POSTGRES_PASSWORD: ${SERVICE_DBPASSWORD:-postgres}
    +      POSTGRES_DB: ${SERVICE_DBNAME:-dhamps_vdb}
    +    ports:
    +      - "${POSTGRES_PORT:-5432}:5432"
    +    volumes:
    +      - postgres_data:/var/lib/postgresql/data
    +
    +  dhamps-vdb:
    +    build:
    +      context: .
    +      dockerfile: Dockerfile
    +    depends_on:
    +      postgres:
    +        condition: service_healthy
    +    environment:
    +      SERVICE_DEBUG: ${SERVICE_DEBUG:-false}
    +      SERVICE_HOST: ${SERVICE_HOST:-0.0.0.0}
    +      SERVICE_PORT: ${SERVICE_PORT:-8880}
    +      SERVICE_DBHOST: ${SERVICE_DBHOST:-postgres}
    +      SERVICE_DBPORT: ${SERVICE_DBPORT:-5432}
    +      SERVICE_DBUSER: ${SERVICE_DBUSER:-postgres}
    +      SERVICE_DBPASSWORD: ${SERVICE_DBPASSWORD:-postgres}
    +      SERVICE_DBNAME: ${SERVICE_DBNAME:-dhamps_vdb}
    +      SERVICE_ADMINKEY: ${SERVICE_ADMINKEY}
    +      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
    +    ports:
    +      - "${API_PORT:-8880}:8880"

    Docker-Specific Variables:

    • POSTGRES_PORT - External port for PostgreSQL (default: 5432)
    • API_PORT - External port for dhamps-vdb API (default: 8880)

    Docker Setup Script#

    Automated setup using docker-setup.sh:

    # Run automated setup (generates secure keys)
    +./docker-setup.sh
    +
    +# Start services
    +docker-compose up -d
    +
    +# View logs
    +docker-compose logs -f dhamps-vdb

    The script automatically:

    • Generates secure SERVICE_ADMINKEY
    • Generates secure ENCRYPTION_KEY
    • Creates .env file with proper configuration
    • Validates Docker and docker-compose installation

    Docker Run Command#

    For standalone container deployment:

    docker run -d \
    +  --name dhamps-vdb \
    +  -e SERVICE_DEBUG=false \
    +  -e SERVICE_HOST=0.0.0.0 \
    +  -e SERVICE_PORT=8880 \
    +  -e SERVICE_DBHOST=db.example.com \
    +  -e SERVICE_DBPORT=5432 \
    +  -e SERVICE_DBUSER=dhamps_user \
    +  -e SERVICE_DBPASSWORD=secure_password \
    +  -e SERVICE_DBNAME=dhamps_vdb \
    +  -e SERVICE_ADMINKEY=admin_key_here \
    +  -e ENCRYPTION_KEY=encryption_key_here \
    +  -p 8880:8880 \
    +  dhamps-vdb:latest

    External Database#

    Using docker-compose.external-db.yml for external PostgreSQL:

    # Set database connection in .env
    +SERVICE_DBHOST=db.external.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=secure_password
    +SERVICE_DBNAME=dhamps_vdb
    +
    +# Start without bundled PostgreSQL
    +docker-compose -f docker-compose.external-db.yml up -d

    Configuration Scenarios#

    Development Environment#

    Optimized for local development with verbose logging:

    # .env for development
    +SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=localhost
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=postgres
    +SERVICE_DBNAME=dhamps_vdb_dev
    +SERVICE_ADMINKEY=dev-admin-key-not-for-production
    +ENCRYPTION_KEY=dev-encryption-key-at-least-32-chars

    Start service:

    ./dhamps-vdb

    Docker Development#

    Docker-based development with hot reload:

    # .env for Docker development
    +SERVICE_DEBUG=true
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=postgres
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=postgres
    +SERVICE_DBPASSWORD=postgres
    +SERVICE_DBNAME=dhamps_vdb
    +SERVICE_ADMINKEY=dev-admin-key
    +ENCRYPTION_KEY=dev-encryption-32-chars-minimum

    Start with:

    docker-compose up

    Production Environment#

    Production-ready configuration with security hardening:

    # .env for production
    +SERVICE_DEBUG=false
    +SERVICE_HOST=0.0.0.0
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=prod-db.internal.example.com
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_prod_user
    +SERVICE_DBPASSWORD=<from-secrets-manager>
    +SERVICE_DBNAME=dhamps_vdb_prod
    +SERVICE_ADMINKEY=<from-secrets-manager>
    +ENCRYPTION_KEY=<from-secrets-manager>

    Production Best Practices:

    • Use secrets management (Vault, AWS Secrets Manager, etc.)
    • Disable debug logging (SERVICE_DEBUG=false)
    • Use dedicated database user (not superuser)
    • Enable SSL/TLS for database connections
    • Deploy behind reverse proxy (nginx, Traefik)
    • Set up monitoring and alerting
    • Regular key rotation (except ENCRYPTION_KEY)
    • Firewall rules to restrict access

    Testing Environment#

    Configuration for running tests:

    # Tests use testcontainers - no external config needed
    +go test -v ./...

    Test-specific setup:

    # Enable Docker for testcontainers
    +systemctl --user start podman.socket
    +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
    +
    +# Run tests
    +go test -v ./...

    Validation and Verification#

    Startup Validation#

    dhamps-vdb validates configuration on startup:

    1. Required variables check - Fails if missing
    2. Database connection test - Verifies connectivity
    3. Schema migration - Applies pending migrations
    4. Extension check - Verifies pgvector is available

    Configuration Test#

    Verify configuration is working:

    # Check service health
    +curl http://localhost:8880/docs
    +
    +# Test admin authentication
    +curl -X GET http://localhost:8880/v1/users \
    +  -H "Authorization: Bearer ${SERVICE_ADMINKEY}"
    +
    +# Check database connectivity
    +docker-compose exec dhamps-vdb echo "Config OK"

    Common Issues#

    Missing Required Variables:

    Error: SERVICE_ADMINKEY environment variable is not set

    Solution: Set all required variables.

    Database Connection Failed:

    Error: failed to connect to database

    Solution: Verify SERVICE_DBHOST, credentials, and that PostgreSQL is running.

    Invalid Encryption Key:

    Error: ENCRYPTION_KEY must be at least 32 characters

    Solution: Generate proper key with openssl rand -hex 32.

    Port Already in Use:

    Error: bind: address already in use

    Solution: Change SERVICE_PORT or stop conflicting service.

    Generating Secure Keys#

    Admin Key Generation#

    # Base64 encoded (recommended)
    +openssl rand -base64 32
    +
    +# Hex encoded (alternative)
    +openssl rand -hex 24
    +
    +# Output example:
    +# Kx7mP9nQ2rT5vY8zA1bC4dF6gH9jK0lM3nP5qR7sT9u=

    Encryption Key Generation#

    # 32-byte hex key (required format)
    +openssl rand -hex 32
    +
    +# Output example:
    +# a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6

    Secure Key Storage#

    Development:

    • Store in .env file (not committed)
    • Use password manager for team sharing

    Production:

    • Use secrets management system
    • Rotate admin key every 90 days
    • Never rotate encryption key (breaks existing API keys)
    • Store encryption key backup separately from database

    Environment-Specific Examples#

    Local with External PostgreSQL#

    SERVICE_DEBUG=true
    +SERVICE_HOST=localhost
    +SERVICE_PORT=8880
    +SERVICE_DBHOST=192.168.1.100
    +SERVICE_DBPORT=5432
    +SERVICE_DBUSER=dhamps_user
    +SERVICE_DBPASSWORD=user_password
    +SERVICE_DBNAME=dhamps_vdb
    +SERVICE_ADMINKEY=$(openssl rand -base64 32)
    +ENCRYPTION_KEY=$(openssl rand -hex 32)

    Kubernetes ConfigMap + Secrets#

    ConfigMap:

    apiVersion: v1
    +kind: ConfigMap
    +metadata:
    +  name: dhamps-vdb-config
    +data:
    +  SERVICE_DEBUG: "false"
    +  SERVICE_HOST: "0.0.0.0"
    +  SERVICE_PORT: "8880"
    +  SERVICE_DBHOST: "postgres-service"
    +  SERVICE_DBPORT: "5432"
    +  SERVICE_DBUSER: "dhamps_user"
    +  SERVICE_DBNAME: "dhamps_vdb"

    Secrets:

    apiVersion: v1
    +kind: Secret
    +metadata:
    +  name: dhamps-vdb-secrets
    +type: Opaque
    +stringData:
    +  SERVICE_DBPASSWORD: "secure_db_password"
    +  SERVICE_ADMINKEY: "secure_admin_key"
    +  ENCRYPTION_KEY: "secure_encryption_key_32_chars_min"

    Docker Swarm Secrets#

    # Create secrets
    +echo "admin_key_here" | docker secret create dhamps_admin_key -
    +echo "encryption_key" | docker secret create dhamps_encryption_key -
    +
    +# Reference in stack file
    +services:
    +  dhamps-vdb:
    +    secrets:
    +      - dhamps_admin_key
    +      - dhamps_encryption_key
    +    environment:
    +      SERVICE_ADMINKEY_FILE: /run/secrets/dhamps_admin_key
    +      ENCRYPTION_KEY_FILE: /run/secrets/dhamps_encryption_key
    \ No newline at end of file diff --git a/docs/public/reference/database-schema/index.html b/docs/public/reference/database-schema/index.html new file mode 100644 index 0000000..12de6e1 --- /dev/null +++ b/docs/public/reference/database-schema/index.html @@ -0,0 +1,67 @@ +Database Schema Reference | dhamps-vdb Documentation + +

    Database Schema Reference#

    Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.

    Overview#

    The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in internal/database/migrations/.

    Key Features:

    • Vector embeddings stored as halfvec for efficient storage
    • HNSW indexes for fast approximate nearest neighbor search
    • Automatic timestamp tracking (created_at, updated_at)
    • Foreign key constraints with CASCADE deletion
    • Role-based access control through association tables
    • Multi-tenancy support (user-owned resources)

    Schema Migrations#

    Current schema version is defined by 4 migration files:

    1. 001_create_initial_scheme.sql - Core tables and relationships
    2. 002_create_emb_index.sql - HNSW vector indexes
    3. 003_add_public_read_flag.sql - Public access support
    4. 004_refactor_llm_services_architecture.sql - LLM service architecture refactor

    Core Tables#

    users#

    Stores user accounts with API authentication.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)PRIMARY KEYUnique user identifier (username)
    nameTEXTFull name or display name
    emailTEXTUNIQUE, NOT NULLEmail address
    vdb_keyCHAR(64)UNIQUE, NOT NULLAPI key (64-character hex)
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Indexes:

    • Primary key on user_handle
    • Unique constraint on email
    • Unique constraint on vdb_key

    Special Users:

    • _system - Reserved system user for global LLM service definitions

    Relationships:

    • Owns projects (1:N)
    • Owns LLM service instances (1:N)
    • Owns embeddings (1:N)
    • Can share projects (N:M via users_projects)
    • Can share LLM service instances (N:M via instances_shared_with)

    Notes:

    • vdb_key is generated during user creation and returned once
    • Cannot be recovered if lost
    • Transmitted as Authorization: Bearer token

    projects#

    Stores embedding projects owned by users.

    ColumnTypeConstraintsDescription
    project_idSERIALPRIMARY KEYAuto-incrementing project ID
    project_handleVARCHAR(20)NOT NULLProject identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersProject owner user handle
    descriptionTEXTProject description
    metadata_schemeTEXTJSON Schema for validating embedding metadata
    public_readBOOLEANDEFAULT FALSEAllow unauthenticated read access
    instance_idINTEGERFK→instancesLLM service instance used for embeddings
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, project_handle) - Project handles unique per owner
    • ON DELETE CASCADE - Delete project when owner deleted
    • ON DELETE RESTRICT - Prevent instance deletion if used by project

    Relationships:

    • Owned by one user (N:1)
    • Uses one LLM service instance (N:1)
    • Has many embeddings (1:N)
    • Can be shared with users (N:M via users_projects)

    Metadata Schema:

    • Stored as JSON Schema string
    • Used to validate embedding metadata
    • Optional (can be NULL)
    • See Data Validation for details

    Public Access:

    • When public_read=TRUE, allows unauthenticated embedding queries
    • Controlled via API or by setting shared_with to ["*"]

    embeddings#

    Stores vector embeddings with text identifiers and metadata.

    ColumnTypeConstraintsDescription
    embeddings_idSERIALPRIMARY KEYAuto-incrementing embedding ID
    text_idTEXTINDEXEDText identifier (URL, DOI, custom ID)
    ownerVARCHAR(20)NOT NULL, FK→usersEmbedding owner user handle
    project_idSERIALNOT NULL, FK→projectsProject the embedding belongs to
    instance_idSERIALNOT NULL, FK→instancesLLM service instance used
    textTEXTOptional full text of the embedded content
    vectorhalfvecNOT NULLEmbedding vector (half-precision float)
    vector_dimINTEGERNOT NULLVector dimensionality
    metadatajsonbOptional metadata (validated if schema defined)
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (text_id, owner, project_id, instance_id) - Unique text IDs per project/instance
    • ON DELETE CASCADE - Delete embeddings when owner, project, or instance deleted

    Indexes:

    • Primary key on embeddings_id
    • B-tree index on text_id
    • HNSW vector indexes for dimensions: 384, 768, 1024, 1536, 3072 (see Vector Indexes)

    Vector Storage:

    • Uses halfvec type (16-bit floating point) for efficient storage
    • Dimensions must match LLM service instance configuration
    • Validated on upload against instance dimensions

    Relationships:

    • Owned by one user (N:1)
    • Belongs to one project (N:1)
    • Created with one LLM service instance (N:1)

    LLM Service Architecture#

    The LLM service architecture separates service definitions (templates) from user-specific instances.

    definitions#

    Templates for LLM embedding services (shared or user-specific).

    ColumnTypeConstraintsDescription
    definition_idSERIALPRIMARY KEYAuto-incrementing definition ID
    definition_handleVARCHAR(20)NOT NULLDefinition identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersDefinition owner (_system for global)
    endpointTEXTNOT NULLAPI endpoint URL
    descriptionTEXTService description
    api_standardVARCHAR(20)NOT NULL, FK→api_standardsAPI standard handle
    modelTEXTNOT NULLModel name (e.g., text-embedding-3-large)
    dimensionsINTEGERNOT NULLVector dimensions produced by model
    context_limitINTEGERNOT NULLMaximum context length (tokens/chars)
    is_publicBOOLEANNOT NULL, DEFAULT FALSEShare with all users if true
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, definition_handle) - Definition handles unique per owner
    • ON DELETE CASCADE - Delete definition when owner deleted

    Built-in Definitions:

    System-provided definitions (owned by _system, is_public=TRUE):

    HandleModelDimensionsContext LimitAPI Standard
    openai-largetext-embedding-3-large30728192openai
    openai-smalltext-embedding-3-small15368191openai
    cohere-v4embed-v4.01536128000cohere
    gemini-embedding-001gemini-embedding-00130722048gemini

    Relationships:

    • Owned by one user (N:1)
    • References one API standard (N:1)
    • Can be shared with users (N:M via definitions_shared_with)
    • Used by instances (1:N)

    instances#

    User-specific configurations of LLM services with API keys.

    ColumnTypeConstraintsDescription
    instance_idSERIALPRIMARY KEYAuto-incrementing instance ID
    instance_handleVARCHAR(20)NOT NULLInstance identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersInstance owner user handle
    endpointTEXTNOT NULLAPI endpoint URL
    descriptionTEXTInstance description
    api_standardVARCHAR(20)NOT NULL, FK→api_standardsAPI standard handle
    modelTEXTNOT NULLModel name
    dimensionsINTEGERNOT NULLVector dimensions
    context_limitINTEGERNOT NULLMaximum context length
    definition_idINTEGERFK→definitionsReference to definition template
    api_key_encryptedBYTEAEncrypted API key for service authentication
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, instance_handle) - Instance handles unique per owner
    • ON DELETE CASCADE - Delete instance when owner deleted
    • ON DELETE SET NULL - Keep instance if definition deleted

    Indexes:

    • Composite index on (owner, instance_handle)

    API Key Encryption:

    • Encrypted using AES-256-GCM
    • Encryption key from ENCRYPTION_KEY environment variable
    • Cannot be recovered if encryption key is lost
    • Stored as base64-encoded BYTEA

    Relationships:

    • Owned by one user (N:1)
    • References one API standard (N:1)
    • Based on one definition template (N:1, optional)
    • Used by projects (1:N)
    • Used by embeddings (1:N)
    • Can be shared with users (N:M via instances_shared_with)

    api_standards#

    Defines API specifications for LLM embedding services.

    ColumnTypeConstraintsDescription
    api_standard_handleVARCHAR(20)PRIMARY KEYStandard identifier (e.g., openai, cohere)
    descriptionTEXTAPI description and version info
    key_methodVARCHAR(20)NOT NULL, FK→key_methodsAuthentication method
    key_fieldVARCHAR(20)Header/field name for API key
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Built-in Standards:

    HandleDescriptionKey MethodKey Field
    openaiOpenAI Embeddings API v1auth_bearerAuthorization
    cohereCohere Embed API v2auth_bearerAuthorization
    geminiGemini Embeddings APIauth_bearerx-goog-api-key

    Relationships:

    • Used by definitions (1:N)
    • Used by instances (1:N)
    • References one key_method (N:1)

    Association Tables#

    users_projects#

    Defines project sharing and access control.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    project_idSERIALFK→projects, PKProject being shared
    roleVARCHAR(20)NOT NULL, FK→vdb_rolesAccess level (owner/editor/reader)
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, project_id) - One role per user per project
    • ON DELETE CASCADE - Remove sharing when user or project deleted

    Roles:

    • owner - Full control (only project creator)
    • editor - Can add/modify/delete embeddings
    • reader - Read-only access to embeddings

    instances_shared_with#

    Defines LLM service instance sharing.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    instance_idINTEGERFK→instances, PKInstance being shared
    roleVARCHAR(20)NOT NULL, FK→vdb_rolesAccess level
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, instance_id) - One role per user per instance
    • ON DELETE CASCADE - Remove sharing when user or instance deleted

    definitions_shared_with#

    Defines LLM service definition sharing.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    definition_idINTEGERFK→definitions, PKDefinition being shared
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, definition_id) - One share per user per definition
    • ON DELETE CASCADE - Remove sharing when user or definition deleted

    Indexes:

    • Index on user_handle for efficient user lookups
    • Index on definition_id for efficient definition lookups

    Reference Tables#

    vdb_roles#

    Enumeration of valid access roles.

    ColumnTypeConstraintsDescription
    vdb_roleVARCHAR(20)PRIMARY KEYRole name

    Values:

    • owner - Full control over resource
    • editor - Read and write access
    • reader - Read-only access

    key_methods#

    Enumeration of API authentication methods.

    ColumnTypeConstraintsDescription
    key_methodVARCHAR(20)PRIMARY KEYAuthentication method

    Values:

    • auth_bearer - Bearer token in Authorization header
    • body_form - API key in request body
    • query_param - API key in URL query parameter
    • custom_header - API key in custom header

    Vector Indexes#

    HNSW (Hierarchical Navigable Small World) indexes for fast approximate nearest neighbor search.

    Index Configuration#

    All vector indexes use HNSW with these parameters:

    • m = 24 - Number of neighbors per node
    • ef_construction = 200 - Build-time accuracy parameter
    • ef_search = 100 - Query-time accuracy parameter
    • Expected recall: ~99.8%

    Dimension-Specific Indexes#

    Index NameDimensionsCommon Models
    embeddings_vector_384384Cohere embed-multilingual-light-v3.0, embed-english-light-v3.0
    embeddings_vector_768768BERT base, Cohere embed-multilingual-v2.0, Gemini Embeddings
    embeddings_vector_10241024BERT large, SBERT, Cohere embed-multilingual-v3.0, embed-english-v3.0
    embeddings_vector_15361536OpenAI text-embedding-ada-002, text-embedding-3-small, Cohere embed-v4.0
    embeddings_vector_30723072OpenAI text-embedding-3-large, Gemini embedding-001

    Index Structure:

    CREATE INDEX embeddings_vector_1536 ON embeddings 
    +USING hnsw ((vector::halfvec(1536)) halfvec_cosine_ops) 
    +WITH (m = 24, ef_construction = 200) 
    +WHERE (vector_dim = 1536);

    Usage:

    • Indexes are partial - only include vectors of matching dimension
    • Automatically used for similarity queries with matching dimensions
    • Use cosine distance for similarity calculation

    Relationships Diagram#

    users (1) ──owns──> (N) projects (1) ──contains──> (N) embeddings
    +  │                      │                              │
    +  │                      └─> uses (1) instances (N) <───┘
    +  │                                    │
    +  │                                    └─> based on (1) definitions
    +  │                                              │
    +  ├──owns──> (N) instances ──uses──> (1) api_standards
    +  │               │                          │
    +  │               └─> references (1) definitions
    +  │
    +  └──owns──> (N) definitions ──references──> (1) api_standards
    +
    +Sharing:
    +  users (N) <──shares─> (M) projects (via users_projects)
    +  users (N) <──shares─> (M) instances (via instances_shared_with)
    +  users (N) <──shares─> (M) definitions (via definitions_shared_with)

    Data Validation#

    Dimension Validation#

    Embeddings must have dimensions matching their LLM service instance:

    • embeddings.vector_dim must equal instances.dimensions
    • Enforced at API level during upload
    • Similarity queries automatically filter by matching dimensions

    Metadata Validation#

    Projects can define JSON Schema in metadata_scheme:

    • Validates all embedding metadata on upload
    • Optional - if NULL, metadata not validated
    • Enforced at API level
    • Admin sanity check validates all existing metadata

    Sanity Check Queries#

    The /v1/admin/sanity-check endpoint verifies:

    1. All embeddings have dimensions matching their instance
    2. All metadata conforms to project schemas (if defined)

    Common Queries#

    Find User’s Projects#

    SELECT p.project_handle, p.description, p.created_at
    +FROM projects p
    +WHERE p.owner = 'alice'
    +ORDER BY p.created_at DESC;

    Find Shared Projects#

    SELECT p.project_handle, p.owner, up.role
    +FROM users_projects up
    +JOIN projects p ON up.project_id = p.project_id
    +WHERE up.user_handle = 'bob'
    +ORDER BY p.owner, p.project_handle;

    Find Similar Embeddings#

    SELECT text_id, vector <-> '[0.1, 0.2, ...]'::vector AS distance
    +FROM embeddings
    +WHERE project_id = 123 AND vector_dim = 1536
    +ORDER BY vector <-> '[0.1, 0.2, ...]'::vector
    +LIMIT 10;

    Count Embeddings by Project#

    SELECT p.project_handle, COUNT(e.embeddings_id) AS embedding_count
    +FROM projects p
    +LEFT JOIN embeddings e ON p.project_id = e.project_id
    +WHERE p.owner = 'alice'
    +GROUP BY p.project_id, p.project_handle
    +ORDER BY embedding_count DESC;

    Database Maintenance#

    Backup Recommendations#

    Critical Data:

    • User accounts (users)
    • API keys (vdb_key in users, api_key_encrypted in instances)
    • ENCRYPTION_KEY environment variable (backup separately!)
    • Projects and embeddings

    Backup Strategy:

    # Full database backup
    +pg_dump -U postgres dhamps_vdb > backup.sql
    +
    +# Backup encryption key separately
    +echo "$ENCRYPTION_KEY" > encryption_key.backup
    +chmod 400 encryption_key.backup

    Vacuum and Analyze#

    -- Regular maintenance
    +VACUUM ANALYZE embeddings;
    +VACUUM ANALYZE projects;
    +
    +-- Rebuild vector indexes if needed
    +REINDEX INDEX embeddings_vector_1536;

    Monitoring Queries#

    -- Check index usage
    +SELECT schemaname, tablename, indexname, idx_scan
    +FROM pg_stat_user_indexes
    +WHERE tablename = 'embeddings'
    +ORDER BY idx_scan DESC;
    +
    +-- Check table sizes
    +SELECT relname, pg_size_pretty(pg_total_relation_size(oid))
    +FROM pg_class
    +WHERE relname IN ('embeddings', 'projects', 'users')
    +ORDER BY pg_total_relation_size(oid) DESC;
    \ No newline at end of file diff --git a/docs/public/reference/index.html b/docs/public/reference/index.html new file mode 100644 index 0000000..a50ad14 --- /dev/null +++ b/docs/public/reference/index.html @@ -0,0 +1,6 @@ +Reference | dhamps-vdb Documentation + +

    Reference Documentation#

    Technical reference materials and specifications.

    Contents#

    Additional Resources#

    • OpenAPI Specification: Available at /openapi.yaml on any running instance
    • Go Package Documentation: Coming soon
    • Source Code: github.com/mpilhlt/dhamps-vdb
    \ No newline at end of file diff --git a/docs/public/reference/index.xml b/docs/public/reference/index.xml new file mode 100644 index 0000000..9bea3a4 --- /dev/null +++ b/docs/public/reference/index.xml @@ -0,0 +1,56 @@ +Reference on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/reference/Recent content in Reference on dhamps-vdb DocumentationHugoen-usConfiguration Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/configuration/<h1 id="configuration-reference">Configuration Reference<a class="anchor" href="#configuration-reference">#</a></h1> +<p>Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>dhamps-vdb is configured through a combination of:</p> +<ol> +<li><strong>Environment variables</strong> (recommended)</li> +<li><strong>Command-line flags</strong> (overrides environment variables)</li> +<li><strong><code>.env</code> files</strong> (for Docker and local development)</li> +</ol> +<p>Configuration is loaded in the following priority order (highest to lowest):</p> +<ol> +<li>Command-line flags</li> +<li>Environment variables</li> +<li><code>.env</code> file values</li> +<li>Default values from <code>options.go</code></li> +</ol> +<h2 id="configuration-options">Configuration Options<a class="anchor" href="#configuration-options">#</a></h2> +<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> +<p>Options for controlling the API service behavior.</p>Database Schema Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/database-schema/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/<h1 id="database-schema-reference">Database Schema Reference<a class="anchor" href="#database-schema-reference">#</a></h1> +<p>Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in <code>internal/database/migrations/</code>.</p> +<p><strong>Key Features:</strong></p> +<ul> +<li>Vector embeddings stored as <code>halfvec</code> for efficient storage</li> +<li>HNSW indexes for fast approximate nearest neighbor search</li> +<li>Automatic timestamp tracking (<code>created_at</code>, <code>updated_at</code>)</li> +<li>Foreign key constraints with CASCADE deletion</li> +<li>Role-based access control through association tables</li> +<li>Multi-tenancy support (user-owned resources)</li> +</ul> +<h2 id="schema-migrations">Schema Migrations<a class="anchor" href="#schema-migrations">#</a></h2> +<p>Current schema version is defined by 4 migration files:</p>Product Roadmaphttps://mpilhlt.github.io/dhamps-vdb/reference/roadmap/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/<h1 id="product-roadmap">Product Roadmap<a class="anchor" href="#product-roadmap">#</a></h1> +<p>Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.</p> +<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> +<p>This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.</p> +<h2 id="completed-features">Completed Features<a class="anchor" href="#completed-features">#</a></h2> +<h3 id="core-functionality">Core Functionality<a class="anchor" href="#core-functionality">#</a></h3> +<ul> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>User authentication &amp; restrictions on some API calls</strong></p> +<ul> +<li>Bearer token authentication</li> +<li>Role-based access control</li> +<li>Admin vs user permissions</li> +</ul> +</li> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>API versioning</strong></p> +<ul> +<li>Version 1 API with <code>/v1/</code> prefix</li> +<li>Backward compatibility support</li> +</ul> +</li> +<li> +<p><input checked="" disabled="" type="checkbox"> <strong>Better options handling</strong></p> \ No newline at end of file diff --git a/docs/public/reference/roadmap/index.html b/docs/public/reference/roadmap/index.html new file mode 100644 index 0000000..93ca238 --- /dev/null +++ b/docs/public/reference/roadmap/index.html @@ -0,0 +1,16 @@ +Product Roadmap | dhamps-vdb Documentation + +

    Product Roadmap#

    Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.

    Overview#

    This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.

    Completed Features#

    Core Functionality#

    • User authentication & restrictions on some API calls

      • Bearer token authentication
      • Role-based access control
      • Admin vs user permissions
    • API versioning

      • Version 1 API with /v1/ prefix
      • Backward compatibility support
    • Better options handling

      • Command-line flags via Huma CLI
      • Environment variable configuration
      • .env file support
    • Handle metadata

      • JSONB storage for flexible metadata
      • Metadata attached to embeddings
    • Validation with metadata schema

      • JSON Schema validation for embedding metadata
      • Project-level schema definitions
      • Automatic validation on upload
    • Filter similar passages by metadata field

      • Metadata-based filtering in similarity queries
      • Exclude documents by metadata value
      • Query parameters: metadata_path and metadata_value

    Data Management#

    • Use transactions

      • Atomic operations for multi-step actions
      • Consistency for project creation with sharing
      • Rollback on errors
    • Catch POST to existing resources

      • Prevent duplicate creation
      • Return appropriate error codes
      • Suggest using PUT for updates
    • Always use specific error messages

      • Detailed error descriptions
      • Helpful troubleshooting information
      • Consistent error response format

    Testing & Quality#

    • Tests

      • Integration tests for all major operations
      • Testcontainers for isolated database testing
      • Cleanup verification queries
    • When testing, check cleanup by adding a new query/function to see if all tables are empty

      • Verify test isolation
      • Ensure no data leakage between tests
    • Make sure input is validated consistently

      • Dimension validation for embeddings
      • Schema validation for metadata
      • Request validation via Huma

    Collaboration Features#

    • Add project sharing/unsharing functions & API paths

      • Share projects with specific users
      • Define roles: owner, editor, reader
      • API endpoints for managing sharing
    • Add mechanism to allow anonymous/public reading access to embeddings

      • public_read flag on projects
      • Wildcard sharing via "*" in shared_with
      • Unauthenticated access to public embeddings
    • Transfer of projects from one owner to another as new operation

      • Owner-initiated project transfers
      • Ownership verification
      • Automatic cleanup of old owner associations

    Service Architecture#

    • Add definition creation/listing/deletion functions & paths
      • LLM service definitions (templates)
      • Instances (user-specific configurations)
      • System-provided global definitions

    Deployment & Operations#

    • Dockerization

      • Multi-stage Dockerfile
      • Docker Compose with PostgreSQL
      • External database support
      • Automated setup script
    • Make sure pagination is supported consistently

      • Limit and offset parameters
      • Consistent across all list endpoints
      • Documented pagination behavior

    Security#

    • Prevent acceptance of requests as user “_system”
      • Reserved system user for internal use
      • Blocked from external authentication
      • Protected system-owned resources

    In Progress#

    Documentation#

    • Revisit all documentation

      • Comprehensive reference documentation
      • Updated API examples
      • Docker deployment guides
    • Add documentation for metadata filtering of similars

      • Document metadata_path and metadata_value parameters
      • Provide usage examples
      • Explain use cases (exclude same author, etc.)
      • Note: Query parameters are: metadata_path and metadata_value as in: https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7&limit=5&metadata_path=author_id&metadata_value=A0083

    Planned Features#

    High Priority#

    Network Connectivity#

    • Implement and make consequent use of max_idle (5), max_concurr (5), timeouts, and cancellations

      • Connection pool management
      • Maximum idle connections: 5
      • Maximum concurrent connections: 5
      • Request timeouts
      • Context cancellation support
    • Concurrency (leaky bucket approach) and Rate limiting

      • Leaky bucket algorithm for concurrency control
      • Rate limiting using Redis
      • Sliding window implementation
      • Standard rate limit headers
      • See Huma request limits for implementation
    • Caching

      • Response caching for frequently accessed data
      • Cache invalidation strategies
      • Redis or in-memory caching
      • Configurable TTL

    API Standards#

    • Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio
      • Anthropic embeddings API
      • Mistral embeddings API
      • llama.cpp server API
      • Ollama embeddings API
      • vLLM embeddings API
      • LM Studio embeddings API
      • Standard authentication methods
      • Example definitions in testdata

    Medium Priority#

    User Experience#

    • HTML UI

      • Web-based interface for API management
      • User-friendly project creation
      • Visual embedding explorer
      • API key management
      • Alternative to CLI/API usage
    • Allow to request verbose information even in list outputs

      • verbose=yes query parameter
      • Full object details in list endpoints
      • Optional vs default minimal output
      • Performance considerations
    • Add possibility to use PATCH method to change existing resources

      • Partial updates without full replacement
      • PATCH support for users, projects, instances
      • Merge semantics for nested objects
      • Validation of partial updates
      • Status: Partially implemented via automatic PATCH handler

    Logging and Monitoring#

    • Proper logging with --verbose and --quiet modes
      • Structured logging (JSON format)
      • Log levels: ERROR, WARN, INFO, DEBUG, TRACE
      • --verbose flag for detailed logs
      • --quiet flag for minimal logs
      • Request/response logging
      • Performance metrics logging
      • Integration with log aggregation systems

    Future Enhancements#

    Advanced Features#

    • Bulk Operations

      • Batch embedding upload
      • Bulk deletion
      • Transaction support for large operations
    • Advanced Search

      • Combined vector + metadata filtering
      • Hybrid search (vector + keyword)
      • Multi-vector search
      • Weighted search results
    • Embeddings Management

      • Update embeddings in place
      • Re-embedding workflows
      • Embedding versioning
      • Dimension conversion utilities

    Performance#

    • Query Optimization

      • Query plan analysis
      • Index optimization
      • Materialized views for common queries
      • Database connection pooling improvements
    • Scaling

      • Horizontal scaling support
      • Read replicas for query load
      • Partitioning strategies for large datasets
      • Distributed vector search

    Security & Access Control#

    • Fine-grained Permissions

      • Custom roles beyond owner/editor/reader
      • Permission inheritance
      • Temporary access grants
      • IP-based access control
    • Audit Logging

      • Track all API operations
      • User action history
      • Security event logging
      • Compliance reporting
    • OAuth/SAML Integration

      • OAuth 2.0 authentication
      • SAML SSO support
      • Identity provider integration
      • External authentication services

    Integration#

    • Webhooks

      • Event notifications for embeddings changes
      • Project updates notifications
      • Configurable webhook endpoints
      • Retry logic and delivery guarantees
    • Export/Import

      • Project export to standard formats
      • Bulk embedding export
      • Import from other vector databases
      • Migration utilities
    • SDK Support

      • Python SDK
      • JavaScript/TypeScript SDK
      • Go SDK
      • CLI improvements

    Development Process#

    Release Cycle#

    • Minor versions (0.x.0): New features, API additions
    • Patch versions (0.0.x): Bug fixes, documentation updates
    • Major versions (x.0.0): Breaking API changes (future)

    Feature Requests#

    To request a feature or suggest improvements:

    1. Check existing issues on GitHub
    2. Open a new issue with:
      • Clear description of the feature
      • Use cases and motivation
      • Proposed implementation (if any)
    3. Engage in discussion with maintainers

    Contribution Guidelines#

    Contributions are welcome! See the main repository for:

    • Development setup instructions
    • Code style guidelines
    • Testing requirements
    • Pull request process

    Version History#

    v0.1.0 (2026-02-08)#

    • Fix many things
    • Add many things
    • Still API v1 on the way to stable

    v0.0.1 (2024-12-10)#

    • Initial public release
    • API v1 (work in progress)
    • Core functionality implemented
    • Docker support
    • Project sharing
    • Metadata validation

    Feedback#

    We value your feedback! Please share:

    • Feature requests - What would make dhamps-vdb more useful?
    • Bug reports - Help us improve quality
    • Use cases - How are you using dhamps-vdb?
    • Documentation - What needs clarification?

    Open an issue on GitHub or contact the maintainers directly.

    \ No newline at end of file diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml index 5015c8e..dfd8e94 100644 --- a/docs/public/sitemap.xml +++ b/docs/public/sitemap.xml @@ -1 +1 @@ -https://mpilhlt.github.io/dhamps-vdb/categories/https://mpilhlt.github.io/dhamps-vdb/https://mpilhlt.github.io/dhamps-vdb/tags/ \ No newline at end of file +https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/https://mpilhlt.github.io/dhamps-vdb/api/authentication/https://mpilhlt.github.io/dhamps-vdb/reference/configuration/https://mpilhlt.github.io/dhamps-vdb/deployment/docker/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/https://mpilhlt.github.io/dhamps-vdb/getting-started/https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/https://mpilhlt.github.io/dhamps-vdb/development/testing/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/https://mpilhlt.github.io/dhamps-vdb/concepts/https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/https://mpilhlt.github.io/dhamps-vdb/development/contributing/https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/https://mpilhlt.github.io/dhamps-vdb/deployment/database/https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/https://mpilhlt.github.io/dhamps-vdb/development/architecture/https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/https://mpilhlt.github.io/dhamps-vdb/guides/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/https://mpilhlt.github.io/dhamps-vdb/concepts/projects/https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/https://mpilhlt.github.io/dhamps-vdb/api/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/https://mpilhlt.github.io/dhamps-vdb/development/performance/https://mpilhlt.github.io/dhamps-vdb/deployment/security/https://mpilhlt.github.io/dhamps-vdb/deployment/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/https://mpilhlt.github.io/dhamps-vdb/development/https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/https://mpilhlt.github.io/dhamps-vdb/reference/https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/https://mpilhlt.github.io/dhamps-vdb/api/error-handling/https://mpilhlt.github.io/dhamps-vdb/categories/https://mpilhlt.github.io/dhamps-vdb/https://mpilhlt.github.io/dhamps-vdb/tags/ \ No newline at end of file diff --git a/docs/public/tags/index.html b/docs/public/tags/index.html index 161d839..8278ae2 100644 --- a/docs/public/tags/index.html +++ b/docs/public/tags/index.html @@ -1,3 +1,3 @@ Tags | dhamps-vdb Documentation - +
    \ No newline at end of file From 99e45b5882513efe84d887159bcea3fb71984a7d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:46:00 +0000 Subject: [PATCH 9/9] Complete documentation reorganization: concise README and GitHub Actions workflow Co-authored-by: awagner-mainz <2088443+awagner-mainz@users.noreply.github.com> --- .github/workflows/deploy-docs.yml | 39 + .gitignore | 5 + README.md | 744 +---- docs/.hugo_build.lock | 0 docs/ChatGPT.md | 486 --- docs/LLM_SERVICE_REFACTORING.md | 751 ----- docs/METADATA_SCHEMA_EXAMPLES.md | 230 -- docs/PERFORMANCE_OPTIMIZATION.md | 132 - docs/PUBLIC_ACCESS.md | 123 - docs/public/404.html | 4 - docs/public/api/authentication/index.html | 45 - .../api/endpoints/api-standards/index.html | 135 - .../api/endpoints/embeddings/index.html | 207 -- docs/public/api/endpoints/index.html | 13 - docs/public/api/endpoints/index.xml | 103 - .../api/endpoints/llm-services/index.html | 164 - docs/public/api/endpoints/projects/index.html | 169 -- docs/public/api/endpoints/similars/index.html | 135 - docs/public/api/endpoints/users/index.html | 104 - docs/public/api/error-handling/index.html | 236 -- docs/public/api/index.html | 18 - docs/public/api/index.xml | 59 - docs/public/api/patch-updates/index.html | 169 -- docs/public/api/query-parameters/index.html | 115 - docs/public/asciinema/asciinema-auto.js | 7 - docs/public/asciinema/asciinema-player.css | 2389 --------------- docs/public/asciinema/asciinema-player.min.js | 1 - ...87344917b325208841feca0968fe450f570575.css | 1 - docs/public/categories/index.html | 3 - docs/public/categories/index.xml | 1 - docs/public/concepts/architecture/index.html | 92 - docs/public/concepts/embeddings/index.html | 153 - docs/public/concepts/index.html | 10 - docs/public/concepts/index.xml | 219 -- docs/public/concepts/llm-services/index.html | 118 - docs/public/concepts/metadata/index.html | 180 -- docs/public/concepts/projects/index.html | 145 - .../concepts/similarity-search/index.html | 76 - .../public/concepts/users-and-auth/index.html | 73 - docs/public/deployment/database/index.html | 229 -- docs/public/deployment/docker/index.html | 122 - .../environment-variables/index.html | 105 - docs/public/deployment/index.html | 12 - docs/public/deployment/index.xml | 106 - docs/public/deployment/security/index.html | 219 -- .../development/architecture/index.html | 547 ---- .../development/contributing/index.html | 306 -- docs/public/development/index.html | 17 - docs/public/development/index.xml | 137 - .../public/development/performance/index.html | 470 --- docs/public/development/testing/index.html | 288 -- ...ecbe5ed12ab4d8e11ba873c2f11161202b945.json | 1 - ...b05a356d5d9f40e308f4ec936f40762c90de5.json | 1 - ...f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js | 1 - ...4c0460e5894c72e7286c511967078b24f321f5e.js | 1 - docs/public/favicon.png | Bin 298 -> 0 bytes docs/public/favicon.svg | 1 - docs/public/fuse.min.js | 9 - .../getting-started/configuration/index.html | 52 - docs/public/getting-started/docker/index.html | 183 -- .../getting-started/first-project/index.html | 172 -- docs/public/getting-started/index.html | 9 - docs/public/getting-started/index.xml | 192 -- .../getting-started/installation/index.html | 21 - .../getting-started/quick-start/index.html | 160 - .../public/guides/batch-operations/index.html | 508 ---- docs/public/guides/index.html | 10 - docs/public/guides/index.xml | 94 - .../guides/instance-management/index.html | 273 -- .../guides/metadata-filtering/index.html | 189 -- .../guides/metadata-validation/index.html | 372 --- .../guides/ownership-transfer/index.html | 153 - docs/public/guides/project-sharing/index.html | 142 - docs/public/guides/public-projects/index.html | 162 - docs/public/guides/rag-workflow/index.html | 228 -- docs/public/icons/menu.svg | 1 - docs/public/icons/toc.svg | 1 - docs/public/index.html | 21 - docs/public/index.xml | 959 ------ docs/public/katex/auto-render.min.js | 1 - docs/public/katex/fonts/KaTeX_AMS-Regular.ttf | Bin 63632 -> 0 bytes .../public/katex/fonts/KaTeX_AMS-Regular.woff | Bin 33516 -> 0 bytes .../katex/fonts/KaTeX_AMS-Regular.woff2 | Bin 28076 -> 0 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.ttf | Bin 12368 -> 0 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.woff | Bin 7716 -> 0 bytes .../katex/fonts/KaTeX_Caligraphic-Bold.woff2 | Bin 6912 -> 0 bytes .../katex/fonts/KaTeX_Caligraphic-Regular.ttf | Bin 12344 -> 0 bytes .../fonts/KaTeX_Caligraphic-Regular.woff | Bin 7656 -> 0 bytes .../fonts/KaTeX_Caligraphic-Regular.woff2 | Bin 6908 -> 0 bytes .../public/katex/fonts/KaTeX_Fraktur-Bold.ttf | Bin 19584 -> 0 bytes .../katex/fonts/KaTeX_Fraktur-Bold.woff | Bin 13296 -> 0 bytes .../katex/fonts/KaTeX_Fraktur-Bold.woff2 | Bin 11348 -> 0 bytes .../katex/fonts/KaTeX_Fraktur-Regular.ttf | Bin 19572 -> 0 bytes .../katex/fonts/KaTeX_Fraktur-Regular.woff | Bin 13208 -> 0 bytes .../katex/fonts/KaTeX_Fraktur-Regular.woff2 | Bin 11316 -> 0 bytes docs/public/katex/fonts/KaTeX_Main-Bold.ttf | Bin 51336 -> 0 bytes docs/public/katex/fonts/KaTeX_Main-Bold.woff | Bin 29912 -> 0 bytes docs/public/katex/fonts/KaTeX_Main-Bold.woff2 | Bin 25324 -> 0 bytes .../katex/fonts/KaTeX_Main-BoldItalic.ttf | Bin 32968 -> 0 bytes .../katex/fonts/KaTeX_Main-BoldItalic.woff | Bin 19412 -> 0 bytes .../katex/fonts/KaTeX_Main-BoldItalic.woff2 | Bin 16780 -> 0 bytes docs/public/katex/fonts/KaTeX_Main-Italic.ttf | Bin 33580 -> 0 bytes .../public/katex/fonts/KaTeX_Main-Italic.woff | Bin 19676 -> 0 bytes .../katex/fonts/KaTeX_Main-Italic.woff2 | Bin 16988 -> 0 bytes .../public/katex/fonts/KaTeX_Main-Regular.ttf | Bin 53580 -> 0 bytes .../katex/fonts/KaTeX_Main-Regular.woff | Bin 30772 -> 0 bytes .../katex/fonts/KaTeX_Main-Regular.woff2 | Bin 26272 -> 0 bytes .../katex/fonts/KaTeX_Math-BoldItalic.ttf | Bin 31196 -> 0 bytes .../katex/fonts/KaTeX_Math-BoldItalic.woff | Bin 18668 -> 0 bytes .../katex/fonts/KaTeX_Math-BoldItalic.woff2 | Bin 16400 -> 0 bytes docs/public/katex/fonts/KaTeX_Math-Italic.ttf | Bin 31308 -> 0 bytes .../public/katex/fonts/KaTeX_Math-Italic.woff | Bin 18748 -> 0 bytes .../katex/fonts/KaTeX_Math-Italic.woff2 | Bin 16440 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Bold.ttf | Bin 24504 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Bold.woff | Bin 14408 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Bold.woff2 | Bin 12216 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Italic.ttf | Bin 22364 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Italic.woff | Bin 14112 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Italic.woff2 | Bin 12028 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Regular.ttf | Bin 19436 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Regular.woff | Bin 12316 -> 0 bytes .../katex/fonts/KaTeX_SansSerif-Regular.woff2 | Bin 10344 -> 0 bytes .../katex/fonts/KaTeX_Script-Regular.ttf | Bin 16648 -> 0 bytes .../katex/fonts/KaTeX_Script-Regular.woff | Bin 10588 -> 0 bytes .../katex/fonts/KaTeX_Script-Regular.woff2 | Bin 9644 -> 0 bytes .../katex/fonts/KaTeX_Size1-Regular.ttf | Bin 12228 -> 0 bytes .../katex/fonts/KaTeX_Size1-Regular.woff | Bin 6496 -> 0 bytes .../katex/fonts/KaTeX_Size1-Regular.woff2 | Bin 5468 -> 0 bytes .../katex/fonts/KaTeX_Size2-Regular.ttf | Bin 11508 -> 0 bytes .../katex/fonts/KaTeX_Size2-Regular.woff | Bin 6188 -> 0 bytes .../katex/fonts/KaTeX_Size2-Regular.woff2 | Bin 5208 -> 0 bytes .../katex/fonts/KaTeX_Size3-Regular.ttf | Bin 7588 -> 0 bytes .../katex/fonts/KaTeX_Size3-Regular.woff | Bin 4420 -> 0 bytes .../katex/fonts/KaTeX_Size3-Regular.woff2 | Bin 3624 -> 0 bytes .../katex/fonts/KaTeX_Size4-Regular.ttf | Bin 10364 -> 0 bytes .../katex/fonts/KaTeX_Size4-Regular.woff | Bin 5980 -> 0 bytes .../katex/fonts/KaTeX_Size4-Regular.woff2 | Bin 4928 -> 0 bytes .../katex/fonts/KaTeX_Typewriter-Regular.ttf | Bin 27556 -> 0 bytes .../katex/fonts/KaTeX_Typewriter-Regular.woff | Bin 16028 -> 0 bytes .../fonts/KaTeX_Typewriter-Regular.woff2 | Bin 13568 -> 0 bytes docs/public/katex/katex.min.css | 1 - docs/public/katex/katex.min.js | 1 - docs/public/manifest.json | 15 - docs/public/mermaid.min.js | 2659 ----------------- .../public/reference/configuration/index.html | 200 -- .../reference/database-schema/index.html | 67 - docs/public/reference/index.html | 6 - docs/public/reference/index.xml | 56 - docs/public/reference/roadmap/index.html | 16 - docs/public/sitemap.xml | 1 - docs/public/tags/index.html | 3 - docs/public/tags/index.xml | 1 - ...s_b807c86e8030af4cdc30edccea379f5f.content | 1 - ...scss_b807c86e8030af4cdc30edccea379f5f.json | 1 - 154 files changed, 159 insertions(+), 16998 deletions(-) create mode 100644 .github/workflows/deploy-docs.yml delete mode 100644 docs/.hugo_build.lock delete mode 100644 docs/ChatGPT.md delete mode 100644 docs/LLM_SERVICE_REFACTORING.md delete mode 100644 docs/METADATA_SCHEMA_EXAMPLES.md delete mode 100644 docs/PERFORMANCE_OPTIMIZATION.md delete mode 100644 docs/PUBLIC_ACCESS.md delete mode 100644 docs/public/404.html delete mode 100644 docs/public/api/authentication/index.html delete mode 100644 docs/public/api/endpoints/api-standards/index.html delete mode 100644 docs/public/api/endpoints/embeddings/index.html delete mode 100644 docs/public/api/endpoints/index.html delete mode 100644 docs/public/api/endpoints/index.xml delete mode 100644 docs/public/api/endpoints/llm-services/index.html delete mode 100644 docs/public/api/endpoints/projects/index.html delete mode 100644 docs/public/api/endpoints/similars/index.html delete mode 100644 docs/public/api/endpoints/users/index.html delete mode 100644 docs/public/api/error-handling/index.html delete mode 100644 docs/public/api/index.html delete mode 100644 docs/public/api/index.xml delete mode 100644 docs/public/api/patch-updates/index.html delete mode 100644 docs/public/api/query-parameters/index.html delete mode 100644 docs/public/asciinema/asciinema-auto.js delete mode 100644 docs/public/asciinema/asciinema-player.css delete mode 100644 docs/public/asciinema/asciinema-player.min.js delete mode 100644 docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css delete mode 100644 docs/public/categories/index.html delete mode 100644 docs/public/categories/index.xml delete mode 100644 docs/public/concepts/architecture/index.html delete mode 100644 docs/public/concepts/embeddings/index.html delete mode 100644 docs/public/concepts/index.html delete mode 100644 docs/public/concepts/index.xml delete mode 100644 docs/public/concepts/llm-services/index.html delete mode 100644 docs/public/concepts/metadata/index.html delete mode 100644 docs/public/concepts/projects/index.html delete mode 100644 docs/public/concepts/similarity-search/index.html delete mode 100644 docs/public/concepts/users-and-auth/index.html delete mode 100644 docs/public/deployment/database/index.html delete mode 100644 docs/public/deployment/docker/index.html delete mode 100644 docs/public/deployment/environment-variables/index.html delete mode 100644 docs/public/deployment/index.html delete mode 100644 docs/public/deployment/index.xml delete mode 100644 docs/public/deployment/security/index.html delete mode 100644 docs/public/development/architecture/index.html delete mode 100644 docs/public/development/contributing/index.html delete mode 100644 docs/public/development/index.html delete mode 100644 docs/public/development/index.xml delete mode 100644 docs/public/development/performance/index.html delete mode 100644 docs/public/development/testing/index.html delete mode 100644 docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json delete mode 100644 docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json delete mode 100644 docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js delete mode 100644 docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js delete mode 100644 docs/public/favicon.png delete mode 100644 docs/public/favicon.svg delete mode 100644 docs/public/fuse.min.js delete mode 100644 docs/public/getting-started/configuration/index.html delete mode 100644 docs/public/getting-started/docker/index.html delete mode 100644 docs/public/getting-started/first-project/index.html delete mode 100644 docs/public/getting-started/index.html delete mode 100644 docs/public/getting-started/index.xml delete mode 100644 docs/public/getting-started/installation/index.html delete mode 100644 docs/public/getting-started/quick-start/index.html delete mode 100644 docs/public/guides/batch-operations/index.html delete mode 100644 docs/public/guides/index.html delete mode 100644 docs/public/guides/index.xml delete mode 100644 docs/public/guides/instance-management/index.html delete mode 100644 docs/public/guides/metadata-filtering/index.html delete mode 100644 docs/public/guides/metadata-validation/index.html delete mode 100644 docs/public/guides/ownership-transfer/index.html delete mode 100644 docs/public/guides/project-sharing/index.html delete mode 100644 docs/public/guides/public-projects/index.html delete mode 100644 docs/public/guides/rag-workflow/index.html delete mode 100644 docs/public/icons/menu.svg delete mode 100644 docs/public/icons/toc.svg delete mode 100644 docs/public/index.html delete mode 100644 docs/public/index.xml delete mode 100644 docs/public/katex/auto-render.min.js delete mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Bold.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Fraktur-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Bold.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Italic.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Main-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Math-Italic.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Script-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Size3-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Size4-Regular.woff2 delete mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf delete mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff delete mode 100644 docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff2 delete mode 100644 docs/public/katex/katex.min.css delete mode 100644 docs/public/katex/katex.min.js delete mode 100644 docs/public/manifest.json delete mode 100644 docs/public/mermaid.min.js delete mode 100644 docs/public/reference/configuration/index.html delete mode 100644 docs/public/reference/database-schema/index.html delete mode 100644 docs/public/reference/index.html delete mode 100644 docs/public/reference/index.xml delete mode 100644 docs/public/reference/roadmap/index.html delete mode 100644 docs/public/sitemap.xml delete mode 100644 docs/public/tags/index.html delete mode 100644 docs/public/tags/index.xml delete mode 100644 docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content delete mode 100644 docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..e297d54 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,39 @@ +name: Deploy Documentation + +on: + push: + branches: [main] + paths: + - 'docs/**' + - '.github/workflows/deploy-docs.yml' + +permissions: + contents: read + pages: write + id-token: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: 'latest' + extended: true + + - name: Build + run: cd docs && hugo --minify + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./docs/public + + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index f1469b9..f86ba5b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,8 @@ go.work # Files with secrets .env tern.conf + +# Hugo build output +docs/public/ +docs/resources/ +docs/.hugo_build.lock diff --git a/README.md b/README.md index 874ae5f..6a96dcc 100644 --- a/README.md +++ b/README.md @@ -3,707 +3,193 @@ Vector Database for the DH at Max Planck Society initiative [![Go Report Card](https://goreportcard.com/badge/github.com/mpilhlt/dhamps-vdb?style=flat-square)](https://goreportcard.com/report/github.com/mpilhlt/dhamps-vdb) [![Release](https://img.shields.io/github/v/release/mpilhlt/dhamps-vdb.svg?style=flat-square&include_prereleases)](https://github.com/mpilhlt/dhamps-vdb/releases/latest) - - ## Introduction -This is an application serving an API to handle embeddings. It stores embeddings in a PostgreSQL backend and uses its vector support, but allows you to manage different users, projects, and LLM configurations via a simple Restful API. - -The typical use case is as a component of a Retrieval Augmented Generation (RAG) workflow: You create embeddings for a collection of text snippets and upload them to this API. For each text snippet, you upload a text identifier, the embeddings vector and, optionally, metadata or the text itself. Then, you can +dhamps-vdb is a PostgreSQL-backed vector database with pgvector support, providing a RESTful API for managing embeddings in Retrieval Augmented Generation (RAG) workflows. Store embeddings for text snippets with metadata, then find similar content using cosine similarity search. -- `GET` the most similar texts for a text that is already in the database by specifying the text's identifier in a URL -- `POST` raw embeddings to find similar texts without storing the query embeddings in the database - -In both cases, the service returns a list of text identifiers along with their similarity scores that you can then use in your own processing, perhaps based on other means of providing the respective texts. +The typical use case is as a RAG component: Create embeddings for your text collection, upload them with identifiers and optional metadata, then query for similar texts either by identifier (`GET`) or by posting raw embeddings (`POST`). The service returns text identifiers with similarity scores for use in your application. ## Features -- OpenAPI documentation -- Supports different embeddings configurations (e.g. dimensions) -- Rights management (authentication via API token) -- Automatic validation of embeddings and metadata +### Core Capabilities +- **PostgreSQL with pgvector backend** - Reliable, scalable vector storage +- **RESTful API** - OpenAPI-documented endpoints +- **Docker deployment ready** - Includes PostgreSQL with pgvector +- **Comprehensive test coverage** - Integration tests with testcontainers + +### Multi-User & Access Control +- **Multi-user support** - Role-based access control (admin, owner, reader, editor) +- **Project sharing** - Collaborate with specific users +- **Public access mode** - Enable unauthenticated read access for projects +- **Project ownership transfer** - Transfer projects between users -## Getting started +### LLM & Embedding Management +- **LLM service management** - Service definitions and instances with encrypted API keys +- **Multiple embedding configurations** - Support for different dimensions +- **Automatic dimension validation** - Ensures vector consistency +- **Flexible instance sharing** - Share LLM service instances across users -### Docker Deployment (Recommended) +### Data Validation & Search +- **JSON Schema-based metadata validation** - Enforce metadata structure +- **Metadata filtering in similarity search** - Exclude documents by metadata field values +- **PATCH support** - Partial updates for projects and embeddings +- **Configurable thresholds** - Control similarity search results -The easiest way to run dhamps-vdb is using Docker. See [DOCKER.md](./DOCKER.md) for comprehensive Docker deployment instructions. +## Quick Start -Quick start with Docker: +### 1. Start with Docker ```bash # Automated setup (generates secure keys) ./docker-setup.sh -# Start with docker-compose (includes PostgreSQL with pgvector) +# Start services (includes PostgreSQL with pgvector) docker-compose up -d -# Access the API +# Access the API documentation curl http://localhost:8880/docs ``` -### Compiling from Source - -For **compiling**, you should run `go get ./... ; sqlc generate --no-remote ; go build -o build/dhamps-vdb main.go` (or in place of the last command you can also run it directly with `go run main.go`). - -#### Run tests - -Actual (mostly integration) tests are run like this: - -```bash -$> systemctl --user start podman.socket -$> export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock -$> go test -v ./... -``` - -These tests do not contact any separately installed/launched backend, and instead have a container managed by the testing itself (via [testcontainers](https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/)). - -### Running - -For **running**, you need to set an admin key and a couple of other variables. Have a look in [options.go](./internal/models/options.go) for the full list and documentation. - -You can specify them as command line options, with environment values or in an `.env` file. This last option is recommended because this way, the sensitive information will not be in the command history; but you have to take care of this file's security. For instance, it will/should not be synced to your versioning platform, it is thus listed in `.gitignore` by default. - -If you authenticate with this key, you can create users by `POST`ing to the `/v1/users` endpoint. (The response to user creation will contain an API key for the new user. **Keep it safe, it is not stored anywhere and cannot be recovered.**) Then, either the admin or the user can create projects, llm services and finally post embeddings and get similar elements. - -When launching, the application checks and migrates the database schema to the appropriate version if possible. It presupposes however, that a suitable database and user (with appropriate privileges) have been created beforehand. SQL commands to prepare the database are listed below. For other ways of running, e.g. for tests or with a container instead of an external database, see below as well. - -#### Run with local container - -A local container with a pg_vector-enabled postgresql can be run like this: - -```bash -$> podman run -p 8888:5432 -e POSTGRES_PASSWORD=password pgvector/pgvector:0.7.4-pg16 -``` - -But be aware that the filesystem is not persisted if you run it like this. That means that when you stop and remove the container, you will have to repeat the following database setup when you run it again later on. (And of course any data you may have saved inside the container is lost, too.) - -You can connect to it from a second terminal like so: - -```bash -$> psql -p 8888 -h localhost -U postgres -d postgres -``` - -And then set up the database like this: - -```sql -postgres=# CREATE DATABASE my_vectors; -postgres=# CREATE USER my_user WITH PASSWORD 'my-password'; -postgres=# GRANT ALL PRIVILEGES ON DATABASE "my_vectors" to my_user; -postgres=# \c my_vectors -postgres=# GRANT ALL ON SCHEMA public TO my_user; -postgres=# CREATE EXTENSION IF NOT EXISTS vector; -``` - -### Client Authentication - -Clients should communicate the API key in the `Authorization` header with a `Bearer` prefix, e.g. `Bearer 024v2013621509245f2e24`. Most operations can only be done by the (admin or the) owner of the resource in question. - -**Project Sharing**: Projects can be shared with specific users for read or edit access. See the [Project Sharing](#project-sharing) section below for details on sharing projects with individual users. - -**Public Access**: Projects can also be made publicly accessible (allowing unauthenticated read access to embeddings and similars) by setting the `public_read` field to `true` when creating or updating the project. See [docs/PUBLIC_ACCESS.md](./docs/PUBLIC_ACCESS.md) for details. - -## Project Sharing - -Projects can be shared with other users to enable collaboration. The project owner can grant two levels of access: - -- **reader**: Read-only access to embeddings and similar documents -- **editor**: Read and write access to embeddings (can add/modify/delete embeddings) - -### Sharing During Project Creation - -When creating a project, you can specify users to share with using the `shared_with` field: - -```json -{ - "project_handle": "my-project", - "description": "A collaborative project", - "instance_owner": "alice", - "instance_handle": "embedding1", - "shared_with": [ - { - "user_handle": "bob", - "role": "reader" - }, - { - "user_handle": "charlie", - "role": "editor" - } - ] -} -``` - -### Managing Sharing After Creation - -The project owner can manage sharing through dedicated endpoints: - -**Share a project with a user:** +### 2. Create a User ```bash -POST /v1/projects/{owner}/{project}/share -{ - "share_with_handle": "bob", - "role": "reader" -} -``` - -**Unshare a project from a user:** +curl -X POST http://localhost:8880/v1/users \ + -H "Authorization: Bearer YOUR_ADMIN_KEY" \ + -H "Content-Type: application/json" \ + -d '{"user_handle": "alice", "name": "Alice Smith"}' -```bash -DELETE /v1/projects/{owner}/{project}/share/{user_handle} +# Response includes: {"vdb_key": "alice_abc123..."} +# ⚠️ Save the vdb_key! It cannot be recovered. ``` -**List users a project is shared with:** +### 3. Create an LLM Service Instance ```bash -GET /v1/projects/{owner}/{project}/shared-with +# Use a system-provided definition (openai-large, openai-small, etc.) +curl -X PUT http://localhost:8880/v1/llm-instances/alice/my-openai \ + -H "Authorization: Bearer ALICE_VDB_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "definition_owner": "_system", + "definition_handle": "openai-large", + "api_key_encrypted": "YOUR_OPENAI_API_KEY" + }' ``` -Only the project owner can view the list of shared users and manage sharing. Users who have been granted access to a project cannot see which other users also have access. - -## Project Ownership Transfer - -The project owner can transfer ownership of a project to another user. This is useful when: -- A project maintainer is leaving and wants to hand over control -- Organizational changes require reassigning project ownership -- Consolidating projects under a different user account - -**Transfer ownership:** +### 4. Create a Project ```bash -POST /v1/projects/{owner}/{project}/transfer-ownership -{ - "new_owner_handle": "new_owner" -} +curl -X POST http://localhost:8880/v1/projects/alice \ + -H "Authorization: Bearer ALICE_VDB_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "project_handle": "my-texts", + "description": "My text embeddings", + "instance_owner": "alice", + "instance_handle": "my-openai" + }' ``` -**Important notes:** -- Only the current owner can transfer ownership -- The new owner must be an existing user -- The new owner cannot already have a project with the same handle -- After transfer, the old owner will lose all access to the project -- If the new owner was previously shared with the project, their sharing role will be upgraded to owner -- All embeddings and other project data remain intact during transfer - -**Example:** +### 5. Upload Embeddings ```bash -# Alice transfers her project to Bob -curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \ - -H "Authorization: Bearer alice_api_key" \ +curl -X POST http://localhost:8880/v1/embeddings/alice/my-texts \ + -H "Authorization: Bearer ALICE_VDB_KEY" \ -H "Content-Type: application/json" \ -d '{ - "new_owner_handle": "bob" + "embeddings": [{ + "text_id": "doc1", + "instance_handle": "my-openai", + "vector": [0.1, 0.2, 0.3, ...], + "vector_dim": 3072, + "metadata": {"author": "John Doe", "year": 2024} + }] }' - -# After transfer, the project is accessible at /v1/projects/bob/my-project ``` -### Shared User Access - -Once a project is shared with a user, they can: -- View project metadata -- Retrieve embeddings (reader and editor) -- Search for similar documents (reader and editor) -- Add, modify, or delete embeddings (editor only) - -Shared users **cannot**: -- Delete the project -- Change project settings -- Manage sharing (add/remove other users) -- View the list of other users the project is shared with - -## Data Validation - -The API provides automatic validation to ensure data quality and consistency: - -### Embeddings Dimension Validation - -When uploading embeddings, the system automatically validates: - -1. **Vector dimension consistency**: The `vector_dim` field in your embeddings must match the `dimensions` configured in the LLM service being used. -2. **Vector length verification**: The actual number of elements in the `vector` array must match the declared `vector_dim`. - -If validation fails, you'll receive a `400 Bad Request` response with a detailed error message explaining the mismatch. - -**Example error response:** - -```json -{ - "title": "Bad Request", - "status": 400, - "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 5 dimensions" -} -``` - -### Similarity Query Dimension Filtering - -When querying for similar embeddings, the system automatically filters results to only include embeddings with matching dimensions. This ensures that similarity comparisons are only made between vectors of the same dimensionality, preventing invalid comparisons. - -The similarity queries enforce: -- Only embeddings with matching `vector_dim` are compared -- Only embeddings from the same project are considered -- Vector similarity is calculated using cosine distance on compatible dimensions - -### Metadata Schema Validation - -Projects can optionally define a JSON Schema to validate metadata attached to embeddings. This ensures that all embeddings in a project have consistent, well-structured metadata. - -#### Defining a Metadata Schema - -Include a `metadataScheme` field when creating or updating a project with a valid JSON Schema: - -```json -{ - "project_handle": "my-project", - "description": "Project with metadata validation", - "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}" -} -``` - -The schema above requires an `author` field (string) and allows an optional `year` field (integer). - -#### Schema Validation on Upload - -When uploading embeddings to a project with a metadata schema, the API validates each embedding's metadata against the schema. If validation fails, you'll receive a detailed error message: - -**Example error response:** - -```json -{ - "title": "Bad Request", - "status": 400, - "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n - author: author is required" -} -``` - -### Admin Sanity Check - -Administrators can verify database integrity using the `/v1/admin/sanity-check` endpoint. This endpoint: - -- Checks all embeddings have dimensions matching their LLM service -- Validates all metadata against project schemas (if defined) -- Reports issues and warnings in a structured format - -**Example sanity check request:** +### 6. Find Similar Documents ```bash -curl -X GET http://localhost:8080/v1/admin/sanity-check \ - -H "Authorization: ******" -``` - -**Example response:** - -```json -{ - "status": "PASSED", - "total_projects": 5, - "issues_count": 0, - "warnings_count": 1, - "warnings": [ - "Project alice/project1 has 100 embeddings but no metadata schema defined" - ] -} -``` - -Status values: -- `PASSED`: No issues or warnings found -- `WARNING`: No critical issues, but warnings exist -- `FAILED`: Validation issues found that need attention - -#### Example Metadata Schemas - -**Simple schema with required fields:** - -```json -{ - "type": "object", - "properties": { - "author": {"type": "string"}, - "year": {"type": "integer"}, - "language": {"type": "string"} - }, - "required": ["author", "year"] -} -``` - -**Schema with nested objects:** - -```json -{ - "type": "object", - "properties": { - "author": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "id": {"type": "string"} - }, - "required": ["name"] - }, - "publication": { - "type": "object", - "properties": { - "year": {"type": "integer"}, - "title": {"type": "string"} - } - } - }, - "required": ["author"] -} -``` - -**Schema with enums and constraints:** - -```json -{ - "type": "object", - "properties": { - "genre": { - "type": "string", - "enum": ["fiction", "non-fiction", "poetry", "drama"] - }, - "rating": { - "type": "number", - "minimum": 0, - "maximum": 5 - }, - "tags": { - "type": "array", - "items": {"type": "string"} - } - } -} +# Get documents similar to doc1 +curl "http://localhost:8880/v1/similars/alice/my-texts/doc1?threshold=0.7&limit=5" \ + -H "Authorization: Bearer ALICE_VDB_KEY" ``` -For more information on JSON Schema syntax, see [json-schema.org](https://json-schema.org/). - -## API documentation - -### API Versioning - -We are at `v1`. The first path component to all the endpoints (except for the OpenAPI file) is the version number, e.g. `POST https:///v1/embeddings//`. - -### Endpoints - -In the following table, the version number is skipped for readibility reasons. Nevertheless, it is the first component of all these endpoints. - -For a more detailed, and always up-to-date documentation of the endpoints, including query parameters, return values and data schemes, see the automatically generated live OpenAPI document at `/openapi.yaml` or the browsable version at `/docs`. - -| Endpoint | Method | Description | Allowed Users | -| -------- | ------ | ----------- | ------------- | -| /admin/footgun | GET | Reset Database: Remove all records from database and reset serials/counters | admin | -| /admin/sanity-check | GET | Verify all data in database conforms to schemas and dimension requirements | admin | -| /users | GET | Get all users (list of handles) registered with the Db | admin | -| /users | POST | Register a new user with the Db | admin | -| /users/\ | GET | Get information about user \ | admin, \ | -| /users/\ | PUT | Register a new user with the Db | admin | -| /users/\ | DELETE | Delete a user and all their projects/llm services from the Db | admin, \ | -| /projects/\ | GET | Get all projects (objects) for user \ | admin, \ | -| /projects/\ | POST | Register a new project for user \ | admin, \ | -| /projects/\/\ | GET | Get project information for \'s project \ | admin, \, authorized readers | -| /projects/\/\ | PUT | Register a new project calles \ for user \ | admin, \ | -| /projects/\/\ | DELETE | Delete \'s project \ | admin, \ | -| /projects/\/\/share | POST | Share \'s project \ with another user | admin, \ | -| /projects/\/\/share/\ | DELETE | Unshare \'s project \ from \ | admin, \ | -| /projects/\/\/shared-with | GET | Get list of users \'s project \ is shared with | admin, \ | -| /llm-services/\ | GET | Get all LLM services (objects) for user \ | admin, \ | -| /llm-services/\ | POST | Register a new LLM service for user \ | admin, \ | -| /llm-services/\/ | GET | Get information about LLM service of user \ | admin, \ | -| /llm-services/\/ | PUT | Register a new LLM service called for user \ | admin, \ | -| /llm-services/\/ | DELETE | Delete \'s LLM service | admin, \ | -| /api-standards | GET | Get all defined API standards* | public | -| /api-standards | POST | Register a new API standard* | admin | -| /api-standards/\ | GET | Get information about API standard* \ | public | -| /api-standards/\ | PUT | Register a new API standard* \ | admin | -| /api-standards/\ | DELETE | Delete API standard* \ | admin | -| /embeddings/\/\ | GET | Get all embeddings for \'s project \ (use `limit` and `offset` for paging) | admin, \, authorized readers | -| /embeddings/\/\ | POST | Register a new record with an embeddings vector for \'s project \ | admin, \ | -| /embeddings/\/\ | DELETE | Delete ***all*** embeddings for \'s project \ | admin, \ | -| /embeddings/\/\/\ | GET | Get embeddings and other information about text \ from \'s project \ | admin, \, authorized readers | -| /embeddings/\/\/\ | DELETE | Delete record \ from \'s project \ | admin, \ | -| /similars/\/\/\ | GET | Get a list of documents similar to the text \ in \'s project \, with similarity scores | admin, \, authorized readers | -| /similars/\/\ | POST | Find similar documents using raw embeddings without storing them, with similarity scores | admin, \, authorized readers | - -\* API standards are definitions of how to access an LLM Service: API endpoints, authentication mechanism etc. They are referred to from LLM Service definitions. When LLM Processing will be attempted, this is what will be implemented. Examples are the Cohere Embed API, Version 2, as documented in , or the OpenAI Embeddings API, Version 1, as documented in . You can find these examples in the [valid_api_standard\*.json](./testdata/) files in the `testdata` directory. - -### Similarity Search - -The API provides two endpoints for finding similar documents using vector similarity: - -#### GET Similar Documents (from stored embeddings) - -Find documents similar to an already-stored document by its identifier: +### 7. Filter by Metadata ```bash -GET /v1/similars/{username}/{projectname}/{identifier} +# Exclude documents from the same author +curl "http://localhost:8880/v1/similars/alice/my-texts/doc1?threshold=0.7&metadata_path=author&metadata_value=John%20Doe" \ + -H "Authorization: Bearer ALICE_VDB_KEY" ``` -**Query Parameters:** -- `count` (optional, default: 10, max: 200): Number of similar documents to return -- `threshold` (optional, default: 0.5, range: 0-1): Minimum similarity score threshold -- `limit` (optional, default: 10, max: 200): Maximum number of results to return -- `offset` (optional, default: 0): Pagination offset -- `metadata_path` (optional): Filter results by metadata field path (must be used with `metadata_value`) -- `metadata_value` (optional): Metadata value to exclude from results (must be used with `metadata_path`) +## Getting Started -**Example:** +📚 **[Read the Full Documentation](https://mpilhlt.github.io/dhamps-vdb/)** -```bash -curl -X GET "https:///v1/similars/alice/myproject/doc123?count=5&threshold=0.7" \ - -H "Authorization: Bearer " -``` - -#### POST Similar Documents (from raw embeddings) - -Find similar documents by submitting a raw embedding vector without storing it in the database: +- **[Installation Guide](https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/)** - Build from source +- **[Docker Guide](https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/)** - Detailed Docker deployment (also see [DOCKER.md](./DOCKER.md)) +- **[Configuration](https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/)** - Environment variables and options +- **[Your First Project](https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/)** - Complete walkthrough +- **[API Reference](https://mpilhlt.github.io/dhamps-vdb/api/)** - Complete API documentation -```bash -POST /v1/similars/{username}/{projectname} -``` +## Key Concepts -**Request Body:** +- **[Architecture](https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/)** - How dhamps-vdb works +- **[Users & Authentication](https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/)** - API keys and roles +- **[Projects](https://mpilhlt.github.io/dhamps-vdb/concepts/projects/)** - Organizing embeddings +- **[LLM Services](https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/)** - Definitions vs. instances +- **[Similarity Search](https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/)** - How it works -```json -{ - "vector": [0.1, 0.2, 0.3, ...] -} -``` +## Common Tasks -The vector must be an array of float32 values with dimensions matching the project's LLM service instance configuration. +- **[RAG Workflow](https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/)** - End-to-end example +- **[Project Sharing](https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/)** - Collaborate with others +- **[Metadata Filtering](https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/)** - Exclude documents in search +- **[Metadata Validation](https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/)** - Enforce schemas +- **[Public Projects](https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/)** - Unauthenticated access -**Query Parameters:** Same as GET endpoint above. +## Development -**Example:** +### Building from Source ```bash -curl -X POST "https:///v1/similars/alice/myproject?count=10&threshold=0.8" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] - }' -``` - -#### Response Format - -Both similarity endpoints return the same response format with document identifiers and their similarity scores: - -```json -{ - "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json", - "user_handle": "alice", - "project_handle": "myproject", - "results": [ - { - "id": "doc456", - "similarity": 0.95 - }, - { - "id": "doc789", - "similarity": 0.87 - }, - { - "id": "doc321", - "similarity": 0.82 - } - ] -} -``` - -**Response Fields:** - -- `user_handle`: The project owner's username -- `project_handle`: The project identifier -- `results`: Array of similar documents, ordered by similarity (highest first) - - `id`: Document identifier - - `similarity`: Cosine similarity score (0-1, where 1 is most similar) - -#### Dimension Validation +# Install dependencies and generate code +go get ./... +sqlc generate --no-remote -When using the POST endpoint, the API automatically validates that: -1. The project has an associated LLM service instance -2. The submitted vector dimensions match the LLM service instance's configured dimensions -3. If dimensions don't match, a `400 Bad Request` error is returned with details +# Build +go build -o build/dhamps-vdb main.go -**Example error:** - -```json -{ - "title": "Bad Request", - "status": 400, - "detail": "vector dimension mismatch: expected 1536 dimensions, got 768" -} +# Or run directly +go run main.go ``` -#### Metadata Filtering +### Running Tests -Both endpoints support filtering results by metadata fields. The filter uses negative matching (excludes documents where the metadata field matches the specified value): +Tests use testcontainers for integration testing: ```bash -# Exclude documents with author="John Doe" -curl -X GET "https:///v1/similars/alice/myproject/doc123?metadata_path=author&metadata_value=John%20Doe" \ - -H "Authorization: Bearer " -``` - -This is useful for excluding documents from the same source, author, or category when finding similar content. - -### Partial Updates with PATCH - -For resources that support both GET and PUT operations, PATCH requests are automatically available for partial updates. You only need to include the fields you want to change. This is particularly useful for updating single fields without having to provide all resource data. - -#### **Supported resources:** - -- Users: `/v1/users/{username}` -- Projects: `/v1/projects/{username}/{projectname}` -- LLM Services: `/v1/llm-services/{username}/{llm_servicename}` -- API Standards: `/v1/api-standards/{standardname}` - -#### **Example: Enable world-readable access for a project** +# Start container runtime (if using podman) +systemctl --user start podman.socket +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock -```bash -curl -X PATCH https:///v1/projects/alice/myproject \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{"shared_with": ["*"]}' +# Run tests +go test -v ./... ``` -#### **Example: Update project description** +For more details, see the **[Testing Guide](https://mpilhlt.github.io/dhamps-vdb/development/testing/)**. -```bash -curl -X PATCH https:///v1/projects/alice/myproject \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{"description": "Updated project description"}' -``` - -The PATCH endpoint merges your changes with the existing resource data retrieved via GET, then applies the update via PUT. - -## Code creation and structure - -This API is programmed in go and uses the [huma](https://huma.rocks/) framework with go's stock `http.ServeMux()` routing. - -Some initial code and some later bugfixes have been developed in dialogue with [ChatGPT](./docs/ChatGPT.md). After manual inspection and correction, this is the project structure: - -```default -dhamps-vdb/ -├── .env // This is not distributed because it's in .gitignore -├── .gitignore -├── .repopackignore -├── LICENSE -├── README.md -├── go.mod -├── go.sum -├── main.go -├── repopack-output.xml -├── repopack.config.json -├── sqlc.yaml -├── template.env -├── api/ -│ └── openapi.yml // OpenAPI spec file, not up to date -├── docs/ -│ └── ChatGPT.md // Code as suggested by ChatGPT (GPT4 turbo and GPT4o) on 2024-06-09 -├── internal/ -│ ├── auth/ -│ │ └── authenticate.go -│ ├── database/ -│ │ ├── migrations/ -│ │ │ ├── 001_create_initial_scheme.sql -│ │ │ ├── 002_create_emb_index.sql -│ │ │ ├── tern.conf // This is not distributed because it's in .gitignore -│ │ │ └── tern.conf.tpl -│ │ ├── queries/ -│ │ │ └── queries.sql -│ │ ├── database.go -│ │ ├── db.go // This is auto-generated by sqlc -│ │ ├── migrations.go -│ │ ├── models.go // This is auto-generated by sqlc -│ │ └── queries.sql.go // This is auto-generated by sqlc -│ ├── handlers/ -│ │ ├── admin.go -│ │ ├── admin_test.go -│ │ ├── api_standards.go -│ │ ├── api_standards_test.go -│ │ ├── embeddings.go -│ │ ├── embeddings_test.go -│ │ ├── handlers.go -│ │ ├── handlers_test.go -│ │ ├── llm_processes.go -│ │ ├── instances.go -│ │ ├── llm_services_test.go -│ │ ├── projects.go -│ │ ├── projects_test.go -│ │ ├── similars.go -│ │ ├── users.go -│ │ └── users_test.go -│ └── models/ -│ ├── admin.go -│ ├── api_standards.go -│ ├── embeddings.go -│ ├── llm_processes.go -│ ├── instances.go -│ ├── options.go -│ ├── projects.go -│ ├── similars.go -│ └── users.go -├── testdata/ -│ ├── postgres/ -│ │ ├── enable-vector.sql -│ │ └── users.yml -│ ├── invalid_api_standard.json -│ ├── invalid_embeddings.json -│ ├── ... -│ ├── valid_api_standard_cohere_v2.json -│ ├── valid_api_standard_ollama.json -│ ├── valid_api_standard_openai_v1.json -│ ├── valid_embeddings.json -│ ├── valid_llm_service_cohere-multilingual-3.json -│ ├── valid_llm_service_openai-large-full.json -│ ├── ... -│ └── valid_user.json -└── web/ // Web resources for the html response (in the future) -``` +## Contributing -## Roadmap - -- [ ] Revisit all **documentation** - - [ ] Add documentation for metadata filtering of similars (the GET query parameters are called `metadata_path` and `metadata_value` as in: `https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7&limit=5&metadata_path=author_id&metadata_value=A0083`) -- [ ] Network connectivity - - [ ] Implement and make consequent use of **max_idle** (5), **max_concurr** (5), **timeouts**, and **cancellations** - - [ ] **Concurrency** (leaky bucket approach) and **Rate limiting** (redis, sliding window, implement headers). See for limiting. - - [ ] Caching -- [ ] Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio -- [ ] HTML UI? -- [ ] Allow to request verbose information even in list outputs (with a verbose=yes query parameter?) -- [ ] Add possiblity to use PATCH method to change existing resources -- [ ] Proper logging with `--verbose` and `--quiet` modes -- [x] Transfer of projects from one owner to another as new operation -- [x] Make sure pagination is supported consistently -- [x] Dockerization -- [x] Prevent acceptance of requests as user "_system" -- [x] Tests - - [x] When testing, check cleanup by adding a new query/function to see if all tables are empty - - [x] Make sure input is validated consistently -- [x] Catch POST to existing resources -- [x] User authentication & restrictions on some API calls -- [x] API versioning -- [x] better **options** handling () -- [x] handle **metadata** - - [x] Validation with metadata schema -- [x] Allow to filter similar passages by metadata field (so as to exclude e.g. documents from the same author) -- [x] Use **transactions** (most importantly, when an action requires several queries, e.g. projects being added and then linked to several read-authorized users) -- [x] Always use specific error messages -- [x] Add project sharing/unsharing functions & API paths -- [x] Add definition creation/listing/deletion functions & paths -- [x] Add mechanism to allow anonymous/public reading access to embeddings (via `"*"` in `shared_with`) +Contributions are welcome! Please see our **[Contributing Guide](https://mpilhlt.github.io/dhamps-vdb/development/contributing/)** for details. ## License -[MIT License](./LICENSE) +This project is licensed under the terms specified in the [LICENSE](./LICENSE) file. -## Versions +## Support -- 2026-02-08 **v0.1.0**: Fix many things, add many things, still API v1 on the way to stable... -- 2024-12-10 **v0.0.1**: Initial public release (still work in progress) of API v1 +- 📖 [Documentation](https://mpilhlt.github.io/dhamps-vdb/) +- 🐛 [Report Issues](https://github.com/mpilhlt/dhamps-vdb/issues) +- 💬 [GitHub Discussions](https://github.com/mpilhlt/dhamps-vdb/discussions) diff --git a/docs/.hugo_build.lock b/docs/.hugo_build.lock deleted file mode 100644 index e69de29..0000000 diff --git a/docs/ChatGPT.md b/docs/ChatGPT.md deleted file mode 100644 index 4dcf142..0000000 --- a/docs/ChatGPT.md +++ /dev/null @@ -1,486 +0,0 @@ -# ChatGPT Output - -I had ChatGPT (4o) write code implementing an OpenAPI spec developed in dialogue with it. - -## OpenAPI spec - -```yaml -openapi: 3.0.0 -info: - title: Example API - version: 1.0.0 - -servers: - - url: 'https://example.com/' - -paths: - /admin/users: - put: - summary: Create or update a user - operationId: putAdminUsers - tags: - - Admin - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - username: - type: string - email: - type: string - apiKey: - type: string - responses: - '200': - description: User created or updated - content: - application/json: - schema: - type: object - properties: - id: - type: string - username: - type: string - email: - type: string - '401': - description: Unauthorized - '400': - description: Bad Request - - /admin/users/{user}: - patch: - summary: Update a specific user - operationId: patchAdminUser - tags: - - Admin - security: - - bearerAuth: [] - parameters: - - name: user - in: path - required: true - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - username: - type: string - email: - type: string - apiKey: - type: string - responses: - '200': - description: User updated - '401': - description: Unauthorized - '404': - description: User not found - - # Repeating this pattern for other methods like GET and DELETE - - /{user}/projects: - put: - summary: Create or update a project - operationId: putUserProjects - tags: - - Projects - security: - - bearerAuth: [] - # Parameters and request body definition goes here - responses: - '200': - description: Project created or updated - '401': - description: Unauthorized - - # Similar for PATCH, GET, DELETE on /{user}/projects/:project - - /{user}/{project}/embeddings: - put: - summary: Create or update embeddings for a project - operationId: putProjectEmbeddings - tags: - - Embeddings - security: - - bearerAuth: [] - # Define request and response structure - post: - summary: Create embeddings for provided text - operationId: postProjectEmbeddings - tags: - - Embeddings - security: - - bearerAuth: [] - # Define request and response structure - - # Similar for GET, DELETE on /{user}/{project}/embeddings/:id - - /{user}/{project}/similars/{id}: - get: - summary: Retrieve similar items - operationId: getProjectSimilars - tags: - - Similars - security: - - bearerAuth: [] - parameters: - - name: count - in: query - schema: - type: integer - - name: threshold - in: query - schema: - type: number - # Define response structure - - /llm-process: - post: - summary: Process text with LLM service - operationId: llmProcess - tags: - - LLM - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - serviceId: - type: string - projectId: - type: string - contextId: - type: string - textFields: - type: array - items: - type: string - responses: - '200': - description: Processed successfully - '401': - description: Unauthorized - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT -``` - -> Missing information and assumptions: -> -> - Detailed request and response schemas for each endpoint are needed. -> - Error response codes need to be defined for each operation. -> - Authentication method is assumed to be Bearer Token (JWT), which needs to be confirmed. -> - Path and query parameters need to be fully specified with types and descriptions. -> - For the llm-process endpoint, the exact nature of "multiple text fields or text-id parameters" needs clarification for accurate schema definition. -> This is a basic structure, and you will need to fill in the details based on the actual requirements and data structures of your API. - -Then, requesting PASETO tokens: - -```yaml -openapi: 3.0.0 -info: - title: Example API - version: 1.0.0 - -servers: - - url: 'https://example.com/' - -paths: - /admin/users: - put: - summary: Create or update a user - operationId: putAdminUsers - tags: - - Admin - security: - - pasetoAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - username: - type: string - email: - type: string - apiKey: - type: string - responses: - '200': - description: User created or updated - '401': - description: Unauthorized - # Define other responses as needed - - # Other endpoints definitions go here... - -components: - securitySchemes: - pasetoAuth: - type: http - scheme: bearer - bearerFormat: PASETO -``` - -> Please note that while OpenAPI doesn't natively distinguish between JWT and PASETO as they both use Bearer tokens, specifying bearerFormat helps indicate the expected token format. It's also important to document this in the API documentation so that consumers know that the API uses PASETO tokens for authentication. - -## Golang implementation - -Here is the golang implementation using the huma framework and go's own `http.ServeMux()` router: - -Project structure: - -```default -example-api/ -├── main.go -├── handlers/ -│ ├── admin.go -│ ├── projects.go -│ ├── embeddings.go -│ ├── similars.go -│ ├── llm_process.go -└── models/ - ├── user.go - ├── project.go - ├── embedding.go - ├── similar.go - ├── llm_process.go -``` - -```{code} go -:filename: main.go -:linenos: -package main - -import ( - "net/http" - - "github.com/danielgtaylor/huma/v2" - "example-api/handlers" -) - -func main() { - router := http.NewServeMux() - api := huma.NewRouter("Example API", "1.0.0") - - handlers.RegisterAdminRoutes(api) - handlers.RegisterProjectRoutes(api) - handlers.RegisterEmbeddingRoutes(api) - handlers.RegisterSimilarRoutes(api) - handlers.RegisterLLMProcessRoutes(api) - - router.Handle("/", api) - http.ListenAndServe(":8080", router) -} -``` - -```{code} go -:filename: handlers/admin.go -:linenos: -package handlers - -import ( - "github.com/danielgtaylor/huma/v2" - "example-api/models" -) - -func RegisterAdminRoutes(api *huma.Router) { - api.Resource("/admin/users"). - Put("Create or update a user", func(ctx huma.Context, input models.User) { - // Implement your logic here - }) - - api.Resource("/admin/users/{user}"). - Patch("Update a specific user", func(ctx huma.Context, input models.User) { - // Implement your logic here - }). - Get("Get a specific user", func(ctx huma.Context) { - // Implement your logic here - }). - Delete("Delete a specific user", func(ctx huma.Context) { - // Implement your logic here - }) -} -``` - -```{code} go -:filename: handlers/projects.go -:linenos: -package handlers - -import ( - "github.com/danielgtaylor/huma/v2" - "example-api/models" -) - -func RegisterProjectRoutes(api *huma.Router) { - api.Resource("/{user}/projects"). - Put("Create or update a project", func(ctx huma.Context, input models.Project) { - // Implement your logic here - }) - - api.Resource("/{user}/projects/{project}"). - Patch("Update a specific project", func(ctx huma.Context, input models.Project) { - // Implement your logic here - }). - Get("Get a specific project", func(ctx huma.Context) { - // Implement your logic here - }). - Delete("Delete a specific project", func(ctx huma.Context) { - // Implement your logic here - }) -} -``` - -```{code} go -:filename: handlers/embeddings.go -:linenos: -package handlers - -import ( - "github.com/danielgtaylor/huma/v2" - "example-api/models" -) - -func RegisterEmbeddingRoutes(api *huma.Router) { - api.Resource("/{user}/{project}/embeddings"). - Put("Create or update embeddings for a project", func(ctx huma.Context, input models.Embedding) { - // Implement your logic here - }). - Post("Create embeddings for provided text", func(ctx huma.Context, input models.Embedding) { - // Implement your logic here - }) - - api.Resource("/{user}/{project}/embeddings/{id}"). - Get("Get a specific embedding", func(ctx huma.Context) { - // Implement your logic here - }). - Delete("Delete a specific embedding", func(ctx huma.Context) { - // Implement your logic here - }) -} -``` - -```{code} go -:filename: handlers/similars.go -:linenos: -package handlers - -import ( - "github.com/danielgtaylor/huma/v2" - "example-api/models" -) - -func RegisterSimilarRoutes(api *huma.Router) { - api.Resource("/{user}/{project}/similars/{id}"). - Get("Retrieve similar items", func(ctx huma.Context) { - // Implement your logic here - }) - - api.Resource("/{user}/{project}/similars"). - Post("Retrieve similar items with query", func(ctx huma.Context, input models.SimilarQuery) { - // Implement your logic here - }) -} -``` - -```{code} go -:filename: handlers/llm_process.go -:linenos: -package handlers - -import ( - "github.com/danielgtaylor/huma/v2" - "example-api/models" -) - -func RegisterLLMProcessRoutes(api *huma.Router) { - api.Resource("/llm-process"). - Post("Process text with LLM service", func(ctx huma.Context, input models.LLMProcessRequest) { - // Implement your logic here - }) -} -``` - -```{code} go -:filename: models/user.go -:linenos: -package models - -type User struct { - Username string `json:"username"` - Email string `json:"email"` - APIKey string `json:"apiKey"` -} -``` - -```{code} go -:filename: models/project.go -:linenos: -package models - -type Project struct { - // Define project fields here -} -``` - -```{code} go -:filename: models/embedding.go -:linenos: -package models - -type Embedding struct { - // Define embedding fields here -} -``` - -```{code} go -:filename: models/similar.go -:linenos: -package models - -type SimilarQuery struct { - Count int `json:"count"` - Threshold float64 `json:"threshold"` -} -``` - -```{code} go -:filename: models/llm_process.go -:linenos: -package models - -type LLMProcessRequest struct { - ServiceID string `json:"serviceId"` - ProjectID string `json:"projectId"` - ContextID string `json:"contextId"` - TextFields []string `json:"textFields"` -} -``` - -> This code sets up the basic structure and routing for your API using the Huma v2 framework and Go's http.ServeMux. Each handler file contains the route definitions for a specific part of the API, and each model file defines the data structures used in the API. -> -> You will need to fill in the implementation details for each handler function and define the full structure of the models as required by your API. diff --git a/docs/LLM_SERVICE_REFACTORING.md b/docs/LLM_SERVICE_REFACTORING.md deleted file mode 100644 index 6febdf4..0000000 --- a/docs/LLM_SERVICE_REFACTORING.md +++ /dev/null @@ -1,751 +0,0 @@ -# LLM Service Architecture Refactoring - Complete Documentation - -## Table of Contents - -1. [Overview](#overview) -2. [Implementation Summary](#implementation-summary) -3. [Architecture](#architecture) -4. [Completed Work](#completed-work) -5. [Usage Guide](#usage-guide) -6. [Security Features](#security-features) -7. [Migration Guide](#migration-guide) -8. [Testing](#testing) -9. [Remaining Optional Work](#remaining-optional-work) - -## Overview - -This refactoring separates LLM services into two distinct concepts: - -1. **LLM Service Definitions** - Reusable templates owned by `_system` or users - - Contain configuration templates (endpoint, model, dimensions, API standard) - - Can be owned by `_system` (global templates) or individual users - - Used as templates for creating instances - -2. **LLM Service Instances** - User-specific configurations with encrypted API keys - - Contain actual service configurations and credentials - - Owned by individual users - - Can optionally reference a definition - - Support API key encryption - - Can be shared with other users - -## Implementation Summary - -### ✅ All Core Requirements Completed - -1. **Admin can manage _system definitions** - - `_system` user created in migration - - 4 default definitions seeded (openai-large, openai-small, cohere-v4, gemini-embedding-001) - - API standards (openai, cohere, gemini) created before definitions - -2. **Users can list all accessible instances** - - `GetAllAccessibleInstances` query returns owned + shared instances - - Users see all instances they own or have been granted access to - -3. **Handle-based instance references** - - Shared instances identified as `owner/handle` - - Own instances identified as `handle` - - Queries support handle-based lookups - -4. **API keys hidden from shared instances** - - API keys NEVER returned in GET/list responses (security) - - Write-only field in API - - Shared users can use instances but cannot see API keys - -5. **Multiple ways to create instances** - - From own definitions - - From _system definitions - - Standalone (all fields specified) - -6. **1:1 project-instance relationship** - - Projects must reference exactly one instance - - Enforced at database level - -### Build & Test Status - -- ✅ Code compiles successfully -- ✅ All tests passing (100% success rate) -- ✅ Migration tested and verified -- ✅ Encryption module tested - -## Architecture - -### Database Schema - -``` -definitions (templates) -├── definition_id (PK) -├── definition_handle -├── owner (FK → users, can be '_system') -├── endpoint, description, api_standard, model, dimensions -└── UNIQUE(owner, definition_handle) -└── Indexes: (owner, definition_handle), (definition_handle) - -instances (user-specific) -├── instance_id (PK) -├── instance_handle -├── owner (FK → users) -├── definition_id (FK → definitions, nullable) -├── endpoint, description, model, dimensions, api_standard -├── api_key_encrypted (BYTEA, AES-256-GCM encrypted) -└── UNIQUE(owner, instance_handle) - -instances_shared_with (n:m sharing) -├── user_handle (FK → users) -├── instance_id (FK → instances) -├── role (reader/editor/owner) -└── PRIMARY KEY(user_handle, instance_id) - -projects (1:1 with instances) -├── project_id (PK) -├── instance_id (FK → instances) -└── One project → One instance -``` - -### Key Tables Removed - -- `users_llm_services` - Redundant (ownership tracked via `instances.owner`) -- `projects_llm_services` - Replaced by 1:1 FK in projects table - -## Completed Work - -### 1. Database Migration (004) - -**File:** `internal/database/migrations/004_refactor_llm_services_architecture.sql` - -**Changes:** -- Created `definitions` table -- Renamed `instances` → `instances` -- Added `api_key_encrypted` BYTEA column -- Created `_system` user -- Dropped `users_llm_services` table (redundant) -- Modified `projects` table: removed many-to-many, added `instance_id` FK -- Created `instances_shared_with` table -- Seeded 3 API standards with documentation URLs: - - openai: https://platform.openai.com/docs/api-reference/embeddings - - cohere: https://docs.cohere.com/reference/embed - - gemini: https://ai.google.dev/gemini-api/docs/embeddings -- Seeded 4 default LLM service definitions: - - openai-large (3072 dimensions) - - openai-small (1536 dimensions) - - cohere-v4 (1536 dimensions) - - gemini-embedding-001 (3072 dimensions, default size) - -**Data Migration:** -- First linked LLM service per project → `project.instance_id` -- Rollback support included - -### 2. Encryption Module - -**File:** `internal/crypto/encryption.go` - -**Features:** -- AES-256-GCM encryption for API keys -- Uses `ENCRYPTION_KEY` environment variable (SHA256-hashed to ensure 32-byte key) -- Functions: - - `NewEncryptionKey(keyString)` - Create key from string - - `GenerateEncryptionKey()` - Generate random key - - `GetEncryptionKeyFromEnv()` - Read from environment - - `Encrypt(plaintext) → []byte` - - `Decrypt(ciphertext) → string` - - `EncryptToBase64(plaintext) → string` - - `DecryptFromBase64(base64) → string` - -**Testing:** Full test coverage in `internal/crypto/encryption_test.go` ✅ - -### 3. Database Queries (SQLC) - -**File:** `internal/database/queries/queries.sql` - -**Definitions:** -- `UpsertDefinition` - Create/update definition -- `DeleteDefinition` - Delete definition -- `RetrieveDefinition` - Get single definition -- `GetDefinitionsByUser` - List user's definitions -- `GetAllDefinitions` - List all definitions -- `GetSystemDefinitions` - List _system definitions - -**Instances:** -- `UpsertInstance` - Create/update instance (with encryption support) -- `CreateInstanceFromDefinition` - Create instance from definition template -- `DeleteInstance` - Delete instance -- `RetrieveInstance` - Get single instance -- `RetrieveInstanceByID` - Get instance by ID -- `RetrieveInstanceByOwnerHandle` - Get by owner/handle (supports both formats) -- `ShareInstance` - Share instance with another user -- `UnshareInstance` - Remove instance sharing -- `GetSharedUsersForInstance` - List users instance is shared with -- `GetInstanceByProject` - Get instance for project (1:1, renamed from plural) -- `GetInstancesByUser` - List user's owned instances -- `GetAllAccessibleInstances` - List owned + shared instances -- `GetSharedInstances` - List instances shared with user (sorted by role, owner, handle) - -**Updated Queries:** -- `UpsertProject` - Includes `instance_id` -- `UpsertEmbeddings` - Uses `instance_id` -- All embeddings queries - Updated to use instances table - -**SQLC Code Generated:** ✅ (`internal/database/models.go`, `internal/database/queries.sql.go`) - -### 4. Go Models - -**File:** `internal/models/instances.go` - -**Models:** -- `Definition` - For definitions -- `Instance` - For instances -- `LLMService` - Kept for backward API compatibility (maps to Instance) - -**Field Updates:** -- `InstanceHandle` (was `InstanceHandle`) -- `InstanceOwner` (was `LLMServiceOwner`) -- API keys marked as write-only (never returned in responses) - -### 5. Handlers - -**Updated Files:** -- `internal/handlers/instances.go` - All functions renamed with "Instance" suffix -- `internal/handlers/projects.go` - 1:1 instance relationship -- `internal/handlers/embeddings.go` - Uses instance from project -- `internal/handlers/admin.go` - Updated field names -- `internal/handlers/users.go` - Lists accessible instances -- `internal/handlers/validation.go` - Updated to InstanceHandle - -**Function Naming:** -- `putInstanceFunc` (was `putLLMFunc`) -- `getInstanceFunc` (was `getLLMFunc`) -- `deleteInstanceFunc` (was `deleteLLMFunc`) -- `getUserLLMsFunc` - Now returns all accessible instances (own + shared) - -**API Key Handling:** -- Encrypted on write if `ENCRYPTION_KEY` is set -- Never returned on read (security) -- Uses `Valid: true` consistently for nullable fields - -### 6. Environment Configuration - -**File:** `template.env` - -Added: -```bash -# Required for API key encryption (32+ characters recommended) -ENCRYPTION_KEY=your-secret-encryption-key-here-must-be-kept-secure -``` - -## Usage Guide - -### Creating an LLM Service Instance - -**Option A: Standalone (no definition)** -```bash -PUT /v1/llm-services/jdoe/my-openai -{ - "endpoint": "https://api.openai.com/v1/embeddings", - "api_standard": "openai", - "model": "text-embedding-3-large", - "dimensions": 3072, - "api_key_encypted": "sk-..." -} -``` - -**Option B: From _system definition** -```bash -# Use CreateInstanceFromDefinition query -# Handler would accept: -POST /v1/llm-services/jdoe/my-openai-instance -{ - "definition_owner": "_system", - "definition_handle": "openai-large", - "api_key_encrypted": "sk-..." -} -``` - -**Option C: From user's own definition** -```bash -# Similar to Option B, but with user as definition_owner -POST /v1/llm-services/jdoe/my-custom-instance -{ - "definition_owner": "jdoe", - "definition_handle": "my-custom-config", - "api_key_encrypted": "sk-..." -} -``` - -### Listing Accessible Instances - -```bash -GET /v1/llm-services/jdoe -# Returns all instances jdoe owns OR has been granted access to -# API keys are NOT included in response -``` - -### Creating a Project with Instance - -```bash -POST /v1/projects/jdoe/my-project -{ - "instance_id": 123, # or use handle-based reference - "description": "My project" -} -``` - -## Security Features - -### 1. API Key Encryption - -- **Algorithm:** AES-256-GCM -- **Key Source:** `ENCRYPTION_KEY` environment variable -- **Key Derivation:** SHA256 hash of environment variable -- **Storage:** `api_key_encrypted` BYTEA column - -### 2. Write-Only API Keys - -API keys are never returned in GET/list responses: -```json -GET /v1/llm-services/jdoe/my-openai -{ - "instance_id": 1, - "instance_handle": "my-openai", - "owner": "jdoe", - "endpoint": "...", - "model": "text-embedding-3-large", - "dimensions": 3072 - // Note: "api_key_encrypted" field is NOT present -} -``` - -### 3. Shared Instance Protection - -When an instance is shared: -- Shared users can USE the instance (e.g., for projects, embeddings) -- Shared users CANNOT see the API key -- Shared users CANNOT modify the instance (owner-only operation) -- Sharing is tracked in `instances_shared_with` table with role - -### 4. Admin-Only System Definitions - -- Only admin users can create/modify `_system` definitions -- Regular users can read `_system` definitions -- Regular users can create their own definitions -- No one can log in as `_system` - -## Migration Guide - -### For New Installations - -1. Run migrations: `make migrate-up` (or equivalent) -2. Set `ENCRYPTION_KEY` environment variable -3. Service is ready to use - -### For Existing Installations - -The migration (004) handles data migration automatically: - -**Automatic Changes:** -- `instances` table renamed to `instances` -- `users_llm_services` table dropped (ownership via owner column) -- `projects_llm_services` table dropped (replaced by FK) -- First linked instance per project → `project.instance_id` - -**Post-Migration Steps:** - -1. **Set Environment Variable:** - ```bash - export ENCRYPTION_KEY="your-secure-random-string-at-least-32-chars" - ``` - -### Breaking Changes - -**API Changes:** -- `GET /v1/llm-services/{user}` - No longer returns API keys -- `GET /v1/llm-services/{user}/{handle}` - No longer returns API keys -- Projects now require single instance (many-to-many removed) - -**Database:** -- `instances` → `instances` -- `users_llm_services` table removed -- `projects_llm_services` table removed - -**Backward Compatibility:** -- Existing endpoints continue to work -- Field names preserved in JSON responses (for API compatibility) -- Old plaintext API keys continue to work - -## Client Migration Guide - -This section explains what API clients need to change after the refactoring. - -### Summary of Changes for Clients - -**Good News:** Most API endpoints remain unchanged! The main changes are: -1. Projects must be created with a valid LLM service instance (1:1 relationship) -2. Embeddings JSON uses `instance_handle` instead of `llm_service_handle` - -### API Endpoints - No Changes Required - -All existing API endpoints continue to work with the same paths: - -``` -✅ PUT /v1/llm-services/{user}/{handle} # Create/update instance -✅ GET /v1/llm-services/{user} # List user's instances -✅ GET /v1/llm-services/{user}/{handle} # Get specific instance -✅ DELETE /v1/llm-services/{user}/{handle} # Delete instance - -✅ PUT /v1/projects/{user}/{project} # Create/update project -✅ GET /v1/projects/{user}/{project} # Get project -✅ DELETE /v1/projects/{user}/{project} # Delete project - -✅ POST /v1/embeddings/{user}/{project} # Upload embeddings -✅ GET /v1/embeddings/{user}/{project} # List embeddings -✅ DELETE /v1/embeddings/{user}/{project} # Delete embeddings -``` - -### Change #2: Embeddings Field Name Update - -**Before:** Used `llm_service_handle` in embeddings JSON -```json -POST /v1/embeddings/alice/my-project -{ - "text_id": "doc1", - "llm_service_handle": "my-openai", ← Old field name - "embedding": [0.1, 0.2, ...], - "metadata": {...} -} -``` - -**After:** Use `instance_handle` instead -```json -POST /v1/embeddings/alice/my-project -{ - "text_id": "doc1", - "instance_handle": "my-openai", ← New field name - "embedding": [0.1, 0.2, ...], - "metadata": {...} -} -``` - -**Action Required:** -- ⚠️ Update embedding upload code to use `instance_handle` field -- ⚠️ Update code that reads embeddings to expect `instance_handle` in responses - -### Change #3: Projects Must Have LLM Service Instance - -**Before:** Projects could be created without specifying an LLM service -```json -PUT /v1/projects/alice/my-project -{ - "description": "My project" -} -``` - -**After:** Projects require a valid `instance_id` -```json -PUT /v1/projects/alice/my-project -{ - "description": "My project", - "instance_id": 123 ← Required -} -``` - -**Action Required:** -- ⚠️ Create an LLM service instance BEFORE creating projects -- ⚠️ Include `instance_id` in project creation requests -- ℹ️ You can find the instance_id from the GET instances response - -### Complete Migration Workflow - -Here's the recommended workflow for clients: - -#### Step 1: Create LLM Service Instance (if not exists) - -```bash -# Check if instance exists -GET /v1/llm-services/alice - -# If not, create one -PUT /v1/llm-services/alice/my-openai -Content-Type: application/json - -{ - "endpoint": "https://api.openai.com/v1/embeddings", - "api_standard": "openai", - "model": "text-embedding-3-large", - "dimensions": 3072, - "api_key_encrypted": "sk-proj-your-key-here" -} - -# Response includes instance_id -{ - "instance_id": 123, - "instance_handle": "my-openai", - "owner": "alice", - "endpoint": "https://api.openai.com/v1/embeddings", - "api_standard": "openai", - "model": "text-embedding-3-large", - "dimensions": 3072 - // Note: api_key_encrypted not returned -} -``` - -#### Step 2: Create Project with Instance ID - -```bash -PUT /v1/projects/alice/my-project -Content-Type: application/json - -{ - "description": "My research project", - "instance_id": 123 // From step 1 -} -``` - -#### Step 3: Upload Embeddings - -```bash -POST /v1/embeddings/alice/my-project -Content-Type: application/json - -{ - "text_id": "doc1", - "instance_handle": "my-openai", // Use instance_handle (not llm_service_handle) - "embedding": [0.1, 0.2, 0.3, ...], - "metadata": { - "title": "Document 1", - "author": "Alice" - } -} -``` - -### Environment Setup for New Installations - -**Before:** No encryption key needed -```bash -# .env -DATABASE_URL=postgresql://... -ADMIN_KEY=your-admin-key -``` - -**After:** Add encryption key -```bash -# .env -DATABASE_URL=postgresql://... -ADMIN_KEY=your-admin-key -ENCRYPTION_KEY=your-secure-32-char-minimum-key # NEW -``` - -**Action Required:** -- ⚠️ Add `ENCRYPTION_KEY` to your environment variables -- ✅ Use a strong, random string (32+ characters recommended) -- ✅ Keep this key secure - losing it means losing access to encrypted API keys - -### Migration Checklist for Existing Clients - -Use this checklist to ensure your client is fully migrated: - -- [ ] **Stop reading API keys from GET responses** - - Update code to store API keys locally instead - -- [ ] **Update embedding field names** - - Change `llm_service_handle` → `instance_handle` in upload code - - Update parsing code to read `instance_handle` from responses - -- [ ] **Update project creation workflow** - - Create LLM service instance first - - Include `instance_id` in project creation - - Get instance_id from instance creation/list response - -- [ ] **Update environment configuration** - - Add `ENCRYPTION_KEY` to environment variables (for new installations) - - Restart services to pick up new configuration - -- [ ] **Test end-to-end workflow** - - Create instance → Create project → Upload embeddings - - Verify all steps work correctly - -### Troubleshooting - -**Problem:** "Project must have instance_id" error - -**Solution:** Create an LLM service instance first, then use its ID when creating the project. - ---- - -**Problem:** Embeddings upload fails with "unknown field llm_service_handle" - -**Solution:** Update your JSON to use `instance_handle` instead of `llm_service_handle`. - ---- - -**Problem:** Can't see API key after creating instance - -**Solution:** This is expected behavior (security improvement). Store the API key on the client side when you create the instance. - ---- - -**Problem:** Old embeddings have `llm_service_handle` in their data - -**Solution:** Existing embeddings stored before the migration will continue to have the old field name in their metadata. This is preserved for backward compatibility. When retrieving these embeddings, your client should be able to handle both `llm_service_handle` (old data) and `instance_handle` (new data). However, all NEW embeddings uploaded after migration must use `instance_handle`. - ---- - -**Problem:** Missing ENCRYPTION_KEY environment variable - -**Solution:** Add `ENCRYPTION_KEY=your-secure-key` to your environment variables. This is only required for new installations or if you want to start encrypting API keys. - -### Testing Your Migration - -Here's a test sequence to verify your client works correctly: - -```bash -# 1. Create instance -curl -X PUT "http://localhost:8000/v1/llm-services/testuser/test-instance" \ - -H "Authorization: Bearer your-api-key" \ - -H "Content-Type: application/json" \ - -d '{ - "endpoint": "https://api.openai.com/v1/embeddings", - "api_standard": "openai", - "model": "text-embedding-3-large", - "dimensions": 3072, - "api_key_encryped": "test-key" - }' - -# 2. List instances (verify api_key_encrypted is NOT returned) -curl -X GET "http://localhost:8000/v1/llm-services/testuser" \ - -H "Authorization: Bearer your-api-key" - -# 3. Create project with instance_id -curl -X PUT "http://localhost:8000/v1/projects/testuser/test-project" \ - -H "Authorization: Bearer your-api-key" \ - -H "Content-Type: application/json" \ - -d '{ - "description": "Test project", - "instance_id": 123 - }' - -# 4. Upload embeddings with instance_handle -curl -X POST "http://localhost:8000/v1/embeddings/testuser/test-project" \ - -H "Authorization: Bearer your-api-key" \ - -H "Content-Type: application/json" \ - -d '{ - "text_id": "test1", - "instance_handle": "test-instance", - "embedding": [0.1, 0.2, 0.3], - "metadata": {} - }' -``` - -### Summary of Required Client Changes - -| Area | Old Behavior | New Behavior | Action | -|------|-------------|--------------|--------| -| **API Endpoints** | Same paths | Same paths | ✅ No change | -| **API Keys in GET** | Returned in response | NOT returned | ⚠️ Stop reading, store locally | -| **Embeddings field** | `llm_service_handle` | `instance_handle` | ⚠️ Update field name | -| **Project creation** | Optional instance | Required `instance_id` | ⚠️ Create instance first | -| **Project-instance** | Many-to-many | 1:1 relationship | ⚠️ One instance per project | -| **Environment vars** | No encryption key | `ENCRYPTION_KEY` needed | ⚠️ Add to .env (new installs) | - -**Legend:** ✅ No action needed | ⚠️ Action required | ℹ️ Optional/informational - -## Testing - -### Test Status - -**✅ All Tests Passing (100% success rate):** -- TestLLMServicesFunc: 16/16 subtests -- TestEmbeddingsFunc: All subtests -- TestValidationFunc: All subtests (updated to use InstanceHandle) -- TestUserFunc: All subtests -- TestPublicAccess: Pass -- TestSimilarsFunc: Pass - -### Test Fixes Applied - -1. **Query Bug Fixed:** `GetAllAccessibleInstances` had user_handle filter in JOIN ON clause, preventing owned instances from being returned -2. **Test Expectations Updated:** Removed API key from expected responses (security) - -### Test Coverage - -**Current Coverage:** -- ✅ Basic Instance CRUD operations -- ✅ Authentication/authorization -- ✅ Invalid JSON handling -- ✅ Non-existent resource handling -- ✅ API key hiding in responses -- ✅ Field name updates (InstanceHandle, etc.) - -## Remaining Optional Work - -### Potential Enhancements (~7 hours total) - -#### 1. Split Test Files (1 hour) -- Create `definitions_test.go` for Definition tests -- Create `instances_test.go` for Instance tests -- Better organization and clarity - -#### 2. Add Definition Tests (2 hours) -- Creating definitions as _system user (admin only) -- Preventing non-admin users from creating _system definitions -- User-owned definitions -- Invalid input handling -- Deletion behavior - -#### 3. Add Instance Sharing Tests (2 hours) -- Sharing instances with other users -- Listing shared instances -- Access control verification -- API key protection for shared instances -- Revoking access - -#### 4. Add Encryption Tests (1 hour) -- API key encryption/decryption roundtrip -- Handling missing ENCRYPTION_KEY -- Key update scenarios - -#### 5. Documentation (1 hour) -- API documentation for new endpoints -- Examples of instance creation from definitions -- Security best practices - -### New Endpoints (Not Implemented) - -Consider adding these endpoints in the future: -- `GET /v1/llm-service-definitions` - List all available definitions -- `GET /v1/llm-service-definitions/_system` - List system definitions -- `POST /v1/llm-service-definitions/{user}` - Create user definition -- `POST /v1/llm-instances/{user}/from-definition/{handle}` - Create from definition -- `POST /v1/llm-instances/{user}/{instance}/share/{target}` - Share instance -- `DELETE /v1/llm-instances/{user}/{instance}/share/{target}` - Revoke sharing - -### API Key Migration Tool (Not Implemented) - -Create a CLI tool or admin endpoint to: -- List all instances with plaintext API keys -- Re-encrypt them using the current ENCRYPTION_KEY -- Verify successful encryption -- Remove plaintext keys - -## Design Decisions - -1. **Encryption:** Application-level encryption (not PostgreSQL's pgcrypto) for portability -2. **Key Storage:** Environment variable (not file-based) for security and container-friendliness -3. **Backward Compatibility:** Keep existing endpoints, map to new backend -4. **Default Instances:** Projects MUST specify an instance (no auto-creation) -5. **Sharing Model:** Read-only sharing (only owner can modify) -6. **System Definitions:** Owned by `_system` user, created in migration -7. **Ownership Tracking:** Via `owner` column (removed redundant join table) - -## References - -- Encryption implementation: `internal/crypto/encryption.go` -- Migration: `internal/database/migrations/004_refactor_llm_services_architecture.sql` -- Queries: `internal/database/queries/queries.sql` -- Performance notes: See `docs/PERFORMANCE_OPTIMIZATION.md` -- Test data: `testdata/valid_embeddings*.json` (updated to use instance_handle) - -## Support - -For questions or issues: -1. Review this documentation -2. Check the migration file for schema details -3. Review test files for usage examples -4. See PERFORMANCE_OPTIMIZATION.md for performance tuning diff --git a/docs/METADATA_SCHEMA_EXAMPLES.md b/docs/METADATA_SCHEMA_EXAMPLES.md deleted file mode 100644 index f760faa..0000000 --- a/docs/METADATA_SCHEMA_EXAMPLES.md +++ /dev/null @@ -1,230 +0,0 @@ -# Metadata Schema Validation Examples - -This document provides practical examples of using metadata schema validation in the dhamps-vdb API. - -## Example 1: Creating a Project with a Metadata Schema - -```bash -# Create a project with a metadata schema -curl -X POST http://localhost:8080/v1/projects/alice \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "project_handle": "literary-texts", - "description": "Literary texts with structured metadata", - "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\",\"enum\":[\"poetry\",\"prose\",\"drama\"]}},\"required\":[\"author\",\"year\"]}" - }' -``` - -## Example 2: Uploading Embeddings with Valid Metadata - -```bash -# Upload embeddings that conform to the schema -curl -X POST http://localhost:8080/v1/embeddings/alice/literary-texts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "embeddings": [{ - "text_id": "kant-critique-pure-reason", - "llm_service_handle": "openai-large", - "text": "Critique of Pure Reason excerpt", - "vector": [0.1, 0.2, 0.3, 0.4, 0.5], - "vector_dim": 5, - "metadata": { - "author": "Immanuel Kant", - "year": 1781, - "genre": "prose" - } - }] - }' -``` - -## Example 3: Validation Error - Missing Required Field - -```bash -# This will fail because "year" is required but missing -curl -X POST http://localhost:8080/v1/embeddings/alice/literary-texts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "embeddings": [{ - "text_id": "some-text", - "llm_service_handle": "openai-large", - "vector": [0.1, 0.2, 0.3, 0.4, 0.5], - "vector_dim": 5, - "metadata": { - "author": "John Doe" - } - }] - }' -``` - -Expected error response: -```json -{ - "$schema": "http://localhost:8080/schemas/ErrorModel.json", - "title": "Bad Request", - "status": 400, - "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n - year is required" -} -``` - -## Example 4: Validation Error - Wrong Type - -```bash -# This will fail because "year" should be an integer, not a string -curl -X POST http://localhost:8080/v1/embeddings/alice/literary-texts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "embeddings": [{ - "text_id": "some-text", - "llm_service_handle": "openai-large", - "vector": [0.1, 0.2, 0.3, 0.4, 0.5], - "vector_dim": 5, - "metadata": { - "author": "John Doe", - "year": "1781" - } - }] - }' -``` - -## Example 5: Dimension Validation Error - -```bash -# This will fail because vector has 3 elements but declares 5 dimensions -curl -X POST http://localhost:8080/v1/embeddings/alice/literary-texts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "embeddings": [{ - "text_id": "some-text", - "llm_service_handle": "openai-large", - "vector": [0.1, 0.2, 0.3], - "vector_dim": 5, - "metadata": { - "author": "John Doe", - "year": 1781 - } - }] - }' -``` - -Expected error response: -```json -{ - "$schema": "http://localhost:8080/schemas/ErrorModel.json", - "title": "Bad Request", - "status": 400, - "detail": "dimension validation failed: vector length mismatch for text_id 'some-text': actual vector has 3 elements but vector_dim declares 5" -} -``` - -## Common Metadata Schema Patterns - -### Simple Required Fields -```json -{ - "type": "object", - "properties": { - "author": {"type": "string"}, - "year": {"type": "integer"} - }, - "required": ["author"] -} -``` - -### With Enums -```json -{ - "type": "object", - "properties": { - "genre": { - "type": "string", - "enum": ["poetry", "prose", "drama", "essay"] - }, - "language": { - "type": "string", - "enum": ["en", "de", "fr", "es", "la"] - } - }, - "required": ["genre"] -} -``` - -### Nested Objects -```json -{ - "type": "object", - "properties": { - "author": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "birth_year": {"type": "integer"}, - "nationality": {"type": "string"} - }, - "required": ["name"] - } - }, - "required": ["author"] -} -``` - -### Arrays -```json -{ - "type": "object", - "properties": { - "keywords": { - "type": "array", - "items": {"type": "string"}, - "minItems": 1, - "maxItems": 10 - }, - "categories": { - "type": "array", - "items": { - "type": "string", - "enum": ["philosophy", "literature", "science", "history"] - } - } - } -} -``` - -### With Constraints -```json -{ - "type": "object", - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 200 - }, - "page_count": { - "type": "integer", - "minimum": 1 - }, - "rating": { - "type": "number", - "minimum": 0, - "maximum": 5 - } - } -} -``` - -## Tips - -1. **Escape JSON for command line**: When passing JSON schemas in curl commands, make sure to properly escape quotes or use single quotes for the outer JSON. - -2. **Use schema validators**: Before setting up your schema in the API, test it with online JSON Schema validators like [jsonschemavalidator.net](https://www.jsonschemavalidator.net/). - -3. **Start simple**: Begin with a simple schema and add more constraints as needed. You can always update the schema using a PATCH or PUT request to the project endpoint. - -4. **Optional metadata**: If you don't provide a `metadataScheme` when creating a project, metadata validation is skipped, and you can upload any JSON metadata. - -5. **Schema updates**: When you update a project's metadata schema, existing embeddings are not revalidated. The schema only applies to new or updated embeddings. diff --git a/docs/PERFORMANCE_OPTIMIZATION.md b/docs/PERFORMANCE_OPTIMIZATION.md deleted file mode 100644 index 564e1b3..0000000 --- a/docs/PERFORMANCE_OPTIMIZATION.md +++ /dev/null @@ -1,132 +0,0 @@ -# Performance Optimization Notes - -## Query Optimization Opportunities - -### GetAllAccessibleInstances Query - -**Current Implementation:** -```sql -SELECT instances.*, ... -FROM instances -LEFT JOIN instances_shared_with - ON instances."instance_id" = instances_shared_with."instance_id" -WHERE instances."owner" = $1 - OR instances_shared_with."user_handle" = $1 -ORDER BY instances."owner" ASC, instances."instance_handle" ASC -LIMIT $2 OFFSET $3; -``` - -**Issue:** -The LEFT JOIN combined with OR conditions in WHERE clause may result in inefficient query execution. The query planner might struggle to use indexes effectively. - -**Recommended Optimization:** -Use UNION ALL to separate owned instances from shared instances: - -```sql --- Get owned instances -SELECT instances.*, 'owner' as "role", true as "is_owner" -FROM instances -WHERE instances."owner" = $1 - -UNION ALL - --- Get shared instances -SELECT instances.*, - instances_shared_with."role", - false as "is_owner" -FROM instances -INNER JOIN instances_shared_with - ON instances."instance_id" = instances_shared_with."instance_id" -WHERE instances_shared_with."user_handle" = $1 - AND instances."owner" != $1 -- Avoid duplicates - -ORDER BY "owner" ASC, "instance_handle" ASC -LIMIT $2 OFFSET $3; -``` - -**Benefits:** -1. Query planner can use separate index scans for each UNION branch -2. Owned instances can use index on (owner) -3. Shared instances can use index on (user_handle) -4. Clearer query execution plan -5. Better performance with large datasets - -**Tradeoff:** -- Slightly more complex SQL -- Need to deduplicate if user somehow has instance both owned and shared (unlikely scenario) - -**Recommendation:** -- Current implementation is correct and works well for small-medium datasets -- Consider optimization if performance becomes an issue with large numbers of instances -- Profile with EXPLAIN ANALYZE before and after optimization - -## Other Optimization Opportunities - -### Index Suggestions - -Current indexes (from migration 004): -- `definitions(definition_handle)` -- `definitions(owner, definition_handle)` (composite) -- `instances(instance_handle)` -- `instances_shared_with(instance_id, user_handle)` (implicit from PK) - -**Additional indexes to consider:** -1. `instances(owner)` - for owned instance lookups -2. `instances_shared_with(user_handle)` - for shared instance lookups -3. `instances(owner, instance_handle)` - composite for unique constraint - -### Caching Opportunities - -1. **System Definitions**: Cache _system definitions since they rarely change -2. **User Instances**: Cache user's instance list with short TTL -3. **API Standards**: Cache list of API standards (nearly static) - -### Query Analysis Tools - -```bash -# Analyze query performance -EXPLAIN ANALYZE SELECT ...; - -# Check table statistics -ANALYZE instances; -ANALYZE instances_shared_with; - -# View current indexes -\di llm_service_* -``` - -## Performance Testing - -### Recommended Tests - -1. **Load Test**: 1000 users, 10 instances each -2. **Sharing Test**: 100 users sharing instances with 50 others each -3. **Query Test**: Measure GetAllAccessibleInstances with varying instance counts - -### Metrics to Track - -- Query execution time (p50, p95, p99) -- Database connection pool usage -- Index hit rates -- Cache hit rates (if implemented) - -### Performance Targets - -Based on typical usage: -- Single instance lookup: < 10ms -- List all accessible instances: < 50ms (for < 100 instances) -- Create/update instance: < 100ms (including encryption) - -## Implementation Priority - -1. **High**: Profile current performance with realistic data -2. **Medium**: Implement UNION ALL optimization if query time > 100ms -3. **Low**: Add caching layer for frequently accessed data -4. **Low**: Add indexes based on actual query patterns - -## Notes - -- Current implementation prioritizes correctness over optimization -- All tests pass with current query structure -- Performance optimization should be data-driven (measure first) -- Don't optimize prematurely - wait for actual performance issues diff --git a/docs/PUBLIC_ACCESS.md b/docs/PUBLIC_ACCESS.md deleted file mode 100644 index 56ce84a..0000000 --- a/docs/PUBLIC_ACCESS.md +++ /dev/null @@ -1,123 +0,0 @@ -# Public Access to Embeddings - -## Overview - -Projects can be configured to allow unauthenticated (public) read access to embeddings and similar documents by setting the `public_read` field to `true` when creating or updating a project. - -**Note**: The `shared_with` field is used for sharing projects with specific users. For public access, use the `public_read` boolean field. See the main [README.md](../README.md#project-sharing) for details on sharing with specific users. - -## Usage - -### Creating a Public Project - -When creating or updating a project, set `public_read` to `true`: - -```json -{ - "project_handle": "my-public-project", - "description": "A publicly accessible project", - "public_read": true -} -``` - -You can also combine public access with user-specific sharing: - -```json -{ - "project_handle": "my-project", - "description": "A public project with additional editors", - "public_read": true, - "shared_with": [ - { - "user_handle": "bob", - "role": "editor" - } - ] -} -``` - -### Endpoints with Public Access - -When a project has public read access enabled, the following endpoints can be accessed without authentication: - -- `GET /v1/projects/{user}/{project}` - Retrieve project metadata (including owner and shared_with) -- `GET /v1/embeddings/{user}/{project}` - Retrieve all embeddings for the project -- `GET /v1/embeddings/{user}/{project}/{text_id}` - Retrieve a specific embedding -- `GET /v1/similars/{user}/{project}/{text_id}` - Find similar documents - -### Endpoints Requiring Authentication - -Even for public projects, the following operations still require authentication: - -- `POST /v1/embeddings/{user}/{project}` - Create new embeddings -- `DELETE /v1/embeddings/{user}/{project}` - Delete all embeddings -- `DELETE /v1/embeddings/{user}/{project}/{text_id}` - Delete a specific embedding - -## Implementation Details - -### Database Schema - -A `public_read` boolean flag is stored in the `projects` table to indicate whether a project allows public access. - -### Authentication Flow - -1. When a request is made to a reader-protected endpoint, the middleware checks if authentication is required -2. If the project has `public_read` set to true, the request is allowed without an Authorization header -3. Unauthenticated requests are logged with the user set to "public" -4. If `public_read` is false or not set, normal authentication rules apply - -### Backwards Compatibility - -The `public_read` flag defaults to `false`, so existing projects continue to require authentication for read operations unless explicitly updated. - -### Project Metadata Display - -When a project has `public_read` enabled: -- The project is accessible without authentication for read operations -- The `public_read` flag will be set to `true` in the project metadata -- Anonymous users can view project metadata including owner and description - -## Security Considerations - -- Public access only applies to read operations (GET requests) -- Write operations (POST, PUT, DELETE) always require authentication -- Project metadata and ownership information is publicly visible for public projects -- The admin and owner authentication mechanisms are unaffected - -## Examples - -### Accessing a Public Project Without Authentication - -```bash -# Get project metadata without authentication -curl http://localhost:8080/v1/projects/alice/public-project -# Returns: {"project_handle": "public-project", "owner": "alice", "public_read": true, ...} - -# Get all embeddings without authentication -curl http://localhost:8080/v1/embeddings/alice/public-project - -# Get a specific embedding without authentication -curl http://localhost:8080/v1/embeddings/alice/public-project/text123 - -# Find similar documents without authentication -curl http://localhost:8080/v1/similars/alice/public-project/text123 -``` - -### Creating Embeddings Still Requires Authentication - -```bash -# This will fail with 401 Unauthorized -curl -X POST http://localhost:8080/v1/embeddings/alice/public-project \ - -H "Content-Type: application/json" \ - -d '{"embeddings": [...]}' - -# This will succeed with a valid API key -curl -X POST http://localhost:8080/v1/embeddings/alice/public-project \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"embeddings": [...]}' -``` - -## Migration - -Existing projects are not affected. The `public_read` flag defaults to `false`, so all existing projects continue to require authentication for read operations unless explicitly updated to set `public_read: true`. diff --git a/docs/public/404.html b/docs/public/404.html deleted file mode 100644 index 077f282..0000000 --- a/docs/public/404.html +++ /dev/null @@ -1,4 +0,0 @@ -404 Page not found | dhamps-vdb Documentation -

    Page -Not -Found

    dhamps-vdb Documentation

    \ No newline at end of file diff --git a/docs/public/api/authentication/index.html b/docs/public/api/authentication/index.html deleted file mode 100644 index 0608475..0000000 --- a/docs/public/api/authentication/index.html +++ /dev/null @@ -1,45 +0,0 @@ -Authentication | dhamps-vdb Documentation - -

    API Authentication#

    All API requests (except public project read operations) require authentication using API keys passed in the Authorization header with a Bearer prefix.

    Authentication Method#

    Include your API key in the Authorization header of every request:

    Authorization: Bearer your_api_key_here

    API Key Types#

    Admin API Key#

    • Full access to all API endpoints and resources
    • Can create and manage users
    • Can access all projects and resources across all users
    • Required for administrative operations
    • Set via ADMIN_KEY environment variable

    Admin-only operations:

    • POST /v1/users - Create new users
    • GET /v1/users - List all users
    • GET /v1/admin/* - Admin endpoints
    • Create/modify _system LLM service definitions
    • Access any user’s resources

    User API Key#

    • Access limited to user’s own resources and shared projects
    • Cannot create other users
    • Cannot access admin endpoints
    • Returned when creating a new user (store securely)

    User capabilities:

    • Manage own projects and LLM services
    • Upload and query embeddings in owned projects
    • Access projects shared with them (read or edit access)
    • Delete own account

    Getting an API Key#

    Admin Key#

    Set the admin key via environment variable when launching the service:

    export ADMIN_KEY="your-secure-admin-key-here"
    -./dhamps-vdb

    User Key#

    Create a new user using the admin API key:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "alice",
    -    "name": "Alice Doe",
    -    "email": "alice@example.com"
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice@example.com",
    -  "api_key": "024v2013621509245f2e24"
    -}

    ⚠️ Important: The API key is only returned once during user creation. Store it securely - it cannot be recovered.

    Authorization Header Format#

    Correct Format#

    curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer 024v2013621509245f2e24"

    Common Mistakes#

    ❌ Missing “Bearer” prefix:

    Authorization: 024v2013621509245f2e24

    ❌ Wrong prefix:

    Authorization: Token 024v2013621509245f2e24

    ❌ Extra quotes:

    Authorization: Bearer "024v2013621509245f2e24"

    Authentication Errors#

    401 Unauthorized#

    Returned when authentication credentials are missing or invalid.

    Causes:

    • Missing Authorization header
    • Invalid API key
    • Malformed header format

    Example response:

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    403 Forbidden#

    Returned when authentication succeeds but authorization fails.

    Causes:

    • Attempting to access another user’s resources
    • User lacking required permissions
    • Non-admin accessing admin endpoints

    Example response:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to access this resource"
    -}

    Public Access#

    Projects can be made publicly accessible by setting public_read: true when creating or updating the project. Public projects allow unauthenticated read access to:

    • Project metadata
    • Embeddings
    • Similarity search

    See Public Access Documentation for details.

    Security Best Practices#

    1. Never commit API keys to version control
    2. Use environment variables to store API keys in your applications
    3. Rotate keys regularly by creating new users and deleting old ones
    4. Use HTTPS in production to prevent key interception
    5. Store admin keys securely using secrets management systems
    6. Limit admin key distribution to essential personnel only

    Example Authenticated Request#

    # List user's projects
    -curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer 024v2013621509245f2e24"
    -
    -# Create a new project
    -curl -X POST "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer 024v2013621509245f2e24" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "my-project",
    -    "description": "My research project",
    -    "instance_owner": "alice",
    -    "instance_handle": "my-openai"
    -  }'
    \ No newline at end of file diff --git a/docs/public/api/endpoints/api-standards/index.html b/docs/public/api/endpoints/api-standards/index.html deleted file mode 100644 index 9927c9d..0000000 --- a/docs/public/api/endpoints/api-standards/index.html +++ /dev/null @@ -1,135 +0,0 @@ -API Standards | dhamps-vdb Documentation - -

    API Standards Endpoint#

    Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.

    Overview#

    API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:

    • OpenAI: Bearer token in Authorization header
    • Cohere: API key in Authorization header with Bearer prefix
    • Google Gemini: API key as query parameter
    • Ollama: No authentication required

    Pre-seeded standards are available for common providers. See testdata/valid_api_standard_*.json for examples.


    Endpoints#

    List All API Standards#

    Get all defined API standards. This endpoint is publicly accessible (no authentication required).

    Endpoint: GET /v1/api-standards

    Authentication: Public (no authentication required)

    Example:

    curl -X GET "https://api.example.com/v1/api-standards"

    Response:

    {
    -  "standards": [
    -    {
    -      "api_standard_handle": "openai",
    -      "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    -      "key_method": "auth_bearer",
    -      "key_field": "Authorization"
    -    },
    -    {
    -      "api_standard_handle": "cohere",
    -      "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed",
    -      "key_method": "auth_bearer",
    -      "key_field": "Authorization"
    -    },
    -    {
    -      "api_standard_handle": "gemini",
    -      "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings",
    -      "key_method": "query_param",
    -      "key_field": "key"
    -    }
    -  ]
    -}

    Get API Standard#

    Retrieve information about a specific API standard. This endpoint is publicly accessible.

    Endpoint: GET /v1/api-standards/{standardname}

    Authentication: Public (no authentication required)

    Example:

    curl -X GET "https://api.example.com/v1/api-standards/openai"

    Response:

    {
    -  "api_standard_handle": "openai",
    -  "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    -  "key_method": "auth_bearer",
    -  "key_field": "Authorization"
    -}

    Create API Standard#

    Register a new API standard definition. Admin-only operation.

    Endpoint: POST /v1/api-standards

    Authentication: Admin only

    Request Body:

    {
    -  "api_standard_handle": "custom-provider",
    -  "description": "Custom provider embedding API",
    -  "key_method": "auth_bearer",
    -  "key_field": "Authorization"
    -}

    Parameters:

    • api_standard_handle (string, required): Unique identifier for the standard
    • description (string, required): Description including API documentation URL
    • key_method (string, required): Authentication method
      • auth_bearer: Bearer token in header
      • auth_apikey: API key in header
      • query_param: API key as query parameter
      • none: No authentication
    • key_field (string, required): Field name for the API key
      • For headers: typically "Authorization" or "X-API-Key"
      • For query params: parameter name like "key" or "api_key"

    Example:

    curl -X POST "https://api.example.com/v1/api-standards" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "api_standard_handle": "ollama",
    -    "description": "Ollama local embedding API, no authentication required",
    -    "key_method": "none",
    -    "key_field": ""
    -  }'

    Response:

    {
    -  "api_standard_handle": "ollama",
    -  "description": "Ollama local embedding API, no authentication required",
    -  "key_method": "none",
    -  "key_field": ""
    -}

    Update API Standard (PUT)#

    Create or update an API standard with a specific handle. Admin-only operation.

    Endpoint: PUT /v1/api-standards/{standardname}

    Authentication: Admin only

    Request Body: Same as POST endpoint

    Example:

    curl -X PUT "https://api.example.com/v1/api-standards/custom-provider" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "api_standard_handle": "custom-provider",
    -    "description": "Updated description for custom provider",
    -    "key_method": "auth_bearer",
    -    "key_field": "Authorization"
    -  }'

    Delete API Standard#

    Delete an API standard definition. Admin-only operation.

    Endpoint: DELETE /v1/api-standards/{standardname}

    Authentication: Admin only

    Example:

    curl -X DELETE "https://api.example.com/v1/api-standards/custom-provider" \
    -  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    -  "message": "API standard 'custom-provider' deleted successfully"
    -}

    ⚠️ Warning: Cannot delete API standards that are referenced by LLM service instances.


    Partial Update (PATCH)#

    Update specific API standard fields without providing all data. Admin-only operation.

    Endpoint: PATCH /v1/api-standards/{standardname}

    Authentication: Admin only

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/api-standards/openai" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "OpenAI Embeddings API v1 - Updated documentation link"
    -  }'

    See PATCH Updates for more details.


    API Standard Properties#

    FieldTypeRequiredDescription
    api_standard_handlestringYesUnique identifier (e.g., “openai”, “cohere”)
    descriptionstringYesDescription with API documentation URL
    key_methodstringYesAuthentication method
    key_fieldstringYesField name for API key/token

    Authentication Methods#

    auth_bearer#

    Bearer token authentication in the Authorization header.

    Example:

    {
    -  "key_method": "auth_bearer",
    -  "key_field": "Authorization"
    -}

    HTTP Request:

    Authorization: Bearer sk-proj-abc123...

    Used by: OpenAI, Cohere, Anthropic


    auth_apikey#

    API key in a custom header field.

    Example:

    {
    -  "key_method": "auth_apikey",
    -  "key_field": "X-API-Key"
    -}

    HTTP Request:

    X-API-Key: abc123...

    Used by: Some custom API providers


    query_param#

    API key passed as a URL query parameter.

    Example:

    {
    -  "key_method": "query_param",
    -  "key_field": "key"
    -}

    HTTP Request:

    GET https://api.example.com/embed?key=abc123...

    Used by: Google Gemini, some older APIs


    none#

    No authentication required.

    Example:

    {
    -  "key_method": "none",
    -  "key_field": ""
    -}

    Used by: Ollama (local), self-hosted models without auth


    Pre-seeded API Standards#

    The following API standards are created during database migration:

    openai#

    {
    -  "api_standard_handle": "openai",
    -  "description": "OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings",
    -  "key_method": "auth_bearer",
    -  "key_field": "Authorization"
    -}

    cohere#

    {
    -  "api_standard_handle": "cohere",
    -  "description": "Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed",
    -  "key_method": "auth_bearer",
    -  "key_field": "Authorization"
    -}

    gemini#

    {
    -  "api_standard_handle": "gemini",
    -  "description": "Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings",
    -  "key_method": "query_param",
    -  "key_field": "key"
    -}

    Use Cases#

    Creating a Custom API Standard#

    For self-hosted or custom LLM services:

    curl -X POST "https://api.example.com/v1/api-standards" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "api_standard_handle": "vllm-local",
    -    "description": "vLLM local deployment with custom auth",
    -    "key_method": "auth_apikey",
    -    "key_field": "X-API-Key"
    -  }'

    Referencing in LLM Service Instance#

    Once created, reference the API standard in your LLM service instance:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-vllm" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "my-vllm",
    -    "endpoint": "https://vllm.local/v1/embeddings",
    -    "api_standard": "vllm-local",
    -    "model": "custom-embed",
    -    "dimensions": 768,
    -    "api_key_encrypted": "my-secret-key"
    -  }'

    Common Errors#

    400 Bad Request#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Invalid key_method: must be one of auth_bearer, auth_apikey, query_param, none"
    -}

    401 Unauthorized (Admin Operations)#

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    403 Forbidden (Admin Operations)#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only admin users can create/modify/delete API standards"
    -}

    404 Not Found#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "API standard 'custom-provider' not found"
    -}

    409 Conflict#

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Cannot delete API standard: referenced by 5 LLM service instances"
    -}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/embeddings/index.html b/docs/public/api/endpoints/embeddings/index.html deleted file mode 100644 index 9deb413..0000000 --- a/docs/public/api/endpoints/embeddings/index.html +++ /dev/null @@ -1,207 +0,0 @@ -Embeddings | dhamps-vdb Documentation - -

    Embeddings Endpoint#

    Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project’s LLM service instance dimensions.

    Endpoints#

    List Embeddings#

    Get all embeddings for a project with pagination support.

    Endpoint: GET /v1/embeddings/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters:

    • limit (integer, default: 10, max: 200): Maximum number of results to return
    • offset (integer, default: 0): Pagination offset

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=0" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "doc123",
    -      "user_handle": "alice",
    -      "project_handle": "research-docs",
    -      "instance_handle": "openai-large",
    -      "text": "This is a research document about machine learning.",
    -      "vector": [-0.020850, 0.018522, 0.053270, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "Alice Doe",
    -        "year": 2024
    -      }
    -    }
    -  ],
    -  "total_count": 150,
    -  "limit": 20,
    -  "offset": 0
    -}

    Upload Embeddings (Batch)#

    Upload one or more embeddings to a project. Supports batch upload for efficiency.

    Endpoint: POST /v1/embeddings/{username}/{projectname}

    Authentication: Admin, owner, or authorized editors

    Request Body:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "doc123",
    -      "instance_handle": "openai-large",
    -      "text": "This is a research document.",
    -      "vector": [-0.020850, 0.018522, 0.053270, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "Alice Doe",
    -        "year": 2024
    -      }
    -    },
    -    {
    -      "text_id": "doc124",
    -      "instance_handle": "openai-large",
    -      "text": "Another research document.",
    -      "vector": [0.012345, -0.054321, 0.098765, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "Bob Smith",
    -        "year": 2024
    -      }
    -    }
    -  ]
    -}

    Parameters:

    • embeddings (array, required): Array of embedding objects
      • text_id (string, required): Unique identifier for the text (URL-encoded recommended)
      • instance_handle (string, required): Handle of the LLM service instance used
      • vector (array of floats, required): Embedding vector
      • vector_dim (integer, required): Number of dimensions in the vector
      • text (string, optional): The original text
      • metadata (object, optional): Additional metadata (validated against project schema if defined)

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {
    -        "text_id": "doc123",
    -        "instance_handle": "openai-large",
    -        "text": "Machine learning research document.",
    -        "vector": [-0.020850, 0.018522, 0.053270],
    -        "vector_dim": 3,
    -        "metadata": {
    -          "author": "Alice Doe",
    -          "year": 2024
    -        }
    -      }
    -    ]
    -  }'

    Response:

    {
    -  "message": "1 embedding(s) uploaded successfully",
    -  "uploaded": ["doc123"]
    -}

    Get Single Embedding#

    Retrieve information about a specific embedding by its text identifier.

    Endpoint: GET /v1/embeddings/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "text_id": "doc123",
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "project_id": 1,
    -  "instance_handle": "openai-large",
    -  "text": "Machine learning research document.",
    -  "vector": [-0.020850, 0.018522, 0.053270, ...],
    -  "vector_dim": 3072,
    -  "metadata": {
    -    "author": "Alice Doe",
    -    "year": 2024
    -  }
    -}

    Note: URL-encode the identifier if it contains special characters (e.g., URLs).

    Example with URL identifier:

    # URL-encoded identifier
    -curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs/https%3A%2F%2Fexample.com%2Fdoc123" \
    -  -H "Authorization: Bearer alice_api_key"

    Delete Single Embedding#

    Delete a specific embedding by its text identifier.

    Endpoint: DELETE /v1/embeddings/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, or authorized editors

    Example:

    curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs/doc123" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "Embedding 'doc123' deleted successfully"
    -}

    Delete All Embeddings#

    Delete all embeddings in a project.

    Endpoint: DELETE /v1/embeddings/{username}/{projectname}

    Authentication: Admin or owner

    Example:

    curl -X DELETE "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "All embeddings deleted from project alice/research-docs",
    -  "deleted_count": 150
    -}

    ⚠️ Warning: This operation is irreversible.


    Request Format Details#

    Text Identifiers#

    Text identifiers (text_id) should be:

    • Unique within a project
    • URL-encoded if they contain special characters
    • Descriptive for easier retrieval

    Examples:

    • Simple: "doc123", "article-456"
    • URL-based: "https://example.com/docs/123" (URL-encode in requests)
    • Path-based: "books/chapter1/section2"

    Vector Format#

    Vectors must be:

    • Arrays of floats (float32 or float64)
    • Matching dimensions specified in vector_dim
    • Consistent dimensions with the project’s LLM service instance

    Example:

    {
    -  "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003],
    -  "vector_dim": 5
    -}

    Metadata Format#

    Metadata is a flexible JSON object that can contain any valid JSON data:

    Simple metadata:

    {
    -  "metadata": {
    -    "author": "Alice Doe",
    -    "year": 2024,
    -    "category": "research"
    -  }
    -}

    Nested metadata:

    {
    -  "metadata": {
    -    "author": {
    -      "name": "Alice Doe",
    -      "id": "author-123"
    -    },
    -    "publication": {
    -      "year": 2024,
    -      "title": "Machine Learning Research"
    -    },
    -    "tags": ["AI", "ML", "embeddings"]
    -  }
    -}

    Validation#

    Dimension Validation#

    The API automatically validates that:

    1. Vector dimension consistency: The vector_dim field must match the dimensions configured in the LLM service instance
    2. Vector length verification: The actual number of elements in the vector array must match the declared vector_dim

    Error example:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    -}

    Metadata Schema Validation#

    If the project has a metadataScheme defined, all uploaded embeddings’ metadata will be validated against it.

    Example project schema:

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {"type": "string"},
    -    "year": {"type": "integer"}
    -  },
    -  "required": ["author"]
    -}

    Valid metadata:

    {
    -  "author": "Alice Doe",
    -  "year": 2024
    -}

    Invalid metadata (missing required field):

    {
    -  "year": 2024
    -}

    Error response:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    -}

    Response Format#

    List Response#

    {
    -  "embeddings": [...],
    -  "total_count": 150,
    -  "limit": 20,
    -  "offset": 0
    -}

    Single Embedding Response#

    {
    -  "text_id": "doc123",
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "project_id": 1,
    -  "instance_handle": "openai-large",
    -  "text": "...",
    -  "vector": [...],
    -  "vector_dim": 3072,
    -  "metadata": {...}
    -}

    Upload Response#

    {
    -  "message": "3 embedding(s) uploaded successfully",
    -  "uploaded": ["doc123", "doc124", "doc125"]
    -}

    Common Errors#

    400 Bad Request - Dimension Mismatch#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    -}

    400 Bad Request - Invalid Vector#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "vector length (1536) does not match declared vector_dim (3072)"
    -}

    400 Bad Request - Metadata Schema Violation#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    -}

    403 Forbidden#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to upload embeddings to this project"
    -}

    404 Not Found - Project#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Project 'alice/research-docs' not found"
    -}

    404 Not Found - Embedding#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    -}

    409 Conflict#

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Embedding 'doc123' already exists in project 'alice/research-docs'"
    -}

    Best Practices#

    Batch Uploads#

    Upload multiple embeddings in a single request for better performance:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {...},
    -      {...},
    -      {...}
    -    ]
    -  }'

    URL-Encoded Identifiers#

    Use URL encoding for identifiers with special characters:

    import urllib.parse
    -
    -text_id = "https://example.com/docs/123"
    -encoded_id = urllib.parse.quote(text_id, safe='')
    -# Result: "https%3A%2F%2Fexample.com%2Fdocs%2F123"

    Metadata Design#

    Design metadata schemas that:

    • Include commonly queried fields
    • Use consistent data types
    • Validate required fields
    • Support your similarity search filtering needs

    \ No newline at end of file diff --git a/docs/public/api/endpoints/index.html b/docs/public/api/endpoints/index.html deleted file mode 100644 index bbe8993..0000000 --- a/docs/public/api/endpoints/index.html +++ /dev/null @@ -1,13 +0,0 @@ -Endpoints | dhamps-vdb Documentation - -

    API Endpoints#

    Complete reference for all dhamps-vdb API endpoints.

    Endpoint Categories#

    Endpoint Format#

    All endpoints follow the pattern:

    {METHOD} /v1/{resource}/{user}/{identifier}

    Where:

    • METHOD: HTTP method (GET, POST, PUT, DELETE, PATCH)
    • resource: Resource type (users, projects, embeddings, etc.)
    • user: User handle (owner of the resource)
    • identifier: Specific resource identifier

    Authentication#

    Most endpoints require authentication via the Authorization header:

    Authorization: Bearer your_api_key_here

    Public projects allow unauthenticated access to read operations.

    \ No newline at end of file diff --git a/docs/public/api/endpoints/index.xml b/docs/public/api/endpoints/index.xml deleted file mode 100644 index 1f54c8b..0000000 --- a/docs/public/api/endpoints/index.xml +++ /dev/null @@ -1,103 +0,0 @@ -Endpoints on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/Recent content in Endpoints on dhamps-vdb DocumentationHugoen-usUsershttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/<h1 id="users-endpoint">Users Endpoint<a class="anchor" href="#users-endpoint">#</a></h1> -<p>Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-all-users">List All Users<a class="anchor" href="#list-all-users">#</a></h3> -<p>Get a list of all registered user handles.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/users</code></p> -<p><strong>Authentication:</strong> Admin only</p> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/users&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer admin_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;users&#34;</span>: [<span style="color:#e6db74">&#34;alice&#34;</span>, <span style="color:#e6db74">&#34;bob&#34;</span>, <span style="color:#e6db74">&#34;charlie&#34;</span>] -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> -<h3 id="create-user">Create User<a class="anchor" href="#create-user">#</a></h3> -<p>Register a new user and generate their API key.</p> -<p><strong>Endpoint:</strong> <code>POST /v1/users</code></p> -<p><strong>Authentication:</strong> Admin only</p> -<p><strong>Request Body:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Doe&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Parameters:</strong></p>Projectshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/<h1 id="projects-endpoint">Projects Endpoint<a class="anchor" href="#projects-endpoint">#</a></h1> -<p>Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-users-projects">List User&rsquo;s Projects<a class="anchor" href="#list-users-projects">#</a></h3> -<p>Get all projects owned by a user.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/projects/{username}</code></p> -<p><strong>Authentication:</strong> Admin, the user themselves, or users with shared access</p> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/projects/alice&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;projects&#34;</span>: [ -</span></span><span style="display:flex;"><span> { -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_id&#34;</span>: <span style="color:#ae81ff">1</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_handle&#34;</span>: <span style="color:#e6db74">&#34;research-docs&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Research document embeddings&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_id&#34;</span>: <span style="color:#ae81ff">5</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;openai-large&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;public_read&#34;</span>: <span style="color:#66d9ef">false</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> -</span></span><span style="display:flex;"><span> } -</span></span><span style="display:flex;"><span> ] -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> -<h3 id="create-project">Create Project<a class="anchor" href="#create-project">#</a></h3> -<p>Register a new project for a user.</p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/<h1 id="llm-services-endpoint">LLM Services Endpoint<a class="anchor" href="#llm-services-endpoint">#</a></h1> -<p>Manage LLM service instances and definitions. The system supports two types of LLM service resources:</p> -<ol> -<li><strong>Definitions</strong>: Reusable templates owned by <code>_system</code> or individual users</li> -<li><strong>Instances</strong>: User-specific configurations with API keys that reference definitions or stand alone</li> -</ol> -<h2 id="architecture-overview">Architecture Overview<a class="anchor" href="#architecture-overview">#</a></h2> -<pre tabindex="0"><code>definitions (templates) - └── owned by _system or users - └── contain: endpoint, model, dimensions, api_standard - └── no API keys - -instances (user-specific) - └── owned by individual users - └── reference a definition (optional) - └── contain encrypted API keys - └── can be shared with other users</code></pre><p>For complete details, see <a href="https://mpilhlt.github.io/dhamps-vdb/docs/LLM_SERVICE_REFACTORING.md">LLM Service Refactoring Documentation</a>.</p>API Standardshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/<h1 id="api-standards-endpoint">API Standards Endpoint<a class="anchor" href="#api-standards-endpoint">#</a></h1> -<p>Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:</p> -<ul> -<li><strong>OpenAI</strong>: Bearer token in <code>Authorization</code> header</li> -<li><strong>Cohere</strong>: API key in <code>Authorization</code> header with <code>Bearer</code> prefix</li> -<li><strong>Google Gemini</strong>: API key as query parameter</li> -<li><strong>Ollama</strong>: No authentication required</li> -</ul> -<p>Pre-seeded standards are available for common providers. See <a href="https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata">testdata/valid_api_standard_*.json</a> for examples.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/<h1 id="embeddings-endpoint">Embeddings Endpoint<a class="anchor" href="#embeddings-endpoint">#</a></h1> -<p>Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project&rsquo;s LLM service instance dimensions.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-embeddings">List Embeddings<a class="anchor" href="#list-embeddings">#</a></h3> -<p>Get all embeddings for a project with pagination support.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/embeddings/{username}/{projectname}</code></p> -<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> -<p><strong>Query Parameters:</strong></p> -<ul> -<li><code>limit</code> (integer, default: 10, max: 200): Maximum number of results to return</li> -<li><code>offset</code> (integer, default: 0): Pagination offset</li> -</ul> -<p><strong>Example:</strong></p>Similarshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/<h1 id="similarity-search-endpoints">Similarity Search Endpoints<a class="anchor" href="#similarity-search-endpoints">#</a></h1> -<p>Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="get-similar-documents-from-stored-embeddings">GET Similar Documents (from stored embeddings)<a class="anchor" href="#get-similar-documents-from-stored-embeddings">#</a></h3> -<p>Find documents similar to an already-stored document by its text identifier.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/similars/{username}/{projectname}/{identifier}</code></p> -<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> -<p><strong>Query Parameters:</strong></p> -<ul> -<li><code>count</code> (integer, optional, default: 10, max: 200): Number of similar documents to return</li> -<li><code>threshold</code> (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold</li> -<li><code>limit</code> (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for <code>count</code>)</li> -<li><code>offset</code> (integer, optional, default: 0): Pagination offset</li> -<li><code>metadata_path</code> (string, optional): Metadata field path for filtering (must be used with <code>metadata_value</code>)</li> -<li><code>metadata_value</code> (string, optional): Metadata value to exclude from results (must be used with <code>metadata_path</code>)</li> -</ul> -<p><strong>Example - Basic search:</strong></p> \ No newline at end of file diff --git a/docs/public/api/endpoints/llm-services/index.html b/docs/public/api/endpoints/llm-services/index.html deleted file mode 100644 index aaa192b..0000000 --- a/docs/public/api/endpoints/llm-services/index.html +++ /dev/null @@ -1,164 +0,0 @@ -LLM Services | dhamps-vdb Documentation - -

    LLM Services Endpoint#

    Manage LLM service instances and definitions. The system supports two types of LLM service resources:

    1. Definitions: Reusable templates owned by _system or individual users
    2. Instances: User-specific configurations with API keys that reference definitions or stand alone

    Architecture Overview#

    definitions (templates)
    -  └── owned by _system or users
    -  └── contain: endpoint, model, dimensions, api_standard
    -  └── no API keys
    -
    -instances (user-specific)
    -  └── owned by individual users
    -  └── reference a definition (optional)
    -  └── contain encrypted API keys
    -  └── can be shared with other users

    For complete details, see LLM Service Refactoring Documentation.


    Instance Endpoints#

    List User’s Instances#

    Get all LLM service instances owned by or shared with a user.

    Endpoint: GET /v1/llm-services/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "instances": [
    -    {
    -      "instance_id": 1,
    -      "instance_handle": "openai-large",
    -      "owner": "alice",
    -      "endpoint": "https://api.openai.com/v1/embeddings",
    -      "description": "OpenAI large embeddings",
    -      "api_standard": "openai",
    -      "model": "text-embedding-3-large",
    -      "dimensions": 3072,
    -      "definition_id": 1
    -    },
    -    {
    -      "instance_id": 2,
    -      "instance_handle": "custom-model",
    -      "owner": "alice",
    -      "endpoint": "https://custom.api.example.com/embed",
    -      "api_standard": "openai",
    -      "model": "custom-embed-v1",
    -      "dimensions": 1536
    -    }
    -  ]
    -}

    Note: API keys are never returned in GET responses for security.


    Create or Update Instance (PUT)#

    Create a new LLM service instance or update an existing one.

    Endpoint: PUT /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the user themselves

    Request Body (Standalone Instance):

    {
    -  "instance_handle": "openai-large",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "description": "OpenAI large embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072,
    -  "api_key_encrypted": "sk-proj-..."
    -}

    Request Body (From Definition):

    {
    -  "instance_handle": "my-openai",
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-large",
    -  "api_key_encrypted": "sk-proj-..."
    -}

    Parameters:

    • instance_handle (string, required): Unique identifier within user’s namespace
    • endpoint (string, required for standalone): API endpoint URL
    • description (string, optional): Instance description
    • api_standard (string, required for standalone): Reference to API standard (e.g., “openai”, “cohere”)
    • model (string, required for standalone): Model name
    • dimensions (integer, required for standalone): Vector dimensions
    • api_key_encrypted (string, optional): API key (encrypted if ENCRYPTION_KEY is set)
    • definition_owner (string, optional): Owner of the definition template
    • definition_handle (string, optional): Handle of the definition template

    Example - Standalone:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "openai-large",
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "api_key_encrypted": "sk-proj-..."
    -  }'

    Example - From _system Definition:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "my-openai",
    -    "definition_owner": "_system",
    -    "definition_handle": "openai-large",
    -    "api_key_encrypted": "sk-proj-..."
    -  }'

    Response:

    {
    -  "instance_id": 1,
    -  "instance_handle": "openai-large",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072
    -}

    Security Note: API keys are encrypted using AES-256-GCM if the ENCRYPTION_KEY environment variable is set. Keys are never returned in responses.


    Get Instance Information#

    Retrieve information about a specific LLM service instance.

    Endpoint: GET /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin, owner, or users with shared access

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "instance_id": 1,
    -  "instance_handle": "openai-large",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "description": "OpenAI large embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072,
    -  "definition_id": 1
    -}

    Delete Instance#

    Delete an LLM service instance.

    Endpoint: DELETE /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the owner

    Example:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "LLM service instance alice/openai-large deleted successfully"
    -}

    ⚠️ Warning: Cannot delete instances that are in use by projects.


    Partial Update (PATCH)#

    Update specific instance fields without providing all data.

    Endpoint: PATCH /v1/llm-services/{username}/{instance_handle}

    Authentication: Admin or the owner

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated description"
    -  }'

    See PATCH Updates for more details.


    Instance Sharing#

    Share Instance#

    Share an LLM service instance with another user.

    Endpoint: POST /v1/llm-services/{owner}/{instance}/share

    Authentication: Admin or the instance owner

    Request Body:

    {
    -  "share_with_handle": "bob",
    -  "role": "reader"
    -}

    Roles:

    • reader: Can use the instance but cannot see API keys
    • editor: Can use the instance (owner can still modify)
    • owner: Full control (cannot be granted via sharing)

    Example:

    curl -X POST "https://api.example.com/v1/llm-services/alice/openai-large/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "bob",
    -    "role": "reader"
    -  }'

    Important: Shared users can USE the instance but cannot see the API key.


    Unshare Instance#

    Remove a user’s access to a shared instance.

    Endpoint: DELETE /v1/llm-services/{owner}/{instance}/share/{user_handle}

    Authentication: Admin or the instance owner

    Example:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large/share/bob" \
    -  -H "Authorization: Bearer alice_api_key"

    List Shared Users#

    Get a list of users the instance is shared with.

    Endpoint: GET /v1/llm-services/{owner}/{instance}/shared-with

    Authentication: Admin or the instance owner

    Example:

    curl -X GET "https://api.example.com/v1/llm-services/alice/openai-large/shared-with" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "instance": "alice/openai-large",
    -  "shared_with": [
    -    {
    -      "user_handle": "bob",
    -      "role": "reader"
    -    }
    -  ]
    -}

    Definition Endpoints#

    List System Definitions#

    Get all LLM service definitions owned by _system.

    Endpoint: GET /v1/llm-service-definitions/_system

    Authentication: Any authenticated user

    Example:

    curl -X GET "https://api.example.com/v1/llm-service-definitions/_system" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "definitions": [
    -    {
    -      "definition_id": 1,
    -      "definition_handle": "openai-large",
    -      "owner": "_system",
    -      "endpoint": "https://api.openai.com/v1/embeddings",
    -      "description": "OpenAI text-embedding-3-large",
    -      "api_standard": "openai",
    -      "model": "text-embedding-3-large",
    -      "dimensions": 3072
    -    },
    -    {
    -      "definition_id": 2,
    -      "definition_handle": "openai-small",
    -      "owner": "_system",
    -      "endpoint": "https://api.openai.com/v1/embeddings",
    -      "description": "OpenAI text-embedding-3-small",
    -      "api_standard": "openai",
    -      "model": "text-embedding-3-small",
    -      "dimensions": 1536
    -    }
    -  ]
    -}

    Pre-seeded System Definitions:

    • openai-large: OpenAI text-embedding-3-large (3072 dimensions)
    • openai-small: OpenAI text-embedding-3-small (1536 dimensions)
    • cohere-v4: Cohere embed-english-v4.0 (1536 dimensions)
    • gemini-embedding-001: Google Gemini embedding-001 (768 dimensions)

    Create User Definition#

    Create a reusable LLM service definition template.

    Endpoint: POST /v1/llm-service-definitions/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    -  "definition_handle": "custom-model",
    -  "endpoint": "https://custom.api.example.com/embed",
    -  "description": "Custom embedding model",
    -  "api_standard": "openai",
    -  "model": "custom-embed-v1",
    -  "dimensions": 1024
    -}

    Note: Only admin users can create _system definitions.


    Instance Properties#

    FieldTypeRequiredDescription
    instance_handlestringYesUnique identifier within user’s namespace
    ownerstringRead-onlyInstance owner’s user handle
    endpointstringYes*API endpoint URL
    descriptionstringNoInstance description
    api_standardstringYes*Reference to API standard
    modelstringYes*Model name
    dimensionsintegerYes*Vector dimensions
    api_key_encryptedstringWrite-onlyAPI key (never returned)
    definition_idintegerRead-onlyReference to definition template

    * Required for standalone instances; inherited from definition if using template


    Security Features#

    API Key Encryption#

    • Algorithm: AES-256-GCM
    • Key Source: ENCRYPTION_KEY environment variable
    • Storage: Encrypted in api_key_encrypted column
    • Retrieval: Never returned in API responses

    API Key Protection#

    API keys are write-only:

    • Provided during instance creation/update
    • Encrypted before storage
    • Never returned in GET/list responses
    • Shared users cannot see API keys

    Shared Instance Access#

    When an instance is shared:

    • Shared users can USE the instance for projects
    • Shared users CANNOT see the API key
    • Shared users CANNOT modify the instance
    • Only owner can manage sharing

    Common Errors#

    400 Bad Request#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Instance must specify either all configuration fields or reference a definition"
    -}

    403 Forbidden#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only admin users can create _system definitions"
    -}

    404 Not Found#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "LLM service instance 'alice/openai-large' not found"
    -}

    409 Conflict#

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Cannot delete instance: in use by 3 projects"
    -}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/projects/index.html b/docs/public/api/endpoints/projects/index.html deleted file mode 100644 index 26b81ce..0000000 --- a/docs/public/api/endpoints/projects/index.html +++ /dev/null @@ -1,169 +0,0 @@ -Projects | dhamps-vdb Documentation - -

    Projects Endpoint#

    Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.

    Endpoints#

    List User’s Projects#

    Get all projects owned by a user.

    Endpoint: GET /v1/projects/{username}

    Authentication: Admin, the user themselves, or users with shared access

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "projects": [
    -    {
    -      "project_id": 1,
    -      "project_handle": "research-docs",
    -      "owner": "alice",
    -      "description": "Research document embeddings",
    -      "instance_id": 5,
    -      "instance_owner": "alice",
    -      "instance_handle": "openai-large",
    -      "public_read": false,
    -      "created_at": "2024-01-15T10:30:00Z"
    -    }
    -  ]
    -}

    Create Project#

    Register a new project for a user.

    Endpoint: POST /v1/projects/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    -  "project_handle": "research-docs",
    -  "description": "Research document embeddings",
    -  "instance_owner": "alice",
    -  "instance_handle": "openai-large",
    -  "public_read": false,
    -  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}",
    -  "shared_with": [
    -    {
    -      "user_handle": "bob",
    -      "role": "reader"
    -    }
    -  ]
    -}

    Parameters:

    • project_handle (string, required): Unique project identifier within the user’s namespace
    • description (string, optional): Project description
    • instance_owner (string, required): Owner of the LLM service instance
    • instance_handle (string, required): Handle of the LLM service instance to use
    • public_read (boolean, optional): Allow unauthenticated read access (default: false)
    • metadataScheme (string, optional): JSON Schema for validating embedding metadata
    • shared_with (array, optional): List of users to share the project with

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Research document embeddings",
    -    "instance_owner": "alice",
    -    "instance_handle": "openai-large"
    -  }'

    Response:

    {
    -  "project_id": 1,
    -  "project_handle": "research-docs",
    -  "owner": "alice",
    -  "description": "Research document embeddings",
    -  "instance_id": 5,
    -  "instance_owner": "alice",
    -  "instance_handle": "openai-large",
    -  "public_read": false
    -}

    Get Project Information#

    Retrieve information about a specific project.

    Endpoint: GET /v1/projects/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "project_id": 1,
    -  "project_handle": "research-docs",
    -  "owner": "alice",
    -  "description": "Research document embeddings",
    -  "instance_id": 5,
    -  "instance_owner": "alice",
    -  "instance_handle": "openai-large",
    -  "public_read": false,
    -  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"}}}",
    -  "created_at": "2024-01-15T10:30:00Z"
    -}

    Update Project (PUT)#

    Create or update a project with the specified handle.

    Endpoint: PUT /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Request Body: Same as POST endpoint

    Example:

    curl -X PUT "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Updated description",
    -    "instance_owner": "alice",
    -    "instance_handle": "openai-large"
    -  }'

    Delete Project#

    Delete a project and all its embeddings.

    Endpoint: DELETE /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Example:

    curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "Project alice/research-docs deleted successfully"
    -}

    ⚠️ Warning: This operation is irreversible and will delete all embeddings in the project.


    Partial Update (PATCH)#

    Update specific project fields without providing all data.

    Endpoint: PATCH /v1/projects/{username}/{projectname}

    Authentication: Admin or the owner

    Example - Enable public read access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "public_read": true
    -  }'

    Example - Update description:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated project description"
    -  }'

    See PATCH Updates for more details.


    Project Sharing#

    Share Project#

    Share a project with another user, granting them read or edit access.

    Endpoint: POST /v1/projects/{owner}/{project}/share

    Authentication: Admin or the project owner

    Request Body:

    {
    -  "share_with_handle": "bob",
    -  "role": "reader"
    -}

    Roles:

    • reader: Read-only access to embeddings and similarity search
    • editor: Read and write access to embeddings

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice/research-docs/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "bob",
    -    "role": "reader"
    -  }'

    Response:

    {
    -  "message": "Project shared successfully",
    -  "project": "alice/research-docs",
    -  "shared_with": "bob",
    -  "role": "reader"
    -}

    Unshare Project#

    Remove a user’s access to a shared project.

    Endpoint: DELETE /v1/projects/{owner}/{project}/share/{user_handle}

    Authentication: Admin or the project owner

    Example:

    curl -X DELETE "https://api.example.com/v1/projects/alice/research-docs/share/bob" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "Project unshared successfully",
    -  "project": "alice/research-docs",
    -  "removed_user": "bob"
    -}

    List Shared Users#

    Get a list of users the project is shared with.

    Endpoint: GET /v1/projects/{owner}/{project}/shared-with

    Authentication: Admin or the project owner

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice/research-docs/shared-with" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "project": "alice/research-docs",
    -  "shared_with": [
    -    {
    -      "user_handle": "bob",
    -      "role": "reader"
    -    },
    -    {
    -      "user_handle": "charlie",
    -      "role": "editor"
    -    }
    -  ]
    -}

    Note: Only the project owner can view this list. Users with shared access cannot see who else has access.


    Project Ownership Transfer#

    Transfer Ownership#

    Transfer ownership of a project to another user.

    Endpoint: POST /v1/projects/{owner}/{project}/transfer-ownership

    Authentication: Admin or the project owner

    Request Body:

    {
    -  "new_owner_handle": "bob"
    -}

    Example:

    curl -X POST "https://api.example.com/v1/projects/alice/research-docs/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "new_owner_handle": "bob"
    -  }'

    Response:

    {
    -  "message": "Project ownership transferred successfully",
    -  "old_owner": "alice",
    -  "new_owner": "bob",
    -  "project_handle": "research-docs",
    -  "new_path": "/v1/projects/bob/research-docs"
    -}

    Important Notes:

    • Only the current owner can transfer ownership
    • The new owner must be an existing user
    • The new owner cannot already have a project with the same handle
    • After transfer, the old owner loses all access to the project
    • All embeddings and project data remain intact

    Query Parameters#

    List Projects#

    When listing projects, the following query parameters are available:

    • limit (integer, default: 10, max: 200): Maximum number of results to return
    • offset (integer, default: 0): Pagination offset

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice?limit=20&offset=40" \
    -  -H "Authorization: Bearer alice_api_key"

    Project Properties#

    FieldTypeRequiredDescription
    project_handlestringYesUnique identifier within user’s namespace
    ownerstringRead-onlyProject owner’s user handle
    descriptionstringNoProject description
    instance_ownerstringYesOwner of the LLM service instance
    instance_handlestringYesHandle of the LLM service instance
    instance_idintegerRead-onlyInternal ID of the LLM service instance
    public_readbooleanNoAllow unauthenticated read access
    metadataSchemestringNoJSON Schema for metadata validation
    created_attimestampRead-onlyProject creation timestamp

    Metadata Schema Validation#

    Projects can define a JSON Schema to validate metadata attached to embeddings. See the main README for examples.

    Example Schema:

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {"type": "string"},
    -    "year": {"type": "integer"}
    -  },
    -  "required": ["author"]
    -}

    When uploading embeddings, metadata will be validated against this schema. Invalid metadata will result in a 400 Bad Request error.


    Common Errors#

    400 Bad Request#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Project must have instance_id"
    -}

    403 Forbidden#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to modify this project"
    -}

    404 Not Found#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Project 'alice/research-docs' not found"
    -}

    409 Conflict#

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Project 'alice/research-docs' already exists"
    -}

    \ No newline at end of file diff --git a/docs/public/api/endpoints/similars/index.html b/docs/public/api/endpoints/similars/index.html deleted file mode 100644 index 3ff4a46..0000000 --- a/docs/public/api/endpoints/similars/index.html +++ /dev/null @@ -1,135 +0,0 @@ -Similars | dhamps-vdb Documentation - -

    Similarity Search Endpoints#

    Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.

    Endpoints#

    GET Similar Documents (from stored embeddings)#

    Find documents similar to an already-stored document by its text identifier.

    Endpoint: GET /v1/similars/{username}/{projectname}/{identifier}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters:

    • count (integer, optional, default: 10, max: 200): Number of similar documents to return
    • threshold (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold
    • limit (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for count)
    • offset (integer, optional, default: 0): Pagination offset
    • metadata_path (string, optional): Metadata field path for filtering (must be used with metadata_value)
    • metadata_value (string, optional): Metadata value to exclude from results (must be used with metadata_path)

    Example - Basic search:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_api_key"

    Example - With metadata filtering:

    # Exclude documents with author="John Doe"
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json",
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "results": [
    -    {
    -      "id": "doc456",
    -      "similarity": 0.95
    -    },
    -    {
    -      "id": "doc789",
    -      "similarity": 0.87
    -    },
    -    {
    -      "id": "doc321",
    -      "similarity": 0.82
    -    }
    -  ]
    -}

    POST Similar Documents (from raw embeddings)#

    Find similar documents by submitting a raw embedding vector without storing it in the database. Useful for one-time queries or testing.

    Endpoint: POST /v1/similars/{username}/{projectname}

    Authentication: Admin, owner, authorized readers, or public if public_read is enabled

    Query Parameters: Same as GET endpoint above

    Request Body:

    {
    -  "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003, ...]
    -}

    The vector must be an array of float values with dimensions matching the project’s LLM service instance configuration.

    Example - Basic search:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003]
    -  }'

    Example - With metadata filtering:

    # Exclude documents from the same category
    -curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=5&metadata_path=category&metadata_value=biology" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [-0.020850, 0.018522, 0.053270, ...]
    -  }'

    Response: Same format as GET endpoint


    Query Parameters Reference#

    count / limit#

    Maximum number of similar documents to return.

    • Type: Integer
    • Default: 10
    • Max: 200
    • Note: count and limit are aliases; use either one

    Example:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20"

    threshold#

    Minimum similarity score threshold. Only documents with similarity scores >= threshold are returned.

    • Type: Float
    • Default: 0.5
    • Range: 0.0 to 1.0 (where 1.0 is most similar)

    Example:

    # Only return very similar documents (>= 0.8)
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8"

    offset#

    Pagination offset for large result sets.

    • Type: Integer
    • Default: 0
    • Use: Skip the first N results

    Example:

    # Get results 21-40
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20"

    metadata_path#

    Metadata field path for filtering results. Must be used together with metadata_value.

    • Type: String
    • Format: JSON path notation (e.g., "author", "author.name", "publication.year")
    • Use: Exclude documents where metadata field matches a specific value

    Examples:

    # Simple field
    -metadata_path=author
    -
    -# Nested field
    -metadata_path=author.name
    -
    -# Deeply nested field
    -metadata_path=publication.journal.name

    metadata_value#

    Metadata value to exclude from results. Must be used together with metadata_path.

    • Type: String
    • Use: Excludes documents where the metadata field at metadata_path equals this value

    Example - Exclude same author:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe"

    Example - Exclude same category:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=research"

    Example - Nested field:

    # Exclude documents from same author ID
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083"

    Response Format#

    Both GET and POST endpoints return the same response format:

    {
    -  "$schema": "http://localhost:8080/schemas/SimilarResponseBody.json",
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "results": [
    -    {
    -      "id": "doc456",
    -      "similarity": 0.95
    -    },
    -    {
    -      "id": "doc789",
    -      "similarity": 0.87
    -    },
    -    {
    -      "id": "doc321",
    -      "similarity": 0.82
    -    }
    -  ]
    -}

    Response Fields:

    • $schema (string): JSON schema reference
    • user_handle (string): Project owner’s username
    • project_handle (string): Project identifier
    • results (array): Array of similar documents, ordered by similarity (highest first)
      • id (string): Document text identifier
      • similarity (float): Cosine similarity score (0-1, where 1 is most similar)

    Similarity Calculation#

    Cosine Distance#

    The API uses cosine distance (or equivalently, cosine similarity) to calculate vector similarity:

    • Range: 0 to 1
    • 1.0: Identical vectors
    • 0.0: Orthogonal vectors (completely dissimilar)
    • Higher values: More similar documents

    Dimension Filtering#

    The system automatically filters results to only include embeddings with matching dimensions. This ensures:

    • Only embeddings with matching vector_dim are compared
    • Only embeddings from the same project are considered
    • Invalid comparisons are prevented

    Dimension Validation (POST only)#

    When using the POST endpoint with raw embeddings, the API validates:

    1. The project has an associated LLM service instance
    2. The submitted vector dimensions match the instance’s configured dimensions
    3. If dimensions don’t match, a 400 Bad Request error is returned

    Error example:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "vector dimension mismatch: expected 1536 dimensions, got 768"
    -}

    Metadata Filtering#

    Both endpoints support metadata filtering to exclude documents based on metadata field values. This uses negative matching (excludes documents where the field matches the value).

    Use Cases#

    Exclude documents from the same source:

    # When finding similar documents to doc123, exclude others from the same author
    -curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=author_id&metadata_value=A0083"

    Exclude documents from the same category:

    # Find similar documents in other categories
    -curl -X GET ".../similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology"

    Exclude documents with the same tag:

    # Find documents with similar content but different tags
    -curl -X POST ".../similars/alice/research-docs?metadata_path=primary_tag&metadata_value=machine-learning" \
    -  -d '{"vector": [...]}'

    Nested Field Access#

    Use dot notation for nested metadata fields:

    # Exclude documents from the same author (nested field)
    -metadata_path=author.id&metadata_value=author-123
    -
    -# Exclude documents from the same publication year
    -metadata_path=publication.year&metadata_value=2024
    -
    -# Deeply nested field
    -metadata_path=source.journal.publisher&metadata_value=Springer

    Examples#

    Find 5 most similar documents with at least 0.7 similarity:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_api_key"

    Search with Raw Vector#

    Submit a vector without storing it:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003]
    -  }'

    Search with Metadata Filtering#

    Find similar documents but exclude those from the same author:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&metadata_path=author&metadata_value=John%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"

    Paginated Results#

    Get the next page of results:

    # Page 1
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=0"
    -
    -# Page 2
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=20"
    -
    -# Page 3
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40"

    Complex Query#

    High threshold, metadata filtering, and pagination:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&threshold=0.9&offset=0&metadata_path=category&metadata_value=biology" \
    -  -H "Authorization: Bearer alice_api_key"

    Common Errors#

    400 Bad Request - Dimension Mismatch (POST only)#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "vector dimension mismatch: expected 1536 dimensions, got 768"
    -}

    400 Bad Request - Missing metadata_value#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata_path requires metadata_value to be specified"
    -}

    400 Bad Request - Invalid threshold#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "threshold must be between 0.0 and 1.0"
    -}

    403 Forbidden#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to search this project"
    -}

    404 Not Found - Project#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Project 'alice/research-docs' not found"
    -}

    404 Not Found - Embedding (GET only)#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    -}

    Performance Considerations#

    Indexing#

    The database uses vector indexes for efficient similarity search. See the database migrations for index configuration.

    Result Limits#

    • Default limit: 10 results
    • Maximum limit: 200 results
    • Use pagination for large result sets

    Threshold Optimization#

    Higher thresholds reduce result set size and improve performance:

    • 0.5-0.7: Broad similarity (default)
    • 0.7-0.85: Moderate similarity
    • 0.85-0.95: High similarity
    • 0.95-1.0: Near-identical documents

    \ No newline at end of file diff --git a/docs/public/api/endpoints/users/index.html b/docs/public/api/endpoints/users/index.html deleted file mode 100644 index 53cf9ad..0000000 --- a/docs/public/api/endpoints/users/index.html +++ /dev/null @@ -1,104 +0,0 @@ -Users | dhamps-vdb Documentation - -

    Users Endpoint#

    Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.

    Endpoints#

    List All Users#

    Get a list of all registered user handles.

    Endpoint: GET /v1/users

    Authentication: Admin only

    Example:

    curl -X GET "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    -  "users": ["alice", "bob", "charlie"]
    -}

    Create User#

    Register a new user and generate their API key.

    Endpoint: POST /v1/users

    Authentication: Admin only

    Request Body:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice@example.com"
    -}

    Parameters:

    • user_handle (string, required): Unique identifier for the user (alphanumeric, hyphens, underscores)
    • name (string, optional): User’s full name
    • email (string, optional): User’s email address

    Example:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "alice",
    -    "name": "Alice Doe",
    -    "email": "alice@example.com"
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice@example.com",
    -  "api_key": "024v2013621509245f2e24"
    -}

    ⚠️ Important: The api_key is only returned once during user creation. Store it securely - it cannot be recovered later.

    Error Responses:

    • 400 Bad Request: Invalid user handle or missing required fields
    • 409 Conflict: User handle already exists

    Get User Information#

    Retrieve information about a specific user.

    Endpoint: GET /v1/users/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X GET "https://api.example.com/v1/users/alice" \
    -  -H "Authorization: Bearer alice_or_admin_api_key"

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice@example.com"
    -}

    Note: API key is never returned in GET responses for security reasons.


    Create or Update User (PUT)#

    Register a new user with a specific handle or update existing user information.

    Endpoint: PUT /v1/users/{username}

    Authentication: Admin only

    Request Body:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice@example.com"
    -}

    Example:

    curl -X PUT "https://api.example.com/v1/users/alice" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "alice",
    -    "name": "Alice Smith",
    -    "email": "alice.smith@example.com"
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Smith",
    -  "email": "alice.smith@example.com",
    -  "api_key": "024v2013621509245f2e24"
    -}

    Delete User#

    Delete a user and all their associated resources (projects, LLM services, embeddings).

    Endpoint: DELETE /v1/users/{username}

    Authentication: Admin or the user themselves

    Example:

    curl -X DELETE "https://api.example.com/v1/users/alice" \
    -  -H "Authorization: Bearer alice_or_admin_api_key"

    Response:

    {
    -  "message": "User alice deleted successfully"
    -}

    ⚠️ Warning: This operation is irreversible and will delete:

    • All projects owned by the user
    • All LLM service instances owned by the user
    • All embeddings in the user’s projects
    • All sharing relationships

    Partial Update (PATCH)#

    Update specific user fields without providing all user data.

    Endpoint: PATCH /v1/users/{username}

    Authentication: Admin or the user themselves

    Request Body:

    {
    -  "name": "Alice Smith"
    -}

    Example:

    curl -X PATCH "https://api.example.com/v1/users/alice" \
    -  -H "Authorization: Bearer alice_or_admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "email": "newemail@example.com"
    -  }'

    See PATCH Updates for more details.


    User Properties#

    FieldTypeRequiredDescription
    user_handlestringYesUnique identifier (alphanumeric, hyphens, underscores)
    namestringNoUser’s full name
    emailstringNoUser’s email address
    api_keystringRead-onlyGenerated API key (only returned on creation)

    Special User: _system#

    The _system user is a special internal user that:

    • Owns global LLM service definitions
    • Cannot be used for authentication
    • Cannot be deleted
    • Is created automatically during database migrations

    Users can create LLM service instances from _system definitions.

    Common Errors#

    400 Bad Request#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Invalid user_handle: must be alphanumeric with hyphens or underscores"
    -}

    401 Unauthorized#

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    403 Forbidden#

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only admin users can create new users"
    -}

    404 Not Found#

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "User 'alice' not found"
    -}

    409 Conflict#

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "User 'alice' already exists"
    -}
    \ No newline at end of file diff --git a/docs/public/api/error-handling/index.html b/docs/public/api/error-handling/index.html deleted file mode 100644 index 97e5264..0000000 --- a/docs/public/api/error-handling/index.html +++ /dev/null @@ -1,236 +0,0 @@ -Error Handling | dhamps-vdb Documentation - -

    Error Handling#

    The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.

    Error Response Format#

    All error responses follow this structure:

    {
    -  "title": "Error Title",
    -  "status": 400,
    -  "detail": "Detailed error message explaining what went wrong"
    -}

    Fields:

    • title (string): Human-readable error title
    • status (integer): HTTP status code
    • detail (string): Detailed description of the error

    HTTP Status Codes#

    2xx Success#

    200 OK#

    Request succeeded. Response body contains requested data.

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "projects": [...]
    -}

    201 Created#

    Resource created successfully. Response body contains the new resource.

    Example:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -d '{"user_handle": "bob"}'

    Response:

    {
    -  "user_handle": "bob",
    -  "api_key": "..."
    -}

    4xx Client Errors#

    400 Bad Request#

    The request is invalid or contains malformed data.

    Common causes:

    • Invalid JSON syntax
    • Missing required fields
    • Invalid field values or types
    • Dimension mismatches in embeddings
    • Metadata schema violations
    • Invalid query parameter values

    Examples:

    Invalid JSON:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Invalid JSON: unexpected end of input"
    -}

    Missing required field:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Missing required field: project_handle"
    -}

    Dimension mismatch:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'openai-large' expects 1536 dimensions"
    -}

    Metadata validation:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    -}

    Invalid query parameter:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "limit must be between 1 and 200"
    -}

    401 Unauthorized#

    Authentication failed or credentials are missing.

    Common causes:

    • Missing Authorization header
    • Invalid API key
    • Expired API key
    • Malformed Authorization header

    Example:

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    Troubleshooting:

    • Verify the Authorization header is present
    • Check the API key is correct
    • Ensure the header format is Authorization: Bearer <api_key>
    • Verify the user still exists

    403 Forbidden#

    Authentication succeeded but authorization failed. The authenticated user lacks permission for the requested operation.

    Common causes:

    • User attempting to access another user’s private resources
    • Non-admin attempting admin-only operations
    • User attempting to modify shared resources they don’t own
    • Attempting to access resources with insufficient role (reader vs editor)

    Examples:

    Admin-only operation:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only admin users can create new users"
    -}

    Accessing another user’s resource:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to access this project"
    -}

    Insufficient role:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to modify embeddings in this project. Editor role required."
    -}

    404 Not Found#

    The requested resource does not exist.

    Common causes:

    • Resource was deleted
    • Incorrect resource identifier
    • Typo in URL path
    • Resource never existed

    Examples:

    User not found:

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "User 'alice' not found"
    -}

    Project not found:

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Project 'alice/research-docs' not found"
    -}

    Embedding not found:

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Embedding 'doc123' not found in project 'alice/research-docs'"
    -}

    LLM service not found:

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "LLM service instance 'alice/openai-large' not found"
    -}

    409 Conflict#

    The request conflicts with the current state of the resource.

    Common causes:

    • Creating a resource that already exists
    • Deleting a resource that is in use
    • Concurrent modification conflicts

    Examples:

    Resource already exists:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "User 'alice' already exists"
    -}

    Resource in use:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Cannot delete LLM service instance: in use by 3 projects"
    -}

    Ownership transfer conflict:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "New owner already has a project with handle 'research-docs'"
    -}

    422 Unprocessable Entity#

    The request is syntactically correct but semantically invalid.

    Common causes:

    • Invalid JSON Schema
    • Logical validation failures
    • Constraint violations

    Example:

    {
    -  "title": "Unprocessable Entity",
    -  "status": 422,
    -  "detail": "metadataScheme is not valid JSON Schema: invalid schema structure"
    -}

    5xx Server Errors#

    500 Internal Server Error#

    An unexpected error occurred on the server.

    Common causes:

    • Database connection failures
    • Unexpected exceptions
    • Configuration errors

    Example:

    {
    -  "title": "Internal Server Error",
    -  "status": 500,
    -  "detail": "An internal error occurred. Please try again later."
    -}

    Action: Contact support if the error persists.


    503 Service Unavailable#

    The service is temporarily unavailable.

    Common causes:

    • Database maintenance
    • Service overload
    • Network issues

    Example:

    {
    -  "title": "Service Unavailable",
    -  "status": 503,
    -  "detail": "Service temporarily unavailable. Please try again later."
    -}

    Action: Retry the request after a delay.


    Common Error Scenarios#

    Authentication Errors#

    Missing Authorization Header#

    Request:

    curl -X GET "https://api.example.com/v1/projects/alice"

    Response:

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    Solution: Include the Authorization header:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer alice_api_key"

    Invalid API Key#

    Request:

    curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer invalid_key"

    Response:

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    Solution: Verify your API key is correct.


    Permission Errors#

    Non-Admin Creating Users#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -d '{"user_handle": "bob"}'

    Response:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only admin users can create new users"
    -}

    Solution: Use an admin API key.


    Accessing Another User’s Project#

    Request:

    curl -X GET "https://api.example.com/v1/projects/bob/private-project" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to access this project"
    -}

    Solution: Request the project owner to share the project with you.


    Validation Errors#

    Invalid JSON#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle": "bob"'

    Response:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Invalid JSON: unexpected end of input"
    -}

    Solution: Fix the JSON syntax.


    Dimension Mismatch#

    Request:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc123",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3],
    -      "vector_dim": 3
    -    }]
    -  }'

    Response:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3 dimensions but LLM service 'openai-large' expects 3072 dimensions"
    -}

    Solution: Ensure vector dimensions match the LLM service configuration.


    Metadata Schema Violation#

    Request:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc123",
    -      "instance_handle": "openai-large",
    -      "vector": [...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "year": 2024
    -      }
    -    }]
    -  }'

    Response (if project schema requires “author”):

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc123': metadata validation failed:\n  - author: author is required"
    -}

    Solution: Include all required metadata fields.


    Resource Conflicts#

    Creating Duplicate Resource#

    Request:

    curl -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -d '{"user_handle": "alice"}'

    Response:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "User 'alice' already exists"
    -}

    Solution: Use a different user handle or update the existing user.


    Deleting Resource In Use#

    Request:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "Cannot delete LLM service instance: in use by 3 projects"
    -}

    Solution: Delete or update the projects using this instance first.


    Error Handling Best Practices#

    Client-Side Error Handling#

    Python example:

    import requests
    -
    -response = requests.get(
    -    "https://api.example.com/v1/projects/alice",
    -    headers={"Authorization": f"Bearer {api_key}"}
    -)
    -
    -if response.status_code == 200:
    -    projects = response.json()["projects"]
    -    print(f"Found {len(projects)} projects")
    -    
    -elif response.status_code == 401:
    -    print("Authentication failed - check API key")
    -    
    -elif response.status_code == 403:
    -    print("Permission denied")
    -    
    -elif response.status_code == 404:
    -    print("User not found")
    -    
    -elif response.status_code >= 500:
    -    print("Server error - retry later")
    -    
    -else:
    -    error = response.json()
    -    print(f"Error: {error['detail']}")

    Retry Logic#

    For transient errors (5xx), implement exponential backoff:

    import time
    -import requests
    -
    -def api_request_with_retry(url, max_retries=3):
    -    for attempt in range(max_retries):
    -        response = requests.get(url, headers={...})
    -        
    -        if response.status_code < 500:
    -            return response
    -            
    -        if attempt < max_retries - 1:
    -            wait_time = 2 ** attempt  # Exponential backoff
    -            print(f"Retrying in {wait_time}s...")
    -            time.sleep(wait_time)
    -    
    -    return response

    Validation Before Request#

    Validate data locally before sending to reduce 400 errors:

    def create_embedding(text_id, vector, metadata):
    -    # Validate locally
    -    if not text_id:
    -        raise ValueError("text_id is required")
    -    
    -    if not isinstance(vector, list):
    -        raise ValueError("vector must be a list")
    -    
    -    if len(vector) != 3072:
    -        raise ValueError("vector must have 3072 dimensions")
    -    
    -    # Send request
    -    response = requests.post(
    -        "https://api.example.com/v1/embeddings/alice/research-docs",
    -        json={
    -            "embeddings": [{
    -                "text_id": text_id,
    -                "instance_handle": "openai-large",
    -                "vector": vector,
    -                "vector_dim": len(vector),
    -                "metadata": metadata
    -            }]
    -        },
    -        headers={"Authorization": f"Bearer {api_key}"}
    -    )
    -    
    -    return response.json()

    Troubleshooting#

    Check API Documentation#

    Always refer to the live API documentation:

    • OpenAPI YAML: /openapi.yaml
    • Interactive Docs: /docs

    Verify Request Format#

    Use tools like curl -v to inspect the full request:

    curl -v -X POST "https://api.example.com/v1/users" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle": "bob"}'

    Check Status and Logs#

    For persistent 5xx errors, check service status and logs (if you have access).


    Contact Support#

    If errors persist or the cause is unclear:

    1. Note the error message and status code
    2. Record the request details (method, URL, headers, body)
    3. Check if the issue is reproducible
    4. Contact support with this information

    \ No newline at end of file diff --git a/docs/public/api/index.html b/docs/public/api/index.html deleted file mode 100644 index ed3425a..0000000 --- a/docs/public/api/index.html +++ /dev/null @@ -1,18 +0,0 @@ -API Reference | dhamps-vdb Documentation - -

    API Reference#

    Complete reference for the dhamps-vdb REST API.

    API Version#

    Current version: v1

    All endpoints are prefixed with /v1/ (e.g., POST /v1/embeddings/{user}/{project}).

    API Documentation#

    The complete, always up-to-date API specification is available at:

    • OpenAPI YAML: /openapi.yaml
    • Interactive Documentation: /docs

    Reference Sections#

    Quick Example#

    # Authenticate with API key
    -curl -X GET "https://api.example.com/v1/projects/alice" \
    -  -H "Authorization: Bearer your_api_key_here"

    All API requests require authentication except for public project read operations.

    \ No newline at end of file diff --git a/docs/public/api/index.xml b/docs/public/api/index.xml deleted file mode 100644 index 0824b4a..0000000 --- a/docs/public/api/index.xml +++ /dev/null @@ -1,59 +0,0 @@ -API Reference on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/api/Recent content in API Reference on dhamps-vdb DocumentationHugoen-usAuthenticationhttps://mpilhlt.github.io/dhamps-vdb/api/authentication/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/authentication/<h1 id="api-authentication">API Authentication<a class="anchor" href="#api-authentication">#</a></h1> -<p>All API requests (except public project read operations) require authentication using API keys passed in the <code>Authorization</code> header with a <code>Bearer</code> prefix.</p> -<h2 id="authentication-method">Authentication Method<a class="anchor" href="#authentication-method">#</a></h2> -<p>Include your API key in the <code>Authorization</code> header of every request:</p> -<pre tabindex="0"><code>Authorization: Bearer your_api_key_here</code></pre><h2 id="api-key-types">API Key Types<a class="anchor" href="#api-key-types">#</a></h2> -<h3 id="admin-api-key">Admin API Key<a class="anchor" href="#admin-api-key">#</a></h3> -<ul> -<li>Full access to all API endpoints and resources</li> -<li>Can create and manage users</li> -<li>Can access all projects and resources across all users</li> -<li>Required for administrative operations</li> -<li>Set via <code>ADMIN_KEY</code> environment variable</li> -</ul> -<p><strong>Admin-only operations:</strong></p>Query Parametershttps://mpilhlt.github.io/dhamps-vdb/api/query-parameters/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/<h1 id="query-parameters-reference">Query Parameters Reference<a class="anchor" href="#query-parameters-reference">#</a></h1> -<p>Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.</p> -<h2 id="pagination-parameters">Pagination Parameters<a class="anchor" href="#pagination-parameters">#</a></h2> -<h3 id="limit">limit<a class="anchor" href="#limit">#</a></h3> -<p>Maximum number of results to return in a single response.</p> -<p><strong>Type:</strong> Integer<br> -<strong>Default:</strong> 10<br> -<strong>Maximum:</strong> 200<br> -<strong>Minimum:</strong> 1</p> -<p><strong>Used by:</strong></p> -<ul> -<li><code>GET /v1/embeddings/{user}/{project}</code> - List embeddings</li> -<li><code>GET /v1/similars/{user}/{project}/{id}</code> - Similarity search</li> -<li><code>POST /v1/similars/{user}/{project}</code> - Raw vector search</li> -<li><code>GET /v1/projects/{user}</code> - List projects</li> -</ul> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get 50 embeddings</span> -</span></span><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Aliases:</strong></p>PATCH Updateshttps://mpilhlt.github.io/dhamps-vdb/api/patch-updates/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/<h1 id="patch-method-for-partial-updates">PATCH Method for Partial Updates<a class="anchor" href="#patch-method-for-partial-updates">#</a></h1> -<p>The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:</p> -<ol> -<li>Retrieves the current resource state via GET</li> -<li>Merges your changes with the existing data</li> -<li>Applies the update via PUT</li> -</ol> -<p>This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.</p>Error Handlinghttps://mpilhlt.github.io/dhamps-vdb/api/error-handling/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/error-handling/<h1 id="error-handling">Error Handling<a class="anchor" href="#error-handling">#</a></h1> -<p>The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.</p> -<h2 id="error-response-format">Error Response Format<a class="anchor" href="#error-response-format">#</a></h2> -<p>All error responses follow this structure:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Error Title&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;status&#34;</span>: <span style="color:#ae81ff">400</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;detail&#34;</span>: <span style="color:#e6db74">&#34;Detailed error message explaining what went wrong&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Fields:</strong></p> -<ul> -<li><code>title</code> (string): Human-readable error title</li> -<li><code>status</code> (integer): HTTP status code</li> -<li><code>detail</code> (string): Detailed description of the error</li> -</ul> -<h2 id="http-status-codes">HTTP Status Codes<a class="anchor" href="#http-status-codes">#</a></h2> -<h3 id="2xx-success">2xx Success<a class="anchor" href="#2xx-success">#</a></h3> -<h4 id="200-ok">200 OK<a class="anchor" href="#200-ok">#</a></h4> -<p>Request succeeded. Response body contains requested data.</p> \ No newline at end of file diff --git a/docs/public/api/patch-updates/index.html b/docs/public/api/patch-updates/index.html deleted file mode 100644 index 60335f6..0000000 --- a/docs/public/api/patch-updates/index.html +++ /dev/null @@ -1,169 +0,0 @@ -PATCH Updates | dhamps-vdb Documentation - -

    PATCH Method for Partial Updates#

    The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.

    Overview#

    PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:

    1. Retrieves the current resource state via GET
    2. Merges your changes with the existing data
    3. Applies the update via PUT

    This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.

    Supported Resources#

    PATCH is available for:

    • Users: /v1/users/{username}
    • Projects: /v1/projects/{username}/{projectname}
    • LLM Services: /v1/llm-services/{username}/{llm_servicename}
    • API Standards: /v1/api-standards/{standardname}

    Request Format#

    Endpoint: PATCH {resource_url}

    Content-Type: application/json

    Body: JSON object containing only the fields to update

    Examples#

    Update Project Description#

    Change only the project description without affecting other fields.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated project description"
    -  }'

    Response:

    {
    -  "project_id": 1,
    -  "project_handle": "research-docs",
    -  "owner": "alice",
    -  "description": "Updated project description",
    -  "instance_id": 5,
    -  "instance_owner": "alice",
    -  "instance_handle": "openai-large",
    -  "public_read": false
    -}

    Enable Public Read Access#

    Make a project publicly accessible without changing other settings.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "public_read": true
    -  }'

    Response:

    {
    -  "project_id": 1,
    -  "project_handle": "research-docs",
    -  "owner": "alice",
    -  "description": "Research document embeddings",
    -  "instance_id": 5,
    -  "instance_owner": "alice",
    -  "instance_handle": "openai-large",
    -  "public_read": true
    -}

    Update User Email#

    Change a user’s email address without affecting other user data.

    Request:

    curl -X PATCH "https://api.example.com/v1/users/alice" \
    -  -H "Authorization: Bearer alice_or_admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "email": "alice.new@example.com"
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Doe",
    -  "email": "alice.new@example.com"
    -}

    Update LLM Service Description#

    Change the description of an LLM service instance.

    Request:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/openai-large" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Production OpenAI embeddings service"
    -  }'

    Response:

    {
    -  "instance_id": 1,
    -  "instance_handle": "openai-large",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "description": "Production OpenAI embeddings service",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072
    -}

    Update API Standard Documentation#

    Update the description of an API standard (admin only).

    Request:

    curl -X PATCH "https://api.example.com/v1/api-standards/openai" \
    -  -H "Authorization: Bearer admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "OpenAI Embeddings API, Version 1 - Updated 2024"
    -  }'

    Update Multiple Fields#

    You can update multiple fields in a single PATCH request.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated description",
    -    "public_read": true
    -  }'

    Add Project Metadata Schema#

    Add or update a project’s metadata validation schema.

    Request:

    curl -X PATCH "https://api.example.com/v1/projects/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    -  }'

    Use Cases#

    Configuration Changes#

    Update configuration settings without rebuilding entire resource objects:

    # Enable/disable public access
    -curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{"public_read": true}'
    -
    -# Update instance dimensions
    -curl -X PATCH ".../llm-services/alice/custom-model" \
    -  -d '{"dimensions": 1024}'

    Metadata Management#

    Update descriptive metadata:

    # Update project description
    -curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{"description": "New description"}'
    -
    -# Update user name
    -curl -X PATCH ".../users/alice" \
    -  -d '{"name": "Alice Smith"}'

    Schema Evolution#

    Add or update validation schemas:

    curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"category\":{\"type\":\"string\"}}}"
    -  }'

    Authentication#

    PATCH requests require the same authentication as PUT requests for the resource:

    ResourceWho Can PATCH
    UsersAdmin or the user themselves
    ProjectsAdmin or project owner
    LLM ServicesAdmin or instance owner
    API StandardsAdmin only

    Behavior Details#

    Merge Strategy#

    PATCH uses a shallow merge strategy:

    • Top-level fields you specify replace the existing values
    • Nested objects are replaced entirely (not deep-merged)
    • Fields you don’t specify remain unchanged

    Example:

    Existing project:

    {
    -  "description": "Old description",
    -  "public_read": false,
    -  "metadataScheme": "{...old schema...}"
    -}

    PATCH request:

    {
    -  "description": "New description"
    -}

    Result:

    {
    -  "description": "New description",
    -  "public_read": false,
    -  "metadataScheme": "{...old schema...}"
    -}

    Validation#

    All field values are validated according to the resource’s schema:

    • Field types must be correct
    • Required fields (if specified) must be valid
    • Constraints (e.g., string length, enum values) are enforced

    Atomic Operations#

    PATCH operations are atomic:

    • Either all changes succeed, or none are applied
    • If validation fails, the resource remains unchanged

    Comparison: PATCH vs PUT#

    PUT (Complete Replacement)#

    Requires: All fields (except read-only ones)

    curl -X PUT ".../projects/alice/research-docs" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Updated description",
    -    "instance_owner": "alice",
    -    "instance_handle": "openai-large",
    -    "public_read": false
    -  }'

    Use when: Creating or completely replacing a resource


    PATCH (Partial Update)#

    Requires: Only fields to change

    curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{
    -    "description": "Updated description"
    -  }'

    Use when: Modifying one or a few fields of an existing resource


    Error Handling#

    400 Bad Request#

    Invalid field values or types:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "Invalid value for field 'public_read': expected boolean, got string"
    -}

    401 Unauthorized#

    Missing or invalid authentication:

    {
    -  "title": "Unauthorized",
    -  "status": 401,
    -  "detail": "Invalid or missing authorization credentials"
    -}

    403 Forbidden#

    Insufficient permissions:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "You don't have permission to modify this resource"
    -}

    404 Not Found#

    Resource doesn’t exist:

    {
    -  "title": "Not Found",
    -  "status": 404,
    -  "detail": "Project 'alice/research-docs' not found"
    -}

    422 Unprocessable Entity#

    Validation failed:

    {
    -  "title": "Unprocessable Entity",
    -  "status": 422,
    -  "detail": "metadataScheme is not valid JSON Schema"
    -}

    Best Practices#

    Use PATCH for Single-Field Updates#

    Do:

    curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{"public_read": true}'

    Don’t:

    # Unnecessarily complex
    -curl -X PUT ".../projects/alice/research-docs" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Research docs",
    -    "instance_owner": "alice",
    -    "instance_handle": "openai-large",
    -    "public_read": true
    -  }'

    Update multiple related fields in one request:

    curl -X PATCH ".../projects/alice/research-docs" \
    -  -d '{
    -    "description": "Updated project",
    -    "public_read": true,
    -    "metadataScheme": "{...new schema...}"
    -  }'

    Validate Before Patching#

    When possible, validate changes locally before submitting:

    # Python example
    -def update_project_description(project_path, new_description):
    -    if not new_description or len(new_description) > 500:
    -        raise ValueError("Invalid description")
    -    
    -    response = requests.patch(
    -        f"{API_BASE}/projects/{project_path}",
    -        json={"description": new_description},
    -        headers={"Authorization": f"Bearer {API_KEY}"}
    -    )
    -    return response.json()

    Handle Errors Gracefully#

    response = requests.patch(
    -    f"{API_BASE}/projects/alice/research-docs",
    -    json={"public_read": True},
    -    headers={"Authorization": f"Bearer {API_KEY}"}
    -)
    -
    -if response.status_code == 200:
    -    print("Updated successfully")
    -elif response.status_code == 403:
    -    print("Permission denied")
    -elif response.status_code == 404:
    -    print("Project not found")
    -else:
    -    print(f"Error: {response.json()['detail']}")

    Limitations#

    Not Available For#

    PATCH is not available for:

    • Endpoints that don’t support GET and PUT
    • List endpoints (e.g., GET /v1/projects/alice)
    • Action endpoints (e.g., /share, /transfer-ownership)

    Cannot Change Identifiers#

    You cannot use PATCH to change resource identifiers:

    • user_handle
    • project_handle
    • instance_handle
    • api_standard_handle

    To rename a resource, you must create a new resource and delete the old one.


    \ No newline at end of file diff --git a/docs/public/api/query-parameters/index.html b/docs/public/api/query-parameters/index.html deleted file mode 100644 index d037f96..0000000 --- a/docs/public/api/query-parameters/index.html +++ /dev/null @@ -1,115 +0,0 @@ -Query Parameters | dhamps-vdb Documentation - -

    Query Parameters Reference#

    Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.

    Pagination Parameters#

    limit#

    Maximum number of results to return in a single response.

    Type: Integer
    Default: 10
    Maximum: 200
    Minimum: 1

    Used by:

    • GET /v1/embeddings/{user}/{project} - List embeddings
    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search
    • GET /v1/projects/{user} - List projects

    Example:

    # Get 50 embeddings
    -curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=50" \
    -  -H "Authorization: Bearer alice_api_key"

    Aliases:

    • count - Used in similarity search endpoints (same behavior as limit)

    offset#

    Number of results to skip before returning data. Used for pagination.

    Type: Integer
    Default: 0
    Minimum: 0

    Used by:

    • GET /v1/embeddings/{user}/{project} - List embeddings
    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search
    • GET /v1/projects/{user} - List projects

    Example:

    # Get results 21-40 (page 2)
    -curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=20" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Get results 41-60 (page 3)
    -curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=20&offset=40" \
    -  -H "Authorization: Bearer alice_api_key"

    Pagination Formula:

    Page N: offset = (N - 1) * limit

    Similarity Search Parameters#

    count#

    Number of similar documents to return. Alias for limit in similarity search endpoints.

    Type: Integer
    Default: 10
    Maximum: 200
    Minimum: 1

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Find 5 most similar documents
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=5" \
    -  -H "Authorization: Bearer alice_api_key"

    Note: count and limit can be used interchangeably in similarity endpoints.


    threshold#

    Minimum similarity score threshold. Only results with similarity >= threshold are returned.

    Type: Float
    Default: 0.5
    Range: 0.0 to 1.0
    Note: 1.0 = most similar, 0.0 = least similar

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Only return highly similar documents (>= 0.8)
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Return moderately similar documents (>= 0.6)
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.6" \
    -  -H "Authorization: Bearer alice_api_key"

    Threshold Guidelines:

    ThresholdInterpretationUse Case
    0.95-1.0Near-identicalDuplicate detection
    0.85-0.95Very similarFinding closely related documents
    0.7-0.85Moderately similarBroad similarity search
    0.5-0.7Loosely similarExploratory search
    0.0-0.5Weakly similarGenerally not useful

    Metadata Filtering Parameters#

    metadata_path#

    JSON path to a metadata field for filtering results. Must be used together with metadata_value.

    Type: String
    Format: JSON path notation (e.g., "author", "author.name", "publication.year")

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Path Notation:

    • Simple field: author
    • Nested field: author.name
    • Deeply nested: publication.journal.name

    Example:

    # Simple field path
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=John%20Doe"
    -
    -# Nested field path
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id&metadata_value=A0083"

    metadata_value#

    Metadata value to exclude from similarity search results. Must be used together with metadata_path.

    Type: String
    Behavior: Negative matching (excludes documents where field equals this value)

    Used by:

    • GET /v1/similars/{user}/{project}/{id} - Similarity search
    • POST /v1/similars/{user}/{project} - Raw vector search

    Example:

    # Exclude documents from the same author
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author&metadata_value=Alice%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Exclude documents from the same category
    -curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category&metadata_value=biology" \
    -  -H "Authorization: Bearer alice_api_key"

    URL Encoding:

    Always URL-encode metadata values that contain special characters:

    # Value: "John Doe" → "John%20Doe"
    -# Value: "2024-01-15" → "2024-01-15" (no special chars)
    -# Value: "author@example.com" → "author%40example.com"

    Parameter Combinations#

    Pagination with Filtering#

    Combine limit, offset, and threshold:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&offset=40&threshold=0.7" \
    -  -H "Authorization: Bearer alice_api_key"

    Similarity Search with Metadata Filtering#

    Combine threshold and metadata filtering:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=10&threshold=0.8&metadata_path=author&metadata_value=John%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"

    Complete Query with All Parameters#

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=50&offset=0&threshold=0.75&metadata_path=category&metadata_value=biology" \
    -  -H "Authorization: Bearer alice_api_key"

    Endpoint-Specific Parameters#

    List Embeddings#

    Endpoint: GET /v1/embeddings/{user}/{project}

    Supported Parameters:

    • limit (default: 10, max: 200)
    • offset (default: 0)

    Example:

    curl -X GET "https://api.example.com/v1/embeddings/alice/research-docs?limit=100&offset=200" \
    -  -H "Authorization: Bearer alice_api_key"

    List Projects#

    Endpoint: GET /v1/projects/{user}

    Supported Parameters:

    • limit (default: 10, max: 200)
    • offset (default: 0)

    Example:

    curl -X GET "https://api.example.com/v1/projects/alice?limit=50&offset=0" \
    -  -H "Authorization: Bearer alice_api_key"

    Similarity Search (GET)#

    Endpoint: GET /v1/similars/{user}/{project}/{id}

    Supported Parameters:

    • count / limit (default: 10, max: 200)
    • offset (default: 0)
    • threshold (default: 0.5, range: 0.0-1.0)
    • metadata_path (optional, requires metadata_value)
    • metadata_value (optional, requires metadata_path)

    Example:

    curl -X GET "https://api.example.com/v1/similars/alice/research-docs/doc123?count=20&threshold=0.7&metadata_path=author&metadata_value=John%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"

    Similarity Search (POST)#

    Endpoint: POST /v1/similars/{user}/{project}

    Supported Parameters: Same as GET similarity search

    Example:

    curl -X POST "https://api.example.com/v1/similars/alice/research-docs?count=10&threshold=0.8" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [-0.020850, 0.018522, 0.053270, ...]
    -  }'

    Parameter Validation#

    Invalid Parameter Values#

    Error Response:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "limit must be between 1 and 200"
    -}

    Common Validation Errors:

    • limit exceeds maximum (200)
    • limit less than minimum (1)
    • offset is negative
    • threshold outside range 0.0-1.0
    • metadata_path without metadata_value
    • metadata_value without metadata_path

    Best Practices#

    Pagination#

    Do:

    • Use consistent limit values across pages
    • Start with offset=0 for the first page
    • Increment offset by limit for each subsequent page

    Example pagination logic:

    limit = 20
    -page = 1
    -
    -# Page 1
    -offset = (page - 1) * limit  # 0
    -url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"
    -
    -# Page 2
    -page = 2
    -offset = (page - 1) * limit  # 20
    -url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"
    -
    -# Page 3
    -page = 3
    -offset = (page - 1) * limit  # 40
    -url = f"/v1/embeddings/alice/research?limit={limit}&offset={offset}"

    Do:

    • Use higher thresholds (0.7-0.9) for focused searches
    • Use lower thresholds (0.5-0.7) for exploratory searches
    • Combine with count to limit result size
    • Use metadata filtering to exclude unwanted results

    Don’t:

    • Request more results than needed (affects performance)
    • Use very low thresholds (<0.5) unless necessary

    Metadata Filtering#

    Do:

    • URL-encode metadata values with special characters
    • Use specific field paths for nested metadata
    • Test metadata paths with sample queries first

    Example:

    # Good: URL-encoded, specific path
    -metadata_path=author.id&metadata_value=A0083
    -
    -# Good: Simple field
    -metadata_path=category&metadata_value=biology
    -
    -# Bad: Not URL-encoded
    -metadata_path=author name&metadata_value=John Doe
    -
    -# Good: URL-encoded
    -metadata_path=author%20name&metadata_value=John%20Doe

    Response Formats#

    Paginated Response#

    Endpoints that support pagination typically return:

    {
    -  "items": [...],
    -  "total_count": 500,
    -  "limit": 20,
    -  "offset": 40,
    -  "has_more": true
    -}

    Fields:

    • items: Array of results
    • total_count: Total number of items available
    • limit: Number of items requested per page
    • offset: Current offset
    • has_more: Boolean indicating if more results exist

    Similarity Response#

    Similarity endpoints return:

    {
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "results": [
    -    {
    -      "id": "doc456",
    -      "similarity": 0.95
    -    },
    -    {
    -      "id": "doc789",
    -      "similarity": 0.87
    -    }
    -  ]
    -}

    Notes:

    • Results are ordered by similarity (highest first)
    • Only results >= threshold are included
    • Maximum of count/limit results returned
    • Filtered by metadata_path/metadata_value if specified

    \ No newline at end of file diff --git a/docs/public/asciinema/asciinema-auto.js b/docs/public/asciinema/asciinema-auto.js deleted file mode 100644 index 3ae311c..0000000 --- a/docs/public/asciinema/asciinema-auto.js +++ /dev/null @@ -1,7 +0,0 @@ -(function() { - document.querySelectorAll(".asciinema").forEach(function(element) { - AsciinemaPlayer.create(element.getAttribute("x-data-cast"), - element, - JSON.parse(element.getAttribute("x-data-opts"))); - }); -}()); \ No newline at end of file diff --git a/docs/public/asciinema/asciinema-player.css b/docs/public/asciinema/asciinema-player.css deleted file mode 100644 index 26c9319..0000000 --- a/docs/public/asciinema/asciinema-player.css +++ /dev/null @@ -1,2389 +0,0 @@ -div.ap-wrapper { - outline: none; - height: 100%; - display: flex; - justify-content: center; -} -div.ap-wrapper .title-bar { - display: none; - top: -78px; - transition: top 0.15s linear; - position: absolute; - left: 0; - right: 0; - box-sizing: content-box; - font-size: 20px; - line-height: 1em; - padding: 15px; - font-family: sans-serif; - color: white; - background-color: rgba(0, 0, 0, 0.8); -} -div.ap-wrapper .title-bar img { - vertical-align: middle; - height: 48px; - margin-right: 16px; -} -div.ap-wrapper .title-bar a { - color: white; - text-decoration: underline; -} -div.ap-wrapper .title-bar a:hover { - text-decoration: none; -} -div.ap-wrapper:fullscreen { - background-color: #000; - width: 100%; - align-items: center; -} -div.ap-wrapper:fullscreen .title-bar { - display: initial; -} -div.ap-wrapper:fullscreen.hud .title-bar { - top: 0; -} -div.ap-wrapper div.ap-player { - text-align: left; - display: inline-block; - padding: 0px; - position: relative; - box-sizing: content-box; - overflow: hidden; - max-width: 100%; - border-radius: 4px; - font-size: 15px; - background-color: var(--term-color-background); -} -.ap-player { - --term-color-foreground: #ffffff; - --term-color-background: #000000; - --term-color-0: var(--term-color-foreground); - --term-color-1: var(--term-color-foreground); - --term-color-2: var(--term-color-foreground); - --term-color-3: var(--term-color-foreground); - --term-color-4: var(--term-color-foreground); - --term-color-5: var(--term-color-foreground); - --term-color-6: var(--term-color-foreground); - --term-color-7: var(--term-color-foreground); - --term-color-8: var(--term-color-0); - --term-color-9: var(--term-color-1); - --term-color-10: var(--term-color-2); - --term-color-11: var(--term-color-3); - --term-color-12: var(--term-color-4); - --term-color-13: var(--term-color-5); - --term-color-14: var(--term-color-6); - --term-color-15: var(--term-color-7); -} -.ap-player .fg-0 { - --fg: var(--term-color-0); -} -.ap-player .bg-0 { - --bg: var(--term-color-0); -} -.ap-player .fg-1 { - --fg: var(--term-color-1); -} -.ap-player .bg-1 { - --bg: var(--term-color-1); -} -.ap-player .fg-2 { - --fg: var(--term-color-2); -} -.ap-player .bg-2 { - --bg: var(--term-color-2); -} -.ap-player .fg-3 { - --fg: var(--term-color-3); -} -.ap-player .bg-3 { - --bg: var(--term-color-3); -} -.ap-player .fg-4 { - --fg: var(--term-color-4); -} -.ap-player .bg-4 { - --bg: var(--term-color-4); -} -.ap-player .fg-5 { - --fg: var(--term-color-5); -} -.ap-player .bg-5 { - --bg: var(--term-color-5); -} -.ap-player .fg-6 { - --fg: var(--term-color-6); -} -.ap-player .bg-6 { - --bg: var(--term-color-6); -} -.ap-player .fg-7 { - --fg: var(--term-color-7); -} -.ap-player .bg-7 { - --bg: var(--term-color-7); -} -.ap-player .fg-8 { - --fg: var(--term-color-8); -} -.ap-player .bg-8 { - --bg: var(--term-color-8); -} -.ap-player .fg-9 { - --fg: var(--term-color-9); -} -.ap-player .bg-9 { - --bg: var(--term-color-9); -} -.ap-player .fg-10 { - --fg: var(--term-color-10); -} -.ap-player .bg-10 { - --bg: var(--term-color-10); -} -.ap-player .fg-11 { - --fg: var(--term-color-11); -} -.ap-player .bg-11 { - --bg: var(--term-color-11); -} -.ap-player .fg-12 { - --fg: var(--term-color-12); -} -.ap-player .bg-12 { - --bg: var(--term-color-12); -} -.ap-player .fg-13 { - --fg: var(--term-color-13); -} -.ap-player .bg-13 { - --bg: var(--term-color-13); -} -.ap-player .fg-14 { - --fg: var(--term-color-14); -} -.ap-player .bg-14 { - --bg: var(--term-color-14); -} -.ap-player .fg-15 { - --fg: var(--term-color-15); -} -.ap-player .bg-15 { - --bg: var(--term-color-15); -} -.ap-player .fg-8, -.ap-player .fg-9, -.ap-player .fg-10, -.ap-player .fg-11, -.ap-player .fg-12, -.ap-player .fg-13, -.ap-player .fg-14, -.ap-player .fg-15 { - font-weight: bold; -} -pre.ap-terminal { - box-sizing: content-box; - overflow: hidden; - padding: 0; - margin: 0px; - display: block; - white-space: pre; - word-wrap: normal; - word-break: normal; - border-radius: 0; - border-style: solid; - cursor: text; - border-width: 0.75em; - color: var(--term-color-foreground); - background-color: var(--term-color-background); - border-color: var(--term-color-background); - outline: none; - line-height: var(--term-line-height); - font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; - font-variant-ligatures: none; -} -pre.ap-terminal .ap-line { - letter-spacing: normal; - overflow: hidden; -} -pre.ap-terminal .ap-line span { - padding: 0; - display: inline-block; - height: 100%; -} -pre.ap-terminal .ap-line { - display: block; - width: 100%; - height: var(--term-line-height); - position: relative; -} -pre.ap-terminal .ap-line span { - position: absolute; - left: calc(100% * var(--offset) / var(--term-cols)); - color: var(--fg); - background-color: var(--bg); -} -pre.ap-terminal .ap-line .ap-inverse { - color: var(--bg); - background-color: var(--fg); -} -pre.ap-terminal .ap-line .cp-2580 { - border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2581 { - border-bottom: calc(0.125 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2582 { - border-bottom: calc(0.25 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2583 { - border-bottom: calc(0.375 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2584 { - border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2585 { - border-bottom: calc(0.625 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2586 { - border-bottom: calc(0.75 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2587 { - border-bottom: calc(0.875 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2588 { - background-color: var(--fg); -} -pre.ap-terminal .ap-line .cp-2589 { - border-left: 0.875ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258a { - border-left: 0.75ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258b { - border-left: 0.625ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258c { - border-left: 0.5ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258d { - border-left: 0.375ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258e { - border-left: 0.25ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-258f { - border-left: 0.125ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2590 { - border-right: 0.5ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2591 { - background-color: color-mix(in srgb, var(--fg) 25%, var(--bg)); -} -pre.ap-terminal .ap-line .cp-2592 { - background-color: color-mix(in srgb, var(--fg) 50%, var(--bg)); -} -pre.ap-terminal .ap-line .cp-2593 { - background-color: color-mix(in srgb, var(--fg) 75%, var(--bg)); -} -pre.ap-terminal .ap-line .cp-2594 { - border-top: calc(0.125 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2595 { - border-right: 0.125ch solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2596 { - border-right: 0.5ch solid var(--bg); - border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); - background-color: var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2597 { - border-left: 0.5ch solid var(--bg); - border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); - background-color: var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2598 { - border-right: 0.5ch solid var(--bg); - border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); - background-color: var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-2599 { - border-left: 0.5ch solid var(--fg); - border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259a { - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259a::before, -pre.ap-terminal .ap-line .cp-259a::after { - content: ''; - position: absolute; - width: 0.5ch; - height: calc(0.5 * var(--term-line-height)); - background-color: var(--fg); -} -pre.ap-terminal .ap-line .cp-259a::before { - top: 0; - left: 0; -} -pre.ap-terminal .ap-line .cp-259a::after { - bottom: 0; - right: 0; -} -pre.ap-terminal .ap-line .cp-259b { - border-left: 0.5ch solid var(--fg); - border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259c { - border-right: 0.5ch solid var(--fg); - border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259d { - border-left: 0.5ch solid var(--bg); - border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); - background-color: var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259e { - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-259e::before, -pre.ap-terminal .ap-line .cp-259e::after { - content: ''; - position: absolute; - width: 0.5ch; - height: calc(0.5 * var(--term-line-height)); - background-color: var(--fg); -} -pre.ap-terminal .ap-line .cp-259e::before { - top: 0; - right: 0; -} -pre.ap-terminal .ap-line .cp-259e::after { - bottom: 0; - left: 0; -} -pre.ap-terminal .ap-line .cp-259f { - border-right: 0.5ch solid var(--fg); - border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-e0b0 { - border-left: 1ch solid var(--fg); - border-top: calc(0.5 * var(--term-line-height)) solid transparent; - border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; - box-sizing: border-box; -} -pre.ap-terminal .ap-line .cp-e0b2 { - border-right: 1ch solid var(--fg); - border-top: calc(0.5 * var(--term-line-height)) solid transparent; - border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; - box-sizing: border-box; -} -pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor { - color: var(--bg); - background-color: var(--fg); - border-radius: 0.05em; -} -pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor.ap-inverse { - color: var(--fg); - background-color: var(--bg); -} -pre.ap-terminal:not(.ap-blink) .ap-line .ap-blink { - color: transparent; - border-color: transparent; -} -pre.ap-terminal .ap-bright { - font-weight: bold; -} -pre.ap-terminal .ap-faint { - opacity: 0.5; -} -pre.ap-terminal .ap-underline { - text-decoration: underline; -} -pre.ap-terminal .ap-italic { - font-style: italic; -} -pre.ap-terminal .ap-strikethrough { - text-decoration: line-through; -} -.ap-line span { - --fg: var(--term-color-foreground); - --bg: var(--term-color-background); -} -div.ap-player div.ap-control-bar { - width: 100%; - height: 32px; - display: flex; - justify-content: space-between; - align-items: stretch; - color: var(--term-color-foreground); - box-sizing: content-box; - line-height: 1; - position: absolute; - bottom: 0; - left: 0; - opacity: 0; - transition: opacity 0.15s linear; - user-select: none; - border-top: 2px solid color-mix(in oklab, var(--term-color-background) 80%, var(--term-color-foreground)); - z-index: 30; -} -div.ap-player div.ap-control-bar * { - box-sizing: inherit; -} -div.ap-control-bar svg.ap-icon path { - fill: var(--term-color-foreground); -} -div.ap-control-bar span.ap-button { - display: flex; - flex: 0 0 auto; - cursor: pointer; -} -div.ap-control-bar span.ap-playback-button { - width: 12px; - height: 12px; - padding: 10px; -} -div.ap-control-bar span.ap-playback-button svg { - height: 12px; - width: 12px; -} -div.ap-control-bar span.ap-timer { - display: flex; - flex: 0 0 auto; - min-width: 50px; - margin: 0 10px; - height: 100%; - text-align: center; - font-size: 13px; - line-height: 100%; - cursor: default; -} -div.ap-control-bar span.ap-timer span { - font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; - font-size: inherit; - font-weight: 600; - margin: auto; -} -div.ap-control-bar span.ap-timer .ap-time-remaining { - display: none; -} -div.ap-control-bar span.ap-timer:hover .ap-time-elapsed { - display: none; -} -div.ap-control-bar span.ap-timer:hover .ap-time-remaining { - display: flex; -} -div.ap-control-bar .ap-progressbar { - display: block; - flex: 1 1 auto; - height: 100%; - padding: 0 10px; -} -div.ap-control-bar .ap-progressbar .ap-bar { - display: block; - position: relative; - cursor: default; - height: 100%; - font-size: 0; -} -div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter { - display: block; - position: absolute; - top: 15px; - left: 0; - right: 0; - height: 3px; -} -div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-empty { - background-color: color-mix(in oklab, var(--term-color-foreground) 20%, var(--term-color-background)); -} -div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full { - width: 100%; - transform-origin: left center; - background-color: var(--term-color-foreground); - border-radius: 3px; -} -div.ap-control-bar.ap-seekable .ap-progressbar .ap-bar { - cursor: pointer; -} -div.ap-control-bar .ap-fullscreen-button { - width: 14px; - height: 14px; - padding: 9px; -} -div.ap-control-bar .ap-fullscreen-button svg { - width: 14px; - height: 14px; -} -div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-on { - display: inline; -} -div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-off { - display: none; -} -div.ap-control-bar .ap-fullscreen-button .ap-tooltip { - right: 5px; - left: initial; - transform: none; -} -div.ap-control-bar .ap-kbd-button { - height: 14px; - padding: 9px; - margin: 0 4px; -} -div.ap-control-bar .ap-kbd-button svg { - width: 26px; - height: 14px; -} -div.ap-control-bar .ap-kbd-button .ap-tooltip { - right: 5px; - left: initial; - transform: none; -} -div.ap-wrapper.ap-hud .ap-control-bar { - opacity: 1; -} -div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-on { - display: none; -} -div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-off { - display: inline; -} -span.ap-progressbar span.ap-marker-container { - display: block; - top: 0; - bottom: 0; - width: 21px; - position: absolute; - margin-left: -10px; -} -span.ap-marker-container span.ap-marker { - display: block; - top: 13px; - bottom: 12px; - left: 7px; - right: 7px; - background-color: color-mix(in oklab, var(--term-color-foreground) 33%, var(--term-color-background)); - position: absolute; - transition: top 0.1s, bottom 0.1s, left 0.1s, right 0.1s, background-color 0.1s; - border-radius: 50%; -} -span.ap-marker-container span.ap-marker.ap-marker-past { - background-color: var(--term-color-foreground); -} -span.ap-marker-container span.ap-marker:hover, -span.ap-marker-container:hover span.ap-marker { - background-color: var(--term-color-foreground); - top: 11px; - bottom: 10px; - left: 5px; - right: 5px; -} -.ap-tooltip-container span.ap-tooltip { - visibility: hidden; - background-color: var(--term-color-foreground); - color: var(--term-color-background); - font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; - font-weight: bold; - text-align: center; - padding: 0 0.5em; - border-radius: 4px; - position: absolute; - z-index: 1; - white-space: nowrap; - /* Prevents the text from wrapping and makes sure the tooltip width adapts to the text length */ - font-size: 13px; - line-height: 2em; - bottom: 100%; - left: 50%; - transform: translateX(-50%); -} -.ap-tooltip-container:hover span.ap-tooltip { - visibility: visible; -} -.ap-player .ap-overlay { - z-index: 10; - background-repeat: no-repeat; - background-position: center; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - justify-content: center; - align-items: center; -} -.ap-player .ap-overlay-start { - cursor: pointer; -} -.ap-player .ap-overlay-start .ap-play-button { - font-size: 0px; - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - text-align: center; - color: white; - height: 80px; - max-height: 66%; - margin: auto; -} -.ap-player .ap-overlay-start .ap-play-button div { - height: 100%; -} -.ap-player .ap-overlay-start .ap-play-button div span { - height: 100%; - display: block; -} -.ap-player .ap-overlay-start .ap-play-button div span svg { - height: 100%; -} -.ap-player .ap-overlay-start .ap-play-button svg { - filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.4)); -} -.ap-player .ap-overlay-loading .ap-loader { - width: 48px; - height: 48px; - border-radius: 50%; - display: inline-block; - position: relative; - border: 10px solid; - border-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.5) rgba(255, 255, 255, 0.7) #ffffff; - border-color: color-mix(in srgb, var(--term-color-foreground) 30%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 50%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 70%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 100%, var(--term-color-background)); - box-sizing: border-box; - animation: ap-loader-rotation 1s linear infinite; -} -.ap-player .ap-overlay-info { - background-color: var(--term-color-background); -} -.ap-player .ap-overlay-info span { - font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; - font-variant-ligatures: none; - font-size: 2em; - color: var(--term-color-foreground); -} -.ap-player .ap-overlay-info span .ap-line { - letter-spacing: normal; - overflow: hidden; -} -.ap-player .ap-overlay-info span .ap-line span { - padding: 0; - display: inline-block; - height: 100%; -} -.ap-player .ap-overlay-help { - background-color: rgba(0, 0, 0, 0.8); - container-type: inline-size; -} -.ap-player .ap-overlay-help > div { - font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; - font-variant-ligatures: none; - max-width: 85%; - max-height: 85%; - font-size: 18px; - color: var(--term-color-foreground); - box-sizing: border-box; - margin-bottom: 32px; -} -.ap-player .ap-overlay-help > div .ap-line { - letter-spacing: normal; - overflow: hidden; -} -.ap-player .ap-overlay-help > div .ap-line span { - padding: 0; - display: inline-block; - height: 100%; -} -.ap-player .ap-overlay-help > div div { - padding: calc(min(4cqw, 40px)); - font-size: calc(min(1.9cqw, 18px)); - background-color: var(--term-color-background); - border: 1px solid color-mix(in oklab, var(--term-color-background) 90%, var(--term-color-foreground)); - border-radius: 6px; -} -.ap-player .ap-overlay-help > div div p { - font-weight: bold; - margin: 0 0 2em 0; -} -.ap-player .ap-overlay-help > div div ul { - list-style: none; - padding: 0; -} -.ap-player .ap-overlay-help > div div ul li { - margin: 0 0 0.75em 0; -} -.ap-player .ap-overlay-help > div div kbd { - color: var(--term-color-background); - background-color: var(--term-color-foreground); - padding: 0.2em 0.5em; - border-radius: 0.2em; - font-family: inherit; - font-size: 0.85em; - border: none; - margin: 0; -} -.ap-player .ap-overlay-error span { - font-size: 8em; -} -@keyframes ap-loader-rotation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} -.ap-terminal .fg-16 { - --fg: #000000; -} -.ap-terminal .bg-16 { - --bg: #000000; -} -.ap-terminal .fg-17 { - --fg: #00005f; -} -.ap-terminal .bg-17 { - --bg: #00005f; -} -.ap-terminal .fg-18 { - --fg: #000087; -} -.ap-terminal .bg-18 { - --bg: #000087; -} -.ap-terminal .fg-19 { - --fg: #0000af; -} -.ap-terminal .bg-19 { - --bg: #0000af; -} -.ap-terminal .fg-20 { - --fg: #0000d7; -} -.ap-terminal .bg-20 { - --bg: #0000d7; -} -.ap-terminal .fg-21 { - --fg: #0000ff; -} -.ap-terminal .bg-21 { - --bg: #0000ff; -} -.ap-terminal .fg-22 { - --fg: #005f00; -} -.ap-terminal .bg-22 { - --bg: #005f00; -} -.ap-terminal .fg-23 { - --fg: #005f5f; -} -.ap-terminal .bg-23 { - --bg: #005f5f; -} -.ap-terminal .fg-24 { - --fg: #005f87; -} -.ap-terminal .bg-24 { - --bg: #005f87; -} -.ap-terminal .fg-25 { - --fg: #005faf; -} -.ap-terminal .bg-25 { - --bg: #005faf; -} -.ap-terminal .fg-26 { - --fg: #005fd7; -} -.ap-terminal .bg-26 { - --bg: #005fd7; -} -.ap-terminal .fg-27 { - --fg: #005fff; -} -.ap-terminal .bg-27 { - --bg: #005fff; -} -.ap-terminal .fg-28 { - --fg: #008700; -} -.ap-terminal .bg-28 { - --bg: #008700; -} -.ap-terminal .fg-29 { - --fg: #00875f; -} -.ap-terminal .bg-29 { - --bg: #00875f; -} -.ap-terminal .fg-30 { - --fg: #008787; -} -.ap-terminal .bg-30 { - --bg: #008787; -} -.ap-terminal .fg-31 { - --fg: #0087af; -} -.ap-terminal .bg-31 { - --bg: #0087af; -} -.ap-terminal .fg-32 { - --fg: #0087d7; -} -.ap-terminal .bg-32 { - --bg: #0087d7; -} -.ap-terminal .fg-33 { - --fg: #0087ff; -} -.ap-terminal .bg-33 { - --bg: #0087ff; -} -.ap-terminal .fg-34 { - --fg: #00af00; -} -.ap-terminal .bg-34 { - --bg: #00af00; -} -.ap-terminal .fg-35 { - --fg: #00af5f; -} -.ap-terminal .bg-35 { - --bg: #00af5f; -} -.ap-terminal .fg-36 { - --fg: #00af87; -} -.ap-terminal .bg-36 { - --bg: #00af87; -} -.ap-terminal .fg-37 { - --fg: #00afaf; -} -.ap-terminal .bg-37 { - --bg: #00afaf; -} -.ap-terminal .fg-38 { - --fg: #00afd7; -} -.ap-terminal .bg-38 { - --bg: #00afd7; -} -.ap-terminal .fg-39 { - --fg: #00afff; -} -.ap-terminal .bg-39 { - --bg: #00afff; -} -.ap-terminal .fg-40 { - --fg: #00d700; -} -.ap-terminal .bg-40 { - --bg: #00d700; -} -.ap-terminal .fg-41 { - --fg: #00d75f; -} -.ap-terminal .bg-41 { - --bg: #00d75f; -} -.ap-terminal .fg-42 { - --fg: #00d787; -} -.ap-terminal .bg-42 { - --bg: #00d787; -} -.ap-terminal .fg-43 { - --fg: #00d7af; -} -.ap-terminal .bg-43 { - --bg: #00d7af; -} -.ap-terminal .fg-44 { - --fg: #00d7d7; -} -.ap-terminal .bg-44 { - --bg: #00d7d7; -} -.ap-terminal .fg-45 { - --fg: #00d7ff; -} -.ap-terminal .bg-45 { - --bg: #00d7ff; -} -.ap-terminal .fg-46 { - --fg: #00ff00; -} -.ap-terminal .bg-46 { - --bg: #00ff00; -} -.ap-terminal .fg-47 { - --fg: #00ff5f; -} -.ap-terminal .bg-47 { - --bg: #00ff5f; -} -.ap-terminal .fg-48 { - --fg: #00ff87; -} -.ap-terminal .bg-48 { - --bg: #00ff87; -} -.ap-terminal .fg-49 { - --fg: #00ffaf; -} -.ap-terminal .bg-49 { - --bg: #00ffaf; -} -.ap-terminal .fg-50 { - --fg: #00ffd7; -} -.ap-terminal .bg-50 { - --bg: #00ffd7; -} -.ap-terminal .fg-51 { - --fg: #00ffff; -} -.ap-terminal .bg-51 { - --bg: #00ffff; -} -.ap-terminal .fg-52 { - --fg: #5f0000; -} -.ap-terminal .bg-52 { - --bg: #5f0000; -} -.ap-terminal .fg-53 { - --fg: #5f005f; -} -.ap-terminal .bg-53 { - --bg: #5f005f; -} -.ap-terminal .fg-54 { - --fg: #5f0087; -} -.ap-terminal .bg-54 { - --bg: #5f0087; -} -.ap-terminal .fg-55 { - --fg: #5f00af; -} -.ap-terminal .bg-55 { - --bg: #5f00af; -} -.ap-terminal .fg-56 { - --fg: #5f00d7; -} -.ap-terminal .bg-56 { - --bg: #5f00d7; -} -.ap-terminal .fg-57 { - --fg: #5f00ff; -} -.ap-terminal .bg-57 { - --bg: #5f00ff; -} -.ap-terminal .fg-58 { - --fg: #5f5f00; -} -.ap-terminal .bg-58 { - --bg: #5f5f00; -} -.ap-terminal .fg-59 { - --fg: #5f5f5f; -} -.ap-terminal .bg-59 { - --bg: #5f5f5f; -} -.ap-terminal .fg-60 { - --fg: #5f5f87; -} -.ap-terminal .bg-60 { - --bg: #5f5f87; -} -.ap-terminal .fg-61 { - --fg: #5f5faf; -} -.ap-terminal .bg-61 { - --bg: #5f5faf; -} -.ap-terminal .fg-62 { - --fg: #5f5fd7; -} -.ap-terminal .bg-62 { - --bg: #5f5fd7; -} -.ap-terminal .fg-63 { - --fg: #5f5fff; -} -.ap-terminal .bg-63 { - --bg: #5f5fff; -} -.ap-terminal .fg-64 { - --fg: #5f8700; -} -.ap-terminal .bg-64 { - --bg: #5f8700; -} -.ap-terminal .fg-65 { - --fg: #5f875f; -} -.ap-terminal .bg-65 { - --bg: #5f875f; -} -.ap-terminal .fg-66 { - --fg: #5f8787; -} -.ap-terminal .bg-66 { - --bg: #5f8787; -} -.ap-terminal .fg-67 { - --fg: #5f87af; -} -.ap-terminal .bg-67 { - --bg: #5f87af; -} -.ap-terminal .fg-68 { - --fg: #5f87d7; -} -.ap-terminal .bg-68 { - --bg: #5f87d7; -} -.ap-terminal .fg-69 { - --fg: #5f87ff; -} -.ap-terminal .bg-69 { - --bg: #5f87ff; -} -.ap-terminal .fg-70 { - --fg: #5faf00; -} -.ap-terminal .bg-70 { - --bg: #5faf00; -} -.ap-terminal .fg-71 { - --fg: #5faf5f; -} -.ap-terminal .bg-71 { - --bg: #5faf5f; -} -.ap-terminal .fg-72 { - --fg: #5faf87; -} -.ap-terminal .bg-72 { - --bg: #5faf87; -} -.ap-terminal .fg-73 { - --fg: #5fafaf; -} -.ap-terminal .bg-73 { - --bg: #5fafaf; -} -.ap-terminal .fg-74 { - --fg: #5fafd7; -} -.ap-terminal .bg-74 { - --bg: #5fafd7; -} -.ap-terminal .fg-75 { - --fg: #5fafff; -} -.ap-terminal .bg-75 { - --bg: #5fafff; -} -.ap-terminal .fg-76 { - --fg: #5fd700; -} -.ap-terminal .bg-76 { - --bg: #5fd700; -} -.ap-terminal .fg-77 { - --fg: #5fd75f; -} -.ap-terminal .bg-77 { - --bg: #5fd75f; -} -.ap-terminal .fg-78 { - --fg: #5fd787; -} -.ap-terminal .bg-78 { - --bg: #5fd787; -} -.ap-terminal .fg-79 { - --fg: #5fd7af; -} -.ap-terminal .bg-79 { - --bg: #5fd7af; -} -.ap-terminal .fg-80 { - --fg: #5fd7d7; -} -.ap-terminal .bg-80 { - --bg: #5fd7d7; -} -.ap-terminal .fg-81 { - --fg: #5fd7ff; -} -.ap-terminal .bg-81 { - --bg: #5fd7ff; -} -.ap-terminal .fg-82 { - --fg: #5fff00; -} -.ap-terminal .bg-82 { - --bg: #5fff00; -} -.ap-terminal .fg-83 { - --fg: #5fff5f; -} -.ap-terminal .bg-83 { - --bg: #5fff5f; -} -.ap-terminal .fg-84 { - --fg: #5fff87; -} -.ap-terminal .bg-84 { - --bg: #5fff87; -} -.ap-terminal .fg-85 { - --fg: #5fffaf; -} -.ap-terminal .bg-85 { - --bg: #5fffaf; -} -.ap-terminal .fg-86 { - --fg: #5fffd7; -} -.ap-terminal .bg-86 { - --bg: #5fffd7; -} -.ap-terminal .fg-87 { - --fg: #5fffff; -} -.ap-terminal .bg-87 { - --bg: #5fffff; -} -.ap-terminal .fg-88 { - --fg: #870000; -} -.ap-terminal .bg-88 { - --bg: #870000; -} -.ap-terminal .fg-89 { - --fg: #87005f; -} -.ap-terminal .bg-89 { - --bg: #87005f; -} -.ap-terminal .fg-90 { - --fg: #870087; -} -.ap-terminal .bg-90 { - --bg: #870087; -} -.ap-terminal .fg-91 { - --fg: #8700af; -} -.ap-terminal .bg-91 { - --bg: #8700af; -} -.ap-terminal .fg-92 { - --fg: #8700d7; -} -.ap-terminal .bg-92 { - --bg: #8700d7; -} -.ap-terminal .fg-93 { - --fg: #8700ff; -} -.ap-terminal .bg-93 { - --bg: #8700ff; -} -.ap-terminal .fg-94 { - --fg: #875f00; -} -.ap-terminal .bg-94 { - --bg: #875f00; -} -.ap-terminal .fg-95 { - --fg: #875f5f; -} -.ap-terminal .bg-95 { - --bg: #875f5f; -} -.ap-terminal .fg-96 { - --fg: #875f87; -} -.ap-terminal .bg-96 { - --bg: #875f87; -} -.ap-terminal .fg-97 { - --fg: #875faf; -} -.ap-terminal .bg-97 { - --bg: #875faf; -} -.ap-terminal .fg-98 { - --fg: #875fd7; -} -.ap-terminal .bg-98 { - --bg: #875fd7; -} -.ap-terminal .fg-99 { - --fg: #875fff; -} -.ap-terminal .bg-99 { - --bg: #875fff; -} -.ap-terminal .fg-100 { - --fg: #878700; -} -.ap-terminal .bg-100 { - --bg: #878700; -} -.ap-terminal .fg-101 { - --fg: #87875f; -} -.ap-terminal .bg-101 { - --bg: #87875f; -} -.ap-terminal .fg-102 { - --fg: #878787; -} -.ap-terminal .bg-102 { - --bg: #878787; -} -.ap-terminal .fg-103 { - --fg: #8787af; -} -.ap-terminal .bg-103 { - --bg: #8787af; -} -.ap-terminal .fg-104 { - --fg: #8787d7; -} -.ap-terminal .bg-104 { - --bg: #8787d7; -} -.ap-terminal .fg-105 { - --fg: #8787ff; -} -.ap-terminal .bg-105 { - --bg: #8787ff; -} -.ap-terminal .fg-106 { - --fg: #87af00; -} -.ap-terminal .bg-106 { - --bg: #87af00; -} -.ap-terminal .fg-107 { - --fg: #87af5f; -} -.ap-terminal .bg-107 { - --bg: #87af5f; -} -.ap-terminal .fg-108 { - --fg: #87af87; -} -.ap-terminal .bg-108 { - --bg: #87af87; -} -.ap-terminal .fg-109 { - --fg: #87afaf; -} -.ap-terminal .bg-109 { - --bg: #87afaf; -} -.ap-terminal .fg-110 { - --fg: #87afd7; -} -.ap-terminal .bg-110 { - --bg: #87afd7; -} -.ap-terminal .fg-111 { - --fg: #87afff; -} -.ap-terminal .bg-111 { - --bg: #87afff; -} -.ap-terminal .fg-112 { - --fg: #87d700; -} -.ap-terminal .bg-112 { - --bg: #87d700; -} -.ap-terminal .fg-113 { - --fg: #87d75f; -} -.ap-terminal .bg-113 { - --bg: #87d75f; -} -.ap-terminal .fg-114 { - --fg: #87d787; -} -.ap-terminal .bg-114 { - --bg: #87d787; -} -.ap-terminal .fg-115 { - --fg: #87d7af; -} -.ap-terminal .bg-115 { - --bg: #87d7af; -} -.ap-terminal .fg-116 { - --fg: #87d7d7; -} -.ap-terminal .bg-116 { - --bg: #87d7d7; -} -.ap-terminal .fg-117 { - --fg: #87d7ff; -} -.ap-terminal .bg-117 { - --bg: #87d7ff; -} -.ap-terminal .fg-118 { - --fg: #87ff00; -} -.ap-terminal .bg-118 { - --bg: #87ff00; -} -.ap-terminal .fg-119 { - --fg: #87ff5f; -} -.ap-terminal .bg-119 { - --bg: #87ff5f; -} -.ap-terminal .fg-120 { - --fg: #87ff87; -} -.ap-terminal .bg-120 { - --bg: #87ff87; -} -.ap-terminal .fg-121 { - --fg: #87ffaf; -} -.ap-terminal .bg-121 { - --bg: #87ffaf; -} -.ap-terminal .fg-122 { - --fg: #87ffd7; -} -.ap-terminal .bg-122 { - --bg: #87ffd7; -} -.ap-terminal .fg-123 { - --fg: #87ffff; -} -.ap-terminal .bg-123 { - --bg: #87ffff; -} -.ap-terminal .fg-124 { - --fg: #af0000; -} -.ap-terminal .bg-124 { - --bg: #af0000; -} -.ap-terminal .fg-125 { - --fg: #af005f; -} -.ap-terminal .bg-125 { - --bg: #af005f; -} -.ap-terminal .fg-126 { - --fg: #af0087; -} -.ap-terminal .bg-126 { - --bg: #af0087; -} -.ap-terminal .fg-127 { - --fg: #af00af; -} -.ap-terminal .bg-127 { - --bg: #af00af; -} -.ap-terminal .fg-128 { - --fg: #af00d7; -} -.ap-terminal .bg-128 { - --bg: #af00d7; -} -.ap-terminal .fg-129 { - --fg: #af00ff; -} -.ap-terminal .bg-129 { - --bg: #af00ff; -} -.ap-terminal .fg-130 { - --fg: #af5f00; -} -.ap-terminal .bg-130 { - --bg: #af5f00; -} -.ap-terminal .fg-131 { - --fg: #af5f5f; -} -.ap-terminal .bg-131 { - --bg: #af5f5f; -} -.ap-terminal .fg-132 { - --fg: #af5f87; -} -.ap-terminal .bg-132 { - --bg: #af5f87; -} -.ap-terminal .fg-133 { - --fg: #af5faf; -} -.ap-terminal .bg-133 { - --bg: #af5faf; -} -.ap-terminal .fg-134 { - --fg: #af5fd7; -} -.ap-terminal .bg-134 { - --bg: #af5fd7; -} -.ap-terminal .fg-135 { - --fg: #af5fff; -} -.ap-terminal .bg-135 { - --bg: #af5fff; -} -.ap-terminal .fg-136 { - --fg: #af8700; -} -.ap-terminal .bg-136 { - --bg: #af8700; -} -.ap-terminal .fg-137 { - --fg: #af875f; -} -.ap-terminal .bg-137 { - --bg: #af875f; -} -.ap-terminal .fg-138 { - --fg: #af8787; -} -.ap-terminal .bg-138 { - --bg: #af8787; -} -.ap-terminal .fg-139 { - --fg: #af87af; -} -.ap-terminal .bg-139 { - --bg: #af87af; -} -.ap-terminal .fg-140 { - --fg: #af87d7; -} -.ap-terminal .bg-140 { - --bg: #af87d7; -} -.ap-terminal .fg-141 { - --fg: #af87ff; -} -.ap-terminal .bg-141 { - --bg: #af87ff; -} -.ap-terminal .fg-142 { - --fg: #afaf00; -} -.ap-terminal .bg-142 { - --bg: #afaf00; -} -.ap-terminal .fg-143 { - --fg: #afaf5f; -} -.ap-terminal .bg-143 { - --bg: #afaf5f; -} -.ap-terminal .fg-144 { - --fg: #afaf87; -} -.ap-terminal .bg-144 { - --bg: #afaf87; -} -.ap-terminal .fg-145 { - --fg: #afafaf; -} -.ap-terminal .bg-145 { - --bg: #afafaf; -} -.ap-terminal .fg-146 { - --fg: #afafd7; -} -.ap-terminal .bg-146 { - --bg: #afafd7; -} -.ap-terminal .fg-147 { - --fg: #afafff; -} -.ap-terminal .bg-147 { - --bg: #afafff; -} -.ap-terminal .fg-148 { - --fg: #afd700; -} -.ap-terminal .bg-148 { - --bg: #afd700; -} -.ap-terminal .fg-149 { - --fg: #afd75f; -} -.ap-terminal .bg-149 { - --bg: #afd75f; -} -.ap-terminal .fg-150 { - --fg: #afd787; -} -.ap-terminal .bg-150 { - --bg: #afd787; -} -.ap-terminal .fg-151 { - --fg: #afd7af; -} -.ap-terminal .bg-151 { - --bg: #afd7af; -} -.ap-terminal .fg-152 { - --fg: #afd7d7; -} -.ap-terminal .bg-152 { - --bg: #afd7d7; -} -.ap-terminal .fg-153 { - --fg: #afd7ff; -} -.ap-terminal .bg-153 { - --bg: #afd7ff; -} -.ap-terminal .fg-154 { - --fg: #afff00; -} -.ap-terminal .bg-154 { - --bg: #afff00; -} -.ap-terminal .fg-155 { - --fg: #afff5f; -} -.ap-terminal .bg-155 { - --bg: #afff5f; -} -.ap-terminal .fg-156 { - --fg: #afff87; -} -.ap-terminal .bg-156 { - --bg: #afff87; -} -.ap-terminal .fg-157 { - --fg: #afffaf; -} -.ap-terminal .bg-157 { - --bg: #afffaf; -} -.ap-terminal .fg-158 { - --fg: #afffd7; -} -.ap-terminal .bg-158 { - --bg: #afffd7; -} -.ap-terminal .fg-159 { - --fg: #afffff; -} -.ap-terminal .bg-159 { - --bg: #afffff; -} -.ap-terminal .fg-160 { - --fg: #d70000; -} -.ap-terminal .bg-160 { - --bg: #d70000; -} -.ap-terminal .fg-161 { - --fg: #d7005f; -} -.ap-terminal .bg-161 { - --bg: #d7005f; -} -.ap-terminal .fg-162 { - --fg: #d70087; -} -.ap-terminal .bg-162 { - --bg: #d70087; -} -.ap-terminal .fg-163 { - --fg: #d700af; -} -.ap-terminal .bg-163 { - --bg: #d700af; -} -.ap-terminal .fg-164 { - --fg: #d700d7; -} -.ap-terminal .bg-164 { - --bg: #d700d7; -} -.ap-terminal .fg-165 { - --fg: #d700ff; -} -.ap-terminal .bg-165 { - --bg: #d700ff; -} -.ap-terminal .fg-166 { - --fg: #d75f00; -} -.ap-terminal .bg-166 { - --bg: #d75f00; -} -.ap-terminal .fg-167 { - --fg: #d75f5f; -} -.ap-terminal .bg-167 { - --bg: #d75f5f; -} -.ap-terminal .fg-168 { - --fg: #d75f87; -} -.ap-terminal .bg-168 { - --bg: #d75f87; -} -.ap-terminal .fg-169 { - --fg: #d75faf; -} -.ap-terminal .bg-169 { - --bg: #d75faf; -} -.ap-terminal .fg-170 { - --fg: #d75fd7; -} -.ap-terminal .bg-170 { - --bg: #d75fd7; -} -.ap-terminal .fg-171 { - --fg: #d75fff; -} -.ap-terminal .bg-171 { - --bg: #d75fff; -} -.ap-terminal .fg-172 { - --fg: #d78700; -} -.ap-terminal .bg-172 { - --bg: #d78700; -} -.ap-terminal .fg-173 { - --fg: #d7875f; -} -.ap-terminal .bg-173 { - --bg: #d7875f; -} -.ap-terminal .fg-174 { - --fg: #d78787; -} -.ap-terminal .bg-174 { - --bg: #d78787; -} -.ap-terminal .fg-175 { - --fg: #d787af; -} -.ap-terminal .bg-175 { - --bg: #d787af; -} -.ap-terminal .fg-176 { - --fg: #d787d7; -} -.ap-terminal .bg-176 { - --bg: #d787d7; -} -.ap-terminal .fg-177 { - --fg: #d787ff; -} -.ap-terminal .bg-177 { - --bg: #d787ff; -} -.ap-terminal .fg-178 { - --fg: #d7af00; -} -.ap-terminal .bg-178 { - --bg: #d7af00; -} -.ap-terminal .fg-179 { - --fg: #d7af5f; -} -.ap-terminal .bg-179 { - --bg: #d7af5f; -} -.ap-terminal .fg-180 { - --fg: #d7af87; -} -.ap-terminal .bg-180 { - --bg: #d7af87; -} -.ap-terminal .fg-181 { - --fg: #d7afaf; -} -.ap-terminal .bg-181 { - --bg: #d7afaf; -} -.ap-terminal .fg-182 { - --fg: #d7afd7; -} -.ap-terminal .bg-182 { - --bg: #d7afd7; -} -.ap-terminal .fg-183 { - --fg: #d7afff; -} -.ap-terminal .bg-183 { - --bg: #d7afff; -} -.ap-terminal .fg-184 { - --fg: #d7d700; -} -.ap-terminal .bg-184 { - --bg: #d7d700; -} -.ap-terminal .fg-185 { - --fg: #d7d75f; -} -.ap-terminal .bg-185 { - --bg: #d7d75f; -} -.ap-terminal .fg-186 { - --fg: #d7d787; -} -.ap-terminal .bg-186 { - --bg: #d7d787; -} -.ap-terminal .fg-187 { - --fg: #d7d7af; -} -.ap-terminal .bg-187 { - --bg: #d7d7af; -} -.ap-terminal .fg-188 { - --fg: #d7d7d7; -} -.ap-terminal .bg-188 { - --bg: #d7d7d7; -} -.ap-terminal .fg-189 { - --fg: #d7d7ff; -} -.ap-terminal .bg-189 { - --bg: #d7d7ff; -} -.ap-terminal .fg-190 { - --fg: #d7ff00; -} -.ap-terminal .bg-190 { - --bg: #d7ff00; -} -.ap-terminal .fg-191 { - --fg: #d7ff5f; -} -.ap-terminal .bg-191 { - --bg: #d7ff5f; -} -.ap-terminal .fg-192 { - --fg: #d7ff87; -} -.ap-terminal .bg-192 { - --bg: #d7ff87; -} -.ap-terminal .fg-193 { - --fg: #d7ffaf; -} -.ap-terminal .bg-193 { - --bg: #d7ffaf; -} -.ap-terminal .fg-194 { - --fg: #d7ffd7; -} -.ap-terminal .bg-194 { - --bg: #d7ffd7; -} -.ap-terminal .fg-195 { - --fg: #d7ffff; -} -.ap-terminal .bg-195 { - --bg: #d7ffff; -} -.ap-terminal .fg-196 { - --fg: #ff0000; -} -.ap-terminal .bg-196 { - --bg: #ff0000; -} -.ap-terminal .fg-197 { - --fg: #ff005f; -} -.ap-terminal .bg-197 { - --bg: #ff005f; -} -.ap-terminal .fg-198 { - --fg: #ff0087; -} -.ap-terminal .bg-198 { - --bg: #ff0087; -} -.ap-terminal .fg-199 { - --fg: #ff00af; -} -.ap-terminal .bg-199 { - --bg: #ff00af; -} -.ap-terminal .fg-200 { - --fg: #ff00d7; -} -.ap-terminal .bg-200 { - --bg: #ff00d7; -} -.ap-terminal .fg-201 { - --fg: #ff00ff; -} -.ap-terminal .bg-201 { - --bg: #ff00ff; -} -.ap-terminal .fg-202 { - --fg: #ff5f00; -} -.ap-terminal .bg-202 { - --bg: #ff5f00; -} -.ap-terminal .fg-203 { - --fg: #ff5f5f; -} -.ap-terminal .bg-203 { - --bg: #ff5f5f; -} -.ap-terminal .fg-204 { - --fg: #ff5f87; -} -.ap-terminal .bg-204 { - --bg: #ff5f87; -} -.ap-terminal .fg-205 { - --fg: #ff5faf; -} -.ap-terminal .bg-205 { - --bg: #ff5faf; -} -.ap-terminal .fg-206 { - --fg: #ff5fd7; -} -.ap-terminal .bg-206 { - --bg: #ff5fd7; -} -.ap-terminal .fg-207 { - --fg: #ff5fff; -} -.ap-terminal .bg-207 { - --bg: #ff5fff; -} -.ap-terminal .fg-208 { - --fg: #ff8700; -} -.ap-terminal .bg-208 { - --bg: #ff8700; -} -.ap-terminal .fg-209 { - --fg: #ff875f; -} -.ap-terminal .bg-209 { - --bg: #ff875f; -} -.ap-terminal .fg-210 { - --fg: #ff8787; -} -.ap-terminal .bg-210 { - --bg: #ff8787; -} -.ap-terminal .fg-211 { - --fg: #ff87af; -} -.ap-terminal .bg-211 { - --bg: #ff87af; -} -.ap-terminal .fg-212 { - --fg: #ff87d7; -} -.ap-terminal .bg-212 { - --bg: #ff87d7; -} -.ap-terminal .fg-213 { - --fg: #ff87ff; -} -.ap-terminal .bg-213 { - --bg: #ff87ff; -} -.ap-terminal .fg-214 { - --fg: #ffaf00; -} -.ap-terminal .bg-214 { - --bg: #ffaf00; -} -.ap-terminal .fg-215 { - --fg: #ffaf5f; -} -.ap-terminal .bg-215 { - --bg: #ffaf5f; -} -.ap-terminal .fg-216 { - --fg: #ffaf87; -} -.ap-terminal .bg-216 { - --bg: #ffaf87; -} -.ap-terminal .fg-217 { - --fg: #ffafaf; -} -.ap-terminal .bg-217 { - --bg: #ffafaf; -} -.ap-terminal .fg-218 { - --fg: #ffafd7; -} -.ap-terminal .bg-218 { - --bg: #ffafd7; -} -.ap-terminal .fg-219 { - --fg: #ffafff; -} -.ap-terminal .bg-219 { - --bg: #ffafff; -} -.ap-terminal .fg-220 { - --fg: #ffd700; -} -.ap-terminal .bg-220 { - --bg: #ffd700; -} -.ap-terminal .fg-221 { - --fg: #ffd75f; -} -.ap-terminal .bg-221 { - --bg: #ffd75f; -} -.ap-terminal .fg-222 { - --fg: #ffd787; -} -.ap-terminal .bg-222 { - --bg: #ffd787; -} -.ap-terminal .fg-223 { - --fg: #ffd7af; -} -.ap-terminal .bg-223 { - --bg: #ffd7af; -} -.ap-terminal .fg-224 { - --fg: #ffd7d7; -} -.ap-terminal .bg-224 { - --bg: #ffd7d7; -} -.ap-terminal .fg-225 { - --fg: #ffd7ff; -} -.ap-terminal .bg-225 { - --bg: #ffd7ff; -} -.ap-terminal .fg-226 { - --fg: #ffff00; -} -.ap-terminal .bg-226 { - --bg: #ffff00; -} -.ap-terminal .fg-227 { - --fg: #ffff5f; -} -.ap-terminal .bg-227 { - --bg: #ffff5f; -} -.ap-terminal .fg-228 { - --fg: #ffff87; -} -.ap-terminal .bg-228 { - --bg: #ffff87; -} -.ap-terminal .fg-229 { - --fg: #ffffaf; -} -.ap-terminal .bg-229 { - --bg: #ffffaf; -} -.ap-terminal .fg-230 { - --fg: #ffffd7; -} -.ap-terminal .bg-230 { - --bg: #ffffd7; -} -.ap-terminal .fg-231 { - --fg: #ffffff; -} -.ap-terminal .bg-231 { - --bg: #ffffff; -} -.ap-terminal .fg-232 { - --fg: #080808; -} -.ap-terminal .bg-232 { - --bg: #080808; -} -.ap-terminal .fg-233 { - --fg: #121212; -} -.ap-terminal .bg-233 { - --bg: #121212; -} -.ap-terminal .fg-234 { - --fg: #1c1c1c; -} -.ap-terminal .bg-234 { - --bg: #1c1c1c; -} -.ap-terminal .fg-235 { - --fg: #262626; -} -.ap-terminal .bg-235 { - --bg: #262626; -} -.ap-terminal .fg-236 { - --fg: #303030; -} -.ap-terminal .bg-236 { - --bg: #303030; -} -.ap-terminal .fg-237 { - --fg: #3a3a3a; -} -.ap-terminal .bg-237 { - --bg: #3a3a3a; -} -.ap-terminal .fg-238 { - --fg: #444444; -} -.ap-terminal .bg-238 { - --bg: #444444; -} -.ap-terminal .fg-239 { - --fg: #4e4e4e; -} -.ap-terminal .bg-239 { - --bg: #4e4e4e; -} -.ap-terminal .fg-240 { - --fg: #585858; -} -.ap-terminal .bg-240 { - --bg: #585858; -} -.ap-terminal .fg-241 { - --fg: #626262; -} -.ap-terminal .bg-241 { - --bg: #626262; -} -.ap-terminal .fg-242 { - --fg: #6c6c6c; -} -.ap-terminal .bg-242 { - --bg: #6c6c6c; -} -.ap-terminal .fg-243 { - --fg: #767676; -} -.ap-terminal .bg-243 { - --bg: #767676; -} -.ap-terminal .fg-244 { - --fg: #808080; -} -.ap-terminal .bg-244 { - --bg: #808080; -} -.ap-terminal .fg-245 { - --fg: #8a8a8a; -} -.ap-terminal .bg-245 { - --bg: #8a8a8a; -} -.ap-terminal .fg-246 { - --fg: #949494; -} -.ap-terminal .bg-246 { - --bg: #949494; -} -.ap-terminal .fg-247 { - --fg: #9e9e9e; -} -.ap-terminal .bg-247 { - --bg: #9e9e9e; -} -.ap-terminal .fg-248 { - --fg: #a8a8a8; -} -.ap-terminal .bg-248 { - --bg: #a8a8a8; -} -.ap-terminal .fg-249 { - --fg: #b2b2b2; -} -.ap-terminal .bg-249 { - --bg: #b2b2b2; -} -.ap-terminal .fg-250 { - --fg: #bcbcbc; -} -.ap-terminal .bg-250 { - --bg: #bcbcbc; -} -.ap-terminal .fg-251 { - --fg: #c6c6c6; -} -.ap-terminal .bg-251 { - --bg: #c6c6c6; -} -.ap-terminal .fg-252 { - --fg: #d0d0d0; -} -.ap-terminal .bg-252 { - --bg: #d0d0d0; -} -.ap-terminal .fg-253 { - --fg: #dadada; -} -.ap-terminal .bg-253 { - --bg: #dadada; -} -.ap-terminal .fg-254 { - --fg: #e4e4e4; -} -.ap-terminal .bg-254 { - --bg: #e4e4e4; -} -.ap-terminal .fg-255 { - --fg: #eeeeee; -} -.ap-terminal .bg-255 { - --bg: #eeeeee; -} -.asciinema-player-theme-asciinema { - --term-color-foreground: #cccccc; - --term-color-background: #121314; - --term-color-0: hsl(0, 0%, 0%); - --term-color-1: hsl(343, 70%, 55%); - --term-color-2: hsl(103, 70%, 44%); - --term-color-3: hsl(43, 70%, 55%); - --term-color-4: hsl(193, 70%, 49.5%); - --term-color-5: hsl(283, 70%, 60.5%); - --term-color-6: hsl(163, 70%, 60.5%); - --term-color-7: hsl(0, 0%, 85%); - --term-color-8: hsl(0, 0%, 30%); - --term-color-9: hsl(343, 70%, 55%); - --term-color-10: hsl(103, 70%, 44%); - --term-color-11: hsl(43, 70%, 55%); - --term-color-12: hsl(193, 70%, 49.5%); - --term-color-13: hsl(283, 70%, 60.5%); - --term-color-14: hsl(163, 70%, 60.5%); - --term-color-15: hsl(0, 0%, 100%); -} -/* - Based on Dracula: https://draculatheme.com - */ -.asciinema-player-theme-dracula { - --term-color-foreground: #f8f8f2; - --term-color-background: #282a36; - --term-color-0: #21222c; - --term-color-1: #ff5555; - --term-color-2: #50fa7b; - --term-color-3: #f1fa8c; - --term-color-4: #bd93f9; - --term-color-5: #ff79c6; - --term-color-6: #8be9fd; - --term-color-7: #f8f8f2; - --term-color-8: #6272a4; - --term-color-9: #ff6e6e; - --term-color-10: #69ff94; - --term-color-11: #ffffa5; - --term-color-12: #d6acff; - --term-color-13: #ff92df; - --term-color-14: #a4ffff; - --term-color-15: #ffffff; -} -/* Based on Monokai from base16 collection - https://github.com/chriskempson/base16 */ -.asciinema-player-theme-monokai { - --term-color-foreground: #f8f8f2; - --term-color-background: #272822; - --term-color-0: #272822; - --term-color-1: #f92672; - --term-color-2: #a6e22e; - --term-color-3: #f4bf75; - --term-color-4: #66d9ef; - --term-color-5: #ae81ff; - --term-color-6: #a1efe4; - --term-color-7: #f8f8f2; - --term-color-8: #75715e; - --term-color-15: #f9f8f5; -} -/* - Based on Nord: https://github.com/arcticicestudio/nord - Via: https://github.com/neilotoole/asciinema-theme-nord - */ -.asciinema-player-theme-nord { - --term-color-foreground: #eceff4; - --term-color-background: #2e3440; - --term-color-0: #3b4252; - --term-color-1: #bf616a; - --term-color-2: #a3be8c; - --term-color-3: #ebcb8b; - --term-color-4: #81a1c1; - --term-color-5: #b48ead; - --term-color-6: #88c0d0; - --term-color-7: #eceff4; -} -.asciinema-player-theme-seti { - --term-color-foreground: #cacecd; - --term-color-background: #111213; - --term-color-0: #323232; - --term-color-1: #c22832; - --term-color-2: #8ec43d; - --term-color-3: #e0c64f; - --term-color-4: #43a5d5; - --term-color-5: #8b57b5; - --term-color-6: #8ec43d; - --term-color-7: #eeeeee; - --term-color-15: #ffffff; -} -/* - Based on Solarized Dark: https://ethanschoonover.com/solarized/ - */ -.asciinema-player-theme-solarized-dark { - --term-color-foreground: #839496; - --term-color-background: #002b36; - --term-color-0: #073642; - --term-color-1: #dc322f; - --term-color-2: #859900; - --term-color-3: #b58900; - --term-color-4: #268bd2; - --term-color-5: #d33682; - --term-color-6: #2aa198; - --term-color-7: #eee8d5; - --term-color-8: #002b36; - --term-color-9: #cb4b16; - --term-color-10: #586e75; - --term-color-11: #657b83; - --term-color-12: #839496; - --term-color-13: #6c71c4; - --term-color-14: #93a1a1; - --term-color-15: #fdf6e3; -} -/* - Based on Solarized Light: https://ethanschoonover.com/solarized/ - */ -.asciinema-player-theme-solarized-light { - --term-color-foreground: #657b83; - --term-color-background: #fdf6e3; - --term-color-0: #073642; - --term-color-1: #dc322f; - --term-color-2: #859900; - --term-color-3: #b58900; - --term-color-4: #268bd2; - --term-color-5: #d33682; - --term-color-6: #2aa198; - --term-color-7: #eee8d5; - --term-color-8: #002b36; - --term-color-9: #cb4b16; - --term-color-10: #586e75; - --term-color-11: #657c83; - --term-color-12: #839496; - --term-color-13: #6c71c4; - --term-color-14: #93a1a1; - --term-color-15: #fdf6e3; -} -.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-fill { - fill: var(--term-color-1); -} -.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-stroke { - stroke: var(--term-color-1); -} -/* - Based on Tango: https://en.wikipedia.org/wiki/Tango_Desktop_Project - */ -.asciinema-player-theme-tango { - --term-color-foreground: #cccccc; - --term-color-background: #121314; - --term-color-0: #000000; - --term-color-1: #cc0000; - --term-color-2: #4e9a06; - --term-color-3: #c4a000; - --term-color-4: #3465a4; - --term-color-5: #75507b; - --term-color-6: #06989a; - --term-color-7: #d3d7cf; - --term-color-8: #555753; - --term-color-9: #ef2929; - --term-color-10: #8ae234; - --term-color-11: #fce94f; - --term-color-12: #729fcf; - --term-color-13: #ad7fa8; - --term-color-14: #34e2e2; - --term-color-15: #eeeeec; -} -/* - Based on gruvbox: https://github.com/morhetz/gruvbox - */ -.asciinema-player-theme-gruvbox-dark { - --term-color-foreground: #fbf1c7; - --term-color-background: #282828; - --term-color-0: #282828; - --term-color-1: #cc241d; - --term-color-2: #98971a; - --term-color-3: #d79921; - --term-color-4: #458588; - --term-color-5: #b16286; - --term-color-6: #689d6a; - --term-color-7: #a89984; - --term-color-8: #7c6f65; - --term-color-9: #fb4934; - --term-color-10: #b8bb26; - --term-color-11: #fabd2f; - --term-color-12: #83a598; - --term-color-13: #d3869b; - --term-color-14: #8ec07c; - --term-color-15: #fbf1c7; -} diff --git a/docs/public/asciinema/asciinema-player.min.js b/docs/public/asciinema/asciinema-player.min.js deleted file mode 100644 index 1bdb365..0000000 --- a/docs/public/asciinema/asciinema-player.min.js +++ /dev/null @@ -1 +0,0 @@ -var AsciinemaPlayer=function(A){"use strict";function g(A){return"number"==typeof A?A:"string"==typeof A?A.split(":").reverse().map(parseFloat).reduce(((A,g,I)=>A+g*Math.pow(60,I))):void 0}class I{log(){}debug(){}info(){}warn(){}error(){}}class B{constructor(A,g){this.logger=A,this.prefix=g}log(A){for(var g=arguments.length,I=new Array(g>1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B{throw Error("TextDecoder not available")}};"undefined"!=typeof TextDecoder&&C.decode();let E=null;function V(){return null!==E&&0!==E.byteLength||(E=new Uint8Array(Q.memory.buffer)),E}function i(A,g){return A>>>=0,C.decode(V().subarray(A,A+g))}const e=new Array(128).fill(void 0);e.push(void 0,null,!0,!1);let o=e.length;function t(A){o===e.length&&e.push(e.length+1);const g=o;return o=e[g],e[g]=A,g}function s(A){return e[A]}function n(A){const g=s(A);return function(A){A<132||(e[A]=o,o=A)}(A),g}function r(A){const g=typeof A;if("number"==g||"boolean"==g||null==A)return`${A}`;if("string"==g)return`"${A}"`;if("symbol"==g){const g=A.description;return null==g?"Symbol":`Symbol(${g})`}if("function"==g){const g=A.name;return"string"==typeof g&&g.length>0?`Function(${g})`:"Function"}if(Array.isArray(A)){const g=A.length;let I="[";g>0&&(I+=r(A[0]));for(let B=1;B1))return toString.call(A);if(B=I[1],"Object"==B)try{return"Object("+JSON.stringify(A)+")"}catch(A){return"Object"}return A instanceof Error?`${A.name}: ${A.message}\n${A.stack}`:B}let a=0;const c="undefined"!=typeof TextEncoder?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},D="function"==typeof c.encodeInto?function(A,g){return c.encodeInto(A,g)}:function(A,g){const I=c.encode(A);return g.set(I),{read:A.length,written:I.length}};function w(A,g,I){if(void 0===I){const I=c.encode(A),B=g(I.length,1)>>>0;return V().subarray(B,B+I.length).set(I),a=I.length,B}let B=A.length,Q=g(B,1)>>>0;const C=V();let E=0;for(;E127)break;C[Q+E]=g}if(E!==B){0!==E&&(A=A.slice(E)),Q=I(Q,B,B=E+3*A.length,1)>>>0;const g=V().subarray(Q+E,Q+B);E+=D(A,g).written,Q=I(Q,B,E,1)>>>0}return a=E,Q}let l=null;function h(){return null!==l&&0!==l.byteLength||(l=new Int32Array(Q.memory.buffer)),l}let y=null;function G(A,g){return A>>>=0,(null!==y&&0!==y.byteLength||(y=new Uint32Array(Q.memory.buffer)),y).subarray(A/4,A/4+g)}const k="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((A=>Q.__wbg_vt_free(A>>>0)));class F{static __wrap(A){A>>>=0;const g=Object.create(F.prototype);return g.__wbg_ptr=A,k.register(g,g.__wbg_ptr,g),g}__destroy_into_raw(){const A=this.__wbg_ptr;return this.__wbg_ptr=0,k.unregister(this),A}free(){const A=this.__destroy_into_raw();Q.__wbg_vt_free(A)}feed(A){const g=w(A,Q.__wbindgen_malloc,Q.__wbindgen_realloc),I=a;return n(Q.vt_feed(this.__wbg_ptr,g,I))}resize(A,g){return n(Q.vt_resize(this.__wbg_ptr,A,g))}inspect(){let A,g;try{const C=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_inspect(C,this.__wbg_ptr);var I=h()[C/4+0],B=h()[C/4+1];return A=I,g=B,i(I,B)}finally{Q.__wbindgen_add_to_stack_pointer(16),Q.__wbindgen_free(A,g,1)}}getSize(){try{const B=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_getSize(B,this.__wbg_ptr);var A=h()[B/4+0],g=h()[B/4+1],I=G(A,g).slice();return Q.__wbindgen_free(A,4*g,4),I}finally{Q.__wbindgen_add_to_stack_pointer(16)}}getLine(A){return n(Q.vt_getLine(this.__wbg_ptr,A))}getCursor(){return n(Q.vt_getCursor(this.__wbg_ptr))}}function N(){const A={wbg:{}};return A.wbg.__wbindgen_error_new=function(A,g){return t(new Error(i(A,g)))},A.wbg.__wbindgen_object_drop_ref=function(A){n(A)},A.wbg.__wbindgen_object_clone_ref=function(A){return t(s(A))},A.wbg.__wbindgen_number_new=function(A){return t(A)},A.wbg.__wbindgen_bigint_from_u64=function(A){return t(BigInt.asUintN(64,A))},A.wbg.__wbindgen_string_new=function(A,g){return t(i(A,g))},A.wbg.__wbg_set_f975102236d3c502=function(A,g,I){s(A)[n(g)]=n(I)},A.wbg.__wbg_new_b525de17f44a8943=function(){return t(new Array)},A.wbg.__wbg_new_f841cc6f2098f4b5=function(){return t(new Map)},A.wbg.__wbg_new_f9876326328f45ed=function(){return t(new Object)},A.wbg.__wbindgen_is_string=function(A){return"string"==typeof s(A)},A.wbg.__wbg_set_17224bc548dd1d7b=function(A,g,I){s(A)[g>>>0]=n(I)},A.wbg.__wbg_set_388c4c6422704173=function(A,g,I){return t(s(A).set(s(g),s(I)))},A.wbg.__wbindgen_debug_string=function(A,g){const I=w(r(s(g)),Q.__wbindgen_malloc,Q.__wbindgen_realloc),B=a;h()[A/4+1]=B,h()[A/4+0]=I},A.wbg.__wbindgen_throw=function(A,g){throw new Error(i(A,g))},A}function q(A,g){return Q=A.exports,R.__wbindgen_wasm_module=g,l=null,y=null,E=null,Q}async function R(A){if(void 0!==Q)return Q;const g=N();("string"==typeof A||"function"==typeof Request&&A instanceof Request||"function"==typeof URL&&A instanceof URL)&&(A=fetch(A));const{instance:I,module:B}=await async function(A,g){if("function"==typeof Response&&A instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,g)}catch(g){if("application/wasm"==A.headers.get("Content-Type"))throw g;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",g)}const I=await A.arrayBuffer();return await WebAssembly.instantiate(I,g)}{const I=await WebAssembly.instantiate(A,g);return I instanceof WebAssembly.Instance?{instance:I,module:A}:I}}(await A,g);return q(I,B)}var J=Object.freeze({__proto__:null,Vt:F,create:function(A,g,I){const B=Q.create(A,g,I);return F.__wrap(B)},default:R,initSync:function(A){if(void 0!==Q)return Q;const g=N();return A instanceof WebAssembly.Module||(A=new WebAssembly.Module(A)),q(new WebAssembly.Instance(A,g),A)}});const d=[62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function M(A){return d[A-43]}const u=function(A){let g,I=A.endsWith("==")?2:A.endsWith("=")?1:0,B=A.length,Q=new Uint8Array(B/4*3);for(let I=0,C=0;I>16,Q[C+1]=g>>8&255,Q[C+2]=255&g;return Q.subarray(0,Q.length-I)}("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ACADKQAAIgk3AAggByAEQRRsaiICQqCAgIAQNwIAIAIgCTcACCAAQRBqIANBCGovAAAiADsAACACQRBqIAA7AAAgAUEBaiIAIAVPDQogByAAQRRsaiIAKAIEQQJGBEAgAUECaiIBIAVPDQ0gByABQRRsaiIBQqCAgIAQNwIAIAEgAykAADcACCABQRBqIANBCGovAAA7AAALIABCIDcCACAAQQhqIQRBAiEGDBALIAFBAWoiACAFTw0KIAcgAEEUbGoiAEKggICAEDcCACAAQQhqIQRBACEGDA8LIAEgBUG4ocAAEGwACyAEQYACQfCdwAAQbAALIARBFUGAnsAAEGwACyAGQbQBQZCewAAQbAALIAAgBUHYocAAEGwACyAAIAVByKHAABBsAAsgASAFQeihwAAQbAALIAEgBUGIosAAEGwACyAEIAVBuKLAABBsAAsgACAFQciiwAAQbAALIAAgBUGoosAAEGwACyABIAVB2KLAABBsAAsgBSABQQFrIgFLBEBBASEGIABBATYCBCAAIAI2AgAgByABQRRsaiIBQqCAgIAQNwIAIAEgAykAADcACCABQRBqIANBCGovAAA7AAAgAEEIaiEEDAMLIAEgBUGYosAAEGwACyAAQQE2AgQgACACNgIAIAggAykAADcAACAIQQhqIANBCGovAAA7AAAgASAFSQRAIAcgAUEUbGoiAEKggICAEDcCACAAQQhqIQRBASEGDAILIAEgBUH4ocAAEGwACyAAQQE2AgQgACACNgIAIABBCGohBEEBIQYLIAQgAykAADcAACAEQQhqIANBCGovAAA7AAALIAYLyAgCCX8BfiMAQUBqIgUkAAJAA0AgASgCDEEUayEDIAEoAhAhBAJAAkADQCADQRRqIgIgBEYNASABIANBKGo2AgwgA0EYaiACIQMoAgAiCUUNAAsgASgCCCIGDQEgBUEYaiICQRBqIgQgA0EQaigCADYCACACQQhqIgYgA0EIaikCADcDACAFIAMpAgA3AxhBACEDIAEoAgBFBEAgAUEAEIQBIAEoAgghAwsgASgCBCADQRRsaiICIAUpAxg3AgAgAkEQaiAEKAIANgIAIAJBCGogBikDADcCACABIAEoAghBAWo2AggMAgsgASgCCARAIAEpAgAhCyABQoCAgIDAADcCACAAIAs3AgAgAUEIaiIBKAIAIQIgAUEANgIAIABBCGogAjYCAAwDCyAAQYCAgIB4NgIADAILIANBCGoiCi0AACECAkACQCABKAIEIgggBkEUbGpBFGsiBC0ACCIHQQJGBEAgAkECRw0CDAELIAJBAkYNASACIAdHDQEgB0UEQCAELQAJIANBCWotAABGDQEMAgsgBC0ACSADQQlqLQAARw0BIAQtAAogA0EKai0AAEcNASAELQALIANBC2otAABHDQELIANBDGotAAAhAgJAIAQtAAwiB0ECRgRAIAJBAkcNAgwBCyACQQJGDQEgAiAHRw0BIAdFBEAgBC0ADSADQQ1qLQAARw0CDAELIAQtAA0gA0ENai0AAEcNASAELQAOIANBDmotAABHDQEgBC0ADyADQQ9qLQAARw0BCyAELQAQIANBEGoiBy0AAEcNACAELQARIANBEWotAABHDQAgBCgCACICQfz//wBxQbDBA0YNACACQeD//wBxQYDLAEYNACACQYD+/wBxQYDQAEYNACAEKAIEQQFLDQAgAkGA//8AcUGAygBGDQAgAygCACICQfz//wBxQbDBA0YNACACQeD//wBxQYDLAEYNACACQYD+/wBxQYDQAEYNACAJQQFHDQAgAkGA//8AcUGAygBGDQAgBUEYaiICQRBqIgQgBygCADYCACACQQhqIgcgCikCADcDACAFIAMpAgA3AxggASgCACAGRgR/IAEgBhCEASABKAIEIQggASgCCAUgBgtBFGwgCGoiAiAFKQMYNwIAIAJBEGogBCgCADYCACACQQhqIAcpAwA3AgAgASABKAIIQQFqNgIIDAELCyABKQIAIQsgAUKAgICAwAA3AgAgBUEQaiIEIAFBCGoiAigCADYCACACQQA2AgAgBSALNwMIIAVBGGoiBkEQaiIIIANBEGooAgA2AgAgBkEIaiIGIANBCGopAgA3AwAgBSADKQIANwMYIAFBABCEASABKAIEIAIoAgBBFGxqIgEgBSkDGDcCACABQRBqIAgoAgA2AgAgAUEIaiAGKQMANwIAIAIgAigCAEEBajYCACAAQQhqIAQoAgA2AgAgACAFKQMINwIACyAFQUBrJAALswcCCH8BfiMAQUBqIgUkAAJAA0AgASgCDEEUayECIAEoAhAhBAJAAkADQCACQRRqIgMgBEYNASABIAJBKGo2AgwgAkEYaiADIQIoAgBF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aiAFQQhqKQIANwIADAILIAhBgICAgHg2AgAgBSgCACICRQ0BIAUoAgQgAkEUbEEEEOUBDAELIANBAEGQpMAAEGwACyAFQSBqJAAgAUEIaiAIQQhqKQIANwIAIAEgBikCKDcCACAAQQhqIAdBCGopAgA3AgAgACAGKQIINwIADAQLIAAgBikCCDcCACAAQQhqIAZBEGopAgA3AgAMAwsCQCACIAxHBEAgASACQRBqIgo2AhAgAigCACIEQYCAgIB4Rw0BCyAGQQA7ATggBkECOgA0IAZBAjoAMCAGQqCAgIAQNwIoIAYgCSADazYCPCAGQQhqIgEgBkEoahAwIAAgBikCCDcCACAGQQA6ABQgAEEIaiABQQhqKQIANwIADAMLIA8gAikCBDcCACAQIAJBDGooAgA2AgAgBiAENgIYIAZBKGohByAGQRhqIQMjAEEgayICJAACQCAJIAZBCGoiBSgCCCIEayIIRQRAIAdBAToAACAHIAMpAgA3AgQgB0EMaiADQQhqKQIANwIADAELIAUtAAxFBEAgAiAINgIcIAJBADsBGCACQQI6ABQgAkECOgAQIAJCoICAgBA3AgggBSACQQhqEDAgB0EBOgAAIAcgAykCADcCBCAHQQxqIANBCGopAgA3AgAMAQsgAy0ADEUEQCADEGILIAMoAgQhCyADKAIIIg0gCE0EQCAFIAsgCyANQRRsahB6QQAhCAJAIAMtAAwNACAFQQA6AAxBASEIIAUoAggiBCAJTw0AIAJBADsBGCACQQI6ABQgAkECOgAQIAJCoICAgBA3AgggAiAJIARrNgIcIAUgAkEIahAwCyAHQYCAgIB4NgIEIAcgCDoAACADKAIAIgNFDQEgCyADQRRsQQQQ5QEMAQsCQCALIAhBFGxqKAIERQRAIARBAWshDSAERQ0BIAJBEGoiESAFKAIEIgsgDUEUbGoiDUEQai8AADsBACACIA0pAAg3AwggBSgCACAERgRAIAUgBBCEASAFKAIEIQsgBSgCCCEECyAEQRRsIAtqIgQgAikDCDcCCCAEQqCAgIAQNwIAIARBEGogES8BADsBACAFIAUoAghBAWo2AgggCEEBayEICwJAIAMoAggiBCAITwRAIAMoAgQhBCACIAg2AgQgAiAENgIADAELIAggBEGApMAAEOsBAAsgBSACKAIAIgQgBCACKAIEQRRsahB6IAMoAgAhBSADKAIEIgsgAygCCCIEIAgQswEgByALNgIIIAcgBTYCBCAHQQE6AAAgByADLQAMOgAQIAcgBCAEIAhrIgMgAyAESxs2AgwMAQsgDUEAQfCjwAAQbAALIAJBIGokACAGLQAoRQRAIAEgBikCCDcCACABQQhqIAZBEGopAgA3AgAgBigCLCICQYCAgIB4Rg0BIAJFDQEgBigCMCACQRRsQQQQ5QEMAQsLIAYoAixBgICAgHhHBEAgASAOKQIANwIAIAFBCGogDkEIaikCADcCAAsgACAGKQIINwIAIABBCGogBkEQaikCADcCAAwBCyAAQYCAgIB4NgIAIAFBgICAgHg2AgALIAZBQGskAAvrBAEPfyMAQTBrIQMCQCAARQ0AIAJFDQAgA0EQaiIGIAEgAEFsbGoiDCIHQRBqKAIANgIAIANBCGoiCCAHQQhqKQIANwMAIAMgBykCADcDACACQRRsIQkgAiIEIQoDQCAMIARBFGxqIQUDQCADQRhqIgFBEGoiDSAGKAIANgIAIAFBCGoiDiAIKQMANwMAIAMgAykDADcDGEEAIQEDQCABIAVqIgsoAgAhDyALIANBGGogAWoiCygCADYCACALIA82AgAgAUEEaiIBQRRHDQALIAYgDSgCADYCACAIIA4pAwA3AwAgAyADKQMYNwMAIAAgBEsEQCAFIAlqIQUgAiAEaiEEDAELCyAEIABrIgQEQCAEIAogBCAKSRshCgwBBSAHIAMpAwA3AgAgB0EQaiADQRBqIgYoAgA2AgAgB0EIaiADQQhqIggpAwA3AgAgCkECSQ0CQQEhBQNAIAYgByAFQRRsaiIJQRBqIgwoAgA2AgAgCCAJQQhqIg0pAgA3AwAgAyAJKQIANwMAIAIgBWohBANAIANBGGoiAUEQaiIOIAYoAgA2AgAgAUEIaiILIAgpAwA3AwAgAyADKQMANwMYIAcgBEEUbGohD0EAIQEDQCABIA9qIhAoAgAhESAQIANBGGogAWoiECgCADYCACAQIBE2AgAgAUEEaiIBQRRHDQALIAYgDigCADYCACAIIAspAwA3AwAgAyADKQMYNwMAIAAgBEsEQCACIARqIQQMAQsgBCAAayIEIAVHDQALIAkgAykDADcCACAMIAYoAgA2AgAgDSAIKQMANwIAIAogBUEBaiIFRw0ACwsLCwv8BAEKfyMAQTBrIgMkACADQQM6ACwgA0EgNgIcIANBADYCKCADIAE2AiQgAyAANgIgIANBADYCFCADQQA2AgwCfwJAAkACQCACKAIQIgpFBEAgAigCDCIARQ0BIAIoAgghASAAQQN0IQUgAEEBa0H/////AXFBAWohByACKAIAIQADQCAAQQRqKAIAIgQEQCADKAIgIAAoAgAgBCADKAIkKAIMEQEADQQLIAEoAgAgA0EMaiABKAIEEQAADQMgAUEIaiEBIABBCGohACAFQQhrIgUNAAsMAQsgAigCFCIARQ0AIABBBXQhCyAAQQFrQf///z9xQQFqIQcgAigCCCEIIAIoAgAhAANAIABBBGooAgAiAQRAIAMoAiAgACgCACABIAMoAiQoAgwRAQANAwsgAyAFIApqIgFBEGooAgA2AhwgAyABQRxqLQAAOgAsIAMgAUEYaigCADYCKCABQQxqKAIAIQRBACEJQQAhBgJAAkACQCABQQhqKAIAQQFrDgIAAgELIAggBEEDdGoiDCgCBEHzAEcNASAMKAIAKAIAIQQLQQEhBgsgAyAENgIQIAMgBjYCDCABQQRqKAIAIQQCQAJAAkAgASgCAEEBaw4CAAIBCyAIIARBA3RqIgYoAgRB8wBHDQEgBigCACgCACEEC0EBIQkLIAMgBDYCGCADIAk2AhQgCCABQRRqKAIAQQN0aiIBKAIAIANBDGogASgCBBEAAA0CIABBCGohACALIAVBIGoiBUcNAAsLIAcgAigCBE8NASADKAIgIAIoAgAgB0EDdGoiACgCACAAKAIEIAMoAiQoAgwRAQBFDQELQQEMAQtBAAsgA0EwaiQAC+8EAQV/IwBBEGsiAyQAAkACQAJAAkACQAJAAkAgACgCpAEiAkEBTQRAAkAgAUH/AEsNACAAIAJqQbABai0AAEUNACABQQJ0QbyowABqKAIAIQELIAAoAmgiBSAAKAKcASIGTw0DIAAoAmwhAiAALQC9AQ0BDAILIAJBAkHgrcAAEGwACyADQQhqIABBugFqLwAAOwEAIAMgACkAsgE3AwAgACgCGCEEIAAgAkG0pcAAEIoBIAUgBCAFRyADEDYLIANBCGogAEG6AWovAAA7AQAgAyAAKQCyATcDACAAIAJBlKXAABCKASAFIAEgAxARIgQNAQsgAC0AvwENASAAKAJsIQIgA0EIaiIEIABBugFqLwAAOwEAIAMgACkAsgE3AwAgACACQZSlwAAQigEgBUEBayABIAMQEUUEQCAEIABBsgFqIgRBCGovAAA7AQAgAyAEKQAANwMAIAAgAkGUpcAAEIoBIAVBAmsgASADEBEaCyAGQQFrIQEMAgsgACAEIAVqIgE2AmggASAGRw0CIAAtAL8BDQIgBkEBayEBDAELAkAgACgCbCICIAAoAqwBRwRAIAIgACgCoAFBAWtPDQEgACACQaSlwAAQigFBAToADCAAIAJBAWoiAjYCbAwBCyAAIAJBpKXAABCKAUEBOgAMIABBARCyASAAKAJsIQILIANBCGogAEG6AWovAAA7AQAgAyAAKQCyATcDACAAIAJBlKXAABCKAUEAIAEgAxARIQEgACgCbCECCyAAIAE2AmgLIAIgACgCZCIBSQRAIAAoAmAgAmpBAToAACADQRBqJAAPCyACIAFBiLDAABBsAAuPBAELfyABQQFrIQ0gACgCBCEKIAAoAgAhCyAAKAIIIQwDQAJAAkAgAiAESQ0AA0AgASAEaiEFAkACQCACIARrIgdBCE8EQAJAIAVBA2pBfHEiBiAFayIDBEBBACEAA0AgACAFai0AAEEKRg0FIAMgAEEBaiIARw0ACyAHQQhrIgAgA08NAQwDCyAHQQhrIQALA0AgBkEEaigCACIJQYqUqNAAc0GBgoQIayAJQX9zcSAGKAIAIglBipSo0ABzQYGChAhrIAlBf3NxckGAgYKEeHENAiAGQQhqIQYgACADQQhqIgNPDQALDAELIAIgBEYEQCACIQQMBAtBACEAA0AgACAFai0AAEEKRg0CIAcgAEEBaiIARw0ACyACIQQMAwsgAyAHRgRAIAIhBAwDCwNAIAMgBWotAABBCkYEQCADIQAMAgsgByADQQFqIgNHDQALIAIhBAwCCyAAIARqIgZBAWohBAJAIAIgBk0NACAAIAVqLQAAQQpHDQBBACEFIAQiBiEADAMLIAIgBE8NAAsLQQEhBSACIgAgCCIGRw0AQQAPCwJAIAwtAABFDQAgC0Gs+cAAQQQgCigCDBEBAEUNAEEBDwsgACAIayEHQQAhAyAAIAhHBEAgACANai0AAEEKRiEDCyABIAhqIQAgDCADOgAAIAYhCCALIAAgByAKKAIMEQEAIgAgBXJFDQALIAALugYBBX8jAEHAAWsiAiQAIAAoAgAhAyACQQxqIgBBrAFqQfyLwAA2AgAgAEGkAWpBhI7AADYCACAAQZwBakH0jcAANgIAIAJBoAFqQfSNwAA2AgAgAkGYAWpBhIvAADYCACACQZABakGEi8AANgIAIAJBiAFqQeSNwAA2AgAgAEH0AGpB5IzAADYCACACQfgAakHkjMAANgIAIAJB8ABqQeSMwAA2AgAgAEHcAGpB5IzAADYCACACQeAAakHUjcAANgIAIAJB2ABqQYSLwAA2AgAgAkHQAGpBxI3AADYCACACQcgAakHIjMAANgIAIAJBQGtBtI3AADYCACACQThqQaSNwAA2AgAgAEEkakGUjcAANgIAIAJBKGpBhI3AADYCACACQSBqQYSNwAA2AgAgAkEYakGEi8AANgIAIAIgA0HcAGo2AqwBIAIgA0GIAWo2AqQBIAIgA0H0AGo2ApwBIAIgA0GsAWo2ApQBIAIgA0GoAWo2AowBIAIgA0HBAWo2AoQBIAIgA0HAAWo2AnwgAiADQb8BajYCdCACIANBvgFqNgJsIAIgA0G9AWo2AmQgAiADQdAAajYCXCACIANBpAFqNgJUIAIgA0GwAWo2AkwgAiADQbIBajYCRCACIANB6ABqNgI8IAIgA0HIAGo2AjQgAiADQbwBajYCLCACIANBJGo2AiQgAiADNgIcIAIgA0GgAWo2AhQgAkGEi8AANgIQIAIgA0GcAWo2AgwgAiADQcIBajYCvAEgAiACQbwBajYCtAFBFiEGQdCPwAAhBCMAQSBrIgMkACADQRY2AgAgA0EWNgIEIAEoAhRBlI7AAEEIIAEoAhgoAgwRAQAhBSADQQA6AA0gAyAFOgAMIAMgATYCCAJ/A0AgA0EIaiAEKAIAIARBBGooAgAgAEHM+8AAECchBSAAQQhqIQAgBEEIaiEEIAZBAWsiBg0ACyADLQAMIQEgAUEARyADLQANRQ0AGkEBIAENABogBSgCACIALQAcQQRxRQRAIAAoAhRBu/nAAEECIAAoAhgoAgwRAQAMAQsgACgCFEG6+cAAQQEgACgCGCgCDBEBAAsgA0EgaiQAIAJBwAFqJAAL+AMBAn8gACABaiECAkACQCAAKAIEIgNBAXENACADQQJxRQ0BIAAoAgAiAyABaiEBIAAgA2siAEGAl8EAKAIARgRAIAIoAgRBA3FBA0cNAUH4lsEAIAE2AgAgAiACKAIEQX5xNgIEIAAgAUEBcjYCBCACIAE2AgAMAgsgACADECYLAkACQAJAIAIoAgQiA0ECcUUEQCACQYSXwQAoAgBGDQIgAkGAl8EAKAIARg0DIAIgA0F4cSICECYgACABIAJqIgFBAXI2AgQgACABaiABNgIAIABBgJfBACgCAEcNAUH4lsEAIAE2AgAPCyACIANBfnE2AgQgACABQQFyNgIEIAAgAWogATYCAAsgAUGAAk8EQCAAIAEQKw8LIAFBeHFB6JTBAGohAgJ/QfCWwQAoAgAiA0EBIAFBA3Z0IgFxRQRAQfCWwQAgASADcjYCACACDAELIAIoAggLIQEgAiAANgIIIAEgADYCDCAAIAI2AgwgACABNgIIDwtBhJfBACAANgIAQfyWwQBB/JbBACgCACABaiIBNgIAIAAgAUEBcjYCBCAAQYCXwQAoAgBHDQFB+JbBAEEANgIAQYCXwQBBADYCAA8LQYCXwQAgADYCAEH4lsEAQfiWwQAoAgAgAWoiATYCACAAIAFBAXI2AgQgACABaiABNgIACwuuBAEFfyMAQTBrIgUkACACIAFrIgggA0shCSACQQFrIgYgACgCHCIHQQFrSQRAIAAgBkG0psAAEIoBQQA6AAwLIAMgCCAJGyEDAkACQCABRQRAIABBDGohBiACIAdGDQEgACgCGCEBIAVBLGogBEEIai8AADsBACAFQqCAgIAQNwIcIAUgBCkAADcCJCAFQQhqIAVBHGogARBXIAVBADoAFCADBEAgACgCFCACaiAAKAIcayECA0AgBUEcaiIBIAVBCGoQYSAFQQA6ACggBigCCCIHIAYoAgBGBEAgBiAHQQEQhgELIAYoAgQgAkEEdGohBAJAIAIgB08EQCACIAdGDQEgAiAHEGsACyAEQRBqIAQgByACa0EEdBCIAgsgBCABKQIANwIAIAYgB0EBajYCCCAEQQhqIAFBCGopAgA3AgAgA0EBayIDDQALCyAFKAIIIgFFDQIgBSgCDCABQRRsQQQQ5QEMAgsgACABQQFrQcSmwAAQigFBADoADCAFIAAgASACQdSmwAAQZSAFKAIAIQYgBSgCBCIBIANJBEBBoJ7AAEEjQZCfwAAQnAEACyADIAYgA0EEdGogASADaxAVIAAgAiADayACIAQQUgwBCyAAKAIYIQIgBUEsaiAEQQhqLwAAOwEAIAVCoICAgBA3AhwgBSAEKQAANwIkIAVBCGoiASAFQRxqIAIQVyAFIAM2AhggBUEAOgAUIAYgARBACyAAQQE6ACAgBUEwaiQAC+cCAQV/AkBBzf97IABBECAAQRBLGyIAayABTQ0AQRAgAUELakF4cSABQQtJGyIEIABqQQxqEA8iAkUNACACQQhrIQECQCAAQQFrIgMgAnFFBEAgASEADAELIAJBBGsiBSgCACIGQXhxQQAgACACIANqQQAgAGtxQQhrIgAgAWtBEEsbIABqIgAgAWsiAmshAyAGQQNxBEAgACADIAAoAgRBAXFyQQJyNgIEIAAgA2oiAyADKAIEQQFyNgIEIAUgAiAFKAIAQQFxckECcjYCACABIAJqIgMgAygCBEEBcjYCBCABIAIQIQwBCyABKAIAIQEgACADNgIEIAAgASACajYCAAsCQCAAKAIEIgFBA3FFDQAgAUF4cSICIARBEGpNDQAgACAEIAFBAXFyQQJyNgIEIAAgBGoiASACIARrIgRBA3I2AgQgACACaiICIAIoAgRBAXI2AgQgASAEECELIABBCGohAwsgAwuLAwEHfyMAQRBrIgQkAAJAAkACQAJAAkACQCABKAIEIgJFDQAgASgCACEFIAJBA3EhBgJAIAJBBEkEQEEAIQIMAQsgBUEcaiEDIAJBfHEhCEEAIQIDQCADKAIAIANBCGsoAgAgA0EQaygCACADQRhrKAIAIAJqampqIQIgA0EgaiEDIAggB0EEaiIHRw0ACwsgBgRAIAdBA3QgBWpBBGohAwNAIAMoAgAgAmohAiADQQhqIQMgBkEBayIGDQALCyABKAIMBEAgAkEASA0BIAUoAgRFIAJBEElxDQEgAkEBdCECCyACDQELQQEhA0EAIQIMAQsgAkEASA0BQYmTwQAtAAAaIAJBARDXASIDRQ0CCyAEQQA2AgggBCADNgIEIAQgAjYCACAEQYTzwAAgARAdRQ0CQeTzwABBMyAEQQ9qQZj0wABBwPTAABBjAAsQqAEAC0EBIAJBxJPBACgCACIAQd4AIAAbEQIAAAsgACAEKQIANwIAIABBCGogBEEIaigCADYCACAEQRBqJAAL1QIBB39BASEJAkACQCACRQ0AIAEgAkEBdGohCiAAQYD+A3FBCHYhCyAAQf8BcSENA0AgAUECaiEMIAcgAS0AASICaiEIIAsgAS0AACIBRwRAIAEgC0sNAiAIIQcgCiAMIgFGDQIMAQsCQAJAIAcgCE0EQCAEIAhJDQEgAyAHaiEBA0AgAkUNAyACQQFrIQIgAS0AACABQQFqIQEgDUcNAAtBACEJDAULIAcgCEGYgMEAEO0BAAsgCCAEQZiAwQAQ6wEACyAIIQcgCiAMIgFHDQALCyAGRQ0AIAUgBmohAyAAQf//A3EhAQNAIAVBAWohAAJAIAUtAAAiAsAiBEEATgRAIAAhBQwBCyAAIANHBEAgBS0AASAEQf8AcUEIdHIhAiAFQQJqIQUMAQtBiIDBABDvAQALIAEgAmsiAUEASA0BIAlBAXMhCSADIAVHDQALCyAJQQFxC/MCAQR/IAAoAgwhAgJAAkAgAUGAAk8EQCAAKAIYIQMCQAJAIAAgAkYEQCAAQRRBECAAKAIUIgIbaigCACIBDQFBACECDAILIAAoAggiASACNgIMIAIgATYCCAwBCyAAQRRqIABBEGogAhshBANAIAQhBSABIgIoAhQhASACQRRqIAJBEGogARshBCACQRRBECABG2ooAgAiAQ0ACyAFQQA2AgALIANFDQIgACAAKAIcQQJ0QdiTwQBqIgEoAgBHBEAgA0EQQRQgAygCECAARhtqIAI2AgAgAkUNAwwCCyABIAI2AgAgAg0BQfSWwQBB9JbBACgCAEF+IAAoAhx3cTYCAAwCCyACIAAoAggiAEcEQCAAIAI2AgwgAiAANgIIDwtB8JbBAEHwlsEAKAIAQX4gAUEDdndxNgIADwsgAiADNgIYIAAoAhAiAQRAIAIgATYCECABIAI2AhgLIAAoAhQiAEUNACACIAA2AhQgACACNgIYCwuBAwIFfwF+IwBBQGoiBSQAQQEhBwJAIAAtAAQNACAALQAFIQggACgCACIGKAIcIglBBHFFBEAgBigCFEGz+cAAQbD5wAAgCBtBAkEDIAgbIAYoAhgoAgwRAQANASAGKAIUIAEgAiAGKAIYKAIMEQEADQEgBigCFEGA+cAAQQIgBigCGCgCDBEBAA0BIAMgBiAEKAIMEQAAIQcMAQsgCEUEQCAGKAIUQbX5wABBAyAGKAIYKAIMEQEADQEgBigCHCEJCyAFQQE6ABsgBSAGKQIUNwIMIAVBlPnAADYCNCAFIAVBG2o2AhQgBSAGKQIINwIkIAYpAgAhCiAFIAk2AjggBSAGKAIQNgIsIAUgBi0AIDoAPCAFIAo3AhwgBSAFQQxqIgY2AjAgBiABIAIQHw0AIAVBDGpBgPnAAEECEB8NACADIAVBHGogBCgCDBEAAA0AIAUoAjBBuPnAAEECIAUoAjQoAgwRAQAhBwsgAEEBOgAFIAAgBzoABCAFQUBrJAAgAAuGBAEFfyMAQRBrIgMkAAJAAn8CQCABQYABTwRAIANBADYCDCABQYAQSQ0BIAFBgIAESQRAIAMgAUE/cUGAAXI6AA4gAyABQQx2QeABcjoADCADIAFBBnZBP3FBgAFyOgANQQMMAwsgAyABQT9xQYABcjoADyADIAFBBnZBP3FBgAFyOgAOIAMgAUEMdkE/cUGAAXI6AA0gAyABQRJ2QQdxQfABcjoADEEEDAILIAAoAggiAiAAKAIARgRAIwBBIGsiBCQAAkACQCACQQFqIgJFDQAgACgCACIFQQF0IgYgAiACIAZJGyICQQggAkEISxsiAkF/c0EfdiEGIAQgBQR/IAQgBTYCHCAEIAAoAgQ2AhRBAQVBAAs2AhggBEEIaiAGIAIgBEEUahBPIAQoAggEQCAEKAIMIgBFDQEgACAEKAIQQcSTwQAoAgAiAEHeACAAGxECAAALIAQoAgwhBSAAIAI2AgAgACAFNgIEIARBIGokAAwBCxCoAQALIAAoAgghAgsgACACQQFqNgIIIAAoAgQgAmogAToAAAwCCyADIAFBP3FBgAFyOgANIAMgAUEGdkHAAXI6AAxBAgshASABIAAoAgAgACgCCCICa0sEQCAAIAIgARBEIAAoAgghAgsgACgCBCACaiADQQxqIAEQigIaIAAgASACajYCCAsgA0EQaiQAQQALugIBA38jAEGAAWsiBCQAAn8CQAJAIAEoAhwiAkEQcUUEQCACQSBxDQEgADUCACABECoMAwsgACgCACEAQQAhAgNAIAIgBGpB/wBqIABBD3EiA0EwciADQdcAaiADQQpJGzoAACACQQFrIQIgAEEQSSAAQQR2IQBFDQALDAELIAAoAgAhAEEAIQIDQCACIARqQf8AaiAAQQ9xIgNBMHIgA0E3aiADQQpJGzoAACACQQFrIQIgAEEQSSAAQQR2IQBFDQALIAJBgAFqIgBBgQFPBEAgAEGAAUHg+cAAEOoBAAsgAUHw+cAAQQIgAiAEakGAAWpBACACaxAYDAELIAJBgAFqIgBBgQFPBEAgAEGAAUHg+cAAEOoBAAsgAUHw+cAAQQIgAiAEakGAAWpBACACaxAYCyAEQYABaiQAC8ACAgV/AX4jAEEwayIEJABBJyECAkAgAEKQzgBUBEAgACEHDAELA0AgBEEJaiACaiIDQQRrIAAgAEKQzgCAIgdCkM4Afn2nIgVB//8DcUHkAG4iBkEBdEHy+cAAai8AADsAACADQQJrIAUgBkHkAGxrQf//A3FBAXRB8vnAAGovAAA7AAAgAkEEayECIABC/8HXL1YgByEADQALCyAHpyIDQeMASwRAIAenIgVB//8DcUHkAG4hAyACQQJrIgIgBEEJamogBSADQeQAbGtB//8DcUEBdEHy+cAAai8AADsAAAsCQCADQQpPBEAgAkECayICIARBCWpqIANBAXRB8vnAAGovAAA7AAAMAQsgAkEBayICIARBCWpqIANBMHI6AAALIAFBiPbAAEEAIARBCWogAmpBJyACaxAYIARBMGokAAvEAgEEfyAAQgA3AhAgAAJ/QQAgAUGAAkkNABpBHyABQf///wdLDQAaIAFBBiABQQh2ZyIDa3ZBAXEgA0EBdGtBPmoLIgI2AhwgAkECdEHYk8EAaiEEQQEgAnQiA0H0lsEAKAIAcUUEQCAEIAA2AgAgACAENgIYIAAgADYCDCAAIAA2AghB9JbBAEH0lsEAKAIAIANyNgIADwsCQAJAIAEgBCgCACIDKAIEQXhxRgRAIAMhAgwBCyABQQBBGSACQQF2ayACQR9GG3QhBQNAIAMgBUEddkEEcWpBEGoiBCgCACICRQ0CIAVBAXQhBSACIQMgAigCBEF4cSABRw0ACwsgAigCCCIBIAA2AgwgAiAANgIIIABBADYCGCAAIAI2AgwgACABNgIIDwsgBCAANgIAIAAgAzYCGCAAIAA2AgwgACAANgIIC7QCAQd/IwBBEGsiAiQAQQEhBwJAAkAgASgCFCIEQScgASgCGCgCECIFEQAADQAgAiAAKAIAQYECEBcCQCACLQAAQYABRgRAIAJBCGohBkGAASEDA0ACQCADQYABRwRAIAItAAoiACACLQALTw0EIAIgAEEBajoACiAAQQpPDQYgACACai0AACEBDAELQQAhAyAGQQA2AgAgAigCBCEBIAJCADcDAAsgBCABIAURAABFDQALDAILIAItAAoiAUEKIAFBCksbIQAgASACLQALIgMgASADSxshBgNAIAEgBkYNASACIAFBAWoiAzoACiAAIAFGDQMgASACaiEIIAMhASAEIAgtAAAgBREAAEUNAAsMAQsgBEEnIAURAAAhBwsgAkEQaiQAIAcPCyAAQQpBnIzBABBsAAvMAgACQAJAAkACQAJAAkACQCADQQFrDgYAAQIDBAUGCyAAKAIYIQMgACACQeSlwAAQigEiBEEAOgAMIAQgASADIAUQLiAAIAJBAWogACgCHCAFEFIPCyAAKAIYIQMgACACQfSlwAAQigFBACABQQFqIgEgAyABIANJGyAFEC4gAEEAIAIgBRBSDwsgAEEAIAAoAhwgBRBSDwsgACgCGCEDIAAgAkGEpsAAEIoBIgAgASADIAUQLiAAQQA6AAwPCyAAKAIYIQMgACACQZSmwAAQigFBACABQQFqIgAgAyAAIANJGyAFEC4PCyAAKAIYIQEgACACQaSmwAAQigEiAEEAIAEgBRAuIABBADoADA8LIAAoAhghAyAAIAJB1KXAABCKASIAIAEgASAEIAMgAWsiASABIARLG2oiASAFEC4gASADRgRAIABBADoADAsLuwIBAn8CQAJAAkACQAJAIAAoAggiBCABRg0AIAEgBE8NASAAKAIEIgUgAUEUbGooAgRFBEAgAUEBayIAIARPDQMgBSAAQRRsaiIAQqCAgIAQNwIAIAAgAykAADcACCAAQRBqIANBCGovAAA7AAALIAEgAksNAyACIARLDQQgBSACQRRsaiEAIAEgAkcEQCAFIAFBFGxqIQEgA0EIaiEFA0AgAUKggICAEDcCACABIAMpAAA3AAggAUEQaiAFLwAAOwAAIAAgAUEUaiIBRw0ACwsgAiAETw0AIAAoAgQNACAAQqCAgIAQNwIAIAAgAykAADcACCAAQRBqIANBCGovAAA7AAALDwsgASAEQYihwAAQbAALIAAgBEGYocAAEGwACyABIAJBqKHAABDtAQALIAIgBEGoocAAEOsBAAuUAgEDfyMAQRBrIgIkAAJAAn8CQCABQYABTwRAIAJBADYCDCABQYAQSQ0BIAFBgIAESQRAIAIgAUEMdkHgAXI6AAwgAiABQQZ2QT9xQYABcjoADUECIQNBAwwDCyACIAFBBnZBP3FBgAFy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aigCADYCACACQRBqJAALugEBAX8jAEEQayILJAAgACgCFCABIAIgACgCGCgCDBEBACEBIAtBADoADSALIAE6AAwgCyAANgIIIAtBCGogAyAEIAUgBhAnIAcgCCAJIAoQJyECIAstAAwhAQJ/IAFBAEcgCy0ADUUNABpBASABDQAaIAIoAgAiAC0AHEEEcUUEQCAAKAIUQbv5wABBAiAAKAIYKAIMEQEADAELIAAoAhRBuvnAAEEBIAAoAhgoAgwRAQALIAtBEGokAAuwAQEDf0EBIQRBBCEGAkAgAUUNACACQQBIDQACfwJAAkACfyADKAIEBEAgAygCCCIBRQRAIAJFBEAMBAtBiZPBAC0AABogAkEBENcBDAILIAMoAgAgAUEBIAIQzQEMAQsgAkUEQAwCC0GJk8EALQAAGiACQQEQ1wELIgRFDQELIAAgBDYCBEEADAELIABBATYCBEEBCyEEQQghBiACIQULIAAgBmogBTYCACAAIAQ2AgALwwEBAn8jAEFAaiICJAACQCABBEAgASgCACIDQX9GDQEgASADQQFqNgIAIAJBATYCFCACQeSGwAA2AhAgAkIBNwIcIAJBEzYCLCACIAFBBGo2AiggAiACQShqNgIYIAJBMGoiAyACQRBqECQgASABKAIAQQFrNgIAIAJBCGogAxDbASACKAIIIQEgAiACKAIMNgIEIAIgATYCACACKAIEIQEgACACKAIANgIAIAAgATYCBCACQUBrJAAPCxD+AQALEP8BAAu4AQEDfwJAIAAoAoQEIgFBf0cEQCABQQFqIQIgAUEgSQ0BIAJBIEHMl8AAEOsBAAtBzJfAABCqAQALIABBBGohASAAIAJBBHRqQQRqIQMDQAJAIAEoAgAiAkF/RwRAIAJBBkkNASACQQFqQQZB3JzAABDrAQALQdycwAAQqgEACyABQQRqQQAgAkEBdEECahCJAhogAUEANgIAIAMgAUEQaiIBRw0ACyAAQYCAxAA2AgAgAEEANgKEBAvmAgEEfyMAQSBrIgMkACADQQxqIQICQCABLQAgRQRAIAJBADYCAAwBCyABQQA6ACACQCABKAIABEAgASgCFCIFIAEoAhxrIgQgASgCCEsNAQsgAkEANgIADAELIAQgASgCBGsiBCAFTQRAIAFBADYCFCACIAQ2AgwgAiAFIARrNgIQIAIgAUEM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gYCAgHggBUUNABogBUECdCEJIAcoAgQhCgJAIARFBEBBBCEBIAogCUEEEOUBDAELQQQgCiAJQQQgBEECdCIFEM0BIgFFDQEaCyAHIAQ2AgAgByABNgIEQYGAgIB4CyEBIAggBTYCBCAIIAE2AgAgAkEgaiQADAELIAJBATYCDCACQYDswAA2AgggAkIANwIUIAJB3OvAADYCECACQQhqQdTswAAQowEACyADKAIIIgFBgYCAgHhGDQAgAUUNASABIAMoAgxBxJPBACgCACIAQd4AIAAbEQIAAAsgA0EQaiQADAELEKgBAAsgBkEIaiAHKQIENwMAIAYoAgghASAGIAYoAgw2AgQgBiABNgIAIAYoAgQhASAAIAYoAgA2AgAgACABNgIEIAZBIGokAAtxAQF/IwBBEGsiAiQAIAIgAEEgajYCDCABQayLwABBBkGyi8AAQQUgAEEMakG4i8AAQciLwABBBCAAQRhqQcyLwABBBCAAQRxqQYSLwABB0IvAAEEQIABB4IvAAEHwi8AAQQsgAkEMahA6IAJBEGokAAtxAQF/IwBBEGsiAiQAIAIgAEETajYCDCABQaeMwABBCEGvjMAAQQogAEGEi8AAQbmMwABBCiAAQQRqQcOMwABBAyAAQQhqQciMwABB2IzAAEELIABBEmpB5IzAAEH0jMAAQQ4gAkEMahA6IAJBEGokAAtvAQF/IwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkEsakHdADYCACACQQM2AgwgAkGU9cAANgIIIAJCAjcCFCACQd0ANgIkIAIgAkEgajYCECACIAJBBGo2AiggAiACNgIgIAJBCGpB4JbAABCjAQALbAEBfyMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBLGpB3QA2AgAgA0ECNgIMIANB0PfAADYCCCADQgI3AhQgA0HdADYCJCADIANBIGo2AhAgAyADNgIoIAMgA0EEajYCICADQQhqIAIQowEAC2YBAn8jAEEQayICJAAgACgCACIDQQFqIQACfyADLQAARQRAIAIgADYCCCABQaGCwABBByACQQhqQaiCwAAQQwwBCyACIAA2AgwgAUG4gsAAQQMgAkEMakG8gsAAEEMLIAJBEGokAAtiAQN/IwBBEGsiAyQAIAEoAgghBCADQQhqIAEoAgAgAjUCABBYIAMoAgwhAiAD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QSBrIgMkACMAQSBrIgQkACAAQQRqIgUgASACED0gBEEUaiICIAUQdiAEQQhqIAUQTSAEKQMIIQYgA0EIaiIBQQhqIAJBCGooAgA2AgAgASAEKQIUNwIAIAEgBjcCDCAEQSBqJAAgA0EANgIcIAMgA0EcaiABEDQgAygCBCEBIAMoAgAEQCADIAE2AhxBlIPAAEErIANBHGpBwIPAAEHUhsAAEGMACyADQQhqEKYBIANBIGokACAAQQA2AgAgAQ8LEP4BAAsQ/wEACzsBAX8CQCACQX9HBEAgAkEBaiEEIAJBIEkNASAEQSAgAxDrAQALIAMQqgEACyAAIAQ2AgQgACABNgIACzkAAkACfyACQYCAxABHBEBBASAAIAIgASgCEBEAAA0BGgsgAw0BQQALDwsgACADIAQgASgCDBEBAAvUAgEDfyAAKAIAIQAgASgCHCIDQRBxRQRAIANBIHFFBEAgADMBACABECoPCyMAQYABayIDJAAgAC8BACECQQAhAANAIAAgA2pB/wBqIAJBD3EiBEEwciAEQTdqIARBCkkbOgAAIABBAWshACACQf//A3EiBEEEdiECIARBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIANqQYABakEAIABrEBggA0GAAWokAA8LIwBBgAFrIgMkACAALwEAIQJBACEAA0AgACADakH/AGogAkEPcSIEQTByIARB1wBqIARBCkkbOgAAIABBAWshACACQf//A3EiBEEEdiECIARBEE8NAAsgAEGAAWoiAkGBAU8EQCACQYABQeD5wAAQ6gEACyABQfD5wABBAiAAIANqQYABakEAIABrEBggA0GAAWokAAs3AQF/IAAoAgAhACABKAIcIgJBEHFFBEAgAkEgcUUEQCAAIAEQ7gEPCyAAIAEQVA8LIAAgARBVCzcBAX8gACgCACEAIAEoAhwiAkEQcUUEQCACQSBxRQRAIAAgARDsAQ8LIAAgARBWDwsgACABEFMLsAIBAn8jAEEgayICJAAgAkEBOwEcIAIgATYCGCACIAA2AhQgAkGM98AANgIQIAJBiPbAADYCDCMAQRBrIgEkACACQQxqIgAoAggiAkUEQEG08cAAEO8BAAsgASAAKAIMNgIMIAEgADYCCCABIAI2AgQjAEEQayIAJAAgAUEE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QZixwAAQnAEACyACIAAgAkEUbGogASACaxAcCyUAIABBATYCBCAAIAEoAgQgASgCAGtBBHYiATYCCCAAIAE2AgALJQAgAEUEQEHQlcAAQTIQ/QEACyAAIAIgAyAEIAUgASgCEBEIAAswACABKAIUIAAtAABBAnQiAEH8h8AAaigCACAAQcSHwABqKAIAIAEoAhgoAgwRAQALMAAgASgCFCAALQAAQQJ0IgBBuJLAAGooAgAgAEGsksAAaigCACABKAIYKAIMEQEACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQEQUACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERgACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERoACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQERwACyMAIABFBEBB0JXAAEEyEP0BAAsgACACIAMgBCABKAIQEQoACygBAX8gACgCACIBQYCAgIB4ckGAgICAeEcEQCAAKAIEIAFBARDlAQsLLgAgASgCFEGgjMAAQZuMwAAgACgCAC0AACIAG0EHQQUgABsgASgCGCgCDBEBAAshACAARQRAQdCVwABBMhD9AQALIAAgAiADIAEoAhARAwALHQEBfyAAKAIAIgEEQCAAKAIEIAFBAnRBBBDlAQsLHQEBfyAAKAIAIgEEQCAAKAIEIAFBFGxBBBDlAQsLHQEBfyAAKAIAIgEEQCAAKAIEIAFBBHRBBBDlAQsLIgAgAC0AAEUEQCABQdz7wABBBRAWDwsgAUHh+8AAQQQQFgsrACABKAIUQYeRwABBgJHAACAALQAAIgAbQQlBByAAGyABKAIYKAIMEQEACysAIAEoAhRBuJHAAEGMjMAAIAAtAAAiABtBC0EGIAAbIAEoAhgoAgwRAQALHwAgAEUEQEHQlcAAQTIQ/QEACyAAIAIgASgCEBEAAAsbABAHIQIgAEEANgIIIAAgAjYCBCAAIAE2AgALwQMCAn4Gf0GMk8EAKAIARQRAIwBBMGsiAyQAAn8CQCAABEAgACgCACAAQQA2AgANAQsgA0EQakGQlMAAKQMANwMAIANBiJTAACkDADcDCEEADAELIANBEGogAEEQaikCADcDACADIAApAgg3AwggACgCBAshAEGMk8EA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IgIgAy0AG08NBCADIAJBAWo6ABogAkEKTw0GIANBEGogAmotAAAhAQwBC0EAIQcgDEEANgIAIAMoAhQhASADQgA3AxALIAogASALEQAARQ0ACwwHCyADLQAaIgFBCiABQQpLGyECIAEgAy0AGyIHIAEgB0sbIQwDQCABIAxGDQEgAyABQQFqIgc6ABogASACRg0DIANBEGogAWohECAHIQEgCiAQLQAAIAsRAABFDQALDAYLAn9BASAGQYABSQ0AGkECIAZBgBBJDQAaQQNBBCAGQYCABEkbCyAFaiECCyAFIAlrIABqIQUgACAPRw0BDAILCyACQQpBnIzBABBsAAsgAkUEQEEAIQIMAQsgAiAETwRAIAIgBEYNAQwDCyACIAhqLAAAQb9/TA0CCyAKIAIgCGogBCACayAOKAIMEQEADQAgCkEiIAsRAAAhDQsgA0EgaiQADAILIAggBCACIARB6PvAABDVAQALIAggBCACIAVB+PvAABDVAQALIA0LFAAgAEEANgIIIABCgICAgBA3AgALEQAgACgCBCAAKAIIIAEQhgILqgIBB38jAEEQayIFJAACQAJAAkAgASgCCCIDIAEoAgBPDQAgBUEIaiEGIwBBIGsiAiQAAkAgASgCACIEIANPBEACf0GBgICAeCAERQ0AGiABKAIEIQcCQCADRQRAQQEhCCAHIARBARDlAQwBC0EBIAcgBEEBIAMQzQEiCEUNARoLIAEgAzYCACABIAg2AgRBgYCAgHgLIQQgBiADNgIEIAYgBDYCACACQSBqJAAMAQsgAkEBNgIMIAJB9O3AADYCCCACQgA3AhQgAkHQ7cAANgIQIAJBCGpByO7AABCjAQALIAUoAggiAkGBgICAeEYNACACRQ0BIAIgBSgCDEHEk8EAKAIAIgBB3gAgABsRAgAACyAFQRBqJAAMAQsQqAEACyAAIAEpAgQ3AwALDgAgACABIAEgAmoQjwELIAAgAEKN04Cn1Nuixjw3AwggAELVnsTj3IPBiXs3AwALIgAgAELiq87AwdHBlKl/NwMIIABCivSnla2v+57uADcDAAsgACAAQsH3+ejMk7LRQTcDCCAAQuTex4WQ0IXefTcDAAsTACAAQdTxwAA2AgQgACABNgIACxAAIAEgACgCACAAKAIEEBYLEAAgASgCFCABKAIYIAAQHQupAQEDfyAA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AgICAgICAgICAgICAgICAgICAgICAgJzAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdHUCAgICAgICdnc5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OXg5OTk5OTk5OTl5egICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICezk5fDk5fQICAgICAgICAgICAgICAgICAgJ+AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICfwICAoCBggICAgICAgICAgICAgICAoOEAgICAgICAgICAoWGdQIChwICAogCAgICAgICiYoCAgICAgICAgICAgICi4wCjY4Cj5CRkpOUlZYClwICmJmamwICAgICAgICAgI5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTmcHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCdAgICAp6fAgQCBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHQICHgICAgICAgIfICEiIwIkJSYnKCkCKgICAgKgoaKjpKWmLqeoqaqrrK0zAgICAgICrgICNTY3Ajg5Ojs8PT6vOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5TAICAgICsE5PsYWGdQIChwICAogCAgICAgICiYoCAgICAgICAgICAgICi4yys44Cj5CRkpOUlZYClwICmJmamwICAgICAgICAgJVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQby/wAALKVVVVVUVAFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBAEHvv8AAC8QBEEEQVVVVVVVXVVVVVVVVVVVVUVVVAABAVPXdVVVVVVVVVVUVAAAAAABVVVVV/F1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQUAFAAUBFBVVVVVVVVVFVFVVVVVVVVVAAAAAAAAQFVVVVVVVVVVVdVXVVVVVVVVVVVVVVUFAABUVVVVVVVVVVVVVVVVVRUAAFVVUVVVVVVVBRAAAAEBUFVVVVVVVVVVVVUBVVVVVVX/////f1VVVVBVAABVVVVVVVVVVVVVBQBBwMHAAAuYBEBVVVVVVVVVVVVVVVVVRVQBAFRRAQBVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVRAFUVVFVFVVVBVVVVVVVVUVBVVVVVVVVVVVVVVVVVVVUQRUUUFFVVVVVVVVVUFFVVUFVVVVVVVVVVVVVVVVVVVQBEFRRVVVVVQVVVVVVVQUAUVVVVVVVVVVVVVVVVVVVBAFUVVFVAVVVBVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVFVFVVUVUVVVVVVVVVVVVVVVRUVVVVVVVVVVVVVVVVVQRUBQRQVUFVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVFEQFBFBVQVVVBVVVVVVVVVVQVVVVVVVVVVVVVVVVVRVEAVRVQVUVVVUFVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVUUVBURVFVVVVVVVVVVVVVVVVVVVVVVVVVVVUQBAVVUVAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRAABUVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVURUVVVVVVVVVVVVVVVVVUBAABAAARVAQAAAQAAAAAAAAAAVFVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEEAEFBVVVVVVVVUAVUVVVVAVRVVUVBVVFVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAEGAxsAAC5ADVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVVVVVVVBVRVVVVVVVUFVVVVVVVVVQVVVVVVVVVVBVVVVX///ff//ddfd9bV11UQAFBVRQEAAFVXUVVVVVVVVVVVVVUVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVUVUVVAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVcVFFVVVVVVVVVVVVVVVVVVRQBARAEAVBUAABRVVVVVVVVVVVVVVVUAAAAAAAAAQFVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVUAAFAFVVVVVVVVVVVVFQAAVVVVUFVVVVVVVVUFUBBQVVVVVVVVVVVVVVVVVUVQEVBVVVVVVVVVVVVVVVVVVQAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAQAVFFVVFBVVVVVVVVVVVVVVVVVVVVVVQBBoMnAAAuTCFVVFQBVVVVVVVUFQFVVVVVVVVVVVVVVVQAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAAAAAAAAAFRVVVVVVVVVVVX1VVVVaVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/VfXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX1VVVVVVV9VVVVVVVVVVVVVVVX///9VVVVVVVVVVVVV1VVVVVXVVVVVXVX1VVVVVX1VX1V1VVdVVVVVdVX1XXVdVV31VVVVVVVVVVdVVVVVVVVVVXfV31VVVVVVVVVVVVVVVVVVVf1VVVVVVVVXVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVdVXVVVVVVVVVVVVVVVVV11VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVBVVVVVVVVVVVVVVVVVVVX9////////////////X1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAAAAAAqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVWqqqqqqqqqqqqqqqqqqgoAqqqqaqmqqqqqqqqqqqqqqqqqqqqqqqqqqmqBqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlWpqqqqqqqqqqqqqqmqqqqqqqqqqqqqqqqoqqqqqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVlaqqqqqqqqqqqqqqaqqqqqqqqqqqqqpVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVVVVVVVVVVVVVVVVVVVVqqqqVqqqqqqqqqqqqqqqqqpqVVVVVVVVVVVVVVVVVV9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVQAAAUFVVVVVVVVUFVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVRUUVVVVVVVVVQVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVUAAAAAUFVFFVVVVVVVVVVVVQUAUFVVVVVVFQAAUFVVVaqqqqqqqqpWQFVVVVVVVVVVVVVVFQVQUFVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVAUBBQVVVFVVVVFVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVQQUVAVRVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFUUVVVVVWqqqqqqqqqqqpVVVUAAAAAAEAVAEG/0cAAC+EMVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAA8KqqWlUAAAAAqqqqqqqqqqpqqqqqqmqqVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFamqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlZVVVVVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVVVqmpVVQAAVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFQFUBQVUAVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVFVVVVVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVVVVVVVVVVVVVUFAABUVVVVVVVVVVVVVVUFUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVAAAAQFVVVVVVVVVVVVUUVFUVUFVVVVVVVVVVVVVVFUBBVUVVVVVVVVVVVVVVVVVVVVVAVVVVVVVVVVUVAAEAVFVVVVVVVVVVVVVVVVVVFVVVVVBVVVVVVVVVVVVVVVUFAEAFVQEUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUARVRVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUVAEBVVVVVVVBVVVVVVVVVVVVVVVVVFURUVVVVVRVVVVUFAFQAVFVVVVVVVVVVVVVVVVVVVVUAAAVEVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVUUAEQRBFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFQVQVRBUVVVVVVVVUFVVVVVVVVVVVVVVVVVVVVVVVVVVFQBAEVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVEAEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBBRAAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVAABBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVRUEEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAFVVRVVVVVVVVVAQBAVVVVVVVVVVVVFQAEQFUVVVUBQAFVVVVVVVVVVVVVAAAAAEBQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBAABBVVVVVVVVVVVVVVVVVVVVVVVVVVQUAAAAAAAUABEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBQEUQAABVVVVVVVVVVVVVVVVVVVVVVVVQEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVUVVVAVVVVVVVVVVVVVVVVBUBVRFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFQAAAFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBUVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVFUBVVVVVVVVVVVVVVVVVVVVVVVVVqlRVVVpVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVVVVVVVqqpWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqmqaaqqqqqqqqqqalVVVWVVVVVVVVVVallVVVWqVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVVVVVVVVQQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBBq97AAAt1UAAAAAAAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRFQBQAAAABAAQBVVVVVVVVVBVBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVAEGt38AACwJAFQBBu9/AAAvFBlRVUVVVVVRVVVVVFQABAAAAVVVVVVVVVVVVVVVVVVVVVVVVVVUAQAAAAAAUABAEQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXVVVVVVVVVVVVVVVVVVVVVdf3/f1VVVVVVVVVVVVVVVVVVVVVVVfX///////9uVVVVqqq6qqqqqur6v79VqqpWVV9VVVWqWlVVVVVVVf//////////V1VV/f/f///////////////////////3//////9VVVX/////////////f9X/VVVV/////1dX//////////////////////9/9//////////////////////////////////////////////////////////////X////////////////////X1VV1X////////9VVVVVdVVVVVVVVX1VVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVXV////////////////////////////VVVVVVVVVVVVVVVV//////////////////////9fVVd//VX/VVXVV1X//1dVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///9VV1VVVVVVVf//////////////f///3/////////////////////////////////////////////////////////////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////V///V1X//////////////9//X1X1////Vf//V1X//1dVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlpVVVVVVVVVVVmWVWGqpVmqVVVVVVWVVVVVVVVVVZVVVQBBjubAAAsBAwBBnObAAAvqLFVVVVVVlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFQCWalpaaqoFQKZZlWVVVVVVVVVVVQAAAABVVlVVqVZVVVVVVVVVVVVWVVVVVVVVVVUAAAAAAAAAAFRVVVWVWVlVVWVVVWlVVVVVVVVVVVVVVZVWlWqqqqpVqqpaVVVVWVWqqqpVVVVVZVVVWlVVVVWlZVZVVVWVVVVVVVVVppaalllZZamWqqpmVapVWllVWlZlVVVVaqqlpVpVVVWlqlpVVVlZVVVZVVVVVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVlVfVVVVVpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVqqqqqqqqqqqqVVVVqqqqqqVaVVWaqlpVpaVVWlqllqVaVVVVpVpVlVVVVX1VaVmlVV9VZlVVVVVVVVVVZlX///9VVVWammqaVVVV1VVVVVXVVVWlXVX1VVVVVb1Vr6q6qquqqppVuqr6rrquVV31VVVVVVVVVVdVVVVVWVVVVXfV31VVVVVVVVWlqqpVVVVVVVXVV1VVVVVVVVVVVVVVVVetWlVVVVVVVVVVVaqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAAAAwKqqWlUAAAAAqqqqqqqqqqpqqqqqqmqqVVVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVWqalVVAABUWaqqalWqqqqqqqqqWqqqqqqqqqqqqqqqqqqqWlWqqqqqqqqquv7/v6qqqqpWVVVVVVVVVVVVVVVVVfX///////9Kc1ZhbHVlKCkAAADANRAACAAAAMg1EAABAAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR53DUQACQAAAAvcnVzdGMvOWIwMDk1NmU1NjAwOWJhYjJhYTE1ZDdiZmYxMDkxNjU5OWUzZDZkNi9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJzCDYQAEwAAADnAQAACQAAAG51bGwgcG9pbnRlciBwYXNzZWQgdG8gcnVzdHJlY3Vyc2l2ZSB1c2Ugb2YgYW4gb2JqZWN0IGRldGVjdGVkIHdoaWNoIHdvdWxkIGxlYWQgdG8gdW5zYWZlIGFsaWFzaW5nIGluIHJ1c3QAAFRyaWVkIHRvIHNocmluayB0byBhIGxhcmdlciBjYXBhY2l0edA2EAAkAAAAL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc/w2EABMAAAA5wEAAAkAAABaAAAADAAAAAQAAABbAAAAXAAAAAQAAABfAAAADAAAAAQAAABgAAAAYQAAAGIAAAAvcnVzdC9kZXBzL2RsbWFsbG9jLTAuMi42L3NyYy9kbG1hbGxvYy5yc2Fzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQAiDcQACkAAACoBAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplIDw9IHNpemUgKyBtYXhfb3ZlcmhlYWQAAIg3EAApAAAArgQAAA0AAABBY2Nlc3NFcnJvcm1lbW9yeSBhbGxvY2F0aW9uIG9mICBieXRlcyBmYWlsZWQAAAA7OBAAFQAAAFA4EAANAAAAbGlicmFyeS9zdGQvc3JjL2FsbG9jLnJzcDgQABgAAABiAQAACQAAAGxpYnJhcnkvc3RkL3NyYy9wYW5pY2tpbmcucnOYOBAAHAAAAIQCAAAeAAAAXwAAAAwAAAAEAAAAYwAAAGQAAAAIAAAABAAAAGUAAABkAAAACAAAAAQAAABmAAAAZwAAAGgAAAAQAAAABAAAAGkAAABqAAAAawAAAAAAAAABAAAAbAAAAEhhc2ggdGFibGUgY2FwYWNpdHkgb3ZlcmZsb3ccORAAHAAAAC9ydXN0L2RlcHMvaGFzaGJyb3duLTAuMTQuMy9zcmMvcmF3L21vZC5ycwAAQDkQACoAAABWAAAAKAAAAEVycm9yAAAAbQAAAAwAAAAEAAAAbgAAAG8AAABwAAAAY2FwYWNpdHkgb3ZlcmZsb3cAAACcORAAEQAAAGxpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMucnO4ORAAHAAAABkAAAAFAAAAYSBmb3JtYXR0aW5nIHRyYWl0IGltcGxlbWVudGF0aW9uIHJldHVybmVkIGFuIGVycm9yAHEAAAAAAAAAAQAAAHIAAABsaWJyYXJ5L2FsbG9jL3NyYy9mbXQucnMoOhAAGAAAAHkCAAAgAAAAKSBzaG91bGQgYmUgPCBsZW4gKGlzIClpbnNlcnRpb24gaW5kZXggKGlzICkgc2hvdWxkIGJlIDw9IGxlbiAoaXMgAABnOhAAFAAAAHs6EAAXAAAAZjoQAAEAAAByZW1vdmFsIGluZGV4IChpcyAAAKw6EAASAAAAUDoQABYAAABmOhAAAQAAAGBhdGAgc3BsaXQgaW5kZXggKGlzIAAAANg6EAAVAAAAezoQABcAAABmOhAAAQAAAGxpYnJhcnkvY29yZS9zcmMvZm10L21vZC5ycykuLjAxMjM0NTY3ODlhYmNkZWZCb3Jyb3dNdXRFcnJvcmFscmVhZHkgYm9ycm93ZWQ6IAAARDsQABIAAABbY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZXoAAAAAAAAAAQAAAHsAAABpbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIAAAnDsQACAAAAC8OxAAEgAAAHwAAAAEAAAABAAAAH0AAAA9PSE9bWF0Y2hlc2Fzc2VydGlvbiBgbGVmdCAgcmlnaHRgIGZhaWxlZAogIGxlZnQ6IAogcmlnaHQ6IAD7OxAAEAAAAAs8EAAXAAAAIjwQAAkAAAAgcmlnaHRgIGZhaWxlZDogCiAgbGVmdDogAAAA+zsQABAAAABEPBAAEAAAAFQ8EAAJAAAAIjwQAAkAAAA6IAAACDsQAAAAAACAPBAAAgAAAHwAAAAMAAAABAAAAH4AAAB/AAAAgAAAACAgICAgeyAsICB7CiwKfSB9KCgKLApdbGlicmFyeS9jb3JlL3NyYy9mbXQvbnVtLnJzAADDPBAAGwAAAGkAAAAXAAAAMHgwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OQAACDsQABsAAAACCAAACQAAAHwAAAAIAAAABAAAAHUAAABmYWxzZXRydWUAAAAIOxAAGwAAAFwJAAAaAAAACDsQABsAAABVCQAAIgAAAHJhbmdlIHN0YXJ0IGluZGV4ICBvdXQgb2YgcmFuZ2UgZm9yIHNsaWNlIG9mIGxlbmd0aCAIPhAAEgAAABo+EAAiAAAAcmFuZ2UgZW5kIGluZGV4IEw+EAAQAAAAGj4QACIAAABzbGljZSBpbmRleCBzdGFydHMgYXQgIGJ1dCBlbmRzIGF0IABsPhAAFgAAAII+EAANAAAAYXR0ZW1wdGVkIHRvIGluZGV4IHNsaWNlIHVwIHRvIG1heGltdW0gdXNpemWgPhAALAAAAFsuLi5dYmVnaW4gPD0gZW5kICggPD0gKSB3aGVuIHNsaWNpbmcgYGDZPhAADgAAAOc+EAAEAAAA6z4QABAAAAD7PhAAAQAAAGJ5dGUgaW5kZXggIGlzIG5vdCBhIGNoYXIgYm91bmRhcnk7IGl0IGlzIGluc2lkZSAgKGJ5dGVzICkgb2YgYAAcPxAACwAAACc/EAAmAAAATT8QAAgAAABVPxAABgAAAPs+EAABAAAAIGlzIG91dCBvZiBib3VuZHMgb2YgYAAAHD8QAAsAAACEPxAAFgAAAPs+EAABAAAAbGlicmFyeS9jb3JlL3NyYy9zdHIvbW9kLnJzALQ/EAAbAAAADQEAACwAAABsaWJyYXJ5L2NvcmUvc3JjL3VuaWNvZGUvcHJpbnRhYmxlLnJzAAAA4D8QACUAAAAaAAAANgAAAOA/EAAlAAAACgAAACsAAAAABgEBAwEEAgUHBwIICAkCCgULAg4EEAERAhIFExEUARUCFwIZDRwFHQgfASQBagRrAq8DsQK8As8C0QLUDNUJ1gLXAtoB4AXhAucE6ALuIPAE+AL6A/sBDCc7Pk5Pj56en3uLk5aisrqGsQYHCTY9Plbz0NEEFBg2N1ZXf6qur7014BKHiY6eBA0OERIpMTQ6RUZJSk5PZGVctrcbHAcICgsUFzY5Oqip2NkJN5CRqAcKOz5maY+SEW9fv+7vWmL0/P9TVJqbLi8nKFWdoKGjpKeorbq8xAYLDBUdOj9FUaanzM2gBxkaIiU+P+fs7//FxgQgIyUmKDM4OkhKTFBTVVZYWlxeYGNlZmtzeH1/iqSqr7DA0K6vbm++k14iewUDBC0DZgMBLy6Agh0DMQ8cBCQJHgUrBUQEDiqAqgYkBCQEKAg0C05DgTcJFgoIGDtFOQNjCAkwFgUhAxsFAUA4BEsFLwQKBwkHQCAnBAwJNgM6BRoHBAwHUEk3Mw0zBy4ICoEmUksrCCoWGiYcFBcJTgQkCUQNGQcKBkgIJwl1C0I+KgY7BQoGUQYBBRADBYCLYh5ICAqApl4iRQsKBg0TOgYKNiwEF4C5PGRTDEgJCkZFG0gIUw1JBwqA9kYKHQNHSTcDDggKBjkHCoE2GQc7AxxWAQ8yDYObZnULgMSKTGMNhDAQFo+qgkehuYI5ByoEXAYmCkYKKAUTgrBbZUsEOQcRQAULAg6X+AiE1ioJoueBMw8BHQYOBAiBjIkEawUNAwkHEJJgRwl0PID2CnMIcBVGehQMFAxXCRmAh4FHA4VCDxWEUB8GBoDVKwU+IQFwLQMaBAKBQB8ROgUBgdAqguaA9ylMBAoEAoMRREw9gMI8BgEEVQUbNAKBDiwEZAxWCoCuOB0NLAQJBwIOBoCag9gEEQMNA3cEXwYMBAEPDAQ4CAoGKAgiToFUDB0DCQc2CA4ECQcJB4DLJQqEBgABAwUFBgYCBwYIBwkRChwLGQwaDRAODA8EEAMSEhMJFgEXBBgBGQMaBxsBHAIfFiADKwMtCy4BMAMxAjIBpwKpAqoEqwj6AvsF/QL+A/8JrXh5i42iMFdYi4yQHN0OD0tM+/wuLz9cXV/ihI2OkZKpsbq7xcbJyt7k5f8ABBESKTE0Nzo7PUlKXYSOkqmxtLq7xsrOz+TlAAQNDhESKTE0OjtFRklKXmRlhJGbncnOzw0RKTo7RUlXW1xeX2RljZGptLq7xcnf5OXwDRFFSWRlgISyvL6/1dfw8YOFi6Smvr/Fx8/a20iYvc3Gzs9JTk9XWV5fiY6Psba3v8HGx9cRFhdbXPb3/v+AbXHe3w4fbm8cHV99fq6vf7u8FhceH0ZHTk9YWlxefn+1xdTV3PDx9XJzj3R1liYuL6evt7/Hz9ffmkCXmDCPH9LUzv9OT1pbBwgPECcv7u9ubzc9P0JFkJFTZ3XIydDR2Nnn/v8AIF8igt8EgkQIGwQGEYGsDoCrBR8JgRsDGQgBBC8ENAQHAwEHBgcRClAPEgdVBwMEHAoJAwgDBwMCAwMDDAQFAwsGAQ4VBU4HGwdXBwIGFwxQBEMDLQMBBBEGDww6BB0lXyBtBGolgMgFgrADGgaC/QNZBxYJGAkUDBQMagYKBhoGWQcrBUYKLAQMBAEDMQssBBoGCwOArAYKBi8xTQOApAg8Aw8DPAc4CCsFgv8RGAgvES0DIQ8hD4CMBIKXGQsViJQFLwU7BwIOGAmAviJ0DIDWGgwFgP8FgN8M8p0DNwmBXBSAuAiAywUKGDsDCgY4CEYIDAZ0Cx4DWgRZCYCDGBwKFglMBICKBqukDBcEMaEEgdomBwwFBYCmEIH1BwEgKgZMBICNBIC+AxsDDw1saWJyYXJ5L2NvcmUvc3JjL3VuaWNvZGUvdW5pY29kZV9kYXRhLnJzpEUQACgAAABQAAAAKAAAAKRFEAAoAAAAXAAAABYAAABsaWJyYXJ5L2NvcmUvc3JjL2VzY2FwZS5ycwAA7EUQABoAAAA4AAAACwAAAFx1ewDsRRAAGgAAAGYAAAAjAAAAAAMAAIMEIACRBWAAXROgABIXIB8MIGAf7yygKyowICxvpuAsAqhgLR77YC4A/iA2nv9gNv0B4TYBCiE3JA3hN6sOYTkvGKE5MBxhSPMeoUxANGFQ8GqhUU9vIVKdvKFSAM9hU2XRoVMA2iFUAODhVa7iYVfs5CFZ0OihWSAA7lnwAX9aAHAABwAtAQEBAgECAQFICzAVEAFlBwIGAgIBBCMBHhtbCzoJCQEYBAEJAQMBBSsDPAgqGAEgNwEBAQQIBAEDBwoCHQE6AQEBAgQIAQkBCgIaAQICOQEEAgQCAgMDAR4CAwELAjkBBAUBAgQBFAIWBgEBOgEBAgEECAEHAwoCHgE7AQEBDAEJASgBAwE3AQEDBQMBBAcCCwIdAToBAgECAQMBBQIHAgsCHAI5AgEBAgQIAQkBCgIdAUgBBAECAwEBCAFRAQIHDAhiAQIJCwdJAhsBAQEBATcOAQUBAgULASQJAWYEAQYBAgICGQIEAxAEDQECAgYBDwEAAwADHQIeAh4CQAIBBwgBAgsJAS0DAQF1AiIBdgMEAgkBBgPbAgIBOgEBBwEBAQECCAYKAgEwHzEEMAcBAQUBKAkMAiAEAgIBAzgBAQIDAQEDOggCApgDAQ0BBwQBBgEDAsZAAAHDIQADjQFgIAAGaQIABAEKIAJQAgABAwEEARkCBQGXAhoSDQEmCBkLLgMwAQIEAgInAUMGAgICAgwBCAEvATMBAQMCAgUCAQEqAggB7gECAQQBAAEAEBAQAAIAAeIBlQUAAwECBQQoAwQBpQIABAACUANGCzEEewE2DykBAgIKAzEEAgIHAT0DJAUBCD4BDAI0CQoEAgFfAwIBAQIGAQIBnQEDCBUCOQIBAQEBFgEOBwMFwwgCAwEBFwFRAQIGAQECAQECAQLrAQIEBgIBAhsCVQgCAQECagEBAQIGAQFlAwIEAQUACQEC9QEKAgEBBAGQBAICBAEgCigGAgQIAQkGAgMuDQECAAcBBgEBUhYCBwECAQJ6BgMBAQIBBwEBSAIDAQEBAAILAjQFBQEBAQABBg8ABTsHAAE/BFEBAAIALgIXAAEBAwQFCAgCBx4ElAMANwQyCAEOARYFAQ8ABwERAgcBAgEFZAGgBwABPQQABAAHbQcAYIDwAHsJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjc4LjAgKDliMDA5NTZlNSAyMDI0LTA0LTI5KQZ3YWxydXMGMC4yMC4zDHdhc20tYmluZGdlbhIwLjIuOTIgKDJhNGE0OTM2MikALA90YXJnZXRfZmVhdHVyZXMCKw9tdXRhYmxlLWdsb2JhbHMrCHNpZ24tZXh0");class f{constructor(){let A=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.speed=A,this.startTime=performance.now()}getTime(){return this.speed*(performance.now()-this.startTime)/1e3}setTime(A){this.startTime=performance.now()-A/this.speed*1e3}}class U{constructor(){}getTime(A){}setTime(A){}}class Y{constructor(A,g){this.input="function"==typeof A.next?A:A[Symbol.iterator](),this.xfs=g??[]}map(A){return this.transform(function(A){return g=>I=>{g(A(I))}}(A))}flatMap(A){return this.transform(function(A){return g=>I=>{A(I).forEach(g)}}(A))}filter(A){return this.transform(function(A){return g=>I=>{A(I)&&g(I)}}(A))}take(A){return this.transform(function(A){let g=0;return I=>B=>{gB=>{g+=1,g>A&&I(B)}}(A))}transform(A){return new Y(this.input,this.xfs.concat([A]))}multiplex(A,g){return new Y(new L(this[Symbol.iterator](),A[Symbol.iterator](),g))}toArray(){return Array.from(this)}[Symbol.iterator](){let A=0,g=[],I=!1;const B=(Q=this.xfs,C=A=>g.push(A),Q.reverse().reduce(((A,g)=>{const I=S(g(A.step));return{step:I.step,flush:()=>{I.flush(),A.flush()}}}),S(C)));var Q,C;return{next:()=>{for(A===g.length&&(g=[],A=0);0===g.length;){const A=this.input.next();if(A.done)break;B.step(A.value)}return 0!==g.length||I||(B.flush(),I=!0),g.length>0?{done:!1,value:g[A++]}:{done:!0}}}}}function S(A){return"function"==typeof A?{step:A,flush:()=>{}}:A}class L{constructor(A,g,I){this.left=A,this.right=g,this.comparator=I}[Symbol.iterator](){let A,g;return{next:()=>{if(void 0===A&&void 0!==this.left){const g=this.left.next();g.done?this.left=void 0:A=g.value}if(void 0===g&&void 0!==this.right){const A=this.right.next();A.done?this.right=void 0:g=A.value}if(void 0===A&&void 0===g)return{done:!0};if(void 0===A){const A=g;return g=void 0,{done:!1,value:A}}if(void 0===g){const g=A;return A=void 0,{done:!1,value:g}}if(this.comparator(A,g)){const g=A;return A=void 0,{done:!1,value:g}}{const A=g;return g=void 0,{done:!1,value:A}}}}}}async function p(A){if(A instanceof Response){const g=await A.text(),I=function(A){const g=A.split("\n");let I;try{I=JSON.parse(g[0])}catch(A){return}const B=new Y(g).drop(1).filter((A=>"["===A[0])).map(JSON.parse);return{header:I,events:B}}(g);if(void 0!==I){const{header:A,events:g}=I;if(2===A.version)return H(A,g);if(3===A.version)return m(A,g);throw`asciicast v${A.version} format not supported`}{const A=JSON.parse(g);if(1===A.version)return K(A)}}else{if("object"==typeof A&&1===A.version)return K(A);if(Array.isArray(A)){const g=A[0];if(2===g.version){return H(g,A.slice(1,A.length))}if(3===g.version){return m(g,A.slice(1,A.length))}throw`asciicast v${g.version} format not supported`}}throw"invalid data"}function K(A){let g=0;const I=new Y(A.stdout).map((A=>(g+=A[0],[g,"o",A[1]])));return{cols:A.width,rows:A.height,events:I}}function H(A,g){return{cols:A.width,rows:A.height,theme:b(A.theme),events:g,idleTimeLimit:A.idle_time_limit}}function m(A,g){g instanceof Y||(g=new Y(g));let I=0;return g=g.map((A=>(I+=A[0],[I,A[1],A[2]]))),{cols:A.term.cols,rows:A.term.rows,theme:b(A.term?.theme),events:g,idleTimeLimit:A.idle_time_limit}}function b(A){if(void 0===A)return;const g=/^#[0-9A-Fa-f]{6}$/,I=A?.fg,B=A?.bg,Q=A?.palette;return g.test(I)&&g.test(B)&&/^(#[0-9A-Fa-f]{6}:){7,}#[0-9A-Fa-f]{6}$/.test(Q)?{foreground:I,background:B,palette:Q.split(":")}:void 0}function v(A){return"number"==typeof A?[A,"m",""]:[A[0],"m",A[1]]}function T(){let A=0;return function(g){return"m"===g[1]?[g[0],g[1],{index:A++,time:g[0],label:g[2]}]:g}}class x{constructor(){this.items=[],this.onPush=void 0}push(A){this.items.push(A),void 0!==this.onPush&&(this.onPush(this.popAll()),this.onPush=void 0)}popAll(){if(this.items.length>0){const A=this.items;return this.items=[],A}{const A=this;return new Promise((g=>{A.onPush=g}))}}}function O(A,g,I,B,Q,C,E,V,i){const e=function(A,g,I,B){return function(Q,C){"o"===Q?A(C):"i"===Q?I(C):"r"===Q?g(C.cols,C.rows):"m"===Q&&B(C)}}(g,I,B,Q);if(0===A)return i.debug("using no buffer"),function(A){return{pushEvent(g){A(g[1],g[2])},pushText(g){A("o",g)},stop(){}}}(e);{let g;return"number"==typeof(A=A??{})?(i.debug(`using fixed time buffer (${A} ms)`),g=g=>A):"function"==typeof A?(i.debug("using custom dynamic buffer"),g=A({logger:i})):(i.debug("using adaptive buffer",A),g=function(A,g){let{logger:I}=A,{minTime:B=25,maxLevel:Q=100,interval:C=50,windowSize:E=20,smoothingFactor:V=.2,minImprovementDuration:i=1e3}=g,e=0,o=a(e),t=[],s=0,n=0,r=null;function a(A){return 0===A?B:C*A}return A=>{if(t.push(A),t.lengthgg>A?g:A))}(t);s=B*V+s*(1-V),n=(B-g)*V+n*(1-V);const C=s+n;if(A>o&&I.debug("buffer underrun",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o}),eo)o=a(e+=1),I.debug("jitter increased, raising bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o});else if(e>1&&Ci&&(r=performance.now(),o=a(e-=1),I.debug("jitter decreased, lowering bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:o})),o;return r=null,o}}({logger:i},A)),function(A,g,I,B,Q){let C=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1/60,E=performance.now()-1e3*Q,V=A(0);const i=new x;C*=1e3;let e=-C,o=!1;function t(){return performance.now()-E}return setTimeout((async()=>{for(;!o;){const A=await i.popAll();if(o)return;for(const B of A){const A=1e3*B[0]+V;if(A-e0&&(await W(Q),o))return;I(B[0]),g(B[1],B[2]),e=A}}}),0),{pushEvent(g){let I=t()-1e3*g[0];I<0&&(B.debug(`correcting epoch by ${I} ms`),E+=I,I=0),V=A(I),i.push(g)},pushText(A){i.push([t()/1e3,"o",A])},stop(){o=!0,i.push(void 0)}}}(g,e,C,i,E??0,V)}}function W(A){return new Promise((g=>{setTimeout(g,A)}))}const j=1e6;function Z(A){const g=new TextDecoder,I=new TextDecoder;let B,Q=function(A){const g=(new TextDecoder).decode(A);if("ALiS"!==g)throw"not an ALiS v1 live stream";Q=E},C=0;function E(A){const g=new _(new DataView(A)),I=g.getUint8();if(1!==I)throw`expected reset (0x01) frame, got ${I}`;return V(g,A)}function V(A,I){A.decodeVarUint();let E=A.decodeVarUint();B=E,E/=j,C=0;const V=A.decodeVarUint(),e=A.decodeVarUint(),o=A.getUint8();let t;if(8===o){const g=30;t=X(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(16===o){const g=54;t=X(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(0!==o)throw`alis: invalid theme format (${o})`;const s=A.decodeVarUint();let n;return s>0&&(n=g.decode(new Uint8Array(I,A.offset,s))),Q=i,{time:E,term:{size:{cols:V,rows:e},theme:t,init:n}}}function i(i){const e=new _(new DataView(i)),o=e.getUint8();return 1===o?V(e,i):111===o?function(A,I){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=g.decode(new Uint8Array(I,A.offset,C));return[B/j,"o",E]}(e,i):105===o?function(A,g){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=I.decode(new Uint8Array(g,A.offset,C));return[B/j,"i",E]}(e,i):114===o?function(A){A.decodeVarUint();const g=A.decodeVarUint();B+=g;const I=A.decodeVarUint(),Q=A.decodeVarUint();return[B/j,"r",{cols:I,rows:Q}]}(e):109===o?function(A,g){A.decodeVarUint();const I=A.decodeVarUint();B+=I;const Q=A.decodeVarUint(),E=new TextDecoder,V=C++,i=B/j,e=E.decode(new Uint8Array(g,A.offset,Q));return[i,"m",{index:V,time:i,label:e}]}(e,i):4===o?(Q=E,!1):void A.debug(`alis: unknown frame type: ${o}`)}return function(A){return Q(A)}}function X(A){const g=A.length/3,I=P(A[0],A[1],A[2]),B=P(A[3],A[4],A[5]),Q=[];for(let I=2;I1&&void 0!==arguments[1]?arguments[1]:0;this.inner=A,this.offset=g}forward(A){this.offset+=A}getUint8(){const A=this.inner.getUint8(this.offset);return this.offset+=1,A}decodeVarUint(){let A=BigInt(0),g=BigInt(0),I=this.getUint8();for(;I>127;)I&=127,A+=BigInt(I)<(await R(u),J))();class QA{constructor(A){this.core=A,this.driver=A.driver}onEnter(A){}init(){}play(){}pause(){}togglePlay(){}seek(A){return!1}step(A){}stop(){this.driver.stop()}}class CA extends QA{async init(){try{return await this.core._initializeDriver(),this.core._setState("idle")}catch(A){throw this.core._setState("errored"),A}}async play(){this.core._dispatchEvent("play");const A=await this.init();await A.doPlay()}async togglePlay(){await this.play()}async seek(A){const g=await this.init();return await g.seek(A)}async step(A){const g=await this.init();await g.step(A)}stop(){}}class EA extends QA{onEnter(A){let{reason:g,message:I}=A;this.core._dispatchEvent("idle",{message:I}),"paused"===g&&this.core._dispatchEvent("pause")}async play(){this.core._dispatchEvent("play"),await this.doPlay()}async doPlay(){const A=await this.driver.play();!0===A?this.core._setState("playing"):"function"==typeof A&&(this.core._setState("playing"),this.driver.stop=A)}async togglePlay(){await this.play()}seek(A){return this.driver.seek(A)}step(A){this.driver.step(A)}}class VA extends QA{onEnter(){this.core._dispatchEvent("playing")}pause(){!0===this.driver.pause()&&this.core._setState("idle",{reason:"paused"})}togglePlay(){this.pause()}seek(A){return this.driver.seek(A)}}class iA extends QA{onEnter(){this.core._dispatchEvent("loading")}}class eA extends QA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("offline",{message:g})}}class oA extends QA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("ended",{message:g})}async play(){this.core._dispatchEvent("play"),await this.driver.restart()&&this.core._setState("playing")}async togglePlay(){await this.play()}seek(A){return!0===this.driver.seek(A)&&(this.core._setState("idle"),!0)}}class tA extends QA{onEnter(){this.core._dispatchEvent("errored")}}class sA{constructor(A,I){this.logger=I.logger,this.state=new CA(this),this.stateName="uninitialized",this.driver=function(A){if("function"==typeof A)return A;"string"==typeof A&&(A="ws://"==A.substring(0,5)||"wss://"==A.substring(0,6)?{driver:"websocket",url:A}:"clock:"==A.substring(0,6)?{driver:"clock"}:"random:"==A.substring(0,7)?{driver:"random"}:"benchmark:"==A.substring(0,10)?{driver:"benchmark",url:A.substring(10)}:{driver:"recording",url:A});void 0===A.driver&&(A.driver="recording");if("recording"==A.driver&&(void 0===A.parser&&(A.parser="asciicast"),"string"==typeof A.parser)){if(!rA.has(A.parser))throw`unknown parser: ${A.parser}`;A.parser=rA.get(A.parser)}if(nA.has(A.driver)){const g=nA.get(A.driver);return(I,B)=>g(A,I,B)}throw`unsupported driver: ${JSON.stringify(A)}`}(A),this.changedLines=new Set,this.cursor=void 0,this.duration=void 0,this.cols=I.cols,this.rows=I.rows,this.speed=I.speed,this.loop=I.loop,this.autoPlay=I.autoPlay,this.idleTimeLimit=I.idleTimeLimit,this.preload=I.preload,this.startAt=g(I.startAt),this.poster=this._parsePoster(I.poster),this.markers=this._normalizeMarkers(I.markers),this.pauseOnMarkers=I.pauseOnMarkers,this.commandQueue=Promise.resolve(),this.eventHandlers=new Map([["ended",[]],["errored",[]],["idle",[]],["input",[]],["loading",[]],["marker",[]],["metadata",[]],["offline",[]],["pause",[]],["play",[]],["playing",[]],["ready",[]],["reset",[]],["resize",[]],["seeked",[]],["terminalUpdate",[]]])}async init(){this.wasm=await BA;const A=this._feed.bind(this),g=this._now.bind(this),I=this._resetVt.bind(this),B=this._resizeVt.bind(this),Q=this._setState.bind(this),C="npt"===this.poster.type?this.poster.value:void 0;this.driver=this.driver({feed:A,onInput:A=>{this._dispatchEvent("input",{data:A})},onMarker:A=>{let{index:g,time:I,label:B}=A;this._dispatchEvent("marker",{index:g,time:I,label:B})},reset:I,resize:B,now:g,setTimeout:(A,g)=>setTimeout(A,g/this.speed),setInterval:(A,g)=>setInterval(A,g/this.speed),setState:Q,logger:this.logger},{cols:this.cols,rows:this.rows,idleTimeLimit:this.idleTimeLimit,startAt:this.startAt,loop:this.loop,posterTime:C,markers:this.markers,pauseOnMarkers:this.pauseOnMarkers}),"function"==typeof this.driver&&(this.driver={play:this.driver}),(this.preload||void 0!==C)&&this._withState((A=>A.init()));const E="text"===this.poster.type?this._renderPoster(this.poster.value):null,V={isPausable:!!this.driver.pause,isSeekable:!!this.driver.seek,poster:E};if(void 0===this.driver.init&&(this.driver.init=()=>({})),void 0===this.driver.pause&&(this.driver.pause=()=>{}),void 0===this.driver.seek&&(this.driver.seek=A=>!1),void 0===this.driver.step&&(this.driver.step=A=>{}),void 0===this.driver.stop&&(this.driver.stop=()=>{}),void 0===this.driver.restart&&(this.driver.restart=()=>{}),void 0===this.driver.getCurrentTime){const A=this.driver.play;let g=new U;this.driver.play=()=>(g=new f(this.speed),A()),this.driver.getCurrentTime=()=>g.getTime()}this._dispatchEvent("ready",V),this.autoPlay&&this.play()}play(){return this._withState((A=>A.play()))}pause(){return this._withState((A=>A.pause()))}togglePlay(){return this._withState((A=>A.togglePlay()))}seek(A){return this._withState((async g=>{await g.seek(A)&&this._dispatchEvent("seeked")}))}step(A){return this._withState((g=>g.step(A)))}stop(){return this._withState((A=>A.stop()))}getChanges(){const A={};if(this.changedLines.size>0){const g=new Map,I=this.vt.rows;for(const A of this.changedLines)A1&&void 0!==arguments[1]?arguments[1]:{};for(const I of this.eventHandlers.get(A))I(g)}_withState(A){return this._enqueueCommand((()=>A(this.state)))}_enqueueCommand(A){return this.commandQueue=this.commandQueue.then(A),this.commandQueue}_setState(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.stateName===A)return this.state;if(this.stateName=A,"playing"===A)this.state=new VA(this);else if("idle"===A)this.state=new EA(this);else if("loading"===A)this.state=new iA(this);else if("ended"===A)this.state=new oA(this);else if("offline"===A)this.state=new eA(this);else{if("errored"!==A)throw`invalid state: ${A}`;this.state=new tA(this)}return this.state.onEnter(g),this.state}_feed(A){this._doFeed(A),this._dispatchEvent("terminalUpdate")}_doFeed(A){this.vt.feed(A).forEach((A=>this.changedLines.add(A))),this.cursor=void 0}_now(){return performance.now()*this.speed}async _initializeDriver(){const A=await this.driver.init();this.cols=this.cols??A.cols??80,this.rows=this.rows??A.rows??24,this.duration=this.duration??A.duration,this.markers=this._normalizeMarkers(A.markers)??this.markers??[],0===this.cols&&(this.cols=80),0===this.rows&&(this.rows=24),this._initializeVt(this.cols,this.rows);const g=void 0!==A.poster?this._renderPoster(A.poster):null;this._dispatchEvent("metadata",{cols:this.cols,rows:this.rows,duration:this.duration,markers:this.markers,theme:A.theme,poster:g})}_resetVt(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,B=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;this.logger.debug(`core: vt reset (${A}x${g})`),this.cols=A,this.rows=g,this.cursor=void 0,this._initializeVt(A,g),void 0!==I&&""!==I&&this._doFeed(I),this._dispatchEvent("reset",{cols:A,rows:g,theme:B})}_resizeVt(A,g){if(A===this.vt.cols&&g===this.vt.rows)return;this.vt.resize(A,g).forEach((A=>this.changedLines.add(A))),this.cursor=void 0,this.vt.cols=A,this.vt.rows=g,this.logger.debug(`core: vt resize (${A}x${g})`),this._dispatchEvent("resize",{cols:A,rows:g})}_initializeVt(A,g){this.vt=this.wasm.create(A,g,!0,100),this.vt.cols=A,this.vt.rows=g,this.changedLines.clear();for(let A=0;AB.feed(A)));const Q=B.getCursor()??!1,C=[];for(let A=0;A"number"==typeof A?[A,""]:A))}}const nA=new Map([["benchmark",function(A,g){let I,{url:B,iterations:Q=10}=A,{feed:C,setState:E,now:V}=g,i=0;return{async init(){const A=await p(await fetch(B)),{cols:g,rows:Q,events:C}=A;I=Array.from(C).filter((A=>{let[g,I,B]=A;return"o"===I})).map((A=>{let[g,I,B]=A;return[g,B]}));const E=I[I.length-1][0];for(const[A,g]of I)i+=new Blob([g]).size;return{cols:g,rows:Q,duration:E}},play(){const A=V();for(let A=0;A{E("stopped",{reason:"ended"})}),0),!0}}}],["clock",function(A,g,I){let{hourColor:B=3,minuteColor:Q=4,separatorColor:C=9}=A,{feed:E}=g,{cols:V=5,rows:i=1}=I;const e=Math.floor(i/2),o=Math.floor(V/2)-2,t=`[?25l[${e}B`;let s;const n=()=>{const A=new Date,g=A.getHours(),I=A.getMinutes(),E=[];E.push("\r");for(let A=0;A{n().forEach(E)};return{init:()=>{const A=[t].concat(n());return{cols:V,rows:i,duration:1440,poster:A}},play:()=>(E(t),r(),s=setInterval(r,1e3),!0),stop:()=>{clearInterval(s)},getCurrentTime:()=>{const A=new Date;return 60*A.getHours()+A.getMinutes()}}}],["eventsource",function(A,g){let I,Q,{url:C,bufferTime:E,minFrameTime:V}=A,{feed:i,reset:e,resize:o,onInput:t,onMarker:s,setState:n,logger:r}=g;r=new B(r,"eventsource: ");let a=new U;function c(A){void 0!==Q&&Q.stop(),Q=O(E,i,o,t,s,(A=>a.setTime(A)),A,V,r)}return{play:()=>{I=new EventSource(C),I.addEventListener("open",(()=>{r.info("opened"),c()})),I.addEventListener("error",(A=>{r.info("errored"),r.debug({e:A}),n("loading")})),I.addEventListener("message",(A=>{const g=JSON.parse(A.data);if(Array.isArray(g))Q.pushEvent(g);else if(void 0!==g.cols||void 0!==g.width){const A=g.cols??g.width,I=g.rows??g.height;r.debug(`vt reset (${A}x${I})`),n("playing"),c(g.time),e(A,I,g.init??void 0),a=new f,"number"==typeof g.time&&a.setTime(g.time)}else"offline"===g.state&&(r.info("stream offline"),n("offline",{message:"Stream offline"}),a=new U)})),I.addEventListener("done",(()=>{r.info("closed"),I.close(),n("ended",{message:"Stream ended"})}))},stop:()=>{void 0!==Q&&Q.stop(),void 0!==I&&I.close()},getCurrentTime:()=>a.getTime()}}],["random",function(A,g){let{feed:I,setTimeout:B}=g;const Q=" ".charCodeAt(0),C="~".charCodeAt(0)-Q;let E;const V=()=>{const A=Math.pow(5,4*Math.random());E=B(i,A)},i=()=>{V();const A=String.fromCharCode(Q+Math.floor(Math.random()*C));I(A)};return()=>(V(),()=>clearInterval(E))}],["recording",function(A,g,I){let B,Q,C,E,V,i,e,o,t,{feed:s,resize:n,onInput:r,onMarker:a,now:c,setTimeout:D,setState:w,logger:l}=g,{idleTimeLimit:h,startAt:y,loop:G,posterTime:k,markers:F,pauseOnMarkers:N,cols:q,rows:R}=I,J=0,d=0,M=0;async function u(A,g){const I=await fetch(A,g);if(!I.ok)throw`failed fetching recording from ${A}: ${I.status} ${I.statusText}`;return I}function f(){const A=C[J];A?e=D(U,function(A){let g=1e3*A-(c()-o);return g<0&&(g=0),g}(A[0])):p()}function U(){let A,g=C[J];do{d=g[0],J++;if(L(g))return;g=C[J],A=c()-o}while(g&&A>1e3*g[0]);f()}function S(){clearTimeout(e),e=null}function L(A){const[g,I,B]=A;if("o"===I)s(B);else if("i"===I)r(B);else if("r"===I){const[A,g]=B.split("x");n(A,g)}else if("m"===I&&(a(B),N))return K(),t=1e3*g,w("idle",{reason:"paused"}),!0;return!1}function p(){S(),M++,!0===G||"number"==typeof G&&M>"===A?A=I+5:"<<<"===A?A=I-.1*V:">>>"===A?A=I+.1*V:"%"===A[A.length-1]&&(A=parseFloat(A.substring(0,A.length-1))/100*V);else if("object"==typeof A)if("prev"===A.marker)A=b(I)??0,g&&I-A<1&&(A=b(A)??0);else if("next"===A.marker)A=function(A){if(0==E.length)return;let g,I=E.length-1,B=E[I];for(;B&&B[0]>A;)g=B[0],B=E[--I];return g}(I)??V;else if("number"==typeof A.marker){const g=E[A.marker];if(void 0===g)throw`invalid marker index: ${A.marker}`;A=g[0]}const B=Math.min(Math.max(A,0),V);B1&&void 0!==arguments[1]?arguments[1]:1/60;return B=>{let Q=0,C=0;return{step:A=>{Q++,void 0!==g?"o"===A[1]&&"o"===g[1]&&A[0]-g[0]{void 0!==g&&(B(g),C++),A.debug(`batched ${Q} frames to ${C} frames`)}}}}(g,C)).map(function(A,g,I){let B=0,Q=0;return function(C){const E=C[0]-B-A;return B=C[0],E>0&&(Q+=E,C[0]"m"!==A[1])).multiplex(V,((A,g)=>A[0]"i"===A[1]?[A[0]+E,A[1],A[2]]:A)),i.sort(((A,g)=>A[0]-g[0])));const o=i[i.length-1][0],t=B-e.offset;return{...A,events:i,duration:o,effectiveStartAt:t}}(await g(await function(A){let{url:g,data:I,fetchOpts:B={}}=A;if("string"==typeof g)return u(g,B);if(Array.isArray(g))return Promise.all(g.map((A=>u(A,B))));if(void 0!==I)return"function"==typeof I&&(I=I()),I instanceof Promise||(I=Promise.resolve(I)),I.then((A=>"string"==typeof A||A instanceof ArrayBuffer?new Response(A):A));throw"failed fetching recording file: url/data missing in src"}(A),{encoding:t}),l,{idleTimeLimit:h,startAt:y,minFrameTime:I,inputOffset:e,markers_:F});if(({cols:B,rows:Q,events:C,duration:V,effectiveStartAt:i}=s),q=q??B,R=R??Q,0===C.length)throw"recording is missing events";void 0!==o&&function(A,g){const I=document.createElement("a"),B=A.events.map((A=>"m"===A[1]?[A[0],A[1],A[2].label]:A)),Q=function(A){return`${JSON.stringify({version:2,width:A.cols,height:A.rows})}\n${A.events.map(JSON.stringify).join("\n")}\n`}({...A,events:B});I.href=URL.createObjectURL(new Blob([Q],{type:"text/plain"})),I.download=g,I.click()}(s,o);const n=void 0!==k?(r=k,C.filter((A=>A[0]A[2]))):void 0;var r;return E=C.filter((A=>"m"===A[1])).map((A=>[A[0],A[2].label])),{cols:B,rows:Q,duration:V,theme:s.theme,poster:n,markers:E}},play:function(){if(e)throw"already playing";if(void 0===C[J])throw"already ended";return null!==i&&m(i),H(),!0},pause:K,seek:m,step:function(A){let g,I;if(void 0===A&&(A=1),A>0){let B=J;g=C[B];for(let Q=0;Q{const A=I.protocol||"raw";a.info("opened"),a.info(`activating ${A} protocol handler`),"v1.alis"===A?I.onmessage=k(Z(a)):"v2.asciicast"===A?I.onmessage=k(function(){let A=function(I){const B=JSON.parse(I);if(2!==B.version)throw"not an asciicast v2 stream";return A=g,{time:0,term:{size:{cols:B.width,rows:B.height}}}};function g(A){const g=JSON.parse(A);if("r"===g[1]){const[A,I]=g[2].split("x");return[g[0],"r",{cols:A,rows:I}]}return g}return function(g){return A(g)}}()):"raw"===A&&(I.onmessage=k($())),c=setTimeout((()=>{l=0}),1e3)},I.onclose=A=>{if(clearTimeout(D),q(),h||1e3===A.code||1005===A.code)a.info("closed"),r("ended",{message:"Stream ended"});else if(1002===A.code)a.debug(`close reason: ${A.reason}`),r("ended",{message:"Err: Player not compatible with the server"});else{clearTimeout(c);const A=V(l++);a.info(`unclean close, reconnecting in ${A}...`),r("loading"),setTimeout(G,A)}},y=!1}function k(A){return D=setTimeout(N,5e3),function(g){try{const I=A(g.data);if(Q)if(Array.isArray(I))Q.pushEvent(I);else if("string"==typeof I)Q.pushText(I);else if("object"!=typeof I||Array.isArray(I)){if(!1===I)N();else if(void 0!==I)throw`unexpected value from protocol handler: ${I}`}else F(I);else if("object"!=typeof I||Array.isArray(I)){if(void 0!==I)throw clearTimeout(D),`unexpected value from protocol handler: ${I}`;clearTimeout(D),D=setTimeout(N,1e3)}else F(I),clearTimeout(D)}catch(A){throw I.close(),A}}}function F(A){let{time:g,term:I}=A;const{size:B,init:C,theme:V}=I,{cols:c,rows:D}=B;a.info(`stream reset (${c}x${D} @${g})`),r("playing"),q(),Q=O(E,e,t,s,n,(A=>w.setTime(A)),g,i,a),o(c,D,C,V),w=new f,y=!0,"number"==typeof g&&w.setTime(g)}function N(){q(),y?(a.info("stream ended"),r("offline",{message:"Stream ended"})):(a.info("stream offline"),r("offline",{message:"Stream offline"})),w=new U}function q(){Q&&Q.stop(),Q=null}return{play:()=>{G()},stop:()=>{h=!0,q(),void 0!==I&&I.close()},getCurrentTime:()=>w.getTime()}}]]),rA=new Map([["asciicast",p],["typescript",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I);let Q,C,E=(await A[0].text()).split("\n").filter((A=>A.length>0)).map((A=>A.split(" ")));E[0].length<3&&(E=E.map((A=>["O",A[0],A[1]])));const V=await A[1].arrayBuffer(),i=new Uint8Array(V),e=i.findIndex((A=>10==A))+1,o=B.decode(i.subarray(0,e)).match(/COLUMNS="(\d+)" LINES="(\d+)"/);null!==o&&(Q=parseInt(o[1],10),C=parseInt(o[2],10));const t={array:i,cursor:e};let s=t;if(void 0!==A[2]){const g=await A[2].arrayBuffer();s={array:new Uint8Array(g),cursor:e}}const n=[];let r=0;for(const A of E)if(r+=parseFloat(A[1]),"O"===A[0]){const g=parseInt(A[2],10),I=t.array.subarray(t.cursor,t.cursor+g),Q=B.decode(I);n.push([r,"o",Q]),t.cursor+=g}else if("I"===A[0]){const g=parseInt(A[2],10),I=s.array.subarray(s.cursor,s.cursor+g),Q=B.decode(I);n.push([r,"i",Q]),s.cursor+=g}else if("S"===A[0]&&"SIGWINCH"===A[2]){const g=parseInt(A[4].slice(5),10),I=parseInt(A[3].slice(5),10);n.push([r,"r",`${g}x${I}`])}else"H"===A[0]&&"COLUMNS"===A[2]?Q=parseInt(A[3],10):"H"===A[0]&&"LINES"===A[2]&&(C=parseInt(A[3],10));return Q=Q??80,C=C??24,{cols:Q,rows:C,events:n}}],["ttyrec",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I),Q=await A.arrayBuffer(),C=new Uint8Array(Q),E=gA(C),V=E.time,i=B.decode(E.data).match(/\x1b\[8;(\d+);(\d+)t/),e=[];let o=80,t=24;null!==i&&(o=parseInt(i[2],10),t=parseInt(i[1],10));let s=0,n=gA(C);for(;void 0!==n;){const A=n.time-V,g=B.decode(n.data);e.push([A,"o",g]),s+=n.len,n=gA(C.subarray(s))}return{cols:o,rows:t,events:e}}]]);const aA=Symbol("solid-proxy"),cA="function"==typeof Proxy,DA=Symbol("solid-track"),wA={equals:(A,g)=>A===g};let lA=OA;const hA=1,yA=2,GA={owned:null,cleanups:null,context:null,owner:null};var kA=null;let FA=null,NA=null,qA=null,RA=null,JA=0;function dA(A,g){const I=NA,B=kA,Q=0===A.length,C=void 0===g?B:g,E=Q?GA:{owned:null,cleanups:null,context:C?C.context:null,owner:C},V=Q?A:()=>A((()=>YA((()=>XA(E)))));kA=E,NA=null;try{return xA(V,!0)}finally{NA=I,kA=B}}function MA(A,g){const I={value:A,observers:null,observerSlots:null,comparator:(g=g?Object.assign({},wA,g):wA).equals||void 0};return[HA.bind(I),A=>("function"==typeof A&&(A=A(I.value)),mA(I,A))]}function uA(A,g,I){bA(vA(A,g,!1,hA))}function fA(A,g,I){I=I?Object.assign({},wA,I):wA;const B=vA(A,g,!0,0);return B.observers=null,B.observerSlots=null,B.comparator=I.equals||void 0,bA(B),HA.bind(B)}function UA(A){return xA(A,!1)}function YA(A){if(null===NA)return A();const g=NA;NA=null;try{return A()}finally{NA=g}}function SA(A){!function(A,g,I){lA=WA;const B=vA(A,g,!1,hA);I&&I.render||(B.user=!0),RA?RA.push(B):bA(B)}((()=>YA(A)))}function LA(A){return null===kA||(null===kA.cleanups?kA.cleanups=[A]:kA.cleanups.push(A)),A}function pA(){return NA}function KA(A){const g=fA(A),I=fA((()=>zA(g())));return I.toArray=()=>{const A=I();return Array.isArray(A)?A:null!=A?[A]:[]},I}function HA(){if(this.sources&&this.state)if(this.state===hA)bA(this);else{const A=qA;qA=null,xA((()=>jA(this)),!1),qA=A}if(NA){const A=this.observers?this.observers.length:0;NA.sources?(NA.sources.push(this),NA.sourceSlots.push(A)):(NA.sources=[this],NA.sourceSlots=[A]),this.observers?(this.observers.push(NA),this.observerSlots.push(NA.sources.length-1)):(this.observers=[NA],this.observerSlots=[NA.sources.length-1])}return this.value}function mA(A,g,I){let B=A.value;return A.comparator&&A.comparator(B,g)||(A.value=g,A.observers&&A.observers.length&&xA((()=>{for(let g=0;g1e6)throw qA=[],new Error}),!1)),g}function bA(A){if(!A.fn)return;XA(A);const g=JA;!function(A,g,I){let B;const Q=kA,C=NA;NA=kA=A;try{B=A.fn(g)}catch(g){return A.pure&&(A.state=hA,A.owned&&A.owned.forEach(XA),A.owned=null),A.updatedAt=I+1,PA(g)}finally{NA=C,kA=Q}(!A.updatedAt||A.updatedAt<=I)&&(null!=A.updatedAt&&"observers"in A?mA(A,B):A.value=B,A.updatedAt=I)}(A,A.value,g)}function vA(A,g,I,B=hA,Q){const C={fn:A,state:B,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:g,owner:kA,context:kA?kA.context:null,pure:I};return null===kA||kA!==GA&&(kA.owned?kA.owned.push(C):kA.owned=[C]),C}function TA(A){if(0===A.state)return;if(A.state===yA)return jA(A);if(A.suspense&&YA(A.suspense.inFallback))return A.suspense.effects.push(A);const g=[A];for(;(A=A.owner)&&(!A.updatedAt||A.updatedAt=0;I--)if((A=g[I]).state===hA)bA(A);else if(A.state===yA){const I=qA;qA=null,xA((()=>jA(A,g[0])),!1),qA=I}}function xA(A,g){if(qA)return A();let I=!1;g||(qA=[]),RA?I=!0:RA=[],JA++;try{const g=A();return function(A){qA&&(OA(qA),qA=null);if(A)return;const g=RA;RA=null,g.length&&xA((()=>lA(g)),!1)}(I),g}catch(A){I||(RA=null),qA=null,PA(A)}}function OA(A){for(let g=0;g=0;g--)XA(A.tOwned[g]);delete A.tOwned}if(A.owned){for(g=A.owned.length-1;g>=0;g--)XA(A.owned[g]);A.owned=null}if(A.cleanups){for(g=A.cleanups.length-1;g>=0;g--)A.cleanups[g]();A.cleanups=null}A.state=0}function PA(A,g=kA){const I=function(A){return A instanceof Error?A:new Error("string"==typeof A?A:"Unknown error",{cause:A})}(A);throw I}function zA(A){if("function"==typeof A&&!A.length)return zA(A());if(Array.isArray(A)){const g=[];for(let I=0;IA(g||{})))}function gg(){return!0}const Ig={get:(A,g,I)=>g===aA?I:A.get(g),has:(A,g)=>g===aA||A.has(g),set:gg,deleteProperty:gg,getOwnPropertyDescriptor:(A,g)=>({configurable:!0,enumerable:!0,get:()=>A.get(g),set:gg,deleteProperty:gg}),ownKeys:A=>A.keys()};function Bg(A){return(A="function"==typeof A?A():A)?A:{}}function Qg(){for(let A=0,g=this.length;A`Stale read from <${A}>.`;function Eg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B=[],Q=[],C=[],E=0,V=g.length>1?[]:null;return LA((()=>$A(C))),()=>{let i,e,o=A()||[],t=o.length;return o[DA],YA((()=>{let A,g,n,r,a,c,D,w,l;if(0===t)0!==E&&($A(C),C=[],B=[],Q=[],E=0,V&&(V=[])),I.fallback&&(B=[_A],Q[0]=dA((A=>(C[0]=A,I.fallback()))),E=1);else if(0===E){for(Q=new Array(t),e=0;e=c&&w>=c&&B[D]===o[w];D--,w--)n[w]=Q[D],r[w]=C[D],V&&(a[w]=V[D]);for(A=new Map,g=new Array(w+1),e=w;e>=c;e--)l=o[e],i=A.get(l),g[e]=void 0===i?-1:i,A.set(l,e);for(i=c;i<=D;i++)l=B[i],e=A.get(l),void 0!==e&&-1!==e?(n[e]=Q[i],r[e]=C[i],V&&(a[e]=V[i]),e=g[e],A.set(l,e)):C[i]();for(e=c;eA.each),A.children,g||void 0))}function Vg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B,Q=[],C=[],E=[],V=[],i=0;return LA((()=>$A(E))),()=>{const e=A()||[],o=e.length;return e[DA],YA((()=>{if(0===o)return 0!==i&&($A(E),E=[],Q=[],C=[],i=0,V=[]),I.fallback&&(Q=[_A],C[0]=dA((A=>(E[0]=A,I.fallback()))),i=1),C;for(Q[0]===_A&&(E[0](),E=[],Q=[],C=[],i=0),B=0;Be[B])):B>=Q.length&&(C[B]=dA(t));for(;BA.each),A.children,g||void 0))}function ig(A){const g=A.keyed,I=fA((()=>A.when),void 0,void 0),B=g?I:fA(I,void 0,{equals:(A,g)=>!A==!g});return fA((()=>{const Q=B();if(Q){const C=A.children;return"function"==typeof C&&C.length>0?YA((()=>C(g?Q:()=>{if(!YA(B))throw Cg("Show");return I()}))):C}return A.fallback}),void 0,void 0)}function eg(A){const g=KA((()=>A.children)),I=fA((()=>{const A=g(),I=Array.isArray(A)?A:[A];let B=()=>{};for(let A=0;AC()?void 0:Q.when),void 0,void 0),V=Q.keyed?E:fA(E,void 0,{equals:(A,g)=>!A==!g});B=()=>C()||(V()?[g,E,Q]:void 0)}return B}));return fA((()=>{const g=I()();if(!g)return A.fallback;const[B,Q,C]=g,E=C.children;return"function"==typeof E&&E.length>0?YA((()=>E(C.keyed?Q():()=>{if(YA(I)()?.[0]!==B)throw Cg("Match");return Q()}))):E}),void 0,void 0)}function og(A){return A}const tg="_$DX_DELEGATE";function sg(A,g,I,B={}){let Q;return dA((B=>{Q=B,g===document?A():lg(g,A(),g.firstChild?null:void 0,I)}),B.owner),()=>{Q(),g.textContent=""}}function ng(A,g,I,B){let Q;const C=()=>{const g=B?document.createElementNS("http://www.w3.org/1998/Math/MathML","template"):document.createElement("template");return g.innerHTML=A,I?g.content.firstChild.firstChild:B?g.firstChild:g.content.firstChild},E=g?()=>YA((()=>document.importNode(Q||(Q=C()),!0))):()=>(Q||(Q=C())).cloneNode(!0);return E.cloneNode=E,E}function rg(A,g=window.document){const I=g[tg]||(g[tg]=new Set);for(let B=0,Q=A.length;BB.call(A,I[1],g))}else A.addEventListener(g,I,"function"!=typeof I&&I)}function Dg(A,g,I){if(!g)return I?function(A,g,I){null==I?A.removeAttribute(g):A.setAttribute(g,I)}(A,"style"):g;const B=A.style;if("string"==typeof g)return B.cssText=g;let Q,C;for(C in"string"==typeof I&&(B.cssText=I=void 0),I||(I={}),g||(g={}),I)null==g[C]&&B.removeProperty(C),delete I[C];for(C in g)Q=g[C],Q!==I[C]&&(B.setProperty(C,Q),I[C]=Q);return I}function wg(A,g,I){return YA((()=>A(g,I)))}function lg(A,g,I,B){if(void 0===I||B||(B=[]),"function"!=typeof g)return yg(A,g,B,I);uA((B=>yg(A,g(),B,I)),B)}function hg(A){let g=A.target;const I=`$$${A.type}`,B=A.target,Q=A.currentTarget,C=g=>Object.defineProperty(A,"target",{configurable:!0,value:g}),E=()=>{const B=g[I];if(B&&!g.disabled){const Q=g[`${I}Data`];if(void 0!==Q?B.call(g,Q,A):B.call(g,A),A.cancelBubble)return}return g.host&&"string"!=typeof g.host&&!g.host._$host&&g.contains(A.target)&&C(g.host),!0},V=()=>{for(;E()&&(g=g._$host||g.parentNode||g.host););};if(Object.defineProperty(A,"currentTarget",{configurable:!0,get:()=>g||document}),A.composedPath){const I=A.composedPath();C(I[0]);for(let A=0;A{let Q=g();for(;"function"==typeof Q;)Q=Q();I=yg(A,Q,I,B)})),()=>I;if(Array.isArray(g)){const C=[],V=I&&Array.isArray(I);if(Gg(C,g,I,Q))return uA((()=>I=yg(A,C,I,B,!0))),()=>I;if(0===C.length){if(I=Fg(A,I,B),E)return I}else V?0===I.length?kg(A,C,B):function(A,g,I){let B=I.length,Q=g.length,C=B,E=0,V=0,i=g[Q-1].nextSibling,e=null;for(;EB-V){const Q=g[E];for(;V=0;C--){const E=g[C];if(Q!==E){const g=E.parentNode===A;B||C?g&&E.remove():g?A.replaceChild(Q,E):A.insertBefore(Q,I)}else B=!0}}else A.insertBefore(Q,I);return[Q]}const Ng=Symbol("store-raw"),qg=Symbol("store-node"),Rg=Symbol("store-has"),Jg=Symbol("store-self");function dg(A){let g=A[aA];if(!g&&(Object.defineProperty(A,aA,{value:g=new Proxy(A,Sg)}),!Array.isArray(A))){const I=Object.keys(A),B=Object.getOwnPropertyDescriptors(A);for(let Q=0,C=I.length;Qg===Ng||g===aA||g===DA||g===qg||g===Rg||"__proto__"===g||(pA()&&Ug(fg(A,Rg),g)(),g in A),set:()=>!0,deleteProperty:()=>!0,ownKeys:function(A){return Yg(A),Reflect.ownKeys(A)},getOwnPropertyDescriptor:function(A,g){const I=Reflect.getOwnPropertyDescriptor(A,g);return I&&!I.get&&I.configurable&&g!==aA&&g!==qg?(delete I.value,delete I.writable,I.get=()=>A[aA][g],I):I}};function Lg(A,g,I,B=!1){if(!B&&A[g]===I)return;const Q=A[g],C=A.length;void 0===I?(delete A[g],A[Rg]&&A[Rg][g]&&void 0!==Q&&A[Rg][g].$()):(A[g]=I,A[Rg]&&A[Rg][g]&&void 0===Q&&A[Rg][g].$());let E,V=fg(A,qg);if((E=Ug(V,g,Q))&&E.$((()=>I)),Array.isArray(A)&&A.length!==C){for(let g=A.length;g1){B=g.shift();const C=typeof B,E=Array.isArray(A);if(Array.isArray(B)){for(let Q=0;Q1)return void Kg(A[B],g,[B].concat(I));Q=A[B],I=[B].concat(I)}let C=g[0];"function"==typeof C&&(C=C(Q,I),C===Q)||void 0===B&&null==C||(C=ug(C),void 0===B||Mg(Q)&&Mg(C)&&!Array.isArray(C)?pg(Q,C):Lg(A,B,C))}function Hg(...[A,g]){const I=ug(A||{}),B=Array.isArray(I);return[dg(I),function(...A){UA((()=>{B&&1===A.length?function(A,g){if("function"==typeof g&&(g=g(A)),g=ug(g),Array.isArray(g)){if(A===g)return;let I=0,B=g.length;for(;I=E&&i>=E&&(C[V]===A[i]||Q&&C[V]&&A[i]&&C[V][Q]===A[i][Q]);V--,i--)s[i]=C[V];if(E>i||E>V){for(I=E;I<=i;I++)Lg(C,I,A[I]);for(;IA.length&&Lg(C,"length",A.length))}for(o=new Array(i+1),I=i;I>=E;I--)e=A[I],t=Q&&e?e[Q]:e,g=n.get(t),o[I]=void 0===g?-1:g,n.set(t,I);for(g=E;g<=V;g++)e=C[g],t=Q&&e?e[Q]:e,I=n.get(t),void 0!==I&&-1!==I&&(s[I]=C[g],I=o[I],n.set(t,I));for(I=E;IA.length&&Lg(C,"length",A.length))}const V=Object.keys(A);for(let g=0,I=V.length;g{if(!Mg(A)||!Mg(Q))return Q;const g=bg(Q,{[mg]:A},mg,I,B);return void 0===g?A:g}}const Tg=ng("",2);var xg=A=>{const g=fA((()=>{if(1==A.text.length){const g=A.text.codePointAt(0);if(g>=9600&&g<=9631||57520==g||57522==g)return g}})),I=fA((()=>g()?" ":A.text)),B=fA((()=>function(A,g,I){const B=A.get("fg"),Q=A.get("bg");let C={"--offset":g,width:`${I+.01}ch`};"string"==typeof B&&(C["--fg"]=B);"string"==typeof Q&&(C["--bg"]=Q);return C}(A.pen,A.offset,A.cellCount))),Q=fA((()=>function(A,g,I){const B=Og(A.get("fg"),A.get("bold"),"fg-"),Q=Og(A.get("bg"),!1,"bg-");let C=I??"";void 0!==g&&(C+=` cp-${g.toString(16)}`);B&&(C+=" "+B);Q&&(C+=" "+Q);A.has("bold")&&(C+=" ap-bright");A.has("faint")&&(C+=" ap-faint");A.has("italic")&&(C+=" ap-italic");A.has("underline")&&(C+=" ap-underline");A.has("blink")&&(C+=" ap-blink");A.get("inverse")&&(C+=" ap-inverse");return C}(A.pen,g(),A.extraClass)));return(()=>{const A=Tg.cloneNode(!0);return lg(A,I),uA((g=>{const I=Q(),C=B();return I!==g._v$&&ag(A,g._v$=I),g._v$2=Dg(A,C,g._v$2),g}),{_v$:void 0,_v$2:void 0}),A})()};function Og(A,g,I){if("number"==typeof A)return g&&A<8&&(A+=8),`${I}${A}`}const Wg=ng('',2);var jg=A=>(()=>{const g=Wg.cloneNode(!0);return lg(g,Ag(Vg,{get each(){return(()=>{if("number"==typeof A.cursor){const g=[];let I=0,B=0;for(;B0&&g.push({...Q,text:i.slice(0,V).join("")}),g.push({...Q,text:i[V],offset:I+E,cellCount:C,extraClass:"ap-cursor"}),VAg(xg,function(...A){let g=!1;for(let I=0;I=0;I--){const B=Bg(A[I])[g];if(void 0!==B)return B}},has(g){for(let I=A.length-1;I>=0;I--)if(g in Bg(A[I]))return!0;return!1},keys(){const g=[];for(let I=0;I=0;g--){const Q=A[g];if(!Q)continue;const C=Object.getOwnPropertyNames(Q);for(let A=C.length-1;A>=0;A--){const g=C[A];if("__proto__"===g||"constructor"===g)continue;const E=Object.getOwnPropertyDescriptor(Q,g);if(B[g]){const A=I[g];A&&(E.get?A.push(E.get.bind(Q)):void 0!==E.value&&A.push((()=>E.value)))}else B[g]=E.get?{enumerable:!0,configurable:!0,get:Qg.bind(I[g]=[E.get.bind(Q)])}:void 0!==E.value?E:void 0}}const Q={},C=Object.keys(B);for(let A=C.length-1;A>=0;A--){const g=C[A],I=B[g];I&&I.get?Object.defineProperty(Q,g,I):Q[g]=I?I.value:void 0}return Q}(A))})),g})();const Zg=ng('
    ',2);var Xg=A=>{const g=()=>A.lineHeight??1.3333333333,I=fA((()=>({width:`${A.cols}ch`,height:g()*A.rows+"em","font-size":100*(A.scale||1)+"%","font-family":A.fontFamily,"--term-line-height":`${g()}em`,"--term-cols":A.cols}))),B=fA((()=>A.cursor?.[0])),Q=fA((()=>A.cursor?.[1]));return(()=>{const g=Zg.cloneNode(!0),C=A.ref;return"function"==typeof C?wg(C,g):A.ref=g,lg(g,Ag(Eg,{get each(){return A.lines},children:(A,g)=>Ag(jg,{get segments(){return A.segments},get cursor(){return(A=()=>g()===Q(),fA((()=>A())))()?B():null;var A}})})),uA((B=>{const Q=!(!A.blink&&!A.cursorHold),C=!!A.blink,E=I();return Q!==B._v$&&g.classList.toggle("ap-cursor-on",B._v$=Q),C!==B._v$2&&g.classList.toggle("ap-blink",B._v$2=C),B._v$3=Dg(g,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})()};const Pg=ng('',6),zg=ng('',4),_g=ng('',2),$g=ng('',6),AI=ng('
    Keyboard shortcuts (?)Fullscreen (f)
    ',34),gI=ng('',6);function II(A){let g=Math.floor(A);const I=Math.floor(g/86400);g%=86400;const B=Math.floor(g/3600);g%=3600;const Q=Math.floor(g/60);return g%=60,I>0?`${BI(I)}:${BI(B)}:${BI(Q)}:${BI(g)}`:B>0?`${BI(B)}:${BI(Q)}:${BI(g)}`:`${BI(Q)}:${BI(g)}`}function BI(A){return A<10?`0${A}`:A.toString()}var QI=A=>{const g=A=>g=>{g.preventDefault(),A(g)},I=()=>"number"==typeof A.currentTime?II(A.currentTime):"--:--",B=()=>"number"==typeof A.remainingTime?"-"+II(A.remainingTime):I(),Q=fA((()=>"number"==typeof A.duration?A.markers.filter((g=>g[0]{const g=A.currentTarget.offsetWidth,I=A.currentTarget.getBoundingClientRect(),B=A.clientX-I.left;return 100*Math.max(0,B/g)+"%"},[E,V]=MA(!1),i=function(A,g){let I=!0;return function(){if(I){I=!1;for(var B=arguments.length,Q=new Array(B),C=0;CI=!0),g)}}}(A.onSeekClick,50),e=g=>{g._marker||g.altKey||g.shiftKey||g.metaKey||g.ctrlKey||0!==g.button||(V(!0),A.onSeekClick(C(g)))},o=A=>{A.altKey||A.shiftKey||A.metaKey||A.ctrlKey||E()&&i(C(A))},t=()=>{V(!1)};return document.addEventListener("mouseup",t),LA((()=>{document.removeEventListener("mouseup",t)})),(()=>{const C=AI.cloneNode(!0),E=C.firstChild,V=E.firstChild,i=V.nextSibling,t=E.nextSibling,s=t.nextSibling,n=s.nextSibling,r=A.ref;return"function"==typeof r?wg(r,C):A.ref=C,lg(C,Ag(ig,{get when(){return A.isPausable},get children(){const I=_g.cloneNode(!0);return cg(I,"click",g(A.onPlayClick),!0),lg(I,Ag(eg,{get children(){return[Ag(og,{get when(){return A.isPlaying},get children(){return Pg.cloneNode(!0)}}),Ag(og,{get when(){return!A.isPlaying},get children(){return zg.cloneNode(!0)}})]}})),I}}),E),lg(V,I),lg(i,B),lg(t,Ag(ig,{get when(){return"number"==typeof A.progress||A.isSeekable},get children(){const I=$g.cloneNode(!0),B=I.firstChild.nextSibling;return I.$$mousemove=o,I.$$mousedown=e,lg(I,Ag(Eg,{get each(){return Q()},children:(I,B)=>(()=>{const Q=gI.cloneNode(!0),C=Q.firstChild,E=C.nextSibling;var V;return Q.$$mousedown=A=>{A._marker=!0},cg(Q,"click",(V=B(),g((()=>{A.onSeekClick({marker:V})}))),!0),lg(E,(()=>(A=>""===A[1]?II(A[0]):`${II(A[0])} - ${A[1]}`)(I))),uA((g=>{const B=(g=>g[0]/A.duration*100+"%")(I),E=!!(g=>"number"==typeof A.currentTime&&g[0]<=A.currentTime)(I);return B!==g._v$&&Q.style.setProperty("left",g._v$=B),E!==g._v$2&&C.classList.toggle("ap-marker-past",g._v$2=E),g}),{_v$:void 0,_v$2:void 0}),Q})()}),null),uA((g=>Dg(B,{transform:`scaleX(${A.progress||0}`},g))),I}})),cg(s,"click",g(A.onHelpClick),!0),cg(n,"click",g(A.onFullscreenClick),!0),uA((()=>C.classList.toggle("ap-seekable",!!A.isSeekable))),C})()};rg(["click","mousedown","mousemove"]);const CI=ng('
    💥
    ',4);var EI=A=>CI.cloneNode(!0);const VI=ng('
    ',4);var iI=A=>VI.cloneNode(!0);const eI=ng('
    ',4);var oI=A=>(()=>{const g=eI.cloneNode(!0),I=g.firstChild;return lg(I,(()=>A.message)),uA((g=>Dg(I,{"font-family":A.fontFamily},g))),g})();const tI=ng('
    ',22);var sI=A=>(()=>{const g=tI.cloneNode(!0);var I;return cg(g,"click",(I=A.onClick,A=>{A.preventDefault(),I(A)}),!0),g})();rg(["click"]);const nI=ng("
  • space - pause / resume
  • ",4),rI=ng("
  • / - rewind / fast-forward by 5 seconds
  • ",6),aI=ng("
  • Shift + / - rewind / fast-forward by 10%
  • ",8),cI=ng("
  • [ / ] - jump to the previous / next marker
  • ",6),DI=ng("
  • 0, 1, 2 ... 9 - jump to 0%, 10%, 20% ... 90%
  • ",10),wI=ng("
  • , / . - step back / forward, a frame at a time (when paused)
  • ",6),lI=ng('

    Keyboard shortcuts

    • f - toggle fullscreen mode
    • ? - toggle this help popup
    ',18);var hI=A=>(()=>{const g=lI.cloneNode(!0),I=g.firstChild,B=I.firstChild.firstChild.nextSibling,Q=B.firstChild;var C;return cg(g,"click",(C=A.onClose,A=>{A.preventDefault(),C(A)}),!0),I.$$click=A=>{A.stopPropagation()},lg(B,Ag(ig,{get when(){return A.isPausable},get children(){return nI.cloneNode(!0)}}),Q),lg(B,Ag(ig,{get when(){return A.isSeekable},get children(){return[rI.cloneNode(!0),aI.cloneNode(!0),cI.cloneNode(!0),DI.cloneNode(!0),wI.cloneNode(!0)]}}),Q),uA((I=>Dg(g,{"font-family":A.fontFamily},I))),g})();rg(["click"]);const yI=ng('
    ',4);var GI=A=>{const g=A.logger,I=A.core,B=A.autoPlay,[Q,C]=Hg({lines:[],cursor:void 0,charW:A.charW,charH:A.charH,bordersW:A.bordersW,bordersH:A.bordersH,containerW:0,containerH:0,isPausable:!0,isSeekable:!0,isFullscreen:!1,currentTime:null,remainingTime:null,progress:null,blink:!0,cursorHold:!1}),[E,V]=MA(!1),[i,e]=MA(B?null:"start"),[o,t]=MA(null),[s,n]=MA({cols:A.cols,rows:A.rows},{equals:(A,g)=>A.cols===g.cols&&A.rows===g.rows}),[r,a]=MA(void 0),[c,D]=Hg([]),[w,l]=MA(!1),[h,y]=MA(!1),[G,k]=MA(void 0),F=fA((()=>s().cols||80)),N=fA((()=>s().rows||24)),q=()=>!1===A.controls?0:32;let R,J,d,M,u,f,U,Y,S,L;function p(){gA(),_(),$()}function K(A){UA((()=>{A.rows{L=A}));I.addEventListener("ready",(A=>{let{isPausable:g,isSeekable:I,poster:B}=A;C({isPausable:g,isSeekable:I}),H(B),L()})),I.addEventListener("metadata",(A=>{let{cols:g,rows:I,duration:B,theme:Q,poster:C,markers:E}=A;UA((()=>{K({cols:g,rows:I}),a(B),k(Q),D(E),H(C)}))})),I.addEventListener("play",(()=>{e(null)})),I.addEventListener("playing",(()=>{UA((()=>{V(!0),e(null),T(),AA(),z()}))})),I.addEventListener("idle",(()=>{UA((()=>{V(!1),p()}))})),I.addEventListener("loading",(()=>{UA((()=>{V(!1),p(),e("loader")}))})),I.addEventListener("offline",(A=>{let{message:g}=A;UA((()=>{V(!1),p(),void 0!==g&&(t(g),e("info"))}))}));let b=0;I.addEventListener("ended",(A=>{let{message:I}=A;UA((()=>{V(!1),p(),void 0!==I&&(t(I),e("info"))})),g.debug(`view: render count: ${b}`)})),I.addEventListener("errored",(()=>{e("error")})),I.addEventListener("resize",K),I.addEventListener("reset",(A=>{let{cols:g,rows:I,theme:B}=A;UA((()=>{K({cols:g,rows:I}),k(B),T()}))})),I.addEventListener("seeked",(()=>{$()})),I.addEventListener("terminalUpdate",(()=>{void 0===R&&(R=requestAnimationFrame(T))}));const v=()=>{S=new ResizeObserver(function(A,g){let I;return function(){for(var B=arguments.length,Q=new Array(B),C=0;CA.apply(this,Q)),g)}}((A=>{C({containerW:u.offsetWidth,containerH:u.offsetHeight}),u.dispatchEvent(new CustomEvent("resize",{detail:{el:f}}))}),10)),S.observe(u)};SA((async()=>{g.info("view: mounted"),g.debug("view: font measurements",{charW:Q.charW,charH:Q.charH}),v(),C({containerW:u.offsetWidth,containerH:u.offsetHeight})})),LA((()=>{I.stop(),gA(),_(),S.disconnect()}));const T=async()=>{const A=await I.getChanges();UA((()=>{void 0!==A.lines&&A.lines.forEach(((A,g)=>{C("lines",g,vg(A))})),void 0!==A.cursor&&C("cursor",vg(A.cursor)),C("cursorHold",!0)})),R=void 0,b+=1},x=fA((()=>{const g=Q.charW*F()+Q.bordersW,I=Q.charH*N()+Q.bordersH;let B=A.fit??"width";if("both"===B||Q.isFullscreen){B=Q.containerW/(Q.containerH-q())>g/I?"height":"width"}if(!1===B||"none"===B)return{};if("width"===B){const A=Q.containerW/g;return{scale:A,width:Q.containerW,height:I*A+q()}}if("height"===B){const A=(Q.containerH-q())/I;return{scale:A,width:g*A,height:Q.containerH}}throw`unsupported fit mode: ${B}`})),O=()=>{C("isFullscreen",document.fullscreenElement??document.webkitFullscreenElement)},W=()=>{Q.isFullscreen?(document.exitFullscreen??document.webkitExitFullscreen??(()=>{})).apply(document):(u.requestFullscreen??u.webkitRequestFullscreen??(()=>{})).apply(u)},j=()=>{h()?y(!1):(I.pause(),y(!0))},Z=A=>{if(!(A.altKey||A.metaKey||A.ctrlKey)){if(" "==A.key)I.togglePlay();else if(","==A.key)I.step(-1),$();else if("."==A.key)I.step(),$();else if("f"==A.key)W();else if("["==A.key)I.seek({marker:"prev"});else if("]"==A.key)I.seek({marker:"next"});else if(A.key.charCodeAt(0)>=48&&A.key.charCodeAt(0)<=57){const g=(A.key.charCodeAt(0)-48)/10;I.seek(100*g+"%")}else if("?"==A.key)j();else if("ArrowLeft"==A.key)A.shiftKey?I.seek("<<<"):I.seek("<<");else if("ArrowRight"==A.key)A.shiftKey?I.seek(">>>"):I.seek(">>");else{if("Escape"!=A.key)return;y(!1)}A.stopPropagation(),A.preventDefault()}},X=()=>{Q.isFullscreen&&IA(!0)},P=()=>{Q.isFullscreen||IA(!1)},z=()=>{d=setInterval($,100)},_=()=>{clearInterval(d)},$=async()=>{const A=await I.getCurrentTime(),g=await I.getRemainingTime(),B=await I.getProgress();C({currentTime:A,remainingTime:g,progress:B})},AA=()=>{M=setInterval((()=>{C((A=>{const g={blink:!A.blink};return g.blink&&(g.cursorHold=!1),g}))}),600)},gA=()=>{clearInterval(M),C("blink",!0)},IA=A=>{clearTimeout(J),A&&(J=setTimeout((()=>IA(!1)),2e3)),l(A)},BA=fA((()=>{const g=A.theme||"auto/asciinema";return"auto/"===g.slice(0,5)?{name:g.slice(5),colors:G()}:{name:g}})),QA=()=>{m.then((()=>I.play()))},CA=()=>{m.then((()=>I.togglePlay()))},EA=A=>{m.then((()=>I.seek(A)))},VA=(()=>{const g=yI.cloneNode(!0),I=g.firstChild;"function"==typeof u?wg(u,g):u=g,g.addEventListener("webkitfullscreenchange",O),g.addEventListener("fullscreenchange",O),g.$$mousemove=X,g.$$keydown=Z;return"function"==typeof f?wg(f,I):f=I,I.$$mousemove=()=>IA(!0),I.addEventListener("mouseleave",P),lg(I,Ag(Xg,{get cols(){return F()},get rows(){return N()},get scale(){return x()?.scale},get blink(){return Q.blink},get lines(){return Q.lines},get cursor(){return Q.cursor},get cursorHold(){return Q.cursorHold},get fontFamily(){return A.terminalFontFamily},get lineHeight(){return A.terminalLineHeight},ref(A){"function"==typeof U?U(A):U=A}}),null),lg(I,Ag(ig,{get when(){return!1!==A.controls},get children(){return Ag(QI,{get duration(){return r()},get currentTime(){return Q.currentTime},get remainingTime(){return Q.remainingTime},get progress(){return Q.progress},markers:c,get isPlaying(){return E()},get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable},onPlayClick:CA,onFullscreenClick:W,onHelpClick:j,onSeekClick:EA,ref(A){"function"==typeof Y?Y(A):Y=A}})}}),null),lg(I,Ag(eg,{get children(){return[Ag(og,{get when(){return"start"==i()},get children(){return Ag(sI,{onClick:QA})}}),Ag(og,{get when(){return"loader"==i()},get children(){return Ag(iI,{})}}),Ag(og,{get when(){return"info"==i()},get children(){return Ag(oI,{get message(){return o()},get fontFamily(){return A.terminalFontFamily}})}}),Ag(og,{get when(){return"error"==i()},get children(){return Ag(EI,{})}})]}}),null),lg(I,Ag(ig,{get when(){return h()},get children(){return Ag(hI,{get fontFamily(){return A.terminalFontFamily},onClose:()=>y(!1),get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable}})}}),null),uA((B=>{const Q=!!(!0===A.controls||"auto"===A.controls&&w()),C=`ap-player asciinema-player-theme-${BA().name}`,E=(()=>{const g={};!1!==A.fit&&"none"!==A.fit||void 0===A.terminalFontSize||("small"===A.terminalFontSize?g["font-size"]="12px":"medium"===A.terminalFontSize?g["font-size"]="18px":"big"===A.terminalFontSize?g["font-size"]="24px":g["font-size"]=A.terminalFontSize);const I=x();void 0!==I.width&&(g.width=`${I.width}px`,g.height=`${I.height}px`);const B=BA().colors;return B&&(g["--term-color-foreground"]=B.foreground,g["--term-color-background"]=B.background,B.palette.forEach(((A,I)=>{g[`--term-color-${I}`]=A}))),g})();return Q!==B._v$&&g.classList.toggle("ap-hud",B._v$=Q),C!==B._v$2&&ag(I,B._v$2=C),B._v$3=Dg(I,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})();return VA};function kI(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const B=function(A,g){const I=80,B=24,Q=document.createElement("div");let C;Q.style.height="0px",Q.style.overflow="hidden",Q.style.fontSize="15px",document.body.appendChild(Q);const E=sg((()=>(C=Ag(Xg,{cols:I,rows:B,lineHeight:g,fontFamily:A,lines:[]}),C)),Q),V={charW:C.clientWidth/I,charH:C.clientHeight/B,bordersW:C.offsetWidth-C.clientWidth,bordersH:C.offsetHeight-C.clientHeight};return E(),document.body.removeChild(Q),V}(I.terminalFontFamily,I.terminalLineHeight),Q={core:A,logger:I.logger,cols:I.cols,rows:I.rows,fit:I.fit,controls:I.controls,autoPlay:I.autoPlay,terminalFontSize:I.terminalFontSize,terminalFontFamily:I.terminalFontFamily,terminalLineHeight:I.terminalLineHeight,theme:I.theme,...B};let C;const E=sg((()=>(C=Ag(GI,Q),C)),g);return{el:C,dispose:E}}rg(["keydown","mousemove"]);const FI=["autoPlay","autoplay","cols","idleTimeLimit","loop","markers","pauseOnMarkers","poster","preload","rows","speed","startAt"],NI=["autoPlay","autoplay","cols","controls","fit","rows","terminalFontFamily","terminalFontSize","terminalLineHeight","theme"];return A.create=function(A,g){let B=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const Q=B.logger??new I,C=new sA(A,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return FI.includes(g)})));return I.autoPlay??=I.autoplay,I.speed??=1,{...I,...g}}(B,{logger:Q})),{el:E,dispose:V}=kI(C,g,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return NI.includes(g)})));return I.autoPlay??=I.autoplay,I.controls??="auto",{...I,...g}}(B,{logger:Q})),i=C.init(),e={el:E,dispose:V,getCurrentTime:()=>i.then(C.getCurrentTime.bind(C)),getDuration:()=>i.then(C.getDuration.bind(C)),play:()=>i.then(C.play.bind(C)),pause:()=>i.then(C.pause.bind(C)),seek:A=>i.then((()=>C.seek(A))),addEventListener:(A,g)=>C.addEventListener(A,g.bind(e))};return e},A}({}); diff --git a/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css b/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css deleted file mode 100644 index db845ba..0000000 --- a/docs/public/book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";:root{--font-size:16px;--font-size-smaller:0.875rem;--font-size-smallest:0.75rem;--body-font-weight:400;--body-background:white;--body-background-tint:transparent;--body-font-color:black;--border-radius:0.25rem}/*!modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize*/*,::before,::after{box-sizing:border-box}html{font-family:system-ui,segoe ui,Roboto,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji;line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,liberation mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:initial}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}.flex{display:flex}.flex.gap{gap:1rem}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-small,small{font-size:.875em}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}html{font-size:var(--font-size);scroll-behavior:smooth;touch-action:manipulation;scrollbar-gutter:stable}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background)var(--body-background-tint);font-weight:var(--body-font-weight);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-weight:inherit}a{flex:auto;align-items:center;gap:.5em;text-decoration:none;cursor:default}a[href],a[role=button]{color:var(--color-link);cursor:pointer}:focus-visible,input.toggle:focus-visible+label{outline-style:auto;outline-color:var(--color-link)}nav ul{padding:0;margin:0;list-style:none}nav ul li{position:relative}nav ul a{padding:.5em 0;display:flex;transition:opacity .1s ease-in-out}nav ul a[href]:hover,nav ul a[role=button]:hover{opacity:.5}nav ul ul{padding-inline-start:1.5em}ul.pagination{display:flex;justify-content:center;list-style-type:none;padding-inline-start:0}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}a .book-icon{height:1em;width:1em}.book-brand{margin-top:0;margin-bottom:1rem}.book-brand img{height:1.5em;width:1.5em}.book-menu{flex:0 0 16rem;font-size:var(--font-size-smaller)}.book-menu .book-menu-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;word-wrap:break-word;display:flex}.book-menu a.active{color:var(--color-link)}.book-menu label>img:last-child{height:1em;width:1em;cursor:pointer;align-self:center;transition:transform .1s ease-in-out}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-menu input.toggle:checked+label+ul{display:block}body[dir=rtl] .book-menu input.toggle+label>img:last-child{transform:rotate(180deg)}body[dir=rtl] .book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-section-flat{margin:1rem 0}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:4rem}.book-post .book-post-date img{height:1em;width:1em;margin-inline-end:.5em}.book-post .book-post-content{margin-top:1rem}.book-post .book-post-thumbnail{flex:0 0 34%}.book-post .book-post-thumbnail img{width:100%;aspect-ratio:4/3;object-fit:cover}.book-header{margin-bottom:1rem}.book-header label{line-height:0}.book-header h3{overflow:hidden;text-overflow:ellipsis;margin:0 1rem}.book-layout-landing .book-header{display:block;position:relative;z-index:1}.book-layout-landing .book-header nav>ul{display:flex;gap:1rem;justify-content:end}.book-layout-landing .book-header nav>ul>li{display:block;white-space:nowrap}.book-layout-landing .book-header nav>ul>li>ul{display:none;position:absolute;padding:0}.book-layout-landing .book-header nav>ul>li:hover>ul,.book-layout-landing .book-header nav>ul>li:focus-within>ul{display:block}.book-search{position:relative;margin:.5rem 0}.book-search input{width:100%;padding:.5rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search ul a{padding-bottom:0}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:var(--font-size-smallest)}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc a{display:block}.book-toc img{height:1em;width:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:var(--font-size-smaller)}.book-footer a{margin:.25rem 0;padding:.25rem 0}.book-comments{margin-top:1rem}.book-copyright{margin-top:1rem}.book-languages{margin-bottom:1rem}.book-languages span{padding:0}.book-languages ul{padding-inline-start:1.5em}.book-menu-content,.book-toc-content{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){.book-menu{visibility:hidden;margin-inline-start:-16rem;z-index:1}.book-menu .book-menu-content{background:var(--body-background)}.book-toc{display:none}.book-header{display:block}.book-post-container{flex-direction:column-reverse}#menu-control,#toc-control{display:inline}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:fixed;top:0;bottom:0;left:0;right:0}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked~main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:inherit;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;margin-inline-start:.25em}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus-visible,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus-visible,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus-visible,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus-visible,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus-visible,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus-visible{opacity:initial;text-decoration:none}.markdown h1{font-size:2rem}.markdown h2{font-size:1.5rem}.markdown h3{font-size:1.25rem}.markdown h4{font-size:1.125rem}.markdown h5{font-size:1rem}.markdown h6{font-size:.875rem}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a[href]:hover{text-decoration:underline}.markdown a[href]:visited{color:var(--color-visited-link)}.markdown img{max-width:100%;height:auto}.markdown code{direction:ltr;unicode-bidi:embed;padding:.125em .25em;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);overflow-x:auto}.markdown pre:focus{outline-style:auto;outline-color:var(--color-link)}.markdown pre code{padding:0;border:0;background:0 0}.markdown p{word-wrap:break-word}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:var(--border-radius)}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200);text-align:start}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem;word-wrap:break-word}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:0;margin-bottom:1rem}.markdown .highlight{direction:ltr;unicode-bidi:embed;border-radius:var(--border-radius)}.markdown .highlight table tbody{border:1px solid var(--gray-200)}.markdown .highlight table tr pre{border:0}.markdown .highlight table tr td pre code>span{display:flex}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;margin:1rem 0;border:1px solid var(--gray-200);border-radius:var(--border-radius)}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer;list-style:none}.markdown details summary::before{content:"›";display:inline-block;margin-inline-end:.5rem;transition:transform .1s ease-in-out}.markdown details[open] summary{margin-bottom:0}.markdown details[open] summary::before{transform:rotate(90deg)}.markdown figure{margin:1rem 0}.markdown figure figcaption{margin-top:1rem}.markdown-inner>:first-child,.markdown .book-steps>ol>li>:first-child,.markdown figure figcaption>:first-child{margin-top:0}.markdown-inner>:last-child,.markdown .book-steps>ol>li>:last-child,.markdown figure figcaption>:last-child{margin-bottom:0}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-columns{gap:1rem}.markdown .book-columns>div{margin:1rem 0;min-width:13.2rem}.markdown .book-columns>ul{list-style:none;display:flex;padding:0;flex-wrap:wrap;gap:1rem}.markdown .book-columns>ul>li{flex:1 1;min-width:13.2rem}.markdown a.book-btn[href]{display:inline-block;font-size:var(--font-size-smaller);color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:var(--border-radius);cursor:pointer}.markdown a.book-btn[href]:hover{text-decoration:none}.markdown .book-hint.note{border-color:var(--color-accent-note);background-color:var(--color-accent-note-tint)}.markdown .book-hint.tip{border-color:var(--color-accent-tip);background-color:var(--color-accent-tip-tint)}.markdown .book-hint.important{border-color:var(--color-accent-important);background-color:var(--color-accent-important-tint)}.markdown .book-hint.warning{border-color:var(--color-accent-warning);background-color:var(--color-accent-warning-tint)}.markdown .book-hint.caution{border-color:var(--color-accent-caution);background-color:var(--color-accent-caution-tint)}.markdown .book-hint.default{border-color:var(--color-accent-default);background-color:var(--color-accent-default-tint)}.markdown .book-hint.info{border-color:var(--color-accent-info);background-color:var(--color-accent-info-tint)}.markdown .book-hint.success{border-color:var(--color-accent-success);background-color:var(--color-accent-success-tint)}.markdown .book-hint.danger{border-color:var(--color-accent-danger);background-color:var(--color-accent-danger-tint)}.markdown .book-badge{display:inline-block;font-size:var(--font-size-smaller);font-weight:var(--body-font-weight);vertical-align:middle;border-radius:var(--border-radius);border:1px solid var(--accent-color);overflow:hidden;text-wrap:nowrap;color:var(--body-font-color)}.markdown .book-badge.note{--accent-color:var(--color-accent-note)}.markdown .book-badge.tip{--accent-color:var(--color-accent-tip)}.markdown .book-badge.important{--accent-color:var(--color-accent-important)}.markdown .book-badge.warning{--accent-color:var(--color-accent-warning)}.markdown .book-badge.caution{--accent-color:var(--color-accent-caution)}.markdown .book-badge.default{--accent-color:var(--color-accent-default)}.markdown .book-badge.info{--accent-color:var(--color-accent-info)}.markdown .book-badge.success{--accent-color:var(--color-accent-success)}.markdown .book-badge.danger{--accent-color:var(--color-accent-danger)}.markdown .book-badge span{display:inline-block;padding:0 .5rem}.markdown .book-badge span.book-badge-value{color:var(--body-background);background-color:var(--accent-color)}.markdown .book-steps{position:relative}.markdown .book-steps>ol{counter-reset:steps;list-style:none;padding-inline-start:1.25rem;margin-top:2rem}.markdown .book-steps>ol>li::before{content:counter(steps);counter-increment:steps;position:absolute;display:flex;justify-content:center;left:.5rem;height:1.5rem;width:1.5rem;padding:.25rem;border-radius:.5rem;white-space:nowrap;line-height:1rem;color:var(--body-background);background:var(--gray-500);outline:.25rem solid var(--body-background)}.markdown .book-steps>ol>li{border-inline-start:1px solid var(--gray-500);padding-inline-start:3rem;padding-bottom:2rem}.markdown .book-steps>ol>li:last-child{border:0}.markdown .book-card{display:block;overflow:hidden;height:100%;border-radius:var(--border-radius);border:1px solid var(--gray-200)}.markdown .book-card>a{display:block;height:100%}.markdown .book-card>a[href],.markdown .book-card>a[href]:visited{color:var(--body-font-color)}.markdown .book-card>a[href]:hover{text-decoration:none;background:var(--gray-100)}.markdown .book-card>a>img,.markdown .book-card>img{width:100%;display:block;aspect-ratio:4/3;object-fit:cover}.markdown .book-card .markdown-inner,.markdown .book-card figure figcaption,.markdown figure .book-card figcaption,.markdown .book-card .book-steps>ol>li{padding:1rem}.markdown .book-image input+img{cursor:zoom-in;transition:transform .2s ease-in-out}.markdown .book-image input:checked+img{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--body-background);object-fit:contain;width:100%;height:100%;z-index:1;cursor:zoom-out;padding:1rem}.markdown .book-asciinema{margin:1rem 0}.markdown .book-hero{min-height:24rem;align-content:center}.markdown .book-hero h1{font-size:3em}.markdown .book-codeblock-filename{background:var(--gray-100);border:1px solid var(--gray-200);border-bottom:0;font-size:var(--font-size-smaller);margin-top:1rem;padding:.25rem .5rem;border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}.markdown .book-codeblock-filename a{color:var(--body-font-color)}.markdown .book-codeblock-filename+.highlight pre{margin-top:0;border-start-start-radius:0;border-start-end-radius:0}:root{--body-background:white;--body-background-tint:none;--body-font-color:black;--color-link:#0055bb;--color-visited-link:#5500bb;--icon-filter:none;--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-accent-default:#64748b;--color-accent-default-tint:rgba(100, 116, 139, 0.1);--color-accent-note:#4486dd;--color-accent-note-tint:rgba(68, 134, 221, 0.1);--color-accent-tip:#3bad3b;--color-accent-tip-tint:rgba(59, 173, 59, 0.1);--color-accent-important:#8144dd;--color-accent-important-tint:rgba(129, 68, 221, 0.1);--color-accent-warning:#f59e42;--color-accent-warning-tint:rgba(245, 158, 66, 0.1);--color-accent-caution:#d84747;--color-accent-caution-tint:rgba(216, 71, 71, 0.1);--color-accent-info:#4486dd;--color-accent-info-tint:rgba(68, 134, 221, 0.1);--color-accent-success:#3bad3b;--color-accent-success-tint:rgba(59, 173, 59, 0.1);--color-accent-danger:#d84747;--color-accent-danger-tint:rgba(216, 71, 71, 0.1)} \ No newline at end of file diff --git a/docs/public/categories/index.html b/docs/public/categories/index.html deleted file mode 100644 index 5ab8dbd..0000000 --- a/docs/public/categories/index.html +++ /dev/null @@ -1,3 +0,0 @@ -Categories | dhamps-vdb Documentation - -
    \ No newline at end of file diff --git a/docs/public/categories/index.xml b/docs/public/categories/index.xml deleted file mode 100644 index 609fa75..0000000 --- a/docs/public/categories/index.xml +++ /dev/null @@ -1 +0,0 @@ -Categories on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/categories/Recent content in Categories on dhamps-vdb DocumentationHugoen-us \ No newline at end of file diff --git a/docs/public/concepts/architecture/index.html b/docs/public/concepts/architecture/index.html deleted file mode 100644 index 68b8f06..0000000 --- a/docs/public/concepts/architecture/index.html +++ /dev/null @@ -1,92 +0,0 @@ -Architecture | dhamps-vdb Documentation - -

    Architecture#

    dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.

    System Overview#

    ┌─────────────┐
    -│   Client    │
    -│ Application │
    -└──────┬──────┘
    -       │ HTTP/REST
    -       │
    -┌──────▼──────────────────────────┐
    -│      dhamps-vdb API Server      │
    -│  ┌──────────────────────────┐   │
    -│  │   Authentication Layer   │   │
    -│  └────────┬─────────────────┘   │
    -│  ┌────────▼─────────────────┐   │
    -│  │   Request Handlers       │   │
    -│  │  (Users, Projects, etc)  │   │
    -│  └────────┬─────────────────┘   │
    -│  ┌────────▼─────────────────┐   │
    -│  │   Validation Layer       │   │
    -│  │  (Dimensions, Metadata)  │   │
    -│  └────────┬─────────────────┘   │
    -│  ┌────────▼─────────────────┐   │
    -│  │     SQLC Queries         │   │
    -│  │  (Type-safe SQL)         │   │
    -│  └────────┬─────────────────┘   │
    -└───────────┼──────────────────────┘
    -            │
    -    ┌───────▼──────────────┐
    -    │   PostgreSQL + 16    │
    -    │  with pgvector 0.7   │
    -    │                      │
    -    │  ┌────────────────┐  │
    -    │  │ Vector Index   │  │
    -    │  │ (HNSW/IVFFlat) │  │
    -    │  └────────────────┘  │
    -    └──────────────────────┘

    Core Components#

    API Layer#

    Built with Huma framework on top of Go’s http.ServeMux:

    • OpenAPI documentation generation
    • Automatic request/response validation
    • JSON schema support
    • REST endpoint routing

    Authentication#

    Token-based authentication using API keys:

    • Admin key: For administrative operations (user creation, system management)
    • User keys: SHA-256 hashed, unique per user
    • Bearer token: Transmitted in Authorization header

    Data Storage#

    PostgreSQL with pgvector extension:

    • Vector storage: Native pgvector support for embeddings
    • Vector search: Cosine similarity using <=> operator
    • ACID compliance: Transactional consistency
    • Relational integrity: Foreign keys and constraints

    Code Generation#

    Uses sqlc for type-safe database queries:

    • SQL queries → Go functions
    • Compile-time type checking
    • No ORM overhead
    • Direct PostgreSQL integration

    Data Model#

    Core Entities#

    users
    -  ├── projects (1:many)
    -  │   ├── embeddings (1:many)
    -  │   └── instance (1:1)
    -  │
    -  └── instances (1:many)
    -      └── definition (many:1, optional)
    -
    -_system (special user)
    -  └── definitions (1:many)

    Key Relationships#

    Users → Projects

    • One user owns many projects
    • Projects can be shared with other users (reader/editor roles)
    • Projects can be public (unauthenticated read access)

    Projects → Instances

    • Each project references exactly one LLM service instance
    • Instance defines embedding dimensions and configuration

    Projects → Embeddings

    • One project contains many embeddings
    • Each embedding has a unique text_id within the project
    • Embeddings store vector, metadata, and optional text

    Users → Instances

    • Users own their instances
    • Instances can be shared with other users
    • Instances store encrypted API keys

    Instances → Definitions

    • Instances can optionally reference a definition (template)
    • System definitions (_system owner) provide defaults
    • User definitions allow custom templates

    Request Flow#

    1. Create Embedding#

    Client Request
    -     ↓
    -Authentication Middleware
    -     ↓
    -Authorization Check (owner/editor?)
    -     ↓
    -Dimension Validation (vector_dim matches instance?)
    -     ↓
    -Metadata Validation (matches project schema?)
    -     ↓
    -Database Insert (with transaction)
    -     ↓
    -Response
    Client Request (text_id or vector)
    -     ↓
    -Authentication Middleware (or public check)
    -     ↓
    -Authorization Check (owner/reader/public?)
    -     ↓
    -Dimension Validation (if raw vector)
    -     ↓
    -Vector Similarity Query
    -     ├── Cosine distance calculation
    -     ├── Threshold filtering
    -     ├── Metadata filtering (exclude matches)
    -     └── Limit/offset pagination
    -     ↓
    -Results (sorted by similarity)
    -     ↓
    -Response

    Storage Architecture#

    Vector Index#

    pgvector supports multiple index types:

    • IVFFlat: Faster build, approximate search
    • HNSW: Slower build, better recall

    Current implementation uses HNSW for better accuracy.

    Vector Storage Format#

    CREATE TABLE embeddings (
    -  embedding_id SERIAL PRIMARY KEY,
    -  text_id TEXT NOT NULL,
    -  project_id INT REFERENCES projects,
    -  vector vector(3072),  -- Dimension varies
    -  vector_dim INT NOT NULL,
    -  metadata JSONB,
    -  text TEXT,
    -  ...
    -)

    Index Strategy#

    CREATE INDEX embedding_vector_idx 
    -ON embeddings 
    -USING hnsw (vector vector_cosine_ops);

    Optimized for cosine similarity searches.

    Security Architecture#

    API Key Encryption#

    • Algorithm: AES-256-GCM
    • Key Source: ENCRYPTION_KEY environment variable
    • Key Derivation: SHA-256 hash to ensure 32-byte key
    • Storage: Binary (BYTEA) in database

    Access Control#

    Three-tier access model:

    1. Owner: Full control (read, write, delete, share, transfer)
    2. Editor: Read and write embeddings
    3. Reader: Read-only access to embeddings and search

    Special access:

    • Admin: System-wide operations (user management, sanity checks)
    • Public: Unauthenticated read access (if public_read=true)

    Data Isolation#

    • Users can only access their own resources or shared resources
    • Cross-user queries are prevented at the database level
    • Project ownership enforced via foreign keys

    Migration System#

    Uses tern for database migrations:

    migrations/
    -  ├── 001_create_initial_scheme.sql
    -  ├── 002_create_emb_index.sql
    -  ├── 003_add_public_read_flag.sql
    -  └── 004_refactor_llm_services_architecture.sql

    Migrations run automatically on startup with rollback support.

    Performance Characteristics#

    Vector Search Performance#

    • Small datasets (<10K embeddings): <10ms per query
    • Medium datasets (10K-100K): 10-50ms per query
    • Large datasets (>100K): 50-200ms per query

    Performance depends on:

    • Vector dimensions
    • Index type and parameters
    • Hardware (CPU, RAM, disk)
    • Number of results requested

    Scaling Considerations#

    Vertical Scaling:

    • More RAM = faster searches (more vectors in memory)
    • Faster CPUs = faster vector comparisons
    • SSD storage = faster index scans

    Horizontal Scaling:

    • Read replicas for search queries
    • Separate write/read workloads
    • Connection pooling for concurrent requests

    Technology Stack#

    Core Technologies#

    • Language: Go 1.21+
    • Web Framework: Huma 2.x
    • Database: PostgreSQL 16+
    • Vector Extension: pgvector 0.7.4
    • Query Generator: sqlc 1.x
    • Migration Tool: tern 2.x

    Development Tools#

    • Testing: Go standard library + testcontainers
    • Documentation: OpenAPI 3.0 (auto-generated)
    • Building: Docker multi-stage builds
    • Deployment: Docker Compose

    Design Principles#

    1. Type Safety#

    • sqlc generates type-safe Go code from SQL
    • Strong typing prevents SQL injection
    • Compile-time validation of queries

    2. Simplicity#

    • REST API (not GraphQL)
    • Straightforward URL patterns
    • Standard HTTP methods

    3. Security#

    • API key encryption at rest
    • No API keys in responses
    • Role-based access control

    4. Validation#

    • Automatic dimension validation
    • Optional metadata schema validation
    • Request/response validation via OpenAPI

    5. Extensibility#

    • User-defined metadata schemas
    • Custom LLM service configurations
    • Flexible sharing model

    Limitations#

    Current Constraints#

    • No multi-tenancy: Each installation is single-tenant
    • No replication: Manual setup required for HA
    • No caching: All queries hit database
    • Synchronous API: No async/batch upload endpoints

    Future Enhancements#

    See Roadmap for planned improvements.

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/embeddings/index.html b/docs/public/concepts/embeddings/index.html deleted file mode 100644 index b3ae7f2..0000000 --- a/docs/public/concepts/embeddings/index.html +++ /dev/null @@ -1,153 +0,0 @@ -Embeddings | dhamps-vdb Documentation - -

    Embeddings#

    Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.

    What are Embeddings?#

    Embeddings are numerical representations (vectors) of text that capture semantic meaning:

    • Vector: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)
    • Dimensions: Fixed length determined by LLM model
    • Similarity: Vectors of similar text are close in vector space
    • Purpose: Enable semantic search and retrieval

    Embedding Structure#

    Required Fields#

    • text_id: Unique identifier for the document (max 300 characters)
    • instance_handle: LLM service instance that generated the embedding
    • vector: Array of float32 values (embedding vector)
    • vector_dim: Declared dimension count (must match vector length)

    Optional Fields#

    • text: Original text content (for reference)
    • metadata: Structured JSON data about the document

    Example#

    {
    -  "text_id": "doc-123",
    -  "instance_handle": "my-openai",
    -  "text": "Introduction to machine learning concepts",
    -  "vector": [0.023, -0.015, 0.087, ..., 0.042],
    -  "vector_dim": 3072,
    -  "metadata": {
    -    "title": "ML Introduction",
    -    "author": "Alice",
    -    "year": 2024,
    -    "category": "tutorial"
    -  }
    -}

    Creating Embeddings#

    Single Embedding#

    POST /v1/embeddings/alice/research-docs
    -
    -{
    -  "embeddings": [
    -    {
    -      "text_id": "doc1",
    -      "instance_handle": "my-openai",
    -      "vector": [0.1, 0.2, ..., 0.3],
    -      "vector_dim": 3072,
    -      "metadata": {"author": "Alice"}
    -    }
    -  ]
    -}

    Batch Upload#

    POST /v1/embeddings/alice/research-docs
    -
    -{
    -  "embeddings": [
    -    {
    -      "text_id": "doc1",
    -      "instance_handle": "my-openai",
    -      "vector": [...],
    -      "vector_dim": 3072
    -    },
    -    {
    -      "text_id": "doc2",
    -      "instance_handle": "my-openai",
    -      "vector": [...],
    -      "vector_dim": 3072
    -    },
    -    ...
    -  ]
    -}

    Batch upload tips:

    • Upload 100-1000 embeddings per request
    • Use consistent instance_handle
    • Ensure all vectors have same dimensions
    • Include metadata for searchability

    Text Identifiers#

    Format#

    Text IDs can be any string up to 300 characters:

    Common patterns:

    • URLs: https://id.example.com/doc/123
    • URNs: urn:example:doc:123
    • Paths: /corpus/section1/doc123
    • IDs: doc-abc-123-xyz

    URL Encoding#

    URL-encode text IDs when using them in API paths:

    # Original ID
    -text_id="https://id.example.com/texts/W0017:1.3.1"
    -
    -# URL-encoded for API
    -encoded="https%3A%2F%2Fid.example.com%2Ftexts%2FW0017%3A1.3.1"
    -
    -# Use in API call
    -GET /v1/embeddings/alice/project/$encoded

    Uniqueness#

    Text IDs must be unique within a project:

    • Same ID in different projects: ✅ Allowed
    • Same ID twice in one project: ❌ Conflict error

    Validation#

    Dimension Validation#

    The system automatically validates vector dimensions:

    Checks performed:

    1. vector_dim matches declared instance dimensions
    2. Actual vector array length matches vector_dim
    3. All embeddings in project have consistent dimensions

    Example error:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service 'my-openai' expects 1536 dimensions"
    -}

    Metadata Validation#

    If project has a metadata schema, all embeddings are validated:

    Example error:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc1': metadata validation failed:\n  - author is required\n  - year must be integer"
    -}

    See Metadata Validation Guide for details.

    Retrieving Embeddings#

    List All Embeddings#

    GET /v1/embeddings/alice/research-docs?limit=100&offset=0

    Returns paginated list of embeddings with:

    • text_id
    • metadata
    • vector_dim
    • created_at

    Vectors are included by default (can be large).

    Get Single Embedding#

    GET /v1/embeddings/alice/research-docs/doc1

    Returns complete embedding including vector.

    Pagination#

    Use limit and offset for large projects:

    # First page (0-99)
    -GET /v1/embeddings/alice/research-docs?limit=100&offset=0
    -
    -# Second page (100-199)
    -GET /v1/embeddings/alice/research-docs?limit=100&offset=100
    -
    -# Third page (200-299)
    -GET /v1/embeddings/alice/research-docs?limit=100&offset=200

    Updating Embeddings#

    Currently, embeddings cannot be updated directly. To modify:

    1. Delete existing embedding
    2. Upload new version with same text_id
    # Delete old version
    -DELETE /v1/embeddings/alice/research-docs/doc1
    -
    -# Upload new version
    -POST /v1/embeddings/alice/research-docs
    -{
    -  "embeddings": [{
    -    "text_id": "doc1",
    -    "instance_handle": "my-openai",
    -    "vector": [...new vector...],
    -    "vector_dim": 3072,
    -    "metadata": {...updated metadata...}
    -  }]
    -}

    Deleting Embeddings#

    Delete Single Embedding#

    DELETE /v1/embeddings/alice/research-docs/doc1

    Delete All Embeddings#

    DELETE /v1/embeddings/alice/research-docs

    Warning: This deletes all embeddings in the project permanently.

    Metadata#

    Purpose#

    Metadata provides structured information about documents:

    • Filtering: Exclude documents in similarity searches
    • Organization: Categorize and group documents
    • Context: Store additional document information
    • Validation: Ensure consistent structure (with schema)

    Structure#

    Metadata is stored as JSONB in PostgreSQL:

    {
    -  "author": "William Shakespeare",
    -  "title": "Hamlet",
    -  "year": 1603,
    -  "act": 1,
    -  "scene": 1,
    -  "genre": "drama",
    -  "language": "English"
    -}

    Nested Metadata#

    Complex structures are supported:

    {
    -  "author": {
    -    "name": "William Shakespeare",
    -    "birth_year": 1564,
    -    "nationality": "English"
    -  },
    -  "publication": {
    -    "year": 1603,
    -    "publisher": "First Folio",
    -    "edition": 1
    -  },
    -  "tags": ["tragedy", "revenge", "madness"]
    -}

    Filtering by Metadata#

    Use metadata to exclude documents from similarity searches:

    # Exclude documents from same author
    -GET /v1/similars/alice/project/doc1?metadata_path=author&metadata_value=Shakespeare

    See Metadata Filtering Guide for details.

    Storage Considerations#

    Vector Storage#

    Vectors are stored using pgvector extension:

    • Type: vector(N) where N is dimension count
    • Size: 4 bytes per dimension + overhead
    • Example: 3072-dimension vector ≈ 12KB

    Storage Calculation#

    Estimate storage per embedding:

    Vector:   4 bytes × dimensions
    -Text ID:  length in bytes (avg ~50 bytes)
    -Text:     length in bytes (optional)
    -Metadata: JSON size (varies, avg ~500 bytes)
    -Overhead: ~100 bytes (indexes, etc.)
    -
    -Example (3072-dim with metadata):
    -4 × 3072 + 50 + 500 + 100 ≈ 13KB per embedding

    Large Projects#

    For projects with millions of embeddings:

    • Use pagination when listing
    • Consider partial indexes for metadata
    • Monitor database size
    • Plan backup strategy

    Performance#

    Upload Performance#

    • Small batches (1-10): ~100ms per request
    • Medium batches (100-500): ~500ms-2s per request
    • Large batches (1000+): ~2-10s per request

    Retrieval Performance#

    • Single embedding: <10ms
    • Paginated list (100 items): ~50ms
    • Large project scan: Use pagination

    Optimization Tips#

    • Batch uploads when possible
    • Use appropriate page sizes
    • Include only needed fields
    • Monitor query performance

    Common Patterns#

    Document Chunking#

    Split long documents into chunks:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "doc1:chunk1",
    -      "text": "First part of document...",
    -      "vector": [...],
    -      "metadata": {"doc_id": "doc1", "chunk": 1}
    -    },
    -    {
    -      "text_id": "doc1:chunk2",
    -      "text": "Second part of document...",
    -      "vector": [...],
    -      "metadata": {"doc_id": "doc1", "chunk": 2}
    -    }
    -  ]
    -}

    Versioned Documents#

    Track document versions:

    {
    -  "text_id": "doc1:v2",
    -  "vector": [...],
    -  "metadata": {
    -    "doc_id": "doc1",
    -    "version": 2,
    -    "updated_at": "2024-01-15T10:30:00Z"
    -  }
    -}

    Multi-Language Documents#

    Store embeddings for different languages:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "doc1:en",
    -      "text": "English version...",
    -      "vector": [...],
    -      "metadata": {"doc_id": "doc1", "language": "en"}
    -    },
    -    {
    -      "text_id": "doc1:de",
    -      "text": "Deutsche Version...",
    -      "vector": [...],
    -      "metadata": {"doc_id": "doc1", "language": "de"}
    -    }
    -  ]
    -}

    Troubleshooting#

    Dimension Mismatch#

    Error: “vector dimension mismatch”

    Cause: Vector dimensions don’t match instance configuration

    Solution:

    • Check instance dimensions: GET /v1/llm-services/owner/instance
    • Regenerate embeddings with correct model
    • Ensure vector_dim matches actual vector length

    Metadata Validation Failed#

    Error: “metadata validation failed”

    Cause: Metadata doesn’t match project schema

    Solution:

    • Check project schema: GET /v1/projects/owner/project
    • Update metadata to match schema
    • Or update schema to accept metadata

    Text ID Conflict#

    Error: “embedding with text_id already exists”

    Cause: Attempting to upload duplicate text_id

    Solution:

    • Use different text_id
    • Delete existing embedding first
    • Check for unintended duplicates

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/index.html b/docs/public/concepts/index.html deleted file mode 100644 index b158ab5..0000000 --- a/docs/public/concepts/index.html +++ /dev/null @@ -1,10 +0,0 @@ -Concepts | dhamps-vdb Documentation - -

    Core Concepts#

    Understanding the key concepts behind dhamps-vdb helps you make the most of its features. This section explains the fundamental building blocks and how they work together.

    Overview#

    dhamps-vdb is a vector database designed for Retrieval Augmented Generation (RAG) workflows. It stores embeddings with metadata and provides fast similarity search capabilities.

    Key Components#

    • Users - Individual accounts with authentication
    • Projects - Containers for embeddings with access control
    • Embeddings - Vector representations of text with metadata
    • LLM Services - Configurations for embedding models
    • Similarity Search - Find similar documents using vector distance

    Architecture#

    dhamps-vdb uses PostgreSQL with the pgvector extension for vector operations. It provides a RESTful API with token-based authentication and supports multi-user environments with project sharing.

    \ No newline at end of file diff --git a/docs/public/concepts/index.xml b/docs/public/concepts/index.xml deleted file mode 100644 index 5bd9c65..0000000 --- a/docs/public/concepts/index.xml +++ /dev/null @@ -1,219 +0,0 @@ -Concepts on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/concepts/Recent content in Concepts on dhamps-vdb DocumentationHugoen-usArchitecturehttps://mpilhlt.github.io/dhamps-vdb/concepts/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/<h1 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h1> -<p>dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.</p> -<h2 id="system-overview">System Overview<a class="anchor" href="#system-overview">#</a></h2> -<pre tabindex="0"><code>┌─────────────┐ -│ Client │ -│ Application │ -└──────┬──────┘ - │ HTTP/REST - │ -┌──────▼──────────────────────────┐ -│ dhamps-vdb API Server │ -│ ┌──────────────────────────┐ │ -│ │ Authentication Layer │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ Request Handlers │ │ -│ │ (Users, Projects, etc) │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ Validation Layer │ │ -│ │ (Dimensions, Metadata) │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ SQLC Queries │ │ -│ │ (Type-safe SQL) │ │ -│ └────────┬─────────────────┘ │ -└───────────┼──────────────────────┘ - │ - ┌───────▼──────────────┐ - │ PostgreSQL + 16 │ - │ with pgvector 0.7 │ - │ │ - │ ┌────────────────┐ │ - │ │ Vector Index │ │ - │ │ (HNSW/IVFFlat) │ │ - │ └────────────────┘ │ - └──────────────────────┘</code></pre><h2 id="core-components">Core Components<a class="anchor" href="#core-components">#</a></h2> -<h3 id="api-layer">API Layer<a class="anchor" href="#api-layer">#</a></h3> -<p>Built with <a href="https://huma.rocks/">Huma</a> framework on top of Go&rsquo;s <code>http.ServeMux</code>:</p>Users and Authenticationhttps://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/<h1 id="users-and-authentication">Users and Authentication<a class="anchor" href="#users-and-authentication">#</a></h1> -<p>dhamps-vdb uses token-based authentication with API keys for all operations.</p> -<h2 id="user-model">User Model<a class="anchor" href="#user-model">#</a></h2> -<h3 id="user-properties">User Properties<a class="anchor" href="#user-properties">#</a></h3> -<ul> -<li><strong>user_handle</strong>: Unique identifier (3-20 characters, alphanumeric + underscore)</li> -<li><strong>name</strong>: Full name (optional)</li> -<li><strong>email</strong>: Email address (unique, required)</li> -<li><strong>vdb_key</strong>: API key (SHA-256 hash, 64 characters)</li> -<li><strong>created_at</strong>: Timestamp of creation</li> -<li><strong>updated_at</strong>: Timestamp of last update</li> -</ul> -<h3 id="special-users">Special Users<a class="anchor" href="#special-users">#</a></h3> -<p><strong><code>_system</code> User</strong></p> -<ul> -<li>Created automatically during database migration</li> -<li>Owns system-wide LLM service definitions</li> -<li>Cannot be used for authentication</li> -<li>Provides default configurations for all users</li> -</ul> -<h2 id="authentication-flow">Authentication Flow<a class="anchor" href="#authentication-flow">#</a></h2> -<h3 id="api-key-authentication">API Key Authentication<a class="anchor" href="#api-key-authentication">#</a></h3> -<p>All requests (except public endpoints) require authentication:</p>Projectshttps://mpilhlt.github.io/dhamps-vdb/concepts/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/projects/<h1 id="projects">Projects<a class="anchor" href="#projects">#</a></h1> -<p>Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.</p> -<h2 id="what-is-a-project">What is a Project?<a class="anchor" href="#what-is-a-project">#</a></h2> -<p>A project is a collection of document embeddings that share:</p> -<ul> -<li>A single LLM service instance (embedding configuration)</li> -<li>Optional metadata schema for validation</li> -<li>Access control (ownership and sharing)</li> -<li>Consistent vector dimensions</li> -</ul> -<h2 id="project-properties">Project Properties<a class="anchor" href="#project-properties">#</a></h2> -<h3 id="core-fields">Core Fields<a class="anchor" href="#core-fields">#</a></h3> -<ul> -<li><strong>project_handle</strong>: Unique identifier within owner&rsquo;s namespace (3-20 characters)</li> -<li><strong>owner</strong>: User who owns the project</li> -<li><strong>description</strong>: Human-readable project description</li> -<li><strong>instance_id</strong>: Reference to LLM service instance (required, 1:1 relationship)</li> -<li><strong>metadataScheme</strong>: Optional JSON Schema for metadata validation</li> -<li><strong>public_read</strong>: Boolean flag for public read access</li> -<li><strong>created_at</strong>: Creation timestamp</li> -<li><strong>updated_at</strong>: Last modification timestamp</li> -</ul> -<h3 id="unique-constraints">Unique Constraints<a class="anchor" href="#unique-constraints">#</a></h3> -<p>Projects are uniquely identified by <code>(owner, project_handle)</code>:</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/<h1 id="embeddings">Embeddings<a class="anchor" href="#embeddings">#</a></h1> -<p>Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.</p> -<h2 id="what-are-embeddings">What are Embeddings?<a class="anchor" href="#what-are-embeddings">#</a></h2> -<p>Embeddings are numerical representations (vectors) of text that capture semantic meaning:</p> -<ul> -<li><strong>Vector</strong>: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)</li> -<li><strong>Dimensions</strong>: Fixed length determined by LLM model</li> -<li><strong>Similarity</strong>: Vectors of similar text are close in vector space</li> -<li><strong>Purpose</strong>: Enable semantic search and retrieval</li> -</ul> -<h2 id="embedding-structure">Embedding Structure<a class="anchor" href="#embedding-structure">#</a></h2> -<h3 id="required-fields">Required Fields<a class="anchor" href="#required-fields">#</a></h3> -<ul> -<li><strong>text_id</strong>: Unique identifier for the document (max 300 characters)</li> -<li><strong>instance_handle</strong>: LLM service instance that generated the embedding</li> -<li><strong>vector</strong>: Array of float32 values (embedding vector)</li> -<li><strong>vector_dim</strong>: Declared dimension count (must match vector length)</li> -</ul> -<h3 id="optional-fields">Optional Fields<a class="anchor" href="#optional-fields">#</a></h3> -<ul> -<li><strong>text</strong>: Original text content (for reference)</li> -<li><strong>metadata</strong>: Structured JSON data about the document</li> -</ul> -<h3 id="example">Example<a class="anchor" href="#example">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc-123&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text&#34;</span>: <span style="color:#e6db74">&#34;Introduction to machine learning concepts&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector&#34;</span>: [<span style="color:#ae81ff">0.023</span>, <span style="color:#ae81ff">-0.015</span>, <span style="color:#ae81ff">0.087</span>, <span style="color:#960050;background-color:#1e0010">...</span>, <span style="color:#ae81ff">0.042</span>], -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;metadata&#34;</span>: { -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;ML Introduction&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">2024</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;category&#34;</span>: <span style="color:#e6db74">&#34;tutorial&#34;</span> -</span></span><span style="display:flex;"><span> } -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h2 id="creating-embeddings">Creating Embeddings<a class="anchor" href="#creating-embeddings">#</a></h2> -<h3 id="single-embedding">Single Embedding<a class="anchor" href="#single-embedding">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>0.1, 0.2, ..., 0.3<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: 3072, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;metadata&#34;</span>: <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span><span style="color:#f92672">}</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><h3 id="batch-upload">Batch Upload<a class="anchor" href="#batch-upload">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc2&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, -</span></span><span style="display:flex;"><span> ... -</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><p><strong>Batch upload tips:</strong></p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/<h1 id="llm-services">LLM Services<a class="anchor" href="#llm-services">#</a></h1> -<p>LLM Services configure embedding generation, defining models, dimensions, and API access.</p> -<h2 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h2> -<p>dhamps-vdb separates LLM services into two concepts:</p> -<h3 id="llm-service-definitions">LLM Service Definitions<a class="anchor" href="#llm-service-definitions">#</a></h3> -<p>Reusable configuration templates owned by <code>_system</code> or users:</p> -<ul> -<li><strong>Purpose</strong>: Provide standard configurations</li> -<li><strong>Ownership</strong>: <code>_system</code> (global) or individual users</li> -<li><strong>Contents</strong>: Endpoint, model, dimensions, API standard</li> -<li><strong>API Keys</strong>: Not stored (templates only)</li> -<li><strong>Usage</strong>: Templates for creating instances</li> -</ul> -<h3 id="llm-service-instances">LLM Service Instances<a class="anchor" href="#llm-service-instances">#</a></h3> -<p>User-specific configurations with encrypted API keys:</p> -<ul> -<li><strong>Purpose</strong>: Actual service configurations users employ</li> -<li><strong>Ownership</strong>: Individual users</li> -<li><strong>Contents</strong>: Endpoint, model, dimensions, API key (encrypted)</li> -<li><strong>Sharing</strong>: Can be shared with other users</li> -<li><strong>Projects</strong>: Each project references exactly one instance</li> -</ul> -<h2 id="system-definitions">System Definitions<a class="anchor" href="#system-definitions">#</a></h2> -<h3 id="available-definitions">Available Definitions<a class="anchor" href="#available-definitions">#</a></h3> -<p>The <code>_system</code> user provides default definitions:</p>Similarity Searchhttps://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/<h1 id="similarity-search">Similarity Search<a class="anchor" href="#similarity-search">#</a></h1> -<p>Find documents with similar semantic meaning using vector similarity.</p> -<h2 id="how-it-works">How it Works<a class="anchor" href="#how-it-works">#</a></h2> -<p>Similarity search compares embedding vectors using cosine distance:</p> -<ol> -<li><strong>Query vector</strong>: Either from stored embedding or raw vector</li> -<li><strong>Comparison</strong>: Calculate cosine similarity with all project embeddings</li> -<li><strong>Filtering</strong>: Apply threshold and metadata filters</li> -<li><strong>Ranking</strong>: Sort by similarity score (highest first)</li> -<li><strong>Return</strong>: Top N most similar documents</li> -</ol> -<h2 id="search-methods">Search Methods<a class="anchor" href="#search-methods">#</a></h2> -<h3 id="stored-document-search-get">Stored Document Search (GET)<a class="anchor" href="#stored-document-search-get">#</a></h3> -<p>Find documents similar to an already-stored embedding:</p>Metadatahttps://mpilhlt.github.io/dhamps-vdb/concepts/metadata/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/<h1 id="metadata">Metadata<a class="anchor" href="#metadata">#</a></h1> -<p>Structured JSON data attached to embeddings for organization, validation, and filtering.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Metadata provides context and structure for your embeddings:</p> -<ul> -<li><strong>Organization</strong>: Categorize and group documents</li> -<li><strong>Filtering</strong>: Exclude documents in similarity searches</li> -<li><strong>Validation</strong>: Ensure consistent structure (optional)</li> -<li><strong>Context</strong>: Store additional document information</li> -</ul> -<h2 id="metadata-structure">Metadata Structure<a class="anchor" href="#metadata-structure">#</a></h2> -<h3 id="format">Format<a class="anchor" href="#format">#</a></h3> -<p>Metadata is JSON stored as JSONB in PostgreSQL:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;William Shakespeare&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Hamlet&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">1603</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;genre&#34;</span>: <span style="color:#e6db74">&#34;drama&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h3 id="types">Types<a class="anchor" href="#types">#</a></h3> -<p>Supported JSON types:</p> -<ul> -<li><strong>String</strong>: <code>&quot;author&quot;: &quot;Shakespeare&quot;</code></li> -<li><strong>Number</strong>: <code>&quot;year&quot;: 1603</code></li> -<li><strong>Boolean</strong>: <code>&quot;published&quot;: true</code></li> -<li><strong>Array</strong>: <code>&quot;tags&quot;: [&quot;tragedy&quot;, &quot;revenge&quot;]</code></li> -<li><strong>Object</strong>: <code>&quot;author&quot;: {&quot;name&quot;: &quot;...&quot;, &quot;id&quot;: &quot;...&quot;}</code></li> -<li><strong>Null</strong>: <code>&quot;notes&quot;: null</code></li> -</ul> -<h3 id="nested-structure">Nested Structure<a class="anchor" href="#nested-structure">#</a></h3> -<p>Complex hierarchies are supported:</p> \ No newline at end of file diff --git a/docs/public/concepts/llm-services/index.html b/docs/public/concepts/llm-services/index.html deleted file mode 100644 index 3c90446..0000000 --- a/docs/public/concepts/llm-services/index.html +++ /dev/null @@ -1,118 +0,0 @@ -LLM Services | dhamps-vdb Documentation - -

    LLM Services#

    LLM Services configure embedding generation, defining models, dimensions, and API access.

    Architecture#

    dhamps-vdb separates LLM services into two concepts:

    LLM Service Definitions#

    Reusable configuration templates owned by _system or users:

    • Purpose: Provide standard configurations
    • Ownership: _system (global) or individual users
    • Contents: Endpoint, model, dimensions, API standard
    • API Keys: Not stored (templates only)
    • Usage: Templates for creating instances

    LLM Service Instances#

    User-specific configurations with encrypted API keys:

    • Purpose: Actual service configurations users employ
    • Ownership: Individual users
    • Contents: Endpoint, model, dimensions, API key (encrypted)
    • Sharing: Can be shared with other users
    • Projects: Each project references exactly one instance

    System Definitions#

    Available Definitions#

    The _system user provides default definitions:

    HandleModelDimensionsAPI Standard
    openai-largetext-embedding-3-large3072openai
    openai-smalltext-embedding-3-small1536openai
    cohere-v4embed-multilingual-v4.01536cohere
    gemini-embedding-001text-embedding-0043072gemini

    Viewing System Definitions#

    GET /v1/llm-services/_system
    -Authorization: Bearer user_vdb_key

    Returns list of available system definitions.

    Creating Instances#

    From System Definition#

    Use a predefined system configuration:

    PUT /v1/llm-services/alice/my-openai
    -
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-large",
    -  "description": "My OpenAI embeddings",
    -  "api_key_encrypted": "sk-proj-your-openai-key"
    -}

    Inherits endpoint, model, dimensions from system definition.

    From User Definition#

    Reference a user-created definition:

    PUT /v1/llm-services/alice/custom-instance
    -
    -{
    -  "definition_owner": "alice",
    -  "definition_handle": "my-custom-config",
    -  "api_key_encrypted": "your-api-key"
    -}

    Standalone Instance#

    Create without a definition:

    PUT /v1/llm-services/alice/standalone
    -
    -{
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072,
    -  "description": "Standalone OpenAI instance",
    -  "api_key_encrypted": "sk-proj-your-key"
    -}

    All fields must be specified.

    Instance Properties#

    Core Fields#

    • instance_handle: Unique identifier (3-20 characters)
    • owner: User who owns the instance
    • endpoint: API endpoint URL
    • api_standard: Authentication mechanism (openai, cohere, gemini)
    • model: Model identifier
    • dimensions: Vector dimensionality
    • description: Human-readable description (optional)
    • definition_id: Reference to definition (optional)

    API Key Storage#

    • Write-only: Provided on create/update
    • Encrypted: AES-256-GCM encryption
    • Never returned: Not included in GET responses
    • Secure: Cannot be retrieved after creation

    API Standards#

    Supported Standards#

    StandardKey MethodDocumentation
    openaiAuthorization: BearerOpenAI Docs
    cohereAuthorization: BearerCohere Docs
    geminix-goog-api-key headerGemini Docs

    Creating API Standards#

    Admins can add new standards:

    POST /v1/api-standards
    -Authorization: Bearer ADMIN_KEY
    -
    -{
    -  "api_standard_handle": "custom",
    -  "description": "Custom LLM API",
    -  "key_method": "auth_bearer",
    -  "key_field": null
    -}

    Instance Management#

    List Instances#

    List all accessible instances (owned + shared):

    GET /v1/llm-services/alice
    -Authorization: Bearer alice_vdb_key

    Returns instances where alice is owner or has been granted access.

    Get Instance Details#

    GET /v1/llm-services/alice/my-openai
    -Authorization: Bearer alice_vdb_key

    Returns instance configuration (API key not included).

    Update Instance#

    PATCH /v1/llm-services/alice/my-openai
    -
    -{
    -  "description": "Updated description",
    -  "api_key_encrypted": "new-api-key"
    -}

    Only owner can update instances.

    Delete Instance#

    DELETE /v1/llm-services/alice/my-openai
    -Authorization: Bearer alice_vdb_key

    Constraints:

    • Cannot delete instance used by projects
    • Delete projects first, then instance

    Instance Sharing#

    Share with User#

    POST /v1/llm-services/alice/my-openai/share
    -
    -{
    -  "share_with_handle": "bob",
    -  "role": "reader"
    -}

    Shared users can:

    • Use instance in their projects
    • View instance configuration
    • Cannot:
      • See API key
      • Modify instance
      • Delete instance

    Unshare from User#

    DELETE /v1/llm-services/alice/my-openai/share/bob

    List Shared Users#

    GET /v1/llm-services/alice/my-openai/shared-with

    Only owner can view shared users.

    Instance References#

    In Projects#

    Projects reference instances by owner and handle:

    {
    -  "project_handle": "my-project",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-openai"
    -}

    In Embeddings#

    Embeddings reference instances by handle:

    {
    -  "text_id": "doc1",
    -  "instance_handle": "my-openai",
    -  "vector": [...]
    -}

    The instance owner is inferred from the project.

    Shared Instance Format#

    When using shared instances:

    Own instance: "instance_handle": "my-openai" -Shared instance: Reference via project configuration

    Encryption#

    API Key Encryption#

    API keys are encrypted using AES-256-GCM:

    Encryption process:

    1. User provides plaintext API key
    2. Server encrypts using ENCRYPTION_KEY from environment
    3. Encrypted bytes stored in database
    4. Key derivation: SHA-256 hash ensures 32-byte key

    Decryption:

    • Only occurs internally for LLM API calls
    • Never exposed via API responses
    • Requires same ENCRYPTION_KEY

    Security Notes#

    • Encryption key: Set via ENCRYPTION_KEY environment variable
    • Key loss: Losing encryption key means losing access to API keys
    • Key rotation: Not currently supported
    • Backup: Back up encryption key securely

    LLM Processing#

    Current Status#

    LLM processing (generating embeddings) is not yet implemented.

    Future Implementation#

    Planned features:

    • Process text to generate embeddings
    • Call external LLM APIs
    • Store generated embeddings
    • Batch processing support

    Current Workflow#

    Users must generate embeddings externally:

    1. Generate embeddings using LLM API (OpenAI, Cohere, etc.)
    2. Upload pre-generated embeddings to dhamps-vdb
    3. Use dhamps-vdb for storage and similarity search

    Common Patterns#

    Per-Environment Instances#

    # Development instance
    -PUT /v1/llm-services/alice/dev-embeddings
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-small",
    -  "api_key_encrypted": "dev-api-key"
    -}
    -
    -# Production instance
    -PUT /v1/llm-services/alice/prod-embeddings
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-large",
    -  "api_key_encrypted": "prod-api-key"
    -}

    Team Shared Instance#

    # Owner creates instance
    -PUT /v1/llm-services/team-lead/team-embeddings
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-large",
    -  "api_key_encrypted": "team-api-key"
    -}
    -
    -# Share with team members
    -POST /v1/llm-services/team-lead/team-embeddings/share
    -{"share_with_handle": "member1", "role": "reader"}
    -
    -POST /v1/llm-services/team-lead/team-embeddings/share
    -{"share_with_handle": "member2", "role": "reader"}
    -
    -# Members use in their projects
    -POST /v1/projects/member1
    -{
    -  "project_handle": "my-project",
    -  "instance_owner": "team-lead",
    -  "instance_handle": "team-embeddings"
    -}

    Multi-Model Setup#

    # Large model for important documents
    -PUT /v1/llm-services/alice/high-quality
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-large",
    -  "api_key_encrypted": "api-key"
    -}
    -
    -# Small model for drafts
    -PUT /v1/llm-services/alice/fast-processing
    -{
    -  "definition_owner": "_system",
    -  "definition_handle": "openai-small",
    -  "api_key_encrypted": "api-key"
    -}

    Troubleshooting#

    Cannot Create Instance#

    Possible causes:

    • Instance handle already exists
    • Referenced definition doesn’t exist
    • Missing required fields
    • Invalid API standard

    Solutions:

    • Choose different handle
    • Verify definition: GET /v1/llm-services/_system
    • Include all required fields
    • Use valid API standard: GET /v1/api-standards

    Cannot Use Instance in Project#

    Possible causes:

    • Instance doesn’t exist
    • Instance not owned or shared with user
    • Incorrect owner/handle reference

    Solutions:

    • Verify instance exists
    • Check instance is accessible
    • Confirm spelling of owner and handle

    Dimension Mismatch#

    Error: “dimension validation failed”

    Cause: Embedding dimensions don’t match instance

    Solutions:

    • Check instance dimensions
    • Regenerate embeddings with correct model
    • Create instance with correct dimensions

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/metadata/index.html b/docs/public/concepts/metadata/index.html deleted file mode 100644 index cb36ebb..0000000 --- a/docs/public/concepts/metadata/index.html +++ /dev/null @@ -1,180 +0,0 @@ -Metadata | dhamps-vdb Documentation - -

    Metadata#

    Structured JSON data attached to embeddings for organization, validation, and filtering.

    Overview#

    Metadata provides context and structure for your embeddings:

    • Organization: Categorize and group documents
    • Filtering: Exclude documents in similarity searches
    • Validation: Ensure consistent structure (optional)
    • Context: Store additional document information

    Metadata Structure#

    Format#

    Metadata is JSON stored as JSONB in PostgreSQL:

    {
    -  "author": "William Shakespeare",
    -  "title": "Hamlet",
    -  "year": 1603,
    -  "genre": "drama"
    -}

    Types#

    Supported JSON types:

    • String: "author": "Shakespeare"
    • Number: "year": 1603
    • Boolean: "published": true
    • Array: "tags": ["tragedy", "revenge"]
    • Object: "author": {"name": "...", "id": "..."}
    • Null: "notes": null

    Nested Structure#

    Complex hierarchies are supported:

    {
    -  "document": {
    -    "id": "W0017",
    -    "type": "manuscript"
    -  },
    -  "author": {
    -    "name": "John Milton",
    -    "birth_year": 1608,
    -    "nationality": "English"
    -  },
    -  "publication": {
    -    "year": 1667,
    -    "publisher": "First Edition",
    -    "location": "London"
    -  },
    -  "tags": ["poetry", "epic", "religious"]
    -}

    Metadata Schemas#

    Purpose#

    JSON Schema validation ensures consistent metadata across all project embeddings.

    Defining a Schema#

    Include metadataScheme when creating/updating project:

    POST /v1/projects/alice
    -
    -{
    -  "project_handle": "research",
    -  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    -}

    Schema Format#

    Use JSON Schema (draft-07+):

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {
    -      "type": "string",
    -      "minLength": 1
    -    },
    -    "year": {
    -      "type": "integer",
    -      "minimum": 1000,
    -      "maximum": 2100
    -    },
    -    "genre": {
    -      "type": "string",
    -      "enum": ["poetry", "prose", "drama"]
    -    }
    -  },
    -  "required": ["author", "year"]
    -}

    Validation Behavior#

    With schema defined:

    • All embeddings validated on upload
    • Invalid metadata rejected with detailed error
    • Schema enforced consistently

    Without schema:

    • Any JSON metadata accepted
    • No validation performed
    • Maximum flexibility

    Common Patterns#

    See Metadata Validation Guide for examples.

    Using Metadata#

    On Upload#

    Include metadata with each embedding:

    POST /v1/embeddings/alice/research
    -
    -{
    -  "embeddings": [
    -    {
    -      "text_id": "doc1",
    -      "instance_handle": "my-embeddings",
    -      "vector": [...],
    -      "metadata": {
    -        "author": "Shakespeare",
    -        "title": "Hamlet",
    -        "year": 1603
    -      }
    -    }
    -  ]
    -}

    In Responses#

    Metadata returned when retrieving embeddings:

    GET /v1/embeddings/alice/research/doc1
    {
    -  "text_id": "doc1",
    -  "metadata": {
    -    "author": "Shakespeare",
    -    "title": "Hamlet",
    -    "year": 1603
    -  },
    -  "vector": [...],
    -  ...
    -}

    Metadata Filtering#

    Exclusion Filter#

    Exclude documents where metadata matches value:

    GET /v1/similars/alice/research/doc1?metadata_path=author&metadata_value=Shakespeare

    Result: Returns similar documents excluding those with metadata.author == "Shakespeare".

    Path Syntax#

    Use JSON path notation:

    Simple field:

    metadata_path=author

    Nested field:

    metadata_path=author.name

    Array element (not currently supported):

    metadata_path=tags[0]

    URL Encoding#

    Encode special characters:

    # Space
    -metadata_value=John%20Doe
    -
    -# Quotes (if needed)
    -metadata_value=%22quoted%20value%22

    Use Cases#

    Exclude same work:

    ?metadata_path=title&metadata_value=Hamlet

    Exclude same author:

    ?metadata_path=author&metadata_value=Shakespeare

    Exclude same source:

    ?metadata_path=source_id&metadata_value=corpus-a

    Exclude same category:

    ?metadata_path=category&metadata_value=draft

    See Metadata Filtering Guide for detailed examples.

    Validation Examples#

    Simple Schema#

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {"type": "string"},
    -    "year": {"type": "integer"}
    -  },
    -  "required": ["author"]
    -}

    Valid metadata:

    {"author": "Shakespeare", "year": 1603}
    -{"author": "Milton"}

    Invalid metadata:

    {"year": 1603}  // Missing required 'author'
    -{"author": 123}  // Wrong type (should be string)

    Schema with Constraints#

    {
    -  "type": "object",
    -  "properties": {
    -    "title": {
    -      "type": "string",
    -      "minLength": 1,
    -      "maxLength": 200
    -    },
    -    "rating": {
    -      "type": "number",
    -      "minimum": 0,
    -      "maximum": 5
    -    },
    -    "tags": {
    -      "type": "array",
    -      "items": {"type": "string"},
    -      "minItems": 1,
    -      "maxItems": 10
    -    }
    -  }
    -}

    Schema with Enums#

    {
    -  "type": "object",
    -  "properties": {
    -    "language": {
    -      "type": "string",
    -      "enum": ["en", "de", "fr", "es", "la"]
    -    },
    -    "status": {
    -      "type": "string",
    -      "enum": ["draft", "review", "published"]
    -    }
    -  }
    -}

    Storage and Performance#

    Storage#

    Metadata stored as JSONB in PostgreSQL:

    • Efficient: Binary storage format
    • Indexable: Can create indexes on fields
    • Queryable: Use PostgreSQL JSON operators

    Size Considerations#

    Typical metadata sizes:

    • Simple: 50-200 bytes
    • Moderate: 200-1000 bytes
    • Complex: 1-5KB
    • Very large: >5KB (consider storing elsewhere)

    Performance#

    Metadata filtering:

    • JSONB queries are efficient
    • Add indexes for frequently filtered fields
    • Keep metadata reasonably sized

    Example index (if needed):

    CREATE INDEX idx_embeddings_author 
    -ON embeddings ((metadata->>'author'));

    Common Patterns#

    Document Provenance#

    Track document source and history:

    {
    -  "source": {
    -    "corpus": "Shakespeare Works",
    -    "collection": "Tragedies",
    -    "document_id": "hamlet",
    -    "version": 2
    -  },
    -  "imported_at": "2024-01-15T10:30:00Z",
    -  "imported_by": "researcher1"
    -}

    Hierarchical Documents#

    Structure for nested documents:

    {
    -  "work": "Paradise Lost",
    -  "book": 1,
    -  "line": 1,
    -  "chapter": null,
    -  "section": "Invocation"
    -}

    Multi-Language Content#

    Track language and translation info:

    {
    -  "language": "en",
    -  "original_language": "la",
    -  "translated_by": "John Smith",
    -  "translation_year": 1850
    -}

    Research Metadata#

    Academic paper metadata:

    {
    -  "doi": "10.1234/example.2024.001",
    -  "authors": ["Alice Smith", "Bob Jones"],
    -  "journal": "Digital Humanities Review",
    -  "year": 2024,
    -  "keywords": ["NLP", "embeddings", "RAG"]
    -}

    Updating Metadata#

    Current Limitation#

    Metadata cannot be updated directly. To change:

    1. Delete embedding
    2. Re-upload with updated metadata
    # Delete
    -DELETE /v1/embeddings/alice/project/doc1
    -
    -# Re-upload with new metadata
    -POST /v1/embeddings/alice/project
    -{
    -  "embeddings": [{
    -    "text_id": "doc1",
    -    "metadata": {...updated...},
    -    ...
    -  }]
    -}

    Schema Updates#

    Updating Project Schema#

    Use PATCH to update schema:

    PATCH /v1/projects/alice/research
    -
    -{
    -  "metadataScheme": "{...new schema...}"
    -}

    Effect on Existing Embeddings#

    • Existing embeddings: Not revalidated
    • New embeddings: Validated against new schema
    • Updates: Validated against current schema

    Migration Strategy#

    When updating schema:

    1. Update project schema
    2. Verify new embeddings work
    3. Optionally re-upload existing embeddings

    Validation Errors#

    Common Errors#

    Missing required field:

    {
    -  "status": 400,
    -  "detail": "metadata validation failed: author is required"
    -}

    Wrong type:

    {
    -  "status": 400,
    -  "detail": "metadata validation failed: year must be integer"
    -}

    Enum violation:

    {
    -  "status": 400,
    -  "detail": "metadata validation failed: genre must be one of [poetry, prose, drama]"
    -}

    Debugging#

    To debug validation errors:

    1. Check project schema: GET /v1/projects/owner/project
    2. Validate metadata with online tool: jsonschemavalidator.net
    3. Review error message for specific field
    4. Update metadata or schema as needed

    Best Practices#

    Schema Design#

    • Start simple, add complexity as needed
    • Use required fields for critical data
    • Use enums for controlled vocabularies
    • Document your schema

    Metadata Content#

    • Keep metadata focused and relevant
    • Avoid redundant data
    • Use consistent field names
    • Consider future queries and filters

    Performance#

    • Keep metadata reasonably sized (<5KB)
    • Index frequently queried fields
    • Avoid deeply nested structures when possible

    Troubleshooting#

    Validation Fails#

    Problem: Metadata doesn’t validate

    Solutions:

    • Check project schema
    • Verify metadata structure
    • Test with JSON Schema validator
    • Review error message details

    Filtering Not Working#

    Problem: Metadata filter doesn’t exclude documents

    Solutions:

    • Verify field path is correct
    • Check value matches exactly (case-sensitive)
    • URL-encode special characters
    • Confirm metadata field exists

    Schema Too Restrictive#

    Problem: Cannot upload valid documents

    Solutions:

    • Make fields optional (remove from required)
    • Broaden type constraints
    • Use oneOf for multiple valid formats
    • Remove unnecessary validations

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/projects/index.html b/docs/public/concepts/projects/index.html deleted file mode 100644 index 41cff54..0000000 --- a/docs/public/concepts/projects/index.html +++ /dev/null @@ -1,145 +0,0 @@ -Projects | dhamps-vdb Documentation - -

    Projects#

    Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.

    What is a Project?#

    A project is a collection of document embeddings that share:

    • A single LLM service instance (embedding configuration)
    • Optional metadata schema for validation
    • Access control (ownership and sharing)
    • Consistent vector dimensions

    Project Properties#

    Core Fields#

    • project_handle: Unique identifier within owner’s namespace (3-20 characters)
    • owner: User who owns the project
    • description: Human-readable project description
    • instance_id: Reference to LLM service instance (required, 1:1 relationship)
    • metadataScheme: Optional JSON Schema for metadata validation
    • public_read: Boolean flag for public read access
    • created_at: Creation timestamp
    • updated_at: Last modification timestamp

    Unique Constraints#

    Projects are uniquely identified by (owner, project_handle):

    • User “alice” can have project “research”
    • User “bob” can also have project “research”
    • Same user cannot have two projects with same handle

    Creating Projects#

    Basic Project#

    POST /v1/projects/alice
    -
    -{
    -  "project_handle": "literature-study",
    -  "description": "Literary text analysis",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-openai"
    -}

    Project with Metadata Schema#

    POST /v1/projects/alice
    -
    -{
    -  "project_handle": "research-papers",
    -  "description": "Academic papers with structured metadata",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-embeddings",
    -  "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"doi\":{\"type\":\"string\"}},\"required\":[\"author\",\"year\"]}"
    -}

    Public Project#

    POST /v1/projects/alice
    -
    -{
    -  "project_handle": "open-dataset",
    -  "description": "Publicly accessible research data",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-embeddings",
    -  "public_read": true
    -}

    Shared Project#

    POST /v1/projects/alice
    -
    -{
    -  "project_handle": "collaborative",
    -  "description": "Team collaboration project",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-embeddings",
    -  "shared_with": [
    -    {
    -      "user_handle": "bob",
    -      "role": "editor"
    -    },
    -    {
    -      "user_handle": "charlie",
    -      "role": "reader"
    -    }
    -  ]
    -}

    Project-Instance Relationship#

    One-to-One Constraint#

    Each project references exactly one LLM service instance:

    Project → Instance (1:1)
    -  ├── Defines vector dimensions
    -  ├── Specifies embedding model
    -  └── Contains API configuration

    Why 1:1?

    • Ensures consistent dimensions across all embeddings
    • Prevents dimension mismatches in similarity searches
    • Simplifies validation and error handling

    Specifying Instance#

    Use owner and handle to reference an instance:

    {
    -  "instance_owner": "alice",
    -  "instance_handle": "my-openai"
    -}

    The instance can be:

    • Owned by project owner: "instance_owner": "alice"
    • Shared with project owner: "instance_owner": "bob" (if bob shared with alice)

    Metadata Schemas#

    Purpose#

    Metadata schemas ensure consistent, structured metadata across all embeddings in a project.

    Schema Format#

    Use JSON Schema (draft-07 or later):

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {"type": "string"},
    -    "title": {"type": "string"},
    -    "year": {
    -      "type": "integer",
    -      "minimum": 1000,
    -      "maximum": 2100
    -    },
    -    "genre": {
    -      "type": "string",
    -      "enum": ["fiction", "non-fiction", "poetry"]
    -    }
    -  },
    -  "required": ["author", "title", "year"]
    -}

    Validation Behavior#

    • With schema: All embeddings validated on upload
    • Without schema: Any JSON metadata accepted
    • Validation failure: Upload rejected with detailed error
    • Schema updates: Only apply to new/updated embeddings

    Example Schemas#

    See Metadata Validation Guide for detailed examples.

    Access Control#

    Ownership#

    • Owner: User who created the project
    • Full control: Read, write, delete, share, transfer
    • Cannot be removed: Owner always has access

    Sharing#

    Projects can be shared with specific users:

    Reader Role

    • View embeddings
    • Search for similar documents
    • View project metadata
    • Cannot modify anything

    Editor Role

    • All reader permissions
    • Add embeddings
    • Modify embeddings
    • Delete embeddings
    • Cannot delete project or change settings

    Managing Sharing:

    # Share with user
    -POST /v1/projects/alice/my-project/share
    -{
    -  "share_with_handle": "bob",
    -  "role": "reader"
    -}
    -
    -# Unshare from user
    -DELETE /v1/projects/alice/my-project/share/bob
    -
    -# List shared users
    -GET /v1/projects/alice/my-project/shared-with

    Public Access#

    Projects can allow unauthenticated read access:

    PATCH /v1/projects/alice/my-project
    -{
    -  "public_read": true
    -}

    With public_read: true:

    • Anyone can view embeddings (no authentication)
    • Anyone can search for similar documents
    • Write operations still require authentication

    See Public Projects Guide for details.

    Project Operations#

    List Projects#

    List all projects owned by a user:

    GET /v1/projects/alice
    -Authorization: Bearer alice_vdb_key

    Returns array of project objects.

    Get Project Details#

    GET /v1/projects/alice/research
    -Authorization: Bearer alice_vdb_key

    Returns full project object including:

    • Configuration
    • Instance reference
    • Metadata schema
    • Sharing information (owner only)

    Update Project#

    Use PATCH for partial updates:

    PATCH /v1/projects/alice/research
    -{
    -  "description": "Updated description"
    -}

    Use PUT for full replacement:

    PUT /v1/projects/alice/research
    -{
    -  "project_handle": "research",
    -  "description": "Complete project configuration",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-embeddings",
    -  "metadataScheme": "{...}"
    -}

    Delete Project#

    DELETE /v1/projects/alice/research
    -Authorization: Bearer alice_vdb_key

    Cascading deletion:

    • All embeddings in project deleted
    • All sharing grants removed
    • Project metadata removed

    Ownership Transfer#

    Transfer project to another user:

    POST /v1/projects/alice/research/transfer-ownership
    -{
    -  "new_owner_handle": "bob"
    -}

    Effects:

    • Project owner changes to bob
    • Project URL changes: /v1/projects/bob/research
    • Alice loses all access (unless re-shared)
    • All embeddings transferred
    • Bob cannot already have project with same handle

    See Ownership Transfer Guide for details.

    Project Limits#

    Current Implementation#

    No enforced limits on:

    • Number of embeddings per project
    • Project storage size
    • Number of shared users

    For large projects:

    • Use pagination when listing embeddings
    • Batch upload embeddings
    • Monitor database size
    • Consider archiving old projects

    Common Patterns#

    Research Project Workflow#

    # 1. Create project
    -POST /v1/projects/alice
    -{
    -  "project_handle": "study-2024",
    -  "description": "2024 Research Study",
    -  "instance_owner": "alice",
    -  "instance_handle": "my-embeddings"
    -}
    -
    -# 2. Upload data
    -POST /v1/embeddings/alice/study-2024
    -{ ... embeddings ... }
    -
    -# 3. Share with team
    -POST /v1/projects/alice/study-2024/share
    -{"share_with_handle": "bob", "role": "reader"}
    -
    -# 4. Make public when published
    -PATCH /v1/projects/alice/study-2024
    -{"public_read": true}

    Multi-Project Organization#

    # Development project
    -POST /v1/projects/alice
    -{
    -  "project_handle": "dev-experiments",
    -  "instance_owner": "alice",
    -  "instance_handle": "dev-embeddings"
    -}
    -
    -# Production project
    -POST /v1/projects/alice
    -{
    -  "project_handle": "prod-dataset",
    -  "instance_owner": "alice",
    -  "instance_handle": "prod-embeddings",
    -  "metadataScheme": "{...}"
    -}
    -
    -# Archive project
    -POST /v1/projects/alice
    -{
    -  "project_handle": "archive-2023",
    -  "instance_owner": "alice",
    -  "instance_handle": "archive-embeddings",
    -  "public_read": true
    -}

    Troubleshooting#

    Cannot Create Project#

    Possible causes:

    • Project handle already exists for this user
    • Invalid project handle format
    • Instance doesn’t exist or not accessible
    • Missing required fields

    Solutions:

    • Choose different project handle
    • Verify instance exists: GET /v1/llm-services/owner
    • Check instance is owned or shared with you
    • Include all required fields (instance_owner, instance_handle)

    Metadata Validation Fails#

    Possible causes:

    • Metadata doesn’t match schema
    • Invalid JSON Schema format
    • Schema too restrictive

    Solutions:

    • Test schema with online validator
    • Verify embedding metadata matches schema
    • Update schema or metadata as needed

    Cannot Share Project#

    Possible causes:

    • Not project owner
    • Target user doesn’t exist
    • Invalid role specified

    Solutions:

    • Only owner can share projects
    • Verify user exists: GET /v1/users/target
    • Use valid role: “reader” or “editor”

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/similarity-search/index.html b/docs/public/concepts/similarity-search/index.html deleted file mode 100644 index e22d8d2..0000000 --- a/docs/public/concepts/similarity-search/index.html +++ /dev/null @@ -1,76 +0,0 @@ -Similarity Search | dhamps-vdb Documentation - -

    Similarity Search#

    Find documents with similar semantic meaning using vector similarity.

    How it Works#

    Similarity search compares embedding vectors using cosine distance:

    1. Query vector: Either from stored embedding or raw vector
    2. Comparison: Calculate cosine similarity with all project embeddings
    3. Filtering: Apply threshold and metadata filters
    4. Ranking: Sort by similarity score (highest first)
    5. Return: Top N most similar documents

    Search Methods#

    Stored Document Search (GET)#

    Find documents similar to an already-stored embedding:

    GET /v1/similars/alice/research/doc1?count=10&threshold=0.7

    Use cases:

    • Find related documents
    • Discover similar passages
    • Identify duplicates

    Raw Vector Search (POST)#

    Search using a new embedding without storing it:

    POST /v1/similars/alice/research?count=10&threshold=0.7
    -
    -{
    -  "vector": [0.023, -0.015, ..., 0.042]
    -}

    Use cases:

    • Query without saving
    • Test embeddings
    • Real-time search

    Query Parameters#

    count#

    Number of similar documents to return.

    • Type: Integer
    • Range: 1-200
    • Default: 10
    GET /v1/similars/alice/project/doc1?count=5

    threshold#

    Minimum similarity score (0-1).

    • Type: Float
    • Range: 0.0-1.0
    • Default: 0.5
    • Meaning: 1.0 = identical, 0.0 = unrelated
    GET /v1/similars/alice/project/doc1?threshold=0.8

    limit#

    Maximum number of results (same as count).

    • Type: Integer
    • Range: 1-200
    • Default: 10

    offset#

    Skip first N results (pagination).

    • Type: Integer
    • Minimum: 0
    • Default: 0
    # First page
    -GET /v1/similars/alice/project/doc1?limit=10&offset=0
    -
    -# Second page
    -GET /v1/similars/alice/project/doc1?limit=10&offset=10

    metadata_path#

    JSON path to metadata field for filtering.

    • Type: String
    • Purpose: Specify metadata field to filter
    • Must be used with: metadata_value
    ?metadata_path=author

    metadata_value#

    Value to exclude from results.

    • Type: String
    • Purpose: Exclude documents matching this value
    • Must be used with: metadata_path
    ?metadata_path=author&metadata_value=Shakespeare

    Important: Excludes matches, doesn’t include them.

    Similarity Scores#

    Cosine Similarity#

    dhamps-vdb uses cosine similarity:

    similarity = 1 - cosine_distance

    Score ranges:

    • 1.0: Identical vectors
    • 0.9-1.0: Very similar
    • 0.7-0.9: Similar
    • 0.5-0.7: Somewhat similar
    • <0.5: Not similar

    Interpreting Scores#

    Typical thresholds:

    • 0.9+: Duplicates or near-duplicates
    • 0.8+: Strong semantic similarity
    • 0.7+: Related topics
    • 0.5-0.7: Weak relation
    • <0.5: Unrelated

    Optimal threshold depends on your use case and model.

    Metadata Filtering#

    Exclude by Field#

    Exclude documents where metadata field matches value:

    # Exclude documents from same author
    -GET /v1/similars/alice/lit-study/hamlet-act1?metadata_path=author&metadata_value=Shakespeare

    Result: Returns similar documents, excluding those with metadata.author == "Shakespeare".

    Nested Fields#

    Use dot notation for nested metadata:

    # Exclude documents from same author.name
    -GET /v1/similars/alice/project/doc1?metadata_path=author.name&metadata_value=John%20Doe

    Common Patterns#

    Exclude same work:

    ?metadata_path=title&metadata_value=Hamlet

    Exclude same source:

    ?metadata_path=source_id&metadata_value=corpus-A

    Exclude same category:

    ?metadata_path=category&metadata_value=tutorial

    See Metadata Filtering Guide for details.

    Response Format#

    {
    -  "user_handle": "alice",
    -  "project_handle": "research",
    -  "results": [
    -    {
    -      "id": "doc2",
    -      "similarity": 0.95
    -    },
    -    {
    -      "id": "doc5",
    -      "similarity": 0.87
    -    },
    -    {
    -      "id": "doc8",
    -      "similarity": 0.82
    -    }
    -  ]
    -}

    Fields:

    • user_handle: Project owner
    • project_handle: Project identifier
    • results: Array of similar documents
      • id: Document text_id
      • similarity: Similarity score (0-1)

    Results are sorted by similarity (highest first).

    Performance#

    Query Speed#

    Typical performance:

    • <10K embeddings: <10ms
    • 10K-100K embeddings: 10-50ms
    • 100K-1M embeddings: 50-200ms
    • >1M embeddings: 200-1000ms

    Optimization#

    HNSW Index:

    • Faster queries than IVFFlat
    • Better recall
    • Larger index size

    Query optimization:

    • Use appropriate threshold (higher = fewer results)
    • Limit result count (lower = faster)
    • Consider dimension reduction for large projects

    Scaling#

    For large datasets:

    • Monitor query performance
    • Consider read replicas
    • Use connection pooling
    • Cache frequent queries (application level)

    Common Use Cases#

    RAG Workflow#

    Retrieval Augmented Generation:

    # 1. User query
    -query="What is machine learning?"
    -
    -# 2. Generate query embedding (external)
    -query_vector=[...]
    -
    -# 3. Find similar documents
    -POST /v1/similars/alice/knowledge-base?count=5&threshold=0.7
    -{"vector": $query_vector}
    -
    -# 4. Retrieve full text for top results
    -for each result:
    -  GET /v1/embeddings/alice/knowledge-base/$result_id
    -
    -# 5. Send context to LLM for generation

    Duplicate Detection#

    Find near-duplicate documents:

    # High threshold for duplicates
    -GET /v1/similars/alice/corpus/doc1?count=10&threshold=0.95

    Documents with similarity > 0.95 are likely duplicates.

    Content Discovery#

    Find related content:

    # Moderate threshold for recommendations
    -GET /v1/similars/alice/articles/article1?count=10&threshold=0.7&metadata_path=article_id&metadata_value=article1

    Excludes the source article itself.

    Topic Clustering#

    Find documents on similar topics:

    # For each document, find similar ones
    -for doc in documents:
    -  GET /v1/similars/alice/corpus/$doc?count=20&threshold=0.8

    Group documents by similarity for clustering.

    Dimension Consistency#

    Automatic Filtering#

    Similarity queries only compare embeddings with matching dimensions:

    Project embeddings:
    -  - doc1: 3072 dimensions
    -  - doc2: 3072 dimensions
    -  - doc3: 1536 dimensions (different model)
    -
    -Query for doc1 similars:
    -  → Only compares with doc2
    -  → Ignores doc3 (dimension mismatch)

    Multiple Instances#

    Projects can have embeddings from multiple instances (if dimensions match):

    {
    -  "text_id": "doc1",
    -  "instance_handle": "openai-large",
    -  "vector_dim": 3072
    -}
    -
    -{
    -  "text_id": "doc2",
    -  "instance_handle": "custom-model",
    -  "vector_dim": 3072
    -}

    Both searchable together (same dimensions).

    Access Control#

    Authentication#

    Similarity search respects project access control:

    Owner: Full access -Editor: Can search (read permission) -Reader: Can search (read permission) -Public (if public_read=true): Can search (no auth required)

    Public Projects#

    Public projects allow unauthenticated similarity search:

    # No Authorization header needed
    -GET /v1/similars/alice/public-project/doc1?count=10

    See Public Projects Guide.

    Limitations#

    Current Constraints#

    • No cross-project search: Similarity search is per-project only
    • No filtering by multiple metadata fields: One field at a time
    • No custom distance metrics: Cosine similarity only
    • No approximate search tuning: Uses default HNSW parameters

    Workarounds#

    Cross-project search:

    • Query each project separately
    • Merge results in application

    Multiple metadata filters:

    • Filter by one field in query
    • Apply additional filters in application

    Troubleshooting#

    No Results Returned#

    Possible causes:

    • Threshold too high
    • No embeddings in project
    • Dimension mismatch
    • All results filtered by metadata

    Solutions:

    • Lower threshold (try 0.5)
    • Verify embeddings exist
    • Check dimensions match
    • Remove metadata filter

    Unexpected Results#

    Possible causes:

    • Threshold too low
    • Poor quality embeddings
    • Incorrect model used
    • Metadata filter excluding desired results

    Solutions:

    • Increase threshold
    • Regenerate embeddings
    • Verify correct model/dimensions
    • Adjust metadata filter

    Slow Queries#

    Possible causes:

    • Large dataset (>100K embeddings)
    • No vector index
    • High result count
    • Complex metadata filtering

    Solutions:

    • Reduce result count
    • Check index exists
    • Optimize database
    • Use read replicas

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/concepts/users-and-auth/index.html b/docs/public/concepts/users-and-auth/index.html deleted file mode 100644 index e43de59..0000000 --- a/docs/public/concepts/users-and-auth/index.html +++ /dev/null @@ -1,73 +0,0 @@ -Users and Authentication | dhamps-vdb Documentation - -

    Users and Authentication#

    dhamps-vdb uses token-based authentication with API keys for all operations.

    User Model#

    User Properties#

    • user_handle: Unique identifier (3-20 characters, alphanumeric + underscore)
    • name: Full name (optional)
    • email: Email address (unique, required)
    • vdb_key: API key (SHA-256 hash, 64 characters)
    • created_at: Timestamp of creation
    • updated_at: Timestamp of last update

    Special Users#

    _system User

    • Created automatically during database migration
    • Owns system-wide LLM service definitions
    • Cannot be used for authentication
    • Provides default configurations for all users

    Authentication Flow#

    API Key Authentication#

    All requests (except public endpoints) require authentication:

    GET /v1/projects/alice/my-project
    -Authorization: Bearer 024v2013621509245f2e24...

    Authentication Process#

    1. Client sends API key in Authorization header with Bearer prefix
    2. Server extracts key and looks up user in database
    3. If user found, request proceeds with user context
    4. If not found or missing, returns 401 Unauthorized

    Admin Authentication#

    Administrative operations require the admin API key:

    curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle":"alice","email":"alice@example.com"}'

    Admin key is set via SERVICE_ADMINKEY environment variable.

    User Creation#

    By Admin#

    Only admin users can create new users:

    POST /v1/users
    -Authorization: Bearer ADMIN_KEY
    -
    -{
    -  "user_handle": "researcher1",
    -  "name": "Research User",
    -  "email": "researcher@example.com"
    -}

    Response:

    {
    -  "user_handle": "researcher1",
    -  "name": "Research User",
    -  "email": "researcher@example.com",
    -  "vdb_key": "024v2013621509245f2e24abcdef...",
    -  "created_at": "2024-01-15T10:30:00Z"
    -}

    Important: Save the vdb_key immediately - it cannot be recovered later.

    User Handle Restrictions#

    • Must be 3-20 characters
    • Alphanumeric characters and underscores only
    • Must be unique
    • Cannot be _system

    User Management#

    Retrieve User Information#

    Users can view their own information:

    GET /v1/users/alice
    -Authorization: Bearer alice_vdb_key

    Admins can view any user:

    GET /v1/users/alice
    -Authorization: Bearer ADMIN_KEY

    List All Users#

    Only admins can list all users:

    GET /v1/users
    -Authorization: Bearer ADMIN_KEY

    Returns array of user handles (not full user objects).

    Update User#

    Users can update their own information:

    PATCH /v1/users/alice
    -Authorization: Bearer alice_vdb_key
    -
    -{
    -  "name": "Alice Smith-Jones",
    -  "email": "alice.smith@example.com"
    -}

    Delete User#

    Users can delete their own account:

    DELETE /v1/users/alice
    -Authorization: Bearer alice_vdb_key

    Admins can delete any user:

    DELETE /v1/users/alice
    -Authorization: Bearer ADMIN_KEY

    Cascading Deletion:

    • All user’s projects are deleted
    • All user’s LLM service instances are deleted
    • All embeddings in user’s projects are deleted
    • Sharing grants from this user to others are removed

    Authorization Model#

    Resource Ownership#

    Users own three types of resources:

    1. Projects: Collections of embeddings
    2. LLM Service Instances: Embedding configurations with API keys
    3. LLM Service Definitions: Reusable configuration templates (optional)

    Access Levels#

    Owner

    • Full control over resource
    • Can read, write, delete
    • Can share with others
    • Can transfer ownership (projects only)

    Editor (via sharing)

    • Read and write access
    • Cannot delete resource
    • Cannot modify sharing
    • Cannot change project settings

    Reader (via sharing)

    • Read-only access
    • Can view embeddings
    • Can search for similar documents
    • Cannot modify anything

    Public (if project.public_read = true)

    • Unauthenticated read access
    • Can view embeddings
    • Can search for similar documents
    • Cannot write or modify

    Security Best Practices#

    API Key Management#

    Storage

    • Store API keys securely (e.g., environment variables, secret managers)
    • Never commit API keys to version control
    • Use different keys for development and production

    Rotation

    • Currently, API keys cannot be rotated
    • To change a key, delete and recreate the user
    • Plan key rotation strategy before production deployment

    Transmission

    • Always use HTTPS in production
    • API keys are transmitted in Authorization header
    • Never pass API keys in URL query parameters

    User Key vs. LLM API Keys#

    dhamps-vdb handles two types of keys:

    1. User API keys (vdb_key): Authenticate users to dhamps-vdb

      • Stored as SHA-256 hash in database
      • Never encrypted (one-way hash)
      • Returned only once on user creation
    2. LLM API keys (api_key_encrypted): Authenticate to LLM services

      • Stored encrypted (AES-256-GCM) in database
      • Never returned in API responses
      • Used internally for LLM processing

    Multi-User Workflows#

    Collaboration Pattern#

    1. Admin creates user accounts for team members
    2. Project Owner creates project with embeddings
    3. Owner shares project with collaborators
    4. Readers can search and view embeddings
    5. Editors can add/modify embeddings

    Organization Pattern#

    1. Admin creates organizational users
    2. Each user creates LLM service instances with their own API keys
    3. Users create projects using their instances
    4. Projects shared within organization as needed

    Public Access Pattern#

    1. User creates project with research data
    2. User sets public_read: true
    3. Anyone can access embeddings and search without authentication
    4. Only owner can modify project

    User Limits#

    Current Implementation#

    No enforced limits on:

    • Number of projects per user
    • Number of embeddings per project
    • Number of LLM service instances per user
    • Storage size per user

    For production deployments, consider implementing:

    • Rate limiting per API key
    • Storage quotas per user
    • Maximum project count per user

    Example Workflows#

    Create and Use User Account#

    # Admin creates user
    -curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer $ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "researcher1",
    -    "email": "researcher@example.com",
    -    "name": "Research User"
    -  }'
    -
    -# Save returned vdb_key
    -export USER_KEY="returned-vdb-key"
    -
    -# User verifies access
    -curl -X GET http://localhost:8880/v1/users/researcher1 \
    -  -H "Authorization: Bearer $USER_KEY"
    -
    -# User creates project
    -curl -X POST http://localhost:8880/v1/projects/researcher1 \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "my-project",
    -    "description": "My research project"
    -  }'

    Share Resources#

    # User shares project with colleague
    -curl -X POST http://localhost:8880/v1/projects/researcher1/my-project/share \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "colleague1",
    -    "role": "reader"
    -  }'
    -
    -# Colleague accesses shared project
    -curl -X GET http://localhost:8880/v1/projects/researcher1/my-project \
    -  -H "Authorization: Bearer $COLLEAGUE_KEY"

    Troubleshooting#

    401 Unauthorized#

    Possible causes:

    • Missing Authorization header
    • Incorrect API key
    • Expired or invalid key
    • Using user key instead of admin key (or vice versa)

    Solution:

    • Verify API key is correct
    • Check Authorization header format: Bearer KEY
    • Ensure operation matches key type (admin vs. user)

    403 Forbidden#

    Possible causes:

    • User doesn’t own resource
    • User not granted access to shared resource
    • Insufficient permissions (reader trying to edit)

    Solution:

    • Verify resource ownership
    • Check sharing grants
    • Ensure user has required role (editor for writes)

    User Creation Failed#

    Possible causes:

    • User handle already exists
    • Email already registered
    • Invalid user handle format
    • Not using admin key

    Solution:

    • Choose different user handle
    • Use unique email address
    • Check user handle format (3-20 chars, alphanumeric + underscore)
    • Verify using admin API key

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/deployment/database/index.html b/docs/public/deployment/database/index.html deleted file mode 100644 index 7b92925..0000000 --- a/docs/public/deployment/database/index.html +++ /dev/null @@ -1,229 +0,0 @@ -Database Setup | dhamps-vdb Documentation - -

    Database Setup#

    dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.

    Requirements#

    • PostgreSQL: Version 11 or higher
    • pgvector: Extension for vector similarity search
    • Storage: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)

    Installing PostgreSQL with pgvector#

    The easiest way to get PostgreSQL with pgvector:

    docker run -d \
    -  --name postgres-pgvector \
    -  -p 5432:5432 \
    -  -e POSTGRES_PASSWORD=secure_password \
    -  -v postgres_data:/var/lib/postgresql/data \
    -  pgvector/pgvector:0.7.4-pg16

    On Ubuntu/Debian#

    # Add PostgreSQL APT repository
    -sudo apt install curl ca-certificates
    -sudo install -d /usr/share/postgresql-common/pgdg
    -sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
    -  https://www.postgresql.org/media/keys/ACCC4CF8.asc
    -echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \
    -  https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
    -  sudo tee /etc/apt/sources.list.d/pgdg.list
    -
    -# Install PostgreSQL
    -sudo apt update
    -sudo apt install postgresql-16 postgresql-contrib-16
    -
    -# Install pgvector
    -sudo apt install postgresql-16-pgvector

    On macOS#

    # Using Homebrew
    -brew install postgresql@16
    -brew install pgvector
    -
    -# Start PostgreSQL
    -brew services start postgresql@16

    On RHEL/CentOS/Fedora#

    # Install PostgreSQL
    -sudo dnf install postgresql16-server postgresql16-contrib
    -
    -# Install pgvector (build from source)
    -sudo dnf install postgresql16-devel git gcc make
    -git clone https://github.com/pgvector/pgvector.git
    -cd pgvector
    -make
    -sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_config

    Database Configuration#

    Step 1: Create Database#

    Connect to PostgreSQL as superuser:

    # Local connection
    -sudo -u postgres psql
    -
    -# Remote connection
    -psql -h db.example.com -U postgres

    Create the database:

    -- Create database
    -CREATE DATABASE dhamps_vdb;

    Step 2: Create User#

    Create a dedicated user for dhamps-vdb:

    -- Create user with password
    -CREATE USER dhamps_user WITH PASSWORD 'secure_password_here';

    Best practices:

    • Use strong, randomly generated password (e.g., openssl rand -base64 32)
    • Store password securely (password manager, secrets management)
    • Rotate passwords regularly

    Step 3: Grant Privileges#

    Grant necessary permissions:

    -- Grant database privileges
    -GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    -
    --- Connect to the database
    -\c dhamps_vdb
    -
    --- Grant schema privileges
    -GRANT ALL ON SCHEMA public TO dhamps_user;
    -
    --- For PostgreSQL 15+, also grant:
    -GRANT CREATE ON DATABASE dhamps_vdb TO dhamps_user;

    Step 4: Enable pgvector Extension#

    Still connected to the dhamps_vdb database:

    -- Enable pgvector extension
    -CREATE EXTENSION IF NOT EXISTS vector;
    -
    --- Verify extension is installed
    -\dx

    Expected output should include:

    List of installed extensions
    -  Name   | Version |   Schema   |         Description
    ----------+---------+------------+------------------------------
    - vector  | 0.7.4   | public     | vector data type and ivfflat and hnsw access methods

    Step 5: Verify Setup#

    Test the setup:

    -- Test vector creation
    -SELECT '[1,2,3]'::vector;
    -
    --- Should return: [1,2,3]
    -
    --- Test vector distance
    -SELECT '[1,2,3]'::vector <=> '[4,5,6]'::vector AS distance;
    -
    --- Should return a float (distance value)

    Exit psql:

    \q

    Connection String Format#

    dhamps-vdb connects using these environment variables:

    SERVICE_DBHOST=localhost      # Database hostname
    -SERVICE_DBPORT=5432          # Database port
    -SERVICE_DBUSER=dhamps_user   # Database username
    -SERVICE_DBPASSWORD=password  # Database password
    -SERVICE_DBNAME=dhamps_vdb    # Database name

    The connection string format used internally:

    postgresql://username:password@host:port/database?sslmode=disable

    Production Configuration#

    PostgreSQL Tuning#

    Edit postgresql.conf for better vector search performance:

    # Memory settings
    -shared_buffers = 4GB                    # 25% of RAM
    -effective_cache_size = 12GB             # 75% of RAM
    -maintenance_work_mem = 1GB
    -work_mem = 50MB
    -
    -# Parallel query settings
    -max_parallel_workers_per_gather = 4
    -max_parallel_workers = 8
    -
    -# Connection settings
    -max_connections = 100
    -
    -# For pgvector specifically
    -shared_preload_libraries = 'vector'     # Add if not present
    -
    -# Write-ahead log
    -wal_level = replica                     # For replication
    -max_wal_senders = 3                     # For replicas

    Restart PostgreSQL after changes:

    # On systemd systems
    -sudo systemctl restart postgresql
    -
    -# On Docker
    -docker restart postgres-container

    Connection Pooling#

    For high-load scenarios, use connection pooling with PgBouncer:

    # Install PgBouncer
    -sudo apt install pgbouncer
    -
    -# Configure /etc/pgbouncer/pgbouncer.ini
    -[databases]
    -dhamps_vdb = host=localhost port=5432 dbname=dhamps_vdb
    -
    -[pgbouncer]
    -listen_addr = 127.0.0.1
    -listen_port = 6432
    -auth_type = md5
    -auth_file = /etc/pgbouncer/userlist.txt
    -pool_mode = transaction
    -max_client_conn = 1000
    -default_pool_size = 20

    Connect dhamps-vdb to PgBouncer instead of PostgreSQL directly.

    SSL/TLS Encryption#

    Enable SSL in postgresql.conf:

    ssl = on
    -ssl_cert_file = '/etc/postgresql/server.crt'
    -ssl_key_file = '/etc/postgresql/server.key'
    -ssl_ca_file = '/etc/postgresql/ca.crt'

    Update connection string:

    # Update dhamps-vdb configuration
    -SERVICE_DBHOST=db.example.com
    -# Change connection to use SSL (requires code modification or PostgreSQL parameter)

    Network Security#

    Restrict access in pg_hba.conf:

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    -
    -# Allow dhamps_user from application server only
    -host    dhamps_vdb      dhamps_user     10.0.1.0/24            md5
    -
    -# Allow localhost connections
    -local   all             all                                    peer
    -host    all             all             127.0.0.1/32           md5
    -host    all             all             ::1/128                md5

    Reload PostgreSQL:

    sudo systemctl reload postgresql

    Backup and Recovery#

    Automated Backups#

    Daily backup script:

    #!/bin/bash
    -# /usr/local/bin/backup-dhamps-vdb.sh
    -
    -BACKUP_DIR="/backups/dhamps-vdb"
    -DATE=$(date +%Y%m%d_%H%M%S)
    -DB_NAME="dhamps_vdb"
    -
    -# Create backup
    -pg_dump -U dhamps_user -h localhost $DB_NAME | gzip > "$BACKUP_DIR/dhamps-vdb-$DATE.sql.gz"
    -
    -# Keep last 30 days
    -find $BACKUP_DIR -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete
    -
    -# Verify backup
    -if [ $? -eq 0 ]; then
    -    echo "Backup successful: $DATE"
    -else
    -    echo "Backup failed: $DATE" >&2
    -    exit 1
    -fi

    Set up cron job:

    # Run daily at 2 AM
    -0 2 * * * /usr/local/bin/backup-dhamps-vdb.sh

    Restore from Backup#

    # Decompress and restore
    -gunzip -c /backups/dhamps-vdb/dhamps-vdb-20240208.sql.gz | \
    -  psql -U dhamps_user -h localhost dhamps_vdb

    Point-in-Time Recovery (PITR)#

    Enable WAL archiving in postgresql.conf:

    wal_level = replica
    -archive_mode = on
    -archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

    Monitoring#

    Check Database Size#

    -- Database size
    -SELECT pg_size_pretty(pg_database_size('dhamps_vdb'));
    -
    --- Table sizes
    -SELECT 
    -    schemaname,
    -    tablename,
    -    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
    -FROM pg_tables
    -WHERE schemaname = 'public'
    -ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

    Check Connection Status#

    -- Active connections
    -SELECT count(*) FROM pg_stat_activity WHERE datname = 'dhamps_vdb';
    -
    --- Connection details
    -SELECT 
    -    pid,
    -    usename,
    -    application_name,
    -    client_addr,
    -    state,
    -    query
    -FROM pg_stat_activity 
    -WHERE datname = 'dhamps_vdb';

    Monitor Performance#

    -- Enable pg_stat_statements
    -CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
    -
    --- View slow queries
    -SELECT 
    -    query,
    -    calls,
    -    total_time,
    -    mean_time,
    -    max_time
    -FROM pg_stat_statements
    -WHERE query NOT LIKE '%pg_stat_statements%'
    -ORDER BY mean_time DESC
    -LIMIT 10;

    Troubleshooting#

    Cannot Connect to Database#

    # Check if PostgreSQL is running
    -sudo systemctl status postgresql
    -
    -# Check PostgreSQL logs
    -sudo tail -f /var/log/postgresql/postgresql-16-main.log
    -
    -# Test connection
    -psql -h localhost -U dhamps_user -d dhamps_vdb

    pgvector Extension Not Found#

    -- Check available extensions
    -SELECT * FROM pg_available_extensions WHERE name = 'vector';
    -
    --- If not listed, install pgvector package
    --- See installation section above

    Permission Denied#

    -- Reconnect as superuser
    -\c dhamps_vdb postgres
    -
    --- Re-grant privileges
    -GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    -GRANT ALL ON SCHEMA public TO dhamps_user;
    -GRANT ALL ON ALL TABLES IN SCHEMA public TO dhamps_user;
    -GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO dhamps_user;
    -
    --- For future objects
    -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO dhamps_user;
    -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO dhamps_user;

    Out of Disk Space#

    # Check disk usage
    -df -h
    -
    -# Check PostgreSQL data directory
    -du -sh /var/lib/postgresql/16/main/
    -
    -# Clean up old WAL files (if safe)
    -# Check archive status first

    Slow Queries#

    -- Check missing indexes
    -SELECT 
    -    schemaname,
    -    tablename,
    -    attname,
    -    n_distinct,
    -    correlation
    -FROM pg_stats
    -WHERE schemaname = 'public'
    -ORDER BY n_distinct DESC;
    -
    --- Analyze tables
    -ANALYZE;
    -
    --- Vacuum tables
    -VACUUM ANALYZE;

    Migration from Other Databases#

    dhamps-vdb is designed specifically for PostgreSQL with pgvector. Migration from other databases requires:

    1. Export data from source database
    2. Set up PostgreSQL with pgvector
    3. Transform data to match dhamps-vdb schema
    4. Import using dhamps-vdb API or direct SQL

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/docker/index.html b/docs/public/deployment/docker/index.html deleted file mode 100644 index e9d80b2..0000000 --- a/docs/public/deployment/docker/index.html +++ /dev/null @@ -1,122 +0,0 @@ -Docker Deployment | dhamps-vdb Documentation - -

    Docker Deployment#

    This guide covers production-focused Docker deployment for dhamps-vdb.

    Overview#

    For detailed Docker setup instructions, see Getting Started with Docker. This page focuses on production deployment considerations.

    Production Deployment#

    Prerequisites#

    • Docker Engine 20.10+
    • Docker Compose 2.0+ (or docker-compose 1.29+)
    • PostgreSQL 11+ with pgvector extension (included in compose setup)

    Quick Production Setup#

    # Clone repository
    -git clone https://github.com/mpilhlt/dhamps-vdb.git
    -cd dhamps-vdb
    -
    -# Generate secure keys
    -./docker-setup.sh
    -
    -# Review and customize .env
    -nano .env
    -
    -# Deploy
    -docker-compose up -d

    Production Considerations#

    Use Reverse Proxy#

    Always run behind a reverse proxy (nginx, Traefik, Caddy) for:

    • HTTPS/TLS termination
    • Request filtering
    • Rate limiting
    • Load balancing

    Example nginx configuration:

    upstream dhamps-vdb {
    -    server localhost:8880;
    -}
    -
    -server {
    -    listen 443 ssl http2;
    -    server_name api.example.com;
    -
    -    ssl_certificate /path/to/cert.pem;
    -    ssl_certificate_key /path/to/key.pem;
    -
    -    location / {
    -        proxy_pass http://dhamps-vdb;
    -        proxy_set_header Host $host;
    -        proxy_set_header X-Real-IP $remote_addr;
    -        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    -        proxy_set_header X-Forwarded-Proto $scheme;
    -    }
    -}

    Container Resource Limits#

    Set resource limits in docker-compose.yml:

    services:
    -  dhamps-vdb:
    -    deploy:
    -      resources:
    -        limits:
    -          cpus: '2'
    -          memory: 2G
    -        reservations:
    -          cpus: '0.5'
    -          memory: 512M
    -  
    -  postgres:
    -    deploy:
    -      resources:
    -        limits:
    -          cpus: '2'
    -          memory: 4G
    -        reservations:
    -          cpus: '1'
    -          memory: 2G

    Use Specific Image Tags#

    Avoid latest in production:

    services:
    -  postgres:
    -    image: pgvector/pgvector:0.7.4-pg16  # Specific version
    -  
    -  dhamps-vdb:
    -    image: dhamps-vdb:v0.1.0  # Tag your builds

    Health Monitoring#

    The image includes health checks. Monitor with:

    # Check health status
    -docker inspect --format='{{.State.Health.Status}}' dhamps-vdb
    -
    -# View health check logs
    -docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' dhamps-vdb
    -
    -# Integrate with monitoring (Prometheus, etc.)

    Logging#

    Configure logging drivers in docker-compose.yml:

    services:
    -  dhamps-vdb:
    -    logging:
    -      driver: "json-file"
    -      options:
    -        max-size: "10m"
    -        max-file: "3"

    Or use centralized logging:

    services:
    -  dhamps-vdb:
    -    logging:
    -      driver: "syslog"
    -      options:
    -        syslog-address: "tcp://logserver:514"

    External Database Deployment#

    For production, consider using a managed PostgreSQL service or separate database server.

    Requirements#

    • PostgreSQL 11+ with pgvector extension
    • Network connectivity from container to database
    • Database user with appropriate privileges

    See Database Setup for detailed instructions.

    Configuration#

    Update .env:

    SERVICE_DBHOST=db.example.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=secure_password
    -SERVICE_DBNAME=dhamps_vdb

    Modify docker-compose.yml to remove postgres service:

    services:
    -  dhamps-vdb:
    -    build: .
    -    ports:
    -      - "8880:8880"
    -    env_file: .env
    -    restart: unless-stopped

    Scaling and High Availability#

    Horizontal Scaling#

    Run multiple instances behind a load balancer:

    services:
    -  dhamps-vdb:
    -    build: .
    -    deploy:
    -      replicas: 3
    -      restart_policy:
    -        condition: on-failure

    Note: All instances must connect to the same database.

    Database Replication#

    For high availability:

    • Use PostgreSQL replication (streaming or logical)
    • Consider read replicas for read-heavy workloads
    • Point write operations to primary, reads to replicas

    Backup Strategy#

    Database Backups#

    # Automated daily backups
    -0 2 * * * docker-compose exec -T postgres pg_dump -U postgres dhamps_vdb | gzip > /backups/dhamps-vdb-$(date +\%Y\%m\%d).sql.gz
    -
    -# Keep last 30 days
    -find /backups -name "dhamps-vdb-*.sql.gz" -mtime +30 -delete

    Volume Backups#

    # Backup Docker volume
    -docker run --rm -v dhamps-vdb_postgres_data:/data -v /backups:/backup alpine tar czf /backup/postgres-data-$(date +\%Y\%m\%d).tar.gz /data

    Environment Configuration Backups#

    # Backup .env (securely!)
    -gpg --encrypt --recipient admin@example.com .env > .env.gpg

    Troubleshooting#

    Container Performance Issues#

    # Check resource usage
    -docker stats
    -
    -# Check container logs
    -docker-compose logs -f --tail=100 dhamps-vdb
    -
    -# Check slow queries (if database is slow)
    -docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;"

    Network Connectivity Issues#

    # Test database connection from container
    -docker-compose exec dhamps-vdb nc -zv postgres 5432
    -
    -# Check DNS resolution
    -docker-compose exec dhamps-vdb nslookup postgres
    -
    -# Test API from inside container
    -docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs

    Update and Rollback#

    # Update to new version
    -docker-compose pull
    -docker-compose up -d
    -
    -# Rollback if needed
    -docker-compose down
    -docker-compose up -d --force-recreate

    Security Best Practices#

    • See Security Guide for comprehensive security recommendations
    • Use Environment Variables Guide for proper configuration
    • Never expose database port publicly
    • Use strong, randomly generated keys (see ./docker-setup.sh)
    • Keep Docker and images updated
    • Run containers as non-root (already configured)

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/environment-variables/index.html b/docs/public/deployment/environment-variables/index.html deleted file mode 100644 index cd8d460..0000000 --- a/docs/public/deployment/environment-variables/index.html +++ /dev/null @@ -1,105 +0,0 @@ -Environment Variables | dhamps-vdb Documentation - -

    Environment Variables#

    Complete reference for all environment variables used by dhamps-vdb.

    Overview#

    dhamps-vdb is configured entirely through environment variables. These can be set:

    1. In a .env file (recommended for Docker)
    2. As system environment variables
    3. Via command-line flags (some variables only)

    Required Variables#

    These variables must be set for dhamps-vdb to function:

    SERVICE_ADMINKEY#

    Admin API key for administrative operations.

    • Type: String
    • Required: Yes
    • Default: None
    • Environment Variable: SERVICE_ADMINKEY
    • Command-line Flag: --admin-key

    Description: Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.

    Example:

    SERVICE_ADMINKEY=Ch4ngeM3SecureAdminKey!

    Security:

    • Generate with: openssl rand -base64 32
    • Never commit to version control
    • Rotate regularly
    • Store securely (password manager, secrets vault)

    Usage:

    curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer $SERVICE_ADMINKEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle": "alice", "full_name": "Alice Smith"}'

    ENCRYPTION_KEY#

    Encryption key for protecting user API keys in the database.

    • Type: String (32+ characters)
    • Required: Yes
    • Default: None
    • Environment Variable: ENCRYPTION_KEY

    Description: AES-256 encryption key used to encrypt user API keys before storing them in the database. Must be at least 32 characters. The key is hashed with SHA-256 to ensure exactly 32 bytes for AES-256 encryption.

    Example:

    ENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

    Security:

    • Generate with: openssl rand -hex 32
    • Minimum 32 characters required
    • Never commit to version control
    • CRITICAL: If lost, all stored API keys become unrecoverable
    • Backup securely and separately from database
    • Never change in production (will invalidate all existing API keys)

    Technical Details:

    • Uses AES-256-GCM for encryption
    • SHA-256 hash ensures correct key length
    • Each encryption uses unique nonce
    • Encrypted keys stored as base64 in database

    Optional Variables#

    SERVICE_DEBUG#

    Enable debug logging.

    • Type: Boolean
    • Required: No
    • Default: true
    • Environment Variable: SERVICE_DEBUG
    • Command-line Flag: -d, --debug

    Description: Enables verbose debug logging including request details, SQL queries, and internal operations.

    Example:

    SERVICE_DEBUG=false   # Production (less verbose)
    -SERVICE_DEBUG=true    # Development (verbose)

    Impact:

    • true: Detailed logs, useful for debugging
    • false: Minimal logs, recommended for production

    SERVICE_HOST#

    Hostname or IP address to bind the service to.

    • Type: String
    • Required: No
    • Default: localhost
    • Environment Variable: SERVICE_HOST
    • Command-line Flag: --host

    Description: Network interface to listen on. Use 0.0.0.0 to listen on all interfaces (required for Docker).

    Examples:

    SERVICE_HOST=localhost    # Local development only
    -SERVICE_HOST=0.0.0.0      # Listen on all interfaces (Docker)
    -SERVICE_HOST=10.0.1.5     # Specific interface

    Security:

    • Use localhost for development
    • Use 0.0.0.0 for Docker/production with firewall
    • Never expose directly to internet without reverse proxy

    SERVICE_PORT#

    Port number for the API service.

    • Type: Integer
    • Required: No
    • Default: 8880
    • Environment Variable: SERVICE_PORT
    • Command-line Flag: -p, --port

    Description: TCP port the service listens on.

    Example:

    SERVICE_PORT=8880      # Default
    -SERVICE_PORT=8080      # Alternative
    -SERVICE_PORT=3000      # Custom

    Notes:

    • Ports below 1024 require root/admin privileges
    • Ensure port is not already in use
    • Update firewall rules accordingly

    Database Variables#

    SERVICE_DBHOST#

    Database hostname or IP address.

    • Type: String
    • Required: No
    • Default: localhost
    • Environment Variable: SERVICE_DBHOST
    • Command-line Flag: --db-host

    Description: PostgreSQL server hostname.

    Examples:

    SERVICE_DBHOST=localhost              # Local PostgreSQL
    -SERVICE_DBHOST=postgres               # Docker Compose service name
    -SERVICE_DBHOST=db.example.com         # Remote database
    -SERVICE_DBHOST=10.0.1.100            # Database IP address

    SERVICE_DBPORT#

    Database port number.

    • Type: Integer
    • Required: No
    • Default: 5432
    • Environment Variable: SERVICE_DBPORT
    • Command-line Flag: --db-port

    Description: PostgreSQL server port.

    Example:

    SERVICE_DBPORT=5432       # Default PostgreSQL port
    -SERVICE_DBPORT=5433       # Alternative port

    SERVICE_DBUSER#

    Database username.

    • Type: String
    • Required: No
    • Default: postgres
    • Environment Variable: SERVICE_DBUSER
    • Command-line Flag: --db-user

    Description: PostgreSQL user for database connections.

    Example:

    SERVICE_DBUSER=postgres        # Default superuser
    -SERVICE_DBUSER=dhamps_user     # Dedicated user (recommended)

    Security:

    • Create dedicated user (not superuser) for production
    • Use principle of least privilege
    • See Database Setup for user creation

    SERVICE_DBPASSWORD#

    Database password.

    • Type: String
    • Required: No
    • Default: password
    • Environment Variable: SERVICE_DBPASSWORD
    • Command-line Flag: --db-password

    Description: Password for database authentication.

    Example:

    SERVICE_DBPASSWORD=secure_database_password_here

    Security:

    • Use strong, randomly generated password
    • Never use default password in production
    • Never commit to version control
    • Store in secrets management system
    • Rotate regularly

    SERVICE_DBNAME#

    Database name.

    • Type: String
    • Required: No
    • Default: postgres
    • Environment Variable: SERVICE_DBNAME
    • Command-line Flag: --db-name

    Description: Name of the PostgreSQL database.

    Example:

    SERVICE_DBNAME=dhamps_vdb      # Production database
    -SERVICE_DBNAME=dhamps_test     # Testing database

    Configuration Examples#

    Development Setup#

    # .env file for development
    -SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=postgres
    -SERVICE_DBNAME=dhamps_vdb
    -SERVICE_ADMINKEY=dev-admin-key-not-for-production
    -ENCRYPTION_KEY=dev-encryption-key-min-32-chars-long

    Docker Compose Setup#

    # .env file for Docker Compose
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=postgres
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=secure_db_password_here
    -SERVICE_DBNAME=dhamps_vdb
    -SERVICE_ADMINKEY=generated_admin_key_from_setup_script
    -ENCRYPTION_KEY=generated_encryption_key_from_setup_script

    Production Setup#

    # .env file for production (or use secrets management)
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=db.internal.example.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_prod_user
    -SERVICE_DBPASSWORD=<from-secrets-manager>
    -SERVICE_DBNAME=dhamps_vdb_prod
    -SERVICE_ADMINKEY=<from-secrets-manager>
    -ENCRYPTION_KEY=<from-secrets-manager>

    Setting Environment Variables#

    Create a .env file in the project root:

    # Copy template
    -cp template.env .env
    -
    -# Edit with your values
    -nano .env

    The application automatically loads .env on startup.

    Using System Environment Variables#

    # Linux/macOS
    -export SERVICE_ADMINKEY="your-admin-key"
    -export ENCRYPTION_KEY="your-encryption-key"
    -
    -# Windows PowerShell
    -$env:SERVICE_ADMINKEY = "your-admin-key"
    -$env:ENCRYPTION_KEY = "your-encryption-key"
    -
    -# Windows Command Prompt
    -set SERVICE_ADMINKEY=your-admin-key
    -set ENCRYPTION_KEY=your-encryption-key

    Using Docker#

    With docker run:

    docker run -d \
    -  -e SERVICE_ADMINKEY=admin-key \
    -  -e ENCRYPTION_KEY=encryption-key \
    -  -e SERVICE_DBHOST=db-host \
    -  dhamps-vdb:latest

    With docker-compose.yml:

    services:
    -  dhamps-vdb:
    -    image: dhamps-vdb:latest
    -    environment:
    -      SERVICE_DEBUG: "false"
    -      SERVICE_HOST: "0.0.0.0"
    -      SERVICE_PORT: "8880"
    -      SERVICE_DBHOST: "postgres"
    -    env_file:
    -      - .env  # Load additional variables from file

    Using Command-Line Flags#

    Some variables support command-line flags:

    ./dhamps-vdb \
    -  --debug \
    -  --host 0.0.0.0 \
    -  --port 8880 \
    -  --admin-key your-admin-key \
    -  --db-host localhost \
    -  --db-port 5432 \
    -  --db-user postgres \
    -  --db-password password \
    -  --db-name dhamps_vdb

    Note: ENCRYPTION_KEY must be set as environment variable, not flag.

    Validation and Troubleshooting#

    Missing Required Variables#

    If required variables are not set, the service will fail to start:

    Error: SERVICE_ADMINKEY environment variable is not set

    Solution: Set the missing variable.

    Invalid ENCRYPTION_KEY#

    If ENCRYPTION_KEY is too short or invalid:

    Error: ENCRYPTION_KEY environment variable is not set

    Solution: Ensure key is at least 32 characters:

    openssl rand -hex 32

    Database Connection Failure#

    Error: failed to connect to database

    Check:

    • SERVICE_DBHOST is correct and reachable
    • SERVICE_DBPORT is correct
    • SERVICE_DBUSER and SERVICE_DBPASSWORD are valid
    • SERVICE_DBNAME exists
    • PostgreSQL is running
    • Firewall allows connection

    Testing Configuration#

    # Start service with debug logging
    -SERVICE_DEBUG=true ./dhamps-vdb
    -
    -# Check if service starts successfully
    -curl http://localhost:8880/docs
    -
    -# Test admin authentication
    -curl -X GET http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer $SERVICE_ADMINKEY"

    Security Best Practices#

    1. Never commit .env files to version control

      • Already in .gitignore
      • Use .env.example templates
    2. Generate secure random keys

      openssl rand -base64 32  # Admin key
      -openssl rand -hex 32     # Encryption key
    3. Use secrets management in production

      • HashiCorp Vault
      • AWS Secrets Manager
      • Azure Key Vault
      • Docker Secrets (Swarm)
      • Kubernetes Secrets
    4. Rotate keys regularly

      • Admin key: Every 90 days
      • Database password: Every 90 days
      • Encryption key: Cannot be rotated without re-encrypting all API keys
    5. Principle of least privilege

      • Use dedicated database user (not superuser)
      • Grant only necessary permissions
      • Restrict network access
    6. Monitor and audit

      • Log admin key usage
      • Monitor failed authentication attempts
      • Review access patterns

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/deployment/index.html b/docs/public/deployment/index.html deleted file mode 100644 index 0b17b38..0000000 --- a/docs/public/deployment/index.html +++ /dev/null @@ -1,12 +0,0 @@ -Deployment | dhamps-vdb Documentation - -

    Deployment Guide#

    Deploy dhamps-vdb to production environments.

    Deployment Options#

    dhamps-vdb can be deployed in several ways:

    • Docker Compose - Simplest option, includes PostgreSQL
    • Docker with External Database - Production-ready setup
    • Standalone Binary - For custom environments
    • Kubernetes - For orchestrated deployments

    Production Considerations#

    When deploying to production:

    • Use strong, randomly generated keys
    • Enable HTTPS/TLS for all API endpoints
    • Configure database backups
    • Set up monitoring and logging
    • Restrict network access to database
    • Use environment variables for sensitive configuration

    Guides#

    \ No newline at end of file diff --git a/docs/public/deployment/index.xml b/docs/public/deployment/index.xml deleted file mode 100644 index 8560882..0000000 --- a/docs/public/deployment/index.xml +++ /dev/null @@ -1,106 +0,0 @@ -Deployment on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/deployment/Recent content in Deployment on dhamps-vdb DocumentationHugoen-usDocker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/deployment/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> -<p>This guide covers production-focused Docker deployment for dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>For detailed Docker setup instructions, see <a href="../../getting-started/docker/">Getting Started with Docker</a>. This page focuses on production deployment considerations.</p> -<h2 id="production-deployment">Production Deployment<a class="anchor" href="#production-deployment">#</a></h2> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<ul> -<li>Docker Engine 20.10+</li> -<li>Docker Compose 2.0+ (or docker-compose 1.29+)</li> -<li>PostgreSQL 11+ with pgvector extension (included in compose setup)</li> -</ul> -<h3 id="quick-production-setup">Quick Production Setup<a class="anchor" href="#quick-production-setup">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate secure keys</span> -</span></span><span style="display:flex;"><span>./docker-setup.sh -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Review and customize .env</span> -</span></span><span style="display:flex;"><span>nano .env -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Deploy</span> -</span></span><span style="display:flex;"><span>docker-compose up -d</span></span></code></pre></div><h2 id="production-considerations">Production Considerations<a class="anchor" href="#production-considerations">#</a></h2> -<h3 id="use-reverse-proxy">Use Reverse Proxy<a class="anchor" href="#use-reverse-proxy">#</a></h3> -<p>Always run behind a reverse proxy (nginx, Traefik, Caddy) for:</p>Database Setuphttps://mpilhlt.github.io/dhamps-vdb/deployment/database/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/database/<h1 id="database-setup">Database Setup<a class="anchor" href="#database-setup">#</a></h1> -<p>dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.</p> -<h2 id="requirements">Requirements<a class="anchor" href="#requirements">#</a></h2> -<ul> -<li><strong>PostgreSQL</strong>: Version 11 or higher</li> -<li><strong>pgvector</strong>: Extension for vector similarity search</li> -<li><strong>Storage</strong>: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)</li> -</ul> -<h2 id="installing-postgresql-with-pgvector">Installing PostgreSQL with pgvector<a class="anchor" href="#installing-postgresql-with-pgvector">#</a></h2> -<h3 id="using-docker-recommended">Using Docker (Recommended)<a class="anchor" href="#using-docker-recommended">#</a></h3> -<p>The easiest way to get PostgreSQL with pgvector:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --name postgres-pgvector <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -p 5432:5432 <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>secure_password <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -v postgres_data:/var/lib/postgresql/data <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> pgvector/pgvector:0.7.4-pg16</span></span></code></pre></div><h3 id="on-ubuntudebian">On Ubuntu/Debian<a class="anchor" href="#on-ubuntudebian">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Add PostgreSQL APT repository</span> -</span></span><span style="display:flex;"><span>sudo apt install curl ca-certificates -</span></span><span style="display:flex;"><span>sudo install -d /usr/share/postgresql-common/pgdg -</span></span><span style="display:flex;"><span>sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> https://www.postgresql.org/media/keys/ACCC4CF8.asc -</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> https://apt.postgresql.org/pub/repos/apt </span><span style="color:#66d9ef">$(</span>lsb_release -cs<span style="color:#66d9ef">)</span><span style="color:#e6db74">-pgdg main&#34;</span> | <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> sudo tee /etc/apt/sources.list.d/pgdg.list -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> -</span></span><span style="display:flex;"><span>sudo apt update -</span></span><span style="display:flex;"><span>sudo apt install postgresql-16 postgresql-contrib-16 -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector</span> -</span></span><span style="display:flex;"><span>sudo apt install postgresql-16-pgvector</span></span></code></pre></div><h3 id="on-macos">On macOS<a class="anchor" href="#on-macos">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Using Homebrew</span> -</span></span><span style="display:flex;"><span>brew install postgresql@16 -</span></span><span style="display:flex;"><span>brew install pgvector -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start PostgreSQL</span> -</span></span><span style="display:flex;"><span>brew services start postgresql@16</span></span></code></pre></div><h3 id="on-rhelcentosfedora">On RHEL/CentOS/Fedora<a class="anchor" href="#on-rhelcentosfedora">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> -</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-server postgresql16-contrib -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector (build from source)</span> -</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-devel git gcc make -</span></span><span style="display:flex;"><span>git clone https://github.com/pgvector/pgvector.git -</span></span><span style="display:flex;"><span>cd pgvector -</span></span><span style="display:flex;"><span>make -</span></span><span style="display:flex;"><span>sudo make install PG_CONFIG<span style="color:#f92672">=</span>/usr/pgsql-16/bin/pg_config</span></span></code></pre></div><h2 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h2> -<h3 id="step-1-create-database">Step 1: Create Database<a class="anchor" href="#step-1-create-database">#</a></h3> -<p>Connect to PostgreSQL as superuser:</p>Environment Variableshttps://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/<h1 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h1> -<p>Complete reference for all environment variables used by dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb is configured entirely through environment variables. These can be set:</p> -<ol> -<li><strong>In a <code>.env</code> file</strong> (recommended for Docker)</li> -<li><strong>As system environment variables</strong></li> -<li><strong>Via command-line flags</strong> (some variables only)</li> -</ol> -<h2 id="required-variables">Required Variables<a class="anchor" href="#required-variables">#</a></h2> -<p>These variables <strong>must</strong> be set for dhamps-vdb to function:</p> -<h3 id="service_adminkey">SERVICE_ADMINKEY<a class="anchor" href="#service_adminkey">#</a></h3> -<p>Admin API key for administrative operations.</p> -<ul> -<li><strong>Type:</strong> String</li> -<li><strong>Required:</strong> Yes</li> -<li><strong>Default:</strong> None</li> -<li><strong>Environment Variable:</strong> <code>SERVICE_ADMINKEY</code></li> -<li><strong>Command-line Flag:</strong> <code>--admin-key</code></li> -</ul> -<p><strong>Description:</strong> Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.</p>Security Best Practiceshttps://mpilhlt.github.io/dhamps-vdb/deployment/security/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/security/<h1 id="security-best-practices">Security Best Practices<a class="anchor" href="#security-best-practices">#</a></h1> -<p>Comprehensive guide for securing your dhamps-vdb production deployment.</p> -<h2 id="security-overview">Security Overview<a class="anchor" href="#security-overview">#</a></h2> -<p>dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.</p> -<h2 id="httpstls-configuration">HTTPS/TLS Configuration<a class="anchor" href="#httpstls-configuration">#</a></h2> -<h3 id="why-https-is-required">Why HTTPS is Required<a class="anchor" href="#why-https-is-required">#</a></h3> -<ul> -<li><strong>Encryption in transit</strong>: Protects API keys and data from interception</li> -<li><strong>Authentication</strong>: Verifies server identity</li> -<li><strong>Compliance</strong>: Required by most security standards</li> -</ul> -<h3 id="using-a-reverse-proxy">Using a Reverse Proxy<a class="anchor" href="#using-a-reverse-proxy">#</a></h3> -<p><strong>Never expose dhamps-vdb directly to the internet.</strong> Always use a reverse proxy with TLS termination.</p> \ No newline at end of file diff --git a/docs/public/deployment/security/index.html b/docs/public/deployment/security/index.html deleted file mode 100644 index 98797d6..0000000 --- a/docs/public/deployment/security/index.html +++ /dev/null @@ -1,219 +0,0 @@ -Security Best Practices | dhamps-vdb Documentation - -

    Security Best Practices#

    Comprehensive guide for securing your dhamps-vdb production deployment.

    Security Overview#

    dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.

    HTTPS/TLS Configuration#

    Why HTTPS is Required#

    • Encryption in transit: Protects API keys and data from interception
    • Authentication: Verifies server identity
    • Compliance: Required by most security standards

    Using a Reverse Proxy#

    Never expose dhamps-vdb directly to the internet. Always use a reverse proxy with TLS termination.

    Nginx with Let’s Encrypt#

    Install Certbot:

    sudo apt install nginx certbot python3-certbot-nginx

    Configure nginx (/etc/nginx/sites-available/dhamps-vdb):

    upstream dhamps_backend {
    -    server 127.0.0.1:8880;
    -    keepalive 32;
    -}
    -
    -server {
    -    listen 80;
    -    server_name api.example.com;
    -    
    -    # Redirect HTTP to HTTPS
    -    return 301 https://$server_name$request_uri;
    -}
    -
    -server {
    -    listen 443 ssl http2;
    -    server_name api.example.com;
    -
    -    # SSL certificates (managed by Certbot)
    -    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    -    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    -
    -    # Modern SSL configuration
    -    ssl_protocols TLSv1.2 TLSv1.3;
    -    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    -    ssl_prefer_server_ciphers off;
    -    ssl_session_cache shared:SSL:10m;
    -    ssl_session_timeout 10m;
    -
    -    # HSTS (HTTP Strict Transport Security)
    -    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    -
    -    # Security headers
    -    add_header X-Frame-Options "DENY" always;
    -    add_header X-Content-Type-Options "nosniff" always;
    -    add_header X-XSS-Protection "1; mode=block" always;
    -    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    -
    -    # Proxy settings
    -    location / {
    -        proxy_pass http://dhamps_backend;
    -        proxy_http_version 1.1;
    -        
    -        proxy_set_header Host $host;
    -        proxy_set_header X-Real-IP $remote_addr;
    -        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    -        proxy_set_header X-Forwarded-Proto $scheme;
    -        proxy_set_header Connection "";
    -        
    -        # Timeouts
    -        proxy_connect_timeout 60s;
    -        proxy_send_timeout 60s;
    -        proxy_read_timeout 60s;
    -        
    -        # Buffer settings
    -        proxy_buffering on;
    -        proxy_buffer_size 4k;
    -        proxy_buffers 8 4k;
    -    }
    -
    -    # Rate limiting (optional, see below)
    -    limit_req zone=api_limit burst=20 nodelay;
    -    limit_req_status 429;
    -}

    Enable site and get certificate:

    sudo ln -s /etc/nginx/sites-available/dhamps-vdb /etc/nginx/sites-enabled/
    -sudo certbot --nginx -d api.example.com
    -sudo systemctl reload nginx

    Auto-renewal:

    # Certbot creates a systemd timer automatically
    -sudo systemctl status certbot.timer
    -
    -# Test renewal
    -sudo certbot renew --dry-run

    Traefik (Docker)#

    docker-compose.yml:

    version: '3.8'
    -
    -services:
    -  traefik:
    -    image: traefik:v2.10
    -    command:
    -      - "--providers.docker=true"
    -      - "--entrypoints.web.address=:80"
    -      - "--entrypoints.websecure.address=:443"
    -      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
    -      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    -      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    -    ports:
    -      - "80:80"
    -      - "443:443"
    -    volumes:
    -      - /var/run/docker.sock:/var/run/docker.sock:ro
    -      - ./letsencrypt:/letsencrypt
    -
    -  dhamps-vdb:
    -    build: .
    -    labels:
    -      - "traefik.enable=true"
    -      - "traefik.http.routers.dhamps-vdb.rule=Host(`api.example.com`)"
    -      - "traefik.http.routers.dhamps-vdb.entrypoints=websecure"
    -      - "traefik.http.routers.dhamps-vdb.tls.certresolver=letsencrypt"
    -      # Redirect HTTP to HTTPS
    -      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
    -      - "traefik.http.routers.dhamps-vdb-http.rule=Host(`api.example.com`)"
    -      - "traefik.http.routers.dhamps-vdb-http.entrypoints=web"
    -      - "traefik.http.routers.dhamps-vdb-http.middlewares=redirect-to-https"

    Caddy (Automatic HTTPS)#

    Caddyfile:

    api.example.com {
    -    reverse_proxy localhost:8880
    -    
    -    # Automatic HTTPS via Let's Encrypt
    -    tls admin@example.com
    -    
    -    # Security headers
    -    header {
    -        Strict-Transport-Security "max-age=31536000; includeSubDomains"
    -        X-Frame-Options "DENY"
    -        X-Content-Type-Options "nosniff"
    -        X-XSS-Protection "1; mode=block"
    -    }
    -}

    API Key Management#

    Admin Key Security#

    The SERVICE_ADMINKEY has full control over the system.

    Best practices:

    1. Generate securely:

      openssl rand -base64 32
    2. Store securely:

      • Password manager (1Password, Bitwarden)
      • Secrets manager (Vault, AWS Secrets Manager)
      • Never in version control
      • Never in logs or error messages
    3. Rotate regularly:

      • Every 90 days minimum
      • After team member departure
      • After suspected compromise
    4. Audit usage:

      • Log all admin operations
      • Monitor for unusual activity
      • Review regularly

    User API Keys#

    User API keys are automatically generated and encrypted before database storage.

    Security features:

    • One-time display: Keys shown only at creation
    • Encrypted storage: AES-256-GCM encryption
    • Non-recoverable: Lost keys cannot be retrieved

    For users:

    1. Secure storage:

      • Use environment variables
      • Never hardcode in applications
      • Never commit to repositories
    2. Use HTTPS:

      • Always transmit over TLS
      • Validate server certificates
    3. Rotate if compromised:

      • Delete old user and create new one
      • Update all client applications

    Bearer Token Authentication#

    All API requests require authentication:

    curl -X GET https://api.example.com/v1/projects/alice \
    -  -H "Authorization: Bearer your-api-key-here"

    Security:

    • Use Authorization header (not query parameters)
    • Never log full API keys
    • Validate on every request
    • Use HTTPS to prevent interception

    Encryption Key Security#

    The ENCRYPTION_KEY protects all user API keys in the database.

    Critical Security Points#

    ⚠️ CRITICAL: If the encryption key is lost or changed, all user API keys become permanently unrecoverable.

    Best practices:

    1. Generate securely:

      openssl rand -hex 32
    2. Backup separately:

      • Store in multiple secure locations
      • Separate from database backups
      • Document recovery procedure
      • Test recovery process
    3. Never rotate in production:

      • Cannot be changed without re-encrypting all keys
      • Requires database migration
      • Risk of data loss
    4. Protect at rest:

      • Encrypt .env files: gpg --encrypt .env
      • Use secrets management (Vault, AWS Secrets Manager)
      • Restrict file permissions: chmod 600 .env
    5. Protect in transit:

      • Never send over unencrypted channels
      • Use secure channels for team sharing
      • Avoid email/chat

    Encryption Details#

    • Algorithm: AES-256-GCM
    • Key derivation: SHA-256 hash of input key
    • Nonce: Unique per encryption
    • Authentication: GCM provides authentication
    • Storage format: Base64-encoded ciphertext

    Disaster Recovery#

    Document and test recovery procedure:

    ## Encryption Key Recovery Procedure
    -
    -1. Retrieve backup encryption key from [location]
    -2. Verify key integrity: [checksum/hash]
    -3. Update deployment configuration
    -4. Restart services
    -5. Verify user authentication works
    -6. Document incident

    Database Security#

    Network Security#

    1. Restrict access:

      -- In pg_hba.conf
      -# Allow only from application server
      -host    dhamps_vdb    dhamps_user    10.0.1.0/24    md5
    2. Firewall rules:

      # UFW example
      -sudo ufw allow from 10.0.1.0/24 to any port 5432
      -sudo ufw deny 5432
    3. Use VPC/private network:

      • Keep database on private network
      • No public internet exposure
      • VPN for remote administration

    Database Authentication#

    1. Strong passwords:

      # Generate secure password
      -openssl rand -base64 32
    2. Dedicated user:

      -- Not superuser
      -CREATE USER dhamps_user WITH PASSWORD 'secure_password';
      -GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    3. SSL/TLS connections:

      # postgresql.conf
      -ssl = on
      -ssl_cert_file = 'server.crt'
      -ssl_key_file = 'server.key'
      -ssl_ca_file = 'ca.crt'

    Database Encryption#

    1. Encryption at rest:

      • Use encrypted filesystems (LUKS, dm-crypt)
      • Cloud provider encryption (AWS RDS encryption)
      • Transparent Data Encryption (TDE)
    2. Backup encryption:

      # Encrypt backup
      -pg_dump -U postgres dhamps_vdb | gzip | \
      -  gpg --encrypt --recipient admin@example.com > backup.sql.gz.gpg

    Database Auditing#

    Enable audit logging:

    -- Install pgaudit
    -CREATE EXTENSION pgaudit;
    -
    --- Configure logging
    -ALTER SYSTEM SET pgaudit.log = 'write, ddl';
    -ALTER SYSTEM SET pgaudit.log_catalog = off;
    -ALTER SYSTEM SET pgaudit.log_parameter = on;
    -
    --- Reload config
    -SELECT pg_reload_conf();

    Network Security#

    Firewall Configuration#

    # UFW example
    -sudo ufw default deny incoming
    -sudo ufw default allow outgoing
    -
    -# Allow SSH
    -sudo ufw allow 22/tcp
    -
    -# Allow HTTP/HTTPS (reverse proxy)
    -sudo ufw allow 80/tcp
    -sudo ufw allow 443/tcp
    -
    -# Application port (if not behind proxy)
    -# sudo ufw allow from trusted_network to any port 8880
    -
    -# Database (from app server only)
    -sudo ufw allow from 10.0.1.0/24 to any port 5432
    -
    -sudo ufw enable

    Network Segmentation#

    Deploy in isolated networks:

    Internet
    -    ↓
    -[Reverse Proxy] ← (DMZ/Public subnet)
    -    ↓
    -[dhamps-vdb]    ← (Application subnet)
    -    ↓
    -[PostgreSQL]    ← (Database subnet)

    Rate Limiting#

    Protect against abuse and DoS attacks.

    Nginx:

    # Define rate limit zone
    -http {
    -    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    -    limit_req_zone $binary_remote_addr zone=api_burst:10m rate=100r/s;
    -}
    -
    -server {
    -    location /v1/ {
    -        limit_req zone=api_limit burst=20 nodelay;
    -        limit_req_status 429;
    -        proxy_pass http://dhamps_backend;
    -    }
    -}

    Application-level (future enhancement):

    • Implement token bucket or leaky bucket
    • Per-user rate limits
    • Different limits for different endpoints

    Backup Strategies#

    Database Backups#

    1. Automated daily backups:

      #!/bin/bash
      -# /usr/local/bin/backup-dhamps.sh
      -
      -DATE=$(date +%Y%m%d_%H%M%S)
      -BACKUP_DIR="/backups/dhamps-vdb"
      -
      -# Create backup
      -pg_dump -U dhamps_user dhamps_vdb | gzip > \
      -  "$BACKUP_DIR/db-$DATE.sql.gz"
      -
      -# Encrypt backup
      -gpg --encrypt --recipient admin@example.com \
      -  "$BACKUP_DIR/db-$DATE.sql.gz"
      -
      -# Remove unencrypted backup
      -rm "$BACKUP_DIR/db-$DATE.sql.gz"
      -
      -# Verify backup
      -gpg --decrypt "$BACKUP_DIR/db-$DATE.sql.gz.gpg" | gunzip | head -n 5
      -
      -# Upload to offsite storage
      -aws s3 cp "$BACKUP_DIR/db-$DATE.sql.gz.gpg" \
      -  s3://backups/dhamps-vdb/ --storage-class GLACIER
      -
      -# Cleanup old local backups (keep 7 days)
      -find $BACKUP_DIR -name "db-*.sql.gz.gpg" -mtime +7 -delete
    2. Cron schedule:

      0 2 * * * /usr/local/bin/backup-dhamps.sh
    3. Test restores regularly:

      # Monthly restore test
      -0 3 1 * * /usr/local/bin/test-restore.sh

    Configuration Backups#

    # Backup environment configuration
    -cp .env .env.backup
    -gpg --encrypt --recipient admin@example.com .env.backup
    -
    -# Backup with timestamp
    -tar czf config-$(date +%Y%m%d).tar.gz .env docker-compose.yml
    -gpg --encrypt --recipient admin@example.com config-*.tar.gz

    Backup Retention Policy#

    • Daily backups: Keep 7 days locally
    • Weekly backups: Keep 4 weeks offsite
    • Monthly backups: Keep 12 months in cold storage
    • Yearly backups: Keep 7 years (compliance dependent)

    Offsite Backups#

    Always maintain offsite backups:

    • Cloud storage: AWS S3, Azure Blob Storage, GCP Cloud Storage
    • Different geographic region
    • Encrypted before upload
    • Test restoration procedures

    Monitoring and Alerting#

    What to Monitor#

    1. Authentication failures:

      # Parse logs for 401 responses
      -grep "401" /var/log/nginx/access.log | wc -l
    2. Unusual API usage:

      • Spike in requests
      • Requests to non-existent endpoints
      • Large data transfers
    3. Database health:

      • Connection count
      • Query performance
      • Disk usage
      • Replication lag (if applicable)
    4. System resources:

      • CPU usage
      • Memory usage
      • Disk I/O
      • Network throughput

    Log Management#

    1. Centralized logging:

      • ELK Stack (Elasticsearch, Logstash, Kibana)
      • Splunk
      • Graylog
      • CloudWatch Logs (AWS)
    2. Log retention:

      • Application logs: 30 days minimum
      • Access logs: 90 days minimum
      • Audit logs: 1 year minimum (compliance dependent)
    3. Log security:

      • Never log API keys in full (mask: api_key=abc...xyz)
      • Never log passwords
      • Encrypt archived logs
      • Restrict access to logs

    Alerting#

    Set up alerts for:

    • Failed authentication attempts (>10/minute)
    • Database connection failures
    • Disk space >80% full
    • Service downtime
    • Unusual network traffic
    • SSL certificate expiration (30 days before)

    Security Checklist#

    Use this checklist for production deployments:

    Pre-Deployment#

    • Strong, random SERVICE_ADMINKEY generated
    • Strong, random ENCRYPTION_KEY generated (32+ chars)
    • Strong database password set
    • .env file encrypted or in secrets manager
    • .env not in version control
    • Encryption key backed up separately from database

    Network & Access#

    • HTTPS/TLS configured with valid certificate
    • Reverse proxy deployed (nginx/Traefik/Caddy)
    • Firewall configured and enabled
    • Database on private network only
    • Rate limiting configured
    • HSTS header enabled
    • Security headers configured

    Database#

    • PostgreSQL 11+ with pgvector installed
    • Dedicated database user (not superuser)
    • Strong database password
    • SSL/TLS for database connections
    • Database firewall rules configured
    • pg_hba.conf restricts access by IP
    • Regular backups configured
    • Backup encryption enabled
    • Restore procedure tested

    Application#

    • Service runs as non-root user
    • Debug logging disabled (SERVICE_DEBUG=false)
    • Resource limits configured
    • Health checks enabled
    • Logging configured
    • Monitoring configured
    • Alerting configured

    Operations#

    • Backup procedure documented
    • Restore procedure documented and tested
    • Disaster recovery plan created
    • Security incident response plan created
    • Key rotation schedule defined
    • Access control documented (who has admin key)
    • Regular security updates scheduled

    Compliance#

    • Data retention policy defined
    • Privacy policy reviewed
    • Terms of service reviewed
    • GDPR compliance (if applicable)
    • Data processing agreements in place
    • Audit logging enabled

    Incident Response#

    Suspected API Key Compromise#

    1. Immediate actions:

      • Identify compromised user
      • Delete user (invalidates API key)
      • Create new user with new API key
      • Review access logs for unauthorized access
    2. Investigation:

      • Determine scope of compromise
      • Check for data exfiltration
      • Document incident
    3. Notification:

      • Notify affected parties (if required)
      • Document lessons learned
      • Update security procedures

    Database Breach#

    1. Immediate actions:

      • Isolate database server
      • Revoke network access
      • Change all database credentials
      • Activate incident response team
    2. Assessment:

      • Determine data accessed
      • Check encryption effectiveness
      • Review audit logs
    3. Recovery:

      • Restore from clean backup
      • Apply security patches
      • Update firewall rules
      • Notify affected parties (if required)
      • Document and learn

    Encryption Key Loss#

    ⚠️ CRITICAL SITUATION: If encryption key is lost, all user API keys are unrecoverable.

    1. Recovery attempt:

      • Check all backup locations
      • Review documentation
      • Contact all team members
    2. If unrecoverable:

      • All users must be deleted and recreated
      • New API keys issued to all users
      • All client applications must be updated
      • Communicate timeline to users
    3. Prevention:

      • Review backup procedures
      • Add redundant backup locations
      • Document key locations
      • Test recovery process

    Security Updates#

    Regular Updates#

    • Weekly: Review security advisories
    • Monthly: Apply security patches
    • Quarterly: Security audit and penetration testing
    • Yearly: Full security review and compliance audit

    Update Procedure#

    1. Test in staging environment
    2. Backup production database and configuration
    3. Schedule maintenance window
    4. Apply updates
    5. Verify functionality
    6. Monitor for issues

    Subscribe to Security Advisories#

    • PostgreSQL security announcements
    • pgvector security updates
    • Docker security advisories
    • Go security advisories
    • Operating system security updates

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/development/architecture/index.html b/docs/public/development/architecture/index.html deleted file mode 100644 index eb22de4..0000000 --- a/docs/public/development/architecture/index.html +++ /dev/null @@ -1,547 +0,0 @@ -Architecture | dhamps-vdb Documentation - -

    Technical Architecture#

    This document provides a technical deep-dive into dhamps-vdb’s architecture for developers who want to understand or modify the codebase.

    Project Structure#

    dhamps-vdb/
    -├── main.go                        # Application entry point
    -├── go.mod                         # Go module definition
    -├── go.sum                         # Dependency checksums
    -├── sqlc.yaml                      # sqlc configuration
    -├── template.env                   # Environment template
    -├── .env                           # Local config (gitignored)
    -│
    -├── api/
    -│   └── openapi.yml                # OpenAPI spec (not actively maintained)
    -│
    -├── internal/                      # Internal packages (non-importable)
    -│   ├── auth/                      # Authentication logic
    -│   │   └── authenticate.go        # Bearer token validation
    -│   │
    -│   ├── crypto/                    # Encryption utilities
    -│   │   └── crypto.go              # AES-256-GCM encryption
    -│   │
    -│   ├── database/                  # Database layer
    -│   │   ├── database.go            # Connection pool management
    -│   │   ├── migrations.go          # Migration runner
    -│   │   ├── db.go                  # Generated by sqlc
    -│   │   ├── models.go              # Generated by sqlc
    -│   │   ├── queries.sql.go         # Generated by sqlc
    -│   │   │
    -│   │   ├── migrations/            # SQL migrations
    -│   │   │   ├── 001_create_initial_scheme.sql
    -│   │   │   ├── 002_create_emb_index.sql
    -│   │   │   ├── 003_add_public_read_flag.sql
    -│   │   │   ├── 004_refactor_llm_services_architecture.sql
    -│   │   │   ├── tern.conf.tpl      # Template for tern
    -│   │   │   └── tern.conf          # Generated (gitignored)
    -│   │   │
    -│   │   └── queries/               # SQL queries for sqlc
    -│   │       └── queries.sql        # All database queries
    -│   │
    -│   ├── handlers/                  # HTTP request handlers
    -│   │   ├── handlers.go            # Common handler utilities
    -│   │   ├── users.go               # User endpoints
    -│   │   ├── projects.go            # Project endpoints
    -│   │   ├── llm_services.go        # LLM service endpoints
    -│   │   ├── api_standards.go       # API standard endpoints
    -│   │   ├── embeddings.go          # Embedding endpoints
    -│   │   ├── similars.go            # Similarity search endpoints
    -│   │   ├── admin.go               # Admin endpoints
    -│   │   │
    -│   │   └── *_test.go              # Test files
    -│   │       ├── users_test.go
    -│   │       ├── projects_test.go
    -│   │       ├── projects_sharing_test.go
    -│   │       ├── embeddings_test.go
    -│   │       ├── llm_services_test.go
    -│   │       ├── editor_permissions_test.go
    -│   │       └── handlers_test.go
    -│   │
    -│   └── models/                    # Data models and options
    -│       ├── options.go             # CLI/environment options
    -│       ├── users.go               # User models
    -│       ├── projects.go            # Project models
    -│       ├── instances.go           # LLM instance models (new)
    -│       ├── api_standards.go       # API standard models
    -│       ├── embeddings.go          # Embedding models
    -│       ├── similars.go            # Similarity search models
    -│       └── admin.go               # Admin operation models
    -│
    -├── testdata/                      # Test fixtures
    -│   ├── postgres/                  # PostgreSQL test data
    -│   │   ├── enable-vector.sql
    -│   │   └── users.yml
    -│   │
    -│   └── *.json                     # JSON test fixtures
    -│       ├── valid_user.json
    -│       ├── valid_embeddings.json
    -│       ├── valid_api_standard_*.json
    -│       └── valid_llm_service_*.json
    -│
    -└── docs/                          # Documentation
    -    ├── content/                   # Hugo content
    -    └── *.md                       # Additional docs

    Code Organization#

    1. Entry Point (main.go)#

    The application entry point handles:

    func main() {
    -	// 1. Parse CLI options and environment variables
    -	cli := huma.NewCLI(func(hooks huma.Hooks, opts *models.Options) {
    -		
    -		// 2. Initialize database connection pool
    -		pool := database.InitDB(opts)
    -		defer pool.Close()
    -		
    -		// 3. Run database migrations
    -		database.RunMigrations(pool, opts)
    -		
    -		// 4. Create HTTP router and Huma API
    -		router := http.NewServeMux()
    -		api := humago.New(router, huma.DefaultConfig("dhamps-vdb", "0.1.0"))
    -		
    -		// 5. Register all routes
    -		handlers.AddRoutes(pool, keyGen, api)
    -		
    -		// 6. Start HTTP server
    -		server := &http.Server{
    -			Addr:    fmt.Sprintf("%s:%d", opts.Host, opts.Port),
    -			Handler: router,
    -		}
    -		server.ListenAndServe()
    -	})
    -	
    -	cli.Run()
    -}

    2. Handlers (internal/handlers/)#

    Handlers process HTTP requests using the Huma framework pattern:

    // Example: Create User Handler
    -func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) {
    -	
    -	// Define request/response types
    -	type CreateUserInput struct {
    -		Body models.CreateUserRequest
    -	}
    -	
    -	type CreateUserOutput struct {
    -		Body models.User
    -	}
    -	
    -	// Register operation with Huma
    -	huma.Register(api, huma.Operation{
    -		OperationID: "create-user",
    -		Method:      http.MethodPost,
    -		Path:        "/v1/users",
    -		Summary:     "Create a new user",
    -		Description: "Admin only. Creates user and returns API key.",
    -		Security:    []map[string][]string{{"bearer": {}}},
    -	}, func(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) {
    -		
    -		// 1. Get authenticated user from context
    -		authUser := auth.GetAuthenticatedUser(ctx)
    -		
    -		// 2. Check authorization (admin only)
    -		if !authUser.IsAdmin {
    -			return nil, huma.Error403Forbidden("admin access required")
    -		}
    -		
    -		// 3. Validate input
    -		if err := input.Body.Validate(); err != nil {
    -			return nil, huma.Error400BadRequest("invalid input", err)
    -		}
    -		
    -		// 4. Business logic
    -		user, apiKey, err := createUserWithKey(ctx, pool, keyGen, &input.Body)
    -		if err != nil {
    -			return nil, handleDatabaseError(err)
    -		}
    -		
    -		// 5. Return response
    -		return &CreateUserOutput{Body: *user}, nil
    -	})
    -}

    Handler file organization:

    • handlers.go - Common utilities (context keys, error handling)
    • users.go - User CRUD operations
    • projects.go - Project CRUD and sharing
    • llm_services.go - LLM service/instance management
    • embeddings.go - Embedding CRUD operations
    • similars.go - Similarity search
    • admin.go - Administrative operations

    3. Models (internal/models/)#

    Models define request/response structures:

    // User model
    -type User struct {
    -	UserHandle string    `json:"user_handle" example:"alice"`
    -	Name       string    `json:"name" example:"Alice Smith"`
    -	Email      string    `json:"email" example:"alice@example.com"`
    -	CreatedAt  time.Time `json:"created_at"`
    -	UpdatedAt  time.Time `json:"updated_at"`
    -}
    -
    -// Request model with validation
    -type CreateUserRequest struct {
    -	UserHandle string `json:"user_handle" minLength:"1" maxLength:"50" pattern:"^[a-z0-9_-]+$"`
    -	Name       string `json:"name" minLength:"1" maxLength:"100"`
    -	Email      string `json:"email" format:"email"`
    -}
    -
    -func (r *CreateUserRequest) Validate() error {
    -	if r.UserHandle == "" {
    -		return fmt.Errorf("user_handle is required")
    -	}
    -	if r.UserHandle == "_system" {
    -		return fmt.Errorf("_system is a reserved handle")
    -	}
    -	return nil
    -}

    Model conventions:

    • Request models: Create*Request, Update*Request
    • Response models: *Response, *Output
    • Database models: Match database schema (generated by sqlc)

    4. Database Layer (internal/database/)#

    Connection Management (database.go)#

    func InitDB(opts *models.Options) *pgxpool.Pool {
    -	connString := fmt.Sprintf(
    -		"postgres://%s:%s@%s:%d/%s",
    -		opts.DBUser, opts.DBPassword, 
    -		opts.DBHost, opts.DBPort, opts.DBName,
    -	)
    -	
    -	config, err := pgxpool.ParseConfig(connString)
    -	if err != nil {
    -		log.Fatal(err)
    -	}
    -	
    -	// Configure connection pool
    -	config.MaxConns = 20
    -	config.MinConns = 5
    -	config.MaxConnIdleTime = time.Minute * 5
    -	
    -	pool, err := pgxpool.NewWithConfig(context.Background(), config)
    -	if err != nil {
    -		log.Fatal(err)
    -	}
    -	
    -	return pool
    -}

    Migrations (migrations.go)#

    Uses tern for versioned migrations:

    func RunMigrations(pool *pgxpool.Pool, opts *models.Options) error {
    -	// Create tern configuration
    -	config := createTernConfig(opts)
    -	
    -	// Initialize migrator
    -	migrator, err := migrate.NewMigrator(context.Background(), pool, "schema_version")
    -	if err != nil {
    -		return err
    -	}
    -	
    -	// Run pending migrations
    -	err = migrator.Migrate(context.Background())
    -	if err != nil {
    -		return fmt.Errorf("migration failed: %w", err)
    -	}
    -	
    -	return nil
    -}

    Migration files are numbered sequentially:

    -- 001_create_initial_scheme.sql
    -CREATE TABLE users (
    -    user_id SERIAL PRIMARY KEY,
    -    user_handle TEXT UNIQUE NOT NULL,
    -    vdb_key TEXT UNIQUE NOT NULL,
    -    ...
    -);
    -
    -CREATE TABLE projects (
    -    project_id SERIAL PRIMARY KEY,
    -    project_handle TEXT NOT NULL,
    -    owner TEXT NOT NULL REFERENCES users(user_handle),
    -    ...
    -);
    -
    --- 002_create_emb_index.sql  
    -CREATE INDEX embedding_vector_idx 
    -ON embeddings 
    -USING hnsw (vector vector_cosine_ops);

    SQLC Queries (queries/queries.sql)#

    Write SQL, generate type-safe Go code:

    -- name: UpsertUser :one
    -INSERT INTO users (
    -  user_handle, name, email, vdb_key, created_at, updated_at
    -) VALUES (
    -  $1, $2, $3, $4, NOW(), NOW()
    -)
    -ON CONFLICT (user_handle) DO UPDATE SET
    -  name = EXCLUDED.name,
    -  email = EXCLUDED.email,
    -  updated_at = NOW()
    -RETURNING *;
    -
    --- name: GetUserByHandle :one
    -SELECT * FROM users WHERE user_handle = $1;
    -
    --- name: GetAllUsers :many
    -SELECT user_handle, name, email, created_at, updated_at 
    -FROM users 
    -ORDER BY user_handle ASC;
    -
    --- name: DeleteUser :exec
    -DELETE FROM users WHERE user_handle = $1;

    Generated Go code (queries.sql.go):

    // Generated by sqlc
    -func (q *Queries) UpsertUser(ctx context.Context, arg UpsertUserParams) (User, error) {
    -	row := q.db.QueryRow(ctx, upsertUser,
    -		arg.UserHandle,
    -		arg.Name,
    -		arg.Email,
    -		arg.VdbKey,
    -	)
    -	var i User
    -	err := row.Scan(
    -		&i.UserID,
    -		&i.UserHandle,
    -		&i.Name,
    -		&i.Email,
    -		&i.VdbKey,
    -		&i.CreatedAt,
    -		&i.UpdatedAt,
    -	)
    -	return i, err
    -}

    sqlc configuration (sqlc.yaml):

    version: "2"
    -sql:
    -  - engine: "postgresql"
    -    queries: "internal/database/queries/queries.sql"
    -    schema: "internal/database/migrations/"
    -    gen:
    -      go:
    -        package: "database"
    -        out: "internal/database"
    -        emit_json_tags: true
    -        emit_db_tags: true
    -        emit_prepared_queries: false
    -        emit_interface: false

    Regenerate code after query changes:

    sqlc generate --no-remote

    5. Authentication (internal/auth/)#

    Token-based authentication using Bearer tokens:

    // Middleware checks Authorization header
    -func AuthMiddleware(pool *pgxpool.Pool, adminKey string) func(http.Handler) http.Handler {
    -	return func(next http.Handler) http.Handler {
    -		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    -			
    -			// Extract Bearer token
    -			authHeader := r.Header.Get("Authorization")
    -			token := strings.TrimPrefix(authHeader, "Bearer ")
    -			
    -			if token == "" {
    -				// Allow public access for certain endpoints
    -				ctx := context.WithValue(r.Context(), "user", nil)
    -				next.ServeHTTP(w, r.WithContext(ctx))
    -				return
    -			}
    -			
    -			// Check admin key
    -			if token == adminKey {
    -				user := &AuthUser{Handle: "_admin", IsAdmin: true}
    -				ctx := context.WithValue(r.Context(), "user", user)
    -				next.ServeHTTP(w, r.WithContext(ctx))
    -				return
    -			}
    -			
    -			// Look up user by API key hash
    -			hash := hashAPIKey(token)
    -			user, err := db.GetUserByKeyHash(r.Context(), pool, hash)
    -			if err != nil {
    -				http.Error(w, "Unauthorized", http.StatusUnauthorized)
    -				return
    -			}
    -			
    -			authUser := &AuthUser{Handle: user.UserHandle, IsAdmin: false}
    -			ctx := context.WithValue(r.Context(), "user", authUser)
    -			next.ServeHTTP(w, r.WithContext(ctx))
    -		})
    -	}
    -}
    -
    -// Helper to get authenticated user from context
    -func GetAuthenticatedUser(ctx context.Context) *AuthUser {
    -	user, _ := ctx.Value("user").(*AuthUser)
    -	return user
    -}

    6. Encryption (internal/crypto/)#

    AES-256-GCM encryption for sensitive data (API keys):

    // Encrypt data with AES-256-GCM
    -func Encrypt(plaintext []byte, key []byte) ([]byte, error) {
    -	// Ensure key is 32 bytes
    -	keyHash := sha256.Sum256(key)
    -	
    -	// Create AES cipher
    -	block, err := aes.NewCipher(keyHash[:])
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	// Create GCM
    -	gcm, err := cipher.NewGCM(block)
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	// Generate random nonce
    -	nonce := make([]byte, gcm.NonceSize())
    -	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
    -		return nil, err
    -	}
    -	
    -	// Encrypt and append nonce
    -	ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
    -	return ciphertext, nil
    -}
    -
    -func Decrypt(ciphertext []byte, key []byte) ([]byte, error) {
    -	// Derive key
    -	keyHash := sha256.Sum256(key)
    -	
    -	block, err := aes.NewCipher(keyHash[:])
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	gcm, err := cipher.NewGCM(block)
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	// Extract nonce
    -	nonceSize := gcm.NonceSize()
    -	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    -	
    -	// Decrypt
    -	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	return plaintext, nil
    -}

    Huma Framework Integration#

    dhamps-vdb uses Huma for API development:

    Benefits#

    1. Automatic OpenAPI generation - No manual spec maintenance
    2. Request/response validation - Type-safe with JSON schema
    3. Error handling - Standardized error responses
    4. Documentation - Interactive docs at /docs

    Operation Registration Pattern#

    huma.Register(api, huma.Operation{
    -	OperationID:   "get-project",
    -	Method:        http.MethodGet,
    -	Path:          "/v1/projects/{owner}/{project}",
    -	Summary:       "Get project details",
    -	Description:   "Returns full project information including metadata schema",
    -	Tags:          []string{"Projects"},
    -	Security:      []map[string][]string{{"bearer": {}}},
    -	MaxBodyBytes:  1024,  // Limit request size
    -	DefaultStatus: http.StatusOK,
    -	Errors:        []int{400, 401, 403, 404, 500},
    -}, handlerFunction)

    Input/Output Patterns#

    // Path parameters, query parameters, and body
    -type GetSimilarInput struct {
    -	Owner     string  `path:"owner" doc:"Project owner"`
    -	Project   string  `path:"project" doc:"Project handle"`
    -	TextID    string  `path:"text_id" doc:"Text identifier"`
    -	Threshold float32 `query:"threshold" default:"0.5" doc:"Similarity threshold"`
    -	Limit     int     `query:"limit" default:"10" maximum:"200" doc:"Max results"`
    -}
    -
    -// Response with status code
    -type GetSimilarOutput struct {
    -	Status int
    -	Body   models.SimilarResponse
    -}

    Error Response Pattern#

    // Standard error responses
    -return nil, huma.Error400BadRequest("validation failed", err)
    -return nil, huma.Error401Unauthorized("invalid credentials")
    -return nil, huma.Error403Forbidden("insufficient permissions")
    -return nil, huma.Error404NotFound("project not found")
    -return nil, huma.Error500InternalServerError("database error", err)
    -
    -// Custom error with details
    -return nil, huma.NewError(400, "Dimension Mismatch", 
    -	fmt.Sprintf("expected %d dimensions, got %d", expected, actual))

    Design Patterns#

    1. Repository Pattern (via sqlc)#

    Database access is centralized in generated queries:

    // Don't write SQL in handlers
    -// Bad:
    -rows, err := pool.Query(ctx, "SELECT * FROM users")
    -
    -// Good: Use generated functions
    -users, err := db.GetAllUsers(ctx)

    2. Dependency Injection#

    Pass dependencies explicitly:

    // Inject pool into handlers
    -func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) {
    -	// Routes have access to pool
    -}
    -
    -// Store in context for handler access
    -ctx = context.WithValue(ctx, PoolKey, pool)

    3. Interface-Based Testing#

    Use interfaces for testability:

    // Production: Real random key generator
    -type StandardKeyGen struct{}
    -func (s StandardKeyGen) RandomKey(len int) (string, error) {
    -	b := make([]byte, len)
    -	_, err := rand.Read(b)
    -	return hex.EncodeToString(b), err
    -}
    -
    -// Testing: Deterministic key generator
    -type MockKeyGen struct {
    -	Keys []string
    -	idx  int
    -}
    -func (m *MockKeyGen) RandomKey(len int) (string, error) {
    -	key := m.Keys[m.idx]
    -	m.idx++
    -	return key, nil
    -}

    4. Validation at Multiple Layers#

    // 1. Huma validates request structure
    -type CreateEmbeddingInput struct {
    -	Body models.Embedding `maxLength:"1000000"`
    -}
    -
    -// 2. Model validates business rules
    -func (e *Embedding) Validate() error {
    -	if e.TextID == "" {
    -		return fmt.Errorf("text_id required")
    -	}
    -	return nil
    -}
    -
    -// 3. Handler validates against database state
    -func CreateEmbedding(ctx context.Context, input *CreateEmbeddingInput) error {
    -	// Check project exists
    -	// Validate dimensions match LLM service
    -	// Validate metadata against schema
    -	// Then insert
    -}

    5. Error Wrapping#

    Provide context while preserving original error:

    user, err := db.GetUserByHandle(ctx, handle)
    -if err != nil {
    -	if errors.Is(err, pgx.ErrNoRows) {
    -		return nil, huma.Error404NotFound("user not found")
    -	}
    -	return nil, fmt.Errorf("failed to retrieve user %s: %w", handle, err)
    -}

    Internal Packages#

    Go’s internal/ directory enforces package privacy:

    // This import works within dhamps-vdb
    -import "github.com/mpilhlt/dhamps-vdb/internal/database"
    -
    -// This import would FAIL from external projects
    -// Enforced by Go compiler

    Benefits:

    • Clear API boundaries
    • Implementation details hidden
    • Refactoring without breaking external users

    Performance Considerations#

    Connection Pooling#

    config.MaxConns = 20        // Max concurrent connections
    -config.MinConns = 5         // Keep-alive connections
    -config.MaxConnIdleTime = 5 * time.Minute

    Query Optimization#

    Use UNION ALL for better performance:

    // Instead of LEFT JOIN with OR conditions
    -query := `
    -	SELECT * FROM projects WHERE owner = $1
    -	UNION ALL
    -	SELECT p.* FROM projects p
    -	INNER JOIN projects_shared_with ps USING (project_id)
    -	WHERE ps.user_handle = $1
    -	ORDER BY owner, project_handle
    -`

    Index Strategy#

    -- Dimension filtering (very important)
    -CREATE INDEX ON embeddings(project_id, vector_dim);
    -
    --- Vector similarity (HNSW for accuracy)
    -CREATE INDEX ON embeddings USING hnsw (vector vector_cosine_ops);
    -
    --- Access lookups
    -CREATE INDEX ON projects_shared_with(user_handle);
    -CREATE INDEX ON projects(owner, project_handle);

    See Performance Guide for detailed optimization strategies.

    Testing Architecture#

    Test Organization#

    // handlers_test.go - Setup and utilities
    -func setupTestDB(t *testing.T) *pgxpool.Pool { }
    -func createTestUser(t *testing.T, pool *pgxpool.Pool) *models.User { }
    -
    -// users_test.go - User-specific tests
    -func TestCreateUser(t *testing.T) { }
    -func TestGetUser(t *testing.T) { }
    -
    -// projects_sharing_test.go - Sharing feature tests
    -func TestShareProject(t *testing.T) { }

    Testcontainers Integration#

    func setupTestDB(t *testing.T) *pgxpool.Pool {
    -	ctx := context.Background()
    -	
    -	// Start PostgreSQL with pgvector
    -	req := testcontainers.ContainerRequest{
    -		Image:        "pgvector/pgvector:0.7.4-pg16",
    -		ExposedPorts: []string{"5432/tcp"},
    -		Env: map[string]string{
    -			"POSTGRES_PASSWORD": "password",
    -			"POSTGRES_DB":       "testdb",
    -		},
    -	}
    -	
    -	container, err := testcontainers.GenericContainer(ctx, 
    -		testcontainers.GenericContainerRequest{
    -			ContainerRequest: req,
    -			Started:          true,
    -		})
    -	require.NoError(t, err)
    -	
    -	// Connect and migrate
    -	pool := connectAndMigrate(ctx, container)
    -	return pool
    -}

    See Testing Guide for comprehensive testing documentation.

    Build and Deployment#

    Building#

    # Development build
    -go build -o dhamps-vdb main.go
    -
    -# Production build with optimizations
    -go build -ldflags="-s -w" -o dhamps-vdb main.go
    -
    -# Cross-compilation
    -GOOS=linux GOARCH=amd64 go build -o dhamps-vdb-linux main.go

    Docker Build#

    Multi-stage build for minimal image:

    # Build stage
    -FROM golang:1.21-alpine AS builder
    -WORKDIR /app
    -COPY go.mod go.sum ./
    -RUN go mod download
    -COPY . .
    -RUN go build -ldflags="-s -w" -o dhamps-vdb main.go
    -
    -# Runtime stage
    -FROM alpine:latest
    -RUN apk --no-cache add ca-certificates
    -WORKDIR /root/
    -COPY --from=builder /app/dhamps-vdb .
    -EXPOSE 8880
    -CMD ["./dhamps-vdb"]

    Configuration#

    Application reads configuration from:

    1. Command line flags: --port 8080
    2. Environment variables: SERVICE_PORT=8080
    3. .env file: SERVICE_PORT=8080

    Priority: CLI flags > Environment > .env file > Defaults

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/development/contributing/index.html b/docs/public/development/contributing/index.html deleted file mode 100644 index e09f09f..0000000 --- a/docs/public/development/contributing/index.html +++ /dev/null @@ -1,306 +0,0 @@ -Contributing | dhamps-vdb Documentation - -

    Contributing Guide#

    Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.

    Development Setup#

    Prerequisites#

    • Go 1.21+: Download Go
    • PostgreSQL 16+: With pgvector extension
    • sqlc: For generating type-safe database code
    • Docker/Podman: For running tests
    • Git: For version control

    Clone and Build#

    # Clone repository
    -git clone https://github.com/mpilhlt/dhamps-vdb.git
    -cd dhamps-vdb
    -
    -# Install dependencies
    -go get ./...
    -
    -# Generate sqlc code
    -sqlc generate --no-remote
    -
    -# Build application
    -go build -o build/dhamps-vdb main.go
    -
    -# Or run directly
    -go run main.go

    Environment Setup#

    Create a .env file for local development:

    # Copy template
    -cp template.env .env
    -
    -# Edit with your settings
    -SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8880
    -SERVICE_ADMINKEY=your-secure-admin-key-here
    -
    -# Database settings
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=password
    -SERVICE_DBNAME=dhamps_vdb_dev
    -
    -# Encryption key (32+ characters)
    -ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars

    Important: Never commit .env files (already in .gitignore)

    Database Setup#

    For local development:

    # Start PostgreSQL with pgvector
    -podman run -p 5432:5432 \
    -  -e POSTGRES_PASSWORD=password \
    -  -e POSTGRES_DB=dhamps_vdb_dev \
    -  pgvector/pgvector:0.7.4-pg16
    -
    -# Or use docker-compose
    -docker-compose up -d
    -
    -# Application auto-migrates on startup
    -go run main.go

    Verify Setup#

    # Check application starts
    -go run main.go
    -
    -# In another terminal, test API
    -curl http://localhost:8880/docs
    -
    -# Run tests
    -go test -v ./...

    Code Style#

    Go Formatting#

    dhamps-vdb follows standard Go conventions:

    # Format all code
    -go fmt ./...
    -
    -# Check for common issues
    -go vet ./...
    -
    -# Run linter (if installed)
    -golangci-lint run

    Code Organization#

    Follow existing patterns:

    // Package comment at top of file
    -package handlers
    -
    -import (
    -	// Standard library first
    -	"context"
    -	"fmt"
    -	
    -	// External packages
    -	"github.com/danielgtaylor/huma/v2"
    -	"github.com/jackc/pgx/v5/pgxpool"
    -	
    -	// Internal packages
    -	"github.com/mpilhlt/dhamps-vdb/internal/database"
    -	"github.com/mpilhlt/dhamps-vdb/internal/models"
    -)
    -
    -// Exported function with doc comment
    -// GetUsers retrieves all users from the database
    -func GetUsers(ctx context.Context, pool *pgxpool.Pool) ([]models.User, error) {
    -	// Implementation
    -}

    Naming Conventions#

    Files:

    • handlers/users.go - Implementation
    • handlers/users_test.go - Tests
    • handlers/users_sharing_test.go - Specific feature tests

    Functions:

    • GetUsers() - List/retrieve multiple
    • GetUser() - Retrieve single
    • CreateUser() - Create new
    • UpdateUser() - Update existing
    • DeleteUser() - Delete
    • LinkUserToProject() - Create association
    • IsProjectOwner() - Boolean check

    Database Queries (in queries.sql):

    • -- name: GetAllUsers :many
    • -- name: RetrieveUserByHandle :one
    • -- name: UpsertUser :one
    • -- name: DeleteUser :exec

    Error Handling#

    // Return errors, don't panic
    -func CreateUser(ctx context.Context, pool *pgxpool.Pool, user models.User) error {
    -	if user.Handle == "" {
    -		return fmt.Errorf("user handle is required")
    -	}
    -	
    -	// Wrap errors with context
    -	err := db.InsertUser(ctx, user)
    -	if err != nil {
    -		return fmt.Errorf("failed to insert user: %w", err)
    -	}
    -	
    -	return nil
    -}
    -
    -// Use specific error responses in handlers
    -func handleCreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) {
    -	err := CreateUser(ctx, pool, input.Body)
    -	if err != nil {
    -		return nil, huma.Error400BadRequest("invalid user data", err)
    -	}
    -	
    -	return &CreateUserOutput{Body: result}, nil
    -}

    Comments#

    Comment public APIs and complex logic:

    // GetAccessibleProjects returns all projects the user can access.
    -// This includes projects owned by the user and projects shared with them.
    -// Results are paginated using limit and offset.
    -func GetAccessibleProjects(ctx context.Context, pool *pgxpool.Pool, 
    -	userHandle string, limit, offset int) ([]models.Project, error) {
    -	
    -	// Use UNION ALL for better query performance
    -	// See docs/PERFORMANCE_OPTIMIZATION.md for details
    -	query := `
    -		SELECT * FROM projects WHERE owner = $1
    -		UNION ALL
    -		SELECT p.* FROM projects p
    -		INNER JOIN projects_shared_with ps ON p.project_id = ps.project_id
    -		WHERE ps.user_handle = $1
    -	`
    -	
    -	// Implementation...
    -}

    Don’t over-comment obvious code:

    // Bad - obvious
    -// i is set to 0
    -i := 0
    -
    -// Good - explains why
    -// Start from second element (first is header)
    -i := 1

    Git Workflow#

    Branching Strategy#

    # Create feature branch from main
    -git checkout main
    -git pull origin main
    -git checkout -b feature/your-feature-name
    -
    -# Create fix branch
    -git checkout -b fix/issue-description
    -
    -# Create docs branch
    -git checkout -b docs/update-contributing-guide

    Branch naming:

    • feature/* - New features
    • fix/* - Bug fixes
    • docs/* - Documentation updates
    • test/* - Test improvements
    • refactor/* - Code refactoring

    Commit Messages#

    Write clear, descriptive commit messages:

    # Good commit messages
    -git commit -m "Add project sharing functionality"
    -git commit -m "Fix dimension validation for embeddings"
    -git commit -m "Update contributing guide with git workflow"
    -
    -# Multi-line for complex changes
    -git commit -m "Refactor similarity search query
    -
    -- Use UNION ALL for better performance
    -- Add dimension filtering to subqueries
    -- Update tests to verify performance improvement
    -
    -Closes #123"

    Commit message format:

    • First line: Brief summary (50 chars or less)
    • Blank line
    • Detailed explanation if needed
    • Reference issues: Closes #123 or Fixes #456

    Pull Request Process#

    1. Create feature branch

      git checkout -b feature/my-feature
    2. Make changes and commit

      git add .
      -git commit -m "Add feature description"
    3. Keep branch updated

      git fetch origin
      -git rebase origin/main
    4. Push to your fork

      git push origin feature/my-feature
    5. Create Pull Request

      • Go to GitHub repository
      • Click “New Pull Request”
      • Select your branch
      • Fill in PR template
    6. PR Review Process

      • Automated tests run
      • Code review by maintainers
      • Address feedback
      • Merge when approved

    PR Title Format#

    [Type] Brief description
    -
    -Examples:
    -[Feature] Add project ownership transfer
    -[Fix] Correct dimension validation in embeddings
    -[Docs] Update API documentation for similarity search
    -[Test] Add integration tests for sharing workflow
    -[Refactor] Simplify authentication middleware

    PR Description Template#

    ## Description
    -Brief description of changes
    -
    -## Motivation
    -Why is this change needed?
    -
    -## Changes
    -- Change 1
    -- Change 2
    -- Change 3
    -
    -## Testing
    -How was this tested?
    -- [ ] Unit tests pass
    -- [ ] Integration tests pass
    -- [ ] Manual testing performed
    -
    -## Related Issues
    -Closes #123
    -Relates to #456
    -
    -## Checklist
    -- [ ] Code follows style guidelines
    -- [ ] Tests added/updated
    -- [ ] Documentation updated
    -- [ ] No breaking changes (or clearly documented)

    Testing Requirements#

    All contributions must include tests:

    For New Features#

    // Add tests in same package
    -// File: handlers/projects.go
    -func CreateProject(...) { ... }
    -
    -// File: handlers/projects_test.go
    -func TestCreateProject(t *testing.T) {
    -	// Test happy path
    -	// Test error cases
    -	// Test edge cases
    -}

    For Bug Fixes#

    // Add regression test
    -func TestBugFix_Issue123(t *testing.T) {
    -	// Reproduce the bug
    -	// Verify it's fixed
    -}

    Test Coverage#

    Aim for reasonable coverage:

    # Check coverage
    -go test -cover ./...
    -
    -# Generate coverage report
    -go test -coverprofile=coverage.out ./...
    -go tool cover -html=coverage.out

    Target coverage: 70%+ for new code

    Running Tests#

    # Before submitting PR
    -go test -v ./...
    -
    -# With race detection
    -go test -race ./...
    -
    -# Specific package
    -go test -v ./internal/handlers

    See Testing Guide for detailed information.

    Documentation Updates#

    When to Update Docs#

    Update documentation for:

    • New features: Add usage examples
    • API changes: Update endpoint documentation
    • Breaking changes: Clearly document migration path
    • Configuration: New environment variables or options

    Documentation Structure#

    docs/content/
    -├── getting-started/     # Installation, quickstart
    -├── concepts/            # Core concepts
    -├── guides/              # How-to guides
    -├── api/                 # API reference
    -└── development/         # Development docs (this section)

    Adding Documentation#

    # Create new doc file
    -cd docs/content/guides
    -cat > new-guide.md <<EOF
    ----
    -title: "Your Guide Title"
    -weight: 5
    ----
    -
    -# Your Guide
    -
    -Content here...
    -EOF

    Hugo Front Matter#

    All docs need front matter:

    ---
    -title: "Page Title"
    -weight: 1          # Determines order in menu
    -draft: false       # Set true for work in progress
    ----

    Code Examples in Docs#

    Include working examples:

    ```bash
    -# Example command
    -curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer admin-key" \
    -  -d '{"user_handle":"alice"}'
    -```
    -
    -```go
    -// Example Go code
    -user := models.User{
    -	Handle: "alice",
    -	Name:   "Alice Smith",
    -}
    -err := CreateUser(ctx, pool, user)
    -```

    Issue Reporting#

    Before Creating an Issue#

    1. Search existing issues
    2. Check documentation
    3. Try latest version
    4. Prepare reproduction steps

    Bug Report Template#

    ## Bug Description
    -Clear description of the bug
    -
    -## Steps to Reproduce
    -1. Start application with these settings...
    -2. Send this request...
    -3. Observe error...
    -
    -## Expected Behavior
    -What should happen
    -
    -## Actual Behavior
    -What actually happens
    -
    -## Environment
    -- dhamps-vdb version: v0.1.0
    -- Go version: 1.21.5
    -- PostgreSQL version: 16.1
    -- OS: Ubuntu 22.04
    -
    -## Logs

    Relevant error logs here

    
    -## Additional Context
    -Any other relevant information

    Feature Request Template#

    ## Feature Description
    -Clear description of proposed feature
    -
    -## Use Case
    -Why is this needed? Who benefits?
    -
    -## Proposed Solution
    -How should it work?
    -
    -## Alternatives Considered
    -Other approaches you've thought about
    -
    -## Additional Context
    -Examples, mockups, related features

    Code Review Guidelines#

    For Reviewers#

    • Be constructive: Suggest improvements, don’t just criticize
    • Ask questions: “Could we handle this case?” vs “This is wrong”
    • Explain reasoning: Help author understand why
    • Approve when ready: Don’t be too pedantic on style

    For Authors#

    • Respond to feedback: Address all comments
    • Ask for clarification: If feedback unclear
    • Don’t take it personally: Focus on improving code
    • Update PR: Push changes after addressing feedback

    What Reviewers Check#

    • Code follows style guidelines
    • Tests are comprehensive
    • Documentation is updated
    • No obvious bugs or security issues
    • Error handling is appropriate
    • Performance considerations addressed
    • Breaking changes documented

    Release Process#

    Maintainers handle releases, but contributors should:

    1. Document breaking changes in PR description
    2. Update CHANGELOG if applicable
    3. Tag related issues with milestone

    Development Best Practices#

    1. Start Small#

    • Small PRs are easier to review
    • Focus on one feature/fix per PR
    • Break large changes into multiple PRs

    2. Write Tests First#

    // Write test first (TDD approach)
    -func TestNewFeature(t *testing.T) {
    -	// This will fail initially
    -	result := NewFeature()
    -	assert.Equal(t, expected, result)
    -}
    -
    -// Then implement
    -func NewFeature() Result {
    -	// Implementation
    -}

    3. Use Type Safety#

    // Generate type-safe queries with sqlc
    -// Edit: internal/database/queries/queries.sql
    --- name: GetUserByHandle :one
    -SELECT * FROM users WHERE user_handle = $1;
    -
    -// Then regenerate
    -sqlc generate --no-remote
    -
    -// Use generated code
    -user, err := db.GetUserByHandle(ctx, handle)

    4. Handle Errors Properly#

    // Don't ignore errors
    -result, err := SomeFunction()
    -if err != nil {
    -	return fmt.Errorf("operation failed: %w", err)
    -}
    -
    -// Provide context
    -if err := ValidateInput(input); err != nil {
    -	return huma.Error400BadRequest("invalid input", err)
    -}

    5. Keep It Simple#

    • Prefer clarity over cleverness
    • Use standard library when possible
    • Don’t over-engineer solutions

    Getting Help#

    Resources#

    • Documentation: Browse /docs folder
    • API Docs: Run locally and visit /docs endpoint
    • Code Examples: Check testdata/ for examples
    • Test Files: See how features are tested

    Communication#

    • GitHub Issues: For bugs and feature requests
    • Pull Requests: For code discussions
    • Code Comments: For implementation questions

    Asking Questions#

    Good questions include:

    • What you’re trying to accomplish
    • What you’ve already tried
    • Relevant code snippets
    • Error messages (full stack trace)

    License#

    By contributing, you agree that your contributions will be licensed under the MIT License.

    Recognition#

    Contributors are acknowledged in:

    • Git commit history
    • GitHub contributors page
    • Release notes (for significant contributions)

    Thank you for contributing to dhamps-vdb! 🎉

    \ No newline at end of file diff --git a/docs/public/development/index.html b/docs/public/development/index.html deleted file mode 100644 index fe982ac..0000000 --- a/docs/public/development/index.html +++ /dev/null @@ -1,17 +0,0 @@ -Development | dhamps-vdb Documentation - -

    Development Guide#

    Information for developers contributing to dhamps-vdb.

    Getting Started with Development#

    This section covers:

    • Setting up a development environment
    • Running tests
    • Understanding the codebase architecture
    • Contributing guidelines
    • Performance optimization

    Project Structure#

    dhamps-vdb/
    -├── main.go                    # Application entry point
    -├── internal/
    -│   ├── auth/                  # Authentication logic
    -│   ├── database/              # Database layer (sqlc)
    -│   ├── handlers/              # HTTP handlers
    -│   └── models/                # Data models
    -├── testdata/                  # Test fixtures
    -└── docs/                      # Documentation

    Development Workflow#

    1. Make changes to code
    2. Generate sqlc code if database queries changed: sqlc generate
    3. Run tests: go test -v ./...
    4. Build: go build -o dhamps-vdb main.go
    5. Submit pull request

    Resources#

    \ No newline at end of file diff --git a/docs/public/development/index.xml b/docs/public/development/index.xml deleted file mode 100644 index d77939e..0000000 --- a/docs/public/development/index.xml +++ /dev/null @@ -1,137 +0,0 @@ -Development on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/development/Recent content in Development on dhamps-vdb DocumentationHugoen-usTestinghttps://mpilhlt.github.io/dhamps-vdb/development/testing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/testing/<h1 id="testing-guide">Testing Guide<a class="anchor" href="#testing-guide">#</a></h1> -<p>This guide covers how to run and write tests for dhamps-vdb.</p> -<h2 id="running-tests">Running Tests<a class="anchor" href="#running-tests">#</a></h2> -<p>dhamps-vdb uses integration tests that spin up real PostgreSQL containers using <a href="https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/">testcontainers</a>. This approach ensures tests run against actual database instances with pgvector support.</p> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<p><strong>Using Podman (Recommended for Linux):</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start podman socket</span> -</span></span><span style="display:flex;"><span>systemctl --user start podman.socket -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Export DOCKER_HOST for testcontainers</span> -</span></span><span style="display:flex;"><span>export DOCKER_HOST<span style="color:#f92672">=</span>unix://$XDG_RUNTIME_DIR/podman/podman.sock</span></span></code></pre></div><p><strong>Using Docker:</strong></p> -<p>Testcontainers works with Docker out of the box. Ensure Docker daemon is running.</p>Contributinghttps://mpilhlt.github.io/dhamps-vdb/development/contributing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/contributing/<h1 id="contributing-guide">Contributing Guide<a class="anchor" href="#contributing-guide">#</a></h1> -<p>Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.</p> -<h2 id="development-setup">Development Setup<a class="anchor" href="#development-setup">#</a></h2> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<ul> -<li><strong>Go 1.21+</strong>: <a href="https://go.dev/dl/">Download Go</a></li> -<li><strong>PostgreSQL 16+</strong>: With pgvector extension</li> -<li><strong>sqlc</strong>: For generating type-safe database code</li> -<li><strong>Docker/Podman</strong>: For running tests</li> -<li><strong>Git</strong>: For version control</li> -</ul> -<h3 id="clone-and-build">Clone and Build<a class="anchor" href="#clone-and-build">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies</span> -</span></span><span style="display:flex;"><span>go get ./... -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate sqlc code</span> -</span></span><span style="display:flex;"><span>sqlc generate --no-remote -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build application</span> -</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Or run directly</span> -</span></span><span style="display:flex;"><span>go run main.go</span></span></code></pre></div><h3 id="environment-setup">Environment Setup<a class="anchor" href="#environment-setup">#</a></h3> -<p>Create a <code>.env</code> file for local development:</p>Architecturehttps://mpilhlt.github.io/dhamps-vdb/development/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/architecture/<h1 id="technical-architecture">Technical Architecture<a class="anchor" href="#technical-architecture">#</a></h1> -<p>This document provides a technical deep-dive into dhamps-vdb&rsquo;s architecture for developers who want to understand or modify the codebase.</p> -<h2 id="project-structure">Project Structure<a class="anchor" href="#project-structure">#</a></h2> -<pre tabindex="0"><code>dhamps-vdb/ -├── main.go # Application entry point -├── go.mod # Go module definition -├── go.sum # Dependency checksums -├── sqlc.yaml # sqlc configuration -├── template.env # Environment template -├── .env # Local config (gitignored) -│ -├── api/ -│ └── openapi.yml # OpenAPI spec (not actively maintained) -│ -├── internal/ # Internal packages (non-importable) -│ ├── auth/ # Authentication logic -│ │ └── authenticate.go # Bearer token validation -│ │ -│ ├── crypto/ # Encryption utilities -│ │ └── crypto.go # AES-256-GCM encryption -│ │ -│ ├── database/ # Database layer -│ │ ├── database.go # Connection pool management -│ │ ├── migrations.go # Migration runner -│ │ ├── db.go # Generated by sqlc -│ │ ├── models.go # Generated by sqlc -│ │ ├── queries.sql.go # Generated by sqlc -│ │ │ -│ │ ├── migrations/ # SQL migrations -│ │ │ ├── 001_create_initial_scheme.sql -│ │ │ ├── 002_create_emb_index.sql -│ │ │ ├── 003_add_public_read_flag.sql -│ │ │ ├── 004_refactor_llm_services_architecture.sql -│ │ │ ├── tern.conf.tpl # Template for tern -│ │ │ └── tern.conf # Generated (gitignored) -│ │ │ -│ │ └── queries/ # SQL queries for sqlc -│ │ └── queries.sql # All database queries -│ │ -│ ├── handlers/ # HTTP request handlers -│ │ ├── handlers.go # Common handler utilities -│ │ ├── users.go # User endpoints -│ │ ├── projects.go # Project endpoints -│ │ ├── llm_services.go # LLM service endpoints -│ │ ├── api_standards.go # API standard endpoints -│ │ ├── embeddings.go # Embedding endpoints -│ │ ├── similars.go # Similarity search endpoints -│ │ ├── admin.go # Admin endpoints -│ │ │ -│ │ └── *_test.go # Test files -│ │ ├── users_test.go -│ │ ├── projects_test.go -│ │ ├── projects_sharing_test.go -│ │ ├── embeddings_test.go -│ │ ├── llm_services_test.go -│ │ ├── editor_permissions_test.go -│ │ └── handlers_test.go -│ │ -│ └── models/ # Data models and options -│ ├── options.go # CLI/environment options -│ ├── users.go # User models -│ ├── projects.go # Project models -│ ├── instances.go # LLM instance models (new) -│ ├── api_standards.go # API standard models -│ ├── embeddings.go # Embedding models -│ ├── similars.go # Similarity search models -│ └── admin.go # Admin operation models -│ -├── testdata/ # Test fixtures -│ ├── postgres/ # PostgreSQL test data -│ │ ├── enable-vector.sql -│ │ └── users.yml -│ │ -│ └── *.json # JSON test fixtures -│ ├── valid_user.json -│ ├── valid_embeddings.json -│ ├── valid_api_standard_*.json -│ └── valid_llm_service_*.json -│ -└── docs/ # Documentation - ├── content/ # Hugo content - └── *.md # Additional docs</code></pre><h2 id="code-organization">Code Organization<a class="anchor" href="#code-organization">#</a></h2> -<h3 id="1-entry-point-maingo">1. Entry Point (<code>main.go</code>)<a class="anchor" href="#1-entry-point-maingo">#</a></h3> -<p>The application entry point handles:</p>Performancehttps://mpilhlt.github.io/dhamps-vdb/development/performance/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/performance/<h1 id="performance-optimization-guide">Performance Optimization Guide<a class="anchor" href="#performance-optimization-guide">#</a></h1> -<p>This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.</p> -<h2 id="query-optimization">Query Optimization<a class="anchor" href="#query-optimization">#</a></h2> -<h3 id="getallaccessibleinstances-query">GetAllAccessibleInstances Query<a class="anchor" href="#getallaccessibleinstances-query">#</a></h3> -<p><strong>Problem:</strong> The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.</p> -<p><strong>Current Implementation:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> instances.<span style="color:#f92672">*</span>, -</span></span><span style="display:flex;"><span> COALESCE(instances_shared_with.<span style="color:#66d9ef">role</span>, <span style="color:#e6db74">&#39;owner&#39;</span>) <span style="color:#66d9ef">as</span> <span style="color:#66d9ef">role</span>, -</span></span><span style="display:flex;"><span> (instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span>) <span style="color:#66d9ef">as</span> is_owner -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> instances -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LEFT</span> <span style="color:#66d9ef">JOIN</span> instances_shared_with -</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">ON</span> instances.instance_id <span style="color:#f92672">=</span> instances_shared_with.instance_id -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> -</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">OR</span> instances_shared_with.user_handle <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#66d9ef">ASC</span>, instances.instance_handle <span style="color:#66d9ef">ASC</span> -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LIMIT</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">2</span> <span style="color:#66d9ef">OFFSET</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">3</span>;</span></span></code></pre></div><p><strong>Issue:</strong> The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.</p> \ No newline at end of file diff --git a/docs/public/development/performance/index.html b/docs/public/development/performance/index.html deleted file mode 100644 index dd95910..0000000 --- a/docs/public/development/performance/index.html +++ /dev/null @@ -1,470 +0,0 @@ -Performance | dhamps-vdb Documentation - -

    Performance Optimization Guide#

    This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.

    Query Optimization#

    GetAllAccessibleInstances Query#

    Problem: The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.

    Current Implementation:

    SELECT instances.*, 
    -       COALESCE(instances_shared_with.role, 'owner') as role,
    -       (instances.owner = $1) as is_owner
    -FROM instances
    -LEFT JOIN instances_shared_with
    -  ON instances.instance_id = instances_shared_with.instance_id
    -WHERE instances.owner = $1
    -   OR instances_shared_with.user_handle = $1
    -ORDER BY instances.owner ASC, instances.instance_handle ASC 
    -LIMIT $2 OFFSET $3;

    Issue: The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.

    Use UNION ALL to separate owned instances from shared instances:

    -- Get owned instances
    -SELECT instances.*, 
    -       'owner' as role, 
    -       true as is_owner
    -FROM instances
    -WHERE instances.owner = $1
    -
    -UNION ALL
    -
    --- Get shared instances
    -SELECT instances.*, 
    -       instances_shared_with.role,
    -       false as is_owner
    -FROM instances
    -INNER JOIN instances_shared_with
    -  ON instances.instance_id = instances_shared_with.instance_id
    -WHERE instances_shared_with.user_handle = $1
    -  AND instances.owner != $1  -- Avoid duplicates
    -
    -ORDER BY owner ASC, instance_handle ASC
    -LIMIT $2 OFFSET $3;

    Benefits:

    1. Separate index scans: Query planner can use different indexes for each UNION branch
    2. Owned instances: Can use index on (owner)
    3. Shared instances: Can use index on (user_handle)
    4. Clearer execution plan: Easier to understand and optimize
    5. Better performance: Especially noticeable with large datasets

    Trade-offs:

    • Slightly more complex SQL
    • Need to deduplicate if user somehow has instance both owned and shared (unlikely scenario)
    • Both queries must have same column structure

    Implementation Example#

    Before (queries.sql):

    -- name: GetAllAccessibleInstances :many
    -SELECT instances.*, ...
    -FROM instances
    -LEFT JOIN instances_shared_with ON ...
    -WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1

    After (queries.sql):

    -- name: GetAllAccessibleInstances :many
    -SELECT instances.*, 'owner' as role, true as is_owner
    -FROM instances
    -WHERE instances.owner = $1
    -UNION ALL
    -SELECT instances.*, isw.role, false as is_owner
    -FROM instances
    -INNER JOIN instances_shared_with isw ON instances.instance_id = isw.instance_id
    -WHERE isw.user_handle = $1 AND instances.owner != $1
    -ORDER BY owner, instance_handle
    -LIMIT $2 OFFSET $3;

    When to optimize:

    • Current implementation is correct and works well for small-medium datasets
    • Consider optimization if performance becomes an issue with:
      • Large numbers of instances (>1000)
      • Many shared relationships (>100 shares per user)
      • Query time consistently >100ms

    Always profile first:

    EXPLAIN ANALYZE 
    -SELECT instances.*, ...
    -FROM instances
    -LEFT JOIN instances_shared_with ON ...
    -WHERE instances.owner = 'alice' OR instances_shared_with.user_handle = 'alice';

    Index Optimization#

    Current Indexes#

    From migration 004_refactor_llm_services_architecture.sql:

    -- API Standards / Definitions
    -CREATE INDEX idx_definitions_handle 
    -  ON definitions(definition_handle);
    -
    -CREATE INDEX idx_definitions_owner_handle 
    -  ON definitions(owner, definition_handle);
    -
    --- Instances
    -CREATE INDEX idx_instances_handle 
    -  ON instances(instance_handle);
    -
    --- Sharing (implicit from PRIMARY KEY)
    --- instances_shared_with(instance_id, user_handle)

    1. Owner Lookups#

    -- For queries: WHERE instances.owner = ?
    -CREATE INDEX idx_instances_owner 
    -  ON instances(owner);

    Benefit: Fast retrieval of user’s owned instances

    Use case:

    SELECT * FROM instances WHERE owner = 'alice';

    2. Shared Instance Lookups#

    -- For queries: WHERE user_handle = ?
    -CREATE INDEX idx_instances_shared_user 
    -  ON instances_shared_with(user_handle);

    Benefit: Fast retrieval of instances shared with user

    Use case:

    SELECT i.* FROM instances i
    -INNER JOIN instances_shared_with isw ON i.instance_id = isw.instance_id
    -WHERE isw.user_handle = 'bob';

    3. Composite Owner+Handle Index#

    -- For unique constraint and lookups
    -CREATE UNIQUE INDEX idx_instances_owner_handle 
    -  ON instances(owner, instance_handle);

    Benefit: Enforces uniqueness and enables index-only scans

    Use case:

    SELECT * FROM instances 
    -WHERE owner = 'alice' AND instance_handle = 'my-service';

    4. Embedding Dimension Filtering#

    -- Critical for similarity search performance
    -CREATE INDEX idx_embeddings_project_dim 
    -  ON embeddings(project_id, vector_dim);

    Benefit: Filters embeddings by dimension before vector comparison

    Use case:

    SELECT * FROM embeddings 
    -WHERE project_id = 123 
    -  AND vector_dim = 1536
    -ORDER BY vector <=> $1::vector
    -LIMIT 10;

    5. Project Ownership#

    CREATE INDEX idx_projects_owner 
    -  ON projects(owner);
    -
    -CREATE UNIQUE INDEX idx_projects_owner_handle 
    -  ON projects(owner, project_handle);

    Index Analysis#

    Check if indexes are being used:

    -- Analyze query plan
    -EXPLAIN ANALYZE 
    -SELECT * FROM instances WHERE owner = 'alice';
    -
    --- Check index usage statistics
    -SELECT 
    -  schemaname,
    -  tablename,
    -  indexname,
    -  idx_scan,
    -  idx_tup_read,
    -  idx_tup_fetch
    -FROM pg_stat_user_indexes
    -WHERE schemaname = 'public'
    -ORDER BY idx_scan DESC;
    -
    --- Find unused indexes
    -SELECT 
    -  schemaname,
    -  tablename,
    -  indexname
    -FROM pg_stat_user_indexes
    -WHERE idx_scan = 0
    -  AND schemaname = 'public';

    Index Maintenance#

    -- Update statistics for query planner
    -ANALYZE instances;
    -ANALYZE instances_shared_with;
    -ANALYZE embeddings;
    -
    --- Rebuild index if fragmented
    -REINDEX INDEX idx_instances_owner;
    -
    --- Check index size
    -SELECT 
    -  indexname,
    -  pg_size_pretty(pg_relation_size(indexrelid)) AS size
    -FROM pg_stat_user_indexes
    -WHERE schemaname = 'public'
    -ORDER BY pg_relation_size(indexrelid) DESC;

    Vector Index Optimization#

    HNSW vs IVFFlat#

    Current implementation uses HNSW:

    CREATE INDEX embedding_vector_idx 
    -ON embeddings 
    -USING hnsw (vector vector_cosine_ops);

    HNSW (Hierarchical Navigable Small World)#

    Pros:

    • Better recall (finds more similar results)
    • Better query performance
    • No training required

    Cons:

    • Slower index build time
    • Higher memory usage
    • Larger index size

    Configuration options:

    -- Default: m=16, ef_construction=64
    -CREATE INDEX embedding_vector_idx 
    -ON embeddings 
    -USING hnsw (vector vector_cosine_ops)
    -WITH (m = 16, ef_construction = 64);
    -
    --- Higher quality (slower build): m=32, ef_construction=128
    -CREATE INDEX embedding_vector_idx_hq
    -ON embeddings 
    -USING hnsw (vector vector_cosine_ops)
    -WITH (m = 32, ef_construction = 128);

    Parameters:

    • m: Number of connections per layer (default 16, range 2-100)
    • ef_construction: Size of candidate list during build (default 64, range 4-1000)
    • Higher values = better recall but slower build and more memory

    IVFFlat (Inverted File with Flat compression)#

    Alternative for very large datasets:

    CREATE INDEX embedding_vector_idx_ivf
    -ON embeddings 
    -USING ivfflat (vector vector_cosine_ops)
    -WITH (lists = 100);

    Pros:

    • Faster index build
    • Lower memory usage
    • Smaller index size

    Cons:

    • Requires training (ANALYZE before creating index)
    • Lower recall than HNSW
    • Need to tune lists parameter

    When to use:

    • Dataset >1M embeddings
    • Build time is critical
    • Memory constrained environment

    Configuration:

    -- Rule of thumb: lists = sqrt(total_rows)
    --- For 100K embeddings: lists = 316
    --- For 1M embeddings: lists = 1000
    -
    --- Train the index
    -ANALYZE embeddings;
    -
    --- Create with appropriate lists
    -CREATE INDEX embedding_vector_idx_ivf
    -ON embeddings 
    -USING ivfflat (vector vector_cosine_ops)
    -WITH (lists = 1000);
    -
    --- Set probes at query time
    -SET ivfflat.probes = 10;  -- Default is 1, higher = better recall

    Query-Time Optimization#

    For HNSW, set hnsw.ef_search:

    -- Default: ef_search = 40
    --- Higher = better recall but slower queries
    -SET hnsw.ef_search = 100;
    -
    -SELECT vector <=> $1::vector AS distance
    -FROM embeddings
    -WHERE project_id = 123
    -ORDER BY distance
    -LIMIT 10;

    Dimension-Specific Indexes#

    For multi-dimensional projects:

    -- Separate indexes per common dimension
    -CREATE INDEX idx_embeddings_768_vector 
    -ON embeddings USING hnsw (vector vector_cosine_ops)
    -WHERE vector_dim = 768;
    -
    -CREATE INDEX idx_embeddings_1536_vector 
    -ON embeddings USING hnsw (vector vector_cosine_ops)
    -WHERE vector_dim = 1536;
    -
    -CREATE INDEX idx_embeddings_3072_vector 
    -ON embeddings USING hnsw (vector vector_cosine_ops)
    -WHERE vector_dim = 3072;

    Benefit: Smaller indexes = faster queries for specific dimensions

    Caching Strategies#

    1. System Definitions Cache#

    System definitions rarely change:

    var (
    -	systemDefsCache   []models.Definition
    -	systemDefsCacheMu sync.RWMutex
    -	systemDefsCacheTTL = 5 * time.Minute
    -	systemDefsCacheExp time.Time
    -)
    -
    -func GetSystemDefinitions(ctx context.Context, pool *pgxpool.Pool) ([]models.Definition, error) {
    -	systemDefsCacheMu.RLock()
    -	if time.Now().Before(systemDefsCacheExp) && systemDefsCache != nil {
    -		defer systemDefsCacheMu.RUnlock()
    -		return systemDefsCache, nil
    -	}
    -	systemDefsCacheMu.RUnlock()
    -	
    -	// Fetch from database
    -	defs, err := db.GetDefinitionsByOwner(ctx, "_system")
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	// Update cache
    -	systemDefsCacheMu.Lock()
    -	systemDefsCache = defs
    -	systemDefsCacheExp = time.Now().Add(systemDefsCacheTTL)
    -	systemDefsCacheMu.Unlock()
    -	
    -	return defs, nil
    -}

    2. User Instances Cache#

    Cache user’s instance list with short TTL:

    type InstanceCache struct {
    -	data map[string][]models.Instance
    -	mu   sync.RWMutex
    -	ttl  time.Duration
    -	exp  map[string]time.Time
    -}
    -
    -func (c *InstanceCache) Get(userHandle string) ([]models.Instance, bool) {
    -	c.mu.RLock()
    -	defer c.mu.RUnlock()
    -	
    -	if exp, ok := c.exp[userHandle]; ok && time.Now().Before(exp) {
    -		return c.data[userHandle], true
    -	}
    -	return nil, false
    -}
    -
    -func (c *InstanceCache) Set(userHandle string, instances []models.Instance) {
    -	c.mu.Lock()
    -	defer c.mu.Unlock()
    -	
    -	c.data[userHandle] = instances
    -	c.exp[userHandle] = time.Now().Add(c.ttl)
    -}
    -
    -func (c *InstanceCache) Invalidate(userHandle string) {
    -	c.mu.Lock()
    -	defer c.mu.Unlock()
    -	
    -	delete(c.data, userHandle)
    -	delete(c.exp, userHandle)
    -}

    Usage:

    var instanceCache = &InstanceCache{
    -	data: make(map[string][]models.Instance),
    -	exp:  make(map[string]time.Time),
    -	ttl:  30 * time.Second,
    -}
    -
    -func GetUserInstances(ctx context.Context, pool *pgxpool.Pool, userHandle string) ([]models.Instance, error) {
    -	// Check cache
    -	if instances, ok := instanceCache.Get(userHandle); ok {
    -		return instances, nil
    -	}
    -	
    -	// Query database
    -	instances, err := db.GetAccessibleInstances(ctx, userHandle)
    -	if err != nil {
    -		return nil, err
    -	}
    -	
    -	// Cache results
    -	instanceCache.Set(userHandle, instances)
    -	return instances, nil
    -}

    3. Project Metadata Cache#

    Cache project metadata including schema:

    type ProjectCache struct {
    -	projects map[string]*models.Project  // key: "owner/handle"
    -	mu       sync.RWMutex
    -	ttl      time.Duration
    -}
    -
    -func (c *ProjectCache) Get(owner, handle string) (*models.Project, bool) {
    -	key := fmt.Sprintf("%s/%s", owner, handle)
    -	c.mu.RLock()
    -	defer c.mu.RUnlock()
    -	
    -	project, ok := c.projects[key]
    -	return project, ok
    -}

    4. Redis-Based Caching#

    For distributed deployments:

    import "github.com/go-redis/redis/v8"
    -
    -type RedisCache struct {
    -	client *redis.Client
    -	ttl    time.Duration
    -}
    -
    -func (c *RedisCache) GetProject(ctx context.Context, owner, handle string) (*models.Project, error) {
    -	key := fmt.Sprintf("project:%s:%s", owner, handle)
    -	
    -	data, err := c.client.Get(ctx, key).Bytes()
    -	if err == redis.Nil {
    -		return nil, nil  // Not in cache
    -	} else if err != nil {
    -		return nil, err
    -	}
    -	
    -	var project models.Project
    -	err = json.Unmarshal(data, &project)
    -	return &project, err
    -}
    -
    -func (c *RedisCache) SetProject(ctx context.Context, project *models.Project) error {
    -	key := fmt.Sprintf("project:%s:%s", project.Owner, project.Handle)
    -	data, err := json.Marshal(project)
    -	if err != nil {
    -		return err
    -	}
    -	
    -	return c.client.Set(ctx, key, data, c.ttl).Err()
    -}

    Cache Invalidation#

    Always invalidate cache on updates:

    func UpdateProject(ctx context.Context, pool *pgxpool.Pool, project *models.Project) error {
    -	// Update database
    -	err := db.UpdateProject(ctx, project)
    -	if err != nil {
    -		return err
    -	}
    -	
    -	// Invalidate cache
    -	projectCache.Invalidate(project.Owner, project.Handle)
    -	
    -	return nil
    -}

    Connection Pool Optimization#

    Pool Configuration#

    func InitDB(opts *models.Options) *pgxpool.Pool {
    -	config, err := pgxpool.ParseConfig(connString)
    -	if err != nil {
    -		log.Fatal(err)
    -	}
    -	
    -	// Connection pool settings
    -	config.MaxConns = 20                      // Max concurrent connections
    -	config.MinConns = 5                       // Keep-alive connections
    -	config.MaxConnLifetime = time.Hour        // Recycle connections
    -	config.MaxConnIdleTime = 5 * time.Minute  // Close idle connections
    -	config.HealthCheckPeriod = time.Minute    // Health check frequency
    -	
    -	// Statement cache
    -	config.ConnConfig.StatementCacheCapacity = 100
    -	
    -	pool, err := pgxpool.NewWithConfig(context.Background(), config)
    -	return pool
    -}

    Pool Sizing#

    General rule:

    MaxConns = (available_cores * 2) + effective_spindle_count

    Example scenarios:

    • 4-core CPU, SSD: MaxConns = 10-20
    • 8-core CPU, SSD: MaxConns = 20-40
    • Under heavy load: Start conservative, increase based on monitoring

    Monitor Pool Usage#

    func monitorPool(pool *pgxpool.Pool) {
    -	ticker := time.NewTicker(30 * time.Second)
    -	
    -	for range ticker.C {
    -		stat := pool.Stat()
    -		log.Printf("Pool stats: total=%d, idle=%d, acquired=%d, waiting=%d",
    -			stat.TotalConns(),
    -			stat.IdleConns(),
    -			stat.AcquiredConns(),
    -			stat.MaxConns()-stat.TotalConns(),
    -		)
    -	}
    -}

    Performance Testing#

    Load Testing Setup#

    Use vegeta for HTTP load testing:

    # Install vegeta
    -go install github.com/tsenart/vegeta@latest
    -
    -# Create targets file
    -cat > targets.txt <<EOF
    -GET http://localhost:8880/v1/projects/alice
    -Authorization: Bearer alice_api_key
    -
    -POST http://localhost:8880/v1/similars/alice/project1/doc1
    -Authorization: Bearer alice_api_key
    -Content-Type: application/json
    -
    -GET http://localhost:8880/v1/embeddings/alice/project1?limit=100
    -Authorization: Bearer alice_api_key
    -EOF
    -
    -# Run load test
    -echo "GET http://localhost:8880/v1/projects/alice" | \
    -  vegeta attack -duration=60s -rate=100 -header="Authorization: Bearer key" | \
    -  vegeta report

    Benchmark Tests#

    Create Go benchmarks:

    func BenchmarkGetAccessibleInstances(b *testing.B) {
    -	pool := setupBenchmarkDB(b)
    -	defer pool.Close()
    -	
    -	// Create test data
    -	createTestInstances(b, pool, 1000)
    -	
    -	ctx := context.Background()
    -	
    -	b.ResetTimer()
    -	for i := 0; i < b.N; i++ {
    -		_, err := db.GetAllAccessibleInstances(ctx, "testuser", 10, 0)
    -		if err != nil {
    -			b.Fatal(err)
    -		}
    -	}
    -}
    -
    -func BenchmarkSimilaritySearch(b *testing.B) {
    -	pool := setupBenchmarkDB(b)
    -	defer pool.Close()
    -	
    -	// Create embeddings
    -	createTestEmbeddings(b, pool, 10000)
    -	
    -	ctx := context.Background()
    -	queryVector := generateRandomVector(1536)
    -	
    -	b.ResetTimer()
    -	for i := 0; i < b.N; i++ {
    -		_, err := SearchSimilar(ctx, pool, "alice", "project1", queryVector, 10, 0.5)
    -		if err != nil {
    -			b.Fatal(err)
    -		}
    -	}
    -}

    Run benchmarks:

    # Run all benchmarks
    -go test -bench=. -benchmem ./...
    -
    -# Run specific benchmark
    -go test -bench=BenchmarkSimilaritySearch -benchmem ./internal/handlers
    -
    -# Compare before/after
    -go test -bench=. -benchmem ./... > old.txt
    -# Make changes
    -go test -bench=. -benchmem ./... > new.txt
    -benchcmp old.txt new.txt

    Database Performance Testing#

    Test with realistic data:

    -- Generate test data
    -INSERT INTO embeddings (project_id, text_id, vector, vector_dim, metadata)
    -SELECT 
    -  1,
    -  'doc_' || generate_series,
    -  array_fill(random()::real, ARRAY[1536])::vector,
    -  1536,
    -  '{"author": "test"}'::jsonb
    -FROM generate_series(1, 100000);
    -
    --- Test query performance
    -EXPLAIN (ANALYZE, BUFFERS) 
    -SELECT text_id, vector <=> $1::vector AS distance
    -FROM embeddings
    -WHERE project_id = 1 AND vector_dim = 1536
    -ORDER BY distance
    -LIMIT 10;

    Metrics and Monitoring#

    Application Metrics#

    Track key metrics:

    type Metrics struct {
    -	QueryDuration    prometheus.Histogram
    -	QueryCount       prometheus.Counter
    -	CacheHits        prometheus.Counter
    -	CacheMisses      prometheus.Counter
    -	PoolWaitDuration prometheus.Histogram
    -}
    -
    -func recordQueryMetrics(start time.Time, query string) {
    -	duration := time.Since(start).Seconds()
    -	metrics.QueryDuration.Observe(duration)
    -	metrics.QueryCount.Inc()
    -}

    PostgreSQL Metrics#

    Monitor database performance:

    -- Slow queries
    -SELECT 
    -  query,
    -  calls,
    -  total_time,
    -  mean_time,
    -  max_time
    -FROM pg_stat_statements
    -ORDER BY mean_time DESC
    -LIMIT 10;
    -
    --- Table statistics
    -SELECT 
    -  schemaname,
    -  tablename,
    -  n_tup_ins,
    -  n_tup_upd,
    -  n_tup_del,
    -  n_live_tup,
    -  n_dead_tup
    -FROM pg_stat_user_tables;
    -
    --- Index usage
    -SELECT 
    -  schemaname,
    -  tablename,
    -  indexname,
    -  idx_scan,
    -  idx_tup_read,
    -  idx_tup_fetch
    -FROM pg_stat_user_indexes
    -ORDER BY idx_scan DESC;

    Performance Targets#

    Based on typical usage:

    OperationTargetAcceptableAction Required
    Single instance lookup< 10ms< 50ms> 50ms
    List accessible instances (<100)< 50ms< 100ms> 100ms
    Create/update instance< 100ms< 200ms> 200ms
    Similarity search (10 results)< 50ms< 100ms> 100ms
    Similarity search (100 results)< 100ms< 200ms> 200ms
    Embedding insert (single)< 50ms< 100ms> 100ms
    Embedding batch (100)< 500ms< 1000ms> 1000ms

    Implementation Priority#

    High Priority#

    1. Profile current performance with realistic data
    2. Add dimension filtering index: idx_embeddings_project_dim
    3. Monitor slow queries with pg_stat_statements

    Medium Priority#

    1. Implement UNION ALL optimization if GetAllAccessibleInstances > 100ms
    2. Add caching for system definitions
    3. Optimize connection pool settings based on load

    Low Priority#

    1. Add Redis caching layer for high-traffic deployments
    2. Implement application metrics with Prometheus
    3. Add additional indexes based on actual query patterns
    4. Tune HNSW parameters for specific use cases

    General Best Practices#

    1. Measure Before Optimizing#

    # Profile in production
    -EXPLAIN ANALYZE your_query;
    -
    -# Load test
    -vegeta attack -duration=60s -rate=100
    -
    -# Benchmark
    -go test -bench=. -benchmem

    2. Start Conservative#

    • Don’t optimize prematurely
    • Use simple queries first
    • Add complexity only when needed

    3. Monitor Continuously#

    • Track query performance
    • Monitor connection pool
    • Watch index usage
    • Alert on slow queries

    4. Document Optimizations#

    • Note why optimization was needed
    • Include before/after metrics
    • Document trade-offs made

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/development/testing/index.html b/docs/public/development/testing/index.html deleted file mode 100644 index ce3246f..0000000 --- a/docs/public/development/testing/index.html +++ /dev/null @@ -1,288 +0,0 @@ -Testing | dhamps-vdb Documentation - -

    Testing Guide#

    This guide covers how to run and write tests for dhamps-vdb.

    Running Tests#

    dhamps-vdb uses integration tests that spin up real PostgreSQL containers using testcontainers. This approach ensures tests run against actual database instances with pgvector support.

    Prerequisites#

    Using Podman (Recommended for Linux):

    # Start podman socket
    -systemctl --user start podman.socket
    -
    -# Export DOCKER_HOST for testcontainers
    -export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock

    Using Docker:

    Testcontainers works with Docker out of the box. Ensure Docker daemon is running.

    Running All Tests#

    # Run all tests with verbose output
    -go test -v ./...
    -
    -# Run tests without verbose output
    -go test ./...
    -
    -# Run tests with coverage
    -go test -cover ./...
    -
    -# Generate coverage report
    -go test -coverprofile=coverage.out ./...
    -go tool cover -html=coverage.out

    Running Specific Tests#

    # Run tests in a specific package
    -go test -v ./internal/handlers
    -
    -# Run a specific test function
    -go test -v ./internal/handlers -run TestCreateUser
    -
    -# Run tests matching a pattern
    -go test -v ./... -run ".*Sharing.*"

    Test Containers#

    Tests automatically manage PostgreSQL containers with pgvector:

    • Container is started before tests run
    • Database schema is migrated automatically
    • Container is cleaned up after tests complete
    • Each test suite gets a fresh database state

    Test Structure#

    Package Organization#

    Tests are organized alongside the code they test:

    internal/
    -├── handlers/
    -│   ├── users.go              # Implementation
    -│   ├── users_test.go         # Unit/integration tests
    -│   ├── projects.go
    -│   ├── projects_test.go
    -│   ├── projects_sharing_test.go
    -│   ├── embeddings.go
    -│   └── embeddings_test.go
    -├── database/
    -│   └── queries.sql           # SQL queries for sqlc
    -└── models/
    -    ├── users.go
    -    └── projects.go

    Test Files#

    Test files follow Go conventions:

    • Filename: *_test.go
    • Package: Same as code under test (e.g., package handlers)
    • Test functions: func TestFunctionName(t *testing.T)

    Test Fixtures#

    Test data is stored in testdata/:

    testdata/
    -├── postgres/
    -│   ├── enable-vector.sql     # Database initialization
    -│   └── users.yml
    -├── valid_embeddings.json
    -├── valid_user.json
    -├── valid_api_standard_openai_v1.json
    -├── valid_llm_service_openai-large-full.json
    -└── invalid_embeddings.json

    Writing Tests#

    Basic Test Structure#

    package handlers
    -
    -import (
    -	"context"
    -	"testing"
    -
    -	"github.com/mpilhlt/dhamps-vdb/internal/database"
    -	"github.com/stretchr/testify/assert"
    -)
    -
    -func TestCreateUser(t *testing.T) {
    -	// Setup: Initialize database pool and test data
    -	ctx := context.Background()
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	// Execute: Call function under test
    -	result, err := CreateUser(ctx, pool, userData)
    -	
    -	// Assert: Verify results
    -	assert.NoError(t, err)
    -	assert.Equal(t, "testuser", result.UserHandle)
    -}

    Integration Test Example#

    func TestProjectSharingWorkflow(t *testing.T) {
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	// Create test users
    -	alice := createTestUser(t, pool, "alice")
    -	bob := createTestUser(t, pool, "bob")
    -	
    -	// Create project as Alice
    -	project := createTestProject(t, pool, alice, "test-project")
    -	
    -	// Share project with Bob
    -	err := shareProject(t, pool, alice, project.ID, bob.Handle, "reader")
    -	assert.NoError(t, err)
    -	
    -	// Verify Bob can access project
    -	projects := getAccessibleProjects(t, pool, bob)
    -	assert.Contains(t, projects, project)
    -}

    Testing with Testcontainers#

    func setupTestDatabase(t *testing.T) *pgxpool.Pool {
    -	ctx := context.Background()
    -	
    -	// Create PostgreSQL container with pgvector
    -	req := testcontainers.ContainerRequest{
    -		Image:        "pgvector/pgvector:0.7.4-pg16",
    -		ExposedPorts: []string{"5432/tcp"},
    -		Env: map[string]string{
    -			"POSTGRES_PASSWORD": "password",
    -			"POSTGRES_DB":       "testdb",
    -		},
    -		WaitStrategy: wait.ForLog("database system is ready to accept connections"),
    -	}
    -	
    -	container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
    -		ContainerRequest: req,
    -		Started:          true,
    -	})
    -	require.NoError(t, err)
    -	
    -	// Get connection details
    -	host, _ := container.Host(ctx)
    -	port, _ := container.MappedPort(ctx, "5432")
    -	
    -	// Connect and migrate
    -	connString := fmt.Sprintf("postgres://postgres:password@%s:%s/testdb", host, port.Port())
    -	pool := connectAndMigrate(t, connString)
    -	
    -	return pool
    -}

    Validation Testing#

    Test dimension and metadata validation:

    func TestEmbeddingDimensionValidation(t *testing.T) {
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	// Create LLM service with 1536 dimensions
    -	llmService := createTestLLMService(t, pool, "openai", 1536)
    -	
    -	// Try to insert embedding with wrong dimensions
    -	embedding := models.Embedding{
    -		TextID:    "doc1",
    -		Vector:    make([]float32, 768), // Wrong size!
    -		VectorDim: 768,
    -	}
    -	
    -	err := insertEmbedding(t, pool, embedding)
    -	assert.Error(t, err)
    -	assert.Contains(t, err.Error(), "dimension mismatch")
    -}
    -
    -func TestMetadataSchemaValidation(t *testing.T) {
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	// Create project with metadata schema
    -	schema := `{"type":"object","properties":{"author":{"type":"string"}},"required":["author"]}`
    -	project := createProjectWithSchema(t, pool, "alice", "test", schema)
    -	
    -	// Valid metadata should succeed
    -	validMeta := `{"author":"John Doe"}`
    -	err := insertEmbeddingWithMetadata(t, pool, project.ID, validMeta)
    -	assert.NoError(t, err)
    -	
    -	// Invalid metadata should fail
    -	invalidMeta := `{"year":2024}` // Missing required 'author'
    -	err = insertEmbeddingWithMetadata(t, pool, project.ID, invalidMeta)
    -	assert.Error(t, err)
    -}

    Table-Driven Tests#

    For testing multiple scenarios:

    func TestSimilaritySearch(t *testing.T) {
    -	tests := []struct {
    -		name      string
    -		threshold float32
    -		limit     int
    -		expected  int
    -	}{
    -		{"high threshold", 0.9, 10, 2},
    -		{"medium threshold", 0.7, 10, 5},
    -		{"low threshold", 0.5, 10, 8},
    -		{"with limit", 0.5, 3, 3},
    -	}
    -	
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	for _, tt := range tests {
    -		t.Run(tt.name, func(t *testing.T) {
    -			results := searchSimilar(t, pool, "doc1", tt.threshold, tt.limit)
    -			assert.Len(t, results, tt.expected)
    -		})
    -	}
    -}

    Cleanup Testing#

    Verify database cleanup:

    func TestDatabaseCleanup(t *testing.T) {
    -	pool := setupTestDatabase(t)
    -	defer pool.Close()
    -	
    -	// Create test data
    -	user := createTestUser(t, pool, "alice")
    -	project := createTestProject(t, pool, user, "test")
    -	createTestEmbeddings(t, pool, project, 10)
    -	
    -	// Delete user (should cascade)
    -	err := deleteUser(t, pool, user.Handle)
    -	assert.NoError(t, err)
    -	
    -	// Verify all related data is deleted
    -	assertTableEmpty(t, pool, "users")
    -	assertTableEmpty(t, pool, "projects")
    -	assertTableEmpty(t, pool, "embeddings")
    -}

    Test Helpers#

    Create helper functions to reduce boilerplate:

    // setupTestDatabase initializes a test database with migrations
    -func setupTestDatabase(t *testing.T) *pgxpool.Pool {
    -	// Implementation...
    -}
    -
    -// createTestUser creates a user for testing
    -func createTestUser(t *testing.T, pool *pgxpool.Pool, handle string) *models.User {
    -	// Implementation...
    -}
    -
    -// createTestProject creates a project for testing
    -func createTestProject(t *testing.T, pool *pgxpool.Pool, owner *models.User, handle string) *models.Project {
    -	// Implementation...
    -}
    -
    -// assertTableEmpty verifies a table has no rows
    -func assertTableEmpty(t *testing.T, pool *pgxpool.Pool, tableName string) {
    -	var count int
    -	err := pool.QueryRow(context.Background(), 
    -		fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)).Scan(&count)
    -	require.NoError(t, err)
    -	assert.Equal(t, 0, count, "table %s should be empty", tableName)
    -}

    CI/CD Integration#

    GitHub Actions#

    Example GitHub Actions workflow:

    name: Tests
    -
    -on: [push, pull_request]
    -
    -jobs:
    -  test:
    -    runs-on: ubuntu-latest
    -    
    -    steps:
    -    - uses: actions/checkout@v3
    -    
    -    - name: Set up Go
    -      uses: actions/setup-go@v4
    -      with:
    -        go-version: '1.21'
    -    
    -    - name: Run tests
    -      run: |
    -        go test -v -race -coverprofile=coverage.txt ./...
    -    
    -    - name: Upload coverage
    -      uses: codecov/codecov-action@v3
    -      with:
    -        files: ./coverage.txt

    Local CI Testing#

    Test as CI would:

    # Clean test with race detection
    -go clean -testcache
    -go test -v -race ./...
    -
    -# Test with coverage
    -go test -coverprofile=coverage.out ./...
    -
    -# Check for test caching issues
    -go test -count=1 ./...

    Best Practices#

    1. Use testcontainers for Real Databases#

    • Don’t mock the database layer
    • Test against actual PostgreSQL with pgvector
    • Catch SQL-specific issues

    2. Isolate Tests#

    • Each test should be independent
    • Use transactions or cleanup between tests
    • Don’t rely on test execution order

    3. Test Validation Logic#

    • Test dimension validation
    • Test metadata schema validation
    • Test authorization checks

    4. Test Error Conditions#

    • Invalid input
    • Missing resources (404)
    • Unauthorized access (403)
    • Constraint violations

    5. Keep Tests Fast#

    • Use parallel tests where possible: t.Parallel()
    • Reuse test database containers when appropriate
    • Avoid unnecessary sleeps

    6. Use Descriptive Names#

    // Good
    -func TestProjectSharingWithReaderRole(t *testing.T)
    -
    -// Less clear
    -func TestSharing(t *testing.T)

    7. Assert Meaningfully#

    // Good - specific assertion
    -assert.Equal(t, "alice", project.Owner)
    -
    -// Less helpful
    -assert.True(t, project.Owner == "alice")

    Debugging Tests#

    Verbose Output#

    # See all test output
    -go test -v ./internal/handlers
    -
    -# See SQL queries (if logging enabled)
    -SERVICE_DEBUG=true go test -v ./...

    Run Single Test#

    # Focus on one failing test
    -go test -v ./internal/handlers -run TestCreateProject

    Keep Test Database Running#

    For manual inspection, prevent container cleanup:

    func TestWithDebugContainer(t *testing.T) {
    -	container := setupContainer(t)
    -	// Comment out: defer container.Terminate(ctx)
    -	
    -	host, port := getContainerDetails(container)
    -	t.Logf("Database running at %s:%s", host, port)
    -	
    -	// Run test...
    -	
    -	// Container stays running for manual inspection
    -	time.Sleep(time.Hour)
    -}

    Then connect with psql:

    psql -h localhost -p <port> -U postgres -d testdb

    Common Issues#

    Container Startup Failures#

    # Check Docker/Podman is running
    -systemctl --user status podman.socket
    -
    -# Check for port conflicts
    -netstat -tulpn | grep 5432
    -
    -# Clean up containers
    -podman rm -f $(podman ps -aq)

    Test Timeouts#

    Increase timeout for slow containers:

    WaitStrategy: wait.ForLog("ready").WithStartupTimeout(2 * time.Minute)

    Permission Errors#

    Ensure test user has proper permissions:

    GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
    -GRANT ALL ON SCHEMA public TO testuser;

    Further Reading#

    \ No newline at end of file diff --git a/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json b/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json deleted file mode 100644 index 0637a08..0000000 --- a/docs/public/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json b/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json deleted file mode 100644 index d10a49d..0000000 --- a/docs/public/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json +++ /dev/null @@ -1 +0,0 @@ -[{"id":0,"href":"/dhamps-vdb/concepts/architecture/","title":"Architecture","section":"Concepts","content":"Architecture# dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.\nSystem Overview# ┌─────────────┐ │ Client │ │ Application │ └──────┬──────┘ │ HTTP/REST │ ┌──────▼──────────────────────────┐ │ dhamps-vdb API Server │ │ ┌──────────────────────────┐ │ │ │ Authentication Layer │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ Request Handlers │ │ │ │ (Users, Projects, etc) │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ Validation Layer │ │ │ │ (Dimensions, Metadata) │ │ │ └────────┬─────────────────┘ │ │ ┌────────▼─────────────────┐ │ │ │ SQLC Queries │ │ │ │ (Type-safe SQL) │ │ │ └────────┬─────────────────┘ │ └───────────┼──────────────────────┘ │ ┌───────▼──────────────┐ │ PostgreSQL + 16 │ │ with pgvector 0.7 │ │ │ │ ┌────────────────┐ │ │ │ Vector Index │ │ │ │ (HNSW/IVFFlat) │ │ │ └────────────────┘ │ └──────────────────────┘Core Components# API Layer# Built with Huma framework on top of Go\u0026rsquo;s http.ServeMux:\nOpenAPI documentation generation Automatic request/response validation JSON schema support REST endpoint routing Authentication# Token-based authentication using API keys:\nAdmin key: For administrative operations (user creation, system management) User keys: SHA-256 hashed, unique per user Bearer token: Transmitted in Authorization header Data Storage# PostgreSQL with pgvector extension:\nVector storage: Native pgvector support for embeddings Vector search: Cosine similarity using \u0026lt;=\u0026gt; operator ACID compliance: Transactional consistency Relational integrity: Foreign keys and constraints Code Generation# Uses sqlc for type-safe database queries:\nSQL queries → Go functions Compile-time type checking No ORM overhead Direct PostgreSQL integration Data Model# Core Entities# users ├── projects (1:many) │ ├── embeddings (1:many) │ └── instance (1:1) │ └── instances (1:many) └── definition (many:1, optional) _system (special user) └── definitions (1:many)Key Relationships# Users → Projects\nOne user owns many projects Projects can be shared with other users (reader/editor roles) Projects can be public (unauthenticated read access) Projects → Instances\nEach project references exactly one LLM service instance Instance defines embedding dimensions and configuration Projects → Embeddings\nOne project contains many embeddings Each embedding has a unique text_id within the project Embeddings store vector, metadata, and optional text Users → Instances\nUsers own their instances Instances can be shared with other users Instances store encrypted API keys Instances → Definitions\nInstances can optionally reference a definition (template) System definitions (_system owner) provide defaults User definitions allow custom templates Request Flow# 1. Create Embedding# Client Request ↓ Authentication Middleware ↓ Authorization Check (owner/editor?) ↓ Dimension Validation (vector_dim matches instance?) ↓ Metadata Validation (matches project schema?) ↓ Database Insert (with transaction) ↓ Response2. Similarity Search# Client Request (text_id or vector) ↓ Authentication Middleware (or public check) ↓ Authorization Check (owner/reader/public?) ↓ Dimension Validation (if raw vector) ↓ Vector Similarity Query ├── Cosine distance calculation ├── Threshold filtering ├── Metadata filtering (exclude matches) └── Limit/offset pagination ↓ Results (sorted by similarity) ↓ ResponseStorage Architecture# Vector Index# pgvector supports multiple index types:\nIVFFlat: Faster build, approximate search HNSW: Slower build, better recall Current implementation uses HNSW for better accuracy.\nVector Storage Format# CREATE TABLE embeddings ( embedding_id SERIAL PRIMARY KEY, text_id TEXT NOT NULL, project_id INT REFERENCES projects, vector vector(3072), -- Dimension varies vector_dim INT NOT NULL, metadata JSONB, text TEXT, ... )Index Strategy# CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);Optimized for cosine similarity searches.\nSecurity Architecture# API Key Encryption# Algorithm: AES-256-GCM Key Source: ENCRYPTION_KEY environment variable Key Derivation: SHA-256 hash to ensure 32-byte key Storage: Binary (BYTEA) in database Access Control# Three-tier access model:\nOwner: Full control (read, write, delete, share, transfer) Editor: Read and write embeddings Reader: Read-only access to embeddings and search Special access:\nAdmin: System-wide operations (user management, sanity checks) Public: Unauthenticated read access (if public_read=true) Data Isolation# Users can only access their own resources or shared resources Cross-user queries are prevented at the database level Project ownership enforced via foreign keys Migration System# Uses tern for database migrations:\nmigrations/ ├── 001_create_initial_scheme.sql ├── 002_create_emb_index.sql ├── 003_add_public_read_flag.sql └── 004_refactor_llm_services_architecture.sqlMigrations run automatically on startup with rollback support.\nPerformance Characteristics# Vector Search Performance# Small datasets (\u0026lt;10K embeddings): \u0026lt;10ms per query Medium datasets (10K-100K): 10-50ms per query Large datasets (\u0026gt;100K): 50-200ms per query Performance depends on:\nVector dimensions Index type and parameters Hardware (CPU, RAM, disk) Number of results requested Scaling Considerations# Vertical Scaling:\nMore RAM = faster searches (more vectors in memory) Faster CPUs = faster vector comparisons SSD storage = faster index scans Horizontal Scaling:\nRead replicas for search queries Separate write/read workloads Connection pooling for concurrent requests Technology Stack# Core Technologies# Language: Go 1.21+ Web Framework: Huma 2.x Database: PostgreSQL 16+ Vector Extension: pgvector 0.7.4 Query Generator: sqlc 1.x Migration Tool: tern 2.x Development Tools# Testing: Go standard library + testcontainers Documentation: OpenAPI 3.0 (auto-generated) Building: Docker multi-stage builds Deployment: Docker Compose Design Principles# 1. Type Safety# sqlc generates type-safe Go code from SQL Strong typing prevents SQL injection Compile-time validation of queries 2. Simplicity# REST API (not GraphQL) Straightforward URL patterns Standard HTTP methods 3. Security# API key encryption at rest No API keys in responses Role-based access control 4. Validation# Automatic dimension validation Optional metadata schema validation Request/response validation via OpenAPI 5. Extensibility# User-defined metadata schemas Custom LLM service configurations Flexible sharing model Limitations# Current Constraints# No multi-tenancy: Each installation is single-tenant No replication: Manual setup required for HA No caching: All queries hit database Synchronous API: No async/batch upload endpoints Future Enhancements# See Roadmap for planned improvements.\nNext Steps# Learn about users and authentication Understand projects Explore LLM services "},{"id":1,"href":"/dhamps-vdb/api/authentication/","title":"Authentication","section":"API Reference","content":"API Authentication# All API requests (except public project read operations) require authentication using API keys passed in the Authorization header with a Bearer prefix.\nAuthentication Method# Include your API key in the Authorization header of every request:\nAuthorization: Bearer your_api_key_hereAPI Key Types# Admin API Key# Full access to all API endpoints and resources Can create and manage users Can access all projects and resources across all users Required for administrative operations Set via ADMIN_KEY environment variable Admin-only operations:\nPOST /v1/users - Create new users GET /v1/users - List all users GET /v1/admin/* - Admin endpoints Create/modify _system LLM service definitions Access any user\u0026rsquo;s resources User API Key# Access limited to user\u0026rsquo;s own resources and shared projects Cannot create other users Cannot access admin endpoints Returned when creating a new user (store securely) User capabilities:\nManage own projects and LLM services Upload and query embeddings in owned projects Access projects shared with them (read or edit access) Delete own account Getting an API Key# Admin Key# Set the admin key via environment variable when launching the service:\nexport ADMIN_KEY=\u0026#34;your-secure-admin-key-here\u0026#34; ./dhamps-vdbUser Key# Create a new user using the admin API key:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; }⚠️ Important: The API key is only returned once during user creation. Store it securely - it cannot be recovered.\nAuthorization Header Format# Correct Format# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34;Common Mistakes# ❌ Missing \u0026ldquo;Bearer\u0026rdquo; prefix:\nAuthorization: 024v2013621509245f2e24❌ Wrong prefix:\nAuthorization: Token 024v2013621509245f2e24❌ Extra quotes:\nAuthorization: Bearer \u0026#34;024v2013621509245f2e24\u0026#34;Authentication Errors# 401 Unauthorized# Returned when authentication credentials are missing or invalid.\nCauses:\nMissing Authorization header Invalid API key Malformed header format Example response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden# Returned when authentication succeeds but authorization fails.\nCauses:\nAttempting to access another user\u0026rsquo;s resources User lacking required permissions Non-admin accessing admin endpoints Example response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this resource\u0026#34; }Public Access# Projects can be made publicly accessible by setting public_read: true when creating or updating the project. Public projects allow unauthenticated read access to:\nProject metadata Embeddings Similarity search See Public Access Documentation for details.\nSecurity Best Practices# Never commit API keys to version control Use environment variables to store API keys in your applications Rotate keys regularly by creating new users and deleting old ones Use HTTPS in production to prevent key interception Store admin keys securely using secrets management systems Limit admin key distribution to essential personnel only Example Authenticated Request# # List user\u0026#39;s projects curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34; # Create a new project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer 024v2013621509245f2e24\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My research project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39;Related Documentation# Error Handling - Complete error response reference Users Endpoint - User management API "},{"id":2,"href":"/dhamps-vdb/reference/configuration/","title":"Configuration Reference","section":"Reference","content":"Configuration Reference# Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.\nOverview# dhamps-vdb is configured through a combination of:\nEnvironment variables (recommended) Command-line flags (overrides environment variables) .env files (for Docker and local development) Configuration is loaded in the following priority order (highest to lowest):\nCommand-line flags Environment variables .env file values Default values from options.go Configuration Options# Service Configuration# Options for controlling the API service behavior.\nOption Environment Variable CLI Flag Type Default Required Description Debug SERVICE_DEBUG -d, --debug Boolean true No Enable verbose debug logging Host SERVICE_HOST --host String localhost No Hostname or IP to bind to Port SERVICE_PORT -p, --port Integer 8880 No Port number to listen on Debug Mode:\ntrue - Detailed logs including SQL queries, request details, internal operations false - Minimal logs for production use Host Configuration:\nlocalhost - Local development only 0.0.0.0 - Listen on all interfaces (required for Docker) Specific IP - Bind to particular network interface Port Configuration:\nDefault: 8880 Ports below 1024 require elevated privileges Ensure port is not in use by another service Database Configuration# Options for connecting to the PostgreSQL database with pgvector extension.\nOption Environment Variable CLI Flag Type Default Required Description DB Host SERVICE_DBHOST --db-host String localhost Yes PostgreSQL server hostname DB Port SERVICE_DBPORT --db-port Integer 5432 No PostgreSQL server port DB User SERVICE_DBUSER --db-user String postgres Yes Database username DB Password SERVICE_DBPASSWORD --db-password String password Yes Database password DB Name SERVICE_DBNAME --db-name String postgres Yes Database name Database Requirements:\nPostgreSQL 12+ (16+ recommended) pgvector extension installed and enabled User must have CREATE, ALTER, DROP, INSERT, SELECT, UPDATE, DELETE privileges Database must exist before starting dhamps-vdb Common Database Hosts:\nlocalhost - Local PostgreSQL instance postgres - Docker Compose service name db.example.com - Remote database server IP address - Direct connection to database Security Configuration# Critical security settings for authentication and encryption.\nOption Environment Variable CLI Flag Type Default Required Description Admin Key SERVICE_ADMINKEY --admin-key String - Yes Master API key for admin operations Encryption Key ENCRYPTION_KEY - String - Yes AES-256 key for API key encryption Admin Key (SERVICE_ADMINKEY):\nMaster API key with full administrative privileges Used to create users and manage global resources Generate with: openssl rand -base64 32 Must be kept secure and rotated regularly Transmitted via Authorization: Bearer header Encryption Key (ENCRYPTION_KEY):\nUsed to encrypt user API keys in the database Minimum 32 characters required Uses AES-256-GCM encryption with SHA-256 hashing CRITICAL: If lost, all stored API keys become unrecoverable Cannot be changed without re-encrypting all existing API keys Generate with: openssl rand -hex 32 Must be backed up securely and separately from database Configuration Files# .env File# The recommended way to configure dhamps-vdb. Create a .env file in the project root:\n# Copy template cp template.env .env # Edit with your values nano .envExample .env file:\n# Service Configuration SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 # Database Configuration SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password_here SERVICE_DBNAME=dhamps_vdb # Security Configuration SERVICE_ADMINKEY=generated_admin_key_here ENCRYPTION_KEY=generated_encryption_key_min_32_charsSecurity Notes:\n.env files are in .gitignore by default Never commit .env files to version control Set restrictive permissions: chmod 600 .env Use different keys for dev/staging/production template.env# Starting template for configuration:\n#!/usr/bin/env bash SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8888 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=postgres SERVICE_ADMINKEY=Ch4ngeM3! # Encryption key for API keys in LLM service instances # Must be secure random string, at least 32 characters # Generate with: openssl rand -hex 32 ENCRYPTION_KEY=ChangeThisToASecureRandomKey123456789012Docker Configuration# Docker Compose# The docker-compose.yml file defines the full stack including PostgreSQL:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 environment: POSTGRES_USER: ${SERVICE_DBUSER:-postgres} POSTGRES_PASSWORD: ${SERVICE_DBPASSWORD:-postgres} POSTGRES_DB: ${SERVICE_DBNAME:-dhamps_vdb} ports: - \u0026#34;${POSTGRES_PORT:-5432}:5432\u0026#34; volumes: - postgres_data:/var/lib/postgresql/data dhamps-vdb: build: context: . dockerfile: Dockerfile depends_on: postgres: condition: service_healthy environment: SERVICE_DEBUG: ${SERVICE_DEBUG:-false} SERVICE_HOST: ${SERVICE_HOST:-0.0.0.0} SERVICE_PORT: ${SERVICE_PORT:-8880} SERVICE_DBHOST: ${SERVICE_DBHOST:-postgres} SERVICE_DBPORT: ${SERVICE_DBPORT:-5432} SERVICE_DBUSER: ${SERVICE_DBUSER:-postgres} SERVICE_DBPASSWORD: ${SERVICE_DBPASSWORD:-postgres} SERVICE_DBNAME: ${SERVICE_DBNAME:-dhamps_vdb} SERVICE_ADMINKEY: ${SERVICE_ADMINKEY} ENCRYPTION_KEY: ${ENCRYPTION_KEY} ports: - \u0026#34;${API_PORT:-8880}:8880\u0026#34;Docker-Specific Variables:\nPOSTGRES_PORT - External port for PostgreSQL (default: 5432) API_PORT - External port for dhamps-vdb API (default: 8880) Docker Setup Script# Automated setup using docker-setup.sh:\n# Run automated setup (generates secure keys) ./docker-setup.sh # Start services docker-compose up -d # View logs docker-compose logs -f dhamps-vdbThe script automatically:\nGenerates secure SERVICE_ADMINKEY Generates secure ENCRYPTION_KEY Creates .env file with proper configuration Validates Docker and docker-compose installation Docker Run Command# For standalone container deployment:\ndocker run -d \\ --name dhamps-vdb \\ -e SERVICE_DEBUG=false \\ -e SERVICE_HOST=0.0.0.0 \\ -e SERVICE_PORT=8880 \\ -e SERVICE_DBHOST=db.example.com \\ -e SERVICE_DBPORT=5432 \\ -e SERVICE_DBUSER=dhamps_user \\ -e SERVICE_DBPASSWORD=secure_password \\ -e SERVICE_DBNAME=dhamps_vdb \\ -e SERVICE_ADMINKEY=admin_key_here \\ -e ENCRYPTION_KEY=encryption_key_here \\ -p 8880:8880 \\ dhamps-vdb:latestExternal Database# Using docker-compose.external-db.yml for external PostgreSQL:\n# Set database connection in .env SERVICE_DBHOST=db.external.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdb # Start without bundled PostgreSQL docker-compose -f docker-compose.external-db.yml up -dConfiguration Scenarios# Development Environment# Optimized for local development with verbose logging:\n# .env for development SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb_dev SERVICE_ADMINKEY=dev-admin-key-not-for-production ENCRYPTION_KEY=dev-encryption-key-at-least-32-charsStart service:\n./dhamps-vdbDocker Development# Docker-based development with hot reload:\n# .env for Docker development SERVICE_DEBUG=true SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=postgres SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=dev-admin-key ENCRYPTION_KEY=dev-encryption-32-chars-minimumStart with:\ndocker-compose upProduction Environment# Production-ready configuration with security hardening:\n# .env for production SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=prod-db.internal.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod_user SERVICE_DBPASSWORD=\u0026lt;from-secrets-manager\u0026gt; SERVICE_DBNAME=dhamps_vdb_prod SERVICE_ADMINKEY=\u0026lt;from-secrets-manager\u0026gt; ENCRYPTION_KEY=\u0026lt;from-secrets-manager\u0026gt;Production Best Practices:\nUse secrets management (Vault, AWS Secrets Manager, etc.) Disable debug logging (SERVICE_DEBUG=false) Use dedicated database user (not superuser) Enable SSL/TLS for database connections Deploy behind reverse proxy (nginx, Traefik) Set up monitoring and alerting Regular key rotation (except ENCRYPTION_KEY) Firewall rules to restrict access Testing Environment# Configuration for running tests:\n# Tests use testcontainers - no external config needed go test -v ./...Test-specific setup:\n# Enable Docker for testcontainers systemctl --user start podman.socket export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock # Run tests go test -v ./...Validation and Verification# Startup Validation# dhamps-vdb validates configuration on startup:\nRequired variables check - Fails if missing Database connection test - Verifies connectivity Schema migration - Applies pending migrations Extension check - Verifies pgvector is available Configuration Test# Verify configuration is working:\n# Check service health curl http://localhost:8880/docs # Test admin authentication curl -X GET http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer ${SERVICE_ADMINKEY}\u0026#34; # Check database connectivity docker-compose exec dhamps-vdb echo \u0026#34;Config OK\u0026#34;Common Issues# Missing Required Variables:\nError: SERVICE_ADMINKEY environment variable is not setSolution: Set all required variables.\nDatabase Connection Failed:\nError: failed to connect to databaseSolution: Verify SERVICE_DBHOST, credentials, and that PostgreSQL is running.\nInvalid Encryption Key:\nError: ENCRYPTION_KEY must be at least 32 charactersSolution: Generate proper key with openssl rand -hex 32.\nPort Already in Use:\nError: bind: address already in useSolution: Change SERVICE_PORT or stop conflicting service.\nGenerating Secure Keys# Admin Key Generation# # Base64 encoded (recommended) openssl rand -base64 32 # Hex encoded (alternative) openssl rand -hex 24 # Output example: # Kx7mP9nQ2rT5vY8zA1bC4dF6gH9jK0lM3nP5qR7sT9u=Encryption Key Generation# # 32-byte hex key (required format) openssl rand -hex 32 # Output example: # a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6Secure Key Storage# Development:\nStore in .env file (not committed) Use password manager for team sharing Production:\nUse secrets management system Rotate admin key every 90 days Never rotate encryption key (breaks existing API keys) Store encryption key backup separately from database Environment-Specific Examples# Local with External PostgreSQL# SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=192.168.1.100 SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=user_password SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=$(openssl rand -base64 32) ENCRYPTION_KEY=$(openssl rand -hex 32)Kubernetes ConfigMap + Secrets# ConfigMap:\napiVersion: v1 kind: ConfigMap metadata: name: dhamps-vdb-config data: SERVICE_DEBUG: \u0026#34;false\u0026#34; SERVICE_HOST: \u0026#34;0.0.0.0\u0026#34; SERVICE_PORT: \u0026#34;8880\u0026#34; SERVICE_DBHOST: \u0026#34;postgres-service\u0026#34; SERVICE_DBPORT: \u0026#34;5432\u0026#34; SERVICE_DBUSER: \u0026#34;dhamps_user\u0026#34; SERVICE_DBNAME: \u0026#34;dhamps_vdb\u0026#34;Secrets:\napiVersion: v1 kind: Secret metadata: name: dhamps-vdb-secrets type: Opaque stringData: SERVICE_DBPASSWORD: \u0026#34;secure_db_password\u0026#34; SERVICE_ADMINKEY: \u0026#34;secure_admin_key\u0026#34; ENCRYPTION_KEY: \u0026#34;secure_encryption_key_32_chars_min\u0026#34;Docker Swarm Secrets# # Create secrets echo \u0026#34;admin_key_here\u0026#34; | docker secret create dhamps_admin_key - echo \u0026#34;encryption_key\u0026#34; | docker secret create dhamps_encryption_key - # Reference in stack file services: dhamps-vdb: secrets: - dhamps_admin_key - dhamps_encryption_key environment: SERVICE_ADMINKEY_FILE: /run/secrets/dhamps_admin_key ENCRYPTION_KEY_FILE: /run/secrets/dhamps_encryption_keyRelated Documentation# Getting Started - Installation Getting Started - Quick Start Deployment - Docker Deployment - Database Setup Deployment - Security Reference - Database Schema "},{"id":3,"href":"/dhamps-vdb/deployment/docker/","title":"Docker Deployment","section":"Deployment","content":"Docker Deployment# This guide covers production-focused Docker deployment for dhamps-vdb.\nOverview# For detailed Docker setup instructions, see Getting Started with Docker. This page focuses on production deployment considerations.\nProduction Deployment# Prerequisites# Docker Engine 20.10+ Docker Compose 2.0+ (or docker-compose 1.29+) PostgreSQL 11+ with pgvector extension (included in compose setup) Quick Production Setup# # Clone repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Generate secure keys ./docker-setup.sh # Review and customize .env nano .env # Deploy docker-compose up -dProduction Considerations# Use Reverse Proxy# Always run behind a reverse proxy (nginx, Traefik, Caddy) for:\nHTTPS/TLS termination Request filtering Rate limiting Load balancing Example nginx configuration:\nupstream dhamps-vdb { server localhost:8880; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://dhamps-vdb; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }Container Resource Limits# Set resource limits in docker-compose.yml:\nservices: dhamps-vdb: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 2G reservations: cpus: \u0026#39;0.5\u0026#39; memory: 512M postgres: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 4G reservations: cpus: \u0026#39;1\u0026#39; memory: 2GUse Specific Image Tags# Avoid latest in production:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 # Specific version dhamps-vdb: image: dhamps-vdb:v0.1.0 # Tag your buildsHealth Monitoring# The image includes health checks. Monitor with:\n# Check health status docker inspect --format=\u0026#39;{{.State.Health.Status}}\u0026#39; dhamps-vdb # View health check logs docker inspect --format=\u0026#39;{{range .State.Health.Log}}{{.Output}}{{end}}\u0026#39; dhamps-vdb # Integrate with monitoring (Prometheus, etc.)Logging# Configure logging drivers in docker-compose.yml:\nservices: dhamps-vdb: logging: driver: \u0026#34;json-file\u0026#34; options: max-size: \u0026#34;10m\u0026#34; max-file: \u0026#34;3\u0026#34;Or use centralized logging:\nservices: dhamps-vdb: logging: driver: \u0026#34;syslog\u0026#34; options: syslog-address: \u0026#34;tcp://logserver:514\u0026#34;External Database Deployment# For production, consider using a managed PostgreSQL service or separate database server.\nRequirements# PostgreSQL 11+ with pgvector extension Network connectivity from container to database Database user with appropriate privileges See Database Setup for detailed instructions.\nConfiguration# Update .env:\nSERVICE_DBHOST=db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdbModify docker-compose.yml to remove postgres service:\nservices: dhamps-vdb: build: . ports: - \u0026#34;8880:8880\u0026#34; env_file: .env restart: unless-stoppedScaling and High Availability# Horizontal Scaling# Run multiple instances behind a load balancer:\nservices: dhamps-vdb: build: . deploy: replicas: 3 restart_policy: condition: on-failureNote: All instances must connect to the same database.\nDatabase Replication# For high availability:\nUse PostgreSQL replication (streaming or logical) Consider read replicas for read-heavy workloads Point write operations to primary, reads to replicas Backup Strategy# Database Backups# # Automated daily backups 0 2 * * * docker-compose exec -T postgres pg_dump -U postgres dhamps_vdb | gzip \u0026gt; /backups/dhamps-vdb-$(date +\\%Y\\%m\\%d).sql.gz # Keep last 30 days find /backups -name \u0026#34;dhamps-vdb-*.sql.gz\u0026#34; -mtime +30 -deleteVolume Backups# # Backup Docker volume docker run --rm -v dhamps-vdb_postgres_data:/data -v /backups:/backup alpine tar czf /backup/postgres-data-$(date +\\%Y\\%m\\%d).tar.gz /dataEnvironment Configuration Backups# # Backup .env (securely!) gpg --encrypt --recipient admin@example.com .env \u0026gt; .env.gpgTroubleshooting# Container Performance Issues# # Check resource usage docker stats # Check container logs docker-compose logs -f --tail=100 dhamps-vdb # Check slow queries (if database is slow) docker-compose exec postgres psql -U postgres -d dhamps_vdb -c \u0026#34;SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;\u0026#34;Network Connectivity Issues# # Test database connection from container docker-compose exec dhamps-vdb nc -zv postgres 5432 # Check DNS resolution docker-compose exec dhamps-vdb nslookup postgres # Test API from inside container docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docsUpdate and Rollback# # Update to new version docker-compose pull docker-compose up -d # Rollback if needed docker-compose down docker-compose up -d --force-recreateSecurity Best Practices# See Security Guide for comprehensive security recommendations Use Environment Variables Guide for proper configuration Never expose database port publicly Use strong, randomly generated keys (see ./docker-setup.sh) Keep Docker and images updated Run containers as non-root (already configured) Further Reading# Docker Official Documentation PostgreSQL Docker Hub pgvector Extension Database Setup Guide Environment Variables Reference Security Best Practices "},{"id":4,"href":"/dhamps-vdb/api/endpoints/","title":"Endpoints","section":"API Reference","content":"API Endpoints# Complete reference for all dhamps-vdb API endpoints.\nEndpoint Categories# Users - User management Projects - Project operations LLM Services - LLM service instances API Standards - API standard definitions Embeddings - Embedding storage and retrieval Similars - Similarity search Endpoint Format# All endpoints follow the pattern:\n{METHOD} /v1/{resource}/{user}/{identifier}Where:\nMETHOD: HTTP method (GET, POST, PUT, DELETE, PATCH) resource: Resource type (users, projects, embeddings, etc.) user: User handle (owner of the resource) identifier: Specific resource identifier Authentication# Most endpoints require authentication via the Authorization header:\nAuthorization: Bearer your_api_key_herePublic projects allow unauthenticated access to read operations.\n"},{"id":5,"href":"/dhamps-vdb/getting-started/","title":"Getting Started","section":"dhamps-vdb Documentation","content":"Getting Started with dhamps-vdb# This section helps you get dhamps-vdb up and running quickly. Whether you\u0026rsquo;re using Docker or compiling from source, you\u0026rsquo;ll find everything you need to start using the vector database API.\nWhat You\u0026rsquo;ll Learn# How to install and run dhamps-vdb How to configure the service for your environment Basic usage patterns and workflows Creating your first project and embeddings Prerequisites# Before you begin, ensure you have:\nPostgreSQL 11+ with pgvector extension (or use the provided Docker setup) Go 1.21+ (if compiling from source) Docker and Docker Compose (for containerized deployment) Quick Links# Installation - Compile and install dhamps-vdb Docker Deployment - Run with Docker (recommended) Configuration - Environment variables and options Quick Start - Your first API requests First Project - Complete walkthrough "},{"id":6,"href":"/dhamps-vdb/getting-started/installation/","title":"Installation","section":"Getting Started","content":"Installation# Install dhamps-vdb by compiling from source.\nPrerequisites# Go 1.21 or later PostgreSQL 11+ with pgvector extension sqlc for code generation Quick Install# # Clone the repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Install dependencies and generate code go get ./... sqlc generate --no-remote # Build the binary go build -o build/dhamps-vdb main.goDetailed Steps# 1. Install Dependencies# Download all Go module dependencies:\ngo get ./...2. Generate Database Code# Generate type-safe database queries using sqlc:\nsqlc generate --no-remoteThis creates Go code from SQL queries in internal/database/queries/.\n3. Build the Application# Compile the application:\ngo build -o build/dhamps-vdb main.goThe binary will be created at build/dhamps-vdb.\nRunning Without Building# You can run the application directly without building a binary:\ngo run main.goThis is useful during development but slower than running a pre-built binary.\nVerify Installation# Check that the binary was created successfully:\n./build/dhamps-vdb --helpYou should see the available command-line options.\nNext Steps# After installation, you need to:\nSet up the database Configure environment variables Run the service System Requirements# Memory: Minimum 512MB RAM (2GB+ recommended for production) Disk: Minimal (\u0026lt; 50MB for binary, database size varies) CPU: Any modern CPU (multi-core recommended for concurrent requests) Troubleshooting# sqlc Command Not Found# Install sqlc:\ngo install github.com/sqlc-dev/sqlc/cmd/sqlc@latestMake sure $GOPATH/bin is in your PATH.\nBuild Errors# Ensure you\u0026rsquo;re using Go 1.21 or later:\ngo versionClean the build cache if you encounter issues:\ngo clean -cache go build -o build/dhamps-vdb main.goMissing Dependencies# Force update all dependencies:\ngo mod download go get -u ./..."},{"id":7,"href":"/dhamps-vdb/guides/rag-workflow/","title":"RAG Workflow Guide","section":"Guides","content":"Complete RAG Workflow Guide# This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.\nOverview# A typical RAG workflow involves:\nGenerate embeddings from your text content (using an external LLM service) Upload embeddings to dhamps-vdb Search for similar documents based on a query Retrieve the relevant context Use the context with an LLM to generate responses Prerequisites# Access to dhamps-vdb API with a valid API key An external LLM service for generating embeddings (e.g., OpenAI, Cohere) Text content you want to process Step 1: Generate Embeddings Externally# First, use your chosen LLM service to generate embeddings for your text content. Here\u0026rsquo;s an example using OpenAI\u0026rsquo;s API:\nimport openai # Initialize OpenAI client client = openai.OpenAI(api_key=\u0026#34;your-openai-key\u0026#34;) # Generate embeddings for your text text = \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34; response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=text, dimensions=3072 ) embedding_vector = response.data[0].embeddingStep 2: Create LLM Service Instance# Before uploading embeddings, create an LLM service instance in dhamps-vdb that matches your embedding configuration:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }Step 3: Create a Project# Create a project to organize your embeddings:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-documents\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Document embeddings for RAG\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39;Step 4: Upload Embeddings to dhamps-vdb# Upload your pre-generated embeddings along with metadata and optional text content:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.021, -0.015, 0.043, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;example.txt\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34; } }] }\u0026#39;Tip: Upload multiple embeddings in batches for efficiency (see Batch Operations Guide).\nStep 5: Search for Similar Documents# When you need to retrieve relevant context for a query:\nOption A: Search by Stored Document ID# If you already have a document in your database that represents your query:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/my-documents/doc001?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Option B: Search with Raw Query Embedding# Generate an embedding for your query and search without storing it:\n# Generate query embedding query = \u0026#34;What animals are mentioned?\u0026#34; query_response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=query, dimensions=3072 ) query_vector = query_response.data[0].embeddingcurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/my-documents?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;my-documents\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc042\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc103\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Step 6: Retrieve Context Documents# Retrieve the full content and metadata for the most similar documents:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-documents/doc001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;example.txt\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34; }, \u0026#34;vector_dim\u0026#34;: 3072 }Step 7: Use Context with LLM# Combine the retrieved context with your original query to generate an informed response:\n# Collect context from similar documents context_docs = [] for result in similarity_results[\u0026#39;results\u0026#39;][:3]: doc = get_document(result[\u0026#39;id\u0026#39;]) # Your function to fetch document context_docs.append(doc[\u0026#39;text\u0026#39;]) # Build context string context = \u0026#34;\\n\\n\u0026#34;.join(context_docs) # Generate response with context response = client.chat.completions.create( model=\u0026#34;gpt-4\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Answer based on the provided context.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: f\u0026#34;Context:\\n{context}\\n\\nQuestion: {query}\u0026#34;} ] ) answer = response.choices[0].message.contentComplete Python Example# Here\u0026rsquo;s a complete example combining all steps:\nimport openai import requests # Configuration DHAMPS_API = \u0026#34;https://api.example.com\u0026#34; DHAMPS_KEY = \u0026#34;your-dhamps-api-key\u0026#34; OPENAI_KEY = \u0026#34;your-openai-key\u0026#34; # Initialize OpenAI client = openai.OpenAI(api_key=OPENAI_KEY) def embed_and_store(text_id, text, metadata=None): \u0026#34;\u0026#34;\u0026#34;Generate embedding and store in dhamps-vdb\u0026#34;\u0026#34;\u0026#34; # Generate embedding response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=text, dimensions=3072 ) vector = response.data[0].embedding # Upload to dhamps-vdb requests.post( f\u0026#34;{DHAMPS_API}/v1/embeddings/alice/my-documents\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: text_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: text, \u0026#34;metadata\u0026#34;: metadata or {} }] } ) def search_similar(query, count=5): \u0026#34;\u0026#34;\u0026#34;Search for similar documents using query text\u0026#34;\u0026#34;\u0026#34; # Generate query embedding response = client.embeddings.create( model=\u0026#34;text-embedding-3-large\u0026#34;, input=query, dimensions=3072 ) query_vector = response.data[0].embedding # Search in dhamps-vdb result = requests.post( f\u0026#34;{DHAMPS_API}/v1/similars/alice/my-documents?count={count}\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;vector\u0026#34;: query_vector} ) return result.json()[\u0026#39;results\u0026#39;] def retrieve_context(doc_ids): \u0026#34;\u0026#34;\u0026#34;Retrieve full document content\u0026#34;\u0026#34;\u0026#34; docs = [] for doc_id in doc_ids: response = requests.get( f\u0026#34;{DHAMPS_API}/v1/embeddings/alice/my-documents/{doc_id}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {DHAMPS_KEY}\u0026#34;} ) docs.append(response.json()) return docs def rag_query(query): \u0026#34;\u0026#34;\u0026#34;Complete RAG workflow\u0026#34;\u0026#34;\u0026#34; # Search for similar documents similar = search_similar(query, count=3) # Retrieve context context_docs = retrieve_context([r[\u0026#39;id\u0026#39;] for r in similar]) context = \u0026#34;\\n\\n\u0026#34;.join([doc[\u0026#39;text\u0026#39;] for doc in context_docs]) # Generate answer with LLM response = client.chat.completions.create( model=\u0026#34;gpt-4\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Answer based on the provided context.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: f\u0026#34;Context:\\n{context}\\n\\nQuestion: {query}\u0026#34;} ] ) return response.choices[0].message.content # Usage embed_and_store(\u0026#34;doc001\u0026#34;, \u0026#34;The quick brown fox jumps over the lazy dog\u0026#34;, {\u0026#34;category\u0026#34;: \u0026#34;animals\u0026#34;}) answer = rag_query(\u0026#34;What animals are mentioned?\u0026#34;) print(answer)Best Practices# Batch Upload: Upload embeddings in batches of 100-1000 for better performance Use Metadata: Include rich metadata for better filtering and organization Set Thresholds: Use similarity thresholds (e.g., 0.7) to filter low-quality matches Cache Embeddings: Cache generated embeddings to avoid redundant API calls Monitor Dimensions: Ensure all embeddings use consistent dimensions (3072 for text-embedding-3-large) Advanced Features# Metadata Filtering# Exclude certain documents from search results using metadata filters:\n# Exclude documents from the same author as the query curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/my-documents/doc001?metadata_path=author\u0026amp;metadata_value=Alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;See the Metadata Filtering Guide for more details.\nMetadata Validation# Enforce consistent metadata structure using JSON Schema validation:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-documents\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;category\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;See the Metadata Validation Guide for more details.\nRelated Documentation# Batch Operations Guide - Efficiently upload large datasets Metadata Filtering Guide - Advanced search filtering Metadata Validation Guide - Schema validation Instance Management Guide - Managing LLM service instances Troubleshooting# Dimension Mismatch Error# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch\u0026#34; }Solution: Ensure the vector_dim field matches the dimensions configured in your LLM service instance.\nNo Similar Results# If searches return no results, try:\nLowering the similarity threshold (e.g., from 0.8 to 0.5) Increasing the count parameter Verifying embeddings are uploaded correctly Checking that query embeddings use the same model and dimensions "},{"id":8,"href":"/dhamps-vdb/development/testing/","title":"Testing","section":"Development","content":"Testing Guide# This guide covers how to run and write tests for dhamps-vdb.\nRunning Tests# dhamps-vdb uses integration tests that spin up real PostgreSQL containers using testcontainers. This approach ensures tests run against actual database instances with pgvector support.\nPrerequisites# Using Podman (Recommended for Linux):\n# Start podman socket systemctl --user start podman.socket # Export DOCKER_HOST for testcontainers export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sockUsing Docker:\nTestcontainers works with Docker out of the box. Ensure Docker daemon is running.\nRunning All Tests# # Run all tests with verbose output go test -v ./... # Run tests without verbose output go test ./... # Run tests with coverage go test -cover ./... # Generate coverage report go test -coverprofile=coverage.out ./... go tool cover -html=coverage.outRunning Specific Tests# # Run tests in a specific package go test -v ./internal/handlers # Run a specific test function go test -v ./internal/handlers -run TestCreateUser # Run tests matching a pattern go test -v ./... -run \u0026#34;.*Sharing.*\u0026#34;Test Containers# Tests automatically manage PostgreSQL containers with pgvector:\nContainer is started before tests run Database schema is migrated automatically Container is cleaned up after tests complete Each test suite gets a fresh database state Test Structure# Package Organization# Tests are organized alongside the code they test:\ninternal/ ├── handlers/ │ ├── users.go # Implementation │ ├── users_test.go # Unit/integration tests │ ├── projects.go │ ├── projects_test.go │ ├── projects_sharing_test.go │ ├── embeddings.go │ └── embeddings_test.go ├── database/ │ └── queries.sql # SQL queries for sqlc └── models/ ├── users.go └── projects.goTest Files# Test files follow Go conventions:\nFilename: *_test.go Package: Same as code under test (e.g., package handlers) Test functions: func TestFunctionName(t *testing.T) Test Fixtures# Test data is stored in testdata/:\ntestdata/ ├── postgres/ │ ├── enable-vector.sql # Database initialization │ └── users.yml ├── valid_embeddings.json ├── valid_user.json ├── valid_api_standard_openai_v1.json ├── valid_llm_service_openai-large-full.json └── invalid_embeddings.jsonWriting Tests# Basic Test Structure# package handlers import ( \u0026#34;context\u0026#34; \u0026#34;testing\u0026#34; \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; \u0026#34;github.com/stretchr/testify/assert\u0026#34; ) func TestCreateUser(t *testing.T) { // Setup: Initialize database pool and test data ctx := context.Background() pool := setupTestDatabase(t) defer pool.Close() // Execute: Call function under test result, err := CreateUser(ctx, pool, userData) // Assert: Verify results assert.NoError(t, err) assert.Equal(t, \u0026#34;testuser\u0026#34;, result.UserHandle) }Integration Test Example# func TestProjectSharingWorkflow(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create test users alice := createTestUser(t, pool, \u0026#34;alice\u0026#34;) bob := createTestUser(t, pool, \u0026#34;bob\u0026#34;) // Create project as Alice project := createTestProject(t, pool, alice, \u0026#34;test-project\u0026#34;) // Share project with Bob err := shareProject(t, pool, alice, project.ID, bob.Handle, \u0026#34;reader\u0026#34;) assert.NoError(t, err) // Verify Bob can access project projects := getAccessibleProjects(t, pool, bob) assert.Contains(t, projects, project) }Testing with Testcontainers# func setupTestDatabase(t *testing.T) *pgxpool.Pool { ctx := context.Background() // Create PostgreSQL container with pgvector req := testcontainers.ContainerRequest{ Image: \u0026#34;pgvector/pgvector:0.7.4-pg16\u0026#34;, ExposedPorts: []string{\u0026#34;5432/tcp\u0026#34;}, Env: map[string]string{ \u0026#34;POSTGRES_PASSWORD\u0026#34;: \u0026#34;password\u0026#34;, \u0026#34;POSTGRES_DB\u0026#34;: \u0026#34;testdb\u0026#34;, }, WaitStrategy: wait.ForLog(\u0026#34;database system is ready to accept connections\u0026#34;), } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) require.NoError(t, err) // Get connection details host, _ := container.Host(ctx) port, _ := container.MappedPort(ctx, \u0026#34;5432\u0026#34;) // Connect and migrate connString := fmt.Sprintf(\u0026#34;postgres://postgres:password@%s:%s/testdb\u0026#34;, host, port.Port()) pool := connectAndMigrate(t, connString) return pool }Validation Testing# Test dimension and metadata validation:\nfunc TestEmbeddingDimensionValidation(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create LLM service with 1536 dimensions llmService := createTestLLMService(t, pool, \u0026#34;openai\u0026#34;, 1536) // Try to insert embedding with wrong dimensions embedding := models.Embedding{ TextID: \u0026#34;doc1\u0026#34;, Vector: make([]float32, 768), // Wrong size! VectorDim: 768, } err := insertEmbedding(t, pool, embedding) assert.Error(t, err) assert.Contains(t, err.Error(), \u0026#34;dimension mismatch\u0026#34;) } func TestMetadataSchemaValidation(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create project with metadata schema schema := `{\u0026#34;type\u0026#34;:\u0026#34;object\u0026#34;,\u0026#34;properties\u0026#34;:{\u0026#34;author\u0026#34;:{\u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;}},\u0026#34;required\u0026#34;:[\u0026#34;author\u0026#34;]}` project := createProjectWithSchema(t, pool, \u0026#34;alice\u0026#34;, \u0026#34;test\u0026#34;, schema) // Valid metadata should succeed validMeta := `{\u0026#34;author\u0026#34;:\u0026#34;John Doe\u0026#34;}` err := insertEmbeddingWithMetadata(t, pool, project.ID, validMeta) assert.NoError(t, err) // Invalid metadata should fail invalidMeta := `{\u0026#34;year\u0026#34;:2024}` // Missing required \u0026#39;author\u0026#39; err = insertEmbeddingWithMetadata(t, pool, project.ID, invalidMeta) assert.Error(t, err) }Table-Driven Tests# For testing multiple scenarios:\nfunc TestSimilaritySearch(t *testing.T) { tests := []struct { name string threshold float32 limit int expected int }{ {\u0026#34;high threshold\u0026#34;, 0.9, 10, 2}, {\u0026#34;medium threshold\u0026#34;, 0.7, 10, 5}, {\u0026#34;low threshold\u0026#34;, 0.5, 10, 8}, {\u0026#34;with limit\u0026#34;, 0.5, 3, 3}, } pool := setupTestDatabase(t) defer pool.Close() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { results := searchSimilar(t, pool, \u0026#34;doc1\u0026#34;, tt.threshold, tt.limit) assert.Len(t, results, tt.expected) }) } }Cleanup Testing# Verify database cleanup:\nfunc TestDatabaseCleanup(t *testing.T) { pool := setupTestDatabase(t) defer pool.Close() // Create test data user := createTestUser(t, pool, \u0026#34;alice\u0026#34;) project := createTestProject(t, pool, user, \u0026#34;test\u0026#34;) createTestEmbeddings(t, pool, project, 10) // Delete user (should cascade) err := deleteUser(t, pool, user.Handle) assert.NoError(t, err) // Verify all related data is deleted assertTableEmpty(t, pool, \u0026#34;users\u0026#34;) assertTableEmpty(t, pool, \u0026#34;projects\u0026#34;) assertTableEmpty(t, pool, \u0026#34;embeddings\u0026#34;) }Test Helpers# Create helper functions to reduce boilerplate:\n// setupTestDatabase initializes a test database with migrations func setupTestDatabase(t *testing.T) *pgxpool.Pool { // Implementation... } // createTestUser creates a user for testing func createTestUser(t *testing.T, pool *pgxpool.Pool, handle string) *models.User { // Implementation... } // createTestProject creates a project for testing func createTestProject(t *testing.T, pool *pgxpool.Pool, owner *models.User, handle string) *models.Project { // Implementation... } // assertTableEmpty verifies a table has no rows func assertTableEmpty(t *testing.T, pool *pgxpool.Pool, tableName string) { var count int err := pool.QueryRow(context.Background(), fmt.Sprintf(\u0026#34;SELECT COUNT(*) FROM %s\u0026#34;, tableName)).Scan(\u0026amp;count) require.NoError(t, err) assert.Equal(t, 0, count, \u0026#34;table %s should be empty\u0026#34;, tableName) }CI/CD Integration# GitHub Actions# Example GitHub Actions workflow:\nname: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v4 with: go-version: \u0026#39;1.21\u0026#39; - name: Run tests run: | go test -v -race -coverprofile=coverage.txt ./... - name: Upload coverage uses: codecov/codecov-action@v3 with: files: ./coverage.txtLocal CI Testing# Test as CI would:\n# Clean test with race detection go clean -testcache go test -v -race ./... # Test with coverage go test -coverprofile=coverage.out ./... # Check for test caching issues go test -count=1 ./...Best Practices# 1. Use testcontainers for Real Databases# Don\u0026rsquo;t mock the database layer Test against actual PostgreSQL with pgvector Catch SQL-specific issues 2. Isolate Tests# Each test should be independent Use transactions or cleanup between tests Don\u0026rsquo;t rely on test execution order 3. Test Validation Logic# Test dimension validation Test metadata schema validation Test authorization checks 4. Test Error Conditions# Invalid input Missing resources (404) Unauthorized access (403) Constraint violations 5. Keep Tests Fast# Use parallel tests where possible: t.Parallel() Reuse test database containers when appropriate Avoid unnecessary sleeps 6. Use Descriptive Names# // Good func TestProjectSharingWithReaderRole(t *testing.T) // Less clear func TestSharing(t *testing.T)7. Assert Meaningfully# // Good - specific assertion assert.Equal(t, \u0026#34;alice\u0026#34;, project.Owner) // Less helpful assert.True(t, project.Owner == \u0026#34;alice\u0026#34;)Debugging Tests# Verbose Output# # See all test output go test -v ./internal/handlers # See SQL queries (if logging enabled) SERVICE_DEBUG=true go test -v ./...Run Single Test# # Focus on one failing test go test -v ./internal/handlers -run TestCreateProjectKeep Test Database Running# For manual inspection, prevent container cleanup:\nfunc TestWithDebugContainer(t *testing.T) { container := setupContainer(t) // Comment out: defer container.Terminate(ctx) host, port := getContainerDetails(container) t.Logf(\u0026#34;Database running at %s:%s\u0026#34;, host, port) // Run test... // Container stays running for manual inspection time.Sleep(time.Hour) }Then connect with psql:\npsql -h localhost -p \u0026lt;port\u0026gt; -U postgres -d testdbCommon Issues# Container Startup Failures# # Check Docker/Podman is running systemctl --user status podman.socket # Check for port conflicts netstat -tulpn | grep 5432 # Clean up containers podman rm -f $(podman ps -aq)Test Timeouts# Increase timeout for slow containers:\nWaitStrategy: wait.ForLog(\u0026#34;ready\u0026#34;).WithStartupTimeout(2 * time.Minute)Permission Errors# Ensure test user has proper permissions:\nGRANT ALL PRIVILEGES ON DATABASE testdb TO testuser; GRANT ALL ON SCHEMA public TO testuser;Further Reading# Go Testing Documentation Testcontainers for Go Testify Assertions Table-Driven Tests in Go "},{"id":9,"href":"/dhamps-vdb/api/endpoints/users/","title":"Users","section":"Endpoints","content":"Users Endpoint# Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.\nEndpoints# List All Users# Get a list of all registered user handles.\nEndpoint: GET /v1/users\nAuthentication: Admin only\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;users\u0026#34;: [\u0026#34;alice\u0026#34;, \u0026#34;bob\u0026#34;, \u0026#34;charlie\u0026#34;] } Create User# Register a new user and generate their API key.\nEndpoint: POST /v1/users\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Parameters:\nuser_handle (string, required): Unique identifier for the user (alphanumeric, hyphens, underscores) name (string, optional): User\u0026rsquo;s full name email (string, optional): User\u0026rsquo;s email address Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; }⚠️ Important: The api_key is only returned once during user creation. Store it securely - it cannot be recovered later.\nError Responses:\n400 Bad Request: Invalid user handle or missing required fields 409 Conflict: User handle already exists Get User Information# Retrieve information about a specific user.\nEndpoint: GET /v1/users/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Note: API key is never returned in GET responses for security reasons.\nCreate or Update User (PUT)# Register a new user with a specific handle or update existing user information.\nEndpoint: PUT /v1/users/{username}\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }Example:\ncurl -X PUT \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;024v2013621509245f2e24\u0026#34; } Delete User# Delete a user and all their associated resources (projects, LLM services, embeddings).\nEndpoint: DELETE /v1/users/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;User alice deleted successfully\u0026#34; }⚠️ Warning: This operation is irreversible and will delete:\nAll projects owned by the user All LLM service instances owned by the user All embeddings in the user\u0026rsquo;s projects All sharing relationships Partial Update (PATCH)# Update specific user fields without providing all user data.\nEndpoint: PATCH /v1/users/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34; }Example:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;email\u0026#34;: \u0026#34;newemail@example.com\u0026#34; }\u0026#39;See PATCH Updates for more details.\nUser Properties# Field Type Required Description user_handle string Yes Unique identifier (alphanumeric, hyphens, underscores) name string No User\u0026rsquo;s full name email string No User\u0026rsquo;s email address api_key string Read-only Generated API key (only returned on creation) Special User: _system# The _system user is a special internal user that:\nOwns global LLM service definitions Cannot be used for authentication Cannot be deleted Is created automatically during database migrations Users can create LLM service instances from _system definitions.\nCommon Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid user_handle: must be alphanumeric with hyphens or underscores\u0026#34; }401 Unauthorized# { \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Related Documentation# Authentication - API key authentication details Projects - Project management LLM Services - LLM service instances "},{"id":10,"href":"/dhamps-vdb/concepts/","title":"Concepts","section":"dhamps-vdb Documentation","content":"Core Concepts# Understanding the key concepts behind dhamps-vdb helps you make the most of its features. This section explains the fundamental building blocks and how they work together.\nOverview# dhamps-vdb is a vector database designed for Retrieval Augmented Generation (RAG) workflows. It stores embeddings with metadata and provides fast similarity search capabilities.\nKey Components# Users - Individual accounts with authentication Projects - Containers for embeddings with access control Embeddings - Vector representations of text with metadata LLM Services - Configurations for embedding models Similarity Search - Find similar documents using vector distance Architecture# dhamps-vdb uses PostgreSQL with the pgvector extension for vector operations. It provides a RESTful API with token-based authentication and supports multi-user environments with project sharing.\n"},{"id":11,"href":"/dhamps-vdb/getting-started/configuration/","title":"Configuration","section":"Getting Started","content":"Configuration# Configure dhamps-vdb using environment variables or command-line options.\nEnvironment Variables# All configuration can be set via environment variables. Use a .env file to keep sensitive information secure.\nService Configuration# Variable Description Default Required SERVICE_DEBUG Enable debug logging true No SERVICE_HOST Hostname to listen on localhost No SERVICE_PORT Port to listen on 8880 No Database Configuration# Variable Description Default Required SERVICE_DBHOST Database hostname localhost Yes SERVICE_DBPORT Database port 5432 No SERVICE_DBUSER Database username postgres Yes SERVICE_DBPASSWORD Database password password Yes SERVICE_DBNAME Database name postgres Yes Security Configuration# Variable Description Default Required SERVICE_ADMINKEY Admin API key for administrative operations - Yes ENCRYPTION_KEY Encryption key for API keys (32+ characters) - Yes Configuration File# Create a .env file in the project root:\n# Service Configuration SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 # Database Configuration SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdb # Security SERVICE_ADMINKEY=your-secure-admin-key-here ENCRYPTION_KEY=your-32-character-encryption-key-minimumCommand-Line Options# You can also provide configuration via command-line flags:\n./dhamps-vdb \\ --debug \\ -p 8880 \\ --db-host localhost \\ --db-port 5432 \\ --db-user dhamps_user \\ --db-password secure_password \\ --db-name dhamps_vdb \\ --admin-key your-admin-keyGenerating Secure Keys# Admin Key# Generate a secure admin key:\nopenssl rand -base64 32Encryption Key# Generate a secure encryption key (minimum 32 characters):\nopenssl rand -hex 32Configuration Priority# Configuration is loaded in the following order (later sources override earlier ones):\nDefault values (from options.go) Environment variables .env file Command-line flags Security Best Practices# Never commit .env files to version control Use strong, randomly generated keys for production Ensure .env file permissions are restrictive (chmod 600 .env) Store encryption key securely - losing it means losing access to encrypted API keys Use different keys for development and production environments Example Configuration# Development# # .env (development) SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=password SERVICE_DBNAME=dhamps_vdb_dev SERVICE_ADMINKEY=dev-admin-key-change-me ENCRYPTION_KEY=dev-encryption-key-32-chars-minProduction# # .env (production) SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=prod-db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod SERVICE_DBPASSWORD=$(cat /run/secrets/db_password) SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=$(cat /run/secrets/admin_key) ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)Validation# The service validates configuration on startup and will exit with an error if required variables are missing.\nNext Steps# After configuration:\nRun the Quick Start tutorial Create your first project Review deployment options "},{"id":12,"href":"/dhamps-vdb/development/contributing/","title":"Contributing","section":"Development","content":"Contributing Guide# Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.\nDevelopment Setup# Prerequisites# Go 1.21+: Download Go PostgreSQL 16+: With pgvector extension sqlc: For generating type-safe database code Docker/Podman: For running tests Git: For version control Clone and Build# # Clone repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Install dependencies go get ./... # Generate sqlc code sqlc generate --no-remote # Build application go build -o build/dhamps-vdb main.go # Or run directly go run main.goEnvironment Setup# Create a .env file for local development:\n# Copy template cp template.env .env # Edit with your settings SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_ADMINKEY=your-secure-admin-key-here # Database settings SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=password SERVICE_DBNAME=dhamps_vdb_dev # Encryption key (32+ characters) ENCRYPTION_KEY=your-secure-encryption-key-min-32-charsImportant: Never commit .env files (already in .gitignore)\nDatabase Setup# For local development:\n# Start PostgreSQL with pgvector podman run -p 5432:5432 \\ -e POSTGRES_PASSWORD=password \\ -e POSTGRES_DB=dhamps_vdb_dev \\ pgvector/pgvector:0.7.4-pg16 # Or use docker-compose docker-compose up -d # Application auto-migrates on startup go run main.goVerify Setup# # Check application starts go run main.go # In another terminal, test API curl http://localhost:8880/docs # Run tests go test -v ./...Code Style# Go Formatting# dhamps-vdb follows standard Go conventions:\n# Format all code go fmt ./... # Check for common issues go vet ./... # Run linter (if installed) golangci-lint runCode Organization# Follow existing patterns:\n// Package comment at top of file package handlers import ( // Standard library first \u0026#34;context\u0026#34; \u0026#34;fmt\u0026#34; // External packages \u0026#34;github.com/danielgtaylor/huma/v2\u0026#34; \u0026#34;github.com/jackc/pgx/v5/pgxpool\u0026#34; // Internal packages \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/models\u0026#34; ) // Exported function with doc comment // GetUsers retrieves all users from the database func GetUsers(ctx context.Context, pool *pgxpool.Pool) ([]models.User, error) { // Implementation }Naming Conventions# Files:\nhandlers/users.go - Implementation handlers/users_test.go - Tests handlers/users_sharing_test.go - Specific feature tests Functions:\nGetUsers() - List/retrieve multiple GetUser() - Retrieve single CreateUser() - Create new UpdateUser() - Update existing DeleteUser() - Delete LinkUserToProject() - Create association IsProjectOwner() - Boolean check Database Queries (in queries.sql):\n-- name: GetAllUsers :many -- name: RetrieveUserByHandle :one -- name: UpsertUser :one -- name: DeleteUser :exec Error Handling# // Return errors, don\u0026#39;t panic func CreateUser(ctx context.Context, pool *pgxpool.Pool, user models.User) error { if user.Handle == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;user handle is required\u0026#34;) } // Wrap errors with context err := db.InsertUser(ctx, user) if err != nil { return fmt.Errorf(\u0026#34;failed to insert user: %w\u0026#34;, err) } return nil } // Use specific error responses in handlers func handleCreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { err := CreateUser(ctx, pool, input.Body) if err != nil { return nil, huma.Error400BadRequest(\u0026#34;invalid user data\u0026#34;, err) } return \u0026amp;CreateUserOutput{Body: result}, nil }Comments# Comment public APIs and complex logic:\n// GetAccessibleProjects returns all projects the user can access. // This includes projects owned by the user and projects shared with them. // Results are paginated using limit and offset. func GetAccessibleProjects(ctx context.Context, pool *pgxpool.Pool, userHandle string, limit, offset int) ([]models.Project, error) { // Use UNION ALL for better query performance // See docs/PERFORMANCE_OPTIMIZATION.md for details query := ` SELECT * FROM projects WHERE owner = $1 UNION ALL SELECT p.* FROM projects p INNER JOIN projects_shared_with ps ON p.project_id = ps.project_id WHERE ps.user_handle = $1 ` // Implementation... }Don\u0026rsquo;t over-comment obvious code:\n// Bad - obvious // i is set to 0 i := 0 // Good - explains why // Start from second element (first is header) i := 1Git Workflow# Branching Strategy# # Create feature branch from main git checkout main git pull origin main git checkout -b feature/your-feature-name # Create fix branch git checkout -b fix/issue-description # Create docs branch git checkout -b docs/update-contributing-guideBranch naming:\nfeature/* - New features fix/* - Bug fixes docs/* - Documentation updates test/* - Test improvements refactor/* - Code refactoring Commit Messages# Write clear, descriptive commit messages:\n# Good commit messages git commit -m \u0026#34;Add project sharing functionality\u0026#34; git commit -m \u0026#34;Fix dimension validation for embeddings\u0026#34; git commit -m \u0026#34;Update contributing guide with git workflow\u0026#34; # Multi-line for complex changes git commit -m \u0026#34;Refactor similarity search query - Use UNION ALL for better performance - Add dimension filtering to subqueries - Update tests to verify performance improvement Closes #123\u0026#34;Commit message format:\nFirst line: Brief summary (50 chars or less) Blank line Detailed explanation if needed Reference issues: Closes #123 or Fixes #456 Pull Request Process# Create feature branch\ngit checkout -b feature/my-feature Make changes and commit\ngit add . git commit -m \u0026#34;Add feature description\u0026#34; Keep branch updated\ngit fetch origin git rebase origin/main Push to your fork\ngit push origin feature/my-feature Create Pull Request\nGo to GitHub repository Click \u0026ldquo;New Pull Request\u0026rdquo; Select your branch Fill in PR template PR Review Process\nAutomated tests run Code review by maintainers Address feedback Merge when approved PR Title Format# [Type] Brief description Examples: [Feature] Add project ownership transfer [Fix] Correct dimension validation in embeddings [Docs] Update API documentation for similarity search [Test] Add integration tests for sharing workflow [Refactor] Simplify authentication middlewarePR Description Template# ## Description Brief description of changes ## Motivation Why is this change needed? ## Changes - Change 1 - Change 2 - Change 3 ## Testing How was this tested? - [ ] Unit tests pass - [ ] Integration tests pass - [ ] Manual testing performed ## Related Issues Closes #123 Relates to #456 ## Checklist - [ ] Code follows style guidelines - [ ] Tests added/updated - [ ] Documentation updated - [ ] No breaking changes (or clearly documented)Testing Requirements# All contributions must include tests:\nFor New Features# // Add tests in same package // File: handlers/projects.go func CreateProject(...) { ... } // File: handlers/projects_test.go func TestCreateProject(t *testing.T) { // Test happy path // Test error cases // Test edge cases }For Bug Fixes# // Add regression test func TestBugFix_Issue123(t *testing.T) { // Reproduce the bug // Verify it\u0026#39;s fixed }Test Coverage# Aim for reasonable coverage:\n# Check coverage go test -cover ./... # Generate coverage report go test -coverprofile=coverage.out ./... go tool cover -html=coverage.outTarget coverage: 70%+ for new code\nRunning Tests# # Before submitting PR go test -v ./... # With race detection go test -race ./... # Specific package go test -v ./internal/handlersSee Testing Guide for detailed information.\nDocumentation Updates# When to Update Docs# Update documentation for:\nNew features: Add usage examples API changes: Update endpoint documentation Breaking changes: Clearly document migration path Configuration: New environment variables or options Documentation Structure# docs/content/ ├── getting-started/ # Installation, quickstart ├── concepts/ # Core concepts ├── guides/ # How-to guides ├── api/ # API reference └── development/ # Development docs (this section)Adding Documentation# # Create new doc file cd docs/content/guides cat \u0026gt; new-guide.md \u0026lt;\u0026lt;EOF --- title: \u0026#34;Your Guide Title\u0026#34; weight: 5 --- # Your Guide Content here... EOFHugo Front Matter# All docs need front matter:\n--- title: \u0026#34;Page Title\u0026#34; weight: 1 # Determines order in menu draft: false # Set true for work in progress ---Code Examples in Docs# Include working examples:\n```bash # Example command curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer admin-key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;}\u0026#39; ``` ```go // Example Go code user := models.User{ Handle: \u0026#34;alice\u0026#34;, Name: \u0026#34;Alice Smith\u0026#34;, } err := CreateUser(ctx, pool, user) ```Issue Reporting# Before Creating an Issue# Search existing issues Check documentation Try latest version Prepare reproduction steps Bug Report Template# ## Bug Description Clear description of the bug ## Steps to Reproduce 1. Start application with these settings... 2. Send this request... 3. Observe error... ## Expected Behavior What should happen ## Actual Behavior What actually happens ## Environment - dhamps-vdb version: v0.1.0 - Go version: 1.21.5 - PostgreSQL version: 16.1 - OS: Ubuntu 22.04 ## LogsRelevant error logs here\n## Additional Context Any other relevant informationFeature Request Template# ## Feature Description Clear description of proposed feature ## Use Case Why is this needed? Who benefits? ## Proposed Solution How should it work? ## Alternatives Considered Other approaches you\u0026#39;ve thought about ## Additional Context Examples, mockups, related featuresCode Review Guidelines# For Reviewers# Be constructive: Suggest improvements, don\u0026rsquo;t just criticize Ask questions: \u0026ldquo;Could we handle this case?\u0026rdquo; vs \u0026ldquo;This is wrong\u0026rdquo; Explain reasoning: Help author understand why Approve when ready: Don\u0026rsquo;t be too pedantic on style For Authors# Respond to feedback: Address all comments Ask for clarification: If feedback unclear Don\u0026rsquo;t take it personally: Focus on improving code Update PR: Push changes after addressing feedback What Reviewers Check# Code follows style guidelines Tests are comprehensive Documentation is updated No obvious bugs or security issues Error handling is appropriate Performance considerations addressed Breaking changes documented Release Process# Maintainers handle releases, but contributors should:\nDocument breaking changes in PR description Update CHANGELOG if applicable Tag related issues with milestone Development Best Practices# 1. Start Small# Small PRs are easier to review Focus on one feature/fix per PR Break large changes into multiple PRs 2. Write Tests First# // Write test first (TDD approach) func TestNewFeature(t *testing.T) { // This will fail initially result := NewFeature() assert.Equal(t, expected, result) } // Then implement func NewFeature() Result { // Implementation }3. Use Type Safety# // Generate type-safe queries with sqlc // Edit: internal/database/queries/queries.sql -- name: GetUserByHandle :one SELECT * FROM users WHERE user_handle = $1; // Then regenerate sqlc generate --no-remote // Use generated code user, err := db.GetUserByHandle(ctx, handle)4. Handle Errors Properly# // Don\u0026#39;t ignore errors result, err := SomeFunction() if err != nil { return fmt.Errorf(\u0026#34;operation failed: %w\u0026#34;, err) } // Provide context if err := ValidateInput(input); err != nil { return huma.Error400BadRequest(\u0026#34;invalid input\u0026#34;, err) }5. Keep It Simple# Prefer clarity over cleverness Use standard library when possible Don\u0026rsquo;t over-engineer solutions Getting Help# Resources# Documentation: Browse /docs folder API Docs: Run locally and visit /docs endpoint Code Examples: Check testdata/ for examples Test Files: See how features are tested Communication# GitHub Issues: For bugs and feature requests Pull Requests: For code discussions Code Comments: For implementation questions Asking Questions# Good questions include:\nWhat you\u0026rsquo;re trying to accomplish What you\u0026rsquo;ve already tried Relevant code snippets Error messages (full stack trace) License# By contributing, you agree that your contributions will be licensed under the MIT License.\nRecognition# Contributors are acknowledged in:\nGit commit history GitHub contributors page Release notes (for significant contributions) Thank you for contributing to dhamps-vdb! 🎉\n"},{"id":13,"href":"/dhamps-vdb/reference/database-schema/","title":"Database Schema Reference","section":"Reference","content":"Database Schema Reference# Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.\nOverview# The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in internal/database/migrations/.\nKey Features:\nVector embeddings stored as halfvec for efficient storage HNSW indexes for fast approximate nearest neighbor search Automatic timestamp tracking (created_at, updated_at) Foreign key constraints with CASCADE deletion Role-based access control through association tables Multi-tenancy support (user-owned resources) Schema Migrations# Current schema version is defined by 4 migration files:\n001_create_initial_scheme.sql - Core tables and relationships 002_create_emb_index.sql - HNSW vector indexes 003_add_public_read_flag.sql - Public access support 004_refactor_llm_services_architecture.sql - LLM service architecture refactor Core Tables# users# Stores user accounts with API authentication.\nColumn Type Constraints Description user_handle VARCHAR(20) PRIMARY KEY Unique user identifier (username) name TEXT Full name or display name email TEXT UNIQUE, NOT NULL Email address vdb_key CHAR(64) UNIQUE, NOT NULL API key (64-character hex) created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Indexes:\nPrimary key on user_handle Unique constraint on email Unique constraint on vdb_key Special Users:\n_system - Reserved system user for global LLM service definitions Relationships:\nOwns projects (1:N) Owns LLM service instances (1:N) Owns embeddings (1:N) Can share projects (N:M via users_projects) Can share LLM service instances (N:M via instances_shared_with) Notes:\nvdb_key is generated during user creation and returned once Cannot be recovered if lost Transmitted as Authorization: Bearer token projects# Stores embedding projects owned by users.\nColumn Type Constraints Description project_id SERIAL PRIMARY KEY Auto-incrementing project ID project_handle VARCHAR(20) NOT NULL Project identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Project owner user handle description TEXT Project description metadata_scheme TEXT JSON Schema for validating embedding metadata public_read BOOLEAN DEFAULT FALSE Allow unauthenticated read access instance_id INTEGER FK→instances LLM service instance used for embeddings created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, project_handle) - Project handles unique per owner ON DELETE CASCADE - Delete project when owner deleted ON DELETE RESTRICT - Prevent instance deletion if used by project Relationships:\nOwned by one user (N:1) Uses one LLM service instance (N:1) Has many embeddings (1:N) Can be shared with users (N:M via users_projects) Metadata Schema:\nStored as JSON Schema string Used to validate embedding metadata Optional (can be NULL) See Data Validation for details Public Access:\nWhen public_read=TRUE, allows unauthenticated embedding queries Controlled via API or by setting shared_with to [\u0026quot;*\u0026quot;] embeddings# Stores vector embeddings with text identifiers and metadata.\nColumn Type Constraints Description embeddings_id SERIAL PRIMARY KEY Auto-incrementing embedding ID text_id TEXT INDEXED Text identifier (URL, DOI, custom ID) owner VARCHAR(20) NOT NULL, FK→users Embedding owner user handle project_id SERIAL NOT NULL, FK→projects Project the embedding belongs to instance_id SERIAL NOT NULL, FK→instances LLM service instance used text TEXT Optional full text of the embedded content vector halfvec NOT NULL Embedding vector (half-precision float) vector_dim INTEGER NOT NULL Vector dimensionality metadata jsonb Optional metadata (validated if schema defined) created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (text_id, owner, project_id, instance_id) - Unique text IDs per project/instance ON DELETE CASCADE - Delete embeddings when owner, project, or instance deleted Indexes:\nPrimary key on embeddings_id B-tree index on text_id HNSW vector indexes for dimensions: 384, 768, 1024, 1536, 3072 (see Vector Indexes) Vector Storage:\nUses halfvec type (16-bit floating point) for efficient storage Dimensions must match LLM service instance configuration Validated on upload against instance dimensions Relationships:\nOwned by one user (N:1) Belongs to one project (N:1) Created with one LLM service instance (N:1) LLM Service Architecture# The LLM service architecture separates service definitions (templates) from user-specific instances.\ndefinitions# Templates for LLM embedding services (shared or user-specific).\nColumn Type Constraints Description definition_id SERIAL PRIMARY KEY Auto-incrementing definition ID definition_handle VARCHAR(20) NOT NULL Definition identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Definition owner (_system for global) endpoint TEXT NOT NULL API endpoint URL description TEXT Service description api_standard VARCHAR(20) NOT NULL, FK→api_standards API standard handle model TEXT NOT NULL Model name (e.g., text-embedding-3-large) dimensions INTEGER NOT NULL Vector dimensions produced by model context_limit INTEGER NOT NULL Maximum context length (tokens/chars) is_public BOOLEAN NOT NULL, DEFAULT FALSE Share with all users if true created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, definition_handle) - Definition handles unique per owner ON DELETE CASCADE - Delete definition when owner deleted Built-in Definitions:\nSystem-provided definitions (owned by _system, is_public=TRUE):\nHandle Model Dimensions Context Limit API Standard openai-large text-embedding-3-large 3072 8192 openai openai-small text-embedding-3-small 1536 8191 openai cohere-v4 embed-v4.0 1536 128000 cohere gemini-embedding-001 gemini-embedding-001 3072 2048 gemini Relationships:\nOwned by one user (N:1) References one API standard (N:1) Can be shared with users (N:M via definitions_shared_with) Used by instances (1:N) instances# User-specific configurations of LLM services with API keys.\nColumn Type Constraints Description instance_id SERIAL PRIMARY KEY Auto-incrementing instance ID instance_handle VARCHAR(20) NOT NULL Instance identifier (unique per owner) owner VARCHAR(20) NOT NULL, FK→users Instance owner user handle endpoint TEXT NOT NULL API endpoint URL description TEXT Instance description api_standard VARCHAR(20) NOT NULL, FK→api_standards API standard handle model TEXT NOT NULL Model name dimensions INTEGER NOT NULL Vector dimensions context_limit INTEGER NOT NULL Maximum context length definition_id INTEGER FK→definitions Reference to definition template api_key_encrypted BYTEA Encrypted API key for service authentication created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nUNIQUE (owner, instance_handle) - Instance handles unique per owner ON DELETE CASCADE - Delete instance when owner deleted ON DELETE SET NULL - Keep instance if definition deleted Indexes:\nComposite index on (owner, instance_handle) API Key Encryption:\nEncrypted using AES-256-GCM Encryption key from ENCRYPTION_KEY environment variable Cannot be recovered if encryption key is lost Stored as base64-encoded BYTEA Relationships:\nOwned by one user (N:1) References one API standard (N:1) Based on one definition template (N:1, optional) Used by projects (1:N) Used by embeddings (1:N) Can be shared with users (N:M via instances_shared_with) api_standards# Defines API specifications for LLM embedding services.\nColumn Type Constraints Description api_standard_handle VARCHAR(20) PRIMARY KEY Standard identifier (e.g., openai, cohere) description TEXT API description and version info key_method VARCHAR(20) NOT NULL, FK→key_methods Authentication method key_field VARCHAR(20) Header/field name for API key created_at TIMESTAMP NOT NULL Creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Built-in Standards:\nHandle Description Key Method Key Field openai OpenAI Embeddings API v1 auth_bearer Authorization cohere Cohere Embed API v2 auth_bearer Authorization gemini Gemini Embeddings API auth_bearer x-goog-api-key Relationships:\nUsed by definitions (1:N) Used by instances (1:N) References one key_method (N:1) Association Tables# users_projects# Defines project sharing and access control.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access project_id SERIAL FK→projects, PK Project being shared role VARCHAR(20) NOT NULL, FK→vdb_roles Access level (owner/editor/reader) created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, project_id) - One role per user per project ON DELETE CASCADE - Remove sharing when user or project deleted Roles:\nowner - Full control (only project creator) editor - Can add/modify/delete embeddings reader - Read-only access to embeddings instances_shared_with# Defines LLM service instance sharing.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access instance_id INTEGER FK→instances, PK Instance being shared role VARCHAR(20) NOT NULL, FK→vdb_roles Access level created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, instance_id) - One role per user per instance ON DELETE CASCADE - Remove sharing when user or instance deleted definitions_shared_with# Defines LLM service definition sharing.\nColumn Type Constraints Description user_handle VARCHAR(20) FK→users, PK User being granted access definition_id INTEGER FK→definitions, PK Definition being shared created_at TIMESTAMP NOT NULL Share creation timestamp updated_at TIMESTAMP NOT NULL Last update timestamp Constraints:\nPRIMARY KEY (user_handle, definition_id) - One share per user per definition ON DELETE CASCADE - Remove sharing when user or definition deleted Indexes:\nIndex on user_handle for efficient user lookups Index on definition_id for efficient definition lookups Reference Tables# vdb_roles# Enumeration of valid access roles.\nColumn Type Constraints Description vdb_role VARCHAR(20) PRIMARY KEY Role name Values:\nowner - Full control over resource editor - Read and write access reader - Read-only access key_methods# Enumeration of API authentication methods.\nColumn Type Constraints Description key_method VARCHAR(20) PRIMARY KEY Authentication method Values:\nauth_bearer - Bearer token in Authorization header body_form - API key in request body query_param - API key in URL query parameter custom_header - API key in custom header Vector Indexes# HNSW (Hierarchical Navigable Small World) indexes for fast approximate nearest neighbor search.\nIndex Configuration# All vector indexes use HNSW with these parameters:\nm = 24 - Number of neighbors per node ef_construction = 200 - Build-time accuracy parameter ef_search = 100 - Query-time accuracy parameter Expected recall: ~99.8% Dimension-Specific Indexes# Index Name Dimensions Common Models embeddings_vector_384 384 Cohere embed-multilingual-light-v3.0, embed-english-light-v3.0 embeddings_vector_768 768 BERT base, Cohere embed-multilingual-v2.0, Gemini Embeddings embeddings_vector_1024 1024 BERT large, SBERT, Cohere embed-multilingual-v3.0, embed-english-v3.0 embeddings_vector_1536 1536 OpenAI text-embedding-ada-002, text-embedding-3-small, Cohere embed-v4.0 embeddings_vector_3072 3072 OpenAI text-embedding-3-large, Gemini embedding-001 Index Structure:\nCREATE INDEX embeddings_vector_1536 ON embeddings USING hnsw ((vector::halfvec(1536)) halfvec_cosine_ops) WITH (m = 24, ef_construction = 200) WHERE (vector_dim = 1536);Usage:\nIndexes are partial - only include vectors of matching dimension Automatically used for similarity queries with matching dimensions Use cosine distance for similarity calculation Relationships Diagram# users (1) ──owns──\u0026gt; (N) projects (1) ──contains──\u0026gt; (N) embeddings │ │ │ │ └─\u0026gt; uses (1) instances (N) \u0026lt;───┘ │ │ │ └─\u0026gt; based on (1) definitions │ │ ├──owns──\u0026gt; (N) instances ──uses──\u0026gt; (1) api_standards │ │ │ │ └─\u0026gt; references (1) definitions │ └──owns──\u0026gt; (N) definitions ──references──\u0026gt; (1) api_standards Sharing: users (N) \u0026lt;──shares─\u0026gt; (M) projects (via users_projects) users (N) \u0026lt;──shares─\u0026gt; (M) instances (via instances_shared_with) users (N) \u0026lt;──shares─\u0026gt; (M) definitions (via definitions_shared_with)Data Validation# Dimension Validation# Embeddings must have dimensions matching their LLM service instance:\nembeddings.vector_dim must equal instances.dimensions Enforced at API level during upload Similarity queries automatically filter by matching dimensions Metadata Validation# Projects can define JSON Schema in metadata_scheme:\nValidates all embedding metadata on upload Optional - if NULL, metadata not validated Enforced at API level Admin sanity check validates all existing metadata Sanity Check Queries# The /v1/admin/sanity-check endpoint verifies:\nAll embeddings have dimensions matching their instance All metadata conforms to project schemas (if defined) Common Queries# Find User\u0026rsquo;s Projects# SELECT p.project_handle, p.description, p.created_at FROM projects p WHERE p.owner = \u0026#39;alice\u0026#39; ORDER BY p.created_at DESC;Find Shared Projects# SELECT p.project_handle, p.owner, up.role FROM users_projects up JOIN projects p ON up.project_id = p.project_id WHERE up.user_handle = \u0026#39;bob\u0026#39; ORDER BY p.owner, p.project_handle;Find Similar Embeddings# SELECT text_id, vector \u0026lt;-\u0026gt; \u0026#39;[0.1, 0.2, ...]\u0026#39;::vector AS distance FROM embeddings WHERE project_id = 123 AND vector_dim = 1536 ORDER BY vector \u0026lt;-\u0026gt; \u0026#39;[0.1, 0.2, ...]\u0026#39;::vector LIMIT 10;Count Embeddings by Project# SELECT p.project_handle, COUNT(e.embeddings_id) AS embedding_count FROM projects p LEFT JOIN embeddings e ON p.project_id = e.project_id WHERE p.owner = \u0026#39;alice\u0026#39; GROUP BY p.project_id, p.project_handle ORDER BY embedding_count DESC;Database Maintenance# Backup Recommendations# Critical Data:\nUser accounts (users) API keys (vdb_key in users, api_key_encrypted in instances) ENCRYPTION_KEY environment variable (backup separately!) Projects and embeddings Backup Strategy:\n# Full database backup pg_dump -U postgres dhamps_vdb \u0026gt; backup.sql # Backup encryption key separately echo \u0026#34;$ENCRYPTION_KEY\u0026#34; \u0026gt; encryption_key.backup chmod 400 encryption_key.backupVacuum and Analyze# -- Regular maintenance VACUUM ANALYZE embeddings; VACUUM ANALYZE projects; -- Rebuild vector indexes if needed REINDEX INDEX embeddings_vector_1536;Monitoring Queries# -- Check index usage SELECT schemaname, tablename, indexname, idx_scan FROM pg_stat_user_indexes WHERE tablename = \u0026#39;embeddings\u0026#39; ORDER BY idx_scan DESC; -- Check table sizes SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) FROM pg_class WHERE relname IN (\u0026#39;embeddings\u0026#39;, \u0026#39;projects\u0026#39;, \u0026#39;users\u0026#39;) ORDER BY pg_total_relation_size(oid) DESC;Related Documentation# Concepts - Architecture Concepts - Projects Concepts - Metadata Deployment - Database Setup Reference - Configuration API - Endpoints "},{"id":14,"href":"/dhamps-vdb/deployment/database/","title":"Database Setup","section":"Deployment","content":"Database Setup# dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.\nRequirements# PostgreSQL: Version 11 or higher pgvector: Extension for vector similarity search Storage: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count) Installing PostgreSQL with pgvector# Using Docker (Recommended)# The easiest way to get PostgreSQL with pgvector:\ndocker run -d \\ --name postgres-pgvector \\ -p 5432:5432 \\ -e POSTGRES_PASSWORD=secure_password \\ -v postgres_data:/var/lib/postgresql/data \\ pgvector/pgvector:0.7.4-pg16On Ubuntu/Debian# # Add PostgreSQL APT repository sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \\ https://www.postgresql.org/media/keys/ACCC4CF8.asc echo \u0026#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \\ https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\u0026#34; | \\ sudo tee /etc/apt/sources.list.d/pgdg.list # Install PostgreSQL sudo apt update sudo apt install postgresql-16 postgresql-contrib-16 # Install pgvector sudo apt install postgresql-16-pgvectorOn macOS# # Using Homebrew brew install postgresql@16 brew install pgvector # Start PostgreSQL brew services start postgresql@16On RHEL/CentOS/Fedora# # Install PostgreSQL sudo dnf install postgresql16-server postgresql16-contrib # Install pgvector (build from source) sudo dnf install postgresql16-devel git gcc make git clone https://github.com/pgvector/pgvector.git cd pgvector make sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_configDatabase Configuration# Step 1: Create Database# Connect to PostgreSQL as superuser:\n# Local connection sudo -u postgres psql # Remote connection psql -h db.example.com -U postgresCreate the database:\n-- Create database CREATE DATABASE dhamps_vdb;Step 2: Create User# Create a dedicated user for dhamps-vdb:\n-- Create user with password CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password_here\u0026#39;;Best practices:\nUse strong, randomly generated password (e.g., openssl rand -base64 32) Store password securely (password manager, secrets management) Rotate passwords regularly Step 3: Grant Privileges# Grant necessary permissions:\n-- Grant database privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; -- Connect to the database \\c dhamps_vdb -- Grant schema privileges GRANT ALL ON SCHEMA public TO dhamps_user; -- For PostgreSQL 15+, also grant: GRANT CREATE ON DATABASE dhamps_vdb TO dhamps_user;Step 4: Enable pgvector Extension# Still connected to the dhamps_vdb database:\n-- Enable pgvector extension CREATE EXTENSION IF NOT EXISTS vector; -- Verify extension is installed \\dxExpected output should include:\nList of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ vector | 0.7.4 | public | vector data type and ivfflat and hnsw access methodsStep 5: Verify Setup# Test the setup:\n-- Test vector creation SELECT \u0026#39;[1,2,3]\u0026#39;::vector; -- Should return: [1,2,3] -- Test vector distance SELECT \u0026#39;[1,2,3]\u0026#39;::vector \u0026lt;=\u0026gt; \u0026#39;[4,5,6]\u0026#39;::vector AS distance; -- Should return a float (distance value)Exit psql:\n\\qConnection String Format# dhamps-vdb connects using these environment variables:\nSERVICE_DBHOST=localhost # Database hostname SERVICE_DBPORT=5432 # Database port SERVICE_DBUSER=dhamps_user # Database username SERVICE_DBPASSWORD=password # Database password SERVICE_DBNAME=dhamps_vdb # Database nameThe connection string format used internally:\npostgresql://username:password@host:port/database?sslmode=disableProduction Configuration# PostgreSQL Tuning# Edit postgresql.conf for better vector search performance:\n# Memory settings shared_buffers = 4GB # 25% of RAM effective_cache_size = 12GB # 75% of RAM maintenance_work_mem = 1GB work_mem = 50MB # Parallel query settings max_parallel_workers_per_gather = 4 max_parallel_workers = 8 # Connection settings max_connections = 100 # For pgvector specifically shared_preload_libraries = \u0026#39;vector\u0026#39; # Add if not present # Write-ahead log wal_level = replica # For replication max_wal_senders = 3 # For replicasRestart PostgreSQL after changes:\n# On systemd systems sudo systemctl restart postgresql # On Docker docker restart postgres-containerConnection Pooling# For high-load scenarios, use connection pooling with PgBouncer:\n# Install PgBouncer sudo apt install pgbouncer # Configure /etc/pgbouncer/pgbouncer.ini [databases] dhamps_vdb = host=localhost port=5432 dbname=dhamps_vdb [pgbouncer] listen_addr = 127.0.0.1 listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 20Connect dhamps-vdb to PgBouncer instead of PostgreSQL directly.\nSSL/TLS Encryption# Enable SSL in postgresql.conf:\nssl = on ssl_cert_file = \u0026#39;/etc/postgresql/server.crt\u0026#39; ssl_key_file = \u0026#39;/etc/postgresql/server.key\u0026#39; ssl_ca_file = \u0026#39;/etc/postgresql/ca.crt\u0026#39;Update connection string:\n# Update dhamps-vdb configuration SERVICE_DBHOST=db.example.com # Change connection to use SSL (requires code modification or PostgreSQL parameter)Network Security# Restrict access in pg_hba.conf:\n# TYPE DATABASE USER ADDRESS METHOD # Allow dhamps_user from application server only host dhamps_vdb dhamps_user 10.0.1.0/24 md5 # Allow localhost connections local all all peer host all all 127.0.0.1/32 md5 host all all ::1/128 md5Reload PostgreSQL:\nsudo systemctl reload postgresqlBackup and Recovery# Automated Backups# Daily backup script:\n#!/bin/bash # /usr/local/bin/backup-dhamps-vdb.sh BACKUP_DIR=\u0026#34;/backups/dhamps-vdb\u0026#34; DATE=$(date +%Y%m%d_%H%M%S) DB_NAME=\u0026#34;dhamps_vdb\u0026#34; # Create backup pg_dump -U dhamps_user -h localhost $DB_NAME | gzip \u0026gt; \u0026#34;$BACKUP_DIR/dhamps-vdb-$DATE.sql.gz\u0026#34; # Keep last 30 days find $BACKUP_DIR -name \u0026#34;dhamps-vdb-*.sql.gz\u0026#34; -mtime +30 -delete # Verify backup if [ $? -eq 0 ]; then echo \u0026#34;Backup successful: $DATE\u0026#34; else echo \u0026#34;Backup failed: $DATE\u0026#34; \u0026gt;\u0026amp;2 exit 1 fiSet up cron job:\n# Run daily at 2 AM 0 2 * * * /usr/local/bin/backup-dhamps-vdb.shRestore from Backup# # Decompress and restore gunzip -c /backups/dhamps-vdb/dhamps-vdb-20240208.sql.gz | \\ psql -U dhamps_user -h localhost dhamps_vdbPoint-in-Time Recovery (PITR)# Enable WAL archiving in postgresql.conf:\nwal_level = replica archive_mode = on archive_command = \u0026#39;test ! -f /archive/%f \u0026amp;\u0026amp; cp %p /archive/%f\u0026#39;Monitoring# Check Database Size# -- Database size SELECT pg_size_pretty(pg_database_size(\u0026#39;dhamps_vdb\u0026#39;)); -- Table sizes SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||\u0026#39;.\u0026#39;||tablename)) AS size FROM pg_tables WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY pg_total_relation_size(schemaname||\u0026#39;.\u0026#39;||tablename) DESC;Check Connection Status# -- Active connections SELECT count(*) FROM pg_stat_activity WHERE datname = \u0026#39;dhamps_vdb\u0026#39;; -- Connection details SELECT pid, usename, application_name, client_addr, state, query FROM pg_stat_activity WHERE datname = \u0026#39;dhamps_vdb\u0026#39;;Monitor Performance# -- Enable pg_stat_statements CREATE EXTENSION IF NOT EXISTS pg_stat_statements; -- View slow queries SELECT query, calls, total_time, mean_time, max_time FROM pg_stat_statements WHERE query NOT LIKE \u0026#39;%pg_stat_statements%\u0026#39; ORDER BY mean_time DESC LIMIT 10;Troubleshooting# Cannot Connect to Database# # Check if PostgreSQL is running sudo systemctl status postgresql # Check PostgreSQL logs sudo tail -f /var/log/postgresql/postgresql-16-main.log # Test connection psql -h localhost -U dhamps_user -d dhamps_vdbpgvector Extension Not Found# -- Check available extensions SELECT * FROM pg_available_extensions WHERE name = \u0026#39;vector\u0026#39;; -- If not listed, install pgvector package -- See installation section abovePermission Denied# -- Reconnect as superuser \\c dhamps_vdb postgres -- Re-grant privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; GRANT ALL ON SCHEMA public TO dhamps_user; GRANT ALL ON ALL TABLES IN SCHEMA public TO dhamps_user; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO dhamps_user; -- For future objects ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO dhamps_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO dhamps_user;Out of Disk Space# # Check disk usage df -h # Check PostgreSQL data directory du -sh /var/lib/postgresql/16/main/ # Clean up old WAL files (if safe) # Check archive status firstSlow Queries# -- Check missing indexes SELECT schemaname, tablename, attname, n_distinct, correlation FROM pg_stats WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY n_distinct DESC; -- Analyze tables ANALYZE; -- Vacuum tables VACUUM ANALYZE;Migration from Other Databases# dhamps-vdb is designed specifically for PostgreSQL with pgvector. Migration from other databases requires:\nExport data from source database Set up PostgreSQL with pgvector Transform data to match dhamps-vdb schema Import using dhamps-vdb API or direct SQL Further Reading# PostgreSQL Documentation pgvector GitHub PostgreSQL Tuning Guide Environment Variables Docker Deployment Security Guide "},{"id":15,"href":"/dhamps-vdb/getting-started/docker/","title":"Docker Deployment","section":"Getting Started","content":"Docker Deployment# Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.\nQuick Start# The fastest way to get dhamps-vdb running with Docker:\n# Clone the repository git clone https://github.com/mpilhlt/dhamps-vdb.git cd dhamps-vdb # Run automated setup (generates secure keys) ./docker-setup.sh # Start services with docker-compose docker-compose up -d # Check logs docker-compose logs -f dhamps-vdb # Access the API curl http://localhost:8880/docsWhat\u0026rsquo;s Included# The Docker Compose setup includes:\ndhamps-vdb: The vector database API service PostgreSQL 16: Database with pgvector extension Persistent storage: Named volume for database data Configuration Files# .env File# All configuration is managed through environment variables. Copy the template:\ncp .env.docker.template .envEdit .env to set required values:\n# Admin API key for administrative operations SERVICE_ADMINKEY=your-secure-admin-key-here # Encryption key for API keys (32+ characters) ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars # Database password SERVICE_DBPASSWORD=secure-database-password # Optional: Debug mode SERVICE_DEBUG=false # Optional: Change ports API_PORT=8880 POSTGRES_PORT=5432docker-compose.yml# The compose file defines two services:\nservices: postgres: image: pgvector/pgvector:0.7.4-pg16 # PostgreSQL with pgvector support dhamps-vdb: build: . # The API service depends_on: - postgresDeployment Options# Option 1: Docker Compose with Included Database (Recommended)# Use the provided docker-compose.yml:\ndocker-compose up -dAdvantages:\nEverything included Automatic networking Data persistence Easy to manage Use when:\nGetting started Development/testing Small to medium deployments Option 2: Standalone Container with External Database# Run only the dhamps-vdb container:\n# Build the image docker build -t dhamps-vdb:latest . # Run the container docker run -d \\ --name dhamps-vdb \\ -p 8880:8880 \\ -e SERVICE_DBHOST=your-db-host \\ -e SERVICE_DBPORT=5432 \\ -e SERVICE_DBUSER=dbuser \\ -e SERVICE_DBPASSWORD=dbpass \\ -e SERVICE_DBNAME=dhamps_vdb \\ -e SERVICE_ADMINKEY=admin-key \\ -e ENCRYPTION_KEY=encryption-key \\ dhamps-vdb:latestUse when:\nYou have an existing PostgreSQL server Production deployments Need database separation Option 3: Docker Compose with External Database# Modify docker-compose.yml to remove the postgres service:\nservices: dhamps-vdb: build: . ports: - \u0026#34;${API_PORT:-8880}:8880\u0026#34; environment: SERVICE_DBHOST: external-db.example.com # ... other variablesBuilding the Image# Standard Build# docker build -t dhamps-vdb:latest .Custom Tag# docker build -t dhamps-vdb:v0.1.0 .Clean Build (No Cache)# docker build --no-cache -t dhamps-vdb:latest .Multi-Stage Build Details# The Dockerfile uses multi-stage builds for efficiency:\nBuilder stage: Compiles Go code with sqlc generation Runtime stage: Minimal Alpine image with only the binary Result: Small, secure image (~20MB vs 800MB+)\nManaging Services# Start Services# # Start in background docker-compose up -d # Start with logs visible docker-compose up # Rebuild and start docker-compose up -d --buildView Logs# # All logs docker-compose logs # Follow logs in real-time docker-compose logs -f # Specific service docker-compose logs -f dhamps-vdb docker-compose logs -f postgresStop Services# # Stop containers (keeps data) docker-compose stop # Stop and remove containers (keeps data) docker-compose down # Stop and remove everything including data docker-compose down -vRestart Services# # Restart all docker-compose restart # Restart specific service docker-compose restart dhamps-vdbData Persistence# Docker Volumes# The compose file creates a named volume:\nvolumes: postgres_data:This ensures database data persists across container restarts.\nView Volumes# docker volume lsInspect Volume# docker volume inspect dhamps-vdb_postgres_dataBackup Database# # Create backup docker-compose exec postgres pg_dump -U postgres dhamps_vdb \u0026gt; backup.sql # Restore from backup docker-compose exec -T postgres psql -U postgres dhamps_vdb \u0026lt; backup.sqlNetworking# Access from Host# The API is accessible at:\nhttp://localhost:8880Access from Other Containers# Use the service name as hostname:\nhttp://dhamps-vdb:8880Custom Network# To use an existing Docker network:\nnetworks: default: external: name: your-network-nameSecurity# Required Environment Variables# Two critical environment variables must be set:\nSERVICE_ADMINKEY: Admin API key ENCRYPTION_KEY: For encrypting user API keys (32+ chars) Generating Secure Keys# # Admin key openssl rand -base64 32 # Encryption key openssl rand -hex 32Production Checklist# Use strong, randomly generated keys Never commit .env to version control Run behind reverse proxy (nginx, Traefik) Enable HTTPS/TLS Restrict database network access Set resource limits Enable logging and monitoring Use specific image tags (not latest) Regular security updates Backup database regularly Verification# Check Service Status# # Check if containers are running docker-compose ps # Expected: both services \u0026#34;running\u0026#34; or \u0026#34;healthy\u0026#34;Test API Access# # Get OpenAPI documentation curl http://localhost:8880/docs # Should return HTML pageTest Database Connection# # Connect to PostgreSQL docker-compose exec postgres psql -U postgres -d dhamps_vdb # Check pgvector extension \\dx # Should show vector extensionCreate Test User# curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;testuser\u0026#34;, \u0026#34;full_name\u0026#34;: \u0026#34;Test User\u0026#34; }\u0026#39;Troubleshooting# Container Won\u0026rsquo;t Start# Check logs:\ndocker-compose logs dhamps-vdbCommon issues:\nMissing SERVICE_ADMINKEY or ENCRYPTION_KEY Database connection failure Port already in use Database Connection Errors# # Check postgres health docker-compose ps # Check database logs docker-compose logs postgres # Test connection docker-compose exec postgres psql -U postgres -d dhamps_vdb -c \u0026#34;SELECT 1;\u0026#34;Can\u0026rsquo;t Connect to API# # Check if container is running docker ps # Check port mapping docker port dhamps-vdb # Test from inside container docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs # Test from host curl http://localhost:8880/docsPermission Issues# The container runs as non-root user appuser (UID 1000). If you have permission errors:\n# Check volume permissions docker volume inspect dhamps-vdb_postgres_dataReset Everything# # Stop and remove everything docker-compose down -v # Remove images docker rmi dhamps-vdb:latest docker rmi pgvector/pgvector:0.7.4-pg16 # Start fresh docker-compose up -d --buildBuild Failures# If Docker build fails with network errors:\n# Try with host network docker build --network=host -t dhamps-vdb:latest .Advanced Configuration# Resource Limits# Add to docker-compose.yml:\nservices: dhamps-vdb: deploy: resources: limits: cpus: \u0026#39;2\u0026#39; memory: 2G reservations: cpus: \u0026#39;0.5\u0026#39; memory: 512MHealth Checks# The Dockerfile includes a health check:\nHEALTHCHECK --interval=30s --timeout=3s \\ CMD wget --no-verbose --tries=1 --spider http://localhost:8880/ || exit 1View health status:\ndocker inspect --format=\u0026#39;{{.State.Health.Status}}\u0026#39; dhamps-vdbCustom Dockerfile Builds# You can customize the build:\ndocker build \\ --build-arg GO_VERSION=1.24 \\ -t dhamps-vdb:custom .External Database Setup# If using an external PostgreSQL database:\nPrepare Database# -- Create database CREATE DATABASE dhamps_vdb; -- Create user CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password\u0026#39;; -- Grant privileges GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; -- Connect to database \\c dhamps_vdb -- Grant schema permissions GRANT ALL ON SCHEMA public TO dhamps_user; -- Enable pgvector CREATE EXTENSION IF NOT EXISTS vector;Configure dhamps-vdb# Update .env:\nSERVICE_DBHOST=external-db.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_user SERVICE_DBPASSWORD=secure_password SERVICE_DBNAME=dhamps_vdbThen run only the dhamps-vdb service or use a standalone container.\nNext Steps# After successful deployment:\nConfigure the service Create your first user Set up a project Review security best practices "},{"id":16,"href":"/dhamps-vdb/guides/project-sharing/","title":"Project Sharing Guide","section":"Guides","content":"Project Sharing Guide# This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.\nOverview# Project sharing allows you to grant other users access to your projects with different permission levels:\nreader: Read-only access to embeddings and similar documents editor: Read and write access to embeddings (can add/modify/delete embeddings) Only the project owner can manage sharing settings and delete the project.\nSharing During Project Creation# You can specify users to share with when creating a new project using the shared_with field:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;A project shared with team members\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }\u0026#39;In this example:\nbob can read embeddings and search for similar documents charlie can read embeddings, search, and also add/modify/delete embeddings alice (the owner) has full control including managing sharing and deleting the project Managing Sharing After Creation# Share a Project with a User# Add a user to an existing project:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project shared successfully\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Update User\u0026rsquo;s Role# To change a user\u0026rsquo;s role, simply share again with the new role:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;david\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }\u0026#39;This updates David\u0026rsquo;s access from reader to editor.\nUnshare a Project from a User# Remove a user\u0026rsquo;s access to a project:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/share/david\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project unshared successfully\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;david\u0026#34; }List Shared Users# View all users a project is shared with:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }Note: Only the project owner can view the list of shared users. Users who have been granted access cannot see which other users also have access.\nWhat Shared Users Can Do# As a Reader# Bob (with reader access) can:\n# View project metadata curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Retrieve embeddings curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Get a specific embedding curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Search for similar documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/collaborative-project/doc123?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34;As an Editor# Charlie (with editor access) can do everything a reader can, plus:\n# Upload new embeddings curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Charlie\u0026#34;} }] }\u0026#39; # Delete specific embeddings curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project/doc456\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; # Delete all embeddings curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/collaborative-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34;What Shared Users Cannot Do# Even with editor access, shared users cannot:\nDelete the project Change project settings (description, instance, metadata schema) Manage sharing (add/remove other users) View the list of other shared users Transfer project ownership These operations require owner privileges.\nPermission Summary Table# Operation Owner Editor Reader View project metadata ✅ ✅ ✅ Retrieve embeddings ✅ ✅ ✅ Search similar documents ✅ ✅ ✅ Add embeddings ✅ ✅ ❌ Modify embeddings ✅ ✅ ❌ Delete embeddings ✅ ✅ ❌ Update project settings ✅ ❌ ❌ Delete project ✅ ❌ ❌ Manage sharing ✅ ❌ ❌ View shared users list ✅ ❌ ❌ Transfer ownership ✅ ❌ ❌ Use Cases# Research Team Collaboration# A research team can share a project where:\nThe principal investigator (PI) is the owner Research assistants have editor access to upload new data External collaborators have reader access to query the data # PI creates and shares the project curl -X PUT \u0026#34;https://api.example.com/v1/projects/pi/research-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer pi_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research team corpus\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;assistant1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;assistant2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;external_collab\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }\u0026#39;Data Pipeline with Read-Only Access# Share processed embeddings with downstream consumers:\n# Data processor creates project curl -X PUT \u0026#34;https://api.example.com/v1/projects/processor/processed-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer processor_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;processed-data\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Processed embeddings for consumption\u0026#34;, \u0026#34;instance_id\u0026#34;: 456, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;app_backend\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;analytics_team\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }\u0026#39;Temporary Access# Grant temporary access to a consultant and revoke it later:\n# Grant access curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/sensitive-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;consultant\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}\u0026#39; # Revoke access when consultation is complete curl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/sensitive-project/share/consultant\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining with Public Access# You can combine user-specific sharing with public access (see Public Projects Guide):\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/mixed-access-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;mixed-access-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Public read, specific editors\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;} ] }\u0026#39;In this case:\nAnyone can read the project (no authentication required) bob can also edit (add/modify/delete embeddings) alice retains full owner privileges Security Considerations# Choose Roles Carefully: Only grant editor access to trusted users who need to modify data Audit Access: Regularly review the shared users list to ensure appropriate access levels Revoke Promptly: Remove access immediately when users no longer need it Use Reader by Default: Start with reader access and upgrade to editor only when necessary Consider Public Access: For truly open data, use public_read: true instead of sharing with many users Related Documentation# Ownership Transfer Guide - Transfer project ownership Public Projects Guide - Make projects publicly accessible Instance Management Guide - Share LLM service instances Troubleshooting# Cannot Share Project# Error: \u0026ldquo;Only the owner can share projects\u0026rdquo;\nSolution: Only the project owner can manage sharing. If you need to share the project, ask the owner to add you, or consider transferring ownership.\nUser Not Found# Error: \u0026ldquo;User not found\u0026rdquo;\nSolution: The user must exist in the system before you can share a project with them. Ask the admin to create the user first.\nCannot View Shared Users List# Error: \u0026ldquo;Forbidden\u0026rdquo;\nSolution: Only the project owner can view the list of shared users. Shared users cannot see other shared users for privacy reasons.\n"},{"id":17,"href":"/dhamps-vdb/api/endpoints/projects/","title":"Projects","section":"Endpoints","content":"Projects Endpoint# Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.\nEndpoints# List User\u0026rsquo;s Projects# Get all projects owned by a user.\nEndpoint: GET /v1/projects/{username}\nAuthentication: Admin, the user themselves, or users with shared access\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;projects\u0026#34;: [ { \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } ] } Create Project# Register a new project for a user.\nEndpoint: POST /v1/projects/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Parameters:\nproject_handle (string, required): Unique project identifier within the user\u0026rsquo;s namespace description (string, optional): Project description instance_owner (string, required): Owner of the LLM service instance instance_handle (string, required): Handle of the LLM service instance to use public_read (boolean, optional): Allow unauthenticated read access (default: false) metadataScheme (string, optional): JSON Schema for validating embedding metadata shared_with (array, optional): List of users to share the project with Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false } Get Project Information# Retrieve information about a specific project.\nEndpoint: GET /v1/projects/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } Update Project (PUT)# Create or update a project with the specified handle.\nEndpoint: PUT /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nRequest Body: Same as POST endpoint\nExample:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34; }\u0026#39; Delete Project# Delete a project and all its embeddings.\nEndpoint: DELETE /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project alice/research-docs deleted successfully\u0026#34; }⚠️ Warning: This operation is irreversible and will delete all embeddings in the project.\nPartial Update (PATCH)# Update specific project fields without providing all data.\nEndpoint: PATCH /v1/projects/{username}/{projectname}\nAuthentication: Admin or the owner\nExample - Enable public read access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Example - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34; }\u0026#39;See PATCH Updates for more details.\nProject Sharing# Share Project# Share a project with another user, granting them read or edit access.\nEndpoint: POST /v1/projects/{owner}/{project}/share\nAuthentication: Admin or the project owner\nRequest Body:\n{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Roles:\nreader: Read-only access to embeddings and similarity search editor: Read and write access to embeddings Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-docs/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project shared successfully\u0026#34;, \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;shared_with\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } Unshare Project# Remove a user\u0026rsquo;s access to a shared project.\nEndpoint: DELETE /v1/projects/{owner}/{project}/share/{user_handle}\nAuthentication: Admin or the project owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/research-docs/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project unshared successfully\u0026#34;, \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;removed_user\u0026#34;: \u0026#34;bob\u0026#34; } List Shared Users# Get a list of users the project is shared with.\nEndpoint: GET /v1/projects/{owner}/{project}/shared-with\nAuthentication: Admin or the project owner\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/research-docs/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;project\u0026#34;: \u0026#34;alice/research-docs\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }Note: Only the project owner can view this list. Users with shared access cannot see who else has access.\nProject Ownership Transfer# Transfer Ownership# Transfer ownership of a project to another user.\nEndpoint: POST /v1/projects/{owner}/{project}/transfer-ownership\nAuthentication: Admin or the project owner\nRequest Body:\n{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-docs/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project ownership transferred successfully\u0026#34;, \u0026#34;old_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;new_owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;new_path\u0026#34;: \u0026#34;/v1/projects/bob/research-docs\u0026#34; }Important Notes:\nOnly the current owner can transfer ownership The new owner must be an existing user The new owner cannot already have a project with the same handle After transfer, the old owner loses all access to the project All embeddings and project data remain intact Query Parameters# List Projects# When listing projects, the following query parameters are available:\nlimit (integer, default: 10, max: 200): Maximum number of results to return offset (integer, default: 0): Pagination offset Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice?limit=20\u0026amp;offset=40\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Project Properties# Field Type Required Description project_handle string Yes Unique identifier within user\u0026rsquo;s namespace owner string Read-only Project owner\u0026rsquo;s user handle description string No Project description instance_owner string Yes Owner of the LLM service instance instance_handle string Yes Handle of the LLM service instance instance_id integer Read-only Internal ID of the LLM service instance public_read boolean No Allow unauthenticated read access metadataScheme string No JSON Schema for metadata validation created_at timestamp Read-only Project creation timestamp Metadata Schema Validation# Projects can define a JSON Schema to validate metadata attached to embeddings. See the main README for examples.\nExample Schema:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }When uploading embeddings, metadata will be validated against this schema. Invalid metadata will result in a 400 Bad Request error.\nCommon Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Project must have instance_id\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify this project\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; already exists\u0026#34; } Related Documentation# LLM Services - Managing LLM service instances Embeddings - Adding and retrieving embeddings Similars - Similarity search Public Access - Public project configuration "},{"id":18,"href":"/dhamps-vdb/concepts/users-and-auth/","title":"Users and Authentication","section":"Concepts","content":"Users and Authentication# dhamps-vdb uses token-based authentication with API keys for all operations.\nUser Model# User Properties# user_handle: Unique identifier (3-20 characters, alphanumeric + underscore) name: Full name (optional) email: Email address (unique, required) vdb_key: API key (SHA-256 hash, 64 characters) created_at: Timestamp of creation updated_at: Timestamp of last update Special Users# _system User\nCreated automatically during database migration Owns system-wide LLM service definitions Cannot be used for authentication Provides default configurations for all users Authentication Flow# API Key Authentication# All requests (except public endpoints) require authentication:\nGET /v1/projects/alice/my-project Authorization: Bearer 024v2013621509245f2e24...Authentication Process# Client sends API key in Authorization header with Bearer prefix Server extracts key and looks up user in database If user found, request proceeds with user context If not found or missing, returns 401 Unauthorized Admin Authentication# Administrative operations require the admin API key:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;,\u0026#34;email\u0026#34;:\u0026#34;alice@example.com\u0026#34;}\u0026#39;Admin key is set via SERVICE_ADMINKEY environment variable.\nUser Creation# By Admin# Only admin users can create new users:\nPOST /v1/users Authorization: Bearer ADMIN_KEY { \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34; }Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34;, \u0026#34;vdb_key\u0026#34;: \u0026#34;024v2013621509245f2e24abcdef...\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; }Important: Save the vdb_key immediately - it cannot be recovered later.\nUser Handle Restrictions# Must be 3-20 characters Alphanumeric characters and underscores only Must be unique Cannot be _system User Management# Retrieve User Information# Users can view their own information:\nGET /v1/users/alice Authorization: Bearer alice_vdb_keyAdmins can view any user:\nGET /v1/users/alice Authorization: Bearer ADMIN_KEYList All Users# Only admins can list all users:\nGET /v1/users Authorization: Bearer ADMIN_KEYReturns array of user handles (not full user objects).\nUpdate User# Users can update their own information:\nPATCH /v1/users/alice Authorization: Bearer alice_vdb_key { \u0026#34;name\u0026#34;: \u0026#34;Alice Smith-Jones\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.smith@example.com\u0026#34; }Delete User# Users can delete their own account:\nDELETE /v1/users/alice Authorization: Bearer alice_vdb_keyAdmins can delete any user:\nDELETE /v1/users/alice Authorization: Bearer ADMIN_KEYCascading Deletion:\nAll user\u0026rsquo;s projects are deleted All user\u0026rsquo;s LLM service instances are deleted All embeddings in user\u0026rsquo;s projects are deleted Sharing grants from this user to others are removed Authorization Model# Resource Ownership# Users own three types of resources:\nProjects: Collections of embeddings LLM Service Instances: Embedding configurations with API keys LLM Service Definitions: Reusable configuration templates (optional) Access Levels# Owner\nFull control over resource Can read, write, delete Can share with others Can transfer ownership (projects only) Editor (via sharing)\nRead and write access Cannot delete resource Cannot modify sharing Cannot change project settings Reader (via sharing)\nRead-only access Can view embeddings Can search for similar documents Cannot modify anything Public (if project.public_read = true)\nUnauthenticated read access Can view embeddings Can search for similar documents Cannot write or modify Security Best Practices# API Key Management# Storage\nStore API keys securely (e.g., environment variables, secret managers) Never commit API keys to version control Use different keys for development and production Rotation\nCurrently, API keys cannot be rotated To change a key, delete and recreate the user Plan key rotation strategy before production deployment Transmission\nAlways use HTTPS in production API keys are transmitted in Authorization header Never pass API keys in URL query parameters User Key vs. LLM API Keys# dhamps-vdb handles two types of keys:\nUser API keys (vdb_key): Authenticate users to dhamps-vdb\nStored as SHA-256 hash in database Never encrypted (one-way hash) Returned only once on user creation LLM API keys (api_key_encrypted): Authenticate to LLM services\nStored encrypted (AES-256-GCM) in database Never returned in API responses Used internally for LLM processing Multi-User Workflows# Collaboration Pattern# Admin creates user accounts for team members Project Owner creates project with embeddings Owner shares project with collaborators Readers can search and view embeddings Editors can add/modify embeddings Organization Pattern# Admin creates organizational users Each user creates LLM service instances with their own API keys Users create projects using their instances Projects shared within organization as needed Public Access Pattern# User creates project with research data User sets public_read: true Anyone can access embeddings and search without authentication Only owner can modify project User Limits# Current Implementation# No enforced limits on:\nNumber of projects per user Number of embeddings per project Number of LLM service instances per user Storage size per user Recommended Limits# For production deployments, consider implementing:\nRate limiting per API key Storage quotas per user Maximum project count per user Example Workflows# Create and Use User Account# # Admin creates user curl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34; }\u0026#39; # Save returned vdb_key export USER_KEY=\u0026#34;returned-vdb-key\u0026#34; # User verifies access curl -X GET http://localhost:8880/v1/users/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; # User creates project curl -X POST http://localhost:8880/v1/projects/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My research project\u0026#34; }\u0026#39;Share Resources# # User shares project with colleague curl -X POST http://localhost:8880/v1/projects/researcher1/my-project/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39; # Colleague accesses shared project curl -X GET http://localhost:8880/v1/projects/researcher1/my-project \\ -H \u0026#34;Authorization: Bearer $COLLEAGUE_KEY\u0026#34;Troubleshooting# 401 Unauthorized# Possible causes:\nMissing Authorization header Incorrect API key Expired or invalid key Using user key instead of admin key (or vice versa) Solution:\nVerify API key is correct Check Authorization header format: Bearer KEY Ensure operation matches key type (admin vs. user) 403 Forbidden# Possible causes:\nUser doesn\u0026rsquo;t own resource User not granted access to shared resource Insufficient permissions (reader trying to edit) Solution:\nVerify resource ownership Check sharing grants Ensure user has required role (editor for writes) User Creation Failed# Possible causes:\nUser handle already exists Email already registered Invalid user handle format Not using admin key Solution:\nChoose different user handle Use unique email address Check user handle format (3-20 chars, alphanumeric + underscore) Verify using admin API key Next Steps# Learn about projects Understand LLM services Explore project sharing "},{"id":19,"href":"/dhamps-vdb/development/architecture/","title":"Architecture","section":"Development","content":"Technical Architecture# This document provides a technical deep-dive into dhamps-vdb\u0026rsquo;s architecture for developers who want to understand or modify the codebase.\nProject Structure# dhamps-vdb/ ├── main.go # Application entry point ├── go.mod # Go module definition ├── go.sum # Dependency checksums ├── sqlc.yaml # sqlc configuration ├── template.env # Environment template ├── .env # Local config (gitignored) │ ├── api/ │ └── openapi.yml # OpenAPI spec (not actively maintained) │ ├── internal/ # Internal packages (non-importable) │ ├── auth/ # Authentication logic │ │ └── authenticate.go # Bearer token validation │ │ │ ├── crypto/ # Encryption utilities │ │ └── crypto.go # AES-256-GCM encryption │ │ │ ├── database/ # Database layer │ │ ├── database.go # Connection pool management │ │ ├── migrations.go # Migration runner │ │ ├── db.go # Generated by sqlc │ │ ├── models.go # Generated by sqlc │ │ ├── queries.sql.go # Generated by sqlc │ │ │ │ │ ├── migrations/ # SQL migrations │ │ │ ├── 001_create_initial_scheme.sql │ │ │ ├── 002_create_emb_index.sql │ │ │ ├── 003_add_public_read_flag.sql │ │ │ ├── 004_refactor_llm_services_architecture.sql │ │ │ ├── tern.conf.tpl # Template for tern │ │ │ └── tern.conf # Generated (gitignored) │ │ │ │ │ └── queries/ # SQL queries for sqlc │ │ └── queries.sql # All database queries │ │ │ ├── handlers/ # HTTP request handlers │ │ ├── handlers.go # Common handler utilities │ │ ├── users.go # User endpoints │ │ ├── projects.go # Project endpoints │ │ ├── llm_services.go # LLM service endpoints │ │ ├── api_standards.go # API standard endpoints │ │ ├── embeddings.go # Embedding endpoints │ │ ├── similars.go # Similarity search endpoints │ │ ├── admin.go # Admin endpoints │ │ │ │ │ └── *_test.go # Test files │ │ ├── users_test.go │ │ ├── projects_test.go │ │ ├── projects_sharing_test.go │ │ ├── embeddings_test.go │ │ ├── llm_services_test.go │ │ ├── editor_permissions_test.go │ │ └── handlers_test.go │ │ │ └── models/ # Data models and options │ ├── options.go # CLI/environment options │ ├── users.go # User models │ ├── projects.go # Project models │ ├── instances.go # LLM instance models (new) │ ├── api_standards.go # API standard models │ ├── embeddings.go # Embedding models │ ├── similars.go # Similarity search models │ └── admin.go # Admin operation models │ ├── testdata/ # Test fixtures │ ├── postgres/ # PostgreSQL test data │ │ ├── enable-vector.sql │ │ └── users.yml │ │ │ └── *.json # JSON test fixtures │ ├── valid_user.json │ ├── valid_embeddings.json │ ├── valid_api_standard_*.json │ └── valid_llm_service_*.json │ └── docs/ # Documentation ├── content/ # Hugo content └── *.md # Additional docsCode Organization# 1. Entry Point (main.go)# The application entry point handles:\nfunc main() { // 1. Parse CLI options and environment variables cli := huma.NewCLI(func(hooks huma.Hooks, opts *models.Options) { // 2. Initialize database connection pool pool := database.InitDB(opts) defer pool.Close() // 3. Run database migrations database.RunMigrations(pool, opts) // 4. Create HTTP router and Huma API router := http.NewServeMux() api := humago.New(router, huma.DefaultConfig(\u0026#34;dhamps-vdb\u0026#34;, \u0026#34;0.1.0\u0026#34;)) // 5. Register all routes handlers.AddRoutes(pool, keyGen, api) // 6. Start HTTP server server := \u0026amp;http.Server{ Addr: fmt.Sprintf(\u0026#34;%s:%d\u0026#34;, opts.Host, opts.Port), Handler: router, } server.ListenAndServe() }) cli.Run() }2. Handlers (internal/handlers/)# Handlers process HTTP requests using the Huma framework pattern:\n// Example: Create User Handler func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { // Define request/response types type CreateUserInput struct { Body models.CreateUserRequest } type CreateUserOutput struct { Body models.User } // Register operation with Huma huma.Register(api, huma.Operation{ OperationID: \u0026#34;create-user\u0026#34;, Method: http.MethodPost, Path: \u0026#34;/v1/users\u0026#34;, Summary: \u0026#34;Create a new user\u0026#34;, Description: \u0026#34;Admin only. Creates user and returns API key.\u0026#34;, Security: []map[string][]string{{\u0026#34;bearer\u0026#34;: {}}}, }, func(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error) { // 1. Get authenticated user from context authUser := auth.GetAuthenticatedUser(ctx) // 2. Check authorization (admin only) if !authUser.IsAdmin { return nil, huma.Error403Forbidden(\u0026#34;admin access required\u0026#34;) } // 3. Validate input if err := input.Body.Validate(); err != nil { return nil, huma.Error400BadRequest(\u0026#34;invalid input\u0026#34;, err) } // 4. Business logic user, apiKey, err := createUserWithKey(ctx, pool, keyGen, \u0026amp;input.Body) if err != nil { return nil, handleDatabaseError(err) } // 5. Return response return \u0026amp;CreateUserOutput{Body: *user}, nil }) }Handler file organization:\nhandlers.go - Common utilities (context keys, error handling) users.go - User CRUD operations projects.go - Project CRUD and sharing llm_services.go - LLM service/instance management embeddings.go - Embedding CRUD operations similars.go - Similarity search admin.go - Administrative operations 3. Models (internal/models/)# Models define request/response structures:\n// User model type User struct { UserHandle string `json:\u0026#34;user_handle\u0026#34; example:\u0026#34;alice\u0026#34;` Name string `json:\u0026#34;name\u0026#34; example:\u0026#34;Alice Smith\u0026#34;` Email string `json:\u0026#34;email\u0026#34; example:\u0026#34;alice@example.com\u0026#34;` CreatedAt time.Time `json:\u0026#34;created_at\u0026#34;` UpdatedAt time.Time `json:\u0026#34;updated_at\u0026#34;` } // Request model with validation type CreateUserRequest struct { UserHandle string `json:\u0026#34;user_handle\u0026#34; minLength:\u0026#34;1\u0026#34; maxLength:\u0026#34;50\u0026#34; pattern:\u0026#34;^[a-z0-9_-]+$\u0026#34;` Name string `json:\u0026#34;name\u0026#34; minLength:\u0026#34;1\u0026#34; maxLength:\u0026#34;100\u0026#34;` Email string `json:\u0026#34;email\u0026#34; format:\u0026#34;email\u0026#34;` } func (r *CreateUserRequest) Validate() error { if r.UserHandle == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;user_handle is required\u0026#34;) } if r.UserHandle == \u0026#34;_system\u0026#34; { return fmt.Errorf(\u0026#34;_system is a reserved handle\u0026#34;) } return nil }Model conventions:\nRequest models: Create*Request, Update*Request Response models: *Response, *Output Database models: Match database schema (generated by sqlc) 4. Database Layer (internal/database/)# Connection Management (database.go)# func InitDB(opts *models.Options) *pgxpool.Pool { connString := fmt.Sprintf( \u0026#34;postgres://%s:%s@%s:%d/%s\u0026#34;, opts.DBUser, opts.DBPassword, opts.DBHost, opts.DBPort, opts.DBName, ) config, err := pgxpool.ParseConfig(connString) if err != nil { log.Fatal(err) } // Configure connection pool config.MaxConns = 20 config.MinConns = 5 config.MaxConnIdleTime = time.Minute * 5 pool, err := pgxpool.NewWithConfig(context.Background(), config) if err != nil { log.Fatal(err) } return pool }Migrations (migrations.go)# Uses tern for versioned migrations:\nfunc RunMigrations(pool *pgxpool.Pool, opts *models.Options) error { // Create tern configuration config := createTernConfig(opts) // Initialize migrator migrator, err := migrate.NewMigrator(context.Background(), pool, \u0026#34;schema_version\u0026#34;) if err != nil { return err } // Run pending migrations err = migrator.Migrate(context.Background()) if err != nil { return fmt.Errorf(\u0026#34;migration failed: %w\u0026#34;, err) } return nil }Migration files are numbered sequentially:\n-- 001_create_initial_scheme.sql CREATE TABLE users ( user_id SERIAL PRIMARY KEY, user_handle TEXT UNIQUE NOT NULL, vdb_key TEXT UNIQUE NOT NULL, ... ); CREATE TABLE projects ( project_id SERIAL PRIMARY KEY, project_handle TEXT NOT NULL, owner TEXT NOT NULL REFERENCES users(user_handle), ... ); -- 002_create_emb_index.sql CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);SQLC Queries (queries/queries.sql)# Write SQL, generate type-safe Go code:\n-- name: UpsertUser :one INSERT INTO users ( user_handle, name, email, vdb_key, created_at, updated_at ) VALUES ( $1, $2, $3, $4, NOW(), NOW() ) ON CONFLICT (user_handle) DO UPDATE SET name = EXCLUDED.name, email = EXCLUDED.email, updated_at = NOW() RETURNING *; -- name: GetUserByHandle :one SELECT * FROM users WHERE user_handle = $1; -- name: GetAllUsers :many SELECT user_handle, name, email, created_at, updated_at FROM users ORDER BY user_handle ASC; -- name: DeleteUser :exec DELETE FROM users WHERE user_handle = $1;Generated Go code (queries.sql.go):\n// Generated by sqlc func (q *Queries) UpsertUser(ctx context.Context, arg UpsertUserParams) (User, error) { row := q.db.QueryRow(ctx, upsertUser, arg.UserHandle, arg.Name, arg.Email, arg.VdbKey, ) var i User err := row.Scan( \u0026amp;i.UserID, \u0026amp;i.UserHandle, \u0026amp;i.Name, \u0026amp;i.Email, \u0026amp;i.VdbKey, \u0026amp;i.CreatedAt, \u0026amp;i.UpdatedAt, ) return i, err }sqlc configuration (sqlc.yaml):\nversion: \u0026#34;2\u0026#34; sql: - engine: \u0026#34;postgresql\u0026#34; queries: \u0026#34;internal/database/queries/queries.sql\u0026#34; schema: \u0026#34;internal/database/migrations/\u0026#34; gen: go: package: \u0026#34;database\u0026#34; out: \u0026#34;internal/database\u0026#34; emit_json_tags: true emit_db_tags: true emit_prepared_queries: false emit_interface: falseRegenerate code after query changes:\nsqlc generate --no-remote5. Authentication (internal/auth/)# Token-based authentication using Bearer tokens:\n// Middleware checks Authorization header func AuthMiddleware(pool *pgxpool.Pool, adminKey string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Extract Bearer token authHeader := r.Header.Get(\u0026#34;Authorization\u0026#34;) token := strings.TrimPrefix(authHeader, \u0026#34;Bearer \u0026#34;) if token == \u0026#34;\u0026#34; { // Allow public access for certain endpoints ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, nil) next.ServeHTTP(w, r.WithContext(ctx)) return } // Check admin key if token == adminKey { user := \u0026amp;AuthUser{Handle: \u0026#34;_admin\u0026#34;, IsAdmin: true} ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, user) next.ServeHTTP(w, r.WithContext(ctx)) return } // Look up user by API key hash hash := hashAPIKey(token) user, err := db.GetUserByKeyHash(r.Context(), pool, hash) if err != nil { http.Error(w, \u0026#34;Unauthorized\u0026#34;, http.StatusUnauthorized) return } authUser := \u0026amp;AuthUser{Handle: user.UserHandle, IsAdmin: false} ctx := context.WithValue(r.Context(), \u0026#34;user\u0026#34;, authUser) next.ServeHTTP(w, r.WithContext(ctx)) }) } } // Helper to get authenticated user from context func GetAuthenticatedUser(ctx context.Context) *AuthUser { user, _ := ctx.Value(\u0026#34;user\u0026#34;).(*AuthUser) return user }6. Encryption (internal/crypto/)# AES-256-GCM encryption for sensitive data (API keys):\n// Encrypt data with AES-256-GCM func Encrypt(plaintext []byte, key []byte) ([]byte, error) { // Ensure key is 32 bytes keyHash := sha256.Sum256(key) // Create AES cipher block, err := aes.NewCipher(keyHash[:]) if err != nil { return nil, err } // Create GCM gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } // Generate random nonce nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err } // Encrypt and append nonce ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) return ciphertext, nil } func Decrypt(ciphertext []byte, key []byte) ([]byte, error) { // Derive key keyHash := sha256.Sum256(key) block, err := aes.NewCipher(keyHash[:]) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } // Extract nonce nonceSize := gcm.NonceSize() nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] // Decrypt plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, err } return plaintext, nil }Huma Framework Integration# dhamps-vdb uses Huma for API development:\nBenefits# Automatic OpenAPI generation - No manual spec maintenance Request/response validation - Type-safe with JSON schema Error handling - Standardized error responses Documentation - Interactive docs at /docs Operation Registration Pattern# huma.Register(api, huma.Operation{ OperationID: \u0026#34;get-project\u0026#34;, Method: http.MethodGet, Path: \u0026#34;/v1/projects/{owner}/{project}\u0026#34;, Summary: \u0026#34;Get project details\u0026#34;, Description: \u0026#34;Returns full project information including metadata schema\u0026#34;, Tags: []string{\u0026#34;Projects\u0026#34;}, Security: []map[string][]string{{\u0026#34;bearer\u0026#34;: {}}}, MaxBodyBytes: 1024, // Limit request size DefaultStatus: http.StatusOK, Errors: []int{400, 401, 403, 404, 500}, }, handlerFunction)Input/Output Patterns# // Path parameters, query parameters, and body type GetSimilarInput struct { Owner string `path:\u0026#34;owner\u0026#34; doc:\u0026#34;Project owner\u0026#34;` Project string `path:\u0026#34;project\u0026#34; doc:\u0026#34;Project handle\u0026#34;` TextID string `path:\u0026#34;text_id\u0026#34; doc:\u0026#34;Text identifier\u0026#34;` Threshold float32 `query:\u0026#34;threshold\u0026#34; default:\u0026#34;0.5\u0026#34; doc:\u0026#34;Similarity threshold\u0026#34;` Limit int `query:\u0026#34;limit\u0026#34; default:\u0026#34;10\u0026#34; maximum:\u0026#34;200\u0026#34; doc:\u0026#34;Max results\u0026#34;` } // Response with status code type GetSimilarOutput struct { Status int Body models.SimilarResponse }Error Response Pattern# // Standard error responses return nil, huma.Error400BadRequest(\u0026#34;validation failed\u0026#34;, err) return nil, huma.Error401Unauthorized(\u0026#34;invalid credentials\u0026#34;) return nil, huma.Error403Forbidden(\u0026#34;insufficient permissions\u0026#34;) return nil, huma.Error404NotFound(\u0026#34;project not found\u0026#34;) return nil, huma.Error500InternalServerError(\u0026#34;database error\u0026#34;, err) // Custom error with details return nil, huma.NewError(400, \u0026#34;Dimension Mismatch\u0026#34;, fmt.Sprintf(\u0026#34;expected %d dimensions, got %d\u0026#34;, expected, actual))Design Patterns# 1. Repository Pattern (via sqlc)# Database access is centralized in generated queries:\n// Don\u0026#39;t write SQL in handlers // Bad: rows, err := pool.Query(ctx, \u0026#34;SELECT * FROM users\u0026#34;) // Good: Use generated functions users, err := db.GetAllUsers(ctx)2. Dependency Injection# Pass dependencies explicitly:\n// Inject pool into handlers func RegisterUsersRoutes(pool *pgxpool.Pool, keyGen RandomKeyGenerator, api huma.API) { // Routes have access to pool } // Store in context for handler access ctx = context.WithValue(ctx, PoolKey, pool)3. Interface-Based Testing# Use interfaces for testability:\n// Production: Real random key generator type StandardKeyGen struct{} func (s StandardKeyGen) RandomKey(len int) (string, error) { b := make([]byte, len) _, err := rand.Read(b) return hex.EncodeToString(b), err } // Testing: Deterministic key generator type MockKeyGen struct { Keys []string idx int } func (m *MockKeyGen) RandomKey(len int) (string, error) { key := m.Keys[m.idx] m.idx++ return key, nil }4. Validation at Multiple Layers# // 1. Huma validates request structure type CreateEmbeddingInput struct { Body models.Embedding `maxLength:\u0026#34;1000000\u0026#34;` } // 2. Model validates business rules func (e *Embedding) Validate() error { if e.TextID == \u0026#34;\u0026#34; { return fmt.Errorf(\u0026#34;text_id required\u0026#34;) } return nil } // 3. Handler validates against database state func CreateEmbedding(ctx context.Context, input *CreateEmbeddingInput) error { // Check project exists // Validate dimensions match LLM service // Validate metadata against schema // Then insert }5. Error Wrapping# Provide context while preserving original error:\nuser, err := db.GetUserByHandle(ctx, handle) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, huma.Error404NotFound(\u0026#34;user not found\u0026#34;) } return nil, fmt.Errorf(\u0026#34;failed to retrieve user %s: %w\u0026#34;, handle, err) }Internal Packages# Go\u0026rsquo;s internal/ directory enforces package privacy:\n// This import works within dhamps-vdb import \u0026#34;github.com/mpilhlt/dhamps-vdb/internal/database\u0026#34; // This import would FAIL from external projects // Enforced by Go compilerBenefits:\nClear API boundaries Implementation details hidden Refactoring without breaking external users Performance Considerations# Connection Pooling# config.MaxConns = 20 // Max concurrent connections config.MinConns = 5 // Keep-alive connections config.MaxConnIdleTime = 5 * time.MinuteQuery Optimization# Use UNION ALL for better performance:\n// Instead of LEFT JOIN with OR conditions query := ` SELECT * FROM projects WHERE owner = $1 UNION ALL SELECT p.* FROM projects p INNER JOIN projects_shared_with ps USING (project_id) WHERE ps.user_handle = $1 ORDER BY owner, project_handle `Index Strategy# -- Dimension filtering (very important) CREATE INDEX ON embeddings(project_id, vector_dim); -- Vector similarity (HNSW for accuracy) CREATE INDEX ON embeddings USING hnsw (vector vector_cosine_ops); -- Access lookups CREATE INDEX ON projects_shared_with(user_handle); CREATE INDEX ON projects(owner, project_handle);See Performance Guide for detailed optimization strategies.\nTesting Architecture# Test Organization# // handlers_test.go - Setup and utilities func setupTestDB(t *testing.T) *pgxpool.Pool { } func createTestUser(t *testing.T, pool *pgxpool.Pool) *models.User { } // users_test.go - User-specific tests func TestCreateUser(t *testing.T) { } func TestGetUser(t *testing.T) { } // projects_sharing_test.go - Sharing feature tests func TestShareProject(t *testing.T) { }Testcontainers Integration# func setupTestDB(t *testing.T) *pgxpool.Pool { ctx := context.Background() // Start PostgreSQL with pgvector req := testcontainers.ContainerRequest{ Image: \u0026#34;pgvector/pgvector:0.7.4-pg16\u0026#34;, ExposedPorts: []string{\u0026#34;5432/tcp\u0026#34;}, Env: map[string]string{ \u0026#34;POSTGRES_PASSWORD\u0026#34;: \u0026#34;password\u0026#34;, \u0026#34;POSTGRES_DB\u0026#34;: \u0026#34;testdb\u0026#34;, }, } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) require.NoError(t, err) // Connect and migrate pool := connectAndMigrate(ctx, container) return pool }See Testing Guide for comprehensive testing documentation.\nBuild and Deployment# Building# # Development build go build -o dhamps-vdb main.go # Production build with optimizations go build -ldflags=\u0026#34;-s -w\u0026#34; -o dhamps-vdb main.go # Cross-compilation GOOS=linux GOARCH=amd64 go build -o dhamps-vdb-linux main.goDocker Build# Multi-stage build for minimal image:\n# Build stage FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o dhamps-vdb main.go # Runtime stage FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/dhamps-vdb . EXPOSE 8880 CMD [\u0026#34;./dhamps-vdb\u0026#34;]Configuration# Application reads configuration from:\nCommand line flags: --port 8080 Environment variables: SERVICE_PORT=8080 .env file: SERVICE_PORT=8080 Priority: CLI flags \u0026gt; Environment \u0026gt; .env file \u0026gt; Defaults\nNext Steps# Testing Guide - Learn how to test changes Contributing Guide - Start contributing Performance Guide - Optimize queries and indexes "},{"id":20,"href":"/dhamps-vdb/deployment/environment-variables/","title":"Environment Variables","section":"Deployment","content":"Environment Variables# Complete reference for all environment variables used by dhamps-vdb.\nOverview# dhamps-vdb is configured entirely through environment variables. These can be set:\nIn a .env file (recommended for Docker) As system environment variables Via command-line flags (some variables only) Required Variables# These variables must be set for dhamps-vdb to function:\nSERVICE_ADMINKEY# Admin API key for administrative operations.\nType: String Required: Yes Default: None Environment Variable: SERVICE_ADMINKEY Command-line Flag: --admin-key Description: Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.\nExample:\nSERVICE_ADMINKEY=Ch4ngeM3SecureAdminKey!Security:\nGenerate with: openssl rand -base64 32 Never commit to version control Rotate regularly Store securely (password manager, secrets vault) Usage:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $SERVICE_ADMINKEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;full_name\u0026#34;: \u0026#34;Alice Smith\u0026#34;}\u0026#39;ENCRYPTION_KEY# Encryption key for protecting user API keys in the database.\nType: String (32+ characters) Required: Yes Default: None Environment Variable: ENCRYPTION_KEY Description: AES-256 encryption key used to encrypt user API keys before storing them in the database. Must be at least 32 characters. The key is hashed with SHA-256 to ensure exactly 32 bytes for AES-256 encryption.\nExample:\nENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6Security:\nGenerate with: openssl rand -hex 32 Minimum 32 characters required Never commit to version control CRITICAL: If lost, all stored API keys become unrecoverable Backup securely and separately from database Never change in production (will invalidate all existing API keys) Technical Details:\nUses AES-256-GCM for encryption SHA-256 hash ensures correct key length Each encryption uses unique nonce Encrypted keys stored as base64 in database Optional Variables# SERVICE_DEBUG# Enable debug logging.\nType: Boolean Required: No Default: true Environment Variable: SERVICE_DEBUG Command-line Flag: -d, --debug Description: Enables verbose debug logging including request details, SQL queries, and internal operations.\nExample:\nSERVICE_DEBUG=false # Production (less verbose) SERVICE_DEBUG=true # Development (verbose)Impact:\ntrue: Detailed logs, useful for debugging false: Minimal logs, recommended for production SERVICE_HOST# Hostname or IP address to bind the service to.\nType: String Required: No Default: localhost Environment Variable: SERVICE_HOST Command-line Flag: --host Description: Network interface to listen on. Use 0.0.0.0 to listen on all interfaces (required for Docker).\nExamples:\nSERVICE_HOST=localhost # Local development only SERVICE_HOST=0.0.0.0 # Listen on all interfaces (Docker) SERVICE_HOST=10.0.1.5 # Specific interfaceSecurity:\nUse localhost for development Use 0.0.0.0 for Docker/production with firewall Never expose directly to internet without reverse proxy SERVICE_PORT# Port number for the API service.\nType: Integer Required: No Default: 8880 Environment Variable: SERVICE_PORT Command-line Flag: -p, --port Description: TCP port the service listens on.\nExample:\nSERVICE_PORT=8880 # Default SERVICE_PORT=8080 # Alternative SERVICE_PORT=3000 # CustomNotes:\nPorts below 1024 require root/admin privileges Ensure port is not already in use Update firewall rules accordingly Database Variables# SERVICE_DBHOST# Database hostname or IP address.\nType: String Required: No Default: localhost Environment Variable: SERVICE_DBHOST Command-line Flag: --db-host Description: PostgreSQL server hostname.\nExamples:\nSERVICE_DBHOST=localhost # Local PostgreSQL SERVICE_DBHOST=postgres # Docker Compose service name SERVICE_DBHOST=db.example.com # Remote database SERVICE_DBHOST=10.0.1.100 # Database IP addressSERVICE_DBPORT# Database port number.\nType: Integer Required: No Default: 5432 Environment Variable: SERVICE_DBPORT Command-line Flag: --db-port Description: PostgreSQL server port.\nExample:\nSERVICE_DBPORT=5432 # Default PostgreSQL port SERVICE_DBPORT=5433 # Alternative portSERVICE_DBUSER# Database username.\nType: String Required: No Default: postgres Environment Variable: SERVICE_DBUSER Command-line Flag: --db-user Description: PostgreSQL user for database connections.\nExample:\nSERVICE_DBUSER=postgres # Default superuser SERVICE_DBUSER=dhamps_user # Dedicated user (recommended)Security:\nCreate dedicated user (not superuser) for production Use principle of least privilege See Database Setup for user creation SERVICE_DBPASSWORD# Database password.\nType: String Required: No Default: password Environment Variable: SERVICE_DBPASSWORD Command-line Flag: --db-password Description: Password for database authentication.\nExample:\nSERVICE_DBPASSWORD=secure_database_password_hereSecurity:\nUse strong, randomly generated password Never use default password in production Never commit to version control Store in secrets management system Rotate regularly SERVICE_DBNAME# Database name.\nType: String Required: No Default: postgres Environment Variable: SERVICE_DBNAME Command-line Flag: --db-name Description: Name of the PostgreSQL database.\nExample:\nSERVICE_DBNAME=dhamps_vdb # Production database SERVICE_DBNAME=dhamps_test # Testing databaseConfiguration Examples# Development Setup# # .env file for development SERVICE_DEBUG=true SERVICE_HOST=localhost SERVICE_PORT=8880 SERVICE_DBHOST=localhost SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=postgres SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=dev-admin-key-not-for-production ENCRYPTION_KEY=dev-encryption-key-min-32-chars-longDocker Compose Setup# # .env file for Docker Compose SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=postgres SERVICE_DBPORT=5432 SERVICE_DBUSER=postgres SERVICE_DBPASSWORD=secure_db_password_here SERVICE_DBNAME=dhamps_vdb SERVICE_ADMINKEY=generated_admin_key_from_setup_script ENCRYPTION_KEY=generated_encryption_key_from_setup_scriptProduction Setup# # .env file for production (or use secrets management) SERVICE_DEBUG=false SERVICE_HOST=0.0.0.0 SERVICE_PORT=8880 SERVICE_DBHOST=db.internal.example.com SERVICE_DBPORT=5432 SERVICE_DBUSER=dhamps_prod_user SERVICE_DBPASSWORD=\u0026lt;from-secrets-manager\u0026gt; SERVICE_DBNAME=dhamps_vdb_prod SERVICE_ADMINKEY=\u0026lt;from-secrets-manager\u0026gt; ENCRYPTION_KEY=\u0026lt;from-secrets-manager\u0026gt;Setting Environment Variables# Using .env File (Recommended)# Create a .env file in the project root:\n# Copy template cp template.env .env # Edit with your values nano .envThe application automatically loads .env on startup.\nUsing System Environment Variables# # Linux/macOS export SERVICE_ADMINKEY=\u0026#34;your-admin-key\u0026#34; export ENCRYPTION_KEY=\u0026#34;your-encryption-key\u0026#34; # Windows PowerShell $env:SERVICE_ADMINKEY = \u0026#34;your-admin-key\u0026#34; $env:ENCRYPTION_KEY = \u0026#34;your-encryption-key\u0026#34; # Windows Command Prompt set SERVICE_ADMINKEY=your-admin-key set ENCRYPTION_KEY=your-encryption-keyUsing Docker# With docker run:\ndocker run -d \\ -e SERVICE_ADMINKEY=admin-key \\ -e ENCRYPTION_KEY=encryption-key \\ -e SERVICE_DBHOST=db-host \\ dhamps-vdb:latestWith docker-compose.yml:\nservices: dhamps-vdb: image: dhamps-vdb:latest environment: SERVICE_DEBUG: \u0026#34;false\u0026#34; SERVICE_HOST: \u0026#34;0.0.0.0\u0026#34; SERVICE_PORT: \u0026#34;8880\u0026#34; SERVICE_DBHOST: \u0026#34;postgres\u0026#34; env_file: - .env # Load additional variables from fileUsing Command-Line Flags# Some variables support command-line flags:\n./dhamps-vdb \\ --debug \\ --host 0.0.0.0 \\ --port 8880 \\ --admin-key your-admin-key \\ --db-host localhost \\ --db-port 5432 \\ --db-user postgres \\ --db-password password \\ --db-name dhamps_vdbNote: ENCRYPTION_KEY must be set as environment variable, not flag.\nValidation and Troubleshooting# Missing Required Variables# If required variables are not set, the service will fail to start:\nError: SERVICE_ADMINKEY environment variable is not setSolution: Set the missing variable.\nInvalid ENCRYPTION_KEY# If ENCRYPTION_KEY is too short or invalid:\nError: ENCRYPTION_KEY environment variable is not setSolution: Ensure key is at least 32 characters:\nopenssl rand -hex 32Database Connection Failure# Error: failed to connect to databaseCheck:\nSERVICE_DBHOST is correct and reachable SERVICE_DBPORT is correct SERVICE_DBUSER and SERVICE_DBPASSWORD are valid SERVICE_DBNAME exists PostgreSQL is running Firewall allows connection Testing Configuration# # Start service with debug logging SERVICE_DEBUG=true ./dhamps-vdb # Check if service starts successfully curl http://localhost:8880/docs # Test admin authentication curl -X GET http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer $SERVICE_ADMINKEY\u0026#34;Security Best Practices# Never commit .env files to version control\nAlready in .gitignore Use .env.example templates Generate secure random keys\nopenssl rand -base64 32 # Admin key openssl rand -hex 32 # Encryption key Use secrets management in production\nHashiCorp Vault AWS Secrets Manager Azure Key Vault Docker Secrets (Swarm) Kubernetes Secrets Rotate keys regularly\nAdmin key: Every 90 days Database password: Every 90 days Encryption key: Cannot be rotated without re-encrypting all API keys Principle of least privilege\nUse dedicated database user (not superuser) Grant only necessary permissions Restrict network access Monitor and audit\nLog admin key usage Monitor failed authentication attempts Review access patterns Further Reading# Docker Deployment Guide Database Setup Security Best Practices Configuration Guide Quick Start "},{"id":21,"href":"/dhamps-vdb/guides/","title":"Guides","section":"dhamps-vdb Documentation","content":"User Guides# Step-by-step guides for common tasks and workflows with dhamps-vdb.\nAvailable Guides# This section contains practical guides for using dhamps-vdb in real-world scenarios:\nRAG Workflows - Implement Retrieval Augmented Generation Project Sharing - Collaborate with other users Public Projects - Enable unauthenticated access Ownership Transfer - Move projects between users Metadata Validation - Ensure data quality with schemas Metadata Filtering - Exclude documents from similarity search Batch Operations - Work with multiple embeddings efficiently Instance Management - Configure LLM service instances These guides complement the API reference by providing context and best practices for common use cases.\n"},{"id":22,"href":"/dhamps-vdb/api/endpoints/llm-services/","title":"LLM Services","section":"Endpoints","content":"LLM Services Endpoint# Manage LLM service instances and definitions. The system supports two types of LLM service resources:\nDefinitions: Reusable templates owned by _system or individual users Instances: User-specific configurations with API keys that reference definitions or stand alone Architecture Overview# definitions (templates) └── owned by _system or users └── contain: endpoint, model, dimensions, api_standard └── no API keys instances (user-specific) └── owned by individual users └── reference a definition (optional) └── contain encrypted API keys └── can be shared with other usersFor complete details, see LLM Service Refactoring Documentation.\nInstance Endpoints# List User\u0026rsquo;s Instances# Get all LLM service instances owned by or shared with a user.\nEndpoint: GET /v1/llm-services/{username}\nAuthentication: Admin or the user themselves\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;definition_id\u0026#34;: 1 }, { \u0026#34;instance_id\u0026#34;: 2, \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom.api.example.com/embed\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed-v1\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ] }Note: API keys are never returned in GET responses for security.\nCreate or Update Instance (PUT)# Create a new LLM service instance or update an existing one.\nEndpoint: PUT /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the user themselves\nRequest Body (Standalone Instance):\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Request Body (From Definition):\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Parameters:\ninstance_handle (string, required): Unique identifier within user\u0026rsquo;s namespace endpoint (string, required for standalone): API endpoint URL description (string, optional): Instance description api_standard (string, required for standalone): Reference to API standard (e.g., \u0026ldquo;openai\u0026rdquo;, \u0026ldquo;cohere\u0026rdquo;) model (string, required for standalone): Model name dimensions (integer, required for standalone): Vector dimensions api_key_encrypted (string, optional): API key (encrypted if ENCRYPTION_KEY is set) definition_owner (string, optional): Owner of the definition template definition_handle (string, optional): Handle of the definition template Example - Standalone:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }\u0026#39;Example - From _system Definition:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }Security Note: API keys are encrypted using AES-256-GCM if the ENCRYPTION_KEY environment variable is set. Keys are never returned in responses.\nGet Instance Information# Retrieve information about a specific LLM service instance.\nEndpoint: GET /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin, owner, or users with shared access\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;definition_id\u0026#34;: 1 } Delete Instance# Delete an LLM service instance.\nEndpoint: DELETE /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;LLM service instance alice/openai-large deleted successfully\u0026#34; }⚠️ Warning: Cannot delete instances that are in use by projects.\nPartial Update (PATCH)# Update specific instance fields without providing all data.\nEndpoint: PATCH /v1/llm-services/{username}/{instance_handle}\nAuthentication: Admin or the owner\nExample - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }\u0026#39;See PATCH Updates for more details.\nInstance Sharing# Share Instance# Share an LLM service instance with another user.\nEndpoint: POST /v1/llm-services/{owner}/{instance}/share\nAuthentication: Admin or the instance owner\nRequest Body:\n{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Roles:\nreader: Can use the instance but cannot see API keys editor: Can use the instance (owner can still modify) owner: Full control (cannot be granted via sharing) Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Important: Shared users can USE the instance but cannot see the API key.\nUnshare Instance# Remove a user\u0026rsquo;s access to a shared instance.\nEndpoint: DELETE /v1/llm-services/{owner}/{instance}/share/{user_handle}\nAuthentication: Admin or the instance owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; List Shared Users# Get a list of users the instance is shared with.\nEndpoint: GET /v1/llm-services/{owner}/{instance}/shared-with\nAuthentication: Admin or the instance owner\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance\u0026#34;: \u0026#34;alice/openai-large\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] } Definition Endpoints# List System Definitions# Get all LLM service definitions owned by _system.\nEndpoint: GET /v1/llm-service-definitions/_system\nAuthentication: Any authenticated user\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-service-definitions/_system\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;definitions\u0026#34;: [ { \u0026#34;definition_id\u0026#34;: 1, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI text-embedding-3-large\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }, { \u0026#34;definition_id\u0026#34;: 2, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI text-embedding-3-small\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-small\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ] }Pre-seeded System Definitions:\nopenai-large: OpenAI text-embedding-3-large (3072 dimensions) openai-small: OpenAI text-embedding-3-small (1536 dimensions) cohere-v4: Cohere embed-english-v4.0 (1536 dimensions) gemini-embedding-001: Google Gemini embedding-001 (768 dimensions) Create User Definition# Create a reusable LLM service definition template.\nEndpoint: POST /v1/llm-service-definitions/{username}\nAuthentication: Admin or the user themselves\nRequest Body:\n{ \u0026#34;definition_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom.api.example.com/embed\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom embedding model\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed-v1\u0026#34;, \u0026#34;dimensions\u0026#34;: 1024 }Note: Only admin users can create _system definitions.\nInstance Properties# Field Type Required Description instance_handle string Yes Unique identifier within user\u0026rsquo;s namespace owner string Read-only Instance owner\u0026rsquo;s user handle endpoint string Yes* API endpoint URL description string No Instance description api_standard string Yes* Reference to API standard model string Yes* Model name dimensions integer Yes* Vector dimensions api_key_encrypted string Write-only API key (never returned) definition_id integer Read-only Reference to definition template * Required for standalone instances; inherited from definition if using template\nSecurity Features# API Key Encryption# Algorithm: AES-256-GCM Key Source: ENCRYPTION_KEY environment variable Storage: Encrypted in api_key_encrypted column Retrieval: Never returned in API responses API Key Protection# API keys are write-only:\nProvided during instance creation/update Encrypted before storage Never returned in GET/list responses Shared users cannot see API keys Shared Instance Access# When an instance is shared:\nShared users can USE the instance for projects Shared users CANNOT see the API key Shared users CANNOT modify the instance Only owner can manage sharing Common Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Instance must specify either all configuration fields or reference a definition\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create _system definitions\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;LLM service instance \u0026#39;alice/openai-large\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete instance: in use by 3 projects\u0026#34; } Related Documentation# API Standards - Managing API standard definitions Projects - Projects require an LLM service instance LLM Service Refactoring - Complete architecture documentation "},{"id":23,"href":"/dhamps-vdb/reference/roadmap/","title":"Product Roadmap","section":"Reference","content":"Product Roadmap# Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.\nOverview# This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.\nCompleted Features# Core Functionality# User authentication \u0026amp; restrictions on some API calls\nBearer token authentication Role-based access control Admin vs user permissions API versioning\nVersion 1 API with /v1/ prefix Backward compatibility support Better options handling\nCommand-line flags via Huma CLI Environment variable configuration .env file support Handle metadata\nJSONB storage for flexible metadata Metadata attached to embeddings Validation with metadata schema\nJSON Schema validation for embedding metadata Project-level schema definitions Automatic validation on upload Filter similar passages by metadata field\nMetadata-based filtering in similarity queries Exclude documents by metadata value Query parameters: metadata_path and metadata_value Data Management# Use transactions\nAtomic operations for multi-step actions Consistency for project creation with sharing Rollback on errors Catch POST to existing resources\nPrevent duplicate creation Return appropriate error codes Suggest using PUT for updates Always use specific error messages\nDetailed error descriptions Helpful troubleshooting information Consistent error response format Testing \u0026amp; Quality# Tests\nIntegration tests for all major operations Testcontainers for isolated database testing Cleanup verification queries When testing, check cleanup by adding a new query/function to see if all tables are empty\nVerify test isolation Ensure no data leakage between tests Make sure input is validated consistently\nDimension validation for embeddings Schema validation for metadata Request validation via Huma Collaboration Features# Add project sharing/unsharing functions \u0026amp; API paths\nShare projects with specific users Define roles: owner, editor, reader API endpoints for managing sharing Add mechanism to allow anonymous/public reading access to embeddings\npublic_read flag on projects Wildcard sharing via \u0026quot;*\u0026quot; in shared_with Unauthenticated access to public embeddings Transfer of projects from one owner to another as new operation\nOwner-initiated project transfers Ownership verification Automatic cleanup of old owner associations Service Architecture# Add definition creation/listing/deletion functions \u0026amp; paths LLM service definitions (templates) Instances (user-specific configurations) System-provided global definitions Deployment \u0026amp; Operations# Dockerization\nMulti-stage Dockerfile Docker Compose with PostgreSQL External database support Automated setup script Make sure pagination is supported consistently\nLimit and offset parameters Consistent across all list endpoints Documented pagination behavior Security# Prevent acceptance of requests as user \u0026ldquo;_system\u0026rdquo; Reserved system user for internal use Blocked from external authentication Protected system-owned resources In Progress# Documentation# Revisit all documentation\nComprehensive reference documentation Updated API examples Docker deployment guides Add documentation for metadata filtering of similars\nDocument metadata_path and metadata_value parameters Provide usage examples Explain use cases (exclude same author, etc.) Note: Query parameters are: metadata_path and metadata_value as in: https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7\u0026amp;limit=5\u0026amp;metadata_path=author_id\u0026amp;metadata_value=A0083 Planned Features# High Priority# Network Connectivity# Implement and make consequent use of max_idle (5), max_concurr (5), timeouts, and cancellations\nConnection pool management Maximum idle connections: 5 Maximum concurrent connections: 5 Request timeouts Context cancellation support Concurrency (leaky bucket approach) and Rate limiting\nLeaky bucket algorithm for concurrency control Rate limiting using Redis Sliding window implementation Standard rate limit headers See Huma request limits for implementation Caching\nResponse caching for frequently accessed data Cache invalidation strategies Redis or in-memory caching Configurable TTL API Standards# Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio Anthropic embeddings API Mistral embeddings API llama.cpp server API Ollama embeddings API vLLM embeddings API LM Studio embeddings API Standard authentication methods Example definitions in testdata Medium Priority# User Experience# HTML UI\nWeb-based interface for API management User-friendly project creation Visual embedding explorer API key management Alternative to CLI/API usage Allow to request verbose information even in list outputs\nverbose=yes query parameter Full object details in list endpoints Optional vs default minimal output Performance considerations Add possibility to use PATCH method to change existing resources\nPartial updates without full replacement PATCH support for users, projects, instances Merge semantics for nested objects Validation of partial updates Status: Partially implemented via automatic PATCH handler Logging and Monitoring# Proper logging with --verbose and --quiet modes Structured logging (JSON format) Log levels: ERROR, WARN, INFO, DEBUG, TRACE --verbose flag for detailed logs --quiet flag for minimal logs Request/response logging Performance metrics logging Integration with log aggregation systems Future Enhancements# Advanced Features# Bulk Operations\nBatch embedding upload Bulk deletion Transaction support for large operations Advanced Search\nCombined vector + metadata filtering Hybrid search (vector + keyword) Multi-vector search Weighted search results Embeddings Management\nUpdate embeddings in place Re-embedding workflows Embedding versioning Dimension conversion utilities Performance# Query Optimization\nQuery plan analysis Index optimization Materialized views for common queries Database connection pooling improvements Scaling\nHorizontal scaling support Read replicas for query load Partitioning strategies for large datasets Distributed vector search Security \u0026amp; Access Control# Fine-grained Permissions\nCustom roles beyond owner/editor/reader Permission inheritance Temporary access grants IP-based access control Audit Logging\nTrack all API operations User action history Security event logging Compliance reporting OAuth/SAML Integration\nOAuth 2.0 authentication SAML SSO support Identity provider integration External authentication services Integration# Webhooks\nEvent notifications for embeddings changes Project updates notifications Configurable webhook endpoints Retry logic and delivery guarantees Export/Import\nProject export to standard formats Bulk embedding export Import from other vector databases Migration utilities SDK Support\nPython SDK JavaScript/TypeScript SDK Go SDK CLI improvements Development Process# Release Cycle# Minor versions (0.x.0): New features, API additions Patch versions (0.0.x): Bug fixes, documentation updates Major versions (x.0.0): Breaking API changes (future) Feature Requests# To request a feature or suggest improvements:\nCheck existing issues on GitHub Open a new issue with: Clear description of the feature Use cases and motivation Proposed implementation (if any) Engage in discussion with maintainers Contribution Guidelines# Contributions are welcome! See the main repository for:\nDevelopment setup instructions Code style guidelines Testing requirements Pull request process Version History# v0.1.0 (2026-02-08)# Fix many things Add many things Still API v1 on the way to stable v0.0.1 (2024-12-10)# Initial public release API v1 (work in progress) Core functionality implemented Docker support Project sharing Metadata validation Feedback# We value your feedback! Please share:\nFeature requests - What would make dhamps-vdb more useful? Bug reports - Help us improve quality Use cases - How are you using dhamps-vdb? Documentation - What needs clarification? Open an issue on GitHub or contact the maintainers directly.\nRelated Documentation# Getting Started API Documentation Deployment Guide Reference - Configuration Reference - Database Schema GitHub Repository "},{"id":24,"href":"/dhamps-vdb/concepts/projects/","title":"Projects","section":"Concepts","content":"Projects# Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.\nWhat is a Project?# A project is a collection of document embeddings that share:\nA single LLM service instance (embedding configuration) Optional metadata schema for validation Access control (ownership and sharing) Consistent vector dimensions Project Properties# Core Fields# project_handle: Unique identifier within owner\u0026rsquo;s namespace (3-20 characters) owner: User who owns the project description: Human-readable project description instance_id: Reference to LLM service instance (required, 1:1 relationship) metadataScheme: Optional JSON Schema for metadata validation public_read: Boolean flag for public read access created_at: Creation timestamp updated_at: Last modification timestamp Unique Constraints# Projects are uniquely identified by (owner, project_handle):\nUser \u0026ldquo;alice\u0026rdquo; can have project \u0026ldquo;research\u0026rdquo; User \u0026ldquo;bob\u0026rdquo; can also have project \u0026ldquo;research\u0026rdquo; Same user cannot have two projects with same handle Creating Projects# Basic Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;literature-study\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary text analysis\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }Project with Metadata Schema# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;research-papers\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Academic papers with structured metadata\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;doi\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }Public Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;open-dataset\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible research data\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;public_read\u0026#34;: true }Shared Project# POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Team collaboration project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Project-Instance Relationship# One-to-One Constraint# Each project references exactly one LLM service instance:\nProject → Instance (1:1) ├── Defines vector dimensions ├── Specifies embedding model └── Contains API configurationWhy 1:1?\nEnsures consistent dimensions across all embeddings Prevents dimension mismatches in similarity searches Simplifies validation and error handling Specifying Instance# Use owner and handle to reference an instance:\n{ \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }The instance can be:\nOwned by project owner: \u0026quot;instance_owner\u0026quot;: \u0026quot;alice\u0026quot; Shared with project owner: \u0026quot;instance_owner\u0026quot;: \u0026quot;bob\u0026quot; (if bob shared with alice) Metadata Schemas# Purpose# Metadata schemas ensure consistent, structured metadata across all embeddings in a project.\nSchema Format# Use JSON Schema (draft-07 or later):\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1000, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;fiction\u0026#34;, \u0026#34;non-fiction\u0026#34;, \u0026#34;poetry\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;, \u0026#34;title\u0026#34;, \u0026#34;year\u0026#34;] }Validation Behavior# With schema: All embeddings validated on upload Without schema: Any JSON metadata accepted Validation failure: Upload rejected with detailed error Schema updates: Only apply to new/updated embeddings Example Schemas# See Metadata Validation Guide for detailed examples.\nAccess Control# Ownership# Owner: User who created the project Full control: Read, write, delete, share, transfer Cannot be removed: Owner always has access Sharing# Projects can be shared with specific users:\nReader Role\nView embeddings Search for similar documents View project metadata Cannot modify anything Editor Role\nAll reader permissions Add embeddings Modify embeddings Delete embeddings Cannot delete project or change settings Managing Sharing:\n# Share with user POST /v1/projects/alice/my-project/share { \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } # Unshare from user DELETE /v1/projects/alice/my-project/share/bob # List shared users GET /v1/projects/alice/my-project/shared-withPublic Access# Projects can allow unauthenticated read access:\nPATCH /v1/projects/alice/my-project { \u0026#34;public_read\u0026#34;: true }With public_read: true:\nAnyone can view embeddings (no authentication) Anyone can search for similar documents Write operations still require authentication See Public Projects Guide for details.\nProject Operations# List Projects# List all projects owned by a user:\nGET /v1/projects/alice Authorization: Bearer alice_vdb_keyReturns array of project objects.\nGet Project Details# GET /v1/projects/alice/research Authorization: Bearer alice_vdb_keyReturns full project object including:\nConfiguration Instance reference Metadata schema Sharing information (owner only) Update Project# Use PATCH for partial updates:\nPATCH /v1/projects/alice/research { \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }Use PUT for full replacement:\nPUT /v1/projects/alice/research { \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Complete project configuration\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...}\u0026#34; }Delete Project# DELETE /v1/projects/alice/research Authorization: Bearer alice_vdb_keyCascading deletion:\nAll embeddings in project deleted All sharing grants removed Project metadata removed Ownership Transfer# Transfer project to another user:\nPOST /v1/projects/alice/research/transfer-ownership { \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }Effects:\nProject owner changes to bob Project URL changes: /v1/projects/bob/research Alice loses all access (unless re-shared) All embeddings transferred Bob cannot already have project with same handle See Ownership Transfer Guide for details.\nProject Limits# Current Implementation# No enforced limits on:\nNumber of embeddings per project Project storage size Number of shared users Recommended Practices# For large projects:\nUse pagination when listing embeddings Batch upload embeddings Monitor database size Consider archiving old projects Common Patterns# Research Project Workflow# # 1. Create project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;study-2024\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;2024 Research Study\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34; } # 2. Upload data POST /v1/embeddings/alice/study-2024 { ... embeddings ... } # 3. Share with team POST /v1/projects/alice/study-2024/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} # 4. Make public when published PATCH /v1/projects/alice/study-2024 {\u0026#34;public_read\u0026#34;: true}Multi-Project Organization# # Development project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;dev-experiments\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;dev-embeddings\u0026#34; } # Production project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;prod-dataset\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;prod-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...}\u0026#34; } # Archive project POST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;archive-2023\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;archive-embeddings\u0026#34;, \u0026#34;public_read\u0026#34;: true }Troubleshooting# Cannot Create Project# Possible causes:\nProject handle already exists for this user Invalid project handle format Instance doesn\u0026rsquo;t exist or not accessible Missing required fields Solutions:\nChoose different project handle Verify instance exists: GET /v1/llm-services/owner Check instance is owned or shared with you Include all required fields (instance_owner, instance_handle) Metadata Validation Fails# Possible causes:\nMetadata doesn\u0026rsquo;t match schema Invalid JSON Schema format Schema too restrictive Solutions:\nTest schema with online validator Verify embedding metadata matches schema Update schema or metadata as needed Cannot Share Project# Possible causes:\nNot project owner Target user doesn\u0026rsquo;t exist Invalid role specified Solutions:\nOnly owner can share projects Verify user exists: GET /v1/users/target Use valid role: \u0026ldquo;reader\u0026rdquo; or \u0026ldquo;editor\u0026rdquo; Next Steps# Learn about embeddings Explore metadata validation Understand project sharing "},{"id":25,"href":"/dhamps-vdb/guides/public-projects/","title":"Public Projects Guide","section":"Guides","content":"Public Projects Guide# This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.\nOverview# Projects can be configured to allow unauthenticated (public) read access by setting the public_read field to true. This is useful for:\nOpen datasets and research data Public APIs and services Shared knowledge bases Educational resources Important: Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.\nCreating a Public Project# Set public_read to true when creating a project:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }\u0026#39;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }Making an Existing Project Public# Update an existing project using PATCH:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39;Making a Public Project Private# To disable public access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;Accessing Public Projects Without Authentication# Once a project has public_read enabled, anyone can access it without providing an API key.\nGet Project Metadata# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34;Response:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Publicly accessible knowledge base\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true }Retrieve All Embeddings# curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge?limit=100\u0026#34;Response:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Public document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072 }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Another public document\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;history\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072 } ] }Get a Specific Embedding# curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge/doc001\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Public document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;}, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;vector\u0026#34;: [0.021, -0.015, 0.043, ...] }Search for Similar Documents# # Search by existing document ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/public-knowledge/doc001?count=5\u0026amp;threshold=0.7\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;public-knowledge\u0026#34;, \u0026#34;results\u0026#34;: [ {\u0026#34;id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;similarity\u0026#34;: 0.92}, {\u0026#34;id\u0026#34;: \u0026#34;doc003\u0026#34;, \u0026#34;similarity\u0026#34;: 0.85}, {\u0026#34;id\u0026#34;: \u0026#34;doc004\u0026#34;, \u0026#34;similarity\u0026#34;: 0.78} ] }Search with Raw Embeddings# curl -X POST \u0026#34;https://api.example.com/v1/similars/alice/public-knowledge?count=5\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;Operations Still Requiring Authentication# Even for public projects, these operations require authentication:\nCreating Embeddings (Requires Auth)# # This will fail with 401 Unauthorized curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;embeddings\u0026#34;: [...]}\u0026#39; # This succeeds with valid API key curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072 }] }\u0026#39;Deleting Embeddings (Requires Auth)# # Delete specific embedding (requires auth) curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge/doc001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Delete all embeddings (requires auth) curl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Modifying Project Settings (Requires Auth)# # Update project description (requires auth) curl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;}\u0026#39;Deleting Project (Requires Auth)# curl -X DELETE \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining Public Access with User Sharing# You can combine public read access with user-specific editor permissions:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/collaborative-public\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;collaborative-public\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Public read, restricted write\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ { \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }, { \u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; } ] }\u0026#39;In this configuration:\nAnyone can read embeddings and search (no auth required) bob and charlie can add/modify/delete embeddings (with auth) alice (owner) has full control (with auth) Use Cases# Open Research Dataset# Share research data publicly while maintaining write control:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/university/research-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer university_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Open research corpus for academic use\u0026#34;, \u0026#34;instance_id\u0026#34;: 456, \u0026#34;public_read\u0026#34;: true, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;doi\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;doi\\\u0026#34;]}\u0026#34; }\u0026#39;Researchers worldwide can access the data without credentials, but only authorized users can add new data.\nPublic API Backend# Build a public search API on top of dhamps-vdb:\nimport requests def public_search_api(query_vector, count=10): \u0026#34;\u0026#34;\u0026#34;Public search function requiring no authentication\u0026#34;\u0026#34;\u0026#34; response = requests.post( \u0026#34;https://api.example.com/v1/similars/company/product-docs\u0026#34;, json={\u0026#34;vector\u0026#34;: query_vector}, params={\u0026#34;count\u0026#34;: count, \u0026#34;threshold\u0026#34;: 0.6} ) return response.json() # No API key needed for public projects! results = public_search_api(query_embedding)Educational Resources# Share educational content publicly:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/edu/learning-materials\u0026#34; \\ -H \u0026#34;Authorization: Bearer edu_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;learning-materials\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Free educational content embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 789, \u0026#34;public_read\u0026#34;: true }\u0026#39;Students and educators can access the materials without creating accounts.\nCommunity-Driven Knowledge Base# Open knowledge base with restricted editors:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/community/wiki-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer community_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;wiki-embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Community wiki embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 321, \u0026#34;public_read\u0026#34;: true, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;moderator1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;moderator2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;} ] }\u0026#39;Security Considerations# What is Publicly Visible# When public_read is enabled:\n✅ Project metadata (name, description, owner) ✅ All embedding vectors and text content ✅ All embedding metadata ✅ Vector dimensions and instance references ❌ API keys (never exposed) ❌ User passwords or credentials Best Practices# Review Content First: Ensure no sensitive information is in embeddings or metadata before enabling public access Use Metadata Schemas: Enforce consistent metadata structure with validation Monitor Usage: Track access patterns to your public projects Set Clear Descriptions: Provide clear project descriptions explaining the data\u0026rsquo;s purpose and licensing Consider Rate Limiting: For high-traffic public APIs, implement rate limiting at the application level What to Avoid# ❌ Don\u0026rsquo;t make projects public that contain:\nPersonal identifiable information (PII) Proprietary or confidential data Sensitive research data not yet published Internal company information ✅ Do make projects public that contain:\nAlready-published research data Open educational resources Public domain content Creative Commons licensed materials Disabling Public Access# If you need to make a public project private again:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;After this change:\nAll read operations require authentication Existing anonymous access is immediately revoked No data is deleted, just access is restricted Checking if a Project is Public# View project metadata to check the public_read flag:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice/public-knowledge\u0026#34;Look for \u0026quot;public_read\u0026quot;: true in the response.\nRelated Documentation# Project Sharing Guide - Share with specific users RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Enforce data quality Troubleshooting# Public Access Not Working# Symptom: Still getting 401 Unauthorized for public project\nSolutions:\nVerify public_read: true is set: curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; Check you\u0026rsquo;re using GET/POST for similars (not other methods) Ensure the project exists and handle is correct Accidentally Made Project Public# Solution: Immediately disable public access:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: false}\u0026#39;Want to Track Public Usage# Solution: Anonymous requests are logged with user set to \u0026ldquo;public\u0026rdquo;. Review server logs to monitor public access patterns.\n"},{"id":26,"href":"/dhamps-vdb/getting-started/quick-start/","title":"Quick Start","section":"Getting Started","content":"Quick Start# Complete walkthrough from installation to searching similar documents using curl.\nPrerequisites# dhamps-vdb installed and running Admin API key configured PostgreSQL with pgvector ready 1. Create a User# Create a new user with the admin API key:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice@example.com\u0026#34;, \u0026#34;vdb_key\u0026#34;: \u0026#34;024v2013621509245f2e24...\u0026#34;, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; }Save the vdb_key - it cannot be recovered later.\n2. Create an LLM Service Instance# Create an LLM service configuration:\ncurl -X PUT http://localhost:8880/v1/llm-services/alice/my-openai \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }3. Create a Project# Create a project to organize your embeddings:\ncurl -X POST http://localhost:8880/v1/projects/alice \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 1, \u0026#34;created_at\u0026#34;: \u0026#34;2024-01-15T10:35:00Z\u0026#34; }4. Upload Embeddings# Upload document embeddings to your project:\ncurl -X POST http://localhost:8880/v1/embeddings/alice/research-docs \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Introduction to machine learning\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ..., 0.5], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;ML Intro\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Deep learning fundamentals\u0026#34;, \u0026#34;vector\u0026#34;: [0.15, 0.25, 0.35, ..., 0.55], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;DL Fundamentals\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Bob\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;2 embeddings uploaded successfully\u0026#34; }5. Search for Similar Documents# Option A: Search Using Stored Document# Find documents similar to an already-stored document:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;similarity\u0026#34;: 0.92 }, { \u0026#34;id\u0026#34;: \u0026#34;doc5\u0026#34;, \u0026#34;similarity\u0026#34;: 0.85 } ] }Option B: Search Using Raw Embeddings# Search without storing the query embedding:\ncurl -X POST \u0026#34;http://localhost:8880/v1/similars/alice/research-docs?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.12, 0.22, 0.32, ..., 0.52] }\u0026#39;6. Filter by Metadata# Exclude documents from a specific author when searching:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5\u0026amp;metadata_path=author\u0026amp;metadata_value=Alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;This excludes all documents where metadata.author equals \u0026ldquo;Alice\u0026rdquo;.\n7. Retrieve Embeddings# Get all embeddings in your project:\ncurl -X GET \u0026#34;http://localhost:8880/v1/embeddings/alice/research-docs?limit=10\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Get a specific embedding:\ncurl -X GET http://localhost:8880/v1/embeddings/alice/research-docs/doc1 \\ -H \u0026#34;Authorization: Bearer alice_vdb_key\u0026#34;Complete Workflow Example# Here\u0026rsquo;s a complete script to get started:\n#!/bin/bash # Configuration API_URL=\u0026#34;http://localhost:8880\u0026#34; ADMIN_KEY=\u0026#34;your-admin-key\u0026#34; # 1. Create user USER_RESPONSE=$(curl -s -X POST \u0026#34;$API_URL/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer $ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;:\u0026#34;alice\u0026#34;,\u0026#34;name\u0026#34;:\u0026#34;Alice Smith\u0026#34;,\u0026#34;email\u0026#34;:\u0026#34;alice@example.com\u0026#34;}\u0026#39;) USER_KEY=$(echo $USER_RESPONSE | jq -r \u0026#39;.vdb_key\u0026#39;) echo \u0026#34;User created with key: $USER_KEY\u0026#34; # 2. Create LLM service instance curl -X PUT \u0026#34;$API_URL/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-your-key\u0026#34; }\u0026#39; # 3. Create project curl -X POST \u0026#34;$API_URL/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research documents\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39; # 4. Upload embeddings curl -X POST \u0026#34;$API_URL/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @embeddings.json # 5. Search similar curl -X GET \u0026#34;$API_URL/v1/similars/alice/research-docs/doc1?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; echo \u0026#34;Setup complete!\u0026#34;API Documentation# For complete API documentation, visit:\ncurl http://localhost:8880/docsOr open http://localhost:8880/docs in your browser.\nNext Steps# Learn about projects Understand embeddings Explore sharing projects Set up metadata validation "},{"id":27,"href":"/dhamps-vdb/api/","title":"API Reference","section":"dhamps-vdb Documentation","content":"API Reference# Complete reference for the dhamps-vdb REST API.\nAPI Version# Current version: v1\nAll endpoints are prefixed with /v1/ (e.g., POST /v1/embeddings/{user}/{project}).\nAPI Documentation# The complete, always up-to-date API specification is available at:\nOpenAPI YAML: /openapi.yaml Interactive Documentation: /docs Reference Sections# Authentication - API key authentication Endpoints - All available API endpoints Query Parameters - Filtering and pagination PATCH Updates - Partial resource updates Error Handling - Error responses and codes Quick Example# # Authenticate with API key curl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer your_api_key_here\u0026#34;All API requests require authentication except for public project read operations.\n"},{"id":28,"href":"/dhamps-vdb/api/endpoints/api-standards/","title":"API Standards","section":"Endpoints","content":"API Standards Endpoint# Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.\nOverview# API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:\nOpenAI: Bearer token in Authorization header Cohere: API key in Authorization header with Bearer prefix Google Gemini: API key as query parameter Ollama: No authentication required Pre-seeded standards are available for common providers. See testdata/valid_api_standard_*.json for examples.\nEndpoints# List All API Standards# Get all defined API standards. This endpoint is publicly accessible (no authentication required).\nEndpoint: GET /v1/api-standards\nAuthentication: Public (no authentication required)\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/api-standards\u0026#34;Response:\n{ \u0026#34;standards\u0026#34;: [ { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }, { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }, { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; } ] } Get API Standard# Retrieve information about a specific API standard. This endpoint is publicly accessible.\nEndpoint: GET /v1/api-standards/{standardname}\nAuthentication: Public (no authentication required)\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34;Response:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; } Create API Standard# Register a new API standard definition. Admin-only operation.\nEndpoint: POST /v1/api-standards\nAuthentication: Admin only\nRequest Body:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom-provider\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom provider embedding API\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }Parameters:\napi_standard_handle (string, required): Unique identifier for the standard description (string, required): Description including API documentation URL key_method (string, required): Authentication method auth_bearer: Bearer token in header auth_apikey: API key in header query_param: API key as query parameter none: No authentication key_field (string, required): Field name for the API key For headers: typically \u0026quot;Authorization\u0026quot; or \u0026quot;X-API-Key\u0026quot; For query params: parameter name like \u0026quot;key\u0026quot; or \u0026quot;api_key\u0026quot; Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/api-standards\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;ollama\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Ollama local embedding API, no authentication required\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; }\u0026#39;Response:\n{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;ollama\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Ollama local embedding API, no authentication required\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; } Update API Standard (PUT)# Create or update an API standard with a specific handle. Admin-only operation.\nEndpoint: PUT /v1/api-standards/{standardname}\nAuthentication: Admin only\nRequest Body: Same as POST endpoint\nExample:\ncurl -X PUT \u0026#34;https://api.example.com/v1/api-standards/custom-provider\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom-provider\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description for custom provider\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }\u0026#39; Delete API Standard# Delete an API standard definition. Admin-only operation.\nEndpoint: DELETE /v1/api-standards/{standardname}\nAuthentication: Admin only\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/api-standards/custom-provider\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;API standard \u0026#39;custom-provider\u0026#39; deleted successfully\u0026#34; }⚠️ Warning: Cannot delete API standards that are referenced by LLM service instances.\nPartial Update (PATCH)# Update specific API standard fields without providing all data. Admin-only operation.\nEndpoint: PATCH /v1/api-standards/{standardname}\nAuthentication: Admin only\nExample - Update description:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API v1 - Updated documentation link\u0026#34; }\u0026#39;See PATCH Updates for more details.\nAPI Standard Properties# Field Type Required Description api_standard_handle string Yes Unique identifier (e.g., \u0026ldquo;openai\u0026rdquo;, \u0026ldquo;cohere\u0026rdquo;) description string Yes Description with API documentation URL key_method string Yes Authentication method key_field string Yes Field name for API key/token Authentication Methods# auth_bearer# Bearer token authentication in the Authorization header.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }HTTP Request:\nAuthorization: Bearer sk-proj-abc123...Used by: OpenAI, Cohere, Anthropic\nauth_apikey# API key in a custom header field.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;auth_apikey\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;X-API-Key\u0026#34; }HTTP Request:\nX-API-Key: abc123...Used by: Some custom API providers\nquery_param# API key passed as a URL query parameter.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; }HTTP Request:\nGET https://api.example.com/embed?key=abc123...Used by: Google Gemini, some older APIs\nnone# No authentication required.\nExample:\n{ \u0026#34;key_method\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;\u0026#34; }Used by: Ollama (local), self-hosted models without auth\nPre-seeded API Standards# The following API standards are created during database migration:\nopenai# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1, as documented in https://platform.openai.com/docs/api-reference/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }cohere# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Cohere Embed API, Version 2, as documented in https://docs.cohere.com/reference/embed\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;Authorization\u0026#34; }gemini# { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Google Gemini Embedding API as documented in https://ai.google.dev/gemini-api/docs/embeddings\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;query_param\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;key\u0026#34; } Use Cases# Creating a Custom API Standard# For self-hosted or custom LLM services:\ncurl -X POST \u0026#34;https://api.example.com/v1/api-standards\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;api_standard_handle\u0026#34;: \u0026#34;vllm-local\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;vLLM local deployment with custom auth\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_apikey\u0026#34;, \u0026#34;key_field\u0026#34;: \u0026#34;X-API-Key\u0026#34; }\u0026#39;Referencing in LLM Service Instance# Once created, reference the API standard in your LLM service instance:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-vllm\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-vllm\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://vllm.local/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;vllm-local\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-embed\u0026#34;, \u0026#34;dimensions\u0026#34;: 768, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;my-secret-key\u0026#34; }\u0026#39; Common Errors# 400 Bad Request# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid key_method: must be one of auth_bearer, auth_apikey, query_param, none\u0026#34; }401 Unauthorized (Admin Operations)# { \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }403 Forbidden (Admin Operations)# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create/modify/delete API standards\u0026#34; }404 Not Found# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;API standard \u0026#39;custom-provider\u0026#39; not found\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete API standard: referenced by 5 LLM service instances\u0026#34; } Related Documentation# LLM Services - LLM service instances reference API standards Authentication - User authentication methods Testdata Examples - Example API standard definitions "},{"id":29,"href":"/dhamps-vdb/concepts/embeddings/","title":"Embeddings","section":"Concepts","content":"Embeddings# Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.\nWhat are Embeddings?# Embeddings are numerical representations (vectors) of text that capture semantic meaning:\nVector: Array of floating-point numbers (e.g., 1536 or 3072 dimensions) Dimensions: Fixed length determined by LLM model Similarity: Vectors of similar text are close in vector space Purpose: Enable semantic search and retrieval Embedding Structure# Required Fields# text_id: Unique identifier for the document (max 300 characters) instance_handle: LLM service instance that generated the embedding vector: Array of float32 values (embedding vector) vector_dim: Declared dimension count (must match vector length) Optional Fields# text: Original text content (for reference) metadata: Structured JSON data about the document Example# { \u0026#34;text_id\u0026#34;: \u0026#34;doc-123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Introduction to machine learning concepts\u0026#34;, \u0026#34;vector\u0026#34;: [0.023, -0.015, 0.087, ..., 0.042], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;ML Introduction\u0026#34;, \u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;category\u0026#34;: \u0026#34;tutorial\u0026#34; } }Creating Embeddings# Single Embedding# POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ..., 0.3], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;} } ] }Batch Upload# POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072 }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072 }, ... ] }Batch upload tips:\nUpload 100-1000 embeddings per request Use consistent instance_handle Ensure all vectors have same dimensions Include metadata for searchability Text Identifiers# Format# Text IDs can be any string up to 300 characters:\nCommon patterns:\nURLs: https://id.example.com/doc/123 URNs: urn:example:doc:123 Paths: /corpus/section1/doc123 IDs: doc-abc-123-xyz URL Encoding# URL-encode text IDs when using them in API paths:\n# Original ID text_id=\u0026#34;https://id.example.com/texts/W0017:1.3.1\u0026#34; # URL-encoded for API encoded=\u0026#34;https%3A%2F%2Fid.example.com%2Ftexts%2FW0017%3A1.3.1\u0026#34; # Use in API call GET /v1/embeddings/alice/project/$encodedUniqueness# Text IDs must be unique within a project:\nSame ID in different projects: ✅ Allowed Same ID twice in one project: ❌ Conflict error Validation# Dimension Validation# The system automatically validates vector dimensions:\nChecks performed:\nvector_dim matches declared instance dimensions Actual vector array length matches vector_dim All embeddings in project have consistent dimensions Example error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;my-openai\u0026#39; expects 1536 dimensions\u0026#34; }Metadata Validation# If project has a metadata schema, all embeddings are validated:\nExample error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc1\u0026#39;: metadata validation failed:\\n - author is required\\n - year must be integer\u0026#34; }See Metadata Validation Guide for details.\nRetrieving Embeddings# List All Embeddings# GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=0Returns paginated list of embeddings with:\ntext_id metadata vector_dim created_at Vectors are included by default (can be large).\nGet Single Embedding# GET /v1/embeddings/alice/research-docs/doc1Returns complete embedding including vector.\nPagination# Use limit and offset for large projects:\n# First page (0-99) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=0 # Second page (100-199) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=100 # Third page (200-299) GET /v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=200Updating Embeddings# Currently, embeddings cannot be updated directly. To modify:\nDelete existing embedding Upload new version with same text_id # Delete old version DELETE /v1/embeddings/alice/research-docs/doc1 # Upload new version POST /v1/embeddings/alice/research-docs { \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...new vector...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {...updated metadata...} }] }Deleting Embeddings# Delete Single Embedding# DELETE /v1/embeddings/alice/research-docs/doc1Delete All Embeddings# DELETE /v1/embeddings/alice/research-docsWarning: This deletes all embeddings in the project permanently.\nMetadata# Purpose# Metadata provides structured information about documents:\nFiltering: Exclude documents in similarity searches Organization: Categorize and group documents Context: Store additional document information Validation: Ensure consistent structure (with schema) Structure# Metadata is stored as JSONB in PostgreSQL:\n{ \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;act\u0026#34;: 1, \u0026#34;scene\u0026#34;: 1, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; }Nested Metadata# Complex structures are supported:\n{ \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;birth_year\u0026#34;: 1564, \u0026#34;nationality\u0026#34;: \u0026#34;English\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 1603, \u0026#34;publisher\u0026#34;: \u0026#34;First Folio\u0026#34;, \u0026#34;edition\u0026#34;: 1 }, \u0026#34;tags\u0026#34;: [\u0026#34;tragedy\u0026#34;, \u0026#34;revenge\u0026#34;, \u0026#34;madness\u0026#34;] }Filtering by Metadata# Use metadata to exclude documents from similarity searches:\n# Exclude documents from same author GET /v1/similars/alice/project/doc1?metadata_path=author\u0026amp;metadata_value=ShakespeareSee Metadata Filtering Guide for details.\nStorage Considerations# Vector Storage# Vectors are stored using pgvector extension:\nType: vector(N) where N is dimension count Size: 4 bytes per dimension + overhead Example: 3072-dimension vector ≈ 12KB Storage Calculation# Estimate storage per embedding:\nVector: 4 bytes × dimensions Text ID: length in bytes (avg ~50 bytes) Text: length in bytes (optional) Metadata: JSON size (varies, avg ~500 bytes) Overhead: ~100 bytes (indexes, etc.) Example (3072-dim with metadata): 4 × 3072 + 50 + 500 + 100 ≈ 13KB per embeddingLarge Projects# For projects with millions of embeddings:\nUse pagination when listing Consider partial indexes for metadata Monitor database size Plan backup strategy Performance# Upload Performance# Small batches (1-10): ~100ms per request Medium batches (100-500): ~500ms-2s per request Large batches (1000+): ~2-10s per request Retrieval Performance# Single embedding: \u0026lt;10ms Paginated list (100 items): ~50ms Large project scan: Use pagination Optimization Tips# Batch uploads when possible Use appropriate page sizes Include only needed fields Monitor query performance Common Patterns# Document Chunking# Split long documents into chunks:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:chunk1\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;First part of document...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;chunk\u0026#34;: 1} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:chunk2\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Second part of document...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;chunk\u0026#34;: 2} } ] }Versioned Documents# Track document versions:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1:v2\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: { \u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;version\u0026#34;: 2, \u0026#34;updated_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34; } }Multi-Language Documents# Store embeddings for different languages:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:en\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;English version...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;en\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc1:de\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Deutsche Version...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: {\u0026#34;doc_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;de\u0026#34;} } ] }Troubleshooting# Dimension Mismatch# Error: \u0026ldquo;vector dimension mismatch\u0026rdquo;\nCause: Vector dimensions don\u0026rsquo;t match instance configuration\nSolution:\nCheck instance dimensions: GET /v1/llm-services/owner/instance Regenerate embeddings with correct model Ensure vector_dim matches actual vector length Metadata Validation Failed# Error: \u0026ldquo;metadata validation failed\u0026rdquo;\nCause: Metadata doesn\u0026rsquo;t match project schema\nSolution:\nCheck project schema: GET /v1/projects/owner/project Update metadata to match schema Or update schema to accept metadata Text ID Conflict# Error: \u0026ldquo;embedding with text_id already exists\u0026rdquo;\nCause: Attempting to upload duplicate text_id\nSolution:\nUse different text_id Delete existing embedding first Check for unintended duplicates Next Steps# Learn about similarity search Explore metadata filtering Understand LLM services "},{"id":30,"href":"/dhamps-vdb/getting-started/first-project/","title":"First Project","section":"Getting Started","content":"First Project# Step-by-step guide to creating your first complete project in dhamps-vdb.\nOverview# This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:\nSet up authentication Configure an LLM service Create a project with metadata validation Upload document embeddings Search for similar documents Share your project with collaborators Step 1: Authentication Setup# Get Your API Key# If you\u0026rsquo;re an admin, create your first user:\ncurl -X POST http://localhost:8880/v1/users \\ -H \u0026#34;Authorization: Bearer YOUR_ADMIN_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Research User\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;researcher@example.com\u0026#34; }\u0026#39;Save the returned vdb_key to a variable:\nexport USER_KEY=\u0026#34;your-returned-vdb-key\u0026#34;Verify Authentication# Test your API key:\ncurl -X GET http://localhost:8880/v1/users/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 2: Configure LLM Service# Option A: Use System Definition# List available system definitions:\ncurl -X GET http://localhost:8880/v1/llm-services/_system \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Create an instance from a system definition:\ncurl -X PUT http://localhost:8880/v1/llm-services/researcher1/my-embeddings \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My OpenAI embeddings instance\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key\u0026#34; }\u0026#39;Option B: Create Custom Instance# Create a standalone instance with custom configuration:\ncurl -X PUT http://localhost:8880/v1/llm-services/researcher1/custom-embeddings \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-small\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536, \u0026#34;description\u0026#34;: \u0026#34;Custom OpenAI small embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-api-key\u0026#34; }\u0026#39;Step 3: Create Project with Metadata Schema# Define a metadata schema to ensure consistent document metadata:\ncurl -X POST http://localhost:8880/v1/projects/researcher1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literature-analysis\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary texts for research analysis\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;genre\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;,\\\u0026#34;enum\\\u0026#34;:[\\\u0026#34;poetry\\\u0026#34;,\\\u0026#34;prose\\\u0026#34;,\\\u0026#34;drama\\\u0026#34;]},\\\u0026#34;language\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;title\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }\u0026#39;This schema requires author, title, and year fields, with optional genre and language fields.\nStep 4: Upload Document Embeddings# Prepare Your Data# Create a file embeddings.json with your document embeddings:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;hamlet-act1-scene1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Who\u0026#39;s there? Nay, answer me: stand, and unfold yourself.\u0026#34;, \u0026#34;vector\u0026#34;: [0.023, -0.015, 0.087, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; } }, { \u0026#34;text_id\u0026#34;: \u0026#34;paradise-lost-book1-line1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Of Man\u0026#39;s first disobedience, and the fruit...\u0026#34;, \u0026#34;vector\u0026#34;: [0.045, -0.032, 0.091, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Milton\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Paradise Lost\u0026#34;, \u0026#34;year\u0026#34;: 1667, \u0026#34;genre\u0026#34;: \u0026#34;poetry\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;English\u0026#34; } } ] }Upload Embeddings# curl -X POST http://localhost:8880/v1/embeddings/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @embeddings.jsonVerify Upload# List all embeddings:\ncurl -X GET \u0026#34;http://localhost:8880/v1/embeddings/researcher1/literature-analysis?limit=10\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Get a specific embedding:\ncurl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 5: Search Similar Documents# Basic Similarity Search# Find passages similar to Hamlet Act 1:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;researcher1\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;literature-analysis\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;hamlet-act2-scene1\u0026#34;, \u0026#34;similarity\u0026#34;: 0.89 }, { \u0026#34;id\u0026#34;: \u0026#34;macbeth-act1-scene3\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 }, { \u0026#34;id\u0026#34;: \u0026#34;othello-act3-scene3\u0026#34;, \u0026#34;similarity\u0026#34;: 0.76 } ] }Search with Metadata Filtering# Exclude passages from the same work:\ncurl -X GET \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5\u0026amp;metadata_path=title\u0026amp;metadata_value=Hamlet\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;This excludes all documents where metadata.title equals \u0026ldquo;Hamlet\u0026rdquo;.\nSearch with Raw Embeddings# Search using a new embedding without storing it:\ncurl -X POST \u0026#34;http://localhost:8880/v1/similars/researcher1/literature-analysis?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.034, -0.021, 0.092, ...] }\u0026#39;Step 6: Share Your Project# Share with Collaborators# Grant read-only access to another user:\ncurl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Grant edit access:\ncurl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;colleague2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34; }\u0026#39;Make Project Public# Enable public read access (no authentication required):\ncurl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Now anyone can read embeddings and search without authentication:\n# No Authorization header needed curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1View Shared Users# List all users with access to your project:\ncurl -X GET http://localhost:8880/v1/projects/researcher1/literature-analysis/shared-with \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Step 7: Manage Your Project# Update Project Description# curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated: Shakespearean and Renaissance literature analysis\u0026#34; }\u0026#39;Update Metadata Schema# curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;genre\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;language\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;act\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;},\\\u0026#34;scene\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;title\\\u0026#34;,\\\u0026#34;year\\\u0026#34;]}\u0026#34; }\u0026#39;Delete Specific Embeddings# curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Delete All Embeddings# curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;Common Patterns# Batch Upload Script# #!/bin/bash USER_KEY=\u0026#34;your-vdb-key\u0026#34; PROJECT=\u0026#34;researcher1/literature-analysis\u0026#34; API_URL=\u0026#34;http://localhost:8880\u0026#34; # Process multiple files for file in data/*.json; do echo \u0026#34;Uploading $file...\u0026#34; curl -X POST \u0026#34;$API_URL/v1/embeddings/$PROJECT\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d @\u0026#34;$file\u0026#34; doneSearch and Filter Workflow# # 1. Find similar documents SIMILAR=$(curl -s -X GET \u0026#34;$API_URL/v1/similars/$PROJECT/doc1?count=20\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34;) # 2. Extract IDs IDS=$(echo $SIMILAR | jq -r \u0026#39;.results[].id\u0026#39;) # 3. Retrieve full embeddings for similar documents for id in $IDS; do curl -X GET \u0026#34;$API_URL/v1/embeddings/$PROJECT/$id\u0026#34; \\ -H \u0026#34;Authorization: Bearer $USER_KEY\u0026#34; doneTroubleshooting# Validation Errors# If metadata validation fails:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc1\u0026#39;: year is required\u0026#34; }Check your metadata schema and ensure all required fields are present.\nDimension Mismatches# If vector dimensions don\u0026rsquo;t match:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: expected 3072 dimensions, got 1536\u0026#34; }Verify your LLM service configuration and embedding dimensions.\nAuthentication Errors# If you get 401 Unauthorized:\nCheck your API key is correct Ensure Authorization: Bearer prefix is included Verify the user owns the resource or has been granted access Next Steps# Learn about metadata validation Explore batch operations Understand similarity search Review API documentation "},{"id":31,"href":"/dhamps-vdb/guides/ownership-transfer/","title":"Ownership Transfer Guide","section":"Guides","content":"Ownership Transfer Guide# This guide explains how to transfer project ownership between users in dhamps-vdb.\nOverview# Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:\nA project maintainer is leaving and wants to hand over control Organizational changes require reassigning project ownership Consolidating projects under a different user account Transferring stewardship of research data to a new PI Important Constraints# Before transferring ownership, understand these constraints:\nOnly the current owner can transfer - Editors and readers cannot initiate transfers New owner must exist - The target user must already be registered in the system No handle conflicts - The new owner cannot already have a project with the same handle Old owner loses access - After transfer, the original owner has no access to the project Data remains intact - All embeddings and metadata are preserved during transfer Shared users remain - Existing sharing relationships are maintained Transferring Ownership# Basic Transfer# Transfer a project to another user:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34; }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Project ownership transferred successfully\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-data\u0026#34;, \u0026#34;old_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;new_owner\u0026#34;: \u0026#34;bob\u0026#34; }After this operation:\nThe project is now accessible at /v1/projects/bob/research-data Bob has full owner privileges Alice no longer has any access to the project All embeddings remain unchanged Complete Transfer Example# Here\u0026rsquo;s a complete workflow showing before and after transfer:\n# Before transfer - Alice is the owner curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Response { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research project\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 } # Alice transfers to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # After transfer - Bob is now the owner curl -X GET \u0026#34;https://api.example.com/v1/projects/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; # Response { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research project\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 } # Alice can no longer access it curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Returns: 404 Not FoundEffects of Transfer# Project Access Path Changes# The project URL changes to reflect the new owner:\nBefore:\n/v1/projects/alice/research-data /v1/embeddings/alice/research-data /v1/similars/alice/research-data/doc123After:\n/v1/projects/bob/research-data /v1/embeddings/bob/research-data /v1/similars/bob/research-data/doc123Important: Update all client code and bookmarks to use the new owner\u0026rsquo;s handle.\nNew Owner Gains Full Control# Bob (new owner) can now:\nView and modify all embeddings Update project settings (description, instance, metadata schema) Manage sharing (add/remove shared users) Transfer ownership again to someone else Delete the project Old Owner Loses All Access# Alice (old owner) can no longer:\nAccess the project in any way View or modify embeddings See project metadata Manage sharing Transfer ownership back Note: If Alice needs continued access, Bob should share the project with her after the transfer.\nShared Users Remain# If the project was shared with other users, those sharing relationships are preserved:\n# Before transfer - Alice shares with Charlie (editor) curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Transfer to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # After transfer - Charlie still has editor access curl -X GET \u0026#34;https://api.example.com/v1/projects/bob/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; # Works! Charlie can still access as editorUpgrading Shared User to Owner# If the new owner was previously a shared user, their role is automatically upgraded:\n# Alice shares project with Bob (editor) curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Alice transfers ownership to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # Bob\u0026#39;s previous \u0026#34;editor\u0026#34; sharing role is removed # Bob now has full owner privileges insteadUse Cases# PI Leaving Institution# A principal investigator leaving an institution transfers project ownership to a colleague:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/prof_jones/lab_data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer prof_jones_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;prof_smith\u0026#34;}\u0026#39;Account Consolidation# Consolidate multiple projects under a single organizational account:\n# Transfer Alice\u0026#39;s personal projects to organization account curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/project1/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;org_datascience\u0026#34;}\u0026#39; curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/project2/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;org_datascience\u0026#34;}\u0026#39;Graduated Student Handoff# A graduating student transfers their research project to their advisor:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/student_bob/thesis_embeddings/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer student_bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;advisor_carol\u0026#34;}\u0026#39; # Advisor can then share it back with the student if needed curl -X POST \u0026#34;https://api.example.com/v1/projects/advisor_carol/thesis_embeddings/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer advisor_carol_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;student_bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}\u0026#39;Department Reorganization# Projects move to a new department owner:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/old_dept/resource_library/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer old_dept_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;new_dept\u0026#34;}\u0026#39;Error Conditions# New Owner Doesn\u0026rsquo;t Exist# curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;nonexistent_user\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;nonexistent_user\u0026#39; does not exist\u0026#34; }Solution: Ensure the target user is registered first. Contact admin to create the user.\nHandle Conflict# # Bob already has a project called \u0026#34;research-data\u0026#34; curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;bob\u0026#39; already has a project with handle \u0026#39;research-data\u0026#39;\u0026#34; }Solution: Either:\nRename Alice\u0026rsquo;s project before transferring: curl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;project_handle\u0026#34;: \u0026#34;research-data-alice\u0026#34;}\u0026#39; Ask Bob to rename or delete their existing project Choose a different target user Not the Owner# # Charlie tries to transfer Alice\u0026#39;s project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer charlie_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only the project owner can transfer ownership\u0026#34; }Solution: Only the current owner (Alice) can initiate the transfer.\nBest Practices# Before Transferring# Communicate with New Owner: Ensure they\u0026rsquo;re willing to accept ownership Document Current State: Export or document current embeddings and metadata Review Shared Users: Check who has access and whether sharing should continue Update Client Code: Identify all systems accessing the project that need updating Backup Data: Consider exporting important data before transfer During Transfer# Transfer at Low-Activity Time: Minimize disruption by transferring during quiet periods Test Access First: Verify new owner can access their other projects Use Correct Handle: Double-check the new owner\u0026rsquo;s handle before submitting After Transferring# Verify New Ownership: Confirm the transfer succeeded Update Client Applications: Change all API calls to use new owner handle Grant Back Access if Needed: New owner can share project back to old owner Update Documentation: Update any documentation referencing the project path Notify Shared Users: Inform shared users about the path change Maintaining Access After Transfer# If the original owner needs continued access, the new owner should share the project:\n# Step 1: Alice transfers to Bob curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/research-data/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; # Step 2: Bob shares back with Alice as editor curl -X POST \u0026#34;https://api.example.com/v1/projects/bob/research-data/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;share_with_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;editor\u0026#34;}\u0026#39; # Now Alice can still access (but as editor, not owner) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/bob/research-data\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Checking Current Owner# To verify current project ownership:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/{owner}/{project}\u0026#34; \\ -H \u0026#34;Authorization: Bearer your_api_key\u0026#34;The owner field in the response shows the current owner.\nRelated Documentation# Project Sharing Guide - Share projects with specific users Public Projects Guide - Make projects publicly accessible Troubleshooting# Cannot Find Project After Transfer# Problem: Getting 404 after transfer\nSolution: Update the owner in your API calls:\nOld: /v1/projects/alice/my-project New: /v1/projects/bob/my-project Need to Reverse Transfer# Problem: Transferred by mistake, need to reverse\nSolution: New owner must transfer back:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/bob/my-project/transfer-ownership\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;new_owner_handle\u0026#34;: \u0026#34;alice\u0026#34;}\u0026#39;Client Applications Failing# Problem: Applications can\u0026rsquo;t access project after transfer\nSolution: Update all hardcoded owner references in your code to use the new owner\u0026rsquo;s handle.\n"},{"id":32,"href":"/dhamps-vdb/development/performance/","title":"Performance","section":"Development","content":"Performance Optimization Guide# This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.\nQuery Optimization# GetAllAccessibleInstances Query# Problem: The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.\nCurrent Implementation:\nSELECT instances.*, COALESCE(instances_shared_with.role, \u0026#39;owner\u0026#39;) as role, (instances.owner = $1) as is_owner FROM instances LEFT JOIN instances_shared_with ON instances.instance_id = instances_shared_with.instance_id WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1 ORDER BY instances.owner ASC, instances.instance_handle ASC LIMIT $2 OFFSET $3;Issue: The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.\nRecommended: UNION ALL Pattern# Use UNION ALL to separate owned instances from shared instances:\n-- Get owned instances SELECT instances.*, \u0026#39;owner\u0026#39; as role, true as is_owner FROM instances WHERE instances.owner = $1 UNION ALL -- Get shared instances SELECT instances.*, instances_shared_with.role, false as is_owner FROM instances INNER JOIN instances_shared_with ON instances.instance_id = instances_shared_with.instance_id WHERE instances_shared_with.user_handle = $1 AND instances.owner != $1 -- Avoid duplicates ORDER BY owner ASC, instance_handle ASC LIMIT $2 OFFSET $3;Benefits:\nSeparate index scans: Query planner can use different indexes for each UNION branch Owned instances: Can use index on (owner) Shared instances: Can use index on (user_handle) Clearer execution plan: Easier to understand and optimize Better performance: Especially noticeable with large datasets Trade-offs:\nSlightly more complex SQL Need to deduplicate if user somehow has instance both owned and shared (unlikely scenario) Both queries must have same column structure Implementation Example# Before (queries.sql):\n-- name: GetAllAccessibleInstances :many SELECT instances.*, ... FROM instances LEFT JOIN instances_shared_with ON ... WHERE instances.owner = $1 OR instances_shared_with.user_handle = $1After (queries.sql):\n-- name: GetAllAccessibleInstances :many SELECT instances.*, \u0026#39;owner\u0026#39; as role, true as is_owner FROM instances WHERE instances.owner = $1 UNION ALL SELECT instances.*, isw.role, false as is_owner FROM instances INNER JOIN instances_shared_with isw ON instances.instance_id = isw.instance_id WHERE isw.user_handle = $1 AND instances.owner != $1 ORDER BY owner, instance_handle LIMIT $2 OFFSET $3;When to optimize:\nCurrent implementation is correct and works well for small-medium datasets Consider optimization if performance becomes an issue with: Large numbers of instances (\u0026gt;1000) Many shared relationships (\u0026gt;100 shares per user) Query time consistently \u0026gt;100ms Always profile first:\nEXPLAIN ANALYZE SELECT instances.*, ... FROM instances LEFT JOIN instances_shared_with ON ... WHERE instances.owner = \u0026#39;alice\u0026#39; OR instances_shared_with.user_handle = \u0026#39;alice\u0026#39;;Index Optimization# Current Indexes# From migration 004_refactor_llm_services_architecture.sql:\n-- API Standards / Definitions CREATE INDEX idx_definitions_handle ON definitions(definition_handle); CREATE INDEX idx_definitions_owner_handle ON definitions(owner, definition_handle); -- Instances CREATE INDEX idx_instances_handle ON instances(instance_handle); -- Sharing (implicit from PRIMARY KEY) -- instances_shared_with(instance_id, user_handle)Recommended Additional Indexes# 1. Owner Lookups# -- For queries: WHERE instances.owner = ? CREATE INDEX idx_instances_owner ON instances(owner);Benefit: Fast retrieval of user\u0026rsquo;s owned instances\nUse case:\nSELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39;;2. Shared Instance Lookups# -- For queries: WHERE user_handle = ? CREATE INDEX idx_instances_shared_user ON instances_shared_with(user_handle);Benefit: Fast retrieval of instances shared with user\nUse case:\nSELECT i.* FROM instances i INNER JOIN instances_shared_with isw ON i.instance_id = isw.instance_id WHERE isw.user_handle = \u0026#39;bob\u0026#39;;3. Composite Owner+Handle Index# -- For unique constraint and lookups CREATE UNIQUE INDEX idx_instances_owner_handle ON instances(owner, instance_handle);Benefit: Enforces uniqueness and enables index-only scans\nUse case:\nSELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39; AND instance_handle = \u0026#39;my-service\u0026#39;;4. Embedding Dimension Filtering# -- Critical for similarity search performance CREATE INDEX idx_embeddings_project_dim ON embeddings(project_id, vector_dim);Benefit: Filters embeddings by dimension before vector comparison\nUse case:\nSELECT * FROM embeddings WHERE project_id = 123 AND vector_dim = 1536 ORDER BY vector \u0026lt;=\u0026gt; $1::vector LIMIT 10;5. Project Ownership# CREATE INDEX idx_projects_owner ON projects(owner); CREATE UNIQUE INDEX idx_projects_owner_handle ON projects(owner, project_handle);Index Analysis# Check if indexes are being used:\n-- Analyze query plan EXPLAIN ANALYZE SELECT * FROM instances WHERE owner = \u0026#39;alice\u0026#39;; -- Check index usage statistics SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch FROM pg_stat_user_indexes WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY idx_scan DESC; -- Find unused indexes SELECT schemaname, tablename, indexname FROM pg_stat_user_indexes WHERE idx_scan = 0 AND schemaname = \u0026#39;public\u0026#39;;Index Maintenance# -- Update statistics for query planner ANALYZE instances; ANALYZE instances_shared_with; ANALYZE embeddings; -- Rebuild index if fragmented REINDEX INDEX idx_instances_owner; -- Check index size SELECT indexname, pg_size_pretty(pg_relation_size(indexrelid)) AS size FROM pg_stat_user_indexes WHERE schemaname = \u0026#39;public\u0026#39; ORDER BY pg_relation_size(indexrelid) DESC;Vector Index Optimization# HNSW vs IVFFlat# Current implementation uses HNSW:\nCREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops);HNSW (Hierarchical Navigable Small World)# Pros:\nBetter recall (finds more similar results) Better query performance No training required Cons:\nSlower index build time Higher memory usage Larger index size Configuration options:\n-- Default: m=16, ef_construction=64 CREATE INDEX embedding_vector_idx ON embeddings USING hnsw (vector vector_cosine_ops) WITH (m = 16, ef_construction = 64); -- Higher quality (slower build): m=32, ef_construction=128 CREATE INDEX embedding_vector_idx_hq ON embeddings USING hnsw (vector vector_cosine_ops) WITH (m = 32, ef_construction = 128);Parameters:\nm: Number of connections per layer (default 16, range 2-100) ef_construction: Size of candidate list during build (default 64, range 4-1000) Higher values = better recall but slower build and more memory IVFFlat (Inverted File with Flat compression)# Alternative for very large datasets:\nCREATE INDEX embedding_vector_idx_ivf ON embeddings USING ivfflat (vector vector_cosine_ops) WITH (lists = 100);Pros:\nFaster index build Lower memory usage Smaller index size Cons:\nRequires training (ANALYZE before creating index) Lower recall than HNSW Need to tune lists parameter When to use:\nDataset \u0026gt;1M embeddings Build time is critical Memory constrained environment Configuration:\n-- Rule of thumb: lists = sqrt(total_rows) -- For 100K embeddings: lists = 316 -- For 1M embeddings: lists = 1000 -- Train the index ANALYZE embeddings; -- Create with appropriate lists CREATE INDEX embedding_vector_idx_ivf ON embeddings USING ivfflat (vector vector_cosine_ops) WITH (lists = 1000); -- Set probes at query time SET ivfflat.probes = 10; -- Default is 1, higher = better recallQuery-Time Optimization# For HNSW, set hnsw.ef_search:\n-- Default: ef_search = 40 -- Higher = better recall but slower queries SET hnsw.ef_search = 100; SELECT vector \u0026lt;=\u0026gt; $1::vector AS distance FROM embeddings WHERE project_id = 123 ORDER BY distance LIMIT 10;Dimension-Specific Indexes# For multi-dimensional projects:\n-- Separate indexes per common dimension CREATE INDEX idx_embeddings_768_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 768; CREATE INDEX idx_embeddings_1536_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 1536; CREATE INDEX idx_embeddings_3072_vector ON embeddings USING hnsw (vector vector_cosine_ops) WHERE vector_dim = 3072;Benefit: Smaller indexes = faster queries for specific dimensions\nCaching Strategies# 1. System Definitions Cache# System definitions rarely change:\nvar ( systemDefsCache []models.Definition systemDefsCacheMu sync.RWMutex systemDefsCacheTTL = 5 * time.Minute systemDefsCacheExp time.Time ) func GetSystemDefinitions(ctx context.Context, pool *pgxpool.Pool) ([]models.Definition, error) { systemDefsCacheMu.RLock() if time.Now().Before(systemDefsCacheExp) \u0026amp;\u0026amp; systemDefsCache != nil { defer systemDefsCacheMu.RUnlock() return systemDefsCache, nil } systemDefsCacheMu.RUnlock() // Fetch from database defs, err := db.GetDefinitionsByOwner(ctx, \u0026#34;_system\u0026#34;) if err != nil { return nil, err } // Update cache systemDefsCacheMu.Lock() systemDefsCache = defs systemDefsCacheExp = time.Now().Add(systemDefsCacheTTL) systemDefsCacheMu.Unlock() return defs, nil }2. User Instances Cache# Cache user\u0026rsquo;s instance list with short TTL:\ntype InstanceCache struct { data map[string][]models.Instance mu sync.RWMutex ttl time.Duration exp map[string]time.Time } func (c *InstanceCache) Get(userHandle string) ([]models.Instance, bool) { c.mu.RLock() defer c.mu.RUnlock() if exp, ok := c.exp[userHandle]; ok \u0026amp;\u0026amp; time.Now().Before(exp) { return c.data[userHandle], true } return nil, false } func (c *InstanceCache) Set(userHandle string, instances []models.Instance) { c.mu.Lock() defer c.mu.Unlock() c.data[userHandle] = instances c.exp[userHandle] = time.Now().Add(c.ttl) } func (c *InstanceCache) Invalidate(userHandle string) { c.mu.Lock() defer c.mu.Unlock() delete(c.data, userHandle) delete(c.exp, userHandle) }Usage:\nvar instanceCache = \u0026amp;InstanceCache{ data: make(map[string][]models.Instance), exp: make(map[string]time.Time), ttl: 30 * time.Second, } func GetUserInstances(ctx context.Context, pool *pgxpool.Pool, userHandle string) ([]models.Instance, error) { // Check cache if instances, ok := instanceCache.Get(userHandle); ok { return instances, nil } // Query database instances, err := db.GetAccessibleInstances(ctx, userHandle) if err != nil { return nil, err } // Cache results instanceCache.Set(userHandle, instances) return instances, nil }3. Project Metadata Cache# Cache project metadata including schema:\ntype ProjectCache struct { projects map[string]*models.Project // key: \u0026#34;owner/handle\u0026#34; mu sync.RWMutex ttl time.Duration } func (c *ProjectCache) Get(owner, handle string) (*models.Project, bool) { key := fmt.Sprintf(\u0026#34;%s/%s\u0026#34;, owner, handle) c.mu.RLock() defer c.mu.RUnlock() project, ok := c.projects[key] return project, ok }4. Redis-Based Caching# For distributed deployments:\nimport \u0026#34;github.com/go-redis/redis/v8\u0026#34; type RedisCache struct { client *redis.Client ttl time.Duration } func (c *RedisCache) GetProject(ctx context.Context, owner, handle string) (*models.Project, error) { key := fmt.Sprintf(\u0026#34;project:%s:%s\u0026#34;, owner, handle) data, err := c.client.Get(ctx, key).Bytes() if err == redis.Nil { return nil, nil // Not in cache } else if err != nil { return nil, err } var project models.Project err = json.Unmarshal(data, \u0026amp;project) return \u0026amp;project, err } func (c *RedisCache) SetProject(ctx context.Context, project *models.Project) error { key := fmt.Sprintf(\u0026#34;project:%s:%s\u0026#34;, project.Owner, project.Handle) data, err := json.Marshal(project) if err != nil { return err } return c.client.Set(ctx, key, data, c.ttl).Err() }Cache Invalidation# Always invalidate cache on updates:\nfunc UpdateProject(ctx context.Context, pool *pgxpool.Pool, project *models.Project) error { // Update database err := db.UpdateProject(ctx, project) if err != nil { return err } // Invalidate cache projectCache.Invalidate(project.Owner, project.Handle) return nil }Connection Pool Optimization# Pool Configuration# func InitDB(opts *models.Options) *pgxpool.Pool { config, err := pgxpool.ParseConfig(connString) if err != nil { log.Fatal(err) } // Connection pool settings config.MaxConns = 20 // Max concurrent connections config.MinConns = 5 // Keep-alive connections config.MaxConnLifetime = time.Hour // Recycle connections config.MaxConnIdleTime = 5 * time.Minute // Close idle connections config.HealthCheckPeriod = time.Minute // Health check frequency // Statement cache config.ConnConfig.StatementCacheCapacity = 100 pool, err := pgxpool.NewWithConfig(context.Background(), config) return pool }Pool Sizing# General rule:\nMaxConns = (available_cores * 2) + effective_spindle_countExample scenarios:\n4-core CPU, SSD: MaxConns = 10-20 8-core CPU, SSD: MaxConns = 20-40 Under heavy load: Start conservative, increase based on monitoring Monitor Pool Usage# func monitorPool(pool *pgxpool.Pool) { ticker := time.NewTicker(30 * time.Second) for range ticker.C { stat := pool.Stat() log.Printf(\u0026#34;Pool stats: total=%d, idle=%d, acquired=%d, waiting=%d\u0026#34;, stat.TotalConns(), stat.IdleConns(), stat.AcquiredConns(), stat.MaxConns()-stat.TotalConns(), ) } }Performance Testing# Load Testing Setup# Use vegeta for HTTP load testing:\n# Install vegeta go install github.com/tsenart/vegeta@latest # Create targets file cat \u0026gt; targets.txt \u0026lt;\u0026lt;EOF GET http://localhost:8880/v1/projects/alice Authorization: Bearer alice_api_key POST http://localhost:8880/v1/similars/alice/project1/doc1 Authorization: Bearer alice_api_key Content-Type: application/json GET http://localhost:8880/v1/embeddings/alice/project1?limit=100 Authorization: Bearer alice_api_key EOF # Run load test echo \u0026#34;GET http://localhost:8880/v1/projects/alice\u0026#34; | \\ vegeta attack -duration=60s -rate=100 -header=\u0026#34;Authorization: Bearer key\u0026#34; | \\ vegeta reportBenchmark Tests# Create Go benchmarks:\nfunc BenchmarkGetAccessibleInstances(b *testing.B) { pool := setupBenchmarkDB(b) defer pool.Close() // Create test data createTestInstances(b, pool, 1000) ctx := context.Background() b.ResetTimer() for i := 0; i \u0026lt; b.N; i++ { _, err := db.GetAllAccessibleInstances(ctx, \u0026#34;testuser\u0026#34;, 10, 0) if err != nil { b.Fatal(err) } } } func BenchmarkSimilaritySearch(b *testing.B) { pool := setupBenchmarkDB(b) defer pool.Close() // Create embeddings createTestEmbeddings(b, pool, 10000) ctx := context.Background() queryVector := generateRandomVector(1536) b.ResetTimer() for i := 0; i \u0026lt; b.N; i++ { _, err := SearchSimilar(ctx, pool, \u0026#34;alice\u0026#34;, \u0026#34;project1\u0026#34;, queryVector, 10, 0.5) if err != nil { b.Fatal(err) } } }Run benchmarks:\n# Run all benchmarks go test -bench=. -benchmem ./... # Run specific benchmark go test -bench=BenchmarkSimilaritySearch -benchmem ./internal/handlers # Compare before/after go test -bench=. -benchmem ./... \u0026gt; old.txt # Make changes go test -bench=. -benchmem ./... \u0026gt; new.txt benchcmp old.txt new.txtDatabase Performance Testing# Test with realistic data:\n-- Generate test data INSERT INTO embeddings (project_id, text_id, vector, vector_dim, metadata) SELECT 1, \u0026#39;doc_\u0026#39; || generate_series, array_fill(random()::real, ARRAY[1536])::vector, 1536, \u0026#39;{\u0026#34;author\u0026#34;: \u0026#34;test\u0026#34;}\u0026#39;::jsonb FROM generate_series(1, 100000); -- Test query performance EXPLAIN (ANALYZE, BUFFERS) SELECT text_id, vector \u0026lt;=\u0026gt; $1::vector AS distance FROM embeddings WHERE project_id = 1 AND vector_dim = 1536 ORDER BY distance LIMIT 10;Metrics and Monitoring# Application Metrics# Track key metrics:\ntype Metrics struct { QueryDuration prometheus.Histogram QueryCount prometheus.Counter CacheHits prometheus.Counter CacheMisses prometheus.Counter PoolWaitDuration prometheus.Histogram } func recordQueryMetrics(start time.Time, query string) { duration := time.Since(start).Seconds() metrics.QueryDuration.Observe(duration) metrics.QueryCount.Inc() }PostgreSQL Metrics# Monitor database performance:\n-- Slow queries SELECT query, calls, total_time, mean_time, max_time FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 10; -- Table statistics SELECT schemaname, tablename, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup FROM pg_stat_user_tables; -- Index usage SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch FROM pg_stat_user_indexes ORDER BY idx_scan DESC;Performance Targets# Based on typical usage:\nOperation Target Acceptable Action Required Single instance lookup \u0026lt; 10ms \u0026lt; 50ms \u0026gt; 50ms List accessible instances (\u0026lt;100) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Create/update instance \u0026lt; 100ms \u0026lt; 200ms \u0026gt; 200ms Similarity search (10 results) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Similarity search (100 results) \u0026lt; 100ms \u0026lt; 200ms \u0026gt; 200ms Embedding insert (single) \u0026lt; 50ms \u0026lt; 100ms \u0026gt; 100ms Embedding batch (100) \u0026lt; 500ms \u0026lt; 1000ms \u0026gt; 1000ms Implementation Priority# High Priority# Profile current performance with realistic data Add dimension filtering index: idx_embeddings_project_dim Monitor slow queries with pg_stat_statements Medium Priority# Implement UNION ALL optimization if GetAllAccessibleInstances \u0026gt; 100ms Add caching for system definitions Optimize connection pool settings based on load Low Priority# Add Redis caching layer for high-traffic deployments Implement application metrics with Prometheus Add additional indexes based on actual query patterns Tune HNSW parameters for specific use cases General Best Practices# 1. Measure Before Optimizing# # Profile in production EXPLAIN ANALYZE your_query; # Load test vegeta attack -duration=60s -rate=100 # Benchmark go test -bench=. -benchmem2. Start Conservative# Don\u0026rsquo;t optimize prematurely Use simple queries first Add complexity only when needed 3. Monitor Continuously# Track query performance Monitor connection pool Watch index usage Alert on slow queries 4. Document Optimizations# Note why optimization was needed Include before/after metrics Document trade-offs made Further Reading# PostgreSQL Performance Tuning pgvector Performance Guide Go Database/SQL Tutorial Connection Pool Best Practices "},{"id":33,"href":"/dhamps-vdb/deployment/security/","title":"Security Best Practices","section":"Deployment","content":"Security Best Practices# Comprehensive guide for securing your dhamps-vdb production deployment.\nSecurity Overview# dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.\nHTTPS/TLS Configuration# Why HTTPS is Required# Encryption in transit: Protects API keys and data from interception Authentication: Verifies server identity Compliance: Required by most security standards Using a Reverse Proxy# Never expose dhamps-vdb directly to the internet. Always use a reverse proxy with TLS termination.\nNginx with Let\u0026rsquo;s Encrypt# Install Certbot:\nsudo apt install nginx certbot python3-certbot-nginxConfigure nginx (/etc/nginx/sites-available/dhamps-vdb):\nupstream dhamps_backend { server 127.0.0.1:8880; keepalive 32; } server { listen 80; server_name api.example.com; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name api.example.com; # SSL certificates (managed by Certbot) ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # Modern SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers \u0026#39;ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384\u0026#39;; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # HSTS (HTTP Strict Transport Security) add_header Strict-Transport-Security \u0026#34;max-age=31536000; includeSubDomains\u0026#34; always; # Security headers add_header X-Frame-Options \u0026#34;DENY\u0026#34; always; add_header X-Content-Type-Options \u0026#34;nosniff\u0026#34; always; add_header X-XSS-Protection \u0026#34;1; mode=block\u0026#34; always; add_header Referrer-Policy \u0026#34;strict-origin-when-cross-origin\u0026#34; always; # Proxy settings location / { proxy_pass http://dhamps_backend; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection \u0026#34;\u0026#34;; # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Buffer settings proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; } # Rate limiting (optional, see below) limit_req zone=api_limit burst=20 nodelay; limit_req_status 429; }Enable site and get certificate:\nsudo ln -s /etc/nginx/sites-available/dhamps-vdb /etc/nginx/sites-enabled/ sudo certbot --nginx -d api.example.com sudo systemctl reload nginxAuto-renewal:\n# Certbot creates a systemd timer automatically sudo systemctl status certbot.timer # Test renewal sudo certbot renew --dry-runTraefik (Docker)# docker-compose.yml:\nversion: \u0026#39;3.8\u0026#39; services: traefik: image: traefik:v2.10 command: - \u0026#34;--providers.docker=true\u0026#34; - \u0026#34;--entrypoints.web.address=:80\u0026#34; - \u0026#34;--entrypoints.websecure.address=:443\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.email=admin@example.com\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\u0026#34; - \u0026#34;--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\u0026#34; ports: - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt dhamps-vdb: build: . labels: - \u0026#34;traefik.enable=true\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.rule=Host(`api.example.com`)\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.entrypoints=websecure\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb.tls.certresolver=letsencrypt\u0026#34; # Redirect HTTP to HTTPS - \u0026#34;traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.rule=Host(`api.example.com`)\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.entrypoints=web\u0026#34; - \u0026#34;traefik.http.routers.dhamps-vdb-http.middlewares=redirect-to-https\u0026#34;Caddy (Automatic HTTPS)# Caddyfile:\napi.example.com { reverse_proxy localhost:8880 # Automatic HTTPS via Let\u0026#39;s Encrypt tls admin@example.com # Security headers header { Strict-Transport-Security \u0026#34;max-age=31536000; includeSubDomains\u0026#34; X-Frame-Options \u0026#34;DENY\u0026#34; X-Content-Type-Options \u0026#34;nosniff\u0026#34; X-XSS-Protection \u0026#34;1; mode=block\u0026#34; } }API Key Management# Admin Key Security# The SERVICE_ADMINKEY has full control over the system.\nBest practices:\nGenerate securely:\nopenssl rand -base64 32 Store securely:\nPassword manager (1Password, Bitwarden) Secrets manager (Vault, AWS Secrets Manager) Never in version control Never in logs or error messages Rotate regularly:\nEvery 90 days minimum After team member departure After suspected compromise Audit usage:\nLog all admin operations Monitor for unusual activity Review regularly User API Keys# User API keys are automatically generated and encrypted before database storage.\nSecurity features:\nOne-time display: Keys shown only at creation Encrypted storage: AES-256-GCM encryption Non-recoverable: Lost keys cannot be retrieved For users:\nSecure storage:\nUse environment variables Never hardcode in applications Never commit to repositories Use HTTPS:\nAlways transmit over TLS Validate server certificates Rotate if compromised:\nDelete old user and create new one Update all client applications Bearer Token Authentication# All API requests require authentication:\ncurl -X GET https://api.example.com/v1/projects/alice \\ -H \u0026#34;Authorization: Bearer your-api-key-here\u0026#34;Security:\nUse Authorization header (not query parameters) Never log full API keys Validate on every request Use HTTPS to prevent interception Encryption Key Security# The ENCRYPTION_KEY protects all user API keys in the database.\nCritical Security Points# ⚠️ CRITICAL: If the encryption key is lost or changed, all user API keys become permanently unrecoverable.\nBest practices:\nGenerate securely:\nopenssl rand -hex 32 Backup separately:\nStore in multiple secure locations Separate from database backups Document recovery procedure Test recovery process Never rotate in production:\nCannot be changed without re-encrypting all keys Requires database migration Risk of data loss Protect at rest:\nEncrypt .env files: gpg --encrypt .env Use secrets management (Vault, AWS Secrets Manager) Restrict file permissions: chmod 600 .env Protect in transit:\nNever send over unencrypted channels Use secure channels for team sharing Avoid email/chat Encryption Details# Algorithm: AES-256-GCM Key derivation: SHA-256 hash of input key Nonce: Unique per encryption Authentication: GCM provides authentication Storage format: Base64-encoded ciphertext Disaster Recovery# Document and test recovery procedure:\n## Encryption Key Recovery Procedure 1. Retrieve backup encryption key from [location] 2. Verify key integrity: [checksum/hash] 3. Update deployment configuration 4. Restart services 5. Verify user authentication works 6. Document incidentDatabase Security# Network Security# Restrict access:\n-- In pg_hba.conf # Allow only from application server host dhamps_vdb dhamps_user 10.0.1.0/24 md5 Firewall rules:\n# UFW example sudo ufw allow from 10.0.1.0/24 to any port 5432 sudo ufw deny 5432 Use VPC/private network:\nKeep database on private network No public internet exposure VPN for remote administration Database Authentication# Strong passwords:\n# Generate secure password openssl rand -base64 32 Dedicated user:\n-- Not superuser CREATE USER dhamps_user WITH PASSWORD \u0026#39;secure_password\u0026#39;; GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user; SSL/TLS connections:\n# postgresql.conf ssl = on ssl_cert_file = \u0026#39;server.crt\u0026#39; ssl_key_file = \u0026#39;server.key\u0026#39; ssl_ca_file = \u0026#39;ca.crt\u0026#39; Database Encryption# Encryption at rest:\nUse encrypted filesystems (LUKS, dm-crypt) Cloud provider encryption (AWS RDS encryption) Transparent Data Encryption (TDE) Backup encryption:\n# Encrypt backup pg_dump -U postgres dhamps_vdb | gzip | \\ gpg --encrypt --recipient admin@example.com \u0026gt; backup.sql.gz.gpg Database Auditing# Enable audit logging:\n-- Install pgaudit CREATE EXTENSION pgaudit; -- Configure logging ALTER SYSTEM SET pgaudit.log = \u0026#39;write, ddl\u0026#39;; ALTER SYSTEM SET pgaudit.log_catalog = off; ALTER SYSTEM SET pgaudit.log_parameter = on; -- Reload config SELECT pg_reload_conf();Network Security# Firewall Configuration# # UFW example sudo ufw default deny incoming sudo ufw default allow outgoing # Allow SSH sudo ufw allow 22/tcp # Allow HTTP/HTTPS (reverse proxy) sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Application port (if not behind proxy) # sudo ufw allow from trusted_network to any port 8880 # Database (from app server only) sudo ufw allow from 10.0.1.0/24 to any port 5432 sudo ufw enableNetwork Segmentation# Deploy in isolated networks:\nInternet ↓ [Reverse Proxy] ← (DMZ/Public subnet) ↓ [dhamps-vdb] ← (Application subnet) ↓ [PostgreSQL] ← (Database subnet)Rate Limiting# Protect against abuse and DoS attacks.\nNginx:\n# Define rate limit zone http { limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=api_burst:10m rate=100r/s; } server { location /v1/ { limit_req zone=api_limit burst=20 nodelay; limit_req_status 429; proxy_pass http://dhamps_backend; } }Application-level (future enhancement):\nImplement token bucket or leaky bucket Per-user rate limits Different limits for different endpoints Backup Strategies# Database Backups# Automated daily backups:\n#!/bin/bash # /usr/local/bin/backup-dhamps.sh DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR=\u0026#34;/backups/dhamps-vdb\u0026#34; # Create backup pg_dump -U dhamps_user dhamps_vdb | gzip \u0026gt; \\ \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Encrypt backup gpg --encrypt --recipient admin@example.com \\ \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Remove unencrypted backup rm \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz\u0026#34; # Verify backup gpg --decrypt \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz.gpg\u0026#34; | gunzip | head -n 5 # Upload to offsite storage aws s3 cp \u0026#34;$BACKUP_DIR/db-$DATE.sql.gz.gpg\u0026#34; \\ s3://backups/dhamps-vdb/ --storage-class GLACIER # Cleanup old local backups (keep 7 days) find $BACKUP_DIR -name \u0026#34;db-*.sql.gz.gpg\u0026#34; -mtime +7 -delete Cron schedule:\n0 2 * * * /usr/local/bin/backup-dhamps.sh Test restores regularly:\n# Monthly restore test 0 3 1 * * /usr/local/bin/test-restore.sh Configuration Backups# # Backup environment configuration cp .env .env.backup gpg --encrypt --recipient admin@example.com .env.backup # Backup with timestamp tar czf config-$(date +%Y%m%d).tar.gz .env docker-compose.yml gpg --encrypt --recipient admin@example.com config-*.tar.gzBackup Retention Policy# Daily backups: Keep 7 days locally Weekly backups: Keep 4 weeks offsite Monthly backups: Keep 12 months in cold storage Yearly backups: Keep 7 years (compliance dependent) Offsite Backups# Always maintain offsite backups:\nCloud storage: AWS S3, Azure Blob Storage, GCP Cloud Storage Different geographic region Encrypted before upload Test restoration procedures Monitoring and Alerting# What to Monitor# Authentication failures:\n# Parse logs for 401 responses grep \u0026#34;401\u0026#34; /var/log/nginx/access.log | wc -l Unusual API usage:\nSpike in requests Requests to non-existent endpoints Large data transfers Database health:\nConnection count Query performance Disk usage Replication lag (if applicable) System resources:\nCPU usage Memory usage Disk I/O Network throughput Log Management# Centralized logging:\nELK Stack (Elasticsearch, Logstash, Kibana) Splunk Graylog CloudWatch Logs (AWS) Log retention:\nApplication logs: 30 days minimum Access logs: 90 days minimum Audit logs: 1 year minimum (compliance dependent) Log security:\nNever log API keys in full (mask: api_key=abc...xyz) Never log passwords Encrypt archived logs Restrict access to logs Alerting# Set up alerts for:\nFailed authentication attempts (\u0026gt;10/minute) Database connection failures Disk space \u0026gt;80% full Service downtime Unusual network traffic SSL certificate expiration (30 days before) Security Checklist# Use this checklist for production deployments:\nPre-Deployment# Strong, random SERVICE_ADMINKEY generated Strong, random ENCRYPTION_KEY generated (32+ chars) Strong database password set .env file encrypted or in secrets manager .env not in version control Encryption key backed up separately from database Network \u0026amp; Access# HTTPS/TLS configured with valid certificate Reverse proxy deployed (nginx/Traefik/Caddy) Firewall configured and enabled Database on private network only Rate limiting configured HSTS header enabled Security headers configured Database# PostgreSQL 11+ with pgvector installed Dedicated database user (not superuser) Strong database password SSL/TLS for database connections Database firewall rules configured pg_hba.conf restricts access by IP Regular backups configured Backup encryption enabled Restore procedure tested Application# Service runs as non-root user Debug logging disabled (SERVICE_DEBUG=false) Resource limits configured Health checks enabled Logging configured Monitoring configured Alerting configured Operations# Backup procedure documented Restore procedure documented and tested Disaster recovery plan created Security incident response plan created Key rotation schedule defined Access control documented (who has admin key) Regular security updates scheduled Compliance# Data retention policy defined Privacy policy reviewed Terms of service reviewed GDPR compliance (if applicable) Data processing agreements in place Audit logging enabled Incident Response# Suspected API Key Compromise# Immediate actions:\nIdentify compromised user Delete user (invalidates API key) Create new user with new API key Review access logs for unauthorized access Investigation:\nDetermine scope of compromise Check for data exfiltration Document incident Notification:\nNotify affected parties (if required) Document lessons learned Update security procedures Database Breach# Immediate actions:\nIsolate database server Revoke network access Change all database credentials Activate incident response team Assessment:\nDetermine data accessed Check encryption effectiveness Review audit logs Recovery:\nRestore from clean backup Apply security patches Update firewall rules Notify affected parties (if required) Document and learn Encryption Key Loss# ⚠️ CRITICAL SITUATION: If encryption key is lost, all user API keys are unrecoverable.\nRecovery attempt:\nCheck all backup locations Review documentation Contact all team members If unrecoverable:\nAll users must be deleted and recreated New API keys issued to all users All client applications must be updated Communicate timeline to users Prevention:\nReview backup procedures Add redundant backup locations Document key locations Test recovery process Security Updates# Regular Updates# Weekly: Review security advisories Monthly: Apply security patches Quarterly: Security audit and penetration testing Yearly: Full security review and compliance audit Update Procedure# Test in staging environment Backup production database and configuration Schedule maintenance window Apply updates Verify functionality Monitor for issues Subscribe to Security Advisories# PostgreSQL security announcements pgvector security updates Docker security advisories Go security advisories Operating system security updates Further Reading# OWASP Top 10 PostgreSQL Security Docker Security Best Practices Let\u0026rsquo;s Encrypt Documentation Environment Variables Reference Database Setup Guide Docker Deployment "},{"id":34,"href":"/dhamps-vdb/deployment/","title":"Deployment","section":"dhamps-vdb Documentation","content":"Deployment Guide# Deploy dhamps-vdb to production environments.\nDeployment Options# dhamps-vdb can be deployed in several ways:\nDocker Compose - Simplest option, includes PostgreSQL Docker with External Database - Production-ready setup Standalone Binary - For custom environments Kubernetes - For orchestrated deployments Production Considerations# When deploying to production:\nUse strong, randomly generated keys Enable HTTPS/TLS for all API endpoints Configure database backups Set up monitoring and logging Restrict network access to database Use environment variables for sensitive configuration Guides# Docker Deployment - Complete Docker guide Database Setup - PostgreSQL configuration Environment Variables - All configuration options Security - Security best practices "},{"id":35,"href":"/dhamps-vdb/api/endpoints/embeddings/","title":"Embeddings","section":"Endpoints","content":"Embeddings Endpoint# Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project\u0026rsquo;s LLM service instance dimensions.\nEndpoints# List Embeddings# Get all embeddings for a project with pagination support.\nEndpoint: GET /v1/embeddings/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters:\nlimit (integer, default: 10, max: 200): Maximum number of results to return offset (integer, default: 0): Pagination offset Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;This is a research document about machine learning.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ], \u0026#34;total_count\u0026#34;: 150, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 0 } Upload Embeddings (Batch)# Upload one or more embeddings to a project. Supports batch upload for efficiency.\nEndpoint: POST /v1/embeddings/{username}/{projectname}\nAuthentication: Admin, owner, or authorized editors\nRequest Body:\n{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;This is a research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc124\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Another research document.\u0026#34;, \u0026#34;vector\u0026#34;: [0.012345, -0.054321, 0.098765, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Bob Smith\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }Parameters:\nembeddings (array, required): Array of embedding objects text_id (string, required): Unique identifier for the text (URL-encoded recommended) instance_handle (string, required): Handle of the LLM service instance used vector (array of floats, required): Embedding vector vector_dim (integer, required): Number of dimensions in the vector text (string, optional): The original text metadata (object, optional): Additional metadata (validated against project schema if defined) Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Machine learning research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270], \u0026#34;vector_dim\u0026#34;: 3, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;1 embedding(s) uploaded successfully\u0026#34;, \u0026#34;uploaded\u0026#34;: [\u0026#34;doc123\u0026#34;] } Get Single Embedding# Retrieve information about a specific embedding by its text identifier.\nEndpoint: GET /v1/embeddings/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;project_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Machine learning research document.\u0026#34;, \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 } }Note: URL-encode the identifier if it contains special characters (e.g., URLs).\nExample with URL identifier:\n# URL-encoded identifier curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/https%3A%2F%2Fexample.com%2Fdoc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Delete Single Embedding# Delete a specific embedding by its text identifier.\nEndpoint: DELETE /v1/embeddings/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, or authorized editors\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs/doc123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; deleted successfully\u0026#34; } Delete All Embeddings# Delete all embeddings in a project.\nEndpoint: DELETE /v1/embeddings/{username}/{projectname}\nAuthentication: Admin or owner\nExample:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;All embeddings deleted from project alice/research-docs\u0026#34;, \u0026#34;deleted_count\u0026#34;: 150 }⚠️ Warning: This operation is irreversible.\nRequest Format Details# Text Identifiers# Text identifiers (text_id) should be:\nUnique within a project URL-encoded if they contain special characters Descriptive for easier retrieval Examples:\nSimple: \u0026quot;doc123\u0026quot;, \u0026quot;article-456\u0026quot; URL-based: \u0026quot;https://example.com/docs/123\u0026quot; (URL-encode in requests) Path-based: \u0026quot;books/chapter1/section2\u0026quot; Vector Format# Vectors must be:\nArrays of floats (float32 or float64) Matching dimensions specified in vector_dim Consistent dimensions with the project\u0026rsquo;s LLM service instance Example:\n{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003], \u0026#34;vector_dim\u0026#34;: 5 }Metadata Format# Metadata is a flexible JSON object that can contain any valid JSON data:\nSimple metadata:\n{ \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;category\u0026#34;: \u0026#34;research\u0026#34; } }Nested metadata:\n{ \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;author-123\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 2024, \u0026#34;title\u0026#34;: \u0026#34;Machine Learning Research\u0026#34; }, \u0026#34;tags\u0026#34;: [\u0026#34;AI\u0026#34;, \u0026#34;ML\u0026#34;, \u0026#34;embeddings\u0026#34;] } } Validation# Dimension Validation# The API automatically validates that:\nVector dimension consistency: The vector_dim field must match the dimensions configured in the LLM service instance Vector length verification: The actual number of elements in the vector array must match the declared vector_dim Error example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }Metadata Schema Validation# If the project has a metadataScheme defined, all uploaded embeddings\u0026rsquo; metadata will be validated against it.\nExample project schema:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Valid metadata:\n{ \u0026#34;author\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;year\u0026#34;: 2024 }Invalid metadata (missing required field):\n{ \u0026#34;year\u0026#34;: 2024 }Error response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; } Response Format# List Response# { \u0026#34;embeddings\u0026#34;: [...], \u0026#34;total_count\u0026#34;: 150, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 0 }Single Embedding Response# { \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;project_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {...} }Upload Response# { \u0026#34;message\u0026#34;: \u0026#34;3 embedding(s) uploaded successfully\u0026#34;, \u0026#34;uploaded\u0026#34;: [\u0026#34;doc123\u0026#34;, \u0026#34;doc124\u0026#34;, \u0026#34;doc125\u0026#34;] } Common Errors# 400 Bad Request - Dimension Mismatch# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }400 Bad Request - Invalid Vector# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector length (1536) does not match declared vector_dim (3072)\u0026#34; }400 Bad Request - Metadata Schema Violation# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to upload embeddings to this project\u0026#34; }404 Not Found - Project# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }404 Not Found - Embedding# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; }409 Conflict# { \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; already exists in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; } Best Practices# Batch Uploads# Upload multiple embeddings in a single request for better performance:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ {...}, {...}, {...} ] }\u0026#39;URL-Encoded Identifiers# Use URL encoding for identifiers with special characters:\nimport urllib.parse text_id = \u0026#34;https://example.com/docs/123\u0026#34; encoded_id = urllib.parse.quote(text_id, safe=\u0026#39;\u0026#39;) # Result: \u0026#34;https%3A%2F%2Fexample.com%2Fdocs%2F123\u0026#34;Metadata Design# Design metadata schemas that:\nInclude commonly queried fields Use consistent data types Validate required fields Support your similarity search filtering needs Related Documentation# Projects - Project management and configuration Similars - Similarity search using embeddings Query Parameters - Pagination and filtering options Error Handling - Complete error reference "},{"id":36,"href":"/dhamps-vdb/concepts/llm-services/","title":"LLM Services","section":"Concepts","content":"LLM Services# LLM Services configure embedding generation, defining models, dimensions, and API access.\nArchitecture# dhamps-vdb separates LLM services into two concepts:\nLLM Service Definitions# Reusable configuration templates owned by _system or users:\nPurpose: Provide standard configurations Ownership: _system (global) or individual users Contents: Endpoint, model, dimensions, API standard API Keys: Not stored (templates only) Usage: Templates for creating instances LLM Service Instances# User-specific configurations with encrypted API keys:\nPurpose: Actual service configurations users employ Ownership: Individual users Contents: Endpoint, model, dimensions, API key (encrypted) Sharing: Can be shared with other users Projects: Each project references exactly one instance System Definitions# Available Definitions# The _system user provides default definitions:\nHandle Model Dimensions API Standard openai-large text-embedding-3-large 3072 openai openai-small text-embedding-3-small 1536 openai cohere-v4 embed-multilingual-v4.0 1536 cohere gemini-embedding-001 text-embedding-004 3072 gemini Viewing System Definitions# GET /v1/llm-services/_system Authorization: Bearer user_vdb_keyReturns list of available system definitions.\nCreating Instances# From System Definition# Use a predefined system configuration:\nPUT /v1/llm-services/alice/my-openai { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;My OpenAI embeddings\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-key\u0026#34; }Inherits endpoint, model, dimensions from system definition.\nFrom User Definition# Reference a user-created definition:\nPUT /v1/llm-services/alice/custom-instance { \u0026#34;definition_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-api-key\u0026#34; }Standalone Instance# Create without a definition:\nPUT /v1/llm-services/alice/standalone { \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;Standalone OpenAI instance\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-key\u0026#34; }All fields must be specified.\nInstance Properties# Core Fields# instance_handle: Unique identifier (3-20 characters) owner: User who owns the instance endpoint: API endpoint URL api_standard: Authentication mechanism (openai, cohere, gemini) model: Model identifier dimensions: Vector dimensionality description: Human-readable description (optional) definition_id: Reference to definition (optional) API Key Storage# Write-only: Provided on create/update Encrypted: AES-256-GCM encryption Never returned: Not included in GET responses Secure: Cannot be retrieved after creation API Standards# Supported Standards# Standard Key Method Documentation openai Authorization: Bearer OpenAI Docs cohere Authorization: Bearer Cohere Docs gemini x-goog-api-key header Gemini Docs Creating API Standards# Admins can add new standards:\nPOST /v1/api-standards Authorization: Bearer ADMIN_KEY { \u0026#34;api_standard_handle\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Custom LLM API\u0026#34;, \u0026#34;key_method\u0026#34;: \u0026#34;auth_bearer\u0026#34;, \u0026#34;key_field\u0026#34;: null }Instance Management# List Instances# List all accessible instances (owned + shared):\nGET /v1/llm-services/alice Authorization: Bearer alice_vdb_keyReturns instances where alice is owner or has been granted access.\nGet Instance Details# GET /v1/llm-services/alice/my-openai Authorization: Bearer alice_vdb_keyReturns instance configuration (API key not included).\nUpdate Instance# PATCH /v1/llm-services/alice/my-openai { \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;new-api-key\u0026#34; }Only owner can update instances.\nDelete Instance# DELETE /v1/llm-services/alice/my-openai Authorization: Bearer alice_vdb_keyConstraints:\nCannot delete instance used by projects Delete projects first, then instance Instance Sharing# Share with User# POST /v1/llm-services/alice/my-openai/share { \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }Shared users can:\nUse instance in their projects View instance configuration Cannot: See API key Modify instance Delete instance Unshare from User# DELETE /v1/llm-services/alice/my-openai/share/bobList Shared Users# GET /v1/llm-services/alice/my-openai/shared-withOnly owner can view shared users.\nInstance References# In Projects# Projects reference instances by owner and handle:\n{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }In Embeddings# Embeddings reference instances by handle:\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [...] }The instance owner is inferred from the project.\nShared Instance Format# When using shared instances:\nOwn instance: \u0026quot;instance_handle\u0026quot;: \u0026quot;my-openai\u0026quot; Shared instance: Reference via project configuration\nEncryption# API Key Encryption# API keys are encrypted using AES-256-GCM:\nEncryption process:\nUser provides plaintext API key Server encrypts using ENCRYPTION_KEY from environment Encrypted bytes stored in database Key derivation: SHA-256 hash ensures 32-byte key Decryption:\nOnly occurs internally for LLM API calls Never exposed via API responses Requires same ENCRYPTION_KEY Security Notes# Encryption key: Set via ENCRYPTION_KEY environment variable Key loss: Losing encryption key means losing access to API keys Key rotation: Not currently supported Backup: Back up encryption key securely LLM Processing# Current Status# LLM processing (generating embeddings) is not yet implemented.\nFuture Implementation# Planned features:\nProcess text to generate embeddings Call external LLM APIs Store generated embeddings Batch processing support Current Workflow# Users must generate embeddings externally:\nGenerate embeddings using LLM API (OpenAI, Cohere, etc.) Upload pre-generated embeddings to dhamps-vdb Use dhamps-vdb for storage and similarity search Common Patterns# Per-Environment Instances# # Development instance PUT /v1/llm-services/alice/dev-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;dev-api-key\u0026#34; } # Production instance PUT /v1/llm-services/alice/prod-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;prod-api-key\u0026#34; }Team Shared Instance# # Owner creates instance PUT /v1/llm-services/team-lead/team-embeddings { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;team-api-key\u0026#34; } # Share with team members POST /v1/llm-services/team-lead/team-embeddings/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;member1\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} POST /v1/llm-services/team-lead/team-embeddings/share {\u0026#34;share_with_handle\u0026#34;: \u0026#34;member2\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} # Members use in their projects POST /v1/projects/member1 { \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;team-lead\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;team-embeddings\u0026#34; }Multi-Model Setup# # Large model for important documents PUT /v1/llm-services/alice/high-quality { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;api-key\u0026#34; } # Small model for drafts PUT /v1/llm-services/alice/fast-processing { \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-small\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;api-key\u0026#34; }Troubleshooting# Cannot Create Instance# Possible causes:\nInstance handle already exists Referenced definition doesn\u0026rsquo;t exist Missing required fields Invalid API standard Solutions:\nChoose different handle Verify definition: GET /v1/llm-services/_system Include all required fields Use valid API standard: GET /v1/api-standards Cannot Use Instance in Project# Possible causes:\nInstance doesn\u0026rsquo;t exist Instance not owned or shared with user Incorrect owner/handle reference Solutions:\nVerify instance exists Check instance is accessible Confirm spelling of owner and handle Dimension Mismatch# Error: \u0026ldquo;dimension validation failed\u0026rdquo;\nCause: Embedding dimensions don\u0026rsquo;t match instance\nSolutions:\nCheck instance dimensions Regenerate embeddings with correct model Create instance with correct dimensions Next Steps# Understand projects Learn about embeddings Explore instance management "},{"id":37,"href":"/dhamps-vdb/guides/metadata-validation/","title":"Metadata Validation Guide","section":"Guides","content":"Metadata Validation Guide# This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.\nOverview# dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.\nBenefits:\nEnforce consistent metadata structure across all embeddings Catch data entry errors early Document expected metadata fields Enable reliable metadata-based filtering Defining a Metadata Schema# When Creating a Project# Include a metadataScheme field with a valid JSON Schema when creating a project:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/validated-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;validated-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Project with metadata validation\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Updating an Existing Project# Add or update a metadata schema using PATCH:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;title\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;title\\\u0026#34;,\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Note: Schema updates only affect new or updated embeddings. Existing embeddings are not retroactively validated.\nCommon Schema Patterns# Simple Required Fields# Require specific fields with basic types:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Example usage:\ncurl -X POST \u0026#34;https://api.example.com/v1/projects/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literary-texts\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Literary texts with structured metadata\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39;Using Enums for Controlled Values# Restrict fields to specific allowed values:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;prose\u0026#34;, \u0026#34;drama\u0026#34;, \u0026#34;essay\u0026#34;] }, \u0026#34;language\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;en\u0026#34;, \u0026#34;de\u0026#34;, \u0026#34;fr\u0026#34;, \u0026#34;es\u0026#34;, \u0026#34;la\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;genre\u0026#34;] }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;hamlet-soliloquy\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34; } }] }\u0026#39;Nested Objects# Define structured metadata with nested objects:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;birth_year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;nationality\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;name\u0026#34;] }, \u0026#34;publication\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;publisher\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;city\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/academic-papers\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;paper001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Jane Smith\u0026#34;, \u0026#34;birth_year\u0026#34;: 1975, \u0026#34;nationality\u0026#34;: \u0026#34;USA\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 2023, \u0026#34;publisher\u0026#34;: \u0026#34;Academic Press\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Boston\u0026#34; } } }] }\u0026#39;Arrays and Lists# Define arrays of values:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;keywords\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1, \u0026#34;maxItems\u0026#34;: 10 }, \u0026#34;categories\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;philosophy\u0026#34;, \u0026#34;literature\u0026#34;, \u0026#34;science\u0026#34;, \u0026#34;history\u0026#34;] } } } }Example:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;keywords\u0026#34;: [\u0026#34;machine learning\u0026#34;, \u0026#34;embeddings\u0026#34;, \u0026#34;NLP\u0026#34;], \u0026#34;categories\u0026#34;: [\u0026#34;science\u0026#34;, \u0026#34;literature\u0026#34;] } }] }\u0026#39;Numeric Constraints# Apply minimum, maximum, and range constraints:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;rating\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0, \u0026#34;maximum\u0026#34;: 5 }, \u0026#34;page_count\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1 }, \u0026#34;confidence\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0.0, \u0026#34;maximum\u0026#34;: 1.0 } } }String Constraints# Apply length and pattern constraints:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 200 }, \u0026#34;isbn\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^[0-9]{13}$\u0026#34; }, \u0026#34;doi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^10\\\\.\\\\d{4,}/[\\\\w\\\\-\\\\.]+$\u0026#34; } } }Validation Examples# Valid Upload# When metadata conforms to the schema:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;kant-critique\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Immanuel Kant\u0026#34;, \u0026#34;year\u0026#34;: 1781, \u0026#34;genre\u0026#34;: \u0026#34;prose\u0026#34; } }] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embeddings uploaded successfully\u0026#34;, \u0026#34;count\u0026#34;: 1 }Validation Error: Missing Required Field# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;year\u0026#34;: 1781 } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - author is required\u0026#34; }Validation Error: Wrong Type# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;year\u0026#34;: \u0026#34;1781\u0026#34; } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - year: expected integer, got string\u0026#34; }Validation Error: Invalid Enum Value# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literary-texts\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;some-text\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;year\u0026#34;: 1781, \u0026#34;genre\u0026#34;: \u0026#34;novel\u0026#34; } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;some-text\u0026#39;: metadata validation failed:\\n - genre: value must be one of: poetry, prose, drama, essay\u0026#34; }Validation Error: Value Out of Range# curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/rated-content\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;review001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;rating\u0026#34;: 7.5 } }] }\u0026#39;Error Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/ErrorModel.json\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;review001\u0026#39;: metadata validation failed:\\n - rating: must be \u0026lt;= 5\u0026#34; }Real-World Schema Examples# Academic Publications# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;doi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^10\\\\.\\\\d{4,}/[\\\\w\\\\-\\\\.]+$\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 500 }, \u0026#34;authors\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1 }, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1900, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;journal\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;volume\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;}, \u0026#34;pages\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;keywords\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;doi\u0026#34;, \u0026#34;title\u0026#34;, \u0026#34;authors\u0026#34;, \u0026#34;year\u0026#34;] }Legal Documents# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;case_number\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;court\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;date\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^\\\\d{4}-\\\\d{2}-\\\\d{2}$\u0026#34; }, \u0026#34;jurisdiction\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;federal\u0026#34;, \u0026#34;state\u0026#34;, \u0026#34;local\u0026#34;] }, \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;civil\u0026#34;, \u0026#34;criminal\u0026#34;, \u0026#34;administrative\u0026#34;] }, \u0026#34;parties\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;case_number\u0026#34;, \u0026#34;court\u0026#34;, \u0026#34;date\u0026#34;] }Product Catalog# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;sku\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;^[A-Z]{3}-\\\\d{6}$\u0026#34; }, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;electronics\u0026#34;, \u0026#34;clothing\u0026#34;, \u0026#34;books\u0026#34;, \u0026#34;home\u0026#34;, \u0026#34;toys\u0026#34;] }, \u0026#34;price\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0 }, \u0026#34;in_stock\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34;}, \u0026#34;tags\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} } }, \u0026#34;required\u0026#34;: [\u0026#34;sku\u0026#34;, \u0026#34;name\u0026#34;, \u0026#34;category\u0026#34;, \u0026#34;price\u0026#34;] }Admin Sanity Check# Administrators can verify database integrity using the /v1/admin/sanity-check endpoint:\ncurl -X GET \u0026#34;https://api.example.com/v1/admin/sanity-check\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34;Response:\n{ \u0026#34;status\u0026#34;: \u0026#34;PASSED\u0026#34;, \u0026#34;total_projects\u0026#34;: 5, \u0026#34;issues_count\u0026#34;: 0, \u0026#34;warnings_count\u0026#34;: 1, \u0026#34;warnings\u0026#34;: [ \u0026#34;Project alice/project1 has 100 embeddings but no metadata schema defined\u0026#34; ] }Status Values:\nPASSED: No issues or warnings found WARNING: No critical issues, but warnings exist FAILED: Validation issues found that need attention The sanity check:\nValidates all embeddings have dimensions matching their LLM service Validates all metadata against project schemas (if defined) Reports projects without schemas as warnings Best Practices# 1. Start Simple, Add Complexity Later# Begin with basic required fields:\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;source\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;source\u0026#34;] }Add more constraints as your needs evolve.\n2. Test Schemas Before Deployment# Use online JSON Schema validators like jsonschemavalidator.net to test your schemas before deploying them.\n3. Document Your Schema# Include a description in your project:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Project with metadata schema: author (required string), year (integer), genre (enum)\u0026#34; }\u0026#39;4. Version Your Schemas# If you need to change a schema significantly, consider creating a new project rather than updating the existing one.\n5. Optional vs Required# Be judicious with required fields. Too many required fields can make uploads cumbersome.\n6. Escape JSON Properly# When passing JSON schemas in curl commands, escape quotes properly or use single quotes for the outer JSON.\nProjects Without Schemas# If you don\u0026rsquo;t provide a metadataScheme when creating a project:\nMetadata validation is skipped You can upload any valid JSON metadata This is useful for exploratory work or heterogeneous data Schema Updates and Existing Data# When you update a project\u0026rsquo;s metadata schema:\nExisting embeddings are not revalidated The new schema only applies to new or updated embeddings Use the admin sanity check to find existing embeddings that don\u0026rsquo;t conform Removing a Schema# To remove metadata validation from a project:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;metadataScheme\u0026#34;: null}\u0026#39;After this, new embeddings can have any metadata structure.\nRelated Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Filtering Guide - Filter search results by metadata Batch Operations Guide - Upload large datasets efficiently Troubleshooting# Schema Syntax Errors# Error: \u0026ldquo;Invalid JSON Schema\u0026rdquo;\nSolution: Validate your schema syntax using an online validator. Common issues:\nMissing commas between properties Unescaped quotes Invalid JSON structure Uploads Failing After Schema Change# Problem: Uploads worked before, now failing with validation errors\nSolution: Check that your metadata matches the new schema requirements. Review the error message for specific validation failures.\nWant to Fix Non-Conforming Data# Problem: Sanity check shows validation errors in existing data\nSolution: Either:\nUpdate the schema to accept existing data Re-upload conforming data to replace non-conforming embeddings Delete and re-upload the project with correct metadata "},{"id":38,"href":"/dhamps-vdb/development/","title":"Development","section":"dhamps-vdb Documentation","content":"Development Guide# Information for developers contributing to dhamps-vdb.\nGetting Started with Development# This section covers:\nSetting up a development environment Running tests Understanding the codebase architecture Contributing guidelines Performance optimization Project Structure# dhamps-vdb/ ├── main.go # Application entry point ├── internal/ │ ├── auth/ # Authentication logic │ ├── database/ # Database layer (sqlc) │ ├── handlers/ # HTTP handlers │ └── models/ # Data models ├── testdata/ # Test fixtures └── docs/ # DocumentationDevelopment Workflow# Make changes to code Generate sqlc code if database queries changed: sqlc generate Run tests: go test -v ./... Build: go build -o dhamps-vdb main.go Submit pull request Resources# Testing - How to run tests Contributing - Contribution guidelines Architecture - Technical deep-dive Performance - Optimization notes "},{"id":39,"href":"/dhamps-vdb/guides/metadata-filtering/","title":"Metadata Filtering Guide","section":"Guides","content":"Metadata Filtering Guide# This guide explains how to use metadata filtering to exclude specific documents from similarity search results.\nOverview# When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:\nExclude documents from the same author when finding similar writing styles Filter out documents from the same source when finding related content Exclude documents with the same category when exploring diversity dhamps-vdb provides metadata filtering using query parameters that perform negative matching - they exclude documents where the metadata field matches the specified value.\nQuery Parameters# Both similarity search endpoints support metadata filtering:\nmetadata_path: The JSON path to the metadata field (e.g., author, source.id, tags[0]) metadata_value: The value to exclude from results Both parameters must be used together. If you specify one without the other, the API returns an error.\nBasic Filtering Examples# Exclude Documents by Author# Find similar documents but exclude those from the same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/literary-corpus/hamlet-soliloquy?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=William%20Shakespeare\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This returns similar documents, excluding any with metadata.author == \u0026quot;William Shakespeare\u0026quot;.\nExclude Documents from Same Source# Find similar content from different sources:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/news-articles/article123?count=10\u0026amp;metadata_path=source\u0026amp;metadata_value=NYTimes\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This excludes any documents with metadata.source == \u0026quot;NYTimes\u0026quot;.\nExclude by Category# Find documents in different categories:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/products/product456?count=10\u0026amp;metadata_path=category\u0026amp;metadata_value=electronics\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This excludes any documents with metadata.category == \u0026quot;electronics\u0026quot;.\nFiltering with Raw Embeddings# Metadata filtering also works when searching with raw embedding vectors:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/literary-corpus?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=William%20Shakespeare\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [0.032, -0.018, 0.056, ...] }\u0026#39;This searches using the provided vector but excludes documents where metadata.author == \u0026quot;William Shakespeare\u0026quot;.\nNested Metadata Paths# For nested metadata objects, use dot notation:\nExample Metadata Structure# { \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Jane Doe\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;author123\u0026#34;, \u0026#34;affiliation\u0026#34;: \u0026#34;University\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;journal\u0026#34;: \u0026#34;Science\u0026#34;, \u0026#34;year\u0026#34;: 2023 } }Filter by Nested Field# # Exclude documents from same author ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/papers/paper001?count=10\u0026amp;metadata_path=author.id\u0026amp;metadata_value=author123\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Exclude documents from same journal curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/papers/paper001?count=10\u0026amp;metadata_path=publication.journal\u0026amp;metadata_value=Science\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Combining with Other Parameters# Metadata filtering works seamlessly with other search parameters:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/documents/doc123?count=20\u0026amp;threshold=0.8\u0026amp;limit=10\u0026amp;offset=0\u0026amp;metadata_path=source_id\u0026amp;metadata_value=src_456\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Parameters:\ncount=20: Consider top 20 similar documents threshold=0.8: Only include documents with similarity ≥ 0.8 limit=10: Return at most 10 results offset=0: Start from first result (for pagination) metadata_path=source_id: Filter on this metadata field metadata_value=src_456: Exclude documents with this value Use Cases# 1. Finding Similar Writing Styles Across Authors# When analyzing writing styles, you want similar texts from different authors:\n# Upload documents with author metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/writing-styles\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy-passage-1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Happy families are all alike...\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Leo Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Anna Karenina\u0026#34;, \u0026#34;language\u0026#34;: \u0026#34;Russian\u0026#34; } }] }\u0026#39; # Find similar writing styles from other authors curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/writing-styles/tolstoy-passage-1?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=Leo%20Tolstoy\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;2. Cross-Source Content Discovery# Find related news articles from different sources:\n# Search for similar content, excluding same source curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/news-corpus/nyt-article-456?count=15\u0026amp;metadata_path=source\u0026amp;metadata_value=New%20York%20Times\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This helps discover how different outlets cover similar topics.\n3. Product Recommendations Across Categories# Find similar products in different categories:\n# User is viewing a laptop curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/product-catalog/laptop-001?count=10\u0026amp;threshold=0.7\u0026amp;metadata_path=category\u0026amp;metadata_value=electronics\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This could recommend accessories, furniture (for home office), or other complementary items.\n4. Research Paper Discovery# Find related papers from different research groups:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-papers/paper123?count=20\u0026amp;metadata_path=lab_id\u0026amp;metadata_value=lab_abc_001\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Helps researchers discover related work from other institutions.\n5. Avoiding Duplicate Content# When building a diverse content feed, exclude items from the same collection:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/blog-posts/post789?count=5\u0026amp;metadata_path=collection_id\u0026amp;metadata_value=series_xyz\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;6. Cross-Language Document Discovery# Find similar documents in other languages:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/multilingual-docs/doc_en_123?count=10\u0026amp;metadata_path=language\u0026amp;metadata_value=en\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;This finds semantically similar documents in languages other than English.\nWorking with Multiple Values# Currently, you can only filter by one metadata field at a time. To exclude multiple values, you need to:\nMake multiple requests and merge results in your application Use more specific metadata fields that combine multiple attributes Post-process results on the client side Example: Excluding Multiple Authors# import requests def find_similar_excluding_authors(doc_id, exclude_authors): \u0026#34;\u0026#34;\u0026#34;Find similar docs excluding multiple authors\u0026#34;\u0026#34;\u0026#34; all_results = [] for author in exclude_authors: response = requests.get( f\u0026#34;https://api.example.com/v1/similars/alice/corpus/{doc_id}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;}, params={ \u0026#34;count\u0026#34;: 20, \u0026#34;metadata_path\u0026#34;: \u0026#34;author\u0026#34;, \u0026#34;metadata_value\u0026#34;: author } ) results = response.json()[\u0026#39;results\u0026#39;] all_results.extend(results) # Deduplicate and sort by similarity seen = set() unique_results = [] for r in sorted(all_results, key=lambda x: x[\u0026#39;similarity\u0026#39;], reverse=True): if r[\u0026#39;id\u0026#39;] not in seen: seen.add(r[\u0026#39;id\u0026#39;]) unique_results.append(r) return unique_results[:10] # Usage similar = find_similar_excluding_authors( \u0026#34;doc123\u0026#34;, [\u0026#34;Author A\u0026#34;, \u0026#34;Author B\u0026#34;, \u0026#34;Author C\u0026#34;] )Combining with Metadata Validation# For reliable filtering, combine with metadata schema validation:\n# Step 1: Create project with metadata schema curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/validated-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;validated-corpus\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Corpus with validated metadata\u0026#34;, \u0026#34;instance_id\u0026#34;: 123, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;source_id\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;,\\\u0026#34;source_id\\\u0026#34;]}\u0026#34; }\u0026#39; # Step 2: Upload embeddings with metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/validated-corpus\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;source_id\u0026#34;: \u0026#34;source_123\u0026#34; } }] }\u0026#39; # Step 3: Search with guaranteed metadata field existence curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/validated-corpus/doc001?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;See the Metadata Validation Guide for more details.\nUnderstanding the Filter Logic# The metadata filter uses negative matching:\nINCLUDE document IF: - document.similarity \u0026gt;= threshold AND - document.metadata[metadata_path] != metadata_valueImportant: Documents without the specified metadata field are included (not filtered out).\nExample# Given this query:\n?metadata_path=author\u0026amp;metadata_value=AliceIncluded:\nDocuments where metadata.author == \u0026quot;Bob\u0026quot; Documents where metadata.author == \u0026quot;Charlie\u0026quot; Documents without an author field in metadata Excluded:\nDocuments where metadata.author == \u0026quot;Alice\u0026quot; Performance Considerations# Metadata filtering is performed at the database level using efficient indexing:\nVector similarity is computed first Metadata filter is applied to the similarity results Results are sorted and limited For best performance:\nUse indexed metadata fields when possible Keep metadata values relatively small (under 1KB per document) Consider using IDs instead of full names for filtering Error Handling# Missing One Parameter# # Missing metadata_value curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Error:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata_path and metadata_value must be used together\u0026#34; }Non-Existent Metadata Field# # Filtering on field that doesn\u0026#39;t exist in documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?count=10\u0026amp;metadata_path=nonexistent_field\u0026amp;metadata_value=some_value\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Result: Returns all matching documents (since none have the field, none are excluded).\nURL Encoding# Remember to URL-encode metadata values with special characters:\n# Correct: URL-encoded value curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026amp;metadata_value=John%20Doe%20%26%20Jane%20Smith\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Incorrect: Unencoded special characters curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author\u0026amp;metadata_value=John Doe \u0026amp; Jane Smith\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Complete Example# Here\u0026rsquo;s a complete workflow demonstrating metadata filtering:\n# 1. Create project curl -X POST \u0026#34;https://api.example.com/v1/projects/alice/literature\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;literature\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39; # 2. Upload documents with metadata curl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/literature\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy_1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;All happy families...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Anna Karenina\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;tolstoy_2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.11, 0.21, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;It was the best of times...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Tolstoy\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;War and Peace\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;dickens_1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.12, 0.19, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;It was the age of wisdom...\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Dickens\u0026#34;, \u0026#34;work\u0026#34;: \u0026#34;Tale of Two Cities\u0026#34;} } ] }\u0026#39; # 3. Find similar to tolstoy_1, excluding Tolstoy\u0026#39;s works curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/literature/tolstoy_1?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=Tolstoy\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Result: Returns dickens_1, excludes tolstoy_2Related Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Schema validation Batch Operations Guide - Upload large datasets Troubleshooting# No Results Returned# Problem: Filter excludes all results\nSolution:\nVerify the metadata field exists in your documents Check that the metadata value matches exactly (case-sensitive) Try without the filter to ensure there are similar documents Filter Not Working# Problem: Still seeing documents you want to exclude\nSolution:\nCheck URL encoding of the metadata value Verify the metadata path is correct (use dot notation for nested fields) Ensure both metadata_path and metadata_value are specified Want Positive Matching# Problem: Want to include only specific values, not exclude them\nSolution: Currently, only negative matching (exclusion) is supported. For positive matching, retrieve all results and filter on the client side, or use multiple negative filters to exclude everything except your target values.\n"},{"id":40,"href":"/dhamps-vdb/concepts/similarity-search/","title":"Similarity Search","section":"Concepts","content":"Similarity Search# Find documents with similar semantic meaning using vector similarity.\nHow it Works# Similarity search compares embedding vectors using cosine distance:\nQuery vector: Either from stored embedding or raw vector Comparison: Calculate cosine similarity with all project embeddings Filtering: Apply threshold and metadata filters Ranking: Sort by similarity score (highest first) Return: Top N most similar documents Search Methods# Stored Document Search (GET)# Find documents similar to an already-stored embedding:\nGET /v1/similars/alice/research/doc1?count=10\u0026amp;threshold=0.7Use cases:\nFind related documents Discover similar passages Identify duplicates Raw Vector Search (POST)# Search using a new embedding without storing it:\nPOST /v1/similars/alice/research?count=10\u0026amp;threshold=0.7 { \u0026#34;vector\u0026#34;: [0.023, -0.015, ..., 0.042] }Use cases:\nQuery without saving Test embeddings Real-time search Query Parameters# count# Number of similar documents to return.\nType: Integer Range: 1-200 Default: 10 GET /v1/similars/alice/project/doc1?count=5threshold# Minimum similarity score (0-1).\nType: Float Range: 0.0-1.0 Default: 0.5 Meaning: 1.0 = identical, 0.0 = unrelated GET /v1/similars/alice/project/doc1?threshold=0.8limit# Maximum number of results (same as count).\nType: Integer Range: 1-200 Default: 10 offset# Skip first N results (pagination).\nType: Integer Minimum: 0 Default: 0 # First page GET /v1/similars/alice/project/doc1?limit=10\u0026amp;offset=0 # Second page GET /v1/similars/alice/project/doc1?limit=10\u0026amp;offset=10metadata_path# JSON path to metadata field for filtering.\nType: String Purpose: Specify metadata field to filter Must be used with: metadata_value ?metadata_path=authormetadata_value# Value to exclude from results.\nType: String Purpose: Exclude documents matching this value Must be used with: metadata_path ?metadata_path=author\u0026amp;metadata_value=ShakespeareImportant: Excludes matches, doesn\u0026rsquo;t include them.\nSimilarity Scores# Cosine Similarity# dhamps-vdb uses cosine similarity:\nsimilarity = 1 - cosine_distanceScore ranges:\n1.0: Identical vectors 0.9-1.0: Very similar 0.7-0.9: Similar 0.5-0.7: Somewhat similar \u0026lt;0.5: Not similar Interpreting Scores# Typical thresholds:\n0.9+: Duplicates or near-duplicates 0.8+: Strong semantic similarity 0.7+: Related topics 0.5-0.7: Weak relation \u0026lt;0.5: Unrelated Optimal threshold depends on your use case and model.\nMetadata Filtering# Exclude by Field# Exclude documents where metadata field matches value:\n# Exclude documents from same author GET /v1/similars/alice/lit-study/hamlet-act1?metadata_path=author\u0026amp;metadata_value=ShakespeareResult: Returns similar documents, excluding those with metadata.author == \u0026quot;Shakespeare\u0026quot;.\nNested Fields# Use dot notation for nested metadata:\n# Exclude documents from same author.name GET /v1/similars/alice/project/doc1?metadata_path=author.name\u0026amp;metadata_value=John%20DoeCommon Patterns# Exclude same work:\n?metadata_path=title\u0026amp;metadata_value=HamletExclude same source:\n?metadata_path=source_id\u0026amp;metadata_value=corpus-AExclude same category:\n?metadata_path=category\u0026amp;metadata_value=tutorialSee Metadata Filtering Guide for details.\nResponse Format# { \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc5\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc8\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Fields:\nuser_handle: Project owner project_handle: Project identifier results: Array of similar documents id: Document text_id similarity: Similarity score (0-1) Results are sorted by similarity (highest first).\nPerformance# Query Speed# Typical performance:\n\u0026lt;10K embeddings: \u0026lt;10ms 10K-100K embeddings: 10-50ms 100K-1M embeddings: 50-200ms \u0026gt;1M embeddings: 200-1000ms Optimization# HNSW Index:\nFaster queries than IVFFlat Better recall Larger index size Query optimization:\nUse appropriate threshold (higher = fewer results) Limit result count (lower = faster) Consider dimension reduction for large projects Scaling# For large datasets:\nMonitor query performance Consider read replicas Use connection pooling Cache frequent queries (application level) Common Use Cases# RAG Workflow# Retrieval Augmented Generation:\n# 1. User query query=\u0026#34;What is machine learning?\u0026#34; # 2. Generate query embedding (external) query_vector=[...] # 3. Find similar documents POST /v1/similars/alice/knowledge-base?count=5\u0026amp;threshold=0.7 {\u0026#34;vector\u0026#34;: $query_vector} # 4. Retrieve full text for top results for each result: GET /v1/embeddings/alice/knowledge-base/$result_id # 5. Send context to LLM for generationDuplicate Detection# Find near-duplicate documents:\n# High threshold for duplicates GET /v1/similars/alice/corpus/doc1?count=10\u0026amp;threshold=0.95Documents with similarity \u0026gt; 0.95 are likely duplicates.\nContent Discovery# Find related content:\n# Moderate threshold for recommendations GET /v1/similars/alice/articles/article1?count=10\u0026amp;threshold=0.7\u0026amp;metadata_path=article_id\u0026amp;metadata_value=article1Excludes the source article itself.\nTopic Clustering# Find documents on similar topics:\n# For each document, find similar ones for doc in documents: GET /v1/similars/alice/corpus/$doc?count=20\u0026amp;threshold=0.8Group documents by similarity for clustering.\nDimension Consistency# Automatic Filtering# Similarity queries only compare embeddings with matching dimensions:\nProject embeddings: - doc1: 3072 dimensions - doc2: 3072 dimensions - doc3: 1536 dimensions (different model) Query for doc1 similars: → Only compares with doc2 → Ignores doc3 (dimension mismatch)Multiple Instances# Projects can have embeddings from multiple instances (if dimensions match):\n{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector_dim\u0026#34;: 3072 } { \u0026#34;text_id\u0026#34;: \u0026#34;doc2\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-model\u0026#34;, \u0026#34;vector_dim\u0026#34;: 3072 }Both searchable together (same dimensions).\nAccess Control# Authentication# Similarity search respects project access control:\nOwner: Full access Editor: Can search (read permission) Reader: Can search (read permission) Public (if public_read=true): Can search (no auth required)\nPublic Projects# Public projects allow unauthenticated similarity search:\n# No Authorization header needed GET /v1/similars/alice/public-project/doc1?count=10See Public Projects Guide.\nLimitations# Current Constraints# No cross-project search: Similarity search is per-project only No filtering by multiple metadata fields: One field at a time No custom distance metrics: Cosine similarity only No approximate search tuning: Uses default HNSW parameters Workarounds# Cross-project search:\nQuery each project separately Merge results in application Multiple metadata filters:\nFilter by one field in query Apply additional filters in application Troubleshooting# No Results Returned# Possible causes:\nThreshold too high No embeddings in project Dimension mismatch All results filtered by metadata Solutions:\nLower threshold (try 0.5) Verify embeddings exist Check dimensions match Remove metadata filter Unexpected Results# Possible causes:\nThreshold too low Poor quality embeddings Incorrect model used Metadata filter excluding desired results Solutions:\nIncrease threshold Regenerate embeddings Verify correct model/dimensions Adjust metadata filter Slow Queries# Possible causes:\nLarge dataset (\u0026gt;100K embeddings) No vector index High result count Complex metadata filtering Solutions:\nReduce result count Check index exists Optimize database Use read replicas Next Steps# Learn about metadata filtering Understand RAG workflows Explore embeddings "},{"id":41,"href":"/dhamps-vdb/api/endpoints/similars/","title":"Similars","section":"Endpoints","content":"Similarity Search Endpoints# Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.\nEndpoints# GET Similar Documents (from stored embeddings)# Find documents similar to an already-stored document by its text identifier.\nEndpoint: GET /v1/similars/{username}/{projectname}/{identifier}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters:\ncount (integer, optional, default: 10, max: 200): Number of similar documents to return threshold (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold limit (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for count) offset (integer, optional, default: 0): Pagination offset metadata_path (string, optional): Metadata field path for filtering (must be used with metadata_value) metadata_value (string, optional): Metadata value to exclude from results (must be used with metadata_path) Example - Basic search:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Example - With metadata filtering:\n# Exclude documents with author=\u0026#34;John Doe\u0026#34; curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/SimilarResponseBody.json\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc321\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] } POST Similar Documents (from raw embeddings)# Find similar documents by submitting a raw embedding vector without storing it in the database. Useful for one-time queries or testing.\nEndpoint: POST /v1/similars/{username}/{projectname}\nAuthentication: Admin, owner, authorized readers, or public if public_read is enabled\nQuery Parameters: Same as GET endpoint above\nRequest Body:\n{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003, ...] }The vector must be an array of float values with dimensions matching the project\u0026rsquo;s LLM service instance configuration.\nExample - Basic search:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026amp;threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] }\u0026#39;Example - With metadata filtering:\n# Exclude documents from the same category curl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=5\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...] }\u0026#39;Response: Same format as GET endpoint\nQuery Parameters Reference# count / limit# Maximum number of similar documents to return.\nType: Integer Default: 10 Max: 200 Note: count and limit are aliases; use either one Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026#34; threshold# Minimum similarity score threshold. Only documents with similarity scores \u0026gt;= threshold are returned.\nType: Float Default: 0.5 Range: 0.0 to 1.0 (where 1.0 is most similar) Example:\n# Only return very similar documents (\u0026gt;= 0.8) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8\u0026#34; offset# Pagination offset for large result sets.\nType: Integer Default: 0 Use: Skip the first N results Example:\n# Get results 21-40 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=20\u0026#34; metadata_path# Metadata field path for filtering results. Must be used together with metadata_value.\nType: String Format: JSON path notation (e.g., \u0026quot;author\u0026quot;, \u0026quot;author.name\u0026quot;, \u0026quot;publication.year\u0026quot;) Use: Exclude documents where metadata field matches a specific value Examples:\n# Simple field metadata_path=author # Nested field metadata_path=author.name # Deeply nested field metadata_path=publication.journal.name metadata_value# Metadata value to exclude from results. Must be used together with metadata_path.\nType: String Use: Excludes documents where the metadata field at metadata_path equals this value Example - Exclude same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=Alice%20Doe\u0026#34;Example - Exclude same category:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=research\u0026#34;Example - Nested field:\n# Exclude documents from same author ID curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id\u0026amp;metadata_value=A0083\u0026#34; Response Format# Both GET and POST endpoints return the same response format:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;http://localhost:8080/schemas/SimilarResponseBody.json\u0026#34;, \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 }, { \u0026#34;id\u0026#34;: \u0026#34;doc321\u0026#34;, \u0026#34;similarity\u0026#34;: 0.82 } ] }Response Fields:\n$schema (string): JSON schema reference user_handle (string): Project owner\u0026rsquo;s username project_handle (string): Project identifier results (array): Array of similar documents, ordered by similarity (highest first) id (string): Document text identifier similarity (float): Cosine similarity score (0-1, where 1 is most similar) Similarity Calculation# Cosine Distance# The API uses cosine distance (or equivalently, cosine similarity) to calculate vector similarity:\nRange: 0 to 1 1.0: Identical vectors 0.0: Orthogonal vectors (completely dissimilar) Higher values: More similar documents Dimension Filtering# The system automatically filters results to only include embeddings with matching dimensions. This ensures:\nOnly embeddings with matching vector_dim are compared Only embeddings from the same project are considered Invalid comparisons are prevented Dimension Validation (POST only)# When using the POST endpoint with raw embeddings, the API validates:\nThe project has an associated LLM service instance The submitted vector dimensions match the instance\u0026rsquo;s configured dimensions If dimensions don\u0026rsquo;t match, a 400 Bad Request error is returned Error example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector dimension mismatch: expected 1536 dimensions, got 768\u0026#34; } Metadata Filtering# Both endpoints support metadata filtering to exclude documents based on metadata field values. This uses negative matching (excludes documents where the field matches the value).\nUse Cases# Exclude documents from the same source:\n# When finding similar documents to doc123, exclude others from the same author curl -X GET \u0026#34;.../similars/alice/research-docs/doc123?metadata_path=author_id\u0026amp;metadata_value=A0083\u0026#34;Exclude documents from the same category:\n# Find similar documents in other categories curl -X GET \u0026#34;.../similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=biology\u0026#34;Exclude documents with the same tag:\n# Find documents with similar content but different tags curl -X POST \u0026#34;.../similars/alice/research-docs?metadata_path=primary_tag\u0026amp;metadata_value=machine-learning\u0026#34; \\ -d \u0026#39;{\u0026#34;vector\u0026#34;: [...]}\u0026#39;Nested Field Access# Use dot notation for nested metadata fields:\n# Exclude documents from the same author (nested field) metadata_path=author.id\u0026amp;metadata_value=author-123 # Exclude documents from the same publication year metadata_path=publication.year\u0026amp;metadata_value=2024 # Deeply nested field metadata_path=source.journal.publisher\u0026amp;metadata_value=Springer Examples# Basic Similarity Search# Find 5 most similar documents with at least 0.7 similarity:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Search with Raw Vector# Submit a vector without storing it:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, 0.071384, 0.020003] }\u0026#39; Search with Metadata Filtering# Find similar documents but exclude those from the same author:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Paginated Results# Get the next page of results:\n# Page 1 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=0\u0026#34; # Page 2 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=20\u0026#34; # Page 3 curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=40\u0026#34; Complex Query# High threshold, metadata filtering, and pagination:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=50\u0026amp;threshold=0.9\u0026amp;offset=0\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Common Errors# 400 Bad Request - Dimension Mismatch (POST only)# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;vector dimension mismatch: expected 1536 dimensions, got 768\u0026#34; }400 Bad Request - Missing metadata_value# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata_path requires metadata_value to be specified\u0026#34; }400 Bad Request - Invalid threshold# { \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;threshold must be between 0.0 and 1.0\u0026#34; }403 Forbidden# { \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to search this project\u0026#34; }404 Not Found - Project# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }404 Not Found - Embedding (GET only)# { \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; } Performance Considerations# Indexing# The database uses vector indexes for efficient similarity search. See the database migrations for index configuration.\nResult Limits# Default limit: 10 results Maximum limit: 200 results Use pagination for large result sets Threshold Optimization# Higher thresholds reduce result set size and improve performance:\n0.5-0.7: Broad similarity (default) 0.7-0.85: Moderate similarity 0.85-0.95: High similarity 0.95-1.0: Near-identical documents Related Documentation# Embeddings - Storing embeddings for similarity search Projects - Project configuration Query Parameters - Complete parameter reference Error Handling - Error response format "},{"id":42,"href":"/dhamps-vdb/guides/batch-operations/","title":"Batch Operations Guide","section":"Guides","content":"Batch Operations Guide# This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.\nOverview# For production workloads and large datasets, efficient batch operations are essential. This guide covers:\nUploading multiple embeddings in a single request Pagination strategies for large result sets Best practices for performance and reliability Error handling in batch operations Batch Upload Basics# Single Request with Multiple Embeddings# Upload multiple embeddings in one API call using the embeddings array:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;First document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;science\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.11, 0.21, 0.31, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Second document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;history\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc003\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.12, 0.22, 0.32, ...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: \u0026#34;Third document content\u0026#34;, \u0026#34;metadata\u0026#34;: {\u0026#34;category\u0026#34;: \u0026#34;literature\u0026#34;} } ] }\u0026#39;Response:\n{ \u0026#34;message\u0026#34;: \u0026#34;Embeddings uploaded successfully\u0026#34;, \u0026#34;count\u0026#34;: 3 }Optimal Batch Sizes# Recommended Batch Sizes# Based on typical embedding dimensions and network constraints:\nEmbedding Dimensions Recommended Batch Size Maximum Batch Size 384 (small models) 500-1000 2000 768 (BERT-base) 300-500 1000 1536 (OpenAI small) 100-300 500 3072 (OpenAI large) 50-100 200 Factors to consider:\nNetwork bandwidth and latency API gateway timeout limits Database transaction size Memory constraints Client-side serialization limits Finding Your Optimal Batch Size# Test different batch sizes to find the sweet spot:\nimport time import requests def test_batch_size(embeddings, batch_size): \u0026#34;\u0026#34;\u0026#34;Test upload performance with given batch size\u0026#34;\u0026#34;\u0026#34; start_time = time.time() for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status() elapsed = time.time() - start_time throughput = len(embeddings) / elapsed print(f\u0026#34;Batch size {batch_size}: {throughput:.1f} embeddings/sec\u0026#34;) # Test different batch sizes for size in [50, 100, 200, 500]: test_batch_size(my_embeddings, size)Pagination for Large Datasets# Retrieving All Embeddings with Pagination# Use limit and offset parameters to paginate through large result sets:\n# Get first page (embeddings 0-99) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get second page (embeddings 100-199) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=100\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get third page (embeddings 200-299) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/my-project?limit=100\u0026amp;offset=200\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Pagination Best Practices# Default Values:\nlimit: 10 (if not specified) offset: 0 (if not specified) Maximum limit: 200 Example: Download Entire Project\nimport requests def download_all_embeddings(owner, project): \u0026#34;\u0026#34;\u0026#34;Download all embeddings from a project\u0026#34;\u0026#34;\u0026#34; all_embeddings = [] offset = 0 limit = 100 while True: response = requests.get( f\u0026#34;https://api.example.com/v1/embeddings/{owner}/{project}\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: \u0026#34;Bearer api_key\u0026#34;}, params={\u0026#34;limit\u0026#34;: limit, \u0026#34;offset\u0026#34;: offset} ) response.raise_for_status() batch = response.json()[\u0026#39;embeddings\u0026#39;] if not batch: break # No more results all_embeddings.extend(batch) offset += len(batch) print(f\u0026#34;Downloaded {len(all_embeddings)} embeddings...\u0026#34;) return all_embeddings # Usage embeddings = download_all_embeddings(\u0026#34;alice\u0026#34;, \u0026#34;my-project\u0026#34;) print(f\u0026#34;Total: {len(embeddings)} embeddings\u0026#34;)Efficient Batch Upload Strategies# Strategy 1: Simple Sequential Upload# Good for small to medium datasets (\u0026lt; 10,000 embeddings):\ndef upload_sequential(embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload embeddings sequentially in batches\u0026#34;\u0026#34;\u0026#34; for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status() print(f\u0026#34;Uploaded batch {i//batch_size + 1}, total: {i+len(batch)}\u0026#34;)Strategy 2: Parallel Upload with Threading# Good for larger datasets with stable network:\nimport concurrent.futures import requests def upload_batch(batch, batch_num): \u0026#34;\u0026#34;\u0026#34;Upload a single batch\u0026#34;\u0026#34;\u0026#34; try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return batch_num, True, None except Exception as e: return batch_num, False, str(e) def upload_parallel(embeddings, batch_size=100, max_workers=4): \u0026#34;\u0026#34;\u0026#34;Upload embeddings in parallel\u0026#34;\u0026#34;\u0026#34; batches = [ embeddings[i:i+batch_size] for i in range(0, len(embeddings), batch_size) ] failed = [] with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = { executor.submit(upload_batch, batch, i): i for i, batch in enumerate(batches) } for future in concurrent.futures.as_completed(futures): batch_num, success, error = future.result() if success: print(f\u0026#34;✓ Batch {batch_num+1}/{len(batches)} uploaded\u0026#34;) else: print(f\u0026#34;✗ Batch {batch_num+1} failed: {error}\u0026#34;) failed.append((batch_num, batches[batch_num])) return failed # Usage failed_batches = upload_parallel(my_embeddings, batch_size=100, max_workers=4) if failed_batches: print(f\u0026#34;Failed batches: {len(failed_batches)}\u0026#34;)Strategy 3: Retry with Exponential Backoff# Robust strategy for unreliable networks:\nimport time import random def upload_with_retry(batch, max_retries=3): \u0026#34;\u0026#34;\u0026#34;Upload batch with exponential backoff retry\u0026#34;\u0026#34;\u0026#34; for attempt in range(max_retries): try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return True except requests.exceptions.RequestException as e: if attempt \u0026lt; max_retries - 1: wait = (2 ** attempt) + random.uniform(0, 1) print(f\u0026#34;Retry attempt {attempt+1} after {wait:.1f}s: {e}\u0026#34;) time.sleep(wait) else: print(f\u0026#34;Failed after {max_retries} attempts: {e}\u0026#34;) return False def upload_robust(embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload with robust error handling\u0026#34;\u0026#34;\u0026#34; failed = [] for i in range(0, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] if not upload_with_retry(batch): failed.append((i, batch)) else: print(f\u0026#34;✓ Uploaded {i+batch_size}/{len(embeddings)}\u0026#34;) return failedProgress Tracking and Resumability# Checkpoint-Based Upload# For very large datasets, implement checkpointing to resume after failures:\nimport json import os class CheckpointUploader: def __init__(self, checkpoint_file=\u0026#34;upload_progress.json\u0026#34;): self.checkpoint_file = checkpoint_file self.progress = self.load_progress() def load_progress(self): \u0026#34;\u0026#34;\u0026#34;Load upload progress from checkpoint file\u0026#34;\u0026#34;\u0026#34; if os.path.exists(self.checkpoint_file): with open(self.checkpoint_file, \u0026#39;r\u0026#39;) as f: return json.load(f) return {\u0026#34;uploaded_count\u0026#34;: 0, \u0026#34;failed_batches\u0026#34;: []} def save_progress(self): \u0026#34;\u0026#34;\u0026#34;Save current progress\u0026#34;\u0026#34;\u0026#34; with open(self.checkpoint_file, \u0026#39;w\u0026#39;) as f: json.dump(self.progress, f) def upload(self, embeddings, batch_size=100): \u0026#34;\u0026#34;\u0026#34;Upload with checkpointing\u0026#34;\u0026#34;\u0026#34; start_idx = self.progress[\u0026#34;uploaded_count\u0026#34;] for i in range(start_idx, len(embeddings), batch_size): batch = embeddings[i:i+batch_size] try: response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() self.progress[\u0026#34;uploaded_count\u0026#34;] = i + len(batch) self.save_progress() print(f\u0026#34;✓ Progress: {self.progress[\u0026#39;uploaded_count\u0026#39;]}/{len(embeddings)}\u0026#34;) except Exception as e: print(f\u0026#34;✗ Failed at index {i}: {e}\u0026#34;) self.progress[\u0026#34;failed_batches\u0026#34;].append(i) self.save_progress() raise # Usage uploader = CheckpointUploader() try: uploader.upload(my_embeddings, batch_size=100) print(\u0026#34;Upload complete!\u0026#34;) except: print(\u0026#34;Upload interrupted. Run again to resume.\u0026#34;)Error Handling# Validation Errors# If any embedding in a batch fails validation, the entire batch is rejected:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Alice\u0026#34;} }, { \u0026#34;text_id\u0026#34;: \u0026#34;doc002\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: {\u0026#34;author\u0026#34;: \u0026#34;Bob\u0026#34;} } ] }\u0026#39;Error Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector length mismatch for text_id \u0026#39;doc002\u0026#39;: actual vector has 2 elements but vector_dim declares 3072\u0026#34; }Solution: Validate all embeddings before batching, or handle errors and retry failed items.\nPre-Upload Validation# def validate_embeddings(embeddings, expected_dim): \u0026#34;\u0026#34;\u0026#34;Validate embeddings before upload\u0026#34;\u0026#34;\u0026#34; errors = [] for i, emb in enumerate(embeddings): # Check vector length if len(emb[\u0026#39;vector\u0026#39;]) != expected_dim: errors.append(f\u0026#34;Index {i} (text_id: {emb[\u0026#39;text_id\u0026#39;]}): \u0026#34; f\u0026#34;vector length {len(emb[\u0026#39;vector\u0026#39;])} != {expected_dim}\u0026#34;) # Check declared dimension if emb.get(\u0026#39;vector_dim\u0026#39;) != expected_dim: errors.append(f\u0026#34;Index {i} (text_id: {emb[\u0026#39;text_id\u0026#39;]}): \u0026#34; f\u0026#34;vector_dim {emb.get(\u0026#39;vector_dim\u0026#39;)} != {expected_dim}\u0026#34;) # Check required fields if not emb.get(\u0026#39;text_id\u0026#39;): errors.append(f\u0026#34;Index {i}: missing text_id\u0026#34;) if not emb.get(\u0026#39;instance_handle\u0026#39;): errors.append(f\u0026#34;Index {i}: missing instance_handle\u0026#34;) return errors # Usage errors = validate_embeddings(my_embeddings, 3072) if errors: print(\u0026#34;Validation errors:\u0026#34;) for error in errors: print(f\u0026#34; - {error}\u0026#34;) else: print(\u0026#34;All embeddings valid, proceeding with upload...\u0026#34;)Performance Optimization Tips# 1. Minimize Payload Size# Exclude unnecessary fields:\n# Include text only if needed for retrieval embeddings_with_text = [ { \u0026#34;text_id\u0026#34;: doc_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;text\u0026#34;: text, # Include if needed \u0026#34;metadata\u0026#34;: metadata } for doc_id, vector, text, metadata in documents ] # Exclude text if not needed (smaller payload) embeddings_without_text = [ { \u0026#34;text_id\u0026#34;: doc_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: metadata } for doc_id, vector, metadata in documents ]2. Compress Requests# Use gzip compression for large payloads:\nimport gzip import json def upload_compressed(embeddings): \u0026#34;\u0026#34;\u0026#34;Upload with gzip compression\u0026#34;\u0026#34;\u0026#34; payload = json.dumps({\u0026#34;embeddings\u0026#34;: embeddings}) compressed = gzip.compress(payload.encode(\u0026#39;utf-8\u0026#39;)) response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, headers={ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34;, \u0026#34;Content-Encoding\u0026#34;: \u0026#34;gzip\u0026#34; }, data=compressed ) return response3. Use Connection Pooling# Reuse HTTP connections for multiple requests:\nsession = requests.Session() session.headers.update({ \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer alice_api_key\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }) for batch in batches: response = session.post( \u0026#34;https://api.example.com/v1/embeddings/alice/my-project\u0026#34;, json={\u0026#34;embeddings\u0026#34;: batch} ) response.raise_for_status()4. Monitor Upload Rate# Track and display upload progress:\nimport time class ProgressTracker: def __init__(self, total): self.total = total self.uploaded = 0 self.start_time = time.time() def update(self, count): self.uploaded += count elapsed = time.time() - self.start_time rate = self.uploaded / elapsed if elapsed \u0026gt; 0 else 0 percent = (self.uploaded / self.total) * 100 eta = (self.total - self.uploaded) / rate if rate \u0026gt; 0 else 0 print(f\u0026#34;\\rProgress: {self.uploaded}/{self.total} ({percent:.1f}%) \u0026#34; f\u0026#34;Rate: {rate:.1f} emb/s ETA: {eta:.0f}s\u0026#34;, end=\u0026#34;\u0026#34;) # Usage tracker = ProgressTracker(len(all_embeddings)) for batch in batches: upload_batch(batch) tracker.update(len(batch)) print() # New line after completionComplete Example: Production-Grade Uploader# import requests import time import json import logging from concurrent.futures import ThreadPoolExecutor, as_completed from typing import List, Dict, Tuple class ProductionUploader: def __init__(self, api_base: str, api_key: str, owner: str, project: str): self.api_base = api_base self.api_key = api_key self.owner = owner self.project = project self.session = requests.Session() self.session.headers.update({ \u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34; }) logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger(__name__) def upload_batch(self, batch: List[Dict], batch_num: int, max_retries: int = 3) -\u0026gt; Tuple[int, bool, str]: \u0026#34;\u0026#34;\u0026#34;Upload a single batch with retry logic\u0026#34;\u0026#34;\u0026#34; url = f\u0026#34;{self.api_base}/v1/embeddings/{self.owner}/{self.project}\u0026#34; for attempt in range(max_retries): try: response = self.session.post( url, json={\u0026#34;embeddings\u0026#34;: batch}, timeout=60 ) response.raise_for_status() return batch_num, True, \u0026#34;\u0026#34; except Exception as e: if attempt \u0026lt; max_retries - 1: wait = 2 ** attempt self.logger.warning( f\u0026#34;Batch {batch_num} attempt {attempt+1} failed: {e}. \u0026#34; f\u0026#34;Retrying in {wait}s...\u0026#34; ) time.sleep(wait) else: return batch_num, False, str(e) def upload(self, embeddings: List[Dict], batch_size: int = 100, max_workers: int = 4) -\u0026gt; Dict: \u0026#34;\u0026#34;\u0026#34;Upload embeddings with parallel processing and progress tracking\u0026#34;\u0026#34;\u0026#34; batches = [ embeddings[i:i+batch_size] for i in range(0, len(embeddings), batch_size) ] results = { \u0026#34;total\u0026#34;: len(embeddings), \u0026#34;uploaded\u0026#34;: 0, \u0026#34;failed\u0026#34;: [], \u0026#34;start_time\u0026#34;: time.time() } self.logger.info(f\u0026#34;Uploading {len(embeddings)} embeddings in \u0026#34; f\u0026#34;{len(batches)} batches...\u0026#34;) with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = { executor.submit(self.upload_batch, batch, i): i for i, batch in enumerate(batches) } for future in as_completed(futures): batch_num, success, error = future.result() if success: results[\u0026#34;uploaded\u0026#34;] += len(batches[batch_num]) percent = (results[\u0026#34;uploaded\u0026#34;] / results[\u0026#34;total\u0026#34;]) * 100 self.logger.info( f\u0026#34;✓ Batch {batch_num+1}/{len(batches)} \u0026#34; f\u0026#34;({percent:.1f}% complete)\u0026#34; ) else: results[\u0026#34;failed\u0026#34;].append({ \u0026#34;batch_num\u0026#34;: batch_num, \u0026#34;error\u0026#34;: error, \u0026#34;embeddings\u0026#34;: batches[batch_num] }) self.logger.error(f\u0026#34;✗ Batch {batch_num+1} failed: {error}\u0026#34;) results[\u0026#34;elapsed\u0026#34;] = time.time() - results[\u0026#34;start_time\u0026#34;] results[\u0026#34;rate\u0026#34;] = results[\u0026#34;uploaded\u0026#34;] / results[\u0026#34;elapsed\u0026#34;] self.logger.info( f\u0026#34;\\nUpload complete: {results[\u0026#39;uploaded\u0026#39;]}/{results[\u0026#39;total\u0026#39;]} \u0026#34; f\u0026#34;in {results[\u0026#39;elapsed\u0026#39;]:.1f}s ({results[\u0026#39;rate\u0026#39;]:.1f} emb/s)\u0026#34; ) if results[\u0026#34;failed\u0026#34;]: self.logger.warning(f\u0026#34;Failed batches: {len(results[\u0026#39;failed\u0026#39;])}\u0026#34;) return results # Usage uploader = ProductionUploader( api_base=\u0026#34;https://api.example.com\u0026#34;, api_key=\u0026#34;alice_api_key\u0026#34;, owner=\u0026#34;alice\u0026#34;, project=\u0026#34;my-project\u0026#34; ) results = uploader.upload( embeddings=my_embeddings, batch_size=100, max_workers=4 ) # Save failed batches for retry if results[\u0026#34;failed\u0026#34;]: with open(\u0026#34;failed_batches.json\u0026#34;, \u0026#34;w\u0026#34;) as f: json.dump(results[\u0026#34;failed\u0026#34;], f)Best Practices Summary# Batch Size: Test to find optimal size (typically 50-500 depending on dimensions) Parallelism: Use 2-8 parallel workers for large uploads Retry Logic: Implement exponential backoff for network errors Validation: Pre-validate embeddings before upload Progress Tracking: Monitor upload rate and ETA Checkpointing: Save progress for resumable uploads Error Logging: Log all errors with sufficient context Connection Reuse: Use session objects for connection pooling Compression: Use gzip for large payloads Testing: Test with small batches before full upload Related Documentation# RAG Workflow Guide - Complete RAG implementation Metadata Validation Guide - Schema validation Instance Management Guide - Managing LLM instances Troubleshooting# Timeout Errors# Problem: Requests timing out with large batches\nSolution: Reduce batch size or increase timeout value\nMemory Issues# Problem: Out of memory when processing large datasets\nSolution: Process embeddings in streaming fashion, don\u0026rsquo;t load all into memory\nRate Limiting# Problem: Getting rate limited by API\nSolution: Reduce parallelism (max_workers) or add delays between requests\n"},{"id":43,"href":"/dhamps-vdb/concepts/metadata/","title":"Metadata","section":"Concepts","content":"Metadata# Structured JSON data attached to embeddings for organization, validation, and filtering.\nOverview# Metadata provides context and structure for your embeddings:\nOrganization: Categorize and group documents Filtering: Exclude documents in similarity searches Validation: Ensure consistent structure (optional) Context: Store additional document information Metadata Structure# Format# Metadata is JSON stored as JSONB in PostgreSQL:\n{ \u0026#34;author\u0026#34;: \u0026#34;William Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603, \u0026#34;genre\u0026#34;: \u0026#34;drama\u0026#34; }Types# Supported JSON types:\nString: \u0026quot;author\u0026quot;: \u0026quot;Shakespeare\u0026quot; Number: \u0026quot;year\u0026quot;: 1603 Boolean: \u0026quot;published\u0026quot;: true Array: \u0026quot;tags\u0026quot;: [\u0026quot;tragedy\u0026quot;, \u0026quot;revenge\u0026quot;] Object: \u0026quot;author\u0026quot;: {\u0026quot;name\u0026quot;: \u0026quot;...\u0026quot;, \u0026quot;id\u0026quot;: \u0026quot;...\u0026quot;} Null: \u0026quot;notes\u0026quot;: null Nested Structure# Complex hierarchies are supported:\n{ \u0026#34;document\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;W0017\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;manuscript\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;John Milton\u0026#34;, \u0026#34;birth_year\u0026#34;: 1608, \u0026#34;nationality\u0026#34;: \u0026#34;English\u0026#34; }, \u0026#34;publication\u0026#34;: { \u0026#34;year\u0026#34;: 1667, \u0026#34;publisher\u0026#34;: \u0026#34;First Edition\u0026#34;, \u0026#34;location\u0026#34;: \u0026#34;London\u0026#34; }, \u0026#34;tags\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;epic\u0026#34;, \u0026#34;religious\u0026#34;] }Metadata Schemas# Purpose# JSON Schema validation ensures consistent metadata across all project embeddings.\nDefining a Schema# Include metadataScheme when creating/updating project:\nPOST /v1/projects/alice { \u0026#34;project_handle\u0026#34;: \u0026#34;research\u0026#34;, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }Schema Format# Use JSON Schema (draft-07+):\n{ \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1 }, \u0026#34;year\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;, \u0026#34;minimum\u0026#34;: 1000, \u0026#34;maximum\u0026#34;: 2100 }, \u0026#34;genre\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;poetry\u0026#34;, \u0026#34;prose\u0026#34;, \u0026#34;drama\u0026#34;] } }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;, \u0026#34;year\u0026#34;] }Validation Behavior# With schema defined:\nAll embeddings validated on upload Invalid metadata rejected with detailed error Schema enforced consistently Without schema:\nAny JSON metadata accepted No validation performed Maximum flexibility Common Patterns# See Metadata Validation Guide for examples.\nUsing Metadata# On Upload# Include metadata with each embedding:\nPOST /v1/embeddings/alice/research { \u0026#34;embeddings\u0026#34;: [ { \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-embeddings\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603 } } ] }In Responses# Metadata returned when retrieving embeddings:\nGET /v1/embeddings/alice/research/doc1{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Hamlet\u0026#34;, \u0026#34;year\u0026#34;: 1603 }, \u0026#34;vector\u0026#34;: [...], ... }Metadata Filtering# Exclusion Filter# Exclude documents where metadata matches value:\nGET /v1/similars/alice/research/doc1?metadata_path=author\u0026amp;metadata_value=ShakespeareResult: Returns similar documents excluding those with metadata.author == \u0026quot;Shakespeare\u0026quot;.\nPath Syntax# Use JSON path notation:\nSimple field:\nmetadata_path=authorNested field:\nmetadata_path=author.nameArray element (not currently supported):\nmetadata_path=tags[0]URL Encoding# Encode special characters:\n# Space metadata_value=John%20Doe # Quotes (if needed) metadata_value=%22quoted%20value%22Use Cases# Exclude same work:\n?metadata_path=title\u0026amp;metadata_value=HamletExclude same author:\n?metadata_path=author\u0026amp;metadata_value=ShakespeareExclude same source:\n?metadata_path=source_id\u0026amp;metadata_value=corpus-aExclude same category:\n?metadata_path=category\u0026amp;metadata_value=draftSee Metadata Filtering Guide for detailed examples.\nValidation Examples# Simple Schema# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;author\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;year\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34;} }, \u0026#34;required\u0026#34;: [\u0026#34;author\u0026#34;] }Valid metadata:\n{\u0026#34;author\u0026#34;: \u0026#34;Shakespeare\u0026#34;, \u0026#34;year\u0026#34;: 1603} {\u0026#34;author\u0026#34;: \u0026#34;Milton\u0026#34;}Invalid metadata:\n{\u0026#34;year\u0026#34;: 1603} // Missing required \u0026#39;author\u0026#39; {\u0026#34;author\u0026#34;: 123} // Wrong type (should be string)Schema with Constraints# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;minLength\u0026#34;: 1, \u0026#34;maxLength\u0026#34;: 200 }, \u0026#34;rating\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;minimum\u0026#34;: 0, \u0026#34;maximum\u0026#34;: 5 }, \u0026#34;tags\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;array\u0026#34;, \u0026#34;items\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;minItems\u0026#34;: 1, \u0026#34;maxItems\u0026#34;: 10 } } }Schema with Enums# { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;language\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;en\u0026#34;, \u0026#34;de\u0026#34;, \u0026#34;fr\u0026#34;, \u0026#34;es\u0026#34;, \u0026#34;la\u0026#34;] }, \u0026#34;status\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;enum\u0026#34;: [\u0026#34;draft\u0026#34;, \u0026#34;review\u0026#34;, \u0026#34;published\u0026#34;] } } }Storage and Performance# Storage# Metadata stored as JSONB in PostgreSQL:\nEfficient: Binary storage format Indexable: Can create indexes on fields Queryable: Use PostgreSQL JSON operators Size Considerations# Typical metadata sizes:\nSimple: 50-200 bytes Moderate: 200-1000 bytes Complex: 1-5KB Very large: \u0026gt;5KB (consider storing elsewhere) Performance# Metadata filtering:\nJSONB queries are efficient Add indexes for frequently filtered fields Keep metadata reasonably sized Example index (if needed):\nCREATE INDEX idx_embeddings_author ON embeddings ((metadata-\u0026gt;\u0026gt;\u0026#39;author\u0026#39;));Common Patterns# Document Provenance# Track document source and history:\n{ \u0026#34;source\u0026#34;: { \u0026#34;corpus\u0026#34;: \u0026#34;Shakespeare Works\u0026#34;, \u0026#34;collection\u0026#34;: \u0026#34;Tragedies\u0026#34;, \u0026#34;document_id\u0026#34;: \u0026#34;hamlet\u0026#34;, \u0026#34;version\u0026#34;: 2 }, \u0026#34;imported_at\u0026#34;: \u0026#34;2024-01-15T10:30:00Z\u0026#34;, \u0026#34;imported_by\u0026#34;: \u0026#34;researcher1\u0026#34; }Hierarchical Documents# Structure for nested documents:\n{ \u0026#34;work\u0026#34;: \u0026#34;Paradise Lost\u0026#34;, \u0026#34;book\u0026#34;: 1, \u0026#34;line\u0026#34;: 1, \u0026#34;chapter\u0026#34;: null, \u0026#34;section\u0026#34;: \u0026#34;Invocation\u0026#34; }Multi-Language Content# Track language and translation info:\n{ \u0026#34;language\u0026#34;: \u0026#34;en\u0026#34;, \u0026#34;original_language\u0026#34;: \u0026#34;la\u0026#34;, \u0026#34;translated_by\u0026#34;: \u0026#34;John Smith\u0026#34;, \u0026#34;translation_year\u0026#34;: 1850 }Research Metadata# Academic paper metadata:\n{ \u0026#34;doi\u0026#34;: \u0026#34;10.1234/example.2024.001\u0026#34;, \u0026#34;authors\u0026#34;: [\u0026#34;Alice Smith\u0026#34;, \u0026#34;Bob Jones\u0026#34;], \u0026#34;journal\u0026#34;: \u0026#34;Digital Humanities Review\u0026#34;, \u0026#34;year\u0026#34;: 2024, \u0026#34;keywords\u0026#34;: [\u0026#34;NLP\u0026#34;, \u0026#34;embeddings\u0026#34;, \u0026#34;RAG\u0026#34;] }Updating Metadata# Current Limitation# Metadata cannot be updated directly. To change:\nDelete embedding Re-upload with updated metadata # Delete DELETE /v1/embeddings/alice/project/doc1 # Re-upload with new metadata POST /v1/embeddings/alice/project { \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc1\u0026#34;, \u0026#34;metadata\u0026#34;: {...updated...}, ... }] }Schema Updates# Updating Project Schema# Use PATCH to update schema:\nPATCH /v1/projects/alice/research { \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...new schema...}\u0026#34; }Effect on Existing Embeddings# Existing embeddings: Not revalidated New embeddings: Validated against new schema Updates: Validated against current schema Migration Strategy# When updating schema:\nUpdate project schema Verify new embeddings work Optionally re-upload existing embeddings Validation Errors# Common Errors# Missing required field:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: author is required\u0026#34; }Wrong type:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: year must be integer\u0026#34; }Enum violation:\n{ \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed: genre must be one of [poetry, prose, drama]\u0026#34; }Debugging# To debug validation errors:\nCheck project schema: GET /v1/projects/owner/project Validate metadata with online tool: jsonschemavalidator.net Review error message for specific field Update metadata or schema as needed Best Practices# Schema Design# Start simple, add complexity as needed Use required fields for critical data Use enums for controlled vocabularies Document your schema Metadata Content# Keep metadata focused and relevant Avoid redundant data Use consistent field names Consider future queries and filters Performance# Keep metadata reasonably sized (\u0026lt;5KB) Index frequently queried fields Avoid deeply nested structures when possible Troubleshooting# Validation Fails# Problem: Metadata doesn\u0026rsquo;t validate\nSolutions:\nCheck project schema Verify metadata structure Test with JSON Schema validator Review error message details Filtering Not Working# Problem: Metadata filter doesn\u0026rsquo;t exclude documents\nSolutions:\nVerify field path is correct Check value matches exactly (case-sensitive) URL-encode special characters Confirm metadata field exists Schema Too Restrictive# Problem: Cannot upload valid documents\nSolutions:\nMake fields optional (remove from required) Broaden type constraints Use oneOf for multiple valid formats Remove unnecessary validations Next Steps# Learn about metadata validation Explore metadata filtering Understand similarity search "},{"id":44,"href":"/dhamps-vdb/api/query-parameters/","title":"Query Parameters","section":"API Reference","content":"Query Parameters Reference# Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.\nPagination Parameters# limit# Maximum number of results to return in a single response.\nType: Integer\nDefault: 10\nMaximum: 200\nMinimum: 1\nUsed by:\nGET /v1/embeddings/{user}/{project} - List embeddings GET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search GET /v1/projects/{user} - List projects Example:\n# Get 50 embeddings curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Aliases:\ncount - Used in similarity search endpoints (same behavior as limit) offset# Number of results to skip before returning data. Used for pagination.\nType: Integer\nDefault: 0\nMinimum: 0\nUsed by:\nGET /v1/embeddings/{user}/{project} - List embeddings GET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search GET /v1/projects/{user} - List projects Example:\n# Get results 21-40 (page 2) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=20\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Get results 41-60 (page 3) curl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=20\u0026amp;offset=40\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Pagination Formula:\nPage N: offset = (N - 1) * limit Similarity Search Parameters# count# Number of similar documents to return. Alias for limit in similarity search endpoints.\nType: Integer\nDefault: 10\nMaximum: 200\nMinimum: 1\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Find 5 most similar documents curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=5\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Note: count and limit can be used interchangeably in similarity endpoints.\nthreshold# Minimum similarity score threshold. Only results with similarity \u0026gt;= threshold are returned.\nType: Float\nDefault: 0.5\nRange: 0.0 to 1.0\nNote: 1.0 = most similar, 0.0 = least similar\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Only return highly similar documents (\u0026gt;= 0.8) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Return moderately similar documents (\u0026gt;= 0.6) curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?threshold=0.6\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Threshold Guidelines:\nThreshold Interpretation Use Case 0.95-1.0 Near-identical Duplicate detection 0.85-0.95 Very similar Finding closely related documents 0.7-0.85 Moderately similar Broad similarity search 0.5-0.7 Loosely similar Exploratory search 0.0-0.5 Weakly similar Generally not useful Metadata Filtering Parameters# metadata_path# JSON path to a metadata field for filtering results. Must be used together with metadata_value.\nType: String\nFormat: JSON path notation (e.g., \u0026quot;author\u0026quot;, \u0026quot;author.name\u0026quot;, \u0026quot;publication.year\u0026quot;)\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Path Notation:\nSimple field: author Nested field: author.name Deeply nested: publication.journal.name Example:\n# Simple field path curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; # Nested field path curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author.id\u0026amp;metadata_value=A0083\u0026#34; metadata_value# Metadata value to exclude from similarity search results. Must be used together with metadata_path.\nType: String\nBehavior: Negative matching (excludes documents where field equals this value)\nUsed by:\nGET /v1/similars/{user}/{project}/{id} - Similarity search POST /v1/similars/{user}/{project} - Raw vector search Example:\n# Exclude documents from the same author curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=author\u0026amp;metadata_value=Alice%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Exclude documents from the same category curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;URL Encoding:\nAlways URL-encode metadata values that contain special characters:\n# Value: \u0026#34;John Doe\u0026#34; → \u0026#34;John%20Doe\u0026#34; # Value: \u0026#34;2024-01-15\u0026#34; → \u0026#34;2024-01-15\u0026#34; (no special chars) # Value: \u0026#34;author@example.com\u0026#34; → \u0026#34;author%40example.com\u0026#34; Parameter Combinations# Pagination with Filtering# Combine limit, offset, and threshold:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;offset=40\u0026amp;threshold=0.7\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search with Metadata Filtering# Combine threshold and metadata filtering:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=10\u0026amp;threshold=0.8\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Complete Query with All Parameters# curl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=50\u0026amp;offset=0\u0026amp;threshold=0.75\u0026amp;metadata_path=category\u0026amp;metadata_value=biology\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Endpoint-Specific Parameters# List Embeddings# Endpoint: GET /v1/embeddings/{user}/{project}\nSupported Parameters:\nlimit (default: 10, max: 200) offset (default: 0) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=100\u0026amp;offset=200\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; List Projects# Endpoint: GET /v1/projects/{user}\nSupported Parameters:\nlimit (default: 10, max: 200) offset (default: 0) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice?limit=50\u0026amp;offset=0\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search (GET)# Endpoint: GET /v1/similars/{user}/{project}/{id}\nSupported Parameters:\ncount / limit (default: 10, max: 200) offset (default: 0) threshold (default: 0.5, range: 0.0-1.0) metadata_path (optional, requires metadata_value) metadata_value (optional, requires metadata_path) Example:\ncurl -X GET \u0026#34;https://api.example.com/v1/similars/alice/research-docs/doc123?count=20\u0026amp;threshold=0.7\u0026amp;metadata_path=author\u0026amp;metadata_value=John%20Doe\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Similarity Search (POST)# Endpoint: POST /v1/similars/{user}/{project}\nSupported Parameters: Same as GET similarity search\nExample:\ncurl -X POST \u0026#34;https://api.example.com/v1/similars/alice/research-docs?count=10\u0026amp;threshold=0.8\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;vector\u0026#34;: [-0.020850, 0.018522, 0.053270, ...] }\u0026#39; Parameter Validation# Invalid Parameter Values# Error Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;limit must be between 1 and 200\u0026#34; }Common Validation Errors:\nlimit exceeds maximum (200) limit less than minimum (1) offset is negative threshold outside range 0.0-1.0 metadata_path without metadata_value metadata_value without metadata_path Best Practices# Pagination# Do:\nUse consistent limit values across pages Start with offset=0 for the first page Increment offset by limit for each subsequent page Example pagination logic:\nlimit = 20 page = 1 # Page 1 offset = (page - 1) * limit # 0 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; # Page 2 page = 2 offset = (page - 1) * limit # 20 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; # Page 3 page = 3 offset = (page - 1) * limit # 40 url = f\u0026#34;/v1/embeddings/alice/research?limit={limit}\u0026amp;offset={offset}\u0026#34; Similarity Search# Do:\nUse higher thresholds (0.7-0.9) for focused searches Use lower thresholds (0.5-0.7) for exploratory searches Combine with count to limit result size Use metadata filtering to exclude unwanted results Don\u0026rsquo;t:\nRequest more results than needed (affects performance) Use very low thresholds (\u0026lt;0.5) unless necessary Metadata Filtering# Do:\nURL-encode metadata values with special characters Use specific field paths for nested metadata Test metadata paths with sample queries first Example:\n# Good: URL-encoded, specific path metadata_path=author.id\u0026amp;metadata_value=A0083 # Good: Simple field metadata_path=category\u0026amp;metadata_value=biology # Bad: Not URL-encoded metadata_path=author name\u0026amp;metadata_value=John Doe # Good: URL-encoded metadata_path=author%20name\u0026amp;metadata_value=John%20Doe Response Formats# Paginated Response# Endpoints that support pagination typically return:\n{ \u0026#34;items\u0026#34;: [...], \u0026#34;total_count\u0026#34;: 500, \u0026#34;limit\u0026#34;: 20, \u0026#34;offset\u0026#34;: 40, \u0026#34;has_more\u0026#34;: true }Fields:\nitems: Array of results total_count: Total number of items available limit: Number of items requested per page offset: Current offset has_more: Boolean indicating if more results exist Similarity Response# Similarity endpoints return:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;results\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;doc456\u0026#34;, \u0026#34;similarity\u0026#34;: 0.95 }, { \u0026#34;id\u0026#34;: \u0026#34;doc789\u0026#34;, \u0026#34;similarity\u0026#34;: 0.87 } ] }Notes:\nResults are ordered by similarity (highest first) Only results \u0026gt;= threshold are included Maximum of count/limit results returned Filtered by metadata_path/metadata_value if specified Related Documentation# Embeddings - Embedding storage and retrieval Similars - Similarity search details Projects - Project management Error Handling - Error responses "},{"id":45,"href":"/dhamps-vdb/reference/","title":"Reference","section":"dhamps-vdb Documentation","content":"Reference Documentation# Technical reference materials and specifications.\nContents# Configuration Reference - Complete configuration options Database Schema - Database structure Roadmap - Planned features and improvements Additional Resources# OpenAPI Specification: Available at /openapi.yaml on any running instance Go Package Documentation: Coming soon Source Code: github.com/mpilhlt/dhamps-vdb "},{"id":46,"href":"/dhamps-vdb/guides/instance-management/","title":"Instance Management Guide","section":"Guides","content":"Instance Management Guide# This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.\nOverview# LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:\nAPI endpoint and credentials Model name and version Vector dimensions API standard (protocol) Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.\nInstance Architecture# System Definitions# The system provides pre-configured templates for common LLM services:\n# List available system definitions (no auth required) curl -X GET \u0026#34;https://api.example.com/v1/llm-service-definitions/_system\u0026#34;Default System Definitions:\nopenai-large: OpenAI text-embedding-3-large (3072 dimensions) openai-small: OpenAI text-embedding-3-small (1536 dimensions) cohere-v4: Cohere Embed v4 (1536 dimensions) gemini-embedding-001: Google Gemini embedding-001 (3072 dimensions, default size) User Instances# Users create instances for their own use. Instances contain:\nConfiguration (endpoint, model, dimensions) Encrypted API keys (write-only, never returned) Optional reference to a definition template Creating LLM Service Instances# Option 1: Standalone Instance# Create an instance by specifying all configuration fields:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model for research\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key-here\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;OpenAI large embedding model for research\u0026#34; }Note: The api_key_encrypted field is not returned in the response for security reasons.\nOption 2: From System Definition# Create an instance based on a system template (only requires API key):\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-your-openai-api-key-here\u0026#34; }\u0026#39;This inherits configuration from the _system/openai-large definition and only requires you to provide your API key.\nOption 3: From User Definition# Users can create their own definitions as templates:\n# Step 1: Create a custom definition curl -X PUT \u0026#34;https://api.example.com/v1/llm-service-definitions/alice/my-custom-config\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom-api.example.com/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-model-v2\u0026#34;, \u0026#34;dimensions\u0026#34;: 2048, \u0026#34;description\u0026#34;: \u0026#34;Custom embedding service\u0026#34; }\u0026#39; # Step 2: Create instance from that definition curl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/custom-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;my-custom-config\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-api-key-here\u0026#34; }\u0026#39;Managing Instances# List Your Instances# Get all instances you own or have access to:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;owned_instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 }, { \u0026#34;instance_id\u0026#34;: 124, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-cohere\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.cohere.ai/v1/embed\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embed-english-v4.0\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536 } ], \u0026#34;shared_instances\u0026#34;: [ { \u0026#34;instance_id\u0026#34;: 456, \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; } ] }Get Instance Details# Retrieve details for a specific instance:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Update Instance# Update instance configuration (owner only):\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-new-api-key-here\u0026#34; }\u0026#39;Delete Instance# Delete an instance (owner only):\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Note: Cannot delete instances that are used by existing projects.\nAPI Key Encryption# How Encryption Works# API keys are encrypted using AES-256-GCM encryption:\nEncryption Key Source: ENCRYPTION_KEY environment variable Key Derivation: SHA256 hash of the environment variable (ensures 32-byte key) Algorithm: AES-256-GCM (authenticated encryption) Storage: Encrypted bytes stored in api_key_encrypted column Setting Up Encryption# Add to your environment configuration:\n# .env file ENCRYPTION_KEY=\u0026#34;your-secure-random-32-character-key-or-longer\u0026#34;Important Security Notes:\nKeep this key secure and backed up Losing the key means losing access to encrypted API keys Use a strong, random string (32+ characters) Never commit the key to version control Rotate the key periodically (requires re-encrypting all API keys) API Key Security# API keys are write-only in the API:\n# Upload API key (works) curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-...\u0026#34;}\u0026#39; # Retrieve instance (API key NOT returned) curl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; # Response does NOT include api_key_encrypted field { \u0026#34;instance_id\u0026#34;: 123, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-instance\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 // No api_key_encrypted field! }This protects API keys from:\nAccidental exposure in logs Unauthorized access via shared instances Client-side data breaches Instance Sharing# Share an Instance# Grant another user access to your instance:\ncurl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;share_with_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34; }\u0026#39;Roles:\nreader: Can use the instance in projects (read-only) editor: Can use the instance (currently same as reader) owner: Full control (only one owner, the creator) List Shared Users# See who has access to your instance:\ncurl -X GET \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/shared-with\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;shared_with\u0026#34;: [ {\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;}, {\u0026#34;user_handle\u0026#34;: \u0026#34;charlie\u0026#34;, \u0026#34;role\u0026#34;: \u0026#34;reader\u0026#34;} ] }Unshare an Instance# Revoke access:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai/share/bob\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Using Shared Instances# Bob can reference Alice\u0026rsquo;s shared instance in his projects:\n# Bob creates a project using Alice\u0026#39;s instance curl -X PUT \u0026#34;https://api.example.com/v1/projects/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Using shared instance\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;my-openai\u0026#34; }\u0026#39; # Bob uploads embeddings using the shared instance curl -X POST \u0026#34;https://api.example.com/v1/embeddings/bob/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer bob_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc001\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;alice/my-openai\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, ...], \u0026#34;vector_dim\u0026#34;: 3072 }] }\u0026#39;Important: Bob can use the instance but cannot see Alice\u0026rsquo;s API key.\nInstance Sharing Patterns# Team Shared Instance# A team lead creates and shares an instance for the team:\n# Team lead creates instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/team_lead/team-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer team_lead_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-team-api-key\u0026#34; }\u0026#39; # Share with team members for member in alice bob charlie; do curl -X POST \u0026#34;https://api.example.com/v1/llm-services/team_lead/team-openai/share\u0026#34; \\ -H \u0026#34;Authorization: Bearer team_lead_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#34;{\\\u0026#34;share_with_handle\\\u0026#34;: \\\u0026#34;$member\\\u0026#34;, \\\u0026#34;role\\\u0026#34;: \\\u0026#34;reader\\\u0026#34;}\u0026#34; doneOrganization-Wide Instance# Create a shared instance for organization-wide use:\n# Organization admin creates instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/org_admin/org-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer org_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;org-embeddings\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;description\u0026#34;: \u0026#34;Organization-wide embedding service\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-org-api-key\u0026#34; }\u0026#39;Per-Project Instance# Each project maintainer creates their own instance:\n# Alice creates her own instance for her project curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/research-embeddings\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;research-embeddings\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-alice-research-key\u0026#34; }\u0026#39;Common Configurations# OpenAI Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-...\u0026#34; }Cohere Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;cohere-english\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.cohere.ai/v1/embed\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;cohere\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embed-english-v4.0\u0026#34;, \u0026#34;dimensions\u0026#34;: 1536, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-cohere-api-key\u0026#34; }Google Gemini Configuration# { \u0026#34;instance_handle\u0026#34;: \u0026#34;gemini-embedding\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;gemini\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;embedding-001\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;your-gemini-api-key\u0026#34; }Custom/Self-Hosted Service# { \u0026#34;instance_handle\u0026#34;: \u0026#34;custom-service\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://custom-api.example.com/v1/embeddings\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;custom-model-v2\u0026#34;, \u0026#34;dimensions\u0026#34;: 2048, \u0026#34;description\u0026#34;: \u0026#34;Self-hosted embedding service\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;custom-auth-token\u0026#34; }Projects and Instances# 1:1 Relationship# Each project must reference exactly one instance:\ncurl -X PUT \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;my-project\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Project with instance\u0026#34;, \u0026#34;instance_id\u0026#34;: 123 }\u0026#39;Changing Instance# Update a project to use a different instance:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_id\u0026#34;: 456}\u0026#39;Note: Only switch to instances with matching dimensions, or you\u0026rsquo;ll get validation errors on future uploads.\nFinding Instance for Project# curl -X GET \u0026#34;https://api.example.com/v1/projects/alice/my-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;The response includes the instance_id field.\nBest Practices# 1. Use System Definitions# Start with system definitions for common services:\n# Easiest approach curl -X POST \u0026#34;https://api.example.com/v1/llm-services/alice/my-instance\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;my-instance\u0026#34;, \u0026#34;definition_owner\u0026#34;: \u0026#34;_system\u0026#34;, \u0026#34;definition_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-...\u0026#34; }\u0026#39;2. Descriptive Instance Names# Use clear, descriptive names:\n# Good names \u0026#34;research-openai-large\u0026#34; \u0026#34;prod-cohere-english\u0026#34; \u0026#34;test-gemini-embedding\u0026#34; # Avoid generic names \u0026#34;instance1\u0026#34; \u0026#34;my-instance\u0026#34; \u0026#34;test\u0026#34;3. Separate Production and Development# Create separate instances for different environments:\n# Development instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/dev-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_handle\u0026#34;: \u0026#34;dev-openai\u0026#34;, ...}\u0026#39; # Production instance curl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/prod-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;instance_handle\u0026#34;: \u0026#34;prod-openai\u0026#34;, ...}\u0026#39;4. Document Instance Purpose# Use the description field:\ncurl -X PUT \u0026#34;https://api.example.com/v1/llm-services/alice/team-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;instance_handle\u0026#34;: \u0026#34;team-openai\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Shared OpenAI instance for research team. Contact alice@example.com for access.\u0026#34;, ... }\u0026#39;5. Regular Key Rotation# Periodically update API keys:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/my-openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;api_key_encrypted\u0026#34;: \u0026#34;sk-proj-new-key-here\u0026#34;}\u0026#39;6. Monitor Instance Usage# Track which projects use each instance to avoid deleting in-use instances.\nTroubleshooting# Cannot Delete Instance# Error: \u0026ldquo;Instance is in use by existing projects\u0026rdquo;\nSolution: Delete or update projects using this instance first.\nDimension Mismatch# Error: \u0026ldquo;vector dimension mismatch\u0026rdquo;\nSolution: Ensure embeddings match the instance\u0026rsquo;s configured dimensions.\nAPI Key Not Working# Problem: Embeddings uploads fail with authentication errors\nSolution:\nVerify API key is correct Check API key permissions with the LLM provider Update the API key in the instance Cannot Access Shared Instance# Problem: Getting \u0026ldquo;Instance not found\u0026rdquo; errors\nSolution: Verify you\u0026rsquo;ve been granted access. Contact the instance owner.\nRelated Documentation# RAG Workflow Guide - Complete RAG implementation Project Sharing Guide - Share projects with users Batch Operations Guide - Upload embeddings efficiently Security Summary# API keys are encrypted at rest using AES-256-GCM API keys are never returned via GET requests Shared users cannot see API keys (write-only field) Encryption key must be secured (loss means cannot decrypt keys) Regular key rotation recommended for production use "},{"id":47,"href":"/dhamps-vdb/api/patch-updates/","title":"PATCH Updates","section":"API Reference","content":"PATCH Method for Partial Updates# The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.\nOverview# PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:\nRetrieves the current resource state via GET Merges your changes with the existing data Applies the update via PUT This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.\nSupported Resources# PATCH is available for:\nUsers: /v1/users/{username} Projects: /v1/projects/{username}/{projectname} LLM Services: /v1/llm-services/{username}/{llm_servicename} API Standards: /v1/api-standards/{standardname} Request Format# Endpoint: PATCH {resource_url}\nContent-Type: application/json\nBody: JSON object containing only the fields to update\nExamples# Update Project Description# Change only the project description without affecting other fields.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34; }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated project description\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false } Enable Public Read Access# Make a project publicly accessible without changing other settings.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;public_read\u0026#34;: true }\u0026#39;Response:\n{ \u0026#34;project_id\u0026#34;: 1, \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research document embeddings\u0026#34;, \u0026#34;instance_id\u0026#34;: 5, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: true } Update User Email# Change a user\u0026rsquo;s email address without affecting other user data.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/users/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_or_admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;email\u0026#34;: \u0026#34;alice.new@example.com\u0026#34; }\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Alice Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;alice.new@example.com\u0026#34; } Update LLM Service Description# Change the description of an LLM service instance.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Production OpenAI embeddings service\u0026#34; }\u0026#39;Response:\n{ \u0026#34;instance_id\u0026#34;: 1, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;endpoint\u0026#34;: \u0026#34;https://api.openai.com/v1/embeddings\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Production OpenAI embeddings service\u0026#34;, \u0026#34;api_standard\u0026#34;: \u0026#34;openai\u0026#34;, \u0026#34;model\u0026#34;: \u0026#34;text-embedding-3-large\u0026#34;, \u0026#34;dimensions\u0026#34;: 3072 } Update API Standard Documentation# Update the description of an API standard (admin only).\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/api-standards/openai\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;OpenAI Embeddings API, Version 1 - Updated 2024\u0026#34; }\u0026#39; Update Multiple Fields# You can update multiple fields in a single PATCH request.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;public_read\u0026#34;: true }\u0026#39; Add Project Metadata Schema# Add or update a project\u0026rsquo;s metadata validation schema.\nRequest:\ncurl -X PATCH \u0026#34;https://api.example.com/v1/projects/alice/research-docs\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;author\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;},\\\u0026#34;year\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;integer\\\u0026#34;}},\\\u0026#34;required\\\u0026#34;:[\\\u0026#34;author\\\u0026#34;]}\u0026#34; }\u0026#39; Use Cases# Configuration Changes# Update configuration settings without rebuilding entire resource objects:\n# Enable/disable public access curl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39; # Update instance dimensions curl -X PATCH \u0026#34;.../llm-services/alice/custom-model\u0026#34; \\ -d \u0026#39;{\u0026#34;dimensions\u0026#34;: 1024}\u0026#39; Metadata Management# Update descriptive metadata:\n# Update project description curl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34;}\u0026#39; # Update user name curl -X PATCH \u0026#34;.../users/alice\u0026#34; \\ -d \u0026#39;{\u0026#34;name\u0026#34;: \u0026#34;Alice Smith\u0026#34;}\u0026#39; Schema Evolution# Add or update validation schemas:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;metadataScheme\u0026#34;: \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;object\\\u0026#34;,\\\u0026#34;properties\\\u0026#34;:{\\\u0026#34;category\\\u0026#34;:{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;string\\\u0026#34;}}}\u0026#34; }\u0026#39; Authentication# PATCH requests require the same authentication as PUT requests for the resource:\nResource Who Can PATCH Users Admin or the user themselves Projects Admin or project owner LLM Services Admin or instance owner API Standards Admin only Behavior Details# Merge Strategy# PATCH uses a shallow merge strategy:\nTop-level fields you specify replace the existing values Nested objects are replaced entirely (not deep-merged) Fields you don\u0026rsquo;t specify remain unchanged Example:\nExisting project:\n{ \u0026#34;description\u0026#34;: \u0026#34;Old description\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...old schema...}\u0026#34; }PATCH request:\n{ \u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34; }Result:\n{ \u0026#34;description\u0026#34;: \u0026#34;New description\u0026#34;, \u0026#34;public_read\u0026#34;: false, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...old schema...}\u0026#34; } Validation# All field values are validated according to the resource\u0026rsquo;s schema:\nField types must be correct Required fields (if specified) must be valid Constraints (e.g., string length, enum values) are enforced Atomic Operations# PATCH operations are atomic:\nEither all changes succeed, or none are applied If validation fails, the resource remains unchanged Comparison: PATCH vs PUT# PUT (Complete Replacement)# Requires: All fields (except read-only ones)\ncurl -X PUT \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: false }\u0026#39;Use when: Creating or completely replacing a resource\nPATCH (Partial Update)# Requires: Only fields to change\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated description\u0026#34; }\u0026#39;Use when: Modifying one or a few fields of an existing resource\nError Handling# 400 Bad Request# Invalid field values or types:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid value for field \u0026#39;public_read\u0026#39;: expected boolean, got string\u0026#34; } 401 Unauthorized# Missing or invalid authentication:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; } 403 Forbidden# Insufficient permissions:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify this resource\u0026#34; } 404 Not Found# Resource doesn\u0026rsquo;t exist:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; } 422 Unprocessable Entity# Validation failed:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unprocessable Entity\u0026#34;, \u0026#34;status\u0026#34;: 422, \u0026#34;detail\u0026#34;: \u0026#34;metadataScheme is not valid JSON Schema\u0026#34; } Best Practices# Use PATCH for Single-Field Updates# Do:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{\u0026#34;public_read\u0026#34;: true}\u0026#39;Don\u0026rsquo;t:\n# Unnecessarily complex curl -X PUT \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;project_handle\u0026#34;: \u0026#34;research-docs\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Research docs\u0026#34;, \u0026#34;instance_owner\u0026#34;: \u0026#34;alice\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;public_read\u0026#34;: true }\u0026#39; Group Related Changes# Update multiple related fields in one request:\ncurl -X PATCH \u0026#34;.../projects/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;description\u0026#34;: \u0026#34;Updated project\u0026#34;, \u0026#34;public_read\u0026#34;: true, \u0026#34;metadataScheme\u0026#34;: \u0026#34;{...new schema...}\u0026#34; }\u0026#39; Validate Before Patching# When possible, validate changes locally before submitting:\n# Python example def update_project_description(project_path, new_description): if not new_description or len(new_description) \u0026gt; 500: raise ValueError(\u0026#34;Invalid description\u0026#34;) response = requests.patch( f\u0026#34;{API_BASE}/projects/{project_path}\u0026#34;, json={\u0026#34;description\u0026#34;: new_description}, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {API_KEY}\u0026#34;} ) return response.json() Handle Errors Gracefully# response = requests.patch( f\u0026#34;{API_BASE}/projects/alice/research-docs\u0026#34;, json={\u0026#34;public_read\u0026#34;: True}, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {API_KEY}\u0026#34;} ) if response.status_code == 200: print(\u0026#34;Updated successfully\u0026#34;) elif response.status_code == 403: print(\u0026#34;Permission denied\u0026#34;) elif response.status_code == 404: print(\u0026#34;Project not found\u0026#34;) else: print(f\u0026#34;Error: {response.json()[\u0026#39;detail\u0026#39;]}\u0026#34;) Limitations# Not Available For# PATCH is not available for:\nEndpoints that don\u0026rsquo;t support GET and PUT List endpoints (e.g., GET /v1/projects/alice) Action endpoints (e.g., /share, /transfer-ownership) Cannot Change Identifiers# You cannot use PATCH to change resource identifiers:\nuser_handle project_handle instance_handle api_standard_handle To rename a resource, you must create a new resource and delete the old one.\nRelated Documentation# Users - User management endpoints Projects - Project management endpoints LLM Services - LLM service instance endpoints API Standards - API standard endpoints Error Handling - Error response reference "},{"id":48,"href":"/dhamps-vdb/api/error-handling/","title":"Error Handling","section":"API Reference","content":"Error Handling# The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.\nError Response Format# All error responses follow this structure:\n{ \u0026#34;title\u0026#34;: \u0026#34;Error Title\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Detailed error message explaining what went wrong\u0026#34; }Fields:\ntitle (string): Human-readable error title status (integer): HTTP status code detail (string): Detailed description of the error HTTP Status Codes# 2xx Success# 200 OK# Request succeeded. Response body contains requested data.\nExample:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;projects\u0026#34;: [...] } 201 Created# Resource created successfully. Response body contains the new resource.\nExample:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Response:\n{ \u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;, \u0026#34;api_key\u0026#34;: \u0026#34;...\u0026#34; } 4xx Client Errors# 400 Bad Request# The request is invalid or contains malformed data.\nCommon causes:\nInvalid JSON syntax Missing required fields Invalid field values or types Dimension mismatches in embeddings Metadata schema violations Invalid query parameter values Examples:\nInvalid JSON:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid JSON: unexpected end of input\u0026#34; }Missing required field:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Missing required field: project_handle\u0026#34; }Dimension mismatch:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3072 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 1536 dimensions\u0026#34; }Metadata validation:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }Invalid query parameter:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;limit must be between 1 and 200\u0026#34; } 401 Unauthorized# Authentication failed or credentials are missing.\nCommon causes:\nMissing Authorization header Invalid API key Expired API key Malformed Authorization header Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Troubleshooting:\nVerify the Authorization header is present Check the API key is correct Ensure the header format is Authorization: Bearer \u0026lt;api_key\u0026gt; Verify the user still exists 403 Forbidden# Authentication succeeded but authorization failed. The authenticated user lacks permission for the requested operation.\nCommon causes:\nUser attempting to access another user\u0026rsquo;s private resources Non-admin attempting admin-only operations User attempting to modify shared resources they don\u0026rsquo;t own Attempting to access resources with insufficient role (reader vs editor) Examples:\nAdmin-only operation:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }Accessing another user\u0026rsquo;s resource:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this project\u0026#34; }Insufficient role:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to modify embeddings in this project. Editor role required.\u0026#34; } 404 Not Found# The requested resource does not exist.\nCommon causes:\nResource was deleted Incorrect resource identifier Typo in URL path Resource never existed Examples:\nUser not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; not found\u0026#34; }Project not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Project \u0026#39;alice/research-docs\u0026#39; not found\u0026#34; }Embedding not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;Embedding \u0026#39;doc123\u0026#39; not found in project \u0026#39;alice/research-docs\u0026#39;\u0026#34; }LLM service not found:\n{ \u0026#34;title\u0026#34;: \u0026#34;Not Found\u0026#34;, \u0026#34;status\u0026#34;: 404, \u0026#34;detail\u0026#34;: \u0026#34;LLM service instance \u0026#39;alice/openai-large\u0026#39; not found\u0026#34; } 409 Conflict# The request conflicts with the current state of the resource.\nCommon causes:\nCreating a resource that already exists Deleting a resource that is in use Concurrent modification conflicts Examples:\nResource already exists:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Resource in use:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete LLM service instance: in use by 3 projects\u0026#34; }Ownership transfer conflict:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;New owner already has a project with handle \u0026#39;research-docs\u0026#39;\u0026#34; } 422 Unprocessable Entity# The request is syntactically correct but semantically invalid.\nCommon causes:\nInvalid JSON Schema Logical validation failures Constraint violations Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unprocessable Entity\u0026#34;, \u0026#34;status\u0026#34;: 422, \u0026#34;detail\u0026#34;: \u0026#34;metadataScheme is not valid JSON Schema: invalid schema structure\u0026#34; } 5xx Server Errors# 500 Internal Server Error# An unexpected error occurred on the server.\nCommon causes:\nDatabase connection failures Unexpected exceptions Configuration errors Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Internal Server Error\u0026#34;, \u0026#34;status\u0026#34;: 500, \u0026#34;detail\u0026#34;: \u0026#34;An internal error occurred. Please try again later.\u0026#34; }Action: Contact support if the error persists.\n503 Service Unavailable# The service is temporarily unavailable.\nCommon causes:\nDatabase maintenance Service overload Network issues Example:\n{ \u0026#34;title\u0026#34;: \u0026#34;Service Unavailable\u0026#34;, \u0026#34;status\u0026#34;: 503, \u0026#34;detail\u0026#34;: \u0026#34;Service temporarily unavailable. Please try again later.\u0026#34; }Action: Retry the request after a delay.\nCommon Error Scenarios# Authentication Errors# Missing Authorization Header# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Solution: Include the Authorization header:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; Invalid API Key# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/alice\u0026#34; \\ -H \u0026#34;Authorization: Bearer invalid_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Unauthorized\u0026#34;, \u0026#34;status\u0026#34;: 401, \u0026#34;detail\u0026#34;: \u0026#34;Invalid or missing authorization credentials\u0026#34; }Solution: Verify your API key is correct.\nPermission Errors# Non-Admin Creating Users# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;Only admin users can create new users\u0026#34; }Solution: Use an admin API key.\nAccessing Another User\u0026rsquo;s Project# Request:\ncurl -X GET \u0026#34;https://api.example.com/v1/projects/bob/private-project\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Forbidden\u0026#34;, \u0026#34;status\u0026#34;: 403, \u0026#34;detail\u0026#34;: \u0026#34;You don\u0026#39;t have permission to access this project\u0026#34; }Solution: Request the project owner to share the project with you.\nValidation Errors# Invalid JSON# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;Invalid JSON: unexpected end of input\u0026#34; }Solution: Fix the JSON syntax.\nDimension Mismatch# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [0.1, 0.2, 0.3], \u0026#34;vector_dim\u0026#34;: 3 }] }\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;dimension validation failed: vector dimension mismatch: embedding declares 3 dimensions but LLM service \u0026#39;openai-large\u0026#39; expects 3072 dimensions\u0026#34; }Solution: Ensure vector dimensions match the LLM service configuration.\nMetadata Schema Violation# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34; \\ -d \u0026#39;{ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: \u0026#34;doc123\u0026#34;, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: [...], \u0026#34;vector_dim\u0026#34;: 3072, \u0026#34;metadata\u0026#34;: { \u0026#34;year\u0026#34;: 2024 } }] }\u0026#39;Response (if project schema requires \u0026ldquo;author\u0026rdquo;):\n{ \u0026#34;title\u0026#34;: \u0026#34;Bad Request\u0026#34;, \u0026#34;status\u0026#34;: 400, \u0026#34;detail\u0026#34;: \u0026#34;metadata validation failed for text_id \u0026#39;doc123\u0026#39;: metadata validation failed:\\n - author: author is required\u0026#34; }Solution: Include all required metadata fields.\nResource Conflicts# Creating Duplicate Resource# Request:\ncurl -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;alice\u0026#34;}\u0026#39;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;User \u0026#39;alice\u0026#39; already exists\u0026#34; }Solution: Use a different user handle or update the existing user.\nDeleting Resource In Use# Request:\ncurl -X DELETE \u0026#34;https://api.example.com/v1/llm-services/alice/openai-large\u0026#34; \\ -H \u0026#34;Authorization: Bearer alice_api_key\u0026#34;Response:\n{ \u0026#34;title\u0026#34;: \u0026#34;Conflict\u0026#34;, \u0026#34;status\u0026#34;: 409, \u0026#34;detail\u0026#34;: \u0026#34;Cannot delete LLM service instance: in use by 3 projects\u0026#34; }Solution: Delete or update the projects using this instance first.\nError Handling Best Practices# Client-Side Error Handling# Python example:\nimport requests response = requests.get( \u0026#34;https://api.example.com/v1/projects/alice\u0026#34;, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;} ) if response.status_code == 200: projects = response.json()[\u0026#34;projects\u0026#34;] print(f\u0026#34;Found {len(projects)} projects\u0026#34;) elif response.status_code == 401: print(\u0026#34;Authentication failed - check API key\u0026#34;) elif response.status_code == 403: print(\u0026#34;Permission denied\u0026#34;) elif response.status_code == 404: print(\u0026#34;User not found\u0026#34;) elif response.status_code \u0026gt;= 500: print(\u0026#34;Server error - retry later\u0026#34;) else: error = response.json() print(f\u0026#34;Error: {error[\u0026#39;detail\u0026#39;]}\u0026#34;) Retry Logic# For transient errors (5xx), implement exponential backoff:\nimport time import requests def api_request_with_retry(url, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers={...}) if response.status_code \u0026lt; 500: return response if attempt \u0026lt; max_retries - 1: wait_time = 2 ** attempt # Exponential backoff print(f\u0026#34;Retrying in {wait_time}s...\u0026#34;) time.sleep(wait_time) return response Validation Before Request# Validate data locally before sending to reduce 400 errors:\ndef create_embedding(text_id, vector, metadata): # Validate locally if not text_id: raise ValueError(\u0026#34;text_id is required\u0026#34;) if not isinstance(vector, list): raise ValueError(\u0026#34;vector must be a list\u0026#34;) if len(vector) != 3072: raise ValueError(\u0026#34;vector must have 3072 dimensions\u0026#34;) # Send request response = requests.post( \u0026#34;https://api.example.com/v1/embeddings/alice/research-docs\u0026#34;, json={ \u0026#34;embeddings\u0026#34;: [{ \u0026#34;text_id\u0026#34;: text_id, \u0026#34;instance_handle\u0026#34;: \u0026#34;openai-large\u0026#34;, \u0026#34;vector\u0026#34;: vector, \u0026#34;vector_dim\u0026#34;: len(vector), \u0026#34;metadata\u0026#34;: metadata }] }, headers={\u0026#34;Authorization\u0026#34;: f\u0026#34;Bearer {api_key}\u0026#34;} ) return response.json() Troubleshooting# Check API Documentation# Always refer to the live API documentation:\nOpenAPI YAML: /openapi.yaml Interactive Docs: /docs Verify Request Format# Use tools like curl -v to inspect the full request:\ncurl -v -X POST \u0026#34;https://api.example.com/v1/users\u0026#34; \\ -H \u0026#34;Authorization: Bearer admin_api_key\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{\u0026#34;user_handle\u0026#34;: \u0026#34;bob\u0026#34;}\u0026#39; Check Status and Logs# For persistent 5xx errors, check service status and logs (if you have access).\nContact Support# If errors persist or the cause is unclear:\nNote the error message and status code Record the request details (method, URL, headers, body) Check if the issue is reproducible Contact support with this information Related Documentation# Authentication - API authentication guide Query Parameters - Valid parameter values Endpoints - Complete endpoint reference "}] \ No newline at end of file diff --git a/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js b/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js deleted file mode 100644 index 0b5c792..0000000 --- a/docs/public/en.search.min.dfbd912265f0ab4ca87f3cda4f5fd68f3a3c607aac07b5a1445fb5c7480f879a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(function(){const o="/dhamps-vdb/en.search-data.min.d18154d153b457904940e5d3d5fb05a356d5d9f40e308f4ec936f40762c90de5.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js b/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js deleted file mode 100644 index 0241b04..0000000 --- a/docs/public/en.search.min.e5f99ffd1cb4862bdf1bad2554c0460e5894c72e7286c511967078b24f321f5e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(function(){const o="/dhamps-vdb/en.search-data.min.4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/docs/public/favicon.png b/docs/public/favicon.png deleted file mode 100644 index 6f545a570a80bd385cfdc27af249c7babe647e31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj_dQ)4Ln;{Ggf?hJij@#(b6^dom#@~z%SdyL~kcG zYv&2dTggrTEH&wQ;ZCv66P2$DAJ6*q?T%^Em(HugMFiE%XK3moU)_^$#b% z5a#;KXjuDfy+i)YhIdamCaKwEiDx}N^}EimL-~4?+Jd!`8cCgN>(m;Y1P-=tmH4z) ulvO8j-G87@|Nl?rlH~?^l?~)oW` \ No newline at end of file diff --git a/docs/public/fuse.min.js b/docs/public/fuse.min.js deleted file mode 100644 index 0d509f3..0000000 --- a/docs/public/fuse.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Fuse.js v7.1.0 - Lightweight fuzzy-search (http://fusejs.io) - * - * Copyright (c) 2025 Kiro Risk (http://kiro.me) - * All Rights Reserved. Apache Software License 2.0 - * - * http://www.apache.org/licenses/LICENSE-2.0 - */ -var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?O.getFn:n,u=t.fieldNormWeight,o=void 0===u?O.fieldNormWeight:u;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(j).length;if(n.has(i))return n.get(i);var u=1/Math.pow(i,.5*e),o=parseFloat(Math.round(u*r)/r);return n.set(i,o),o},clear:function(){n.clear()}}}(o,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return u(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,A(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();A(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?O.getFn:r,u=n.fieldNormWeight,o=void 0===u?O.fieldNormWeight:u,c=new I({getFn:i,fieldNormWeight:o});return c.setKeys(e.map(w)),c.setSources(t),c.create(),c}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,u=void 0===i?0:i,o=t.expectedLocation,c=void 0===o?0:o,a=t.distance,s=void 0===a?O.distance:a,h=t.ignoreLocation,l=void 0===h?O.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(c-u);return s?f+d/s:d?1:f}var N=32;function P(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,u=void 0===i?O.location:i,o=r.distance,c=void 0===o?O.distance:o,a=r.threshold,s=void 0===a?O.threshold:a,h=r.findAllMatches,l=void 0===h?O.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?O.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?O.includeMatches:v,y=r.ignoreLocation,p=void 0===y?O.ignoreLocation:y;if(t.length>N)throw new Error("Pattern length exceeds max of ".concat(N,"."));for(var A,m=t.length,C=e.length,k=Math.max(0,Math.min(u,C)),E=s,F=k,M=d>1||g,b=M?Array(C):[];(A=e.indexOf(t,F))>-1;){var D=R(t,{currentLocation:A,expectedLocation:k,distance:c,ignoreLocation:p});if(E=Math.min(D,E),F=A+m,M)for(var B=0;B=$;z-=1){var T=z-1,K=n[e.charAt(T)];if(M&&(b[T]=+!!K),W[z]=(W[z+1]<<1|1)&K,_&&(W[z]|=(x[z+1]|x[z])<<1|1|x[z+1]),W[z]&L&&(w=R(t,{errors:_,currentLocation:T,expectedLocation:k,distance:c,ignoreLocation:p}))<=E){if(E=w,(F=T)<=k)break;$=Math.max(1,2*k-F)}}if(R(t,{errors:_+1,currentLocation:k,expectedLocation:k,distance:c,ignoreLocation:p})>E)break;x=W}var q={isMatch:F>=0,score:Math.max(.001,w)};if(M){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:O.minMatchCharLength,n=[],r=-1,i=-1,u=0,o=e.length;u=t&&n.push([r,i]),r=-1)}return e[u-1]&&u-r>=t&&n.push([r,u-1]),n}(b,d);J.length?g&&(q.indices=J):q.isMatch=!1}return q}function W(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},u=i.location,o=void 0===u?O.location:u,c=i.threshold,a=void 0===c?O.threshold:c,s=i.distance,h=void 0===s?O.distance:s,l=i.includeMatches,f=void 0===l?O.includeMatches:l,d=i.findAllMatches,v=void 0===d?O.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?O.minMatchCharLength:g,p=i.isCaseSensitive,A=void 0===p?O.isCaseSensitive:p,m=i.ignoreDiacritics,C=void 0===m?O.ignoreDiacritics:m,k=i.ignoreLocation,E=void 0===k?O.ignoreLocation:k;if(r(this,e),this.options={location:o,threshold:a,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:A,ignoreDiacritics:C,ignoreLocation:E},t=A?t:t.toLowerCase(),t=C?z(t):t,this.pattern=t,this.chunks=[],this.pattern.length){var F=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},M=this.pattern.length;if(M>N){for(var b=0,D=M%N,B=M-D;b1&&void 0!==arguments[1]?arguments[1]:{},o=u.location,c=void 0===o?O.location:o,a=u.threshold,s=void 0===a?O.threshold:a,h=u.distance,l=void 0===h?O.distance:h,f=u.includeMatches,d=void 0===f?O.includeMatches:f,v=u.findAllMatches,g=void 0===v?O.findAllMatches:v,y=u.minMatchCharLength,p=void 0===y?O.minMatchCharLength:y,A=u.isCaseSensitive,m=void 0===A?O.isCaseSensitive:A,C=u.ignoreDiacritics,k=void 0===C?O.ignoreDiacritics:C,E=u.ignoreLocation,F=void 0===E?O.ignoreLocation:E;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:c,threshold:s,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:m,ignoreDiacritics:k,ignoreLocation:F}),i}return u(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),Y=function(e){c(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return u(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var u=!!r.length;return{isMatch:u,score:u?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Z=[J,Y,V,G,Q,H,U,X],ee=Z.length,te=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,ne=new Set([X.type,Y.type]),re=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,u=void 0===i?O.isCaseSensitive:i,o=n.ignoreDiacritics,c=void 0===o?O.ignoreDiacritics:o,a=n.includeMatches,s=void 0===a?O.includeMatches:a,h=n.minMatchCharLength,l=void 0===h?O.minMatchCharLength:h,f=n.ignoreLocation,d=void 0===f?O.ignoreLocation:f,v=n.findAllMatches,g=void 0===v?O.findAllMatches:v,y=n.location,p=void 0===y?O.location:y,A=n.threshold,m=void 0===A?O.threshold:A,C=n.distance,k=void 0===C?O.distance:C;r(this,e),this.query=null,this.options={isCaseSensitive:u,ignoreDiacritics:c,includeMatches:s,minMatchCharLength:l,findAllMatches:g,ignoreLocation:d,location:p,threshold:m,distance:k},t=u?t:t.toLowerCase(),t=c?z(t):t,this.pattern=t,this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(te).filter((function(e){return e&&!!e.trim()})),r=[],i=0,u=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return he(e)||(e=le(e)),function e(n){var i=Object.keys(n),u=function(e){return!!e[ae]}(n);if(!u&&i.length>1&&!he(n))return e(le(n));if(function(e){return!g(e)&&k(e)&&!he(e)}(n)){var o=u?n[ae]:i[0],c=u?n[se]:n[o];if(!A(c))throw new Error(function(e){return"Invalid value for key ".concat(e)}(o));var a={keyId:L(o),pattern:c};return r&&(a.searcher=ue(c,t)),a}var s={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){s.children.push(e(t))}))})),s}(e)}function de(e,t){var n=e.matches;t.matches=[],E(n)&&n.forEach((function(e){if(E(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}var ge=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},u=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},O),i),this.options.useExtendedSearch,this._keyStore=new x(this.options.keys),this.setCollection(n,u)}return u(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof I))throw new Error("Incorrect 'index' type");this._myIndex=t||$(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){E(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,u=r.includeScore,o=r.shouldSort,c=r.sortFn,a=r.ignoreFieldNorm,s=A(e)?A(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?O.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,u=e.score,o=n?n.weight:null;t*=Math.pow(0===u&&o?Number.EPSILON:u,(o||1)*(r?1:i))})),e.score=t}))}(s,{ignoreFieldNorm:a}),o&&s.sort(c),m(n)&&n>-1&&(s=s.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?O.includeMatches:r,u=n.includeScore,o=void 0===u?O.includeScore:u,c=[];return i&&c.push(de),o&&c.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return c.length&&c.forEach((function(t){t(e,r)})),r}))}(s,this._docs,{includeMatches:i,includeScore:u})}},{key:"_searchStringList",value:function(e){var t=ue(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,u=e.n;if(E(n)){var o=t.searchIn(n),c=o.isMatch,a=o.score,s=o.indices;c&&r.push({item:n,idx:i,matches:[{score:a,value:n,norm:u,indices:s}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=fe(e,this.options),r=function e(n,r,i){if(!n.children){var u=n.keyId,o=n.searcher,c=t._findMatches({key:t._keyStore.get(u),value:t._myIndex.getValueForItemAtKeyId(r,u),searcher:o});return c&&c.length?[{idx:i,item:r,matches:c}]:[]}for(var a=[],s=0,h=n.children.length;s1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?O.getFn:n,i=t.fieldNormWeight,u=void 0===i?O.fieldNormWeight:i,o=e.keys,c=e.records,a=new I({getFn:r,fieldNormWeight:u});return a.setKeys(o),a.setIndexRecords(c),a},ge.config=O,function(){ie.push.apply(ie,arguments)}(re),ge},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); \ No newline at end of file diff --git a/docs/public/getting-started/configuration/index.html b/docs/public/getting-started/configuration/index.html deleted file mode 100644 index 9a1fec5..0000000 --- a/docs/public/getting-started/configuration/index.html +++ /dev/null @@ -1,52 +0,0 @@ -Configuration | dhamps-vdb Documentation - -

    Configuration#

    Configure dhamps-vdb using environment variables or command-line options.

    Environment Variables#

    All configuration can be set via environment variables. Use a .env file to keep sensitive information secure.

    Service Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_DEBUGEnable debug loggingtrueNo
    SERVICE_HOSTHostname to listen onlocalhostNo
    SERVICE_PORTPort to listen on8880No

    Database Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_DBHOSTDatabase hostnamelocalhostYes
    SERVICE_DBPORTDatabase port5432No
    SERVICE_DBUSERDatabase usernamepostgresYes
    SERVICE_DBPASSWORDDatabase passwordpasswordYes
    SERVICE_DBNAMEDatabase namepostgresYes

    Security Configuration#

    VariableDescriptionDefaultRequired
    SERVICE_ADMINKEYAdmin API key for administrative operations-Yes
    ENCRYPTION_KEYEncryption key for API keys (32+ characters)-Yes

    Configuration File#

    Create a .env file in the project root:

    # Service Configuration
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -
    -# Database Configuration
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=secure_password
    -SERVICE_DBNAME=dhamps_vdb
    -
    -# Security
    -SERVICE_ADMINKEY=your-secure-admin-key-here
    -ENCRYPTION_KEY=your-32-character-encryption-key-minimum

    Command-Line Options#

    You can also provide configuration via command-line flags:

    ./dhamps-vdb \
    -  --debug \
    -  -p 8880 \
    -  --db-host localhost \
    -  --db-port 5432 \
    -  --db-user dhamps_user \
    -  --db-password secure_password \
    -  --db-name dhamps_vdb \
    -  --admin-key your-admin-key

    Generating Secure Keys#

    Admin Key#

    Generate a secure admin key:

    openssl rand -base64 32

    Encryption Key#

    Generate a secure encryption key (minimum 32 characters):

    openssl rand -hex 32

    Configuration Priority#

    Configuration is loaded in the following order (later sources override earlier ones):

    1. Default values (from options.go)
    2. Environment variables
    3. .env file
    4. Command-line flags

    Security Best Practices#

    • Never commit .env files to version control
    • Use strong, randomly generated keys for production
    • Ensure .env file permissions are restrictive (chmod 600 .env)
    • Store encryption key securely - losing it means losing access to encrypted API keys
    • Use different keys for development and production environments

    Example Configuration#

    Development#

    # .env (development)
    -SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=password
    -SERVICE_DBNAME=dhamps_vdb_dev
    -SERVICE_ADMINKEY=dev-admin-key-change-me
    -ENCRYPTION_KEY=dev-encryption-key-32-chars-min

    Production#

    # .env (production)
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=prod-db.example.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_prod
    -SERVICE_DBPASSWORD=$(cat /run/secrets/db_password)
    -SERVICE_DBNAME=dhamps_vdb
    -SERVICE_ADMINKEY=$(cat /run/secrets/admin_key)
    -ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)

    Validation#

    The service validates configuration on startup and will exit with an error if required variables are missing.

    Next Steps#

    After configuration:

    1. Run the Quick Start tutorial
    2. Create your first project
    3. Review deployment options
    \ No newline at end of file diff --git a/docs/public/getting-started/docker/index.html b/docs/public/getting-started/docker/index.html deleted file mode 100644 index 6ecc03b..0000000 --- a/docs/public/getting-started/docker/index.html +++ /dev/null @@ -1,183 +0,0 @@ -Docker Deployment | dhamps-vdb Documentation - -

    Docker Deployment#

    Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.

    Quick Start#

    The fastest way to get dhamps-vdb running with Docker:

    # Clone the repository
    -git clone https://github.com/mpilhlt/dhamps-vdb.git
    -cd dhamps-vdb
    -
    -# Run automated setup (generates secure keys)
    -./docker-setup.sh
    -
    -# Start services with docker-compose
    -docker-compose up -d
    -
    -# Check logs
    -docker-compose logs -f dhamps-vdb
    -
    -# Access the API
    -curl http://localhost:8880/docs

    What’s Included#

    The Docker Compose setup includes:

    • dhamps-vdb: The vector database API service
    • PostgreSQL 16: Database with pgvector extension
    • Persistent storage: Named volume for database data

    Configuration Files#

    .env File#

    All configuration is managed through environment variables. Copy the template:

    cp .env.docker.template .env

    Edit .env to set required values:

    # Admin API key for administrative operations
    -SERVICE_ADMINKEY=your-secure-admin-key-here
    -
    -# Encryption key for API keys (32+ characters)
    -ENCRYPTION_KEY=your-secure-encryption-key-min-32-chars
    -
    -# Database password
    -SERVICE_DBPASSWORD=secure-database-password
    -
    -# Optional: Debug mode
    -SERVICE_DEBUG=false
    -
    -# Optional: Change ports
    -API_PORT=8880
    -POSTGRES_PORT=5432

    docker-compose.yml#

    The compose file defines two services:

    services:
    -  postgres:
    -    image: pgvector/pgvector:0.7.4-pg16
    -    # PostgreSQL with pgvector support
    -    
    -  dhamps-vdb:
    -    build: .
    -    # The API service
    -    depends_on:
    -      - postgres

    Deployment Options#

    Use the provided docker-compose.yml:

    docker-compose up -d

    Advantages:

    • Everything included
    • Automatic networking
    • Data persistence
    • Easy to manage

    Use when:

    • Getting started
    • Development/testing
    • Small to medium deployments

    Option 2: Standalone Container with External Database#

    Run only the dhamps-vdb container:

    # Build the image
    -docker build -t dhamps-vdb:latest .
    -
    -# Run the container
    -docker run -d \
    -  --name dhamps-vdb \
    -  -p 8880:8880 \
    -  -e SERVICE_DBHOST=your-db-host \
    -  -e SERVICE_DBPORT=5432 \
    -  -e SERVICE_DBUSER=dbuser \
    -  -e SERVICE_DBPASSWORD=dbpass \
    -  -e SERVICE_DBNAME=dhamps_vdb \
    -  -e SERVICE_ADMINKEY=admin-key \
    -  -e ENCRYPTION_KEY=encryption-key \
    -  dhamps-vdb:latest

    Use when:

    • You have an existing PostgreSQL server
    • Production deployments
    • Need database separation

    Option 3: Docker Compose with External Database#

    Modify docker-compose.yml to remove the postgres service:

    services:
    -  dhamps-vdb:
    -    build: .
    -    ports:
    -      - "${API_PORT:-8880}:8880"
    -    environment:
    -      SERVICE_DBHOST: external-db.example.com
    -      # ... other variables

    Building the Image#

    Standard Build#

    docker build -t dhamps-vdb:latest .

    Custom Tag#

    docker build -t dhamps-vdb:v0.1.0 .

    Clean Build (No Cache)#

    docker build --no-cache -t dhamps-vdb:latest .

    Multi-Stage Build Details#

    The Dockerfile uses multi-stage builds for efficiency:

    1. Builder stage: Compiles Go code with sqlc generation
    2. Runtime stage: Minimal Alpine image with only the binary

    Result: Small, secure image (~20MB vs 800MB+)

    Managing Services#

    Start Services#

    # Start in background
    -docker-compose up -d
    -
    -# Start with logs visible
    -docker-compose up
    -
    -# Rebuild and start
    -docker-compose up -d --build

    View Logs#

    # All logs
    -docker-compose logs
    -
    -# Follow logs in real-time
    -docker-compose logs -f
    -
    -# Specific service
    -docker-compose logs -f dhamps-vdb
    -docker-compose logs -f postgres

    Stop Services#

    # Stop containers (keeps data)
    -docker-compose stop
    -
    -# Stop and remove containers (keeps data)
    -docker-compose down
    -
    -# Stop and remove everything including data
    -docker-compose down -v

    Restart Services#

    # Restart all
    -docker-compose restart
    -
    -# Restart specific service
    -docker-compose restart dhamps-vdb

    Data Persistence#

    Docker Volumes#

    The compose file creates a named volume:

    volumes:
    -  postgres_data:

    This ensures database data persists across container restarts.

    View Volumes#

    docker volume ls

    Inspect Volume#

    docker volume inspect dhamps-vdb_postgres_data

    Backup Database#

    # Create backup
    -docker-compose exec postgres pg_dump -U postgres dhamps_vdb > backup.sql
    -
    -# Restore from backup
    -docker-compose exec -T postgres psql -U postgres dhamps_vdb < backup.sql

    Networking#

    Access from Host#

    The API is accessible at:

    http://localhost:8880

    Access from Other Containers#

    Use the service name as hostname:

    http://dhamps-vdb:8880

    Custom Network#

    To use an existing Docker network:

    networks:
    -  default:
    -    external:
    -      name: your-network-name

    Security#

    Required Environment Variables#

    Two critical environment variables must be set:

    1. SERVICE_ADMINKEY: Admin API key
    2. ENCRYPTION_KEY: For encrypting user API keys (32+ chars)

    Generating Secure Keys#

    # Admin key
    -openssl rand -base64 32
    -
    -# Encryption key
    -openssl rand -hex 32

    Production Checklist#

    • Use strong, randomly generated keys
    • Never commit .env to version control
    • Run behind reverse proxy (nginx, Traefik)
    • Enable HTTPS/TLS
    • Restrict database network access
    • Set resource limits
    • Enable logging and monitoring
    • Use specific image tags (not latest)
    • Regular security updates
    • Backup database regularly

    Verification#

    Check Service Status#

    # Check if containers are running
    -docker-compose ps
    -
    -# Expected: both services "running" or "healthy"

    Test API Access#

    # Get OpenAPI documentation
    -curl http://localhost:8880/docs
    -
    -# Should return HTML page

    Test Database Connection#

    # Connect to PostgreSQL
    -docker-compose exec postgres psql -U postgres -d dhamps_vdb
    -
    -# Check pgvector extension
    -\dx
    -
    -# Should show vector extension

    Create Test User#

    curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "testuser",
    -    "full_name": "Test User"
    -  }'

    Troubleshooting#

    Container Won’t Start#

    Check logs:

    docker-compose logs dhamps-vdb

    Common issues:

    • Missing SERVICE_ADMINKEY or ENCRYPTION_KEY
    • Database connection failure
    • Port already in use

    Database Connection Errors#

    # Check postgres health
    -docker-compose ps
    -
    -# Check database logs
    -docker-compose logs postgres
    -
    -# Test connection
    -docker-compose exec postgres psql -U postgres -d dhamps_vdb -c "SELECT 1;"

    Can’t Connect to API#

    # Check if container is running
    -docker ps
    -
    -# Check port mapping
    -docker port dhamps-vdb
    -
    -# Test from inside container
    -docker-compose exec dhamps-vdb wget -O- http://localhost:8880/docs
    -
    -# Test from host
    -curl http://localhost:8880/docs

    Permission Issues#

    The container runs as non-root user appuser (UID 1000). If you have permission errors:

    # Check volume permissions
    -docker volume inspect dhamps-vdb_postgres_data

    Reset Everything#

    # Stop and remove everything
    -docker-compose down -v
    -
    -# Remove images
    -docker rmi dhamps-vdb:latest
    -docker rmi pgvector/pgvector:0.7.4-pg16
    -
    -# Start fresh
    -docker-compose up -d --build

    Build Failures#

    If Docker build fails with network errors:

    # Try with host network
    -docker build --network=host -t dhamps-vdb:latest .

    Advanced Configuration#

    Resource Limits#

    Add to docker-compose.yml:

    services:
    -  dhamps-vdb:
    -    deploy:
    -      resources:
    -        limits:
    -          cpus: '2'
    -          memory: 2G
    -        reservations:
    -          cpus: '0.5'
    -          memory: 512M

    Health Checks#

    The Dockerfile includes a health check:

    HEALTHCHECK --interval=30s --timeout=3s \
    -  CMD wget --no-verbose --tries=1 --spider http://localhost:8880/ || exit 1

    View health status:

    docker inspect --format='{{.State.Health.Status}}' dhamps-vdb

    Custom Dockerfile Builds#

    You can customize the build:

    docker build \
    -  --build-arg GO_VERSION=1.24 \
    -  -t dhamps-vdb:custom .

    External Database Setup#

    If using an external PostgreSQL database:

    Prepare Database#

    -- Create database
    -CREATE DATABASE dhamps_vdb;
    -
    --- Create user
    -CREATE USER dhamps_user WITH PASSWORD 'secure_password';
    -
    --- Grant privileges
    -GRANT ALL PRIVILEGES ON DATABASE dhamps_vdb TO dhamps_user;
    -
    --- Connect to database
    -\c dhamps_vdb
    -
    --- Grant schema permissions
    -GRANT ALL ON SCHEMA public TO dhamps_user;
    -
    --- Enable pgvector
    -CREATE EXTENSION IF NOT EXISTS vector;

    Configure dhamps-vdb#

    Update .env:

    SERVICE_DBHOST=external-db.example.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=secure_password
    -SERVICE_DBNAME=dhamps_vdb

    Then run only the dhamps-vdb service or use a standalone container.

    Next Steps#

    After successful deployment:

    1. Configure the service
    2. Create your first user
    3. Set up a project
    4. Review security best practices
    \ No newline at end of file diff --git a/docs/public/getting-started/first-project/index.html b/docs/public/getting-started/first-project/index.html deleted file mode 100644 index 39315c8..0000000 --- a/docs/public/getting-started/first-project/index.html +++ /dev/null @@ -1,172 +0,0 @@ -First Project | dhamps-vdb Documentation - -

    First Project#

    Step-by-step guide to creating your first complete project in dhamps-vdb.

    Overview#

    This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:

    1. Set up authentication
    2. Configure an LLM service
    3. Create a project with metadata validation
    4. Upload document embeddings
    5. Search for similar documents
    6. Share your project with collaborators

    Step 1: Authentication Setup#

    Get Your API Key#

    If you’re an admin, create your first user:

    curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "researcher1",
    -    "name": "Research User",
    -    "email": "researcher@example.com"
    -  }'

    Save the returned vdb_key to a variable:

    export USER_KEY="your-returned-vdb-key"

    Verify Authentication#

    Test your API key:

    curl -X GET http://localhost:8880/v1/users/researcher1 \
    -  -H "Authorization: Bearer $USER_KEY"

    Step 2: Configure LLM Service#

    Option A: Use System Definition#

    List available system definitions:

    curl -X GET http://localhost:8880/v1/llm-services/_system \
    -  -H "Authorization: Bearer $USER_KEY"

    Create an instance from a system definition:

    curl -X PUT http://localhost:8880/v1/llm-services/researcher1/my-embeddings \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "definition_owner": "_system",
    -    "definition_handle": "openai-large",
    -    "description": "My OpenAI embeddings instance",
    -    "api_key_encrypted": "sk-proj-your-openai-api-key"
    -  }'

    Option B: Create Custom Instance#

    Create a standalone instance with custom configuration:

    curl -X PUT http://localhost:8880/v1/llm-services/researcher1/custom-embeddings \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-small",
    -    "dimensions": 1536,
    -    "description": "Custom OpenAI small embeddings",
    -    "api_key_encrypted": "sk-proj-your-api-key"
    -  }'

    Step 3: Create Project with Metadata Schema#

    Define a metadata schema to ensure consistent document metadata:

    curl -X POST http://localhost:8880/v1/projects/researcher1 \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "literature-analysis",
    -    "description": "Literary texts for research analysis",
    -    "instance_owner": "researcher1",
    -    "instance_handle": "my-embeddings",
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\",\"enum\":[\"poetry\",\"prose\",\"drama\"]},\"language\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\",\"year\"]}"
    -  }'

    This schema requires author, title, and year fields, with optional genre and language fields.

    Step 4: Upload Document Embeddings#

    Prepare Your Data#

    Create a file embeddings.json with your document embeddings:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "hamlet-act1-scene1",
    -      "instance_handle": "my-embeddings",
    -      "text": "Who's there? Nay, answer me: stand, and unfold yourself.",
    -      "vector": [0.023, -0.015, 0.087, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "William Shakespeare",
    -        "title": "Hamlet",
    -        "year": 1603,
    -        "genre": "drama",
    -        "language": "English"
    -      }
    -    },
    -    {
    -      "text_id": "paradise-lost-book1-line1",
    -      "instance_handle": "my-embeddings",
    -      "text": "Of Man's first disobedience, and the fruit...",
    -      "vector": [0.045, -0.032, 0.091, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "John Milton",
    -        "title": "Paradise Lost",
    -        "year": 1667,
    -        "genre": "poetry",
    -        "language": "English"
    -      }
    -    }
    -  ]
    -}

    Upload Embeddings#

    curl -X POST http://localhost:8880/v1/embeddings/researcher1/literature-analysis \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d @embeddings.json

    Verify Upload#

    List all embeddings:

    curl -X GET "http://localhost:8880/v1/embeddings/researcher1/literature-analysis?limit=10" \
    -  -H "Authorization: Bearer $USER_KEY"

    Get a specific embedding:

    curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \
    -  -H "Authorization: Bearer $USER_KEY"

    Step 5: Search Similar Documents#

    Find passages similar to Hamlet Act 1:

    curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer $USER_KEY"

    Response:

    {
    -  "user_handle": "researcher1",
    -  "project_handle": "literature-analysis",
    -  "results": [
    -    {
    -      "id": "hamlet-act2-scene1",
    -      "similarity": 0.89
    -    },
    -    {
    -      "id": "macbeth-act1-scene3",
    -      "similarity": 0.82
    -    },
    -    {
    -      "id": "othello-act3-scene3",
    -      "similarity": 0.76
    -    }
    -  ]
    -}

    Search with Metadata Filtering#

    Exclude passages from the same work:

    curl -X GET "http://localhost:8880/v1/similars/researcher1/literature-analysis/hamlet-act1-scene1?count=5&metadata_path=title&metadata_value=Hamlet" \
    -  -H "Authorization: Bearer $USER_KEY"

    This excludes all documents where metadata.title equals “Hamlet”.

    Search with Raw Embeddings#

    Search using a new embedding without storing it:

    curl -X POST "http://localhost:8880/v1/similars/researcher1/literature-analysis?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [0.034, -0.021, 0.092, ...]
    -  }'

    Step 6: Share Your Project#

    Share with Collaborators#

    Grant read-only access to another user:

    curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "colleague1",
    -    "role": "reader"
    -  }'

    Grant edit access:

    curl -X POST http://localhost:8880/v1/projects/researcher1/literature-analysis/share \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "colleague2",
    -    "role": "editor"
    -  }'

    Make Project Public#

    Enable public read access (no authentication required):

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "public_read": true
    -  }'

    Now anyone can read embeddings and search without authentication:

    # No Authorization header needed
    -curl -X GET http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1

    View Shared Users#

    List all users with access to your project:

    curl -X GET http://localhost:8880/v1/projects/researcher1/literature-analysis/shared-with \
    -  -H "Authorization: Bearer $USER_KEY"

    Step 7: Manage Your Project#

    Update Project Description#

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated: Shakespearean and Renaissance literature analysis"
    -  }'

    Update Metadata Schema#

    curl -X PATCH http://localhost:8880/v1/projects/researcher1/literature-analysis \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"},\"genre\":{\"type\":\"string\"},\"language\":{\"type\":\"string\"},\"act\":{\"type\":\"integer\"},\"scene\":{\"type\":\"integer\"}},\"required\":[\"author\",\"title\",\"year\"]}"
    -  }'

    Delete Specific Embeddings#

    curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis/hamlet-act1-scene1 \
    -  -H "Authorization: Bearer $USER_KEY"

    Delete All Embeddings#

    curl -X DELETE http://localhost:8880/v1/embeddings/researcher1/literature-analysis \
    -  -H "Authorization: Bearer $USER_KEY"

    Common Patterns#

    Batch Upload Script#

    #!/bin/bash
    -
    -USER_KEY="your-vdb-key"
    -PROJECT="researcher1/literature-analysis"
    -API_URL="http://localhost:8880"
    -
    -# Process multiple files
    -for file in data/*.json; do
    -  echo "Uploading $file..."
    -  curl -X POST "$API_URL/v1/embeddings/$PROJECT" \
    -    -H "Authorization: Bearer $USER_KEY" \
    -    -H "Content-Type: application/json" \
    -    -d @"$file"
    -done

    Search and Filter Workflow#

    # 1. Find similar documents
    -SIMILAR=$(curl -s -X GET "$API_URL/v1/similars/$PROJECT/doc1?count=20" \
    -  -H "Authorization: Bearer $USER_KEY")
    -
    -# 2. Extract IDs
    -IDS=$(echo $SIMILAR | jq -r '.results[].id')
    -
    -# 3. Retrieve full embeddings for similar documents
    -for id in $IDS; do
    -  curl -X GET "$API_URL/v1/embeddings/$PROJECT/$id" \
    -    -H "Authorization: Bearer $USER_KEY"
    -done

    Troubleshooting#

    Validation Errors#

    If metadata validation fails:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'doc1': year is required"
    -}

    Check your metadata schema and ensure all required fields are present.

    Dimension Mismatches#

    If vector dimensions don’t match:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: expected 3072 dimensions, got 1536"
    -}

    Verify your LLM service configuration and embedding dimensions.

    Authentication Errors#

    If you get 401 Unauthorized:

    • Check your API key is correct
    • Ensure Authorization: Bearer prefix is included
    • Verify the user owns the resource or has been granted access

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/getting-started/index.html b/docs/public/getting-started/index.html deleted file mode 100644 index 6335c13..0000000 --- a/docs/public/getting-started/index.html +++ /dev/null @@ -1,9 +0,0 @@ -Getting Started | dhamps-vdb Documentation - -

    Getting Started with dhamps-vdb#

    This section helps you get dhamps-vdb up and running quickly. Whether you’re using Docker or compiling from source, you’ll find everything you need to start using the vector database API.

    What You’ll Learn#

    • How to install and run dhamps-vdb
    • How to configure the service for your environment
    • Basic usage patterns and workflows
    • Creating your first project and embeddings

    Prerequisites#

    Before you begin, ensure you have:

    • PostgreSQL 11+ with pgvector extension (or use the provided Docker setup)
    • Go 1.21+ (if compiling from source)
    • Docker and Docker Compose (for containerized deployment)
    \ No newline at end of file diff --git a/docs/public/getting-started/index.xml b/docs/public/getting-started/index.xml deleted file mode 100644 index 52823bd..0000000 --- a/docs/public/getting-started/index.xml +++ /dev/null @@ -1,192 +0,0 @@ -Getting Started on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/Recent content in Getting Started on dhamps-vdb DocumentationHugoen-usInstallationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/installation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/<h1 id="installation">Installation<a class="anchor" href="#installation">#</a></h1> -<p>Install dhamps-vdb by compiling from source.</p> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li><strong>Go 1.21 or later</strong></li> -<li><strong>PostgreSQL 11+</strong> with pgvector extension</li> -<li><strong>sqlc</strong> for code generation</li> -</ul> -<h2 id="quick-install">Quick Install<a class="anchor" href="#quick-install">#</a></h2> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies and generate code</span> -</span></span><span style="display:flex;"><span>go get ./... -</span></span><span style="display:flex;"><span>sqlc generate --no-remote -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build the binary</span> -</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go</span></span></code></pre></div><h2 id="detailed-steps">Detailed Steps<a class="anchor" href="#detailed-steps">#</a></h2> -<h3 id="1-install-dependencies">1. Install Dependencies<a class="anchor" href="#1-install-dependencies">#</a></h3> -<p>Download all Go module dependencies:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get ./...</span></span></code></pre></div><h3 id="2-generate-database-code">2. Generate Database Code<a class="anchor" href="#2-generate-database-code">#</a></h3> -<p>Generate type-safe database queries using sqlc:</p>Configurationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/<h1 id="configuration">Configuration<a class="anchor" href="#configuration">#</a></h1> -<p>Configure dhamps-vdb using environment variables or command-line options.</p> -<h2 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h2> -<p>All configuration can be set via environment variables. Use a <code>.env</code> file to keep sensitive information secure.</p> -<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_DEBUG</code></td> - <td>Enable debug logging</td> - <td><code>true</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_HOST</code></td> - <td>Hostname to listen on</td> - <td><code>localhost</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_PORT</code></td> - <td>Port to listen on</td> - <td><code>8880</code></td> - <td>No</td> - </tr> - </tbody> -</table> -<h3 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_DBHOST</code></td> - <td>Database hostname</td> - <td><code>localhost</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBPORT</code></td> - <td>Database port</td> - <td><code>5432</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_DBUSER</code></td> - <td>Database username</td> - <td><code>postgres</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBPASSWORD</code></td> - <td>Database password</td> - <td><code>password</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBNAME</code></td> - <td>Database name</td> - <td><code>postgres</code></td> - <td>Yes</td> - </tr> - </tbody> -</table> -<h3 id="security-configuration">Security Configuration<a class="anchor" href="#security-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_ADMINKEY</code></td> - <td>Admin API key for administrative operations</td> - <td>-</td> - <td>Yes</td> - </tr> - <tr> - <td><code>ENCRYPTION_KEY</code></td> - <td>Encryption key for API keys (32+ characters)</td> - <td>-</td> - <td>Yes</td> - </tr> - </tbody> -</table> -<h2 id="configuration-file">Configuration File<a class="anchor" href="#configuration-file">#</a></h2> -<p>Create a <code>.env</code> file in the project root:</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/getting-started/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> -<p>Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.</p> -<h2 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h2> -<p>The fastest way to get dhamps-vdb running with Docker:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Run automated setup (generates secure keys)</span> -</span></span><span style="display:flex;"><span>./docker-setup.sh -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start services with docker-compose</span> -</span></span><span style="display:flex;"><span>docker-compose up -d -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Check logs</span> -</span></span><span style="display:flex;"><span>docker-compose logs -f dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Access the API</span> -</span></span><span style="display:flex;"><span>curl http://localhost:8880/docs</span></span></code></pre></div><h2 id="whats-included">What&rsquo;s Included<a class="anchor" href="#whats-included">#</a></h2> -<p>The Docker Compose setup includes:</p>Quick Starthttps://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/<h1 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h1> -<p>Complete walkthrough from installation to searching similar documents using curl.</p> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li>dhamps-vdb installed and running</li> -<li>Admin API key configured</li> -<li>PostgreSQL with pgvector ready</li> -</ul> -<h2 id="1-create-a-user">1. Create a User<a class="anchor" href="#1-create-a-user">#</a></h2> -<p>Create a new user with the admin API key:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;alice&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Alice Smith&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;alice@example.com&#34; -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Smith&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vdb_key&#34;</span>: <span style="color:#e6db74">&#34;024v2013621509245f2e24...&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Save the <code>vdb_key</code></strong> - it cannot be recovered later.</p>First Projecthttps://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/<h1 id="first-project">First Project<a class="anchor" href="#first-project">#</a></h1> -<p>Step-by-step guide to creating your first complete project in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:</p> -<ol> -<li>Set up authentication</li> -<li>Configure an LLM service</li> -<li>Create a project with metadata validation</li> -<li>Upload document embeddings</li> -<li>Search for similar documents</li> -<li>Share your project with collaborators</li> -</ol> -<h2 id="step-1-authentication-setup">Step 1: Authentication Setup<a class="anchor" href="#step-1-authentication-setup">#</a></h2> -<h3 id="get-your-api-key">Get Your API Key<a class="anchor" href="#get-your-api-key">#</a></h3> -<p>If you&rsquo;re an admin, create your first user:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;researcher1&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Research User&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;researcher@example.com&#34; -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p>Save the returned <code>vdb_key</code> to a variable:</p> \ No newline at end of file diff --git a/docs/public/getting-started/installation/index.html b/docs/public/getting-started/installation/index.html deleted file mode 100644 index 84ab048..0000000 --- a/docs/public/getting-started/installation/index.html +++ /dev/null @@ -1,21 +0,0 @@ -Installation | dhamps-vdb Documentation - -

    Installation#

    Install dhamps-vdb by compiling from source.

    Prerequisites#

    • Go 1.21 or later
    • PostgreSQL 11+ with pgvector extension
    • sqlc for code generation

    Quick Install#

    # Clone the repository
    -git clone https://github.com/mpilhlt/dhamps-vdb.git
    -cd dhamps-vdb
    -
    -# Install dependencies and generate code
    -go get ./...
    -sqlc generate --no-remote
    -
    -# Build the binary
    -go build -o build/dhamps-vdb main.go

    Detailed Steps#

    1. Install Dependencies#

    Download all Go module dependencies:

    go get ./...

    2. Generate Database Code#

    Generate type-safe database queries using sqlc:

    sqlc generate --no-remote

    This creates Go code from SQL queries in internal/database/queries/.

    3. Build the Application#

    Compile the application:

    go build -o build/dhamps-vdb main.go

    The binary will be created at build/dhamps-vdb.

    Running Without Building#

    You can run the application directly without building a binary:

    go run main.go

    This is useful during development but slower than running a pre-built binary.

    Verify Installation#

    Check that the binary was created successfully:

    ./build/dhamps-vdb --help

    You should see the available command-line options.

    Next Steps#

    After installation, you need to:

    1. Set up the database
    2. Configure environment variables
    3. Run the service

    System Requirements#

    • Memory: Minimum 512MB RAM (2GB+ recommended for production)
    • Disk: Minimal (< 50MB for binary, database size varies)
    • CPU: Any modern CPU (multi-core recommended for concurrent requests)

    Troubleshooting#

    sqlc Command Not Found#

    Install sqlc:

    go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest

    Make sure $GOPATH/bin is in your PATH.

    Build Errors#

    Ensure you’re using Go 1.21 or later:

    go version

    Clean the build cache if you encounter issues:

    go clean -cache
    -go build -o build/dhamps-vdb main.go

    Missing Dependencies#

    Force update all dependencies:

    go mod download
    -go get -u ./...
    \ No newline at end of file diff --git a/docs/public/getting-started/quick-start/index.html b/docs/public/getting-started/quick-start/index.html deleted file mode 100644 index f9f28ce..0000000 --- a/docs/public/getting-started/quick-start/index.html +++ /dev/null @@ -1,160 +0,0 @@ -Quick Start | dhamps-vdb Documentation - -

    Quick Start#

    Complete walkthrough from installation to searching similar documents using curl.

    Prerequisites#

    • dhamps-vdb installed and running
    • Admin API key configured
    • PostgreSQL with pgvector ready

    1. Create a User#

    Create a new user with the admin API key:

    curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "user_handle": "alice",
    -    "name": "Alice Smith",
    -    "email": "alice@example.com"
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "name": "Alice Smith",
    -  "email": "alice@example.com",
    -  "vdb_key": "024v2013621509245f2e24...",
    -  "created_at": "2024-01-15T10:30:00Z"
    -}

    Save the vdb_key - it cannot be recovered later.

    2. Create an LLM Service Instance#

    Create an LLM service configuration:

    curl -X PUT http://localhost:8880/v1/llm-services/alice/my-openai \
    -  -H "Authorization: Bearer alice_vdb_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "description": "OpenAI large embeddings",
    -    "api_key_encrypted": "sk-proj-your-openai-key"
    -  }'

    Response:

    {
    -  "instance_id": 1,
    -  "instance_handle": "my-openai",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072
    -}

    3. Create a Project#

    Create a project to organize your embeddings:

    curl -X POST http://localhost:8880/v1/projects/alice \
    -  -H "Authorization: Bearer alice_vdb_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Research document embeddings",
    -    "instance_owner": "alice",
    -    "instance_handle": "my-openai"
    -  }'

    Response:

    {
    -  "project_id": 1,
    -  "project_handle": "research-docs",
    -  "owner": "alice",
    -  "description": "Research document embeddings",
    -  "instance_id": 1,
    -  "created_at": "2024-01-15T10:35:00Z"
    -}

    4. Upload Embeddings#

    Upload document embeddings to your project:

    curl -X POST http://localhost:8880/v1/embeddings/alice/research-docs \
    -  -H "Authorization: Bearer alice_vdb_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {
    -        "text_id": "doc1",
    -        "instance_handle": "my-openai",
    -        "text": "Introduction to machine learning",
    -        "vector": [0.1, 0.2, 0.3, ..., 0.5],
    -        "vector_dim": 3072,
    -        "metadata": {
    -          "title": "ML Intro",
    -          "author": "Alice",
    -          "year": 2024
    -        }
    -      },
    -      {
    -        "text_id": "doc2",
    -        "instance_handle": "my-openai",
    -        "text": "Deep learning fundamentals",
    -        "vector": [0.15, 0.25, 0.35, ..., 0.55],
    -        "vector_dim": 3072,
    -        "metadata": {
    -          "title": "DL Fundamentals",
    -          "author": "Bob",
    -          "year": 2024
    -        }
    -      }
    -    ]
    -  }'

    Response:

    {
    -  "message": "2 embeddings uploaded successfully"
    -}

    5. Search for Similar Documents#

    Option A: Search Using Stored Document#

    Find documents similar to an already-stored document:

    curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_vdb_key"

    Response:

    {
    -  "user_handle": "alice",
    -  "project_handle": "research-docs",
    -  "results": [
    -    {
    -      "id": "doc2",
    -      "similarity": 0.92
    -    },
    -    {
    -      "id": "doc5",
    -      "similarity": 0.85
    -    }
    -  ]
    -}

    Option B: Search Using Raw Embeddings#

    Search without storing the query embedding:

    curl -X POST "http://localhost:8880/v1/similars/alice/research-docs?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_vdb_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [0.12, 0.22, 0.32, ..., 0.52]
    -  }'

    6. Filter by Metadata#

    Exclude documents from a specific author when searching:

    curl -X GET "http://localhost:8880/v1/similars/alice/research-docs/doc1?count=5&metadata_path=author&metadata_value=Alice" \
    -  -H "Authorization: Bearer alice_vdb_key"

    This excludes all documents where metadata.author equals “Alice”.

    7. Retrieve Embeddings#

    Get all embeddings in your project:

    curl -X GET "http://localhost:8880/v1/embeddings/alice/research-docs?limit=10&offset=0" \
    -  -H "Authorization: Bearer alice_vdb_key"

    Get a specific embedding:

    curl -X GET http://localhost:8880/v1/embeddings/alice/research-docs/doc1 \
    -  -H "Authorization: Bearer alice_vdb_key"

    Complete Workflow Example#

    Here’s a complete script to get started:

    #!/bin/bash
    -
    -# Configuration
    -API_URL="http://localhost:8880"
    -ADMIN_KEY="your-admin-key"
    -
    -# 1. Create user
    -USER_RESPONSE=$(curl -s -X POST "$API_URL/v1/users" \
    -  -H "Authorization: Bearer $ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle":"alice","name":"Alice Smith","email":"alice@example.com"}')
    -
    -USER_KEY=$(echo $USER_RESPONSE | jq -r '.vdb_key')
    -echo "User created with key: $USER_KEY"
    -
    -# 2. Create LLM service instance
    -curl -X PUT "$API_URL/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "api_key_encrypted": "sk-your-key"
    -  }'
    -
    -# 3. Create project
    -curl -X POST "$API_URL/v1/projects/alice" \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-docs",
    -    "description": "Research documents",
    -    "instance_owner": "alice",
    -    "instance_handle": "my-openai"
    -  }'
    -
    -# 4. Upload embeddings
    -curl -X POST "$API_URL/v1/embeddings/alice/research-docs" \
    -  -H "Authorization: Bearer $USER_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d @embeddings.json
    -
    -# 5. Search similar
    -curl -X GET "$API_URL/v1/similars/alice/research-docs/doc1?count=5" \
    -  -H "Authorization: Bearer $USER_KEY"
    -
    -echo "Setup complete!"

    API Documentation#

    For complete API documentation, visit:

    curl http://localhost:8880/docs

    Or open http://localhost:8880/docs in your browser.

    Next Steps#

    \ No newline at end of file diff --git a/docs/public/guides/batch-operations/index.html b/docs/public/guides/batch-operations/index.html deleted file mode 100644 index d58300d..0000000 --- a/docs/public/guides/batch-operations/index.html +++ /dev/null @@ -1,508 +0,0 @@ -Batch Operations Guide | dhamps-vdb Documentation - -

    Batch Operations Guide#

    This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.

    Overview#

    For production workloads and large datasets, efficient batch operations are essential. This guide covers:

    • Uploading multiple embeddings in a single request
    • Pagination strategies for large result sets
    • Best practices for performance and reliability
    • Error handling in batch operations

    Batch Upload Basics#

    Single Request with Multiple Embeddings#

    Upload multiple embeddings in one API call using the embeddings array:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {
    -        "text_id": "doc001",
    -        "instance_handle": "openai-large",
    -        "vector": [0.1, 0.2, 0.3, ...],
    -        "vector_dim": 3072,
    -        "text": "First document content",
    -        "metadata": {"category": "science"}
    -      },
    -      {
    -        "text_id": "doc002",
    -        "instance_handle": "openai-large",
    -        "vector": [0.11, 0.21, 0.31, ...],
    -        "vector_dim": 3072,
    -        "text": "Second document content",
    -        "metadata": {"category": "history"}
    -      },
    -      {
    -        "text_id": "doc003",
    -        "instance_handle": "openai-large",
    -        "vector": [0.12, 0.22, 0.32, ...],
    -        "vector_dim": 3072,
    -        "text": "Third document content",
    -        "metadata": {"category": "literature"}
    -      }
    -    ]
    -  }'

    Response:

    {
    -  "message": "Embeddings uploaded successfully",
    -  "count": 3
    -}

    Optimal Batch Sizes#

    Based on typical embedding dimensions and network constraints:

    Embedding DimensionsRecommended Batch SizeMaximum Batch Size
    384 (small models)500-10002000
    768 (BERT-base)300-5001000
    1536 (OpenAI small)100-300500
    3072 (OpenAI large)50-100200

    Factors to consider:

    • Network bandwidth and latency
    • API gateway timeout limits
    • Database transaction size
    • Memory constraints
    • Client-side serialization limits

    Finding Your Optimal Batch Size#

    Test different batch sizes to find the sweet spot:

    import time
    -import requests
    -
    -def test_batch_size(embeddings, batch_size):
    -    """Test upload performance with given batch size"""
    -    start_time = time.time()
    -    
    -    for i in range(0, len(embeddings), batch_size):
    -        batch = embeddings[i:i+batch_size]
    -        response = requests.post(
    -            "https://api.example.com/v1/embeddings/alice/my-project",
    -            headers={
    -                "Authorization": "Bearer alice_api_key",
    -                "Content-Type": "application/json"
    -            },
    -            json={"embeddings": batch}
    -        )
    -        response.raise_for_status()
    -    
    -    elapsed = time.time() - start_time
    -    throughput = len(embeddings) / elapsed
    -    print(f"Batch size {batch_size}: {throughput:.1f} embeddings/sec")
    -
    -# Test different batch sizes
    -for size in [50, 100, 200, 500]:
    -    test_batch_size(my_embeddings, size)

    Pagination for Large Datasets#

    Retrieving All Embeddings with Pagination#

    Use limit and offset parameters to paginate through large result sets:

    # Get first page (embeddings 0-99)
    -curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=0" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Get second page (embeddings 100-199)
    -curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=100" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Get third page (embeddings 200-299)
    -curl -X GET "https://api.example.com/v1/embeddings/alice/my-project?limit=100&offset=200" \
    -  -H "Authorization: Bearer alice_api_key"

    Pagination Best Practices#

    Default Values:

    • limit: 10 (if not specified)
    • offset: 0 (if not specified)
    • Maximum limit: 200

    Example: Download Entire Project

    import requests
    -
    -def download_all_embeddings(owner, project):
    -    """Download all embeddings from a project"""
    -    all_embeddings = []
    -    offset = 0
    -    limit = 100
    -    
    -    while True:
    -        response = requests.get(
    -            f"https://api.example.com/v1/embeddings/{owner}/{project}",
    -            headers={"Authorization": "Bearer api_key"},
    -            params={"limit": limit, "offset": offset}
    -        )
    -        response.raise_for_status()
    -        
    -        batch = response.json()['embeddings']
    -        if not batch:
    -            break  # No more results
    -        
    -        all_embeddings.extend(batch)
    -        offset += len(batch)
    -        
    -        print(f"Downloaded {len(all_embeddings)} embeddings...")
    -    
    -    return all_embeddings
    -
    -# Usage
    -embeddings = download_all_embeddings("alice", "my-project")
    -print(f"Total: {len(embeddings)} embeddings")

    Efficient Batch Upload Strategies#

    Strategy 1: Simple Sequential Upload#

    Good for small to medium datasets (< 10,000 embeddings):

    def upload_sequential(embeddings, batch_size=100):
    -    """Upload embeddings sequentially in batches"""
    -    for i in range(0, len(embeddings), batch_size):
    -        batch = embeddings[i:i+batch_size]
    -        response = requests.post(
    -            "https://api.example.com/v1/embeddings/alice/my-project",
    -            headers={
    -                "Authorization": "Bearer alice_api_key",
    -                "Content-Type": "application/json"
    -            },
    -            json={"embeddings": batch}
    -        )
    -        response.raise_for_status()
    -        print(f"Uploaded batch {i//batch_size + 1}, total: {i+len(batch)}")

    Strategy 2: Parallel Upload with Threading#

    Good for larger datasets with stable network:

    import concurrent.futures
    -import requests
    -
    -def upload_batch(batch, batch_num):
    -    """Upload a single batch"""
    -    try:
    -        response = requests.post(
    -            "https://api.example.com/v1/embeddings/alice/my-project",
    -            headers={
    -                "Authorization": "Bearer alice_api_key",
    -                "Content-Type": "application/json"
    -            },
    -            json={"embeddings": batch},
    -            timeout=60
    -        )
    -        response.raise_for_status()
    -        return batch_num, True, None
    -    except Exception as e:
    -        return batch_num, False, str(e)
    -
    -def upload_parallel(embeddings, batch_size=100, max_workers=4):
    -    """Upload embeddings in parallel"""
    -    batches = [
    -        embeddings[i:i+batch_size]
    -        for i in range(0, len(embeddings), batch_size)
    -    ]
    -    
    -    failed = []
    -    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
    -        futures = {
    -            executor.submit(upload_batch, batch, i): i
    -            for i, batch in enumerate(batches)
    -        }
    -        
    -        for future in concurrent.futures.as_completed(futures):
    -            batch_num, success, error = future.result()
    -            if success:
    -                print(f"✓ Batch {batch_num+1}/{len(batches)} uploaded")
    -            else:
    -                print(f"✗ Batch {batch_num+1} failed: {error}")
    -                failed.append((batch_num, batches[batch_num]))
    -    
    -    return failed
    -
    -# Usage
    -failed_batches = upload_parallel(my_embeddings, batch_size=100, max_workers=4)
    -if failed_batches:
    -    print(f"Failed batches: {len(failed_batches)}")

    Strategy 3: Retry with Exponential Backoff#

    Robust strategy for unreliable networks:

    import time
    -import random
    -
    -def upload_with_retry(batch, max_retries=3):
    -    """Upload batch with exponential backoff retry"""
    -    for attempt in range(max_retries):
    -        try:
    -            response = requests.post(
    -                "https://api.example.com/v1/embeddings/alice/my-project",
    -                headers={
    -                    "Authorization": "Bearer alice_api_key",
    -                    "Content-Type": "application/json"
    -                },
    -                json={"embeddings": batch},
    -                timeout=60
    -            )
    -            response.raise_for_status()
    -            return True
    -        except requests.exceptions.RequestException as e:
    -            if attempt < max_retries - 1:
    -                wait = (2 ** attempt) + random.uniform(0, 1)
    -                print(f"Retry attempt {attempt+1} after {wait:.1f}s: {e}")
    -                time.sleep(wait)
    -            else:
    -                print(f"Failed after {max_retries} attempts: {e}")
    -                return False
    -
    -def upload_robust(embeddings, batch_size=100):
    -    """Upload with robust error handling"""
    -    failed = []
    -    for i in range(0, len(embeddings), batch_size):
    -        batch = embeddings[i:i+batch_size]
    -        if not upload_with_retry(batch):
    -            failed.append((i, batch))
    -        else:
    -            print(f"✓ Uploaded {i+batch_size}/{len(embeddings)}")
    -    
    -    return failed

    Progress Tracking and Resumability#

    Checkpoint-Based Upload#

    For very large datasets, implement checkpointing to resume after failures:

    import json
    -import os
    -
    -class CheckpointUploader:
    -    def __init__(self, checkpoint_file="upload_progress.json"):
    -        self.checkpoint_file = checkpoint_file
    -        self.progress = self.load_progress()
    -    
    -    def load_progress(self):
    -        """Load upload progress from checkpoint file"""
    -        if os.path.exists(self.checkpoint_file):
    -            with open(self.checkpoint_file, 'r') as f:
    -                return json.load(f)
    -        return {"uploaded_count": 0, "failed_batches": []}
    -    
    -    def save_progress(self):
    -        """Save current progress"""
    -        with open(self.checkpoint_file, 'w') as f:
    -            json.dump(self.progress, f)
    -    
    -    def upload(self, embeddings, batch_size=100):
    -        """Upload with checkpointing"""
    -        start_idx = self.progress["uploaded_count"]
    -        
    -        for i in range(start_idx, len(embeddings), batch_size):
    -            batch = embeddings[i:i+batch_size]
    -            
    -            try:
    -                response = requests.post(
    -                    "https://api.example.com/v1/embeddings/alice/my-project",
    -                    headers={
    -                        "Authorization": "Bearer alice_api_key",
    -                        "Content-Type": "application/json"
    -                    },
    -                    json={"embeddings": batch},
    -                    timeout=60
    -                )
    -                response.raise_for_status()
    -                
    -                self.progress["uploaded_count"] = i + len(batch)
    -                self.save_progress()
    -                print(f"✓ Progress: {self.progress['uploaded_count']}/{len(embeddings)}")
    -                
    -            except Exception as e:
    -                print(f"✗ Failed at index {i}: {e}")
    -                self.progress["failed_batches"].append(i)
    -                self.save_progress()
    -                raise
    -
    -# Usage
    -uploader = CheckpointUploader()
    -try:
    -    uploader.upload(my_embeddings, batch_size=100)
    -    print("Upload complete!")
    -except:
    -    print("Upload interrupted. Run again to resume.")

    Error Handling#

    Validation Errors#

    If any embedding in a batch fails validation, the entire batch is rejected:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {
    -        "text_id": "doc001",
    -        "instance_handle": "openai-large",
    -        "vector": [0.1, 0.2, 0.3],
    -        "vector_dim": 3072,
    -        "metadata": {"author": "Alice"}
    -      },
    -      {
    -        "text_id": "doc002",
    -        "instance_handle": "openai-large",
    -        "vector": [0.1, 0.2],
    -        "vector_dim": 3072,
    -        "metadata": {"author": "Bob"}
    -      }
    -    ]
    -  }'

    Error Response:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector length mismatch for text_id 'doc002': actual vector has 2 elements but vector_dim declares 3072"
    -}

    Solution: Validate all embeddings before batching, or handle errors and retry failed items.

    Pre-Upload Validation#

    def validate_embeddings(embeddings, expected_dim):
    -    """Validate embeddings before upload"""
    -    errors = []
    -    
    -    for i, emb in enumerate(embeddings):
    -        # Check vector length
    -        if len(emb['vector']) != expected_dim:
    -            errors.append(f"Index {i} (text_id: {emb['text_id']}): "
    -                        f"vector length {len(emb['vector'])} != {expected_dim}")
    -        
    -        # Check declared dimension
    -        if emb.get('vector_dim') != expected_dim:
    -            errors.append(f"Index {i} (text_id: {emb['text_id']}): "
    -                        f"vector_dim {emb.get('vector_dim')} != {expected_dim}")
    -        
    -        # Check required fields
    -        if not emb.get('text_id'):
    -            errors.append(f"Index {i}: missing text_id")
    -        
    -        if not emb.get('instance_handle'):
    -            errors.append(f"Index {i}: missing instance_handle")
    -    
    -    return errors
    -
    -# Usage
    -errors = validate_embeddings(my_embeddings, 3072)
    -if errors:
    -    print("Validation errors:")
    -    for error in errors:
    -        print(f"  - {error}")
    -else:
    -    print("All embeddings valid, proceeding with upload...")

    Performance Optimization Tips#

    1. Minimize Payload Size#

    Exclude unnecessary fields:

    # Include text only if needed for retrieval
    -embeddings_with_text = [
    -    {
    -        "text_id": doc_id,
    -        "instance_handle": "openai-large",
    -        "vector": vector,
    -        "vector_dim": 3072,
    -        "text": text,  # Include if needed
    -        "metadata": metadata
    -    }
    -    for doc_id, vector, text, metadata in documents
    -]
    -
    -# Exclude text if not needed (smaller payload)
    -embeddings_without_text = [
    -    {
    -        "text_id": doc_id,
    -        "instance_handle": "openai-large",
    -        "vector": vector,
    -        "vector_dim": 3072,
    -        "metadata": metadata
    -    }
    -    for doc_id, vector, metadata in documents
    -]

    2. Compress Requests#

    Use gzip compression for large payloads:

    import gzip
    -import json
    -
    -def upload_compressed(embeddings):
    -    """Upload with gzip compression"""
    -    payload = json.dumps({"embeddings": embeddings})
    -    compressed = gzip.compress(payload.encode('utf-8'))
    -    
    -    response = requests.post(
    -        "https://api.example.com/v1/embeddings/alice/my-project",
    -        headers={
    -            "Authorization": "Bearer alice_api_key",
    -            "Content-Type": "application/json",
    -            "Content-Encoding": "gzip"
    -        },
    -        data=compressed
    -    )
    -    return response

    3. Use Connection Pooling#

    Reuse HTTP connections for multiple requests:

    session = requests.Session()
    -session.headers.update({
    -    "Authorization": "Bearer alice_api_key",
    -    "Content-Type": "application/json"
    -})
    -
    -for batch in batches:
    -    response = session.post(
    -        "https://api.example.com/v1/embeddings/alice/my-project",
    -        json={"embeddings": batch}
    -    )
    -    response.raise_for_status()

    4. Monitor Upload Rate#

    Track and display upload progress:

    import time
    -
    -class ProgressTracker:
    -    def __init__(self, total):
    -        self.total = total
    -        self.uploaded = 0
    -        self.start_time = time.time()
    -    
    -    def update(self, count):
    -        self.uploaded += count
    -        elapsed = time.time() - self.start_time
    -        rate = self.uploaded / elapsed if elapsed > 0 else 0
    -        percent = (self.uploaded / self.total) * 100
    -        eta = (self.total - self.uploaded) / rate if rate > 0 else 0
    -        
    -        print(f"\rProgress: {self.uploaded}/{self.total} ({percent:.1f}%) "
    -              f"Rate: {rate:.1f} emb/s ETA: {eta:.0f}s", end="")
    -
    -# Usage
    -tracker = ProgressTracker(len(all_embeddings))
    -for batch in batches:
    -    upload_batch(batch)
    -    tracker.update(len(batch))
    -print()  # New line after completion

    Complete Example: Production-Grade Uploader#

    import requests
    -import time
    -import json
    -import logging
    -from concurrent.futures import ThreadPoolExecutor, as_completed
    -from typing import List, Dict, Tuple
    -
    -class ProductionUploader:
    -    def __init__(self, api_base: str, api_key: str, 
    -                 owner: str, project: str):
    -        self.api_base = api_base
    -        self.api_key = api_key
    -        self.owner = owner
    -        self.project = project
    -        self.session = requests.Session()
    -        self.session.headers.update({
    -            "Authorization": f"Bearer {api_key}",
    -            "Content-Type": "application/json"
    -        })
    -        
    -        logging.basicConfig(level=logging.INFO)
    -        self.logger = logging.getLogger(__name__)
    -    
    -    def upload_batch(self, batch: List[Dict], batch_num: int, 
    -                    max_retries: int = 3) -> Tuple[int, bool, str]:
    -        """Upload a single batch with retry logic"""
    -        url = f"{self.api_base}/v1/embeddings/{self.owner}/{self.project}"
    -        
    -        for attempt in range(max_retries):
    -            try:
    -                response = self.session.post(
    -                    url,
    -                    json={"embeddings": batch},
    -                    timeout=60
    -                )
    -                response.raise_for_status()
    -                return batch_num, True, ""
    -            except Exception as e:
    -                if attempt < max_retries - 1:
    -                    wait = 2 ** attempt
    -                    self.logger.warning(
    -                        f"Batch {batch_num} attempt {attempt+1} failed: {e}. "
    -                        f"Retrying in {wait}s..."
    -                    )
    -                    time.sleep(wait)
    -                else:
    -                    return batch_num, False, str(e)
    -    
    -    def upload(self, embeddings: List[Dict], batch_size: int = 100,
    -               max_workers: int = 4) -> Dict:
    -        """Upload embeddings with parallel processing and progress tracking"""
    -        batches = [
    -            embeddings[i:i+batch_size]
    -            for i in range(0, len(embeddings), batch_size)
    -        ]
    -        
    -        results = {
    -            "total": len(embeddings),
    -            "uploaded": 0,
    -            "failed": [],
    -            "start_time": time.time()
    -        }
    -        
    -        self.logger.info(f"Uploading {len(embeddings)} embeddings in "
    -                        f"{len(batches)} batches...")
    -        
    -        with ThreadPoolExecutor(max_workers=max_workers) as executor:
    -            futures = {
    -                executor.submit(self.upload_batch, batch, i): i
    -                for i, batch in enumerate(batches)
    -            }
    -            
    -            for future in as_completed(futures):
    -                batch_num, success, error = future.result()
    -                
    -                if success:
    -                    results["uploaded"] += len(batches[batch_num])
    -                    percent = (results["uploaded"] / results["total"]) * 100
    -                    self.logger.info(
    -                        f"✓ Batch {batch_num+1}/{len(batches)} "
    -                        f"({percent:.1f}% complete)"
    -                    )
    -                else:
    -                    results["failed"].append({
    -                        "batch_num": batch_num,
    -                        "error": error,
    -                        "embeddings": batches[batch_num]
    -                    })
    -                    self.logger.error(f"✗ Batch {batch_num+1} failed: {error}")
    -        
    -        results["elapsed"] = time.time() - results["start_time"]
    -        results["rate"] = results["uploaded"] / results["elapsed"]
    -        
    -        self.logger.info(
    -            f"\nUpload complete: {results['uploaded']}/{results['total']} "
    -            f"in {results['elapsed']:.1f}s ({results['rate']:.1f} emb/s)"
    -        )
    -        
    -        if results["failed"]:
    -            self.logger.warning(f"Failed batches: {len(results['failed'])}")
    -        
    -        return results
    -
    -# Usage
    -uploader = ProductionUploader(
    -    api_base="https://api.example.com",
    -    api_key="alice_api_key",
    -    owner="alice",
    -    project="my-project"
    -)
    -
    -results = uploader.upload(
    -    embeddings=my_embeddings,
    -    batch_size=100,
    -    max_workers=4
    -)
    -
    -# Save failed batches for retry
    -if results["failed"]:
    -    with open("failed_batches.json", "w") as f:
    -        json.dump(results["failed"], f)

    Best Practices Summary#

    1. Batch Size: Test to find optimal size (typically 50-500 depending on dimensions)
    2. Parallelism: Use 2-8 parallel workers for large uploads
    3. Retry Logic: Implement exponential backoff for network errors
    4. Validation: Pre-validate embeddings before upload
    5. Progress Tracking: Monitor upload rate and ETA
    6. Checkpointing: Save progress for resumable uploads
    7. Error Logging: Log all errors with sufficient context
    8. Connection Reuse: Use session objects for connection pooling
    9. Compression: Use gzip for large payloads
    10. Testing: Test with small batches before full upload

    Troubleshooting#

    Timeout Errors#

    Problem: Requests timing out with large batches

    Solution: Reduce batch size or increase timeout value

    Memory Issues#

    Problem: Out of memory when processing large datasets

    Solution: Process embeddings in streaming fashion, don’t load all into memory

    Rate Limiting#

    Problem: Getting rate limited by API

    Solution: Reduce parallelism (max_workers) or add delays between requests

    \ No newline at end of file diff --git a/docs/public/guides/index.html b/docs/public/guides/index.html deleted file mode 100644 index ea0bd44..0000000 --- a/docs/public/guides/index.html +++ /dev/null @@ -1,10 +0,0 @@ -Guides | dhamps-vdb Documentation - -

    User Guides#

    Step-by-step guides for common tasks and workflows with dhamps-vdb.

    Available Guides#

    This section contains practical guides for using dhamps-vdb in real-world scenarios:

    • RAG Workflows - Implement Retrieval Augmented Generation
    • Project Sharing - Collaborate with other users
    • Public Projects - Enable unauthenticated access
    • Ownership Transfer - Move projects between users
    • Metadata Validation - Ensure data quality with schemas
    • Metadata Filtering - Exclude documents from similarity search
    • Batch Operations - Work with multiple embeddings efficiently
    • Instance Management - Configure LLM service instances

    These guides complement the API reference by providing context and best practices for common use cases.

    \ No newline at end of file diff --git a/docs/public/guides/index.xml b/docs/public/guides/index.xml deleted file mode 100644 index fe96114..0000000 --- a/docs/public/guides/index.xml +++ /dev/null @@ -1,94 +0,0 @@ -Guides on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/guides/Recent content in Guides on dhamps-vdb DocumentationHugoen-usRAG Workflow Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/<h1 id="complete-rag-workflow-guide">Complete RAG Workflow Guide<a class="anchor" href="#complete-rag-workflow-guide">#</a></h1> -<p>This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>A typical RAG workflow involves:</p> -<ol> -<li>Generate embeddings from your text content (using an external LLM service)</li> -<li>Upload embeddings to dhamps-vdb</li> -<li>Search for similar documents based on a query</li> -<li>Retrieve the relevant context</li> -<li>Use the context with an LLM to generate responses</li> -</ol> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li>Access to dhamps-vdb API with a valid API key</li> -<li>An external LLM service for generating embeddings (e.g., OpenAI, Cohere)</li> -<li>Text content you want to process</li> -</ul> -<h2 id="step-1-generate-embeddings-externally">Step 1: Generate Embeddings Externally<a class="anchor" href="#step-1-generate-embeddings-externally">#</a></h2> -<p>First, use your chosen LLM service to generate embeddings for your text content. Here&rsquo;s an example using OpenAI&rsquo;s API:</p>Project Sharing Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/<h1 id="project-sharing-guide">Project Sharing Guide<a class="anchor" href="#project-sharing-guide">#</a></h1> -<p>This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Project sharing allows you to grant other users access to your projects with different permission levels:</p> -<ul> -<li><strong>reader</strong>: Read-only access to embeddings and similar documents</li> -<li><strong>editor</strong>: Read and write access to embeddings (can add/modify/delete embeddings)</li> -</ul> -<p>Only the project owner can manage sharing settings and delete the project.</p> -<h2 id="sharing-during-project-creation">Sharing During Project Creation<a class="anchor" href="#sharing-during-project-creation">#</a></h2> -<p>You can specify users to share with when creating a new project using the <code>shared_with</code> field:</p>Public Projects Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/public-projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/<h1 id="public-projects-guide">Public Projects Guide<a class="anchor" href="#public-projects-guide">#</a></h1> -<p>This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Projects can be configured to allow unauthenticated (public) read access by setting the <code>public_read</code> field to <code>true</code>. This is useful for:</p> -<ul> -<li>Open datasets and research data</li> -<li>Public APIs and services</li> -<li>Shared knowledge bases</li> -<li>Educational resources</li> -</ul> -<p><strong>Important:</strong> Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.</p>Ownership Transfer Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/<h1 id="ownership-transfer-guide">Ownership Transfer Guide<a class="anchor" href="#ownership-transfer-guide">#</a></h1> -<p>This guide explains how to transfer project ownership between users in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:</p> -<ul> -<li>A project maintainer is leaving and wants to hand over control</li> -<li>Organizational changes require reassigning project ownership</li> -<li>Consolidating projects under a different user account</li> -<li>Transferring stewardship of research data to a new PI</li> -</ul> -<h2 id="important-constraints">Important Constraints<a class="anchor" href="#important-constraints">#</a></h2> -<p>Before transferring ownership, understand these constraints:</p>Metadata Validation Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/<h1 id="metadata-validation-guide">Metadata Validation Guide<a class="anchor" href="#metadata-validation-guide">#</a></h1> -<p>This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.</p> -<p>Benefits:</p> -<ul> -<li>Enforce consistent metadata structure across all embeddings</li> -<li>Catch data entry errors early</li> -<li>Document expected metadata fields</li> -<li>Enable reliable metadata-based filtering</li> -</ul> -<h2 id="defining-a-metadata-schema">Defining a Metadata Schema<a class="anchor" href="#defining-a-metadata-schema">#</a></h2> -<h3 id="when-creating-a-project">When Creating a Project<a class="anchor" href="#when-creating-a-project">#</a></h3> -<p>Include a <code>metadataScheme</code> field with a valid JSON Schema when creating a project:</p>Metadata Filtering Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/<h1 id="metadata-filtering-guide">Metadata Filtering Guide<a class="anchor" href="#metadata-filtering-guide">#</a></h1> -<p>This guide explains how to use metadata filtering to exclude specific documents from similarity search results.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:</p> -<ul> -<li>Exclude documents from the same author when finding similar writing styles</li> -<li>Filter out documents from the same source when finding related content</li> -<li>Exclude documents with the same category when exploring diversity</li> -</ul> -<p>dhamps-vdb provides metadata filtering using query parameters that perform <strong>negative matching</strong> - they exclude documents where the metadata field matches the specified value.</p>Batch Operations Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/<h1 id="batch-operations-guide">Batch Operations Guide<a class="anchor" href="#batch-operations-guide">#</a></h1> -<p>This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>For production workloads and large datasets, efficient batch operations are essential. This guide covers:</p> -<ul> -<li>Uploading multiple embeddings in a single request</li> -<li>Pagination strategies for large result sets</li> -<li>Best practices for performance and reliability</li> -<li>Error handling in batch operations</li> -</ul> -<h2 id="batch-upload-basics">Batch Upload Basics<a class="anchor" href="#batch-upload-basics">#</a></h2> -<h3 id="single-request-with-multiple-embeddings">Single Request with Multiple Embeddings<a class="anchor" href="#single-request-with-multiple-embeddings">#</a></h3> -<p>Upload multiple embeddings in one API call using the <code>embeddings</code> array:</p>Instance Management Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/instance-management/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/<h1 id="instance-management-guide">Instance Management Guide<a class="anchor" href="#instance-management-guide">#</a></h1> -<p>This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:</p> -<ul> -<li>API endpoint and credentials</li> -<li>Model name and version</li> -<li>Vector dimensions</li> -<li>API standard (protocol)</li> -</ul> -<p>Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.</p> \ No newline at end of file diff --git a/docs/public/guides/instance-management/index.html b/docs/public/guides/instance-management/index.html deleted file mode 100644 index 47b96de..0000000 --- a/docs/public/guides/instance-management/index.html +++ /dev/null @@ -1,273 +0,0 @@ -Instance Management Guide | dhamps-vdb Documentation - -

    Instance Management Guide#

    This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.

    Overview#

    LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:

    • API endpoint and credentials
    • Model name and version
    • Vector dimensions
    • API standard (protocol)

    Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.

    Instance Architecture#

    System Definitions#

    The system provides pre-configured templates for common LLM services:

    # List available system definitions (no auth required)
    -curl -X GET "https://api.example.com/v1/llm-service-definitions/_system"

    Default System Definitions:

    • openai-large: OpenAI text-embedding-3-large (3072 dimensions)
    • openai-small: OpenAI text-embedding-3-small (1536 dimensions)
    • cohere-v4: Cohere Embed v4 (1536 dimensions)
    • gemini-embedding-001: Google Gemini embedding-001 (3072 dimensions, default size)

    User Instances#

    Users create instances for their own use. Instances contain:

    • Configuration (endpoint, model, dimensions)
    • Encrypted API keys (write-only, never returned)
    • Optional reference to a definition template

    Creating LLM Service Instances#

    Option 1: Standalone Instance#

    Create an instance by specifying all configuration fields:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "my-openai",
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "description": "OpenAI large embedding model for research",
    -    "api_key_encrypted": "sk-proj-your-openai-api-key-here"
    -  }'

    Response:

    {
    -  "instance_id": 123,
    -  "instance_handle": "my-openai",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072,
    -  "description": "OpenAI large embedding model for research"
    -}

    Note: The api_key_encrypted field is not returned in the response for security reasons.

    Option 2: From System Definition#

    Create an instance based on a system template (only requires API key):

    curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai-instance" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "my-openai-instance",
    -    "definition_owner": "_system",
    -    "definition_handle": "openai-large",
    -    "api_key_encrypted": "sk-proj-your-openai-api-key-here"
    -  }'

    This inherits configuration from the _system/openai-large definition and only requires you to provide your API key.

    Option 3: From User Definition#

    Users can create their own definitions as templates:

    # Step 1: Create a custom definition
    -curl -X PUT "https://api.example.com/v1/llm-service-definitions/alice/my-custom-config" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "definition_handle": "my-custom-config",
    -    "endpoint": "https://custom-api.example.com/embeddings",
    -    "api_standard": "openai",
    -    "model": "custom-model-v2",
    -    "dimensions": 2048,
    -    "description": "Custom embedding service"
    -  }'
    -
    -# Step 2: Create instance from that definition
    -curl -X POST "https://api.example.com/v1/llm-services/alice/custom-instance" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "custom-instance",
    -    "definition_owner": "alice",
    -    "definition_handle": "my-custom-config",
    -    "api_key_encrypted": "your-api-key-here"
    -  }'

    Managing Instances#

    List Your Instances#

    Get all instances you own or have access to:

    curl -X GET "https://api.example.com/v1/llm-services/alice" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "owned_instances": [
    -    {
    -      "instance_id": 123,
    -      "instance_handle": "my-openai",
    -      "endpoint": "https://api.openai.com/v1/embeddings",
    -      "model": "text-embedding-3-large",
    -      "dimensions": 3072
    -    },
    -    {
    -      "instance_id": 124,
    -      "instance_handle": "my-cohere",
    -      "endpoint": "https://api.cohere.ai/v1/embed",
    -      "model": "embed-english-v4.0",
    -      "dimensions": 1536
    -    }
    -  ],
    -  "shared_instances": [
    -    {
    -      "instance_id": 456,
    -      "instance_handle": "team-openai",
    -      "owner": "bob",
    -      "endpoint": "https://api.openai.com/v1/embeddings",
    -      "model": "text-embedding-3-large",
    -      "dimensions": 3072,
    -      "role": "reader"
    -    }
    -  ]
    -}

    Get Instance Details#

    Retrieve details for a specific instance:

    curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key"

    Update Instance#

    Update instance configuration (owner only):

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Updated description",
    -    "api_key_encrypted": "sk-proj-new-api-key-here"
    -  }'

    Delete Instance#

    Delete an instance (owner only):

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key"

    Note: Cannot delete instances that are used by existing projects.

    API Key Encryption#

    How Encryption Works#

    API keys are encrypted using AES-256-GCM encryption:

    1. Encryption Key Source: ENCRYPTION_KEY environment variable
    2. Key Derivation: SHA256 hash of the environment variable (ensures 32-byte key)
    3. Algorithm: AES-256-GCM (authenticated encryption)
    4. Storage: Encrypted bytes stored in api_key_encrypted column

    Setting Up Encryption#

    Add to your environment configuration:

    # .env file
    -ENCRYPTION_KEY="your-secure-random-32-character-key-or-longer"

    Important Security Notes:

    • Keep this key secure and backed up
    • Losing the key means losing access to encrypted API keys
    • Use a strong, random string (32+ characters)
    • Never commit the key to version control
    • Rotate the key periodically (requires re-encrypting all API keys)

    API Key Security#

    API keys are write-only in the API:

    # Upload API key (works)
    -curl -X PUT "https://api.example.com/v1/llm-services/alice/my-instance" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"api_key_encrypted": "sk-..."}'
    -
    -# Retrieve instance (API key NOT returned)
    -curl -X GET "https://api.example.com/v1/llm-services/alice/my-instance" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Response does NOT include api_key_encrypted field
    -{
    -  "instance_id": 123,
    -  "instance_handle": "my-instance",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072
    -  // No api_key_encrypted field!
    -}

    This protects API keys from:

    • Accidental exposure in logs
    • Unauthorized access via shared instances
    • Client-side data breaches

    Instance Sharing#

    Share an Instance#

    Grant another user access to your instance:

    curl -X POST "https://api.example.com/v1/llm-services/alice/my-openai/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "bob",
    -    "role": "reader"
    -  }'

    Roles:

    • reader: Can use the instance in projects (read-only)
    • editor: Can use the instance (currently same as reader)
    • owner: Full control (only one owner, the creator)

    List Shared Users#

    See who has access to your instance:

    curl -X GET "https://api.example.com/v1/llm-services/alice/my-openai/shared-with" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "instance_handle": "my-openai",
    -  "owner": "alice",
    -  "shared_with": [
    -    {"user_handle": "bob", "role": "reader"},
    -    {"user_handle": "charlie", "role": "reader"}
    -  ]
    -}

    Unshare an Instance#

    Revoke access:

    curl -X DELETE "https://api.example.com/v1/llm-services/alice/my-openai/share/bob" \
    -  -H "Authorization: Bearer alice_api_key"

    Using Shared Instances#

    Bob can reference Alice’s shared instance in his projects:

    # Bob creates a project using Alice's instance
    -curl -X PUT "https://api.example.com/v1/projects/bob/my-project" \
    -  -H "Authorization: Bearer bob_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "my-project",
    -    "description": "Using shared instance",
    -    "instance_owner": "alice",
    -    "instance_handle": "my-openai"
    -  }'
    -
    -# Bob uploads embeddings using the shared instance
    -curl -X POST "https://api.example.com/v1/embeddings/bob/my-project" \
    -  -H "Authorization: Bearer bob_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc001",
    -      "instance_handle": "alice/my-openai",
    -      "vector": [0.1, 0.2, ...],
    -      "vector_dim": 3072
    -    }]
    -  }'

    Important: Bob can use the instance but cannot see Alice’s API key.

    Instance Sharing Patterns#

    Team Shared Instance#

    A team lead creates and shares an instance for the team:

    # Team lead creates instance
    -curl -X PUT "https://api.example.com/v1/llm-services/team_lead/team-openai" \
    -  -H "Authorization: Bearer team_lead_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "team-openai",
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "api_key_encrypted": "sk-proj-team-api-key"
    -  }'
    -
    -# Share with team members
    -for member in alice bob charlie; do
    -  curl -X POST "https://api.example.com/v1/llm-services/team_lead/team-openai/share" \
    -    -H "Authorization: Bearer team_lead_api_key" \
    -    -H "Content-Type: application/json" \
    -    -d "{\"share_with_handle\": \"$member\", \"role\": \"reader\"}"
    -done

    Organization-Wide Instance#

    Create a shared instance for organization-wide use:

    # Organization admin creates instance
    -curl -X PUT "https://api.example.com/v1/llm-services/org_admin/org-embeddings" \
    -  -H "Authorization: Bearer org_admin_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "org-embeddings",
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "description": "Organization-wide embedding service",
    -    "api_key_encrypted": "sk-proj-org-api-key"
    -  }'

    Per-Project Instance#

    Each project maintainer creates their own instance:

    # Alice creates her own instance for her project
    -curl -X PUT "https://api.example.com/v1/llm-services/alice/research-embeddings" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "research-embeddings",
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "api_key_encrypted": "sk-proj-alice-research-key"
    -  }'

    Common Configurations#

    OpenAI Configuration#

    {
    -  "instance_handle": "openai-large",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "api_standard": "openai",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072,
    -  "api_key_encrypted": "sk-proj-..."
    -}

    Cohere Configuration#

    {
    -  "instance_handle": "cohere-english",
    -  "endpoint": "https://api.cohere.ai/v1/embed",
    -  "api_standard": "cohere",
    -  "model": "embed-english-v4.0",
    -  "dimensions": 1536,
    -  "api_key_encrypted": "your-cohere-api-key"
    -}

    Google Gemini Configuration#

    {
    -  "instance_handle": "gemini-embedding",
    -  "endpoint": "https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent",
    -  "api_standard": "gemini",
    -  "model": "embedding-001",
    -  "dimensions": 3072,
    -  "api_key_encrypted": "your-gemini-api-key"
    -}

    Custom/Self-Hosted Service#

    {
    -  "instance_handle": "custom-service",
    -  "endpoint": "https://custom-api.example.com/v1/embeddings",
    -  "api_standard": "openai",
    -  "model": "custom-model-v2",
    -  "dimensions": 2048,
    -  "description": "Self-hosted embedding service",
    -  "api_key_encrypted": "custom-auth-token"
    -}

    Projects and Instances#

    1:1 Relationship#

    Each project must reference exactly one instance:

    curl -X PUT "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "my-project",
    -    "description": "Project with instance",
    -    "instance_id": 123
    -  }'

    Changing Instance#

    Update a project to use a different instance:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"instance_id": 456}'

    Note: Only switch to instances with matching dimensions, or you’ll get validation errors on future uploads.

    Finding Instance for Project#

    curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key"

    The response includes the instance_id field.

    Best Practices#

    1. Use System Definitions#

    Start with system definitions for common services:

    # Easiest approach
    -curl -X POST "https://api.example.com/v1/llm-services/alice/my-instance" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "my-instance",
    -    "definition_owner": "_system",
    -    "definition_handle": "openai-large",
    -    "api_key_encrypted": "sk-..."
    -  }'

    2. Descriptive Instance Names#

    Use clear, descriptive names:

    # Good names
    -"research-openai-large"
    -"prod-cohere-english"
    -"test-gemini-embedding"
    -
    -# Avoid generic names
    -"instance1"
    -"my-instance"
    -"test"

    3. Separate Production and Development#

    Create separate instances for different environments:

    # Development instance
    -curl -X PUT "https://api.example.com/v1/llm-services/alice/dev-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"instance_handle": "dev-openai", ...}'
    -
    -# Production instance
    -curl -X PUT "https://api.example.com/v1/llm-services/alice/prod-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"instance_handle": "prod-openai", ...}'

    4. Document Instance Purpose#

    Use the description field:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/team-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "instance_handle": "team-openai",
    -    "description": "Shared OpenAI instance for research team. Contact alice@example.com for access.",
    -    ...
    -  }'

    5. Regular Key Rotation#

    Periodically update API keys:

    curl -X PATCH "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"api_key_encrypted": "sk-proj-new-key-here"}'

    6. Monitor Instance Usage#

    Track which projects use each instance to avoid deleting in-use instances.

    Troubleshooting#

    Cannot Delete Instance#

    Error: “Instance is in use by existing projects”

    Solution: Delete or update projects using this instance first.

    Dimension Mismatch#

    Error: “vector dimension mismatch”

    Solution: Ensure embeddings match the instance’s configured dimensions.

    API Key Not Working#

    Problem: Embeddings uploads fail with authentication errors

    Solution:

    1. Verify API key is correct
    2. Check API key permissions with the LLM provider
    3. Update the API key in the instance

    Cannot Access Shared Instance#

    Problem: Getting “Instance not found” errors

    Solution: Verify you’ve been granted access. Contact the instance owner.

    Security Summary#

    1. API keys are encrypted at rest using AES-256-GCM
    2. API keys are never returned via GET requests
    3. Shared users cannot see API keys (write-only field)
    4. Encryption key must be secured (loss means cannot decrypt keys)
    5. Regular key rotation recommended for production use
    \ No newline at end of file diff --git a/docs/public/guides/metadata-filtering/index.html b/docs/public/guides/metadata-filtering/index.html deleted file mode 100644 index 27f59ab..0000000 --- a/docs/public/guides/metadata-filtering/index.html +++ /dev/null @@ -1,189 +0,0 @@ -Metadata Filtering Guide | dhamps-vdb Documentation - -

    Metadata Filtering Guide#

    This guide explains how to use metadata filtering to exclude specific documents from similarity search results.

    Overview#

    When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:

    • Exclude documents from the same author when finding similar writing styles
    • Filter out documents from the same source when finding related content
    • Exclude documents with the same category when exploring diversity

    dhamps-vdb provides metadata filtering using query parameters that perform negative matching - they exclude documents where the metadata field matches the specified value.

    Query Parameters#

    Both similarity search endpoints support metadata filtering:

    • metadata_path: The JSON path to the metadata field (e.g., author, source.id, tags[0])
    • metadata_value: The value to exclude from results

    Both parameters must be used together. If you specify one without the other, the API returns an error.

    Basic Filtering Examples#

    Exclude Documents by Author#

    Find similar documents but exclude those from the same author:

    curl -X GET "https://api.example.com/v1/similars/alice/literary-corpus/hamlet-soliloquy?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \
    -  -H "Authorization: Bearer alice_api_key"

    This returns similar documents, excluding any with metadata.author == "William Shakespeare".

    Exclude Documents from Same Source#

    Find similar content from different sources:

    curl -X GET "https://api.example.com/v1/similars/alice/news-articles/article123?count=10&metadata_path=source&metadata_value=NYTimes" \
    -  -H "Authorization: Bearer alice_api_key"

    This excludes any documents with metadata.source == "NYTimes".

    Exclude by Category#

    Find documents in different categories:

    curl -X GET "https://api.example.com/v1/similars/alice/products/product456?count=10&metadata_path=category&metadata_value=electronics" \
    -  -H "Authorization: Bearer alice_api_key"

    This excludes any documents with metadata.category == "electronics".

    Filtering with Raw Embeddings#

    Metadata filtering also works when searching with raw embedding vectors:

    curl -X POST "https://api.example.com/v1/similars/alice/literary-corpus?count=10&metadata_path=author&metadata_value=William%20Shakespeare" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [0.032, -0.018, 0.056, ...]
    -  }'

    This searches using the provided vector but excludes documents where metadata.author == "William Shakespeare".

    Nested Metadata Paths#

    For nested metadata objects, use dot notation:

    Example Metadata Structure#

    {
    -  "author": {
    -    "name": "Jane Doe",
    -    "id": "author123",
    -    "affiliation": "University"
    -  },
    -  "publication": {
    -    "journal": "Science",
    -    "year": 2023
    -  }
    -}

    Filter by Nested Field#

    # Exclude documents from same author ID
    -curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=author.id&metadata_value=author123" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Exclude documents from same journal
    -curl -X GET "https://api.example.com/v1/similars/alice/papers/paper001?count=10&metadata_path=publication.journal&metadata_value=Science" \
    -  -H "Authorization: Bearer alice_api_key"

    Combining with Other Parameters#

    Metadata filtering works seamlessly with other search parameters:

    curl -X GET "https://api.example.com/v1/similars/alice/documents/doc123?count=20&threshold=0.8&limit=10&offset=0&metadata_path=source_id&metadata_value=src_456" \
    -  -H "Authorization: Bearer alice_api_key"

    Parameters:

    • count=20: Consider top 20 similar documents
    • threshold=0.8: Only include documents with similarity ≥ 0.8
    • limit=10: Return at most 10 results
    • offset=0: Start from first result (for pagination)
    • metadata_path=source_id: Filter on this metadata field
    • metadata_value=src_456: Exclude documents with this value

    Use Cases#

    1. Finding Similar Writing Styles Across Authors#

    When analyzing writing styles, you want similar texts from different authors:

    # Upload documents with author metadata
    -curl -X POST "https://api.example.com/v1/embeddings/alice/writing-styles" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "tolstoy-passage-1",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, ...],
    -      "vector_dim": 3072,
    -      "text": "Happy families are all alike...",
    -      "metadata": {
    -        "author": "Leo Tolstoy",
    -        "work": "Anna Karenina",
    -        "language": "Russian"
    -      }
    -    }]
    -  }'
    -
    -# Find similar writing styles from other authors
    -curl -X GET "https://api.example.com/v1/similars/alice/writing-styles/tolstoy-passage-1?count=10&metadata_path=author&metadata_value=Leo%20Tolstoy" \
    -  -H "Authorization: Bearer alice_api_key"

    2. Cross-Source Content Discovery#

    Find related news articles from different sources:

    # Search for similar content, excluding same source
    -curl -X GET "https://api.example.com/v1/similars/alice/news-corpus/nyt-article-456?count=15&metadata_path=source&metadata_value=New%20York%20Times" \
    -  -H "Authorization: Bearer alice_api_key"

    This helps discover how different outlets cover similar topics.

    3. Product Recommendations Across Categories#

    Find similar products in different categories:

    # User is viewing a laptop
    -curl -X GET "https://api.example.com/v1/similars/alice/product-catalog/laptop-001?count=10&threshold=0.7&metadata_path=category&metadata_value=electronics" \
    -  -H "Authorization: Bearer alice_api_key"

    This could recommend accessories, furniture (for home office), or other complementary items.

    4. Research Paper Discovery#

    Find related papers from different research groups:

    curl -X GET "https://api.example.com/v1/similars/alice/research-papers/paper123?count=20&metadata_path=lab_id&metadata_value=lab_abc_001" \
    -  -H "Authorization: Bearer alice_api_key"

    Helps researchers discover related work from other institutions.

    5. Avoiding Duplicate Content#

    When building a diverse content feed, exclude items from the same collection:

    curl -X GET "https://api.example.com/v1/similars/alice/blog-posts/post789?count=5&metadata_path=collection_id&metadata_value=series_xyz" \
    -  -H "Authorization: Bearer alice_api_key"

    6. Cross-Language Document Discovery#

    Find similar documents in other languages:

    curl -X GET "https://api.example.com/v1/similars/alice/multilingual-docs/doc_en_123?count=10&metadata_path=language&metadata_value=en" \
    -  -H "Authorization: Bearer alice_api_key"

    This finds semantically similar documents in languages other than English.

    Working with Multiple Values#

    Currently, you can only filter by one metadata field at a time. To exclude multiple values, you need to:

    1. Make multiple requests and merge results in your application
    2. Use more specific metadata fields that combine multiple attributes
    3. Post-process results on the client side

    Example: Excluding Multiple Authors#

    import requests
    -
    -def find_similar_excluding_authors(doc_id, exclude_authors):
    -    """Find similar docs excluding multiple authors"""
    -    all_results = []
    -    
    -    for author in exclude_authors:
    -        response = requests.get(
    -            f"https://api.example.com/v1/similars/alice/corpus/{doc_id}",
    -            headers={"Authorization": "Bearer alice_api_key"},
    -            params={
    -                "count": 20,
    -                "metadata_path": "author",
    -                "metadata_value": author
    -            }
    -        )
    -        results = response.json()['results']
    -        all_results.extend(results)
    -    
    -    # Deduplicate and sort by similarity
    -    seen = set()
    -    unique_results = []
    -    for r in sorted(all_results, key=lambda x: x['similarity'], reverse=True):
    -        if r['id'] not in seen:
    -            seen.add(r['id'])
    -            unique_results.append(r)
    -    
    -    return unique_results[:10]
    -
    -# Usage
    -similar = find_similar_excluding_authors(
    -    "doc123",
    -    ["Author A", "Author B", "Author C"]
    -)

    Combining with Metadata Validation#

    For reliable filtering, combine with metadata schema validation:

    # Step 1: Create project with metadata schema
    -curl -X POST "https://api.example.com/v1/projects/alice/validated-corpus" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "validated-corpus",
    -    "description": "Corpus with validated metadata",
    -    "instance_id": 123,
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"source_id\":{\"type\":\"string\"}},\"required\":[\"author\",\"source_id\"]}"
    -  }'
    -
    -# Step 2: Upload embeddings with metadata
    -curl -X POST "https://api.example.com/v1/embeddings/alice/validated-corpus" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc001",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "John Doe",
    -        "source_id": "source_123"
    -      }
    -    }]
    -  }'
    -
    -# Step 3: Search with guaranteed metadata field existence
    -curl -X GET "https://api.example.com/v1/similars/alice/validated-corpus/doc001?count=10&metadata_path=author&metadata_value=John%20Doe" \
    -  -H "Authorization: Bearer alice_api_key"

    See the Metadata Validation Guide for more details.

    Understanding the Filter Logic#

    The metadata filter uses negative matching:

    INCLUDE document IF:
    -  - document.similarity >= threshold
    -  AND
    -  - document.metadata[metadata_path] != metadata_value

    Important: Documents without the specified metadata field are included (not filtered out).

    Example#

    Given this query:

    ?metadata_path=author&metadata_value=Alice

    Included:

    • Documents where metadata.author == "Bob"
    • Documents where metadata.author == "Charlie"
    • Documents without an author field in metadata

    Excluded:

    • Documents where metadata.author == "Alice"

    Performance Considerations#

    Metadata filtering is performed at the database level using efficient indexing:

    1. Vector similarity is computed first
    2. Metadata filter is applied to the similarity results
    3. Results are sorted and limited

    For best performance:

    • Use indexed metadata fields when possible
    • Keep metadata values relatively small (under 1KB per document)
    • Consider using IDs instead of full names for filtering

    Error Handling#

    Missing One Parameter#

    # Missing metadata_value
    -curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author" \
    -  -H "Authorization: Bearer alice_api_key"

    Error:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata_path and metadata_value must be used together"
    -}

    Non-Existent Metadata Field#

    # Filtering on field that doesn't exist in documents
    -curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?count=10&metadata_path=nonexistent_field&metadata_value=some_value" \
    -  -H "Authorization: Bearer alice_api_key"

    Result: Returns all matching documents (since none have the field, none are excluded).

    URL Encoding#

    Remember to URL-encode metadata values with special characters:

    # Correct: URL-encoded value
    -curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John%20Doe%20%26%20Jane%20Smith" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Incorrect: Unencoded special characters
    -curl -X GET "https://api.example.com/v1/similars/alice/corpus/doc123?metadata_path=author&metadata_value=John Doe & Jane Smith" \
    -  -H "Authorization: Bearer alice_api_key"

    Complete Example#

    Here’s a complete workflow demonstrating metadata filtering:

    # 1. Create project
    -curl -X POST "https://api.example.com/v1/projects/alice/literature" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "literature",
    -    "instance_id": 123
    -  }'
    -
    -# 2. Upload documents with metadata
    -curl -X POST "https://api.example.com/v1/embeddings/alice/literature" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [
    -      {
    -        "text_id": "tolstoy_1",
    -        "instance_handle": "openai-large",
    -        "vector": [0.1, 0.2, ...],
    -        "vector_dim": 3072,
    -        "text": "All happy families...",
    -        "metadata": {"author": "Tolstoy", "work": "Anna Karenina"}
    -      },
    -      {
    -        "text_id": "tolstoy_2",
    -        "instance_handle": "openai-large",
    -        "vector": [0.11, 0.21, ...],
    -        "vector_dim": 3072,
    -        "text": "It was the best of times...",
    -        "metadata": {"author": "Tolstoy", "work": "War and Peace"}
    -      },
    -      {
    -        "text_id": "dickens_1",
    -        "instance_handle": "openai-large",
    -        "vector": [0.12, 0.19, ...],
    -        "vector_dim": 3072,
    -        "text": "It was the age of wisdom...",
    -        "metadata": {"author": "Dickens", "work": "Tale of Two Cities"}
    -      }
    -    ]
    -  }'
    -
    -# 3. Find similar to tolstoy_1, excluding Tolstoy's works
    -curl -X GET "https://api.example.com/v1/similars/alice/literature/tolstoy_1?count=10&metadata_path=author&metadata_value=Tolstoy" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Result: Returns dickens_1, excludes tolstoy_2

    Troubleshooting#

    No Results Returned#

    Problem: Filter excludes all results

    Solution:

    • Verify the metadata field exists in your documents
    • Check that the metadata value matches exactly (case-sensitive)
    • Try without the filter to ensure there are similar documents

    Filter Not Working#

    Problem: Still seeing documents you want to exclude

    Solution:

    • Check URL encoding of the metadata value
    • Verify the metadata path is correct (use dot notation for nested fields)
    • Ensure both metadata_path and metadata_value are specified

    Want Positive Matching#

    Problem: Want to include only specific values, not exclude them

    Solution: Currently, only negative matching (exclusion) is supported. For positive matching, retrieve all results and filter on the client side, or use multiple negative filters to exclude everything except your target values.

    \ No newline at end of file diff --git a/docs/public/guides/metadata-validation/index.html b/docs/public/guides/metadata-validation/index.html deleted file mode 100644 index 07c32ce..0000000 --- a/docs/public/guides/metadata-validation/index.html +++ /dev/null @@ -1,372 +0,0 @@ -Metadata Validation Guide | dhamps-vdb Documentation - -

    Metadata Validation Guide#

    This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.

    Overview#

    dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.

    Benefits:

    • Enforce consistent metadata structure across all embeddings
    • Catch data entry errors early
    • Document expected metadata fields
    • Enable reliable metadata-based filtering

    Defining a Metadata Schema#

    When Creating a Project#

    Include a metadataScheme field with a valid JSON Schema when creating a project:

    curl -X POST "https://api.example.com/v1/projects/alice/validated-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "validated-project",
    -    "description": "Project with metadata validation",
    -    "instance_id": 123,
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    -  }'

    Updating an Existing Project#

    Add or update a metadata schema using PATCH:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"},\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"title\",\"author\"]}"
    -  }'

    Note: Schema updates only affect new or updated embeddings. Existing embeddings are not retroactively validated.

    Common Schema Patterns#

    Simple Required Fields#

    Require specific fields with basic types:

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {"type": "string"},
    -    "year": {"type": "integer"}
    -  },
    -  "required": ["author"]
    -}

    Example usage:

    curl -X POST "https://api.example.com/v1/projects/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "literary-texts",
    -    "description": "Literary texts with structured metadata",
    -    "instance_id": 123,
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"author\"]}"
    -  }'

    Using Enums for Controlled Values#

    Restrict fields to specific allowed values:

    {
    -  "type": "object",
    -  "properties": {
    -    "genre": {
    -      "type": "string",
    -      "enum": ["poetry", "prose", "drama", "essay"]
    -    },
    -    "language": {
    -      "type": "string",
    -      "enum": ["en", "de", "fr", "es", "la"]
    -    }
    -  },
    -  "required": ["genre"]
    -}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "hamlet-soliloquy",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "William Shakespeare",
    -        "year": 1603,
    -        "genre": "drama"
    -      }
    -    }]
    -  }'

    Nested Objects#

    Define structured metadata with nested objects:

    {
    -  "type": "object",
    -  "properties": {
    -    "author": {
    -      "type": "object",
    -      "properties": {
    -        "name": {"type": "string"},
    -        "birth_year": {"type": "integer"},
    -        "nationality": {"type": "string"}
    -      },
    -      "required": ["name"]
    -    },
    -    "publication": {
    -      "type": "object",
    -      "properties": {
    -        "year": {"type": "integer"},
    -        "publisher": {"type": "string"},
    -        "city": {"type": "string"}
    -      }
    -    }
    -  },
    -  "required": ["author"]
    -}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/academic-papers" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "paper001",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": {
    -          "name": "Jane Smith",
    -          "birth_year": 1975,
    -          "nationality": "USA"
    -        },
    -        "publication": {
    -          "year": 2023,
    -          "publisher": "Academic Press",
    -          "city": "Boston"
    -        }
    -      }
    -    }]
    -  }'

    Arrays and Lists#

    Define arrays of values:

    {
    -  "type": "object",
    -  "properties": {
    -    "keywords": {
    -      "type": "array",
    -      "items": {"type": "string"},
    -      "minItems": 1,
    -      "maxItems": 10
    -    },
    -    "categories": {
    -      "type": "array",
    -      "items": {
    -        "type": "string",
    -        "enum": ["philosophy", "literature", "science", "history"]
    -      }
    -    }
    -  }
    -}

    Example:

    curl -X POST "https://api.example.com/v1/embeddings/alice/research-docs" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc001",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "keywords": ["machine learning", "embeddings", "NLP"],
    -        "categories": ["science", "literature"]
    -      }
    -    }]
    -  }'

    Numeric Constraints#

    Apply minimum, maximum, and range constraints:

    {
    -  "type": "object",
    -  "properties": {
    -    "rating": {
    -      "type": "number",
    -      "minimum": 0,
    -      "maximum": 5
    -    },
    -    "page_count": {
    -      "type": "integer",
    -      "minimum": 1
    -    },
    -    "confidence": {
    -      "type": "number",
    -      "minimum": 0.0,
    -      "maximum": 1.0
    -    }
    -  }
    -}

    String Constraints#

    Apply length and pattern constraints:

    {
    -  "type": "object",
    -  "properties": {
    -    "title": {
    -      "type": "string",
    -      "minLength": 1,
    -      "maxLength": 200
    -    },
    -    "isbn": {
    -      "type": "string",
    -      "pattern": "^[0-9]{13}$"
    -    },
    -    "doi": {
    -      "type": "string",
    -      "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$"
    -    }
    -  }
    -}

    Validation Examples#

    Valid Upload#

    When metadata conforms to the schema:

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "kant-critique",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "Immanuel Kant",
    -        "year": 1781,
    -        "genre": "prose"
    -      }
    -    }]
    -  }'

    Response:

    {
    -  "message": "Embeddings uploaded successfully",
    -  "count": 1
    -}

    Validation Error: Missing Required Field#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "some-text",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "year": 1781
    -      }
    -    }]
    -  }'

    Error Response:

    {
    -  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - author is required"
    -}

    Validation Error: Wrong Type#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "some-text",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "John Doe",
    -        "year": "1781"
    -      }
    -    }]
    -  }'

    Error Response:

    {
    -  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - year: expected integer, got string"
    -}

    Validation Error: Invalid Enum Value#

    curl -X POST "https://api.example.com/v1/embeddings/alice/literary-texts" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "some-text",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "author": "John Doe",
    -        "year": 1781,
    -        "genre": "novel"
    -      }
    -    }]
    -  }'

    Error Response:

    {
    -  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'some-text': metadata validation failed:\n  - genre: value must be one of: poetry, prose, drama, essay"
    -}

    Validation Error: Value Out of Range#

    curl -X POST "https://api.example.com/v1/embeddings/alice/rated-content" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "review001",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {
    -        "rating": 7.5
    -      }
    -    }]
    -  }'

    Error Response:

    {
    -  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "metadata validation failed for text_id 'review001': metadata validation failed:\n  - rating: must be <= 5"
    -}

    Real-World Schema Examples#

    Academic Publications#

    {
    -  "type": "object",
    -  "properties": {
    -    "doi": {
    -      "type": "string",
    -      "pattern": "^10\\.\\d{4,}/[\\w\\-\\.]+$"
    -    },
    -    "title": {
    -      "type": "string",
    -      "minLength": 1,
    -      "maxLength": 500
    -    },
    -    "authors": {
    -      "type": "array",
    -      "items": {"type": "string"},
    -      "minItems": 1
    -    },
    -    "year": {
    -      "type": "integer",
    -      "minimum": 1900,
    -      "maximum": 2100
    -    },
    -    "journal": {"type": "string"},
    -    "volume": {"type": "integer"},
    -    "pages": {"type": "string"},
    -    "keywords": {
    -      "type": "array",
    -      "items": {"type": "string"}
    -    }
    -  },
    -  "required": ["doi", "title", "authors", "year"]
    -}
    {
    -  "type": "object",
    -  "properties": {
    -    "case_number": {"type": "string"},
    -    "court": {"type": "string"},
    -    "date": {
    -      "type": "string",
    -      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    -    },
    -    "jurisdiction": {
    -      "type": "string",
    -      "enum": ["federal", "state", "local"]
    -    },
    -    "category": {
    -      "type": "string",
    -      "enum": ["civil", "criminal", "administrative"]
    -    },
    -    "parties": {
    -      "type": "array",
    -      "items": {"type": "string"}
    -    }
    -  },
    -  "required": ["case_number", "court", "date"]
    -}

    Product Catalog#

    {
    -  "type": "object",
    -  "properties": {
    -    "sku": {
    -      "type": "string",
    -      "pattern": "^[A-Z]{3}-\\d{6}$"
    -    },
    -    "name": {"type": "string"},
    -    "category": {
    -      "type": "string",
    -      "enum": ["electronics", "clothing", "books", "home", "toys"]
    -    },
    -    "price": {
    -      "type": "number",
    -      "minimum": 0
    -    },
    -    "in_stock": {"type": "boolean"},
    -    "tags": {
    -      "type": "array",
    -      "items": {"type": "string"}
    -    }
    -  },
    -  "required": ["sku", "name", "category", "price"]
    -}

    Admin Sanity Check#

    Administrators can verify database integrity using the /v1/admin/sanity-check endpoint:

    curl -X GET "https://api.example.com/v1/admin/sanity-check" \
    -  -H "Authorization: Bearer admin_api_key"

    Response:

    {
    -  "status": "PASSED",
    -  "total_projects": 5,
    -  "issues_count": 0,
    -  "warnings_count": 1,
    -  "warnings": [
    -    "Project alice/project1 has 100 embeddings but no metadata schema defined"
    -  ]
    -}

    Status Values:

    • PASSED: No issues or warnings found
    • WARNING: No critical issues, but warnings exist
    • FAILED: Validation issues found that need attention

    The sanity check:

    • Validates all embeddings have dimensions matching their LLM service
    • Validates all metadata against project schemas (if defined)
    • Reports projects without schemas as warnings

    Best Practices#

    1. Start Simple, Add Complexity Later#

    Begin with basic required fields:

    {
    -  "type": "object",
    -  "properties": {
    -    "source": {"type": "string"}
    -  },
    -  "required": ["source"]
    -}

    Add more constraints as your needs evolve.

    2. Test Schemas Before Deployment#

    Use online JSON Schema validators like jsonschemavalidator.net to test your schemas before deploying them.

    3. Document Your Schema#

    Include a description in your project:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "description": "Project with metadata schema: author (required string), year (integer), genre (enum)"
    -  }'

    4. Version Your Schemas#

    If you need to change a schema significantly, consider creating a new project rather than updating the existing one.

    5. Optional vs Required#

    Be judicious with required fields. Too many required fields can make uploads cumbersome.

    6. Escape JSON Properly#

    When passing JSON schemas in curl commands, escape quotes properly or use single quotes for the outer JSON.

    Projects Without Schemas#

    If you don’t provide a metadataScheme when creating a project:

    • Metadata validation is skipped
    • You can upload any valid JSON metadata
    • This is useful for exploratory work or heterogeneous data

    Schema Updates and Existing Data#

    When you update a project’s metadata schema:

    • Existing embeddings are not revalidated
    • The new schema only applies to new or updated embeddings
    • Use the admin sanity check to find existing embeddings that don’t conform

    Removing a Schema#

    To remove metadata validation from a project:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"metadataScheme": null}'

    After this, new embeddings can have any metadata structure.

    Troubleshooting#

    Schema Syntax Errors#

    Error: “Invalid JSON Schema”

    Solution: Validate your schema syntax using an online validator. Common issues:

    • Missing commas between properties
    • Unescaped quotes
    • Invalid JSON structure

    Uploads Failing After Schema Change#

    Problem: Uploads worked before, now failing with validation errors

    Solution: Check that your metadata matches the new schema requirements. Review the error message for specific validation failures.

    Want to Fix Non-Conforming Data#

    Problem: Sanity check shows validation errors in existing data

    Solution: Either:

    1. Update the schema to accept existing data
    2. Re-upload conforming data to replace non-conforming embeddings
    3. Delete and re-upload the project with correct metadata
    \ No newline at end of file diff --git a/docs/public/guides/ownership-transfer/index.html b/docs/public/guides/ownership-transfer/index.html deleted file mode 100644 index fe3aa0b..0000000 --- a/docs/public/guides/ownership-transfer/index.html +++ /dev/null @@ -1,153 +0,0 @@ -Ownership Transfer Guide | dhamps-vdb Documentation - -

    Ownership Transfer Guide#

    This guide explains how to transfer project ownership between users in dhamps-vdb.

    Overview#

    Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:

    • A project maintainer is leaving and wants to hand over control
    • Organizational changes require reassigning project ownership
    • Consolidating projects under a different user account
    • Transferring stewardship of research data to a new PI

    Important Constraints#

    Before transferring ownership, understand these constraints:

    1. Only the current owner can transfer - Editors and readers cannot initiate transfers
    2. New owner must exist - The target user must already be registered in the system
    3. No handle conflicts - The new owner cannot already have a project with the same handle
    4. Old owner loses access - After transfer, the original owner has no access to the project
    5. Data remains intact - All embeddings and metadata are preserved during transfer
    6. Shared users remain - Existing sharing relationships are maintained

    Transferring Ownership#

    Basic Transfer#

    Transfer a project to another user:

    curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "new_owner_handle": "bob"
    -  }'

    Response:

    {
    -  "message": "Project ownership transferred successfully",
    -  "project_handle": "research-data",
    -  "old_owner": "alice",
    -  "new_owner": "bob"
    -}

    After this operation:

    • The project is now accessible at /v1/projects/bob/research-data
    • Bob has full owner privileges
    • Alice no longer has any access to the project
    • All embeddings remain unchanged

    Complete Transfer Example#

    Here’s a complete workflow showing before and after transfer:

    # Before transfer - Alice is the owner
    -curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Response
    -{
    -  "project_handle": "my-project",
    -  "owner": "alice",
    -  "description": "Research project",
    -  "instance_id": 123
    -}
    -
    -# Alice transfers to Bob
    -curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'
    -
    -# After transfer - Bob is now the owner
    -curl -X GET "https://api.example.com/v1/projects/bob/my-project" \
    -  -H "Authorization: Bearer bob_api_key"
    -
    -# Response
    -{
    -  "project_handle": "my-project",
    -  "owner": "bob",
    -  "description": "Research project",
    -  "instance_id": 123
    -}
    -
    -# Alice can no longer access it
    -curl -X GET "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key"
    -# Returns: 404 Not Found

    Effects of Transfer#

    Project Access Path Changes#

    The project URL changes to reflect the new owner:

    Before:

    /v1/projects/alice/research-data
    -/v1/embeddings/alice/research-data
    -/v1/similars/alice/research-data/doc123

    After:

    /v1/projects/bob/research-data
    -/v1/embeddings/bob/research-data
    -/v1/similars/bob/research-data/doc123

    Important: Update all client code and bookmarks to use the new owner’s handle.

    New Owner Gains Full Control#

    Bob (new owner) can now:

    • View and modify all embeddings
    • Update project settings (description, instance, metadata schema)
    • Manage sharing (add/remove shared users)
    • Transfer ownership again to someone else
    • Delete the project

    Old Owner Loses All Access#

    Alice (old owner) can no longer:

    • Access the project in any way
    • View or modify embeddings
    • See project metadata
    • Manage sharing
    • Transfer ownership back

    Note: If Alice needs continued access, Bob should share the project with her after the transfer.

    Shared Users Remain#

    If the project was shared with other users, those sharing relationships are preserved:

    # Before transfer - Alice shares with Charlie (editor)
    -curl -X POST "https://api.example.com/v1/projects/alice/research-data/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"share_with_handle": "charlie", "role": "editor"}'
    -
    -# Transfer to Bob
    -curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'
    -
    -# After transfer - Charlie still has editor access
    -curl -X GET "https://api.example.com/v1/projects/bob/research-data" \
    -  -H "Authorization: Bearer charlie_api_key"
    -# Works! Charlie can still access as editor

    Upgrading Shared User to Owner#

    If the new owner was previously a shared user, their role is automatically upgraded:

    # Alice shares project with Bob (editor)
    -curl -X POST "https://api.example.com/v1/projects/alice/my-project/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"share_with_handle": "bob", "role": "editor"}'
    -
    -# Alice transfers ownership to Bob
    -curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'
    -
    -# Bob's previous "editor" sharing role is removed
    -# Bob now has full owner privileges instead

    Use Cases#

    PI Leaving Institution#

    A principal investigator leaving an institution transfers project ownership to a colleague:

    curl -X POST "https://api.example.com/v1/projects/prof_jones/lab_data/transfer-ownership" \
    -  -H "Authorization: Bearer prof_jones_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "prof_smith"}'

    Account Consolidation#

    Consolidate multiple projects under a single organizational account:

    # Transfer Alice's personal projects to organization account
    -curl -X POST "https://api.example.com/v1/projects/alice/project1/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "org_datascience"}'
    -
    -curl -X POST "https://api.example.com/v1/projects/alice/project2/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "org_datascience"}'

    Graduated Student Handoff#

    A graduating student transfers their research project to their advisor:

    curl -X POST "https://api.example.com/v1/projects/student_bob/thesis_embeddings/transfer-ownership" \
    -  -H "Authorization: Bearer student_bob_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "advisor_carol"}'
    -
    -# Advisor can then share it back with the student if needed
    -curl -X POST "https://api.example.com/v1/projects/advisor_carol/thesis_embeddings/share" \
    -  -H "Authorization: Bearer advisor_carol_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"share_with_handle": "student_bob", "role": "reader"}'

    Department Reorganization#

    Projects move to a new department owner:

    curl -X POST "https://api.example.com/v1/projects/old_dept/resource_library/transfer-ownership" \
    -  -H "Authorization: Bearer old_dept_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "new_dept"}'

    Error Conditions#

    New Owner Doesn’t Exist#

    curl -X POST "https://api.example.com/v1/projects/alice/my-project/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "nonexistent_user"}'

    Error:

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "User 'nonexistent_user' does not exist"
    -}

    Solution: Ensure the target user is registered first. Contact admin to create the user.

    Handle Conflict#

    # Bob already has a project called "research-data"
    -curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'

    Error:

    {
    -  "title": "Conflict",
    -  "status": 409,
    -  "detail": "User 'bob' already has a project with handle 'research-data'"
    -}

    Solution: Either:

    1. Rename Alice’s project before transferring:
      curl -X PATCH "https://api.example.com/v1/projects/alice/research-data" \
      -  -H "Authorization: Bearer alice_api_key" \
      -  -H "Content-Type: application/json" \
      -  -d '{"project_handle": "research-data-alice"}'
    2. Ask Bob to rename or delete their existing project
    3. Choose a different target user

    Not the Owner#

    # Charlie tries to transfer Alice's project
    -curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    -  -H "Authorization: Bearer charlie_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'

    Error:

    {
    -  "title": "Forbidden",
    -  "status": 403,
    -  "detail": "Only the project owner can transfer ownership"
    -}

    Solution: Only the current owner (Alice) can initiate the transfer.

    Best Practices#

    Before Transferring#

    1. Communicate with New Owner: Ensure they’re willing to accept ownership
    2. Document Current State: Export or document current embeddings and metadata
    3. Review Shared Users: Check who has access and whether sharing should continue
    4. Update Client Code: Identify all systems accessing the project that need updating
    5. Backup Data: Consider exporting important data before transfer

    During Transfer#

    1. Transfer at Low-Activity Time: Minimize disruption by transferring during quiet periods
    2. Test Access First: Verify new owner can access their other projects
    3. Use Correct Handle: Double-check the new owner’s handle before submitting

    After Transferring#

    1. Verify New Ownership: Confirm the transfer succeeded
    2. Update Client Applications: Change all API calls to use new owner handle
    3. Grant Back Access if Needed: New owner can share project back to old owner
    4. Update Documentation: Update any documentation referencing the project path
    5. Notify Shared Users: Inform shared users about the path change

    Maintaining Access After Transfer#

    If the original owner needs continued access, the new owner should share the project:

    # Step 1: Alice transfers to Bob
    -curl -X POST "https://api.example.com/v1/projects/alice/research-data/transfer-ownership" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "bob"}'
    -
    -# Step 2: Bob shares back with Alice as editor
    -curl -X POST "https://api.example.com/v1/projects/bob/research-data/share" \
    -  -H "Authorization: Bearer bob_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"share_with_handle": "alice", "role": "editor"}'
    -
    -# Now Alice can still access (but as editor, not owner)
    -curl -X GET "https://api.example.com/v1/embeddings/bob/research-data" \
    -  -H "Authorization: Bearer alice_api_key"

    Checking Current Owner#

    To verify current project ownership:

    curl -X GET "https://api.example.com/v1/projects/{owner}/{project}" \
    -  -H "Authorization: Bearer your_api_key"

    The owner field in the response shows the current owner.

    Troubleshooting#

    Cannot Find Project After Transfer#

    Problem: Getting 404 after transfer

    Solution: Update the owner in your API calls:

    • Old: /v1/projects/alice/my-project
    • New: /v1/projects/bob/my-project

    Need to Reverse Transfer#

    Problem: Transferred by mistake, need to reverse

    Solution: New owner must transfer back:

    curl -X POST "https://api.example.com/v1/projects/bob/my-project/transfer-ownership" \
    -  -H "Authorization: Bearer bob_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"new_owner_handle": "alice"}'

    Client Applications Failing#

    Problem: Applications can’t access project after transfer

    Solution: Update all hardcoded owner references in your code to use the new owner’s handle.

    \ No newline at end of file diff --git a/docs/public/guides/project-sharing/index.html b/docs/public/guides/project-sharing/index.html deleted file mode 100644 index 5a54d9a..0000000 --- a/docs/public/guides/project-sharing/index.html +++ /dev/null @@ -1,142 +0,0 @@ -Project Sharing Guide | dhamps-vdb Documentation - -

    Project Sharing Guide#

    This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.

    Overview#

    Project sharing allows you to grant other users access to your projects with different permission levels:

    • reader: Read-only access to embeddings and similar documents
    • editor: Read and write access to embeddings (can add/modify/delete embeddings)

    Only the project owner can manage sharing settings and delete the project.

    Sharing During Project Creation#

    You can specify users to share with when creating a new project using the shared_with field:

    curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "collaborative-project",
    -    "description": "A project shared with team members",
    -    "instance_id": 123,
    -    "shared_with": [
    -      {
    -        "user_handle": "bob",
    -        "role": "reader"
    -      },
    -      {
    -        "user_handle": "charlie",
    -        "role": "editor"
    -      }
    -    ]
    -  }'

    In this example:

    • bob can read embeddings and search for similar documents
    • charlie can read embeddings, search, and also add/modify/delete embeddings
    • alice (the owner) has full control including managing sharing and deleting the project

    Managing Sharing After Creation#

    Share a Project with a User#

    Add a user to an existing project:

    curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "david",
    -    "role": "reader"
    -  }'

    Response:

    {
    -  "message": "Project shared successfully",
    -  "user": "david",
    -  "role": "reader"
    -}

    Update User’s Role#

    To change a user’s role, simply share again with the new role:

    curl -X POST "https://api.example.com/v1/projects/alice/collaborative-project/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "share_with_handle": "david",
    -    "role": "editor"
    -  }'

    This updates David’s access from reader to editor.

    Unshare a Project from a User#

    Remove a user’s access to a project:

    curl -X DELETE "https://api.example.com/v1/projects/alice/collaborative-project/share/david" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "message": "Project unshared successfully",
    -  "user": "david"
    -}

    List Shared Users#

    View all users a project is shared with:

    curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project/shared-with" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "project_handle": "collaborative-project",
    -  "owner": "alice",
    -  "shared_with": [
    -    {
    -      "user_handle": "bob",
    -      "role": "reader"
    -    },
    -    {
    -      "user_handle": "charlie",
    -      "role": "editor"
    -    }
    -  ]
    -}

    Note: Only the project owner can view the list of shared users. Users who have been granted access cannot see which other users also have access.

    What Shared Users Can Do#

    As a Reader#

    Bob (with reader access) can:

    # View project metadata
    -curl -X GET "https://api.example.com/v1/projects/alice/collaborative-project" \
    -  -H "Authorization: Bearer bob_api_key"
    -
    -# Retrieve embeddings
    -curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    -  -H "Authorization: Bearer bob_api_key"
    -
    -# Get a specific embedding
    -curl -X GET "https://api.example.com/v1/embeddings/alice/collaborative-project/doc123" \
    -  -H "Authorization: Bearer bob_api_key"
    -
    -# Search for similar documents
    -curl -X GET "https://api.example.com/v1/similars/alice/collaborative-project/doc123?count=5" \
    -  -H "Authorization: Bearer bob_api_key"

    As an Editor#

    Charlie (with editor access) can do everything a reader can, plus:

    # Upload new embeddings
    -curl -X POST "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    -  -H "Authorization: Bearer charlie_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc456",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072,
    -      "metadata": {"author": "Charlie"}
    -    }]
    -  }'
    -
    -# Delete specific embeddings
    -curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project/doc456" \
    -  -H "Authorization: Bearer charlie_api_key"
    -
    -# Delete all embeddings
    -curl -X DELETE "https://api.example.com/v1/embeddings/alice/collaborative-project" \
    -  -H "Authorization: Bearer charlie_api_key"

    What Shared Users Cannot Do#

    Even with editor access, shared users cannot:

    • Delete the project
    • Change project settings (description, instance, metadata schema)
    • Manage sharing (add/remove other users)
    • View the list of other shared users
    • Transfer project ownership

    These operations require owner privileges.

    Permission Summary Table#

    OperationOwnerEditorReader
    View project metadata
    Retrieve embeddings
    Search similar documents
    Add embeddings
    Modify embeddings
    Delete embeddings
    Update project settings
    Delete project
    Manage sharing
    View shared users list
    Transfer ownership

    Use Cases#

    Research Team Collaboration#

    A research team can share a project where:

    • The principal investigator (PI) is the owner
    • Research assistants have editor access to upload new data
    • External collaborators have reader access to query the data
    # PI creates and shares the project
    -curl -X PUT "https://api.example.com/v1/projects/pi/research-corpus" \
    -  -H "Authorization: Bearer pi_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-corpus",
    -    "description": "Research team corpus",
    -    "instance_id": 123,
    -    "shared_with": [
    -      {"user_handle": "assistant1", "role": "editor"},
    -      {"user_handle": "assistant2", "role": "editor"},
    -      {"user_handle": "external_collab", "role": "reader"}
    -    ]
    -  }'

    Data Pipeline with Read-Only Access#

    Share processed embeddings with downstream consumers:

    # Data processor creates project
    -curl -X PUT "https://api.example.com/v1/projects/processor/processed-data" \
    -  -H "Authorization: Bearer processor_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "processed-data",
    -    "description": "Processed embeddings for consumption",
    -    "instance_id": 456,
    -    "shared_with": [
    -      {"user_handle": "app_backend", "role": "reader"},
    -      {"user_handle": "analytics_team", "role": "reader"}
    -    ]
    -  }'

    Temporary Access#

    Grant temporary access to a consultant and revoke it later:

    # Grant access
    -curl -X POST "https://api.example.com/v1/projects/alice/sensitive-project/share" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"share_with_handle": "consultant", "role": "reader"}'
    -
    -# Revoke access when consultation is complete
    -curl -X DELETE "https://api.example.com/v1/projects/alice/sensitive-project/share/consultant" \
    -  -H "Authorization: Bearer alice_api_key"

    Combining with Public Access#

    You can combine user-specific sharing with public access (see Public Projects Guide):

    curl -X PUT "https://api.example.com/v1/projects/alice/mixed-access-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "mixed-access-project",
    -    "description": "Public read, specific editors",
    -    "instance_id": 123,
    -    "public_read": true,
    -    "shared_with": [
    -      {"user_handle": "bob", "role": "editor"}
    -    ]
    -  }'

    In this case:

    • Anyone can read the project (no authentication required)
    • bob can also edit (add/modify/delete embeddings)
    • alice retains full owner privileges

    Security Considerations#

    1. Choose Roles Carefully: Only grant editor access to trusted users who need to modify data
    2. Audit Access: Regularly review the shared users list to ensure appropriate access levels
    3. Revoke Promptly: Remove access immediately when users no longer need it
    4. Use Reader by Default: Start with reader access and upgrade to editor only when necessary
    5. Consider Public Access: For truly open data, use public_read: true instead of sharing with many users

    Troubleshooting#

    Cannot Share Project#

    Error: “Only the owner can share projects”

    Solution: Only the project owner can manage sharing. If you need to share the project, ask the owner to add you, or consider transferring ownership.

    User Not Found#

    Error: “User not found”

    Solution: The user must exist in the system before you can share a project with them. Ask the admin to create the user first.

    Cannot View Shared Users List#

    Error: “Forbidden”

    Solution: Only the project owner can view the list of shared users. Shared users cannot see other shared users for privacy reasons.

    \ No newline at end of file diff --git a/docs/public/guides/public-projects/index.html b/docs/public/guides/public-projects/index.html deleted file mode 100644 index 9e03df4..0000000 --- a/docs/public/guides/public-projects/index.html +++ /dev/null @@ -1,162 +0,0 @@ -Public Projects Guide | dhamps-vdb Documentation - -

    Public Projects Guide#

    This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.

    Overview#

    Projects can be configured to allow unauthenticated (public) read access by setting the public_read field to true. This is useful for:

    • Open datasets and research data
    • Public APIs and services
    • Shared knowledge bases
    • Educational resources

    Important: Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.

    Creating a Public Project#

    Set public_read to true when creating a project:

    curl -X PUT "https://api.example.com/v1/projects/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "public-knowledge",
    -    "description": "Publicly accessible knowledge base",
    -    "instance_id": 123,
    -    "public_read": true
    -  }'

    Response:

    {
    -  "project_handle": "public-knowledge",
    -  "owner": "alice",
    -  "description": "Publicly accessible knowledge base",
    -  "instance_id": 123,
    -  "public_read": true
    -}

    Making an Existing Project Public#

    Update an existing project using PATCH:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"public_read": true}'

    Making a Public Project Private#

    To disable public access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"public_read": false}'

    Accessing Public Projects Without Authentication#

    Once a project has public_read enabled, anyone can access it without providing an API key.

    Get Project Metadata#

    curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge"

    Response:

    {
    -  "project_handle": "public-knowledge",
    -  "owner": "alice",
    -  "description": "Publicly accessible knowledge base",
    -  "instance_id": 123,
    -  "public_read": true
    -}

    Retrieve All Embeddings#

    curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge?limit=100"

    Response:

    {
    -  "embeddings": [
    -    {
    -      "text_id": "doc001",
    -      "text": "Public document content",
    -      "metadata": {"category": "science"},
    -      "vector_dim": 3072
    -    },
    -    {
    -      "text_id": "doc002",
    -      "text": "Another public document",
    -      "metadata": {"category": "history"},
    -      "vector_dim": 3072
    -    }
    -  ]
    -}

    Get a Specific Embedding#

    curl -X GET "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001"

    Response:

    {
    -  "text_id": "doc001",
    -  "text": "Public document content",
    -  "metadata": {"category": "science"},
    -  "vector_dim": 3072,
    -  "vector": [0.021, -0.015, 0.043, ...]
    -}

    Search for Similar Documents#

    # Search by existing document ID
    -curl -X GET "https://api.example.com/v1/similars/alice/public-knowledge/doc001?count=5&threshold=0.7"

    Response:

    {
    -  "user_handle": "alice",
    -  "project_handle": "public-knowledge",
    -  "results": [
    -    {"id": "doc002", "similarity": 0.92},
    -    {"id": "doc003", "similarity": 0.85},
    -    {"id": "doc004", "similarity": 0.78}
    -  ]
    -}

    Search with Raw Embeddings#

    curl -X POST "https://api.example.com/v1/similars/alice/public-knowledge?count=5" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [0.032, -0.018, 0.056, ...]
    -  }'

    Operations Still Requiring Authentication#

    Even for public projects, these operations require authentication:

    Creating Embeddings (Requires Auth)#

    # This will fail with 401 Unauthorized
    -curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    -  -H "Content-Type: application/json" \
    -  -d '{"embeddings": [...]}'
    -
    -# This succeeds with valid API key
    -curl -X POST "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc123",
    -      "instance_handle": "openai-large",
    -      "vector": [0.1, 0.2, 0.3, ...],
    -      "vector_dim": 3072
    -    }]
    -  }'

    Deleting Embeddings (Requires Auth)#

    # Delete specific embedding (requires auth)
    -curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge/doc001" \
    -  -H "Authorization: Bearer alice_api_key"
    -
    -# Delete all embeddings (requires auth)
    -curl -X DELETE "https://api.example.com/v1/embeddings/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key"

    Modifying Project Settings (Requires Auth)#

    # Update project description (requires auth)
    -curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"description": "Updated description"}'

    Deleting Project (Requires Auth)#

    curl -X DELETE "https://api.example.com/v1/projects/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key"

    Combining Public Access with User Sharing#

    You can combine public read access with user-specific editor permissions:

    curl -X PUT "https://api.example.com/v1/projects/alice/collaborative-public" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "collaborative-public",
    -    "description": "Public read, restricted write",
    -    "instance_id": 123,
    -    "public_read": true,
    -    "shared_with": [
    -      {
    -        "user_handle": "bob",
    -        "role": "editor"
    -      },
    -      {
    -        "user_handle": "charlie",
    -        "role": "editor"
    -      }
    -    ]
    -  }'

    In this configuration:

    • Anyone can read embeddings and search (no auth required)
    • bob and charlie can add/modify/delete embeddings (with auth)
    • alice (owner) has full control (with auth)

    Use Cases#

    Open Research Dataset#

    Share research data publicly while maintaining write control:

    curl -X PUT "https://api.example.com/v1/projects/university/research-corpus" \
    -  -H "Authorization: Bearer university_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "research-corpus",
    -    "description": "Open research corpus for academic use",
    -    "instance_id": 456,
    -    "public_read": true,
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"doi\":{\"type\":\"string\"},\"year\":{\"type\":\"integer\"}},\"required\":[\"doi\"]}"
    -  }'

    Researchers worldwide can access the data without credentials, but only authorized users can add new data.

    Public API Backend#

    Build a public search API on top of dhamps-vdb:

    import requests
    -
    -def public_search_api(query_vector, count=10):
    -    """Public search function requiring no authentication"""
    -    response = requests.post(
    -        "https://api.example.com/v1/similars/company/product-docs",
    -        json={"vector": query_vector},
    -        params={"count": count, "threshold": 0.6}
    -    )
    -    return response.json()
    -
    -# No API key needed for public projects!
    -results = public_search_api(query_embedding)

    Educational Resources#

    Share educational content publicly:

    curl -X PUT "https://api.example.com/v1/projects/edu/learning-materials" \
    -  -H "Authorization: Bearer edu_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "learning-materials",
    -    "description": "Free educational content embeddings",
    -    "instance_id": 789,
    -    "public_read": true
    -  }'

    Students and educators can access the materials without creating accounts.

    Community-Driven Knowledge Base#

    Open knowledge base with restricted editors:

    curl -X PUT "https://api.example.com/v1/projects/community/wiki-embeddings" \
    -  -H "Authorization: Bearer community_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "wiki-embeddings",
    -    "description": "Community wiki embeddings",
    -    "instance_id": 321,
    -    "public_read": true,
    -    "shared_with": [
    -      {"user_handle": "moderator1", "role": "editor"},
    -      {"user_handle": "moderator2", "role": "editor"}
    -    ]
    -  }'

    Security Considerations#

    What is Publicly Visible#

    When public_read is enabled:

    • ✅ Project metadata (name, description, owner)
    • ✅ All embedding vectors and text content
    • ✅ All embedding metadata
    • ✅ Vector dimensions and instance references
    • ❌ API keys (never exposed)
    • ❌ User passwords or credentials

    Best Practices#

    1. Review Content First: Ensure no sensitive information is in embeddings or metadata before enabling public access
    2. Use Metadata Schemas: Enforce consistent metadata structure with validation
    3. Monitor Usage: Track access patterns to your public projects
    4. Set Clear Descriptions: Provide clear project descriptions explaining the data’s purpose and licensing
    5. Consider Rate Limiting: For high-traffic public APIs, implement rate limiting at the application level

    What to Avoid#

    Don’t make projects public that contain:

    • Personal identifiable information (PII)
    • Proprietary or confidential data
    • Sensitive research data not yet published
    • Internal company information

    Do make projects public that contain:

    • Already-published research data
    • Open educational resources
    • Public domain content
    • Creative Commons licensed materials

    Disabling Public Access#

    If you need to make a public project private again:

    curl -X PATCH "https://api.example.com/v1/projects/alice/public-knowledge" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"public_read": false}'

    After this change:

    • All read operations require authentication
    • Existing anonymous access is immediately revoked
    • No data is deleted, just access is restricted

    Checking if a Project is Public#

    View project metadata to check the public_read flag:

    curl -X GET "https://api.example.com/v1/projects/alice/public-knowledge"

    Look for "public_read": true in the response.

    Troubleshooting#

    Public Access Not Working#

    Symptom: Still getting 401 Unauthorized for public project

    Solutions:

    1. Verify public_read: true is set:
      curl -X GET "https://api.example.com/v1/projects/alice/my-project"
    2. Check you’re using GET/POST for similars (not other methods)
    3. Ensure the project exists and handle is correct

    Accidentally Made Project Public#

    Solution: Immediately disable public access:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-project" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{"public_read": false}'

    Want to Track Public Usage#

    Solution: Anonymous requests are logged with user set to “public”. Review server logs to monitor public access patterns.

    \ No newline at end of file diff --git a/docs/public/guides/rag-workflow/index.html b/docs/public/guides/rag-workflow/index.html deleted file mode 100644 index d00aa26..0000000 --- a/docs/public/guides/rag-workflow/index.html +++ /dev/null @@ -1,228 +0,0 @@ -RAG Workflow Guide | dhamps-vdb Documentation - -

    Complete RAG Workflow Guide#

    This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.

    Overview#

    A typical RAG workflow involves:

    1. Generate embeddings from your text content (using an external LLM service)
    2. Upload embeddings to dhamps-vdb
    3. Search for similar documents based on a query
    4. Retrieve the relevant context
    5. Use the context with an LLM to generate responses

    Prerequisites#

    • Access to dhamps-vdb API with a valid API key
    • An external LLM service for generating embeddings (e.g., OpenAI, Cohere)
    • Text content you want to process

    Step 1: Generate Embeddings Externally#

    First, use your chosen LLM service to generate embeddings for your text content. Here’s an example using OpenAI’s API:

    import openai
    -
    -# Initialize OpenAI client
    -client = openai.OpenAI(api_key="your-openai-key")
    -
    -# Generate embeddings for your text
    -text = "The quick brown fox jumps over the lazy dog"
    -response = client.embeddings.create(
    -    model="text-embedding-3-large",
    -    input=text,
    -    dimensions=3072
    -)
    -
    -embedding_vector = response.data[0].embedding

    Step 2: Create LLM Service Instance#

    Before uploading embeddings, create an LLM service instance in dhamps-vdb that matches your embedding configuration:

    curl -X PUT "https://api.example.com/v1/llm-services/alice/my-openai" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "endpoint": "https://api.openai.com/v1/embeddings",
    -    "api_standard": "openai",
    -    "model": "text-embedding-3-large",
    -    "dimensions": 3072,
    -    "description": "OpenAI large embedding model",
    -    "api_key_encrypted": "sk-proj-your-openai-key"
    -  }'

    Response:

    {
    -  "instance_id": 123,
    -  "instance_handle": "my-openai",
    -  "owner": "alice",
    -  "endpoint": "https://api.openai.com/v1/embeddings",
    -  "model": "text-embedding-3-large",
    -  "dimensions": 3072
    -}

    Step 3: Create a Project#

    Create a project to organize your embeddings:

    curl -X PUT "https://api.example.com/v1/projects/alice/my-documents" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "project_handle": "my-documents",
    -    "description": "Document embeddings for RAG",
    -    "instance_id": 123
    -  }'

    Step 4: Upload Embeddings to dhamps-vdb#

    Upload your pre-generated embeddings along with metadata and optional text content:

    curl -X POST "https://api.example.com/v1/embeddings/alice/my-documents" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "embeddings": [{
    -      "text_id": "doc001",
    -      "instance_handle": "my-openai",
    -      "vector": [0.021, -0.015, 0.043, ...],
    -      "vector_dim": 3072,
    -      "text": "The quick brown fox jumps over the lazy dog",
    -      "metadata": {
    -        "source": "example.txt",
    -        "author": "Alice",
    -        "category": "animals"
    -      }
    -    }]
    -  }'

    Tip: Upload multiple embeddings in batches for efficiency (see Batch Operations Guide).

    Step 5: Search for Similar Documents#

    When you need to retrieve relevant context for a query:

    Option A: Search by Stored Document ID#

    If you already have a document in your database that represents your query:

    curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_api_key"

    Option B: Search with Raw Query Embedding#

    Generate an embedding for your query and search without storing it:

    # Generate query embedding
    -query = "What animals are mentioned?"
    -query_response = client.embeddings.create(
    -    model="text-embedding-3-large",
    -    input=query,
    -    dimensions=3072
    -)
    -query_vector = query_response.data[0].embedding
    curl -X POST "https://api.example.com/v1/similars/alice/my-documents?count=5&threshold=0.7" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "vector": [0.032, -0.018, 0.056, ...]
    -  }'

    Response:

    {
    -  "user_handle": "alice",
    -  "project_handle": "my-documents",
    -  "results": [
    -    {
    -      "id": "doc001",
    -      "similarity": 0.95
    -    },
    -    {
    -      "id": "doc042",
    -      "similarity": 0.87
    -    },
    -    {
    -      "id": "doc103",
    -      "similarity": 0.82
    -    }
    -  ]
    -}

    Step 6: Retrieve Context Documents#

    Retrieve the full content and metadata for the most similar documents:

    curl -X GET "https://api.example.com/v1/embeddings/alice/my-documents/doc001" \
    -  -H "Authorization: Bearer alice_api_key"

    Response:

    {
    -  "text_id": "doc001",
    -  "text": "The quick brown fox jumps over the lazy dog",
    -  "metadata": {
    -    "source": "example.txt",
    -    "author": "Alice",
    -    "category": "animals"
    -  },
    -  "vector_dim": 3072
    -}

    Step 7: Use Context with LLM#

    Combine the retrieved context with your original query to generate an informed response:

    # Collect context from similar documents
    -context_docs = []
    -for result in similarity_results['results'][:3]:
    -    doc = get_document(result['id'])  # Your function to fetch document
    -    context_docs.append(doc['text'])
    -
    -# Build context string
    -context = "\n\n".join(context_docs)
    -
    -# Generate response with context
    -response = client.chat.completions.create(
    -    model="gpt-4",
    -    messages=[
    -        {"role": "system", "content": "Answer based on the provided context."},
    -        {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
    -    ]
    -)
    -
    -answer = response.choices[0].message.content

    Complete Python Example#

    Here’s a complete example combining all steps:

    import openai
    -import requests
    -
    -# Configuration
    -DHAMPS_API = "https://api.example.com"
    -DHAMPS_KEY = "your-dhamps-api-key"
    -OPENAI_KEY = "your-openai-key"
    -
    -# Initialize OpenAI
    -client = openai.OpenAI(api_key=OPENAI_KEY)
    -
    -def embed_and_store(text_id, text, metadata=None):
    -    """Generate embedding and store in dhamps-vdb"""
    -    # Generate embedding
    -    response = client.embeddings.create(
    -        model="text-embedding-3-large",
    -        input=text,
    -        dimensions=3072
    -    )
    -    vector = response.data[0].embedding
    -    
    -    # Upload to dhamps-vdb
    -    requests.post(
    -        f"{DHAMPS_API}/v1/embeddings/alice/my-documents",
    -        headers={
    -            "Authorization": f"Bearer {DHAMPS_KEY}",
    -            "Content-Type": "application/json"
    -        },
    -        json={
    -            "embeddings": [{
    -                "text_id": text_id,
    -                "instance_handle": "my-openai",
    -                "vector": vector,
    -                "vector_dim": 3072,
    -                "text": text,
    -                "metadata": metadata or {}
    -            }]
    -        }
    -    )
    -
    -def search_similar(query, count=5):
    -    """Search for similar documents using query text"""
    -    # Generate query embedding
    -    response = client.embeddings.create(
    -        model="text-embedding-3-large",
    -        input=query,
    -        dimensions=3072
    -    )
    -    query_vector = response.data[0].embedding
    -    
    -    # Search in dhamps-vdb
    -    result = requests.post(
    -        f"{DHAMPS_API}/v1/similars/alice/my-documents?count={count}",
    -        headers={
    -            "Authorization": f"Bearer {DHAMPS_KEY}",
    -            "Content-Type": "application/json"
    -        },
    -        json={"vector": query_vector}
    -    )
    -    return result.json()['results']
    -
    -def retrieve_context(doc_ids):
    -    """Retrieve full document content"""
    -    docs = []
    -    for doc_id in doc_ids:
    -        response = requests.get(
    -            f"{DHAMPS_API}/v1/embeddings/alice/my-documents/{doc_id}",
    -            headers={"Authorization": f"Bearer {DHAMPS_KEY}"}
    -        )
    -        docs.append(response.json())
    -    return docs
    -
    -def rag_query(query):
    -    """Complete RAG workflow"""
    -    # Search for similar documents
    -    similar = search_similar(query, count=3)
    -    
    -    # Retrieve context
    -    context_docs = retrieve_context([r['id'] for r in similar])
    -    context = "\n\n".join([doc['text'] for doc in context_docs])
    -    
    -    # Generate answer with LLM
    -    response = client.chat.completions.create(
    -        model="gpt-4",
    -        messages=[
    -            {"role": "system", "content": "Answer based on the provided context."},
    -            {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
    -        ]
    -    )
    -    
    -    return response.choices[0].message.content
    -
    -# Usage
    -embed_and_store("doc001", "The quick brown fox jumps over the lazy dog", 
    -                {"category": "animals"})
    -answer = rag_query("What animals are mentioned?")
    -print(answer)

    Best Practices#

    1. Batch Upload: Upload embeddings in batches of 100-1000 for better performance
    2. Use Metadata: Include rich metadata for better filtering and organization
    3. Set Thresholds: Use similarity thresholds (e.g., 0.7) to filter low-quality matches
    4. Cache Embeddings: Cache generated embeddings to avoid redundant API calls
    5. Monitor Dimensions: Ensure all embeddings use consistent dimensions (3072 for text-embedding-3-large)

    Advanced Features#

    Metadata Filtering#

    Exclude certain documents from search results using metadata filters:

    # Exclude documents from the same author as the query
    -curl -X GET "https://api.example.com/v1/similars/alice/my-documents/doc001?metadata_path=author&metadata_value=Alice" \
    -  -H "Authorization: Bearer alice_api_key"

    See the Metadata Filtering Guide for more details.

    Metadata Validation#

    Enforce consistent metadata structure using JSON Schema validation:

    curl -X PATCH "https://api.example.com/v1/projects/alice/my-documents" \
    -  -H "Authorization: Bearer alice_api_key" \
    -  -H "Content-Type: application/json" \
    -  -d '{
    -    "metadataScheme": "{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"category\":{\"type\":\"string\"}},\"required\":[\"author\"]}"
    -  }'

    See the Metadata Validation Guide for more details.

    Troubleshooting#

    Dimension Mismatch Error#

    {
    -  "title": "Bad Request",
    -  "status": 400,
    -  "detail": "dimension validation failed: vector dimension mismatch"
    -}

    Solution: Ensure the vector_dim field matches the dimensions configured in your LLM service instance.

    No Similar Results#

    If searches return no results, try:

    • Lowering the similarity threshold (e.g., from 0.8 to 0.5)
    • Increasing the count parameter
    • Verifying embeddings are uploaded correctly
    • Checking that query embeddings use the same model and dimensions
    \ No newline at end of file diff --git a/docs/public/icons/menu.svg b/docs/public/icons/menu.svg deleted file mode 100644 index a121a2a..0000000 --- a/docs/public/icons/menu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/icons/toc.svg b/docs/public/icons/toc.svg deleted file mode 100644 index ed75c4a..0000000 --- a/docs/public/icons/toc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/index.html b/docs/public/index.html deleted file mode 100644 index 85137d4..0000000 --- a/docs/public/index.html +++ /dev/null @@ -1,21 +0,0 @@ -dhamps-vdb Documentation | dhamps-vdb Documentation - -

    dhamps-vdb Documentation#

    Welcome to the documentation for dhamps-vdb, a vector database designed for Digital Humanities applications at the Max Planck Society initiative.

    What is dhamps-vdb?#

    dhamps-vdb is a PostgreSQL-backed vector database with pgvector support, providing a RESTful API for managing embeddings in Retrieval Augmented Generation (RAG) workflows. It offers multi-user support, project management, and flexible embedding configurations.

    Key Features#

    • Multi-user Support: Role-based access control (admin, owner, reader, editor)
    • Project Management: Organize embeddings into projects with sharing capabilities
    • LLM Service Management: Flexible service definitions and instances with encrypted API keys
    • Metadata Support: JSON Schema validation and filtering in similarity search
    • PostgreSQL Backend: Reliable storage with pgvector extension
    • RESTful API: OpenAPI-documented endpoints
    • Docker Ready: Easy deployment with Docker Compose

    Getting Help#

    Quick Example#

    # Start the service with Docker
    -./docker-setup.sh
    -docker-compose up -d
    -
    -# Create a user
    -curl -X POST http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer YOUR_ADMIN_KEY" \
    -  -H "Content-Type: application/json" \
    -  -d '{"user_handle": "alice", "name": "Alice Smith"}'
    -
    -# Create a project and start working with embeddings
    -# See the Getting Started guide for a complete walkthrough

    Ready to get started? Head over to the Installation Guide.

    \ No newline at end of file diff --git a/docs/public/index.xml b/docs/public/index.xml deleted file mode 100644 index a61f35a..0000000 --- a/docs/public/index.xml +++ /dev/null @@ -1,959 +0,0 @@ -dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/Recent content on dhamps-vdb DocumentationHugoen-usArchitecturehttps://mpilhlt.github.io/dhamps-vdb/concepts/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/<h1 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h1> -<p>dhamps-vdb is a vector database API designed for RAG (Retrieval Augmented Generation) workflows in Digital Humanities research.</p> -<h2 id="system-overview">System Overview<a class="anchor" href="#system-overview">#</a></h2> -<pre tabindex="0"><code>┌─────────────┐ -│ Client │ -│ Application │ -└──────┬──────┘ - │ HTTP/REST - │ -┌──────▼──────────────────────────┐ -│ dhamps-vdb API Server │ -│ ┌──────────────────────────┐ │ -│ │ Authentication Layer │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ Request Handlers │ │ -│ │ (Users, Projects, etc) │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ Validation Layer │ │ -│ │ (Dimensions, Metadata) │ │ -│ └────────┬─────────────────┘ │ -│ ┌────────▼─────────────────┐ │ -│ │ SQLC Queries │ │ -│ │ (Type-safe SQL) │ │ -│ └────────┬─────────────────┘ │ -└───────────┼──────────────────────┘ - │ - ┌───────▼──────────────┐ - │ PostgreSQL + 16 │ - │ with pgvector 0.7 │ - │ │ - │ ┌────────────────┐ │ - │ │ Vector Index │ │ - │ │ (HNSW/IVFFlat) │ │ - │ └────────────────┘ │ - └──────────────────────┘</code></pre><h2 id="core-components">Core Components<a class="anchor" href="#core-components">#</a></h2> -<h3 id="api-layer">API Layer<a class="anchor" href="#api-layer">#</a></h3> -<p>Built with <a href="https://huma.rocks/">Huma</a> framework on top of Go&rsquo;s <code>http.ServeMux</code>:</p>Authenticationhttps://mpilhlt.github.io/dhamps-vdb/api/authentication/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/authentication/<h1 id="api-authentication">API Authentication<a class="anchor" href="#api-authentication">#</a></h1> -<p>All API requests (except public project read operations) require authentication using API keys passed in the <code>Authorization</code> header with a <code>Bearer</code> prefix.</p> -<h2 id="authentication-method">Authentication Method<a class="anchor" href="#authentication-method">#</a></h2> -<p>Include your API key in the <code>Authorization</code> header of every request:</p> -<pre tabindex="0"><code>Authorization: Bearer your_api_key_here</code></pre><h2 id="api-key-types">API Key Types<a class="anchor" href="#api-key-types">#</a></h2> -<h3 id="admin-api-key">Admin API Key<a class="anchor" href="#admin-api-key">#</a></h3> -<ul> -<li>Full access to all API endpoints and resources</li> -<li>Can create and manage users</li> -<li>Can access all projects and resources across all users</li> -<li>Required for administrative operations</li> -<li>Set via <code>ADMIN_KEY</code> environment variable</li> -</ul> -<p><strong>Admin-only operations:</strong></p>Configuration Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/configuration/<h1 id="configuration-reference">Configuration Reference<a class="anchor" href="#configuration-reference">#</a></h1> -<p>Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb is configured through a combination of:</p> -<ol> -<li><strong>Environment variables</strong> (recommended)</li> -<li><strong>Command-line flags</strong> (overrides environment variables)</li> -<li><strong><code>.env</code> files</strong> (for Docker and local development)</li> -</ol> -<p>Configuration is loaded in the following priority order (highest to lowest):</p> -<ol> -<li>Command-line flags</li> -<li>Environment variables</li> -<li><code>.env</code> file values</li> -<li>Default values from <code>options.go</code></li> -</ol> -<h2 id="configuration-options">Configuration Options<a class="anchor" href="#configuration-options">#</a></h2> -<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> -<p>Options for controlling the API service behavior.</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/deployment/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> -<p>This guide covers production-focused Docker deployment for dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>For detailed Docker setup instructions, see <a href="../../getting-started/docker/">Getting Started with Docker</a>. This page focuses on production deployment considerations.</p> -<h2 id="production-deployment">Production Deployment<a class="anchor" href="#production-deployment">#</a></h2> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<ul> -<li>Docker Engine 20.10+</li> -<li>Docker Compose 2.0+ (or docker-compose 1.29+)</li> -<li>PostgreSQL 11+ with pgvector extension (included in compose setup)</li> -</ul> -<h3 id="quick-production-setup">Quick Production Setup<a class="anchor" href="#quick-production-setup">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate secure keys</span> -</span></span><span style="display:flex;"><span>./docker-setup.sh -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Review and customize .env</span> -</span></span><span style="display:flex;"><span>nano .env -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Deploy</span> -</span></span><span style="display:flex;"><span>docker-compose up -d</span></span></code></pre></div><h2 id="production-considerations">Production Considerations<a class="anchor" href="#production-considerations">#</a></h2> -<h3 id="use-reverse-proxy">Use Reverse Proxy<a class="anchor" href="#use-reverse-proxy">#</a></h3> -<p>Always run behind a reverse proxy (nginx, Traefik, Caddy) for:</p>Installationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/installation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/<h1 id="installation">Installation<a class="anchor" href="#installation">#</a></h1> -<p>Install dhamps-vdb by compiling from source.</p> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li><strong>Go 1.21 or later</strong></li> -<li><strong>PostgreSQL 11+</strong> with pgvector extension</li> -<li><strong>sqlc</strong> for code generation</li> -</ul> -<h2 id="quick-install">Quick Install<a class="anchor" href="#quick-install">#</a></h2> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies and generate code</span> -</span></span><span style="display:flex;"><span>go get ./... -</span></span><span style="display:flex;"><span>sqlc generate --no-remote -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build the binary</span> -</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go</span></span></code></pre></div><h2 id="detailed-steps">Detailed Steps<a class="anchor" href="#detailed-steps">#</a></h2> -<h3 id="1-install-dependencies">1. Install Dependencies<a class="anchor" href="#1-install-dependencies">#</a></h3> -<p>Download all Go module dependencies:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get ./...</span></span></code></pre></div><h3 id="2-generate-database-code">2. Generate Database Code<a class="anchor" href="#2-generate-database-code">#</a></h3> -<p>Generate type-safe database queries using sqlc:</p>RAG Workflow Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/<h1 id="complete-rag-workflow-guide">Complete RAG Workflow Guide<a class="anchor" href="#complete-rag-workflow-guide">#</a></h1> -<p>This guide demonstrates a complete Retrieval Augmented Generation (RAG) workflow using dhamps-vdb as your vector database.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>A typical RAG workflow involves:</p> -<ol> -<li>Generate embeddings from your text content (using an external LLM service)</li> -<li>Upload embeddings to dhamps-vdb</li> -<li>Search for similar documents based on a query</li> -<li>Retrieve the relevant context</li> -<li>Use the context with an LLM to generate responses</li> -</ol> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li>Access to dhamps-vdb API with a valid API key</li> -<li>An external LLM service for generating embeddings (e.g., OpenAI, Cohere)</li> -<li>Text content you want to process</li> -</ul> -<h2 id="step-1-generate-embeddings-externally">Step 1: Generate Embeddings Externally<a class="anchor" href="#step-1-generate-embeddings-externally">#</a></h2> -<p>First, use your chosen LLM service to generate embeddings for your text content. Here&rsquo;s an example using OpenAI&rsquo;s API:</p>Testinghttps://mpilhlt.github.io/dhamps-vdb/development/testing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/testing/<h1 id="testing-guide">Testing Guide<a class="anchor" href="#testing-guide">#</a></h1> -<p>This guide covers how to run and write tests for dhamps-vdb.</p> -<h2 id="running-tests">Running Tests<a class="anchor" href="#running-tests">#</a></h2> -<p>dhamps-vdb uses integration tests that spin up real PostgreSQL containers using <a href="https://testcontainers.com/guides/getting-started-with-testcontainers-for-go/">testcontainers</a>. This approach ensures tests run against actual database instances with pgvector support.</p> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<p><strong>Using Podman (Recommended for Linux):</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start podman socket</span> -</span></span><span style="display:flex;"><span>systemctl --user start podman.socket -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Export DOCKER_HOST for testcontainers</span> -</span></span><span style="display:flex;"><span>export DOCKER_HOST<span style="color:#f92672">=</span>unix://$XDG_RUNTIME_DIR/podman/podman.sock</span></span></code></pre></div><p><strong>Using Docker:</strong></p> -<p>Testcontainers works with Docker out of the box. Ensure Docker daemon is running.</p>Usershttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/<h1 id="users-endpoint">Users Endpoint<a class="anchor" href="#users-endpoint">#</a></h1> -<p>Manage user accounts and API keys. User creation is admin-only, but users can manage their own account information.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-all-users">List All Users<a class="anchor" href="#list-all-users">#</a></h3> -<p>Get a list of all registered user handles.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/users</code></p> -<p><strong>Authentication:</strong> Admin only</p> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/users&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer admin_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;users&#34;</span>: [<span style="color:#e6db74">&#34;alice&#34;</span>, <span style="color:#e6db74">&#34;bob&#34;</span>, <span style="color:#e6db74">&#34;charlie&#34;</span>] -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> -<h3 id="create-user">Create User<a class="anchor" href="#create-user">#</a></h3> -<p>Register a new user and generate their API key.</p> -<p><strong>Endpoint:</strong> <code>POST /v1/users</code></p> -<p><strong>Authentication:</strong> Admin only</p> -<p><strong>Request Body:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Doe&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Parameters:</strong></p>Configurationhttps://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/<h1 id="configuration">Configuration<a class="anchor" href="#configuration">#</a></h1> -<p>Configure dhamps-vdb using environment variables or command-line options.</p> -<h2 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h2> -<p>All configuration can be set via environment variables. Use a <code>.env</code> file to keep sensitive information secure.</p> -<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_DEBUG</code></td> - <td>Enable debug logging</td> - <td><code>true</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_HOST</code></td> - <td>Hostname to listen on</td> - <td><code>localhost</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_PORT</code></td> - <td>Port to listen on</td> - <td><code>8880</code></td> - <td>No</td> - </tr> - </tbody> -</table> -<h3 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_DBHOST</code></td> - <td>Database hostname</td> - <td><code>localhost</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBPORT</code></td> - <td>Database port</td> - <td><code>5432</code></td> - <td>No</td> - </tr> - <tr> - <td><code>SERVICE_DBUSER</code></td> - <td>Database username</td> - <td><code>postgres</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBPASSWORD</code></td> - <td>Database password</td> - <td><code>password</code></td> - <td>Yes</td> - </tr> - <tr> - <td><code>SERVICE_DBNAME</code></td> - <td>Database name</td> - <td><code>postgres</code></td> - <td>Yes</td> - </tr> - </tbody> -</table> -<h3 id="security-configuration">Security Configuration<a class="anchor" href="#security-configuration">#</a></h3> -<table> - <thead> - <tr> - <th>Variable</th> - <th>Description</th> - <th>Default</th> - <th>Required</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>SERVICE_ADMINKEY</code></td> - <td>Admin API key for administrative operations</td> - <td>-</td> - <td>Yes</td> - </tr> - <tr> - <td><code>ENCRYPTION_KEY</code></td> - <td>Encryption key for API keys (32+ characters)</td> - <td>-</td> - <td>Yes</td> - </tr> - </tbody> -</table> -<h2 id="configuration-file">Configuration File<a class="anchor" href="#configuration-file">#</a></h2> -<p>Create a <code>.env</code> file in the project root:</p>Contributinghttps://mpilhlt.github.io/dhamps-vdb/development/contributing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/contributing/<h1 id="contributing-guide">Contributing Guide<a class="anchor" href="#contributing-guide">#</a></h1> -<p>Thank you for your interest in contributing to dhamps-vdb! This guide will help you get started.</p> -<h2 id="development-setup">Development Setup<a class="anchor" href="#development-setup">#</a></h2> -<h3 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h3> -<ul> -<li><strong>Go 1.21+</strong>: <a href="https://go.dev/dl/">Download Go</a></li> -<li><strong>PostgreSQL 16+</strong>: With pgvector extension</li> -<li><strong>sqlc</strong>: For generating type-safe database code</li> -<li><strong>Docker/Podman</strong>: For running tests</li> -<li><strong>Git</strong>: For version control</li> -</ul> -<h3 id="clone-and-build">Clone and Build<a class="anchor" href="#clone-and-build">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies</span> -</span></span><span style="display:flex;"><span>go get ./... -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Generate sqlc code</span> -</span></span><span style="display:flex;"><span>sqlc generate --no-remote -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Build application</span> -</span></span><span style="display:flex;"><span>go build -o build/dhamps-vdb main.go -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Or run directly</span> -</span></span><span style="display:flex;"><span>go run main.go</span></span></code></pre></div><h3 id="environment-setup">Environment Setup<a class="anchor" href="#environment-setup">#</a></h3> -<p>Create a <code>.env</code> file for local development:</p>Database Schema Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/database-schema/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/<h1 id="database-schema-reference">Database Schema Reference<a class="anchor" href="#database-schema-reference">#</a></h1> -<p>Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in <code>internal/database/migrations/</code>.</p> -<p><strong>Key Features:</strong></p> -<ul> -<li>Vector embeddings stored as <code>halfvec</code> for efficient storage</li> -<li>HNSW indexes for fast approximate nearest neighbor search</li> -<li>Automatic timestamp tracking (<code>created_at</code>, <code>updated_at</code>)</li> -<li>Foreign key constraints with CASCADE deletion</li> -<li>Role-based access control through association tables</li> -<li>Multi-tenancy support (user-owned resources)</li> -</ul> -<h2 id="schema-migrations">Schema Migrations<a class="anchor" href="#schema-migrations">#</a></h2> -<p>Current schema version is defined by 4 migration files:</p>Database Setuphttps://mpilhlt.github.io/dhamps-vdb/deployment/database/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/database/<h1 id="database-setup">Database Setup<a class="anchor" href="#database-setup">#</a></h1> -<p>dhamps-vdb requires PostgreSQL 11 or later with the pgvector extension.</p> -<h2 id="requirements">Requirements<a class="anchor" href="#requirements">#</a></h2> -<ul> -<li><strong>PostgreSQL</strong>: Version 11 or higher</li> -<li><strong>pgvector</strong>: Extension for vector similarity search</li> -<li><strong>Storage</strong>: Depends on your embeddings volume (estimate: 4 bytes × dimensions × embeddings count)</li> -</ul> -<h2 id="installing-postgresql-with-pgvector">Installing PostgreSQL with pgvector<a class="anchor" href="#installing-postgresql-with-pgvector">#</a></h2> -<h3 id="using-docker-recommended">Using Docker (Recommended)<a class="anchor" href="#using-docker-recommended">#</a></h3> -<p>The easiest way to get PostgreSQL with pgvector:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --name postgres-pgvector <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -p 5432:5432 <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>secure_password <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -v postgres_data:/var/lib/postgresql/data <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> pgvector/pgvector:0.7.4-pg16</span></span></code></pre></div><h3 id="on-ubuntudebian">On Ubuntu/Debian<a class="anchor" href="#on-ubuntudebian">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Add PostgreSQL APT repository</span> -</span></span><span style="display:flex;"><span>sudo apt install curl ca-certificates -</span></span><span style="display:flex;"><span>sudo install -d /usr/share/postgresql-common/pgdg -</span></span><span style="display:flex;"><span>sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> https://www.postgresql.org/media/keys/ACCC4CF8.asc -</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> https://apt.postgresql.org/pub/repos/apt </span><span style="color:#66d9ef">$(</span>lsb_release -cs<span style="color:#66d9ef">)</span><span style="color:#e6db74">-pgdg main&#34;</span> | <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> sudo tee /etc/apt/sources.list.d/pgdg.list -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> -</span></span><span style="display:flex;"><span>sudo apt update -</span></span><span style="display:flex;"><span>sudo apt install postgresql-16 postgresql-contrib-16 -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector</span> -</span></span><span style="display:flex;"><span>sudo apt install postgresql-16-pgvector</span></span></code></pre></div><h3 id="on-macos">On macOS<a class="anchor" href="#on-macos">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Using Homebrew</span> -</span></span><span style="display:flex;"><span>brew install postgresql@16 -</span></span><span style="display:flex;"><span>brew install pgvector -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start PostgreSQL</span> -</span></span><span style="display:flex;"><span>brew services start postgresql@16</span></span></code></pre></div><h3 id="on-rhelcentosfedora">On RHEL/CentOS/Fedora<a class="anchor" href="#on-rhelcentosfedora">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install PostgreSQL</span> -</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-server postgresql16-contrib -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install pgvector (build from source)</span> -</span></span><span style="display:flex;"><span>sudo dnf install postgresql16-devel git gcc make -</span></span><span style="display:flex;"><span>git clone https://github.com/pgvector/pgvector.git -</span></span><span style="display:flex;"><span>cd pgvector -</span></span><span style="display:flex;"><span>make -</span></span><span style="display:flex;"><span>sudo make install PG_CONFIG<span style="color:#f92672">=</span>/usr/pgsql-16/bin/pg_config</span></span></code></pre></div><h2 id="database-configuration">Database Configuration<a class="anchor" href="#database-configuration">#</a></h2> -<h3 id="step-1-create-database">Step 1: Create Database<a class="anchor" href="#step-1-create-database">#</a></h3> -<p>Connect to PostgreSQL as superuser:</p>Docker Deploymenthttps://mpilhlt.github.io/dhamps-vdb/getting-started/docker/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/<h1 id="docker-deployment">Docker Deployment<a class="anchor" href="#docker-deployment">#</a></h1> -<p>Deploy dhamps-vdb using Docker containers. This is the recommended approach for most users.</p> -<h2 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h2> -<p>The fastest way to get dhamps-vdb running with Docker:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Clone the repository</span> -</span></span><span style="display:flex;"><span>git clone https://github.com/mpilhlt/dhamps-vdb.git -</span></span><span style="display:flex;"><span>cd dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Run automated setup (generates secure keys)</span> -</span></span><span style="display:flex;"><span>./docker-setup.sh -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start services with docker-compose</span> -</span></span><span style="display:flex;"><span>docker-compose up -d -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Check logs</span> -</span></span><span style="display:flex;"><span>docker-compose logs -f dhamps-vdb -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#75715e"># Access the API</span> -</span></span><span style="display:flex;"><span>curl http://localhost:8880/docs</span></span></code></pre></div><h2 id="whats-included">What&rsquo;s Included<a class="anchor" href="#whats-included">#</a></h2> -<p>The Docker Compose setup includes:</p>Project Sharing Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/<h1 id="project-sharing-guide">Project Sharing Guide<a class="anchor" href="#project-sharing-guide">#</a></h1> -<p>This guide explains how to share projects with specific users for collaborative work in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Project sharing allows you to grant other users access to your projects with different permission levels:</p> -<ul> -<li><strong>reader</strong>: Read-only access to embeddings and similar documents</li> -<li><strong>editor</strong>: Read and write access to embeddings (can add/modify/delete embeddings)</li> -</ul> -<p>Only the project owner can manage sharing settings and delete the project.</p> -<h2 id="sharing-during-project-creation">Sharing During Project Creation<a class="anchor" href="#sharing-during-project-creation">#</a></h2> -<p>You can specify users to share with when creating a new project using the <code>shared_with</code> field:</p>Projectshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/<h1 id="projects-endpoint">Projects Endpoint<a class="anchor" href="#projects-endpoint">#</a></h1> -<p>Manage vector database projects. Each project contains embeddings and must be associated with an LLM service instance.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-users-projects">List User&rsquo;s Projects<a class="anchor" href="#list-users-projects">#</a></h3> -<p>Get all projects owned by a user.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/projects/{username}</code></p> -<p><strong>Authentication:</strong> Admin, the user themselves, or users with shared access</p> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/projects/alice&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;projects&#34;</span>: [ -</span></span><span style="display:flex;"><span> { -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_id&#34;</span>: <span style="color:#ae81ff">1</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;project_handle&#34;</span>: <span style="color:#e6db74">&#34;research-docs&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Research document embeddings&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_id&#34;</span>: <span style="color:#ae81ff">5</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_owner&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;openai-large&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;public_read&#34;</span>: <span style="color:#66d9ef">false</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> -</span></span><span style="display:flex;"><span> } -</span></span><span style="display:flex;"><span> ] -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><hr> -<h3 id="create-project">Create Project<a class="anchor" href="#create-project">#</a></h3> -<p>Register a new project for a user.</p>Users and Authenticationhttps://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/<h1 id="users-and-authentication">Users and Authentication<a class="anchor" href="#users-and-authentication">#</a></h1> -<p>dhamps-vdb uses token-based authentication with API keys for all operations.</p> -<h2 id="user-model">User Model<a class="anchor" href="#user-model">#</a></h2> -<h3 id="user-properties">User Properties<a class="anchor" href="#user-properties">#</a></h3> -<ul> -<li><strong>user_handle</strong>: Unique identifier (3-20 characters, alphanumeric + underscore)</li> -<li><strong>name</strong>: Full name (optional)</li> -<li><strong>email</strong>: Email address (unique, required)</li> -<li><strong>vdb_key</strong>: API key (SHA-256 hash, 64 characters)</li> -<li><strong>created_at</strong>: Timestamp of creation</li> -<li><strong>updated_at</strong>: Timestamp of last update</li> -</ul> -<h3 id="special-users">Special Users<a class="anchor" href="#special-users">#</a></h3> -<p><strong><code>_system</code> User</strong></p> -<ul> -<li>Created automatically during database migration</li> -<li>Owns system-wide LLM service definitions</li> -<li>Cannot be used for authentication</li> -<li>Provides default configurations for all users</li> -</ul> -<h2 id="authentication-flow">Authentication Flow<a class="anchor" href="#authentication-flow">#</a></h2> -<h3 id="api-key-authentication">API Key Authentication<a class="anchor" href="#api-key-authentication">#</a></h3> -<p>All requests (except public endpoints) require authentication:</p>Architecturehttps://mpilhlt.github.io/dhamps-vdb/development/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/architecture/<h1 id="technical-architecture">Technical Architecture<a class="anchor" href="#technical-architecture">#</a></h1> -<p>This document provides a technical deep-dive into dhamps-vdb&rsquo;s architecture for developers who want to understand or modify the codebase.</p> -<h2 id="project-structure">Project Structure<a class="anchor" href="#project-structure">#</a></h2> -<pre tabindex="0"><code>dhamps-vdb/ -├── main.go # Application entry point -├── go.mod # Go module definition -├── go.sum # Dependency checksums -├── sqlc.yaml # sqlc configuration -├── template.env # Environment template -├── .env # Local config (gitignored) -│ -├── api/ -│ └── openapi.yml # OpenAPI spec (not actively maintained) -│ -├── internal/ # Internal packages (non-importable) -│ ├── auth/ # Authentication logic -│ │ └── authenticate.go # Bearer token validation -│ │ -│ ├── crypto/ # Encryption utilities -│ │ └── crypto.go # AES-256-GCM encryption -│ │ -│ ├── database/ # Database layer -│ │ ├── database.go # Connection pool management -│ │ ├── migrations.go # Migration runner -│ │ ├── db.go # Generated by sqlc -│ │ ├── models.go # Generated by sqlc -│ │ ├── queries.sql.go # Generated by sqlc -│ │ │ -│ │ ├── migrations/ # SQL migrations -│ │ │ ├── 001_create_initial_scheme.sql -│ │ │ ├── 002_create_emb_index.sql -│ │ │ ├── 003_add_public_read_flag.sql -│ │ │ ├── 004_refactor_llm_services_architecture.sql -│ │ │ ├── tern.conf.tpl # Template for tern -│ │ │ └── tern.conf # Generated (gitignored) -│ │ │ -│ │ └── queries/ # SQL queries for sqlc -│ │ └── queries.sql # All database queries -│ │ -│ ├── handlers/ # HTTP request handlers -│ │ ├── handlers.go # Common handler utilities -│ │ ├── users.go # User endpoints -│ │ ├── projects.go # Project endpoints -│ │ ├── llm_services.go # LLM service endpoints -│ │ ├── api_standards.go # API standard endpoints -│ │ ├── embeddings.go # Embedding endpoints -│ │ ├── similars.go # Similarity search endpoints -│ │ ├── admin.go # Admin endpoints -│ │ │ -│ │ └── *_test.go # Test files -│ │ ├── users_test.go -│ │ ├── projects_test.go -│ │ ├── projects_sharing_test.go -│ │ ├── embeddings_test.go -│ │ ├── llm_services_test.go -│ │ ├── editor_permissions_test.go -│ │ └── handlers_test.go -│ │ -│ └── models/ # Data models and options -│ ├── options.go # CLI/environment options -│ ├── users.go # User models -│ ├── projects.go # Project models -│ ├── instances.go # LLM instance models (new) -│ ├── api_standards.go # API standard models -│ ├── embeddings.go # Embedding models -│ ├── similars.go # Similarity search models -│ └── admin.go # Admin operation models -│ -├── testdata/ # Test fixtures -│ ├── postgres/ # PostgreSQL test data -│ │ ├── enable-vector.sql -│ │ └── users.yml -│ │ -│ └── *.json # JSON test fixtures -│ ├── valid_user.json -│ ├── valid_embeddings.json -│ ├── valid_api_standard_*.json -│ └── valid_llm_service_*.json -│ -└── docs/ # Documentation - ├── content/ # Hugo content - └── *.md # Additional docs</code></pre><h2 id="code-organization">Code Organization<a class="anchor" href="#code-organization">#</a></h2> -<h3 id="1-entry-point-maingo">1. Entry Point (<code>main.go</code>)<a class="anchor" href="#1-entry-point-maingo">#</a></h3> -<p>The application entry point handles:</p>Environment Variableshttps://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/<h1 id="environment-variables">Environment Variables<a class="anchor" href="#environment-variables">#</a></h1> -<p>Complete reference for all environment variables used by dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb is configured entirely through environment variables. These can be set:</p> -<ol> -<li><strong>In a <code>.env</code> file</strong> (recommended for Docker)</li> -<li><strong>As system environment variables</strong></li> -<li><strong>Via command-line flags</strong> (some variables only)</li> -</ol> -<h2 id="required-variables">Required Variables<a class="anchor" href="#required-variables">#</a></h2> -<p>These variables <strong>must</strong> be set for dhamps-vdb to function:</p> -<h3 id="service_adminkey">SERVICE_ADMINKEY<a class="anchor" href="#service_adminkey">#</a></h3> -<p>Admin API key for administrative operations.</p> -<ul> -<li><strong>Type:</strong> String</li> -<li><strong>Required:</strong> Yes</li> -<li><strong>Default:</strong> None</li> -<li><strong>Environment Variable:</strong> <code>SERVICE_ADMINKEY</code></li> -<li><strong>Command-line Flag:</strong> <code>--admin-key</code></li> -</ul> -<p><strong>Description:</strong> Master API key with full administrative privileges. Used to create users, manage global resources, and perform administrative operations.</p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/<h1 id="llm-services-endpoint">LLM Services Endpoint<a class="anchor" href="#llm-services-endpoint">#</a></h1> -<p>Manage LLM service instances and definitions. The system supports two types of LLM service resources:</p> -<ol> -<li><strong>Definitions</strong>: Reusable templates owned by <code>_system</code> or individual users</li> -<li><strong>Instances</strong>: User-specific configurations with API keys that reference definitions or stand alone</li> -</ol> -<h2 id="architecture-overview">Architecture Overview<a class="anchor" href="#architecture-overview">#</a></h2> -<pre tabindex="0"><code>definitions (templates) - └── owned by _system or users - └── contain: endpoint, model, dimensions, api_standard - └── no API keys - -instances (user-specific) - └── owned by individual users - └── reference a definition (optional) - └── contain encrypted API keys - └── can be shared with other users</code></pre><p>For complete details, see <a href="https://mpilhlt.github.io/dhamps-vdb/docs/LLM_SERVICE_REFACTORING.md">LLM Service Refactoring Documentation</a>.</p>Product Roadmaphttps://mpilhlt.github.io/dhamps-vdb/reference/roadmap/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/<h1 id="product-roadmap">Product Roadmap<a class="anchor" href="#product-roadmap">#</a></h1> -<p>Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.</p> -<h2 id="completed-features">Completed Features<a class="anchor" href="#completed-features">#</a></h2> -<h3 id="core-functionality">Core Functionality<a class="anchor" href="#core-functionality">#</a></h3> -<ul> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>User authentication &amp; restrictions on some API calls</strong></p> -<ul> -<li>Bearer token authentication</li> -<li>Role-based access control</li> -<li>Admin vs user permissions</li> -</ul> -</li> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>API versioning</strong></p> -<ul> -<li>Version 1 API with <code>/v1/</code> prefix</li> -<li>Backward compatibility support</li> -</ul> -</li> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>Better options handling</strong></p>Projectshttps://mpilhlt.github.io/dhamps-vdb/concepts/projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/projects/<h1 id="projects">Projects<a class="anchor" href="#projects">#</a></h1> -<p>Projects organize embeddings and define their configuration, including LLM service instances and optional metadata validation.</p> -<h2 id="what-is-a-project">What is a Project?<a class="anchor" href="#what-is-a-project">#</a></h2> -<p>A project is a collection of document embeddings that share:</p> -<ul> -<li>A single LLM service instance (embedding configuration)</li> -<li>Optional metadata schema for validation</li> -<li>Access control (ownership and sharing)</li> -<li>Consistent vector dimensions</li> -</ul> -<h2 id="project-properties">Project Properties<a class="anchor" href="#project-properties">#</a></h2> -<h3 id="core-fields">Core Fields<a class="anchor" href="#core-fields">#</a></h3> -<ul> -<li><strong>project_handle</strong>: Unique identifier within owner&rsquo;s namespace (3-20 characters)</li> -<li><strong>owner</strong>: User who owns the project</li> -<li><strong>description</strong>: Human-readable project description</li> -<li><strong>instance_id</strong>: Reference to LLM service instance (required, 1:1 relationship)</li> -<li><strong>metadataScheme</strong>: Optional JSON Schema for metadata validation</li> -<li><strong>public_read</strong>: Boolean flag for public read access</li> -<li><strong>created_at</strong>: Creation timestamp</li> -<li><strong>updated_at</strong>: Last modification timestamp</li> -</ul> -<h3 id="unique-constraints">Unique Constraints<a class="anchor" href="#unique-constraints">#</a></h3> -<p>Projects are uniquely identified by <code>(owner, project_handle)</code>:</p>Public Projects Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/public-projects/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/<h1 id="public-projects-guide">Public Projects Guide<a class="anchor" href="#public-projects-guide">#</a></h1> -<p>This guide explains how to make projects publicly accessible, allowing anyone to read embeddings and search for similar documents without authentication.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Projects can be configured to allow unauthenticated (public) read access by setting the <code>public_read</code> field to <code>true</code>. This is useful for:</p> -<ul> -<li>Open datasets and research data</li> -<li>Public APIs and services</li> -<li>Shared knowledge bases</li> -<li>Educational resources</li> -</ul> -<p><strong>Important:</strong> Public access only applies to read operations. Write operations (creating, updating, or deleting embeddings) always require authentication.</p>Quick Starthttps://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/<h1 id="quick-start">Quick Start<a class="anchor" href="#quick-start">#</a></h1> -<p>Complete walkthrough from installation to searching similar documents using curl.</p> -<h2 id="prerequisites">Prerequisites<a class="anchor" href="#prerequisites">#</a></h2> -<ul> -<li>dhamps-vdb installed and running</li> -<li>Admin API key configured</li> -<li>PostgreSQL with pgvector ready</li> -</ul> -<h2 id="1-create-a-user">1. Create a User<a class="anchor" href="#1-create-a-user">#</a></h2> -<p>Create a new user with the admin API key:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;alice&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Alice Smith&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;alice@example.com&#34; -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p><strong>Response:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;user_handle&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Alice Smith&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;email&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vdb_key&#34;</span>: <span style="color:#e6db74">&#34;024v2013621509245f2e24...&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;created_at&#34;</span>: <span style="color:#e6db74">&#34;2024-01-15T10:30:00Z&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Save the <code>vdb_key</code></strong> - it cannot be recovered later.</p>API Standardshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/<h1 id="api-standards-endpoint">API Standards Endpoint<a class="anchor" href="#api-standards-endpoint">#</a></h1> -<p>Manage API standard definitions that specify how to authenticate with different LLM service providers. API standards define the authentication mechanism (Bearer token, API key header, etc.) used by LLM service instances.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>API standards are referenced by LLM service instances to determine how to authenticate API requests. Examples include:</p> -<ul> -<li><strong>OpenAI</strong>: Bearer token in <code>Authorization</code> header</li> -<li><strong>Cohere</strong>: API key in <code>Authorization</code> header with <code>Bearer</code> prefix</li> -<li><strong>Google Gemini</strong>: API key as query parameter</li> -<li><strong>Ollama</strong>: No authentication required</li> -</ul> -<p>Pre-seeded standards are available for common providers. See <a href="https://github.com/mpilhlt/dhamps-vdb/tree/main/testdata">testdata/valid_api_standard_*.json</a> for examples.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/<h1 id="embeddings">Embeddings<a class="anchor" href="#embeddings">#</a></h1> -<p>Embeddings are vector representations of text stored in dhamps-vdb for similarity search and retrieval.</p> -<h2 id="what-are-embeddings">What are Embeddings?<a class="anchor" href="#what-are-embeddings">#</a></h2> -<p>Embeddings are numerical representations (vectors) of text that capture semantic meaning:</p> -<ul> -<li><strong>Vector</strong>: Array of floating-point numbers (e.g., 1536 or 3072 dimensions)</li> -<li><strong>Dimensions</strong>: Fixed length determined by LLM model</li> -<li><strong>Similarity</strong>: Vectors of similar text are close in vector space</li> -<li><strong>Purpose</strong>: Enable semantic search and retrieval</li> -</ul> -<h2 id="embedding-structure">Embedding Structure<a class="anchor" href="#embedding-structure">#</a></h2> -<h3 id="required-fields">Required Fields<a class="anchor" href="#required-fields">#</a></h3> -<ul> -<li><strong>text_id</strong>: Unique identifier for the document (max 300 characters)</li> -<li><strong>instance_handle</strong>: LLM service instance that generated the embedding</li> -<li><strong>vector</strong>: Array of float32 values (embedding vector)</li> -<li><strong>vector_dim</strong>: Declared dimension count (must match vector length)</li> -</ul> -<h3 id="optional-fields">Optional Fields<a class="anchor" href="#optional-fields">#</a></h3> -<ul> -<li><strong>text</strong>: Original text content (for reference)</li> -<li><strong>metadata</strong>: Structured JSON data about the document</li> -</ul> -<h3 id="example">Example<a class="anchor" href="#example">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc-123&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;text&#34;</span>: <span style="color:#e6db74">&#34;Introduction to machine learning concepts&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector&#34;</span>: [<span style="color:#ae81ff">0.023</span>, <span style="color:#ae81ff">-0.015</span>, <span style="color:#ae81ff">0.087</span>, <span style="color:#960050;background-color:#1e0010">...</span>, <span style="color:#ae81ff">0.042</span>], -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;metadata&#34;</span>: { -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;ML Introduction&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">2024</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;category&#34;</span>: <span style="color:#e6db74">&#34;tutorial&#34;</span> -</span></span><span style="display:flex;"><span> } -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h2 id="creating-embeddings">Creating Embeddings<a class="anchor" href="#creating-embeddings">#</a></h2> -<h3 id="single-embedding">Single Embedding<a class="anchor" href="#single-embedding">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>0.1, 0.2, ..., 0.3<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: 3072, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;metadata&#34;</span>: <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;Alice&#34;</span><span style="color:#f92672">}</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><h3 id="batch-upload">Batch Upload<a class="anchor" href="#batch-upload">#</a></h3> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>POST /v1/embeddings/alice/research-docs -</span></span><span style="display:flex;"><span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;embeddings&#34;</span>: <span style="color:#f92672">[</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc1&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;text_id&#34;</span>: <span style="color:#e6db74">&#34;doc2&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;instance_handle&#34;</span>: <span style="color:#e6db74">&#34;my-openai&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector&#34;</span>: <span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>, -</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;vector_dim&#34;</span>: <span style="color:#ae81ff">3072</span> -</span></span><span style="display:flex;"><span> <span style="color:#f92672">}</span>, -</span></span><span style="display:flex;"><span> ... -</span></span><span style="display:flex;"><span> <span style="color:#f92672">]</span> -</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code></pre></div><p><strong>Batch upload tips:</strong></p>First Projecthttps://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/<h1 id="first-project">First Project<a class="anchor" href="#first-project">#</a></h1> -<p>Step-by-step guide to creating your first complete project in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>This guide walks you through creating a complete RAG (Retrieval Augmented Generation) workflow:</p> -<ol> -<li>Set up authentication</li> -<li>Configure an LLM service</li> -<li>Create a project with metadata validation</li> -<li>Upload document embeddings</li> -<li>Search for similar documents</li> -<li>Share your project with collaborators</li> -</ol> -<h2 id="step-1-authentication-setup">Step 1: Authentication Setup<a class="anchor" href="#step-1-authentication-setup">#</a></h2> -<h3 id="get-your-api-key">Get Your API Key<a class="anchor" href="#get-your-api-key">#</a></h3> -<p>If you&rsquo;re an admin, create your first user:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X POST http://localhost:8880/v1/users <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer YOUR_ADMIN_KEY&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -d <span style="color:#e6db74">&#39;{ -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;user_handle&#34;: &#34;researcher1&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;name&#34;: &#34;Research User&#34;, -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> &#34;email&#34;: &#34;researcher@example.com&#34; -</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }&#39;</span></span></span></code></pre></div><p>Save the returned <code>vdb_key</code> to a variable:</p>Ownership Transfer Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/<h1 id="ownership-transfer-guide">Ownership Transfer Guide<a class="anchor" href="#ownership-transfer-guide">#</a></h1> -<p>This guide explains how to transfer project ownership between users in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Project ownership transfer allows you to reassign full control of a project from one user to another. This is useful when:</p> -<ul> -<li>A project maintainer is leaving and wants to hand over control</li> -<li>Organizational changes require reassigning project ownership</li> -<li>Consolidating projects under a different user account</li> -<li>Transferring stewardship of research data to a new PI</li> -</ul> -<h2 id="important-constraints">Important Constraints<a class="anchor" href="#important-constraints">#</a></h2> -<p>Before transferring ownership, understand these constraints:</p>Performancehttps://mpilhlt.github.io/dhamps-vdb/development/performance/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/development/performance/<h1 id="performance-optimization-guide">Performance Optimization Guide<a class="anchor" href="#performance-optimization-guide">#</a></h1> -<p>This guide covers performance optimization strategies for dhamps-vdb, including query optimization, indexing, caching, and performance testing.</p> -<h2 id="query-optimization">Query Optimization<a class="anchor" href="#query-optimization">#</a></h2> -<h3 id="getallaccessibleinstances-query">GetAllAccessibleInstances Query<a class="anchor" href="#getallaccessibleinstances-query">#</a></h3> -<p><strong>Problem:</strong> The original implementation uses a LEFT JOIN with OR conditions, which can result in inefficient query execution.</p> -<p><strong>Current Implementation:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> instances.<span style="color:#f92672">*</span>, -</span></span><span style="display:flex;"><span> COALESCE(instances_shared_with.<span style="color:#66d9ef">role</span>, <span style="color:#e6db74">&#39;owner&#39;</span>) <span style="color:#66d9ef">as</span> <span style="color:#66d9ef">role</span>, -</span></span><span style="display:flex;"><span> (instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span>) <span style="color:#66d9ef">as</span> is_owner -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> instances -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LEFT</span> <span style="color:#66d9ef">JOIN</span> instances_shared_with -</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">ON</span> instances.instance_id <span style="color:#f92672">=</span> instances_shared_with.instance_id -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> -</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">OR</span> instances_shared_with.user_handle <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">1</span> -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> instances.<span style="color:#66d9ef">owner</span> <span style="color:#66d9ef">ASC</span>, instances.instance_handle <span style="color:#66d9ef">ASC</span> -</span></span><span style="display:flex;"><span><span style="color:#66d9ef">LIMIT</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">2</span> <span style="color:#66d9ef">OFFSET</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">3</span>;</span></span></code></pre></div><p><strong>Issue:</strong> The query planner may struggle to use indexes effectively with LEFT JOIN combined with OR conditions in the WHERE clause.</p>Security Best Practiceshttps://mpilhlt.github.io/dhamps-vdb/deployment/security/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/deployment/security/<h1 id="security-best-practices">Security Best Practices<a class="anchor" href="#security-best-practices">#</a></h1> -<p>Comprehensive guide for securing your dhamps-vdb production deployment.</p> -<h2 id="security-overview">Security Overview<a class="anchor" href="#security-overview">#</a></h2> -<p>dhamps-vdb handles sensitive data including embeddings, metadata, and API credentials. This guide covers essential security measures for production deployments.</p> -<h2 id="httpstls-configuration">HTTPS/TLS Configuration<a class="anchor" href="#httpstls-configuration">#</a></h2> -<h3 id="why-https-is-required">Why HTTPS is Required<a class="anchor" href="#why-https-is-required">#</a></h3> -<ul> -<li><strong>Encryption in transit</strong>: Protects API keys and data from interception</li> -<li><strong>Authentication</strong>: Verifies server identity</li> -<li><strong>Compliance</strong>: Required by most security standards</li> -</ul> -<h3 id="using-a-reverse-proxy">Using a Reverse Proxy<a class="anchor" href="#using-a-reverse-proxy">#</a></h3> -<p><strong>Never expose dhamps-vdb directly to the internet.</strong> Always use a reverse proxy with TLS termination.</p>Embeddingshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/<h1 id="embeddings-endpoint">Embeddings Endpoint<a class="anchor" href="#embeddings-endpoint">#</a></h1> -<p>Store and retrieve vector embeddings with associated text identifiers and metadata. Embeddings are organized within projects and validated against the project&rsquo;s LLM service instance dimensions.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="list-embeddings">List Embeddings<a class="anchor" href="#list-embeddings">#</a></h3> -<p>Get all embeddings for a project with pagination support.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/embeddings/{username}/{projectname}</code></p> -<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> -<p><strong>Query Parameters:</strong></p> -<ul> -<li><code>limit</code> (integer, default: 10, max: 200): Maximum number of results to return</li> -<li><code>offset</code> (integer, default: 0): Pagination offset</li> -</ul> -<p><strong>Example:</strong></p>LLM Serviceshttps://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/<h1 id="llm-services">LLM Services<a class="anchor" href="#llm-services">#</a></h1> -<p>LLM Services configure embedding generation, defining models, dimensions, and API access.</p> -<h2 id="architecture">Architecture<a class="anchor" href="#architecture">#</a></h2> -<p>dhamps-vdb separates LLM services into two concepts:</p> -<h3 id="llm-service-definitions">LLM Service Definitions<a class="anchor" href="#llm-service-definitions">#</a></h3> -<p>Reusable configuration templates owned by <code>_system</code> or users:</p> -<ul> -<li><strong>Purpose</strong>: Provide standard configurations</li> -<li><strong>Ownership</strong>: <code>_system</code> (global) or individual users</li> -<li><strong>Contents</strong>: Endpoint, model, dimensions, API standard</li> -<li><strong>API Keys</strong>: Not stored (templates only)</li> -<li><strong>Usage</strong>: Templates for creating instances</li> -</ul> -<h3 id="llm-service-instances">LLM Service Instances<a class="anchor" href="#llm-service-instances">#</a></h3> -<p>User-specific configurations with encrypted API keys:</p> -<ul> -<li><strong>Purpose</strong>: Actual service configurations users employ</li> -<li><strong>Ownership</strong>: Individual users</li> -<li><strong>Contents</strong>: Endpoint, model, dimensions, API key (encrypted)</li> -<li><strong>Sharing</strong>: Can be shared with other users</li> -<li><strong>Projects</strong>: Each project references exactly one instance</li> -</ul> -<h2 id="system-definitions">System Definitions<a class="anchor" href="#system-definitions">#</a></h2> -<h3 id="available-definitions">Available Definitions<a class="anchor" href="#available-definitions">#</a></h3> -<p>The <code>_system</code> user provides default definitions:</p>Metadata Validation Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/<h1 id="metadata-validation-guide">Metadata Validation Guide<a class="anchor" href="#metadata-validation-guide">#</a></h1> -<p>This guide explains how to use JSON Schema validation to ensure consistent metadata structure across your embeddings.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb supports optional metadata validation using JSON Schema. When you define a metadata schema for a project, the API automatically validates all embedding metadata against that schema, ensuring data quality and consistency.</p> -<p>Benefits:</p> -<ul> -<li>Enforce consistent metadata structure across all embeddings</li> -<li>Catch data entry errors early</li> -<li>Document expected metadata fields</li> -<li>Enable reliable metadata-based filtering</li> -</ul> -<h2 id="defining-a-metadata-schema">Defining a Metadata Schema<a class="anchor" href="#defining-a-metadata-schema">#</a></h2> -<h3 id="when-creating-a-project">When Creating a Project<a class="anchor" href="#when-creating-a-project">#</a></h3> -<p>Include a <code>metadataScheme</code> field with a valid JSON Schema when creating a project:</p>Metadata Filtering Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/<h1 id="metadata-filtering-guide">Metadata Filtering Guide<a class="anchor" href="#metadata-filtering-guide">#</a></h1> -<p>This guide explains how to use metadata filtering to exclude specific documents from similarity search results.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>When searching for similar documents, you may want to exclude results that share certain metadata values with your query. For example:</p> -<ul> -<li>Exclude documents from the same author when finding similar writing styles</li> -<li>Filter out documents from the same source when finding related content</li> -<li>Exclude documents with the same category when exploring diversity</li> -</ul> -<p>dhamps-vdb provides metadata filtering using query parameters that perform <strong>negative matching</strong> - they exclude documents where the metadata field matches the specified value.</p>Similarity Searchhttps://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/<h1 id="similarity-search">Similarity Search<a class="anchor" href="#similarity-search">#</a></h1> -<p>Find documents with similar semantic meaning using vector similarity.</p> -<h2 id="how-it-works">How it Works<a class="anchor" href="#how-it-works">#</a></h2> -<p>Similarity search compares embedding vectors using cosine distance:</p> -<ol> -<li><strong>Query vector</strong>: Either from stored embedding or raw vector</li> -<li><strong>Comparison</strong>: Calculate cosine similarity with all project embeddings</li> -<li><strong>Filtering</strong>: Apply threshold and metadata filters</li> -<li><strong>Ranking</strong>: Sort by similarity score (highest first)</li> -<li><strong>Return</strong>: Top N most similar documents</li> -</ol> -<h2 id="search-methods">Search Methods<a class="anchor" href="#search-methods">#</a></h2> -<h3 id="stored-document-search-get">Stored Document Search (GET)<a class="anchor" href="#stored-document-search-get">#</a></h3> -<p>Find documents similar to an already-stored embedding:</p>Similarshttps://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/<h1 id="similarity-search-endpoints">Similarity Search Endpoints<a class="anchor" href="#similarity-search-endpoints">#</a></h1> -<p>Find similar documents using vector similarity search. The API provides two methods: searching from stored embeddings or searching with raw vectors without storing them.</p> -<h2 id="endpoints">Endpoints<a class="anchor" href="#endpoints">#</a></h2> -<h3 id="get-similar-documents-from-stored-embeddings">GET Similar Documents (from stored embeddings)<a class="anchor" href="#get-similar-documents-from-stored-embeddings">#</a></h3> -<p>Find documents similar to an already-stored document by its text identifier.</p> -<p><strong>Endpoint:</strong> <code>GET /v1/similars/{username}/{projectname}/{identifier}</code></p> -<p><strong>Authentication:</strong> Admin, owner, authorized readers, or public if <code>public_read</code> is enabled</p> -<p><strong>Query Parameters:</strong></p> -<ul> -<li><code>count</code> (integer, optional, default: 10, max: 200): Number of similar documents to return</li> -<li><code>threshold</code> (float, optional, default: 0.5, range: 0-1): Minimum similarity score threshold</li> -<li><code>limit</code> (integer, optional, default: 10, max: 200): Maximum number of results to return (alias for <code>count</code>)</li> -<li><code>offset</code> (integer, optional, default: 0): Pagination offset</li> -<li><code>metadata_path</code> (string, optional): Metadata field path for filtering (must be used with <code>metadata_value</code>)</li> -<li><code>metadata_value</code> (string, optional): Metadata value to exclude from results (must be used with <code>metadata_path</code>)</li> -</ul> -<p><strong>Example - Basic search:</strong></p>Batch Operations Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/<h1 id="batch-operations-guide">Batch Operations Guide<a class="anchor" href="#batch-operations-guide">#</a></h1> -<p>This guide explains how to efficiently upload multiple embeddings, manage large datasets, and implement best practices for batch operations in dhamps-vdb.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>For production workloads and large datasets, efficient batch operations are essential. This guide covers:</p> -<ul> -<li>Uploading multiple embeddings in a single request</li> -<li>Pagination strategies for large result sets</li> -<li>Best practices for performance and reliability</li> -<li>Error handling in batch operations</li> -</ul> -<h2 id="batch-upload-basics">Batch Upload Basics<a class="anchor" href="#batch-upload-basics">#</a></h2> -<h3 id="single-request-with-multiple-embeddings">Single Request with Multiple Embeddings<a class="anchor" href="#single-request-with-multiple-embeddings">#</a></h3> -<p>Upload multiple embeddings in one API call using the <code>embeddings</code> array:</p>Metadatahttps://mpilhlt.github.io/dhamps-vdb/concepts/metadata/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/<h1 id="metadata">Metadata<a class="anchor" href="#metadata">#</a></h1> -<p>Structured JSON data attached to embeddings for organization, validation, and filtering.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>Metadata provides context and structure for your embeddings:</p> -<ul> -<li><strong>Organization</strong>: Categorize and group documents</li> -<li><strong>Filtering</strong>: Exclude documents in similarity searches</li> -<li><strong>Validation</strong>: Ensure consistent structure (optional)</li> -<li><strong>Context</strong>: Store additional document information</li> -</ul> -<h2 id="metadata-structure">Metadata Structure<a class="anchor" href="#metadata-structure">#</a></h2> -<h3 id="format">Format<a class="anchor" href="#format">#</a></h3> -<p>Metadata is JSON stored as JSONB in PostgreSQL:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;William Shakespeare&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Hamlet&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;year&#34;</span>: <span style="color:#ae81ff">1603</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;genre&#34;</span>: <span style="color:#e6db74">&#34;drama&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><h3 id="types">Types<a class="anchor" href="#types">#</a></h3> -<p>Supported JSON types:</p> -<ul> -<li><strong>String</strong>: <code>&quot;author&quot;: &quot;Shakespeare&quot;</code></li> -<li><strong>Number</strong>: <code>&quot;year&quot;: 1603</code></li> -<li><strong>Boolean</strong>: <code>&quot;published&quot;: true</code></li> -<li><strong>Array</strong>: <code>&quot;tags&quot;: [&quot;tragedy&quot;, &quot;revenge&quot;]</code></li> -<li><strong>Object</strong>: <code>&quot;author&quot;: {&quot;name&quot;: &quot;...&quot;, &quot;id&quot;: &quot;...&quot;}</code></li> -<li><strong>Null</strong>: <code>&quot;notes&quot;: null</code></li> -</ul> -<h3 id="nested-structure">Nested Structure<a class="anchor" href="#nested-structure">#</a></h3> -<p>Complex hierarchies are supported:</p>Query Parametershttps://mpilhlt.github.io/dhamps-vdb/api/query-parameters/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/<h1 id="query-parameters-reference">Query Parameters Reference<a class="anchor" href="#query-parameters-reference">#</a></h1> -<p>Comprehensive reference for query parameters used across API endpoints for pagination, filtering, and search configuration.</p> -<h2 id="pagination-parameters">Pagination Parameters<a class="anchor" href="#pagination-parameters">#</a></h2> -<h3 id="limit">limit<a class="anchor" href="#limit">#</a></h3> -<p>Maximum number of results to return in a single response.</p> -<p><strong>Type:</strong> Integer<br> -<strong>Default:</strong> 10<br> -<strong>Maximum:</strong> 200<br> -<strong>Minimum:</strong> 1</p> -<p><strong>Used by:</strong></p> -<ul> -<li><code>GET /v1/embeddings/{user}/{project}</code> - List embeddings</li> -<li><code>GET /v1/similars/{user}/{project}/{id}</code> - Similarity search</li> -<li><code>POST /v1/similars/{user}/{project}</code> - Raw vector search</li> -<li><code>GET /v1/projects/{user}</code> - List projects</li> -</ul> -<p><strong>Example:</strong></p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get 50 embeddings</span> -</span></span><span style="display:flex;"><span>curl -X GET <span style="color:#e6db74">&#34;https://api.example.com/v1/embeddings/alice/research-docs?limit=50&#34;</span> <span style="color:#ae81ff">\ -</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> -H <span style="color:#e6db74">&#34;Authorization: Bearer alice_api_key&#34;</span></span></span></code></pre></div><p><strong>Aliases:</strong></p>Instance Management Guidehttps://mpilhlt.github.io/dhamps-vdb/guides/instance-management/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/<h1 id="instance-management-guide">Instance Management Guide<a class="anchor" href="#instance-management-guide">#</a></h1> -<p>This guide explains how to create, configure, and share LLM service instances for generating and managing embeddings.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>LLM service instances define the configuration for connecting to embedding services (like OpenAI, Cohere, or Gemini). Each instance includes:</p> -<ul> -<li>API endpoint and credentials</li> -<li>Model name and version</li> -<li>Vector dimensions</li> -<li>API standard (protocol)</li> -</ul> -<p>Instances can be created from system templates, user-defined templates, or as standalone configurations. They can also be shared with other users for collaborative work.</p>PATCH Updateshttps://mpilhlt.github.io/dhamps-vdb/api/patch-updates/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/<h1 id="patch-method-for-partial-updates">PATCH Method for Partial Updates<a class="anchor" href="#patch-method-for-partial-updates">#</a></h1> -<p>The API supports PATCH requests for partial updates of resources. Instead of providing all resource fields (as required by PUT), you only need to include the fields you want to change.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>PATCH is automatically available for resources that support both GET and PUT operations. The PATCH endpoint:</p> -<ol> -<li>Retrieves the current resource state via GET</li> -<li>Merges your changes with the existing data</li> -<li>Applies the update via PUT</li> -</ol> -<p>This approach simplifies updates by eliminating the need to fetch, modify, and submit complete resource objects.</p>Error Handlinghttps://mpilhlt.github.io/dhamps-vdb/api/error-handling/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/api/error-handling/<h1 id="error-handling">Error Handling<a class="anchor" href="#error-handling">#</a></h1> -<p>The API uses standard HTTP status codes and returns structured error responses in JSON format for all error conditions.</p> -<h2 id="error-response-format">Error Response Format<a class="anchor" href="#error-response-format">#</a></h2> -<p>All error responses follow this structure:</p> -<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{ -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Error Title&#34;</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;status&#34;</span>: <span style="color:#ae81ff">400</span>, -</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;detail&#34;</span>: <span style="color:#e6db74">&#34;Detailed error message explaining what went wrong&#34;</span> -</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p><strong>Fields:</strong></p> -<ul> -<li><code>title</code> (string): Human-readable error title</li> -<li><code>status</code> (integer): HTTP status code</li> -<li><code>detail</code> (string): Detailed description of the error</li> -</ul> -<h2 id="http-status-codes">HTTP Status Codes<a class="anchor" href="#http-status-codes">#</a></h2> -<h3 id="2xx-success">2xx Success<a class="anchor" href="#2xx-success">#</a></h3> -<h4 id="200-ok">200 OK<a class="anchor" href="#200-ok">#</a></h4> -<p>Request succeeded. Response body contains requested data.</p> \ No newline at end of file diff --git a/docs/public/katex/auto-render.min.js b/docs/public/katex/auto-render.min.js deleted file mode 100644 index 32a7dd8..0000000 --- a/docs/public/katex/auto-render.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={757:function(t){t.exports=e}},n={};function r(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o={};r.d(o,{default:function(){return p}});var i=r(757),a=r.n(i);const l=function(e,t,n){let r=n,o=0;const i=e.length;for(;re.left.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"))).join("|")+")");for(;n=e.search(o),-1!==n;){n>0&&(r.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));const o=t.findIndex((t=>e.startsWith(t.left)));if(n=l(t[o].right,e,t[o].left.length),-1===n)break;const i=e.slice(0,n+t[o].right.length),a=s.test(i)?i:e.slice(t[o].left.length,n);r.push({type:"math",data:a,rawData:i,display:t[o].display}),e=e.slice(n+t[o].right.length)}return""!==e&&r.push({type:"text",data:e}),r};const c=function(e,t){const n=d(e,t.delimiters);if(1===n.length&&"text"===n[0].type)return null;const r=document.createDocumentFragment();for(let e=0;e-1===e.indexOf(" "+t+" ")))&&f(r,t)}}};var p=function(e,t){if(!e)throw new Error("No element provided to render");const n={};for(const e in t)t.hasOwnProperty(e)&&(n[e]=t[e]);n.delimiters=n.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\begin{equation}",right:"\\end{equation}",display:!0},{left:"\\begin{align}",right:"\\end{align}",display:!0},{left:"\\begin{alignat}",right:"\\end{alignat}",display:!0},{left:"\\begin{gather}",right:"\\end{gather}",display:!0},{left:"\\begin{CD}",right:"\\end{CD}",display:!0},{left:"\\[",right:"\\]",display:!0}],n.ignoredTags=n.ignoredTags||["script","noscript","style","textarea","pre","code","option"],n.ignoredClasses=n.ignoredClasses||[],n.errorCallback=n.errorCallback||console.error,n.macros=n.macros||{},f(e,n)};return o=o.default}()})); \ No newline at end of file diff --git a/docs/public/katex/fonts/KaTeX_AMS-Regular.ttf b/docs/public/katex/fonts/KaTeX_AMS-Regular.ttf deleted file mode 100644 index c6f9a5e7c03f9e64e9c7b4773a8e37ade8eaf406..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63632 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 diff --git a/docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 b/docs/public/katex/fonts/KaTeX_AMS-Regular.woff2 deleted file mode 100644 index 0acaaff03d4bb7606de02a827aeee338e5a86910..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28076 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 G2<`xUL{2yW diff --git a/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf deleted file mode 100644 index f522294ff0f3f8c52dfdaef7ebfaa06ebfcfaabf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12344 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 Mepdy)y#Y}F4=Hd9=l}o! diff --git a/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2 deleted file mode 100644 index 75344a1f98e37e2c631e178065854c3a81fb842f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6908 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 CFgb+) diff --git a/docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf b/docs/public/katex/fonts/KaTeX_Fraktur-Bold.ttf deleted file mode 100644 index 4e98259c3b54076d684bf3459baeaeae8dbce97a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19584 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 diff --git a/docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/docs/public/katex/fonts/KaTeX_Fraktur-Bold.woff2 deleted file mode 100644 index 395f28beac23c7b0f7f3a1e714bd8dac253dd3bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11348 zcmV-aEUVLZPew8T0RR9104!7h4gdfE08HQj04x0f0RR9100000000000000000000 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 Y{My=5Zj3WbM|mX<0#Lulu=APmKiR?A3IG5A diff --git a/docs/public/katex/fonts/KaTeX_Main-Bold.woff b/docs/public/katex/fonts/KaTeX_Main-Bold.woff deleted file mode 100644 index f38136ac1cc2dcdc9d9b10b8521487468b1f768c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29912 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 bnfbLfgSm6Day;iB;wah|00962|Nj6Fv8wea diff --git a/docs/public/katex/fonts/KaTeX_Main-Bold.woff2 b/docs/public/katex/fonts/KaTeX_Main-Bold.woff2 deleted file mode 100644 index ab2ad21da6fbe6c171bb869240954d0ead8f68fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25324 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 PaXk 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 diff --git a/docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff b/docs/public/katex/fonts/KaTeX_Main-BoldItalic.woff deleted file mode 100644 index 67807b0bd4f867853271f5917fb3adf377f93f53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19412 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 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.ttf b/docs/public/katex/fonts/KaTeX_Main-Italic.ttf deleted file mode 100644 index 0e9b0f354ad460202bba554359f5adcc8da666b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33580 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 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.woff b/docs/public/katex/fonts/KaTeX_Main-Italic.woff deleted file mode 100644 index 6f43b594b6c1d863a0e3f93b001f8dd503316464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19676 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 diff --git a/docs/public/katex/fonts/KaTeX_Main-Italic.woff2 b/docs/public/katex/fonts/KaTeX_Main-Italic.woff2 deleted file mode 100644 index b50920e138807f385d0b0359f4f0f09891f18406..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16988 zcmV(>K-j-`Pew8T0RR91076^<4gdfE0E4su073x(0RR9100000000000000000000 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 diff --git a/docs/public/katex/fonts/KaTeX_Main-Regular.ttf b/docs/public/katex/fonts/KaTeX_Main-Regular.ttf deleted file mode 100644 index dd45e1ed2e18b32c516d9b481ebed3cb8bffa711..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53580 zcmd442bd&Rc`n@NRIci-?&_|t>YUT0p3ptrljF|J##wFDMrl{lYJ<`$AR#0nAqkX0 zB*_AcWPEL|Ot6Fyw%{5tV8CQ!urb%h27>@|eYu1m8*T6Zo>M&=KoUHD{`)-t&g@Kg zRdv<(edo*JjF0$yKGS!HPw*Yux?^x;=`S{p`+QG+5JwMPdez~Rm4EvFoX_`^?ehsc zFTL@G9K9;u_W3?l!})!epFDciCG}Ic`g|WchMV}09=`r0j)#1{udKsw_2`v1U;ang zqqx`bO~kGc*cp6`!wRHLPmGDvmsI z*~kcup8C-U`BPl8>Lb3tqM!E#eQBTiv=h=P9qEfSTa6JXYEwln7OE8*aqz}_J=$!o z7UQvUjZiC0No_WsO9mo67A?{@M+#7xRgd8%o*f;Adap z7`erk{R?~jMllgDR&oQ=t)6u71r7nWvC}hx2H1A^4g$7)yG9gFg?0n5F_>%`Rl2Vk zS@6aqNKsMjF33eiW)uPv;nDW_Z*UBE0+PjwgdglPjrN%N)7~CY^oQv-@=?5!bvbYW zc`~TW7hP;eZ@5m@gX{wD@HrQlp^w#qxue_+?)KiMBp9)GK>h2_pSM9N-iiqZLd zfhqyNBy8S71ljPe(3JowQ+`SJr4k5AxI&T%er^Wa``V{JLq0-j#9Xz|4Rs5=j&G^x88+PKDM3+Xqqt5z`Sj zn{mbT9x>RH=o#8Lp45f9d{HGU5Gmc8nWti;Sa0+SGNqH6K>DW}&pJ7wIwBGhC6p3- zXK&xk0oPFLbrP8D8@Hs0lXaaeq3aCtpMnui9U5IZ5!DCl;feZOSc

    viU|OFj=e4 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

    Yqh7OdB% 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�q{iqW@P3>Beq0%EJjvF((%W5V$Nl;YoRM#4D5D7f{7MJE)%@L?;5S z6PC1FaW5(Zu6INvK30(rr!FvkQ^|w*&iOB7veje0>LOFfevf}sMWRpDM;gYmoGD5_ z%^E1-6#ZvOyiEe?)pil^>@|_p=$y!Xm}@%G+Uk8SfBMN2^%xoFDk$T?1&`4$z}=&> z;czh}pHI19t~J43jM?lZs0OQ?KWUGtV-BFbPI$d^ZNyK!AKNb4e;n~n)gfbgg z1h-}Tvnfcp70lIxF)=A!UuofhSZ#=r%fmdvLin%;Y_|rz%bYpQEjwSObjelZ;cTn@ zZiGYi%x!Bks7}D0#7?<nHc_Vha&q&>eHcmu52C2zzw&2SV3WaWC3Ov$8G4i_zf0xss)GiJ0G{ z7-kNa8dBrOlkNOr;>L?~TJn@9ffw^2+e*Wg%KWG3bdjo=OZS&dMmhKR#z9;YqTp;Z zqyQyaZ0PvMiHE(JIqE=krRT;qq$_3TgXJADXSIt}Hu|w>u8jG8deQUnmiU1CHTp=n zkW(rSRbx;QW)M#kg=m3QyeL4RVgQ-OJ!qe~e-V7ciAvID=ih1|{{+f6HOND)Js&x}6uys-%T>c;Lhs0BlqQd0}^buKWM07kCbAWn4zi zg{Br9k24l$ejcPaOt7F)L_UIWehbKf@2!f26(T31#+q*iJlSwn1cA5=-0L>A@&uXd z2(D}y-rZzM?8eQ=8H6~v+is38UmE!=2n5rNmOwd@{OF zno%~`vzyo=G`8vFLb=CAAoCrkr^$!#Ytomf=G6Z5ZEPY4`nK-jP%R}>+L=5EnOEvB zem+Lx=5RYT=eWaT24l6Yj*j(E5;h4(e!WdJghi8h|I=?8-Y`XU=P#+kR};#HFt z>KqEhE}L<}?LHgz`x}kt=tvD05$@ge{eb~H7e2Pv&##*%U-an&HUCfqsy6d=x}r*% zt(>uz-EV}vmVXV?z z9IaHfW_lRpsGREtHg-@0U!0U3iHDfa!mbp&?6fEcY=aRB_l~||%g!!9sN39UIvUKH znJ$J_E&9hM69vyH62n7mJZJRfTXuE=gsj|&iy{HvZDO(v@ngmvg4z!WYG;JbYjKvu zXGmRZwmvXcQ}>#!KfiQ83;Y1p4q5slMCjVNvKgnCeu_j1%fES{W%U zo1_*{L$LpTQOmu@;_(nb=guuJABC3^#ZW39yI(R?)v|1p3{v1aTCxdR_0gD++8~qj zk5Sjskx`Ns*(3=Y7T^!gtGlycMJ<5$*j9Xc!}*o?hUvIvRbKkOfHpb^r=>QRzO)Mu zuF5J8R4Ea67D;^;zA>?UWg`3-2|iYR_bb+77bQQ53)7>7zUQ= zyC&N*s`LvDe3Q^~ctt#lLGkD3pQ23rk!sVlu*?M^QYFhWRd$KulOSh?0k!U)0!mFi zjD!szC&Uefe#8ue@oldJ;((li-?o()X`?A8o|ckw;%9UDlb$o^tvWDrc_{SEzvy|s zv6B%DJ4|1Chebg%n0Slc&Np8gp^SR3+RB-<5&}Atf@sAn^_kBgmMx5b78mcBx+x9@ z;m9L{IjqsIQQtTSGc;U?$YZk8v1p`Hw(H3&q*1aoeAfnc<%OdF$Z7uhjnROdp3rt z8vaC3=1NPxYoWEN3Ll#Y5DP&nNwDa>I8;%ZVvb1j^C7EN*5fv(>mTSHv>3CFJ~YU5 zH>#Iw7G56m8jm#|vqn}@Rv)wQLEwbE&gIs`D%lgvSFBDrM7MO3x$S_BU=nB5gr(NY zH>x>;>23pbqM`tKfoNSJY_X-9mhz|st3`s*Z+xE4u^9{&SWGt82qqDE5D|wePDFkH zlu(@*HaHVYU51?6dv0q7M5HJdRWigzTYGU_1PQJ=eeslIs2HD0+2fn1><6{ej)R-9;636Fri}NzWNqt3IPiP)R?mVC%JeuFCr)mCeJ1RrKdApI$SJF_Z}r2J@*@8IBm zV+J3|j;2K{?K6Lp7xa@zvu&Y-1a)HY+#TB;XS3RaD-dnmqX2t^&b)(J+E<{1;*n64`!dk)s<$;F*cnH2(TEV_6Oub&Q^~uf<2M> zg#V&U6IDt~Qw-2Rq?N>?j$!GfzaNJCtdy&J(Z(}GkL#o{2M;xVbN4BHi{WzeoRc@U zFDZbDQ98Gqa8B`EjRrvDAz0?`7=sh|r06*tm6hHanQd{*Jv(Wr-b`qhR$D4K7N0~j z!u`cq8x5_iwQ;A&c3hqu+qdnq@zw1~jx4odi67hfJB@h$Dy%51Es>&b1pJ-jX+ zPeu&?S=HQl`}5osg?GQi5tsyXOv zUgH*gb%q;!?znD(1mWb>AB||$(;tQ}5vtXMyzW)<8W`Dp;l^xDcU*vmXjRpU0J-h{p+RpawOVoUGWk(-!Hj#Bvj>I!g}KZAO{AYGmV;T&8z)wy$9H zI?>Utv2H%L zzE5SjtI^<$Wa={EDO!sT>iGA1G zEhrgQbqh37oHwJ9^&m|_Wr8X>3V;p*=euLRG(GnE!~E!_il#y#ky@2xjg_7UPq63} z>m^xeh!VXQT$Em&I`|Sp5N4a88=f7W*e*yD5+_Job-5r7OvxSXNB9VM8dsK_V#Q7m zR|$Z?jVj9cQo=O7%lG4Fj{8A58l< zA$MmuW&(tr$O{=2IT<9Kv2Yrb{iYX6Anv>~?1n$dBr7L8;w z!&|lvi@#g9XwdTRXT7=gO=q4KPpmz?i0mQ-Nec+;K0%0ljBv$2Uw6eueQE6Rsx5bUU*i8D2w1d9%DKe98F=6zQ!G0M~kN39(*nI(h$ zZS4spndqA3<$eIr`R*5#iX%(ARxU{xyQjoj+0&k9)4?TwxA&gIv5K>9tzJd+F7Gz= zJ+ny{YiumD0ssx?<)QQqYt~(j;Y;PcT@HeEsYd+ykf=vhn^5vNpXS$^<;Mf_y=D78 zeYCkLrK}^AS^yuuO|!La&-Cssl}?YZ+TK?!<`!?Wr<-n@3Wz+egn00wEY^QG8xcNB=v-N!P+eenIzoJmt+udUw zf^~%i>o?qxPp7jh44Jo)Vxw&H>8M(^^W8;`#WPw36lj!NNVkJaY`?yrY?t zx+lYdf|;+}ymtHT#dfO3O|*--%{zAxI1@Tow z#Zp!5FQz~F`IfS~)x0bbEVa#9)28&NX`(5cn-fmp7TZ*1cRhdg<~vIn9l*52CG_sv zrOM{GJJc+_Z)AG3GRVL51=s!RSF9DA{G#Xcr~VGVByGTyA8ie`L6qeLpVoDmjMI)^o6|6;u59vwz%=;rsc?ZDG^12NPDC32phYj+~S1pLGpL!zOv9W5SC4tPl<_T7QloWeoWv z$(3O(EV%L$VOuYi+PX=;QY;?fEli4?31^g=3{WaYP8XLu;al!@+EU(Kw>V)N2y)za z@!FZCYcJksqxqFpi`TBccwfj4JGb2BrP`c(pWFNue2;mTM-U^ITaH0=iX7JFQ>pw~ zQ;#%0pG@Z0x~Ab+@+Z;D&iq7W^Gp4LZ&7=Is-Ao{0fYrPg6G%^baOLF@T}W{!s}ae z1ZBxVZ#K1v)*h6sN{a_G6yCg|N(|548J6F&ux96cLW-)(^^dE0$p_~9B8r*XP521j zs%2$d9fC;!qdb|SetvjYXH{*;ueB(L*D+$+{=TW#-34w8NSPkRyYE5Wk+T#&C$zp#L<nfTDxu3JZA2J2c=f(!h+ z22z9>Eswrt-TME^qsnvhl#u^+saf=Rpan}x-jt&xh`%rubWtCCBp%kouRZm>Dzz+H zU9ssmyQ&77PShCM@Uep|Re4^4N7Cs#rba08BuC)sV?)y+ha|QvI#5j`k4#;y@FqKg zlBJ>R+a~k)eB}#nqLW&XIinN!R>QGr_0@;|J*kJ|evz5d^NL24G7F9BuHSB0X(hq4 zEt?~WkG(IQ_KP(`ORgz}l0=V94;@Q$fWT|@NYiW8x+;&PqnRqE%Kk&IRV-f}O}`=J zzWLn|;M=Zo0j!PnVn@95rEhjauX~6ed0nj4ZAAd$S8p}iGsem7&7Z6k^)Hhg&)`ogHt4KmamiEGftu8A9V0hWf zX2Q`}cqX6msW~6wgfLRYWbHm_sANImnn|sm=;YI%I z_sd1e=Kj_qGDr!(o117_3ZPAkA`Xhyhzf1NxblFg64Y_=2)7*zI7ey`dDs{Zc@TyU z$eL7?^m%cDxrJ}3Rpz}Y#mK~{e38D%p~{^CUz0v$yK$O2@)d4q?z@;5Ecv`{f~M)h zf_T5M3D;;zEia^FL|ZI5`t0SZl@`|{e$s2A%Lm&=iV!LKI8GQZM%1+CwZ~p^-;qP; zyx`*D(QRwjUTOn`phxfN-*~x!>+Ah zukHwScHOm?FXkt2hcHHScWg6^D;{vM@telyA*>F;Fhsb}eLy2E)R(p4b5kzA0}yI4 zF&+?oE_(4&L0dSNO&z$+#&vU#+OIguGwuB7E6zsbt&$);cJC2m*f6eqzy%O=wQ{wj z^$X3n^qjPH1&%;5OjY!%S_M$X&Bv-Th%3^N^-+m+W;}UT*8XC{RoT?8kxv}Dlvs_g z94b}T_K#lzE7tap9Xce=8h?MyR{E0J*%z%j8|^zL^~lI4E%R(}tIk1f{0-OcU7tI6!&lIp``vp^UAs*jLVMo=3Wv4X3sBe`Zd$y^WURR#iu(Oo z$yGvee8p^A_PW*CnRanx#wJ$&QzZiqE%x-4MicyOgufK^#Evb;moA#!=jrOOvvd9A zy2dYZ{S;_#QLKONY0WJ3N3_tqR#3^eO1E7i^?>Er96k~XHC9M{fUgOI*Z4fo@YZL; zK~$vZKdfG}CLD$*f+(K<5I2EgQx!r->8Lxr&XEFhgFE^Z{)*xQa)^? zjkz~S3Jz;6&x$H^25CS6;rLf#)+WmCRfP8y(uUCDcvzPF2F>>ZlRn|wEw*}rg9&MA ztehAfs|9n?rf+zDE(!q9oQ=*qj2jQCc__RQf@x^uK@Bxa6LAXonHJO9{26;PSf@-0 zg-`*hs*ul#e>OS&77~KrqTJN~kx+{N_~b`Ea`4b0_z|Vzs$q!x@+vb7{U3k&k&hfY zcu>}2v-VN#b1*4mEcJ7s>pt2#8J5owEd;-XpKF7@MKo5EsSPsNE*4cdeIp0drn!&nU@oP)Y0$j~EMDwdy}GN&E!f{ZvJb%o$lxcDa_7@faP&ONstkOX zaV%C>udWu6Gx~u|C@yc;gU9>YO~Z~sCEJn?k{0fFf{0|Yd_{-%8XGw&2P9ivej`Oxt& z0K!G1@Zjh0v(Ozvxa4F6u6Z6H+VCwK5uSG-7QNvRVCXm5qtj;NI{2)@Jf8lZ_BnD_ zfO*tX3;0dWdDhw%>9ZW=TH9x#>jEBJ*mgv=H(dpj^EA}|*U*+9y&&8&px_SeFuj%3 z=P8ISC>QJd|4jq!EU-ci86-Oc1faJ!ZXTHasnBH5C*Tr6<5(QvK4wRgN@_|(Z0vzBX^ z&Yg|lHU8yJ=Vq6g?(+KOOrM=TRH_@2MLKFYqTx-r(S(fQo z)87E=>(h=M1v;5JdVg(p+2{jDQekXo{sPCu&j>V@o5`X+}(jA z_!F&Hlp|j4C)e{9?|ofvq$1ChuOy{zvtI*L1~-{D5+M5`YNn#^oaJ$1?1>?~;6xUk zYfr9SzOjO~g8(x(cn?;mb6}mkP2Y5~lMvITQz!i~PL=;tnYmt9QTr?=Su&nb0VrOc zUlLhRFol%~fp$>m@>3fXpPKreAO`@#2MrS6Gms__oN@|C(cC;xnFAL$cc=R@Nynu4 z;-%Cz$-v&>QFf$y0~)ucd;J?Pnk5E7K&!H0&B~J+N~*{depyIXa$(F`9fOjV zAXDC4N0<;eff(iVFCH6jJPeIT;x0FB%H%TbjOy5UZ{vL~;NiJ9f`(GZ!Z(GEO=~5= z_ogECTeqoUyXN(2W?pN4NzMU2H?K?KB~8r;bqOU)xb*P*zzauO(dR=XK2vX%&A4s-uSbyVN zvW_0Qe8Z*Bw=0|1T=DwGv3LC{26pbTTgyF@BbU9tlEdg7hi;22d47Sge*R8MPFK9S zX-FdO(;R3ubtQ-lH4#b+7K*{YTDEd*HAgY1+H^U!_0(uv*K#WyEk-LucXw~tKFSQs zwnw+`sSI%V(y?25N(QCIhK*6(j~?soy1qA(i4Y8>BE4ICSHEzguiK;{ z+a%_)LDptcieH);A$s>B2H8dTvlw1~DzmzCaxg|oW^l4|b>`Id7-O5S5|78;zH!y; zHPv*flj`|gy1HrN;Qo*FbWf&jZ)BqdplW`xsQFVuyAEj@Nd1~4&6L_8TodR&2+~I9 zvqs?tm+72S18#i3=RJH2&Cr|P;kc&RQM%(&7dl>ZlHfJ3jYflS6w*#D79!tyiyL*{ z^E=c06)R5!CDxn2BWEw5>f=6Sw*9S&X#Ew?#*wHA-Z+lvO(M{ zjpfokBgw?3+VBd!MIM({2P-{0!;#fTLtMNAz;=>Fr?xC(&Rk?dr2D8nY_A{ElPLi4 z5-)yecC5dDQGXAAmXHSCDA*`Q;gr@XB~c;_gSC`{9fgQU?TF29LLiqp*=QSP_oCV= z8zA}RuFWGv@0buo>I}r;s;xUXqL$y|=w>!~Q8z z>ax>CSc%^ey1gK6M;~(Mmz|2J^!pN%m}?=~f{OKoA=+U>tf38N*wc0VO7_D5aPdgz zAx8R;P-ZrM*xSSAx?KL`j;q(eyWUxid8&3r*o1$j9n=m>v}GzGE2ZM6D*2r81P_j7 zL9FTnQR)lNnr54*y>!i`)ZA1?O@kMz6D}>7$b_gCCm0S$c686+*|4xq#^{mvR3^?|LUs!Dib{H9jmD585@Snc&Z_WX@=P9+HM* zQCaIz1-AQ>efw$DWaQCD3E_l56!-tfuYSp+7Kd+H@GY)Wi1J@5?aLsEzfyiQA@6>w zP8^j68>|1~%xjnxq4V!(l&nUHTmBo~AJ{`OX0gEhSZDz84)hZp;7HTvXfc75G4k7a z6XV8b8$J)*-u=pLx->(43rPD7{#3^6Vhhb0xhtUG1(ZcLZ<0OB7FyJ_asYuAg;{1$ zH1l-UT4TnzOn7HS*XW2giVoQJ8$7;ul$qS>k-=QxH zh5qAX=f{wNXIv1gts*B+v&er55xvvXm!A(9_8%X;Fd|yjncJe=HL}hZF7?7J`SQjjebsq;%j5q&Tx?d;@ayF`}lPup6D|H%)Ue#kzwQgjSq+~OpB|C!PRir zC2f1+E>*upD9h_{gE`?{%XftxhOc6dZp(Ct9}$}oFG>Mu)FaGhkb)$W*CGtT@Z|59 z+-?#IkYl#)FvHXV^w!8~w~Tyr1wwVfpgRrRyCV2*8#2uOn@uau6Mvuk(*RzuHD!hU zc=uUj@kUt0;(yi}PgS(_YNKaj@>EI0d4uv=KwS`=Z~W-gp%5DOIm7dFe;$wr*Qz)@ z+pzd}*h-xvP~Y(8F%mC3-GeVsGkuA=ODWt+Agdbg!zec!!<6zEb>VUR6cdM*{>&*P z5rb#Q#oGTL(c@^i009610UiLV00jU5000020000O0F3|u03Hqu00000c-maS0}vDd z006MJZQHhOE8Dhh+qP}nwr$(CPHg}Hfb?%1Fb>E9E(euBufSYz65JVl6#{`6Abv;{ zNH@qaC>UBEdJKkzHHV#o^Wc*ZV1yOX9x(@T5(z}sMuAZ^P?yjy^eFUqOjXQPYyjIE zdlOe5w-V3BH^XluFbT_vA>u|7h186+j;tfEq@XBeDGezDDN`x?Dd(sO>O$%}T81`} z_J}@`{*4i2jAUY%3FbpqIo5dA4|XN?CXS3#owJ_vjoY02l9%C4=6&bW_$~Q!_;UmS z!BN3yAzfGy_7(0BJ`uGMZ5KPm>m`*X6Qx+GS9)7kOEy)uU-m%uLC%y1K^$a>S}whgjfv`g)IdnfxW`#uNB(a>?gNp&`NzIJtX zt#%9DN%t}L2am_o-!sv3#Piq-_qOm(^RD+k@@0KneUE(K{Z4;N{~Z6V06)+!usiT2 zm=10U#X|E!x5LD6+3@i2qsZAPF`Ic7ZIh#u ztCA;@PgDFUx!l~mFyA8o zs30j+EIce?i@IWi;;Q0{lDage^mFfmor8~uh=%lp+zQnS^#%Yp@V|Bd0096100961 z-ca-bUk^O>01pG`00000000000000000000{wehmO?6&vIx6M3RIvVkWhd? zfFJ=20t6ITkdRd0Ki=aReExI)`_8%doVlal>Pu2`ULsb~(uL%wy6KW~G+NVf^@jeY zu0X^e;N|wnn<#T~I0yywp$Azlj&KBqwG1^1$gRm&MaN-V^Wl@SutoewbK$Mp;i=l` zl)TqYu4z{YtjFWl-`<4CN2G{!n z*WohXT@2gFq|b!=o*z9Nb)E1*^PJoByr_K)FQR#=3!YEY>AT>b~iB1^fnAz<$L5qT#!<-g9l=yZqfY$cuI8$M4ts);f!jmlUSDYk6)l zs;*bY1LBj$`J;Glh8SQ~zT0^D8>H!mW*vL}JAyX(E#5<`(rSLmE9DT=dpb_uEPBG~ zdye#y`Tq|~rQQJNzk|5*9IR<&Y*~(T;(Y9stdVz>xhEBR@*gSA)K>ric-muNWME)! z|M!6*irx92=Kp={+&~c&z$gO%ojwLKc-muNVqC*Gfq|8QfvJmW4+8^34}@lXz+lM8 z#DD}E7#Q9QFuZvS;|HXzPP)V+&oHBgBH10w(r z$`E=0c-m~wQ-EDD5C-7cWNX`PGUuYUZJRH(ZQHhO+qP}DXR=0Zp4&7v2mk;40RS`4 z%_lbL_qF|bant8vFhqsQ&JL7RKUO3d>-5tb*0C3AVs?*bj%{D4d9Ma0RZ$lXx1R;&UsO zWm#L?+uVEH2i(WpPd&{%oxG9Wr```#OFi(bP1W zlk5z;&F=GQziC$R)q;r_B9TZgQVa1P&19olBlpY0MswL{n9)QtnuM4H(|p%>|IswZ zw%8Yk;z*;Jf=i9&xY0Z@n&=iQiB zCeb(=Lw%?hb)y#4h#F8mszX(%5@n}s6q91uFKyfYyujN5x4mzB+;+Y#acjk``8U;X zD&Lg5DSPeqwH$@Nz;ri^006Pe3~B%Xc-pL1*LvGb4jrnwSCtf|fSJhaHHV7R-3!OG zHr@66$gQL$=YIDp&%k{dQ0aI3XbX^%d-Ag>Y!;%&{YGYyRQzw_p(J^Qp-mzHQ8Lb-b9iXLjJ7uFx zHi=@(KMXoGgFPKAD9qbf)jsFLn$}$h6WW0P+rq-sUpv#ri1u0@mOS6Wd_CCtn@`SW z>;rCXk!p>+agJAWK>$hSO%+X(s=EW6W&137(y2ZW8*v0UxaEhW0k#eD>IJV}gk~57 zfk|xPux_E)@lm{CXN&gc8@$J>dvBs2u(g?x(GEC7_UQgt>!{Xtbyh?3;0L zKmk`fO0Wvz0Qdx43j=luH_~bcRcBySXwRLojs|B)ogSp&>=eV6q$lVhc(IJ2-6dO? z+zukZk!0(?@vS zI0jBTK4VD=>#fbqP9gM3H31=MQvFTRo^IA9Elh+cOX5qTSm_vsk#?)9L?UwDo{y8# z1rJB1izAXo&V}&%&6|dp5M|-IE;CRen-L|IejER5n-7St8ey#34&G3S!SW{Y&GME? z@+@zwq`=ZtNs;9pm6TZCRY@Pqdn)N?d0!<1ENvxw{9`F3rX@7c_y^w>2h|B_+;dou(rX{))VB(cFWJFD=KjgRO)K2`utxTKphnv?us zztY2G^iO&%PDV=}PaHm;Ns30*^Jjw;<KY7k)4Mn>Gr$< zLw=^LZTp`KPz3XHVXAmLa9s&Fs3DeVgxn0Vq|aX05Qv`azfwVmZHYx4waHx2kxA>2 zpLAzqA_?R@B{!+Zk}_-(P7-OB5H3n0Ig2DqND_z==xRLc00)^8QglX%B0dPFyD#xm-$^7EZ&+nn<576^Roih%epa;*;gBNX^lI6WJ^85{Y{ti9=&^hDa6MFCkJ@}3amG)(u zE2%2{`}4O$f130$m};%bm8ElktA{hcFYDSLV@v@@c-ms{-obDJP@^;)I1q->H`W@L z#c7!|5&Z?kIL{Q24q~I0F?$O}AD^0igQAWDoeD&VP=^MDs`U>V#TYs7;yp{tDgNPK z=>$vFNC1m#NVzhl8limcm<3<}VtiBUMqe+l`!Uyu@gH+vL@Iy`-i^Ol3dJ!fw!Bu` zxe=H1DL%6FUD2n`3!Oa}G>FA%JP5e}p~5SWc-mvY4J06tX$1oVlPC}${Qn9>Gb90_ z8iN|sYM|IQ#`O#g|Lwr?+y1`-@(=v~`rjDD2LOd$548XQc-mrMVBlmZVqj)qWZ?v| z7XdMZ&B!1E415gRAZ#G%!f*u2W?@iavWz zd*E~MwQh6(&cZn*Pphc{c}<%tQ)@WZs3$#P(C3}yc~4>BrN*~7mt-~Z^_~}S?m?b8 zP=hN4r%5a;<8FViT4qi2jH%~`ZufuRZ|lsf?Q0Oi4sn;Do0KK2Or!JK856;SSsv%KI-A@cn~-VerMtUd$zrs>PG_-xT9b?U^G{Ph8Q7 zaYM6cu^p}oc!;Zx8e1c8fCqWddh~cmNA&OirsozCp|EKHc-m~i)1eRm06@`upKaT= zt)8vyQL=5@cHa$=IYCVjzdMHj{`s|q2L8hwKmrIPh+skpC5&()h$M<=Vu&Syl*dsZeQHX6V-wzHqB zY~cty`OHCnaEM)8NTo9&#m!%n;GwukTb+GoE5E^&}+4sqCFM;vv`aVMPQtW!=q<19CvbKV7xa?Hiw z1i^!m0{{R3u*;DDwQbwBJ8%>V7PoLyYq+&w(KynTFsJ<-*c+d32m;B(rB;aMEBE{$cz zTgBd!XpIaN47`04>z@hu+aO$C*j{*E=1uxR;w%`onIcgz?{^ggmc=<&OHz8wJeb4h@07DqT7&4g6JJDN1E-jPEgI6!# z-Y9-+ta61zu(>BeN*l$sUVcM!#wCsC6<2DwmvmzmQ)I{Wq!OpIam{wP?_G2p3?|sI z?cM4uh6zj|b7nDQFmvVwES-f153ty}-H-Bmy7g0H$K6vno$-0p^_b7e^`vf{GFn}{ zBc-|A(1Xy1dLy`8Qa74MO=fvgycL(?f+Tepm)bUGbLM7Rz&`{qg7KDXLrUn|j+--z zDP-GG4dbAU7Xxp|=n zgH<#1CuONOsFcpg+t6Pt?zp7B!LD%zb7zvld^#v8ZI7DF{wcXW$ZQqeNP0jI33_gR zS~=MP`Y?dux)G|8G)k*ciubP6S!u*5A5l&rb7npaV7MDejnucIv63rPF{=m{?O?7i z0(lJ4uPRtO>%(N=rI5i4=1$*-fiw4@n;+!?WUzD=s8{t&kG!QRi{k_IUp3Mmk(984 v^<+||kiiO~Uq>*82}~h_87wBVpmt`^U8(YX?;rBk=34*&00962|Nj6FrM%4V diff --git a/docs/public/katex/fonts/KaTeX_Main-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Main-Regular.woff2 deleted file mode 100644 index eb24a7ba282b03d830fa6c63ee897d92a5188736..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26272 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�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 bkH82T%!~T~dOL3iZSfI!+IWoKhyte*`46Vs diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.ttf deleted file mode 100644 index 728ce7a1e2cb689df32c3a6c26e1bd072dcf2acb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31196 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 T)YS6}E-Q5R&CfXgJ?`xQe`ny2 diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff deleted file mode 100644 index 0ae390d74c9f665cf8b1e5ea5483395da7513444..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18668 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�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 J00IC101u*7EU^Fp diff --git a/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/docs/public/katex/fonts/KaTeX_Math-BoldItalic.woff2 deleted file mode 100644 index 29657023adc09956249f6295746c8ce4469b50d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16400 zcmV+rK<~eIPew8T0RR9106-7`4gdfE0D43K06(+<0RR9100000000000000000000 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 diff --git a/docs/public/katex/fonts/KaTeX_Math-Italic.ttf b/docs/public/katex/fonts/KaTeX_Math-Italic.ttf deleted file mode 100644 index 70d559b4e937ca1b805eb39f544cbebe3c58ca6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31308 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 G#ECDig^RoZ diff --git a/docs/public/katex/fonts/KaTeX_Math-Italic.woff b/docs/public/katex/fonts/KaTeX_Math-Italic.woff deleted file mode 100644 index eb5159d4c1ca83fb92b3190223698427df0e010c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18748 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 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff deleted file mode 100644 index 8d47c02d9408d34b2a9d566c0fe0d42bf82fb735..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14408 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 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/docs/public/katex/fonts/KaTeX_SansSerif-Bold.woff2 deleted file mode 100644 index cfaa3bda59246b49e94298478d6de3b3208066c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12216 zcmV;pFGtXKPew8T0RR91057-z4gdfE0AMHp054wv0RR9100000000000000000000 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 G>;nKVNojrn diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf b/docs/public/katex/fonts/KaTeX_SansSerif-Italic.ttf deleted file mode 100644 index d5850df98ec19de2eee9ff922ef59586efe471d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22364 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 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Italic.woff deleted file mode 100644 index 7e02df963621a5e26d53d510f0b4992eebde1c60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14112 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 ZM6wWJ659DkbG}7@mjJD1@jO-Eqc8pH1xbNXy>V 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 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff b/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff deleted file mode 100644 index 31b84829b42edae20d0148eeec0d922dad2108c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12316 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 DqysK0 diff --git a/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/docs/public/katex/fonts/KaTeX_SansSerif-Regular.woff2 deleted file mode 100644 index a90eea85f6f7bded69ff5d40114447a6d8b48cfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10344 zcmV-uD3{lFPew8T0RR9104Qhx4gdfE08C&204NXu0RR9100000000000000000000 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 GG{*pT{>~Tx diff --git a/docs/public/katex/fonts/KaTeX_Script-Regular.ttf b/docs/public/katex/fonts/KaTeX_Script-Regular.ttf deleted file mode 100644 index fd679bf374af72f2a183b97b40c9c7e9e51fbe5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16648 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 diff --git a/docs/public/katex/fonts/KaTeX_Script-Regular.woff b/docs/public/katex/fonts/KaTeX_Script-Regular.woff deleted file mode 100644 index 0e7da821eee0dd05a0a6f0b16c2c1345dc573a84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10588 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 diff --git a/docs/public/katex/fonts/KaTeX_Size1-Regular.ttf b/docs/public/katex/fonts/KaTeX_Size1-Regular.ttf deleted file mode 100644 index 871fd7d19d8658f64d8696ed9cdfc82c821ed76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12228 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 diff --git a/docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Size1-Regular.woff2 deleted file mode 100644 index c5a8462fbfe2c39a7c1857b9e296e62500a8a8a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5468 zcmV-i6{G5RPew8T0RR9102N#S4gdfE059|a02KrP0RR9100000000000000000000 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 a^|k5z`r34UeQg~YeP3G~_EX$#+W!Ytlnjvo diff --git a/docs/public/katex/fonts/KaTeX_Size2-Regular.woff b/docs/public/katex/fonts/KaTeX_Size2-Regular.woff deleted file mode 100644 index d241d9be2d317f7b39b401d96c8b18836acea0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6188 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 diff --git a/docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 b/docs/public/katex/fonts/KaTeX_Size2-Regular.woff2 deleted file mode 100644 index e1bccfe2403a4ed770c1697ae7c15b9e1cd9bc4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5208 zcmV-e6sPNVPew8T0RR9102EjN4gdfE04)>%02BcL0RR9100000000000000000000 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 CPy?p` diff --git a/docs/public/katex/fonts/KaTeX_Size3-Regular.woff b/docs/public/katex/fonts/KaTeX_Size3-Regular.woff deleted file mode 100644 index e6e9b658dcf1cd031ac82b6b8f312444c55d4fc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4420 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 diff --git a/docs/public/katex/fonts/KaTeX_Size4-Regular.ttf b/docs/public/katex/fonts/KaTeX_Size4-Regular.ttf deleted file mode 100644 index 74f08921f00f71f413ca42c9d1c90202e672ef38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10364 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 diff --git a/docs/public/katex/fonts/KaTeX_Size4-Regular.woff b/docs/public/katex/fonts/KaTeX_Size4-Regular.woff deleted file mode 100644 index e1ec5457664f438ce5a1cc6dd8409bf60ca7804b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5980 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 diff --git a/docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf b/docs/public/katex/fonts/KaTeX_Typewriter-Regular.ttf deleted file mode 100644 index c83252c5714c71a3e0ec62195884167339a0129b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27556 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 MzaRX}iWL5T03x1QQ2+n{ diff --git a/docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff b/docs/public/katex/fonts/KaTeX_Typewriter-Regular.woff deleted file mode 100644 index 2432419f28936aff53ddfa2a732d027e6a6648fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16028 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 G0ssIW.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} \ No newline at end of file diff --git a/docs/public/katex/katex.min.js b/docs/public/katex/katex.min.js deleted file mode 100644 index f59062a..0000000 --- a/docs/public/katex/katex.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return Wn}});class r{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;let n,o,s="KaTeX parse error: "+e;const i=t&&t.loc;if(i&&i.start<=i.end){const e=i.lexer.input;n=i.start,o=i.end,n===e.length?s+=" at end of input: ":s+=" at position "+(n+1)+": ";const t=e.slice(n,o).replace(/[^]/g,"$&\u0332");let r,a;r=n>15?"\u2026"+e.slice(n-15,n):e.slice(0,n),a=o+15":">","<":"<",'"':""","'":"'"},i=/[&><"']/g;const a=function(e){return"ordgroup"===e.type||"color"===e.type?1===e.body.length?a(e.body[0]):e:"font"===e.type?a(e.body):e};var l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(i,(e=>s[e]))},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:a,isCharacterBox:function(e){const t=a(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){const t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}};const h={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function c(e){if(e.default)return e.default;const t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class m{constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(const t in h)if(h.hasOwnProperty(t)){const r=h[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:c(r)}}reportNonstrict(e,t,r){let o=this.strict;if("function"==typeof o&&(o=o(e,t,r)),o&&"ignore"!==o){if(!0===o||"error"===o)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===o?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+o+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){let n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){const t=l.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}const t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)}}class p{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return u[d[this.id]]}sub(){return u[g[this.id]]}fracNum(){return u[f[this.id]]}fracDen(){return u[b[this.id]]}cramp(){return u[y[this.id]]}text(){return u[x[this.id]]}isTight(){return this.size>=2}}const u=[new p(0,0,!1),new p(1,0,!0),new p(2,1,!1),new p(3,1,!0),new p(4,2,!1),new p(5,2,!0),new p(6,3,!1),new p(7,3,!0)],d=[4,5,4,5,6,7,6,7],g=[5,5,5,5,7,7,7,7],f=[2,3,4,5,6,7,6,7],b=[3,3,5,5,7,7,7,7],y=[1,1,3,3,5,5,7,7],x=[0,1,2,3,2,3,2,3];var w={DISPLAY:u[0],TEXT:u[2],SCRIPT:u[4],SCRIPTSCRIPT:u[6]};const v=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];const k=[];function S(e){for(let t=0;t=k[t]&&e<=k[t+1])return!0;return!1}v.forEach((e=>e.blocks.forEach((e=>k.push(...e)))));const M=80,z={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class A{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createDocumentFragment();for(let t=0;te.toText())).join("")}}var T={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}};const B={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},C={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function N(e,t,r){if(!T[t])throw new Error("Font metrics not found for font: "+t+".");let n=e.charCodeAt(0),o=T[t][n];if(!o&&e[0]in C&&(n=C[e[0]].charCodeAt(0),o=T[t][n]),o||"text"!==r||S(n)&&(o=T[t][77]),o)return{depth:o[0],height:o[1],italic:o[2],skew:o[3],width:o[4]}}const q={};const I=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],R=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],H=function(e,t){return t.size<2?e:I[e-1][t.size-1]};class O{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||O.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=R[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){const t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(const r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new O(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:H(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:R[e-1]})}havingBaseStyle(e){e=e||this.style.text();const t=H(O.BASESIZE,e);return this.size===t&&this.textSize===O.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){let e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==O.BASESIZE?["sizing","reset-size"+this.size,"size"+O.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){let t;if(t=e>=5?0:e>=3?1:2,!q[t]){const e=q[t]={cssEmPerMu:B.quad[t]/18};for(const r in B)B.hasOwnProperty(r)&&(e[r]=B[r][t])}return q[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}O.BASESIZE=6;var E=O;const L={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},D={ex:!0,em:!0,mu:!0},V=function(e){return"string"!=typeof e&&(e=e.unit),e in L||e in D||"ex"===e},P=function(e,t){let r;if(e.unit in L)r=L[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{let o;if(o=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=o.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=o.fontMetrics().quad}o!==t&&(r*=o.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},F=function(e){return+e.toFixed(4)+"em"},G=function(e){return e.filter((e=>e)).join(" ")},U=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");const e=t.getColor();e&&(this.style.color=e)}},Y=function(e){const t=document.createElement(e);t.className=G(this.classes);for(const e in this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);for(const e in this.attributes)this.attributes.hasOwnProperty(e)&&t.setAttribute(e,this.attributes[e]);for(let e=0;e/=\x00-\x1f]/,W=function(e){let t="<"+e;this.classes.length&&(t+=' class="'+l.escape(G(this.classes))+'"');let r="";for(const e in this.style)this.style.hasOwnProperty(e)&&(r+=l.hyphenate(e)+":"+this.style[e]+";");r&&(t+=' style="'+l.escape(r)+'"');for(const e in this.attributes)if(this.attributes.hasOwnProperty(e)){if(X.test(e))throw new n("Invalid attribute name '"+e+"'");t+=" "+e+'="'+l.escape(this.attributes[e])+'"'}t+=">";for(let e=0;e",t};class _{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,e,r,n),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return l.contains(this.classes,e)}toNode(){return Y.call(this,"span")}toMarkup(){return W.call(this,"span")}}class j{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return l.contains(this.classes,e)}toNode(){return Y.call(this,"a")}toMarkup(){return W.call(this,"a")}}class ${constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(const t in this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){let e=''+l.escape(this.alt)+'=n[0]&&e<=n[1])return r.name}}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Z[this.text])}hasClass(e){return l.contains(this.classes,e)}toNode(){const e=document.createTextNode(this.text);let t=null;this.italic>0&&(t=document.createElement("span"),t.style.marginRight=F(this.italic)),this.classes.length>0&&(t=t||document.createElement("span"),t.className=G(this.classes));for(const e in this.style)this.style.hasOwnProperty(e)&&(t=t||document.createElement("span"),t.style[e]=this.style[e]);return t?(t.appendChild(e),t):e}toMarkup(){let e=!1,t="0&&(r+="margin-right:"+this.italic+"em;");for(const e in this.style)this.style.hasOwnProperty(e)&&(r+=l.hyphenate(e)+":"+this.style[e]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');const n=l.escape(this.text);return e?(t+=">",t+=n,t+="",t):n}}class J{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(let t=0;t':''}}class ee{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){const e=document.createElementNS("http://www.w3.org/2000/svg","line");for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){let e="","\\gt",!0),ie(ae,he,xe,"\u2208","\\in",!0),ie(ae,he,xe,"\ue020","\\@not"),ie(ae,he,xe,"\u2282","\\subset",!0),ie(ae,he,xe,"\u2283","\\supset",!0),ie(ae,he,xe,"\u2286","\\subseteq",!0),ie(ae,he,xe,"\u2287","\\supseteq",!0),ie(ae,ce,xe,"\u2288","\\nsubseteq",!0),ie(ae,ce,xe,"\u2289","\\nsupseteq",!0),ie(ae,he,xe,"\u22a8","\\models"),ie(ae,he,xe,"\u2190","\\leftarrow",!0),ie(ae,he,xe,"\u2264","\\le"),ie(ae,he,xe,"\u2264","\\leq",!0),ie(ae,he,xe,"<","\\lt",!0),ie(ae,he,xe,"\u2192","\\rightarrow",!0),ie(ae,he,xe,"\u2192","\\to"),ie(ae,ce,xe,"\u2271","\\ngeq",!0),ie(ae,ce,xe,"\u2270","\\nleq",!0),ie(ae,he,we,"\xa0","\\ "),ie(ae,he,we,"\xa0","\\space"),ie(ae,he,we,"\xa0","\\nobreakspace"),ie(le,he,we,"\xa0","\\ "),ie(le,he,we,"\xa0"," "),ie(le,he,we,"\xa0","\\space"),ie(le,he,we,"\xa0","\\nobreakspace"),ie(ae,he,we,null,"\\nobreak"),ie(ae,he,we,null,"\\allowbreak"),ie(ae,he,ye,",",","),ie(ae,he,ye,";",";"),ie(ae,ce,pe,"\u22bc","\\barwedge",!0),ie(ae,ce,pe,"\u22bb","\\veebar",!0),ie(ae,he,pe,"\u2299","\\odot",!0),ie(ae,he,pe,"\u2295","\\oplus",!0),ie(ae,he,pe,"\u2297","\\otimes",!0),ie(ae,he,ve,"\u2202","\\partial",!0),ie(ae,he,pe,"\u2298","\\oslash",!0),ie(ae,ce,pe,"\u229a","\\circledcirc",!0),ie(ae,ce,pe,"\u22a1","\\boxdot",!0),ie(ae,he,pe,"\u25b3","\\bigtriangleup"),ie(ae,he,pe,"\u25bd","\\bigtriangledown"),ie(ae,he,pe,"\u2020","\\dagger"),ie(ae,he,pe,"\u22c4","\\diamond"),ie(ae,he,pe,"\u22c6","\\star"),ie(ae,he,pe,"\u25c3","\\triangleleft"),ie(ae,he,pe,"\u25b9","\\triangleright"),ie(ae,he,be,"{","\\{"),ie(le,he,ve,"{","\\{"),ie(le,he,ve,"{","\\textbraceleft"),ie(ae,he,ue,"}","\\}"),ie(le,he,ve,"}","\\}"),ie(le,he,ve,"}","\\textbraceright"),ie(ae,he,be,"{","\\lbrace"),ie(ae,he,ue,"}","\\rbrace"),ie(ae,he,be,"[","\\lbrack",!0),ie(le,he,ve,"[","\\lbrack",!0),ie(ae,he,ue,"]","\\rbrack",!0),ie(le,he,ve,"]","\\rbrack",!0),ie(ae,he,be,"(","\\lparen",!0),ie(ae,he,ue,")","\\rparen",!0),ie(le,he,ve,"<","\\textless",!0),ie(le,he,ve,">","\\textgreater",!0),ie(ae,he,be,"\u230a","\\lfloor",!0),ie(ae,he,ue,"\u230b","\\rfloor",!0),ie(ae,he,be,"\u2308","\\lceil",!0),ie(ae,he,ue,"\u2309","\\rceil",!0),ie(ae,he,ve,"\\","\\backslash"),ie(ae,he,ve,"\u2223","|"),ie(ae,he,ve,"\u2223","\\vert"),ie(le,he,ve,"|","\\textbar",!0),ie(ae,he,ve,"\u2225","\\|"),ie(ae,he,ve,"\u2225","\\Vert"),ie(le,he,ve,"\u2225","\\textbardbl"),ie(le,he,ve,"~","\\textasciitilde"),ie(le,he,ve,"\\","\\textbackslash"),ie(le,he,ve,"^","\\textasciicircum"),ie(ae,he,xe,"\u2191","\\uparrow",!0),ie(ae,he,xe,"\u21d1","\\Uparrow",!0),ie(ae,he,xe,"\u2193","\\downarrow",!0),ie(ae,he,xe,"\u21d3","\\Downarrow",!0),ie(ae,he,xe,"\u2195","\\updownarrow",!0),ie(ae,he,xe,"\u21d5","\\Updownarrow",!0),ie(ae,he,fe,"\u2210","\\coprod"),ie(ae,he,fe,"\u22c1","\\bigvee"),ie(ae,he,fe,"\u22c0","\\bigwedge"),ie(ae,he,fe,"\u2a04","\\biguplus"),ie(ae,he,fe,"\u22c2","\\bigcap"),ie(ae,he,fe,"\u22c3","\\bigcup"),ie(ae,he,fe,"\u222b","\\int"),ie(ae,he,fe,"\u222b","\\intop"),ie(ae,he,fe,"\u222c","\\iint"),ie(ae,he,fe,"\u222d","\\iiint"),ie(ae,he,fe,"\u220f","\\prod"),ie(ae,he,fe,"\u2211","\\sum"),ie(ae,he,fe,"\u2a02","\\bigotimes"),ie(ae,he,fe,"\u2a01","\\bigoplus"),ie(ae,he,fe,"\u2a00","\\bigodot"),ie(ae,he,fe,"\u222e","\\oint"),ie(ae,he,fe,"\u222f","\\oiint"),ie(ae,he,fe,"\u2230","\\oiiint"),ie(ae,he,fe,"\u2a06","\\bigsqcup"),ie(ae,he,fe,"\u222b","\\smallint"),ie(le,he,de,"\u2026","\\textellipsis"),ie(ae,he,de,"\u2026","\\mathellipsis"),ie(le,he,de,"\u2026","\\ldots",!0),ie(ae,he,de,"\u2026","\\ldots",!0),ie(ae,he,de,"\u22ef","\\@cdots",!0),ie(ae,he,de,"\u22f1","\\ddots",!0),ie(ae,he,ve,"\u22ee","\\varvdots"),ie(le,he,ve,"\u22ee","\\varvdots"),ie(ae,he,me,"\u02ca","\\acute"),ie(ae,he,me,"\u02cb","\\grave"),ie(ae,he,me,"\xa8","\\ddot"),ie(ae,he,me,"~","\\tilde"),ie(ae,he,me,"\u02c9","\\bar"),ie(ae,he,me,"\u02d8","\\breve"),ie(ae,he,me,"\u02c7","\\check"),ie(ae,he,me,"^","\\hat"),ie(ae,he,me,"\u20d7","\\vec"),ie(ae,he,me,"\u02d9","\\dot"),ie(ae,he,me,"\u02da","\\mathring"),ie(ae,he,ge,"\ue131","\\@imath"),ie(ae,he,ge,"\ue237","\\@jmath"),ie(ae,he,ve,"\u0131","\u0131"),ie(ae,he,ve,"\u0237","\u0237"),ie(le,he,ve,"\u0131","\\i",!0),ie(le,he,ve,"\u0237","\\j",!0),ie(le,he,ve,"\xdf","\\ss",!0),ie(le,he,ve,"\xe6","\\ae",!0),ie(le,he,ve,"\u0153","\\oe",!0),ie(le,he,ve,"\xf8","\\o",!0),ie(le,he,ve,"\xc6","\\AE",!0),ie(le,he,ve,"\u0152","\\OE",!0),ie(le,he,ve,"\xd8","\\O",!0),ie(le,he,me,"\u02ca","\\'"),ie(le,he,me,"\u02cb","\\`"),ie(le,he,me,"\u02c6","\\^"),ie(le,he,me,"\u02dc","\\~"),ie(le,he,me,"\u02c9","\\="),ie(le,he,me,"\u02d8","\\u"),ie(le,he,me,"\u02d9","\\."),ie(le,he,me,"\xb8","\\c"),ie(le,he,me,"\u02da","\\r"),ie(le,he,me,"\u02c7","\\v"),ie(le,he,me,"\xa8",'\\"'),ie(le,he,me,"\u02dd","\\H"),ie(le,he,me,"\u25ef","\\textcircled");const ke={"--":!0,"---":!0,"``":!0,"''":!0};ie(le,he,ve,"\u2013","--",!0),ie(le,he,ve,"\u2013","\\textendash"),ie(le,he,ve,"\u2014","---",!0),ie(le,he,ve,"\u2014","\\textemdash"),ie(le,he,ve,"\u2018","`",!0),ie(le,he,ve,"\u2018","\\textquoteleft"),ie(le,he,ve,"\u2019","'",!0),ie(le,he,ve,"\u2019","\\textquoteright"),ie(le,he,ve,"\u201c","``",!0),ie(le,he,ve,"\u201c","\\textquotedblleft"),ie(le,he,ve,"\u201d","''",!0),ie(le,he,ve,"\u201d","\\textquotedblright"),ie(ae,he,ve,"\xb0","\\degree",!0),ie(le,he,ve,"\xb0","\\degree"),ie(le,he,ve,"\xb0","\\textdegree",!0),ie(ae,he,ve,"\xa3","\\pounds"),ie(ae,he,ve,"\xa3","\\mathsterling",!0),ie(le,he,ve,"\xa3","\\pounds"),ie(le,he,ve,"\xa3","\\textsterling",!0),ie(ae,ce,ve,"\u2720","\\maltese"),ie(le,ce,ve,"\u2720","\\maltese");const Se='0123456789/@."';for(let e=0;e<14;e++){const t=Se.charAt(e);ie(ae,he,ve,t,t)}const Me='0123456789!@*()-=+";:?/.,';for(let e=0;e<25;e++){const t=Me.charAt(e);ie(le,he,ve,t,t)}const ze="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";for(let e=0;e<52;e++){const t=ze.charAt(e);ie(ae,he,ge,t,t),ie(le,he,ve,t,t)}ie(ae,ce,ve,"C","\u2102"),ie(le,ce,ve,"C","\u2102"),ie(ae,ce,ve,"H","\u210d"),ie(le,ce,ve,"H","\u210d"),ie(ae,ce,ve,"N","\u2115"),ie(le,ce,ve,"N","\u2115"),ie(ae,ce,ve,"P","\u2119"),ie(le,ce,ve,"P","\u2119"),ie(ae,ce,ve,"Q","\u211a"),ie(le,ce,ve,"Q","\u211a"),ie(ae,ce,ve,"R","\u211d"),ie(le,ce,ve,"R","\u211d"),ie(ae,ce,ve,"Z","\u2124"),ie(le,ce,ve,"Z","\u2124"),ie(ae,he,ge,"h","\u210e"),ie(le,he,ge,"h","\u210e");let Ae="";for(let e=0;e<52;e++){const t=ze.charAt(e);Ae=String.fromCharCode(55349,56320+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56372+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56424+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56580+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56684+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56736+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56788+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56840+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56944+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),e<26&&(Ae=String.fromCharCode(55349,56632+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,56476+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae))}Ae=String.fromCharCode(55349,56668),ie(ae,he,ge,"k",Ae),ie(le,he,ve,"k",Ae);for(let e=0;e<10;e++){const t=e.toString();Ae=String.fromCharCode(55349,57294+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57314+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57324+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae),Ae=String.fromCharCode(55349,57334+e),ie(ae,he,ge,t,Ae),ie(le,he,ve,t,Ae)}const Te="\xd0\xde\xfe";for(let e=0;e<3;e++){const t=Te.charAt(e);ie(ae,he,ge,t,t),ie(le,he,ve,t,t)}const Be=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Ce=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Ne=function(e,t,r){return se[r][e]&&se[r][e].replace&&(e=se[r][e].replace),{value:e,metrics:N(e,t,r)}},qe=function(e,t,r,n,o){const s=Ne(e,t,r),i=s.metrics;let a;if(e=s.value,i){let t=i.italic;("text"===r||n&&"mathit"===n.font)&&(t=0),a=new K(e,i.height,i.depth,t,i.skew,i.width,o)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),a=new K(e,0,0,0,0,0,o);if(n){a.maxFontSize=n.sizeMultiplier,n.style.isTight()&&a.classes.push("mtight");const e=n.getColor();e&&(a.style.color=e)}return a},Ie=(e,t)=>{if(G(e.classes)!==G(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){const t=e.classes[0];if("mbin"===t||"mord"===t)return!1}for(const r in e.style)if(e.style.hasOwnProperty(r)&&e.style[r]!==t.style[r])return!1;for(const r in t.style)if(t.style.hasOwnProperty(r)&&e.style[r]!==t.style[r])return!1;return!0},Re=function(e){let t=0,r=0,n=0;for(let o=0;ot&&(t=s.height),s.depth>r&&(r=s.depth),s.maxFontSize>n&&(n=s.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},He=function(e,t,r,n){const o=new _(e,t,r,n);return Re(o),o},Oe=(e,t,r,n)=>new _(e,t,r,n),Ee=function(e){const t=new A(e);return Re(t),t},Le=function(e,t,r){let n,o="";switch(e){case"amsrm":o="AMS";break;case"textrm":o="Main";break;case"textsf":o="SansSerif";break;case"texttt":o="Typewriter";break;default:o=e}return n="textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular",o+"-"+n},De={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ve={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]};var Pe={fontMap:De,makeSymbol:qe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Ne(e,"Main-Bold",t).metrics?qe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===se[t][e].font?qe(e,"Main-Regular",t,r,n):qe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:He,makeSvgSpan:Oe,makeLineSpan:function(e,t,r){const n=He([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=F(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){const o=new j(e,t,r,n);return Re(o),o},makeFragment:Ee,wrapFragment:function(e,t){return e instanceof A?He([],[e],t):e},makeVList:function(e,t){const{children:r,depth:n}=function(e){if("individualShift"===e.positionType){const t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth;let o=n;for(let e=1;e0)return qe(s,h,o,t,i.concat(c));if(l){let e,n;if("boldsymbol"===l){const t=function(e,t,r,n,o){return"textord"!==o&&Ne(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(s,o,0,0,r);e=t.fontName,n=[t.fontClass]}else a?(e=De[l].fontName,n=[l]):(e=Le(l,t.fontWeight,t.fontShape),n=[l,t.fontWeight,t.fontShape]);if(Ne(s,e,o).metrics)return qe(s,e,o,t,i.concat(n));if(ke.hasOwnProperty(s)&&"Typewriter"===e.slice(0,10)){const r=[];for(let a=0;a{const r=He(["mspace"],[],t),n=P(e,t);return r.style.marginRight=F(n),r},staticSvg:function(e,t){const[r,n,o]=Ve[e],s=new Q(r),i=new J([s],{width:F(n),height:F(o),style:"width:"+F(n),viewBox:"0 0 "+1e3*n+" "+1e3*o,preserveAspectRatio:"xMinYMin"}),a=Oe(["overlay"],[i],t);return a.height=o,a.style.height=F(o),a.style.width=F(n),a},svgData:Ve,tryCombineChars:e=>{for(let t=0;t{const r=t.classes[0],n=e.classes[0];"mbin"===r&&l.contains(tt,n)?t.classes[0]="mord":"mbin"===n&&l.contains(et,r)&&(e.classes[0]="mord")}),{node:i},a,h),st(o,((e,t)=>{const r=lt(t),n=lt(e),o=r&&n?e.hasClass("mtight")?Xe[r][n]:Ye[r][n]:null;if(o)return Pe.makeGlue(o,s)}),{node:i},a,h),o},st=function(e,t,r,n,o){n&&e.push(n);let s=0;for(;sr=>{e.splice(t+1,0,r),s++})(s)}n&&e.pop()},it=function(e){return e instanceof A||e instanceof j||e instanceof _&&e.hasClass("enclosing")?e:null},at=function(e,t){const r=it(e);if(r){const e=r.children;if(e.length){if("right"===t)return at(e[e.length-1],"right");if("left"===t)return at(e[0],"left")}}return e},lt=function(e,t){return e?(t&&(e=at(e,t)),nt[e.classes[0]]||null):null},ht=function(e,t){const r=["nulldelimiter"].concat(e.baseSizingClasses());return Qe(t.concat(r))},ct=function(e,t,r){if(!e)return Qe();if(_e[e.type]){let n=_e[e.type](e,t);if(r&&t.size!==r.size){n=Qe(t.sizingClasses(r),[n],t);const e=t.sizeMultiplier/r.sizeMultiplier;n.height*=e,n.depth*=e}return n}throw new n("Got group of unknown type: '"+e.type+"'")};function mt(e,t){const r=Qe(["base"],e,t),n=Qe(["strut"]);return n.style.height=F(r.height+r.depth),r.depth&&(n.style.verticalAlign=F(-r.depth)),r.children.unshift(n),r}function pt(e,t){let r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);const n=ot(e,t,"root");let o;2===n.length&&n[1].hasClass("tag")&&(o=n.pop());const s=[];let i,a=[];for(let e=0;e0&&(s.push(mt(a,t)),a=[]),s.push(n[e]));a.length>0&&s.push(mt(a,t)),r?(i=mt(ot(r,t,!0)),i.classes=["tag"],s.push(i)):o&&s.push(o);const l=Qe(["katex-html"],s);if(l.setAttribute("aria-hidden","true"),i){const e=i.children[0];e.style.height=F(l.height+l.depth),l.depth&&(e.style.verticalAlign=F(-l.depth))}return l}function ut(e){return new A(e)}class dt{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){const e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(const t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=G(this.classes));for(let t=0;t0&&(e+=' class ="'+l.escape(G(this.classes))+'"'),e+=">";for(let t=0;t",e}toText(){return this.children.map((e=>e.toText())).join("")}}class gt{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return l.escape(this.toText())}toText(){return this.text}}var ft={MathNode:dt,TextNode:gt,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);{const e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",F(this.width)),e}}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},newDocumentFragment:ut};const bt=function(e,t,r){return!se[t][e]||!se[t][e].replace||55349===e.charCodeAt(0)||ke.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=se[t][e].replace),new ft.TextNode(e)},yt=function(e){return 1===e.length?e[0]:new ft.MathNode("mrow",e)},xt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";const r=t.font;if(!r||"mathnormal"===r)return null;const n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathsfit"===r)return"sans-serif-italic";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";let o=e.text;if(l.contains(["\\imath","\\jmath"],o))return null;se[n][o]&&se[n][o].replace&&(o=se[n][o].replace);return N(o,Pe.fontMap[r].fontName,n)?Pe.fontMap[r].variant:null};function wt(e){if(!e)return!1;if("mi"===e.type&&1===e.children.length){const t=e.children[0];return t instanceof gt&&"."===t.text}if("mo"===e.type&&1===e.children.length&&"true"===e.getAttribute("separator")&&"0em"===e.getAttribute("lspace")&&"0em"===e.getAttribute("rspace")){const t=e.children[0];return t instanceof gt&&","===t.text}return!1}const vt=function(e,t,r){if(1===e.length){const n=St(e[0],t);return r&&n instanceof dt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}const n=[];let o;for(let r=0;r=1&&("mn"===o.type||wt(o))){const e=s.children[0];e instanceof dt&&"mn"===e.type&&(e.children=[...o.children,...e.children],n.pop())}else if("mi"===o.type&&1===o.children.length){const e=o.children[0];if(e instanceof gt&&"\u0338"===e.text&&("mo"===s.type||"mi"===s.type||"mn"===s.type)){const e=s.children[0];e instanceof gt&&e.text.length>0&&(e.text=e.text.slice(0,1)+"\u0338"+e.text.slice(1),n.pop())}}}n.push(s),o=s}return n},kt=function(e,t,r){return yt(vt(e,t,r))},St=function(e,t){if(!e)return new ft.MathNode("mrow");if(je[e.type]){return je[e.type](e,t)}throw new n("Got group of unknown type: '"+e.type+"'")};function Mt(e,t,r,n,o){const s=vt(e,r);let i;i=1===s.length&&s[0]instanceof dt&&l.contains(["mrow","mtable"],s[0].type)?s[0]:new ft.MathNode("mrow",s);const a=new ft.MathNode("annotation",[new ft.TextNode(t)]);a.setAttribute("encoding","application/x-tex");const h=new ft.MathNode("semantics",[i,a]),c=new ft.MathNode("math",[h]);c.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&c.setAttribute("display","block");const m=o?"katex":"katex-mathml";return Pe.makeSpan([m],[c])}const zt=function(e){return new E({style:e.displayMode?w.DISPLAY:w.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},At=function(e,t){if(t.displayMode){const r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Pe.makeSpan(r,[e])}return e},Tt=function(e,t,r){const n=zt(r);let o;if("mathml"===r.output)return Mt(e,t,n,r.displayMode,!0);if("html"===r.output){const t=pt(e,n);o=Pe.makeSpan(["katex"],[t])}else{const s=Mt(e,t,n,r.displayMode,!1),i=pt(e,n);o=Pe.makeSpan(["katex"],[s,i])}return At(o,r)};const Bt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Ct={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]};var Nt=function(e,t,r,n,o){let s;const i=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(s=Pe.makeSpan(["stretchy",t],[],o),"fbox"===t){const e=o.color&&o.getColor();e&&(s.style.borderColor=e)}}else{const e=[];/^[bx]cancel$/.test(t)&&e.push(new ee({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&e.push(new ee({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));const r=new J(e,{width:"100%",height:F(i)});s=Pe.makeSvgSpan([],[r],o)}return s.height=i,s.style.height=F(i),s},qt=function(e){const t=new ft.MathNode("mo",[new ft.TextNode(Bt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},It=function(e,t){const{span:r,minWidth:n,height:o}=function(){let r=4e5;const n=e.label.slice(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){const s="ordgroup"===(o=e.base).type?o.body.length:1;let i,a,l;if(s>5)"widehat"===n||"widecheck"===n?(i=420,r=2364,l=.42,a=n+"4"):(i=312,r=2340,l=.34,a="tilde4");else{const e=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][e],i=[0,239,300,360,420][e],l=[0,.24,.3,.3,.36,.42][e],a=n+e):(r=[0,600,1033,2339,2340][e],i=[0,260,286,306,312][e],l=[0,.26,.286,.3,.306,.34][e],a="tilde"+e)}const h=new Q(a),c=new J([h],{width:"100%",height:F(l),viewBox:"0 0 "+r+" "+i,preserveAspectRatio:"none"});return{span:Pe.makeSvgSpan([],[c],t),minWidth:0,height:l}}{const e=[],o=Ct[n],[s,i,a]=o,l=a/1e3,h=s.length;let c,m;if(1===h){c=["hide-tail"],m=[o[3]]}else if(2===h)c=["halfarrow-left","halfarrow-right"],m=["xMinYMin","xMaxYMin"];else{if(3!==h)throw new Error("Correct katexImagesData or update code here to support\n "+h+" children.");c=["brace-left","brace-center","brace-right"],m=["xMinYMin","xMidYMin","xMaxYMin"]}for(let n=0;n0&&(r.style.minWidth=F(n)),r};function Rt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Ht(e){const t=Ot(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ot(e){return e&&("atom"===e.type||ne.hasOwnProperty(e.type))?e:null}const Et=(e,t)=>{let r,n,o;e&&"supsub"===e.type?(n=Rt(e.base,"accent"),r=n.base,e.base=r,o=function(e){if(e instanceof _)return e;throw new Error("Expected span but got "+String(e)+".")}(ct(e,t)),e.base=n):(n=Rt(e,"accent"),r=n.base);const s=ct(r,t.havingCrampedStyle());let i=0;if(n.isShifty&&l.isCharacterBox(r)){const e=l.getBaseElem(r);i=te(ct(e,t.havingCrampedStyle())).skew}const a="\\c"===n.label;let h,c=a?s.height+s.depth:Math.min(s.height,t.fontMetrics().xHeight);if(n.isStretchy)h=It(n,t),h=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:i>0?{width:"calc(100% - "+F(2*i)+")",marginLeft:F(2*i)}:void 0}]},t);else{let e,r;"\\vec"===n.label?(e=Pe.staticSvg("vec",t),r=Pe.svgData.vec[1]):(e=Pe.makeOrd({mode:n.mode,text:n.label},t,"textord"),e=te(e),e.italic=0,r=e.width,a&&(c+=e.depth)),h=Pe.makeSpan(["accent-body"],[e]);const o="\\textcircled"===n.label;o&&(h.classes.push("accent-full"),c=s.height);let l=i;o||(l-=r/2),h.style.left=F(l),"\\textcircled"===n.label&&(h.style.top=".2em"),h=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}const m=Pe.makeSpan(["mord","accent"],[h],t);return o?(o.children[0]=m,o.height=Math.max(m.height,o.height),o.classes[0]="mord",o):m},Lt=(e,t)=>{const r=e.isStretchy?qt(e.label):new ft.MathNode("mo",[bt(e.label,e.mode)]),n=new ft.MathNode("mover",[St(e.base,t),r]);return n.setAttribute("accent","true"),n},Dt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((e=>"\\"+e)).join("|"));$e({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{const r=Ke(t[0]),n=!Dt.test(e.funcName),o=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:o,base:r}},htmlBuilder:Et,mathmlBuilder:Lt}),$e({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{const r=t[0];let n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Et,mathmlBuilder:Lt}),$e({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:o}},htmlBuilder:(e,t)=>{const r=ct(e.base,t),n=It(e,t),o="\\utilde"===e.label?.12:0,s=Pe.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:o},{type:"elem",elem:r}]},t);return Pe.makeSpan(["mord","accentunder"],[s],t)},mathmlBuilder:(e,t)=>{const r=qt(e.label),n=new ft.MathNode("munder",[St(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});const Vt=e=>{const t=new ft.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};$e({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){let{parser:n,funcName:o}=e;return{type:"xArrow",mode:n.mode,label:o,body:t[0],below:r[0]}},htmlBuilder(e,t){const r=t.style;let n=t.havingStyle(r.sup());const o=Pe.wrapFragment(ct(e.body,n,t),t),s="\\x"===e.label.slice(0,2)?"x":"cd";let i;o.classes.push(s+"-arrow-pad"),e.below&&(n=t.havingStyle(r.sub()),i=Pe.wrapFragment(ct(e.below,n,t),t),i.classes.push(s+"-arrow-pad"));const a=It(e,t),l=-t.fontMetrics().axisHeight+.5*a.height;let h,c=-t.fontMetrics().axisHeight-.5*a.height-.111;if((o.depth>.25||"\\xleftequilibrium"===e.label)&&(c-=o.depth),i){const e=-t.fontMetrics().axisHeight+i.height+.5*a.height+.111;h=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:c},{type:"elem",elem:a,shift:l},{type:"elem",elem:i,shift:e}]},t)}else h=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:c},{type:"elem",elem:a,shift:l}]},t);return h.children[0].children[0].children[1].classes.push("svg-align"),Pe.makeSpan(["mrel","x-arrow"],[h],t)},mathmlBuilder(e,t){const r=qt(e.label);let n;if(r.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){const o=Vt(St(e.body,t));if(e.below){const s=Vt(St(e.below,t));n=new ft.MathNode("munderover",[r,s,o])}else n=new ft.MathNode("mover",[r,o])}else if(e.below){const o=Vt(St(e.below,t));n=new ft.MathNode("munder",[r,o])}else n=Vt(),n=new ft.MathNode("mover",[r,n]);return n}});const Pt=Pe.makeSpan;function Ft(e,t){const r=ot(e.body,t,!0);return Pt([e.mclass],r,t)}function Gt(e,t){let r;const n=vt(e.body,t);return"minner"===e.mclass?r=new ft.MathNode("mpadded",n):"mord"===e.mclass?e.isCharacterBox?(r=n[0],r.type="mi"):r=new ft.MathNode("mi",n):(e.isCharacterBox?(r=n[0],r.type="mo"):r=new ft.MathNode("mo",n),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}$e({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:Je(o),isCharacterBox:l.isCharacterBox(o)}},htmlBuilder:Ft,mathmlBuilder:Gt});const Ut=e=>{const t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};$e({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){let{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:Ut(t[0]),body:Je(t[1]),isCharacterBox:l.isCharacterBox(t[1])}}}),$e({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){let{parser:r,funcName:n}=e;const o=t[1],s=t[0];let i;i="\\stackrel"!==n?Ut(o):"mrel";const a={type:"op",mode:o.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:Je(o)},h={type:"supsub",mode:s.mode,base:a,sup:"\\underset"===n?null:s,sub:"\\underset"===n?s:null};return{type:"mclass",mode:r.mode,mclass:i,body:[h],isCharacterBox:l.isCharacterBox(h)}},htmlBuilder:Ft,mathmlBuilder:Gt}),$e({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:Ut(t[0]),body:Je(t[0])}},htmlBuilder(e,t){const r=ot(e.body,t,!0),n=Pe.makeSpan([e.mclass],r,t);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(e,t){const r=vt(e.body,t),n=new ft.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});const Yt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},Xt=e=>"textord"===e.type&&"@"===e.text;function Wt(e,t,r){const n=Yt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":{const e={type:"atom",text:n,mode:"math",family:"rel"},o={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[e],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[o],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{const e={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[e],[])}default:return{type:"textord",text:" ",mode:"math"}}}$e({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder(e,t){const r=t.havingStyle(t.style.sup()),n=Pe.wrapFragment(ct(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=F(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(e,t){let r=new ft.MathNode("mrow",[St(e.label,t)]);return r=new ft.MathNode("mpadded",[r]),r.setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new ft.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),$e({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){let{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){const r=Pe.wrapFragment(ct(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(e,t){return new ft.MathNode("mrow",[St(e.fragment,t)])}}),$e({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;const o=Rt(t[0],"ordgroup").body;let s="";for(let e=0;e=1114111)throw new n("\\@char with invalid code point "+s);return a<=65535?i=String.fromCharCode(a):(a-=65536,i=String.fromCharCode(55296+(a>>10),56320+(1023&a))),{type:"textord",mode:r.mode,text:i}}});const _t=(e,t)=>{const r=ot(e.body,t.withColor(e.color),!1);return Pe.makeFragment(r)},jt=(e,t)=>{const r=vt(e.body,t.withColor(e.color)),n=new ft.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};$e({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){let{parser:r}=e;const n=Rt(t[0],"color-token").color,o=t[1];return{type:"color",mode:r.mode,color:n,body:Je(o)}},htmlBuilder:_t,mathmlBuilder:jt}),$e({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){let{parser:r,breakOnTokenText:n}=e;const o=Rt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",o);const s=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:o,body:s}},htmlBuilder:_t,mathmlBuilder:jt}),$e({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){let{parser:n}=e;const o="["===n.gullet.future().text?n.parseSizeGroup(!0):null,s=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:s,size:o&&Rt(o,"size").value}},htmlBuilder(e,t){const r=Pe.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=F(P(e.size,t)))),r},mathmlBuilder(e,t){const r=new ft.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",F(P(e.size,t)))),r}});const $t={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},Zt=e=>{const t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},Kt=(e,t,r,n)=>{let o=e.gullet.macros.get(r.text);null==o&&(r.noexpand=!0,o={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,o,n)};$e({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){let{parser:t,funcName:r}=e;t.consumeSpaces();const o=t.fetch();if($t[o.text])return"\\global"!==r&&"\\\\globallong"!==r||(o.text=$t[o.text]),Rt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",o)}}),$e({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e,o=t.gullet.popToken();const s=o.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(s))throw new n("Expected a control sequence",o);let i,a=0;const l=[[]];for(;"{"!==t.gullet.future().text;)if(o=t.gullet.popToken(),"#"===o.text){if("{"===t.gullet.future().text){i=t.gullet.future(),l[a].push("{");break}if(o=t.gullet.popToken(),!/^[1-9]$/.test(o.text))throw new n('Invalid argument number "'+o.text+'"');if(parseInt(o.text)!==a+1)throw new n('Argument number "'+o.text+'" out of order');a++,l.push([])}else{if("EOF"===o.text)throw new n("Expected a macro definition");l[a].push(o.text)}let{tokens:h}=t.gullet.consumeArg();return i&&h.unshift(i),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h),h.reverse()),t.gullet.macros.set(s,{tokens:h,numArgs:a,delimiters:l},r===$t[r]),{type:"internal",mode:t.mode}}}),$e({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e;const n=Zt(t.gullet.popToken());t.gullet.consumeSpaces();const o=(e=>{let t=e.gullet.popToken();return"="===t.text&&(t=e.gullet.popToken()," "===t.text&&(t=e.gullet.popToken())),t})(t);return Kt(t,n,o,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),$e({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){let{parser:t,funcName:r}=e;const n=Zt(t.gullet.popToken()),o=t.gullet.popToken(),s=t.gullet.popToken();return Kt(t,n,s,"\\\\globalfuture"===r),t.gullet.pushToken(s),t.gullet.pushToken(o),{type:"internal",mode:t.mode}}});const Jt=function(e,t,r){const n=N(se.math[e]&&se.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},Qt=function(e,t,r,n){const o=r.havingBaseStyle(t),s=Pe.makeSpan(n.concat(o.sizingClasses(r)),[e],r),i=o.sizeMultiplier/r.sizeMultiplier;return s.height*=i,s.depth*=i,s.maxFontSize=o.sizeMultiplier,s},er=function(e,t,r){const n=t.havingBaseStyle(r),o=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=F(o),e.height-=o,e.depth+=o},tr=function(e,t,r,n,o,s){const i=function(e,t,r,n){return Pe.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,o,n),a=Qt(Pe.makeSpan(["delimsizing","size"+t],[i],n),w.TEXT,n,s);return r&&er(a,n,w.TEXT),a},rr=function(e,t,r){let n;n="Size1-Regular"===t?"delim-size1":"delim-size4";return{type:"elem",elem:Pe.makeSpan(["delimsizinginner",n],[Pe.makeSpan([],[Pe.makeSymbol(e,t,r)])])}},nr=function(e,t,r){const n=T["Size4-Regular"][e.charCodeAt(0)]?T["Size4-Regular"][e.charCodeAt(0)][4]:T["Size1-Regular"][e.charCodeAt(0)][4],o=new Q("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),s=new J([o],{width:F(n),height:F(t),style:"width:"+F(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),i=Pe.makeSvgSpan([],[s],r);return i.height=t,i.style.height=F(t),i.style.width=F(n),{type:"elem",elem:i}},or={type:"kern",size:-.008},sr=["|","\\lvert","\\rvert","\\vert"],ir=["\\|","\\lVert","\\rVert","\\Vert"],ar=function(e,t,r,n,o,s){let i,a,h,c,m="",p=0;i=h=c=e,a=null;let u="Size1-Regular";"\\uparrow"===e?h=c="\u23d0":"\\Uparrow"===e?h=c="\u2016":"\\downarrow"===e?i=h="\u23d0":"\\Downarrow"===e?i=h="\u2016":"\\updownarrow"===e?(i="\\uparrow",h="\u23d0",c="\\downarrow"):"\\Updownarrow"===e?(i="\\Uparrow",h="\u2016",c="\\Downarrow"):l.contains(sr,e)?(h="\u2223",m="vert",p=333):l.contains(ir,e)?(h="\u2225",m="doublevert",p=556):"["===e||"\\lbrack"===e?(i="\u23a1",h="\u23a2",c="\u23a3",u="Size4-Regular",m="lbrack",p=667):"]"===e||"\\rbrack"===e?(i="\u23a4",h="\u23a5",c="\u23a6",u="Size4-Regular",m="rbrack",p=667):"\\lfloor"===e||"\u230a"===e?(h=i="\u23a2",c="\u23a3",u="Size4-Regular",m="lfloor",p=667):"\\lceil"===e||"\u2308"===e?(i="\u23a1",h=c="\u23a2",u="Size4-Regular",m="lceil",p=667):"\\rfloor"===e||"\u230b"===e?(h=i="\u23a5",c="\u23a6",u="Size4-Regular",m="rfloor",p=667):"\\rceil"===e||"\u2309"===e?(i="\u23a4",h=c="\u23a5",u="Size4-Regular",m="rceil",p=667):"("===e||"\\lparen"===e?(i="\u239b",h="\u239c",c="\u239d",u="Size4-Regular",m="lparen",p=875):")"===e||"\\rparen"===e?(i="\u239e",h="\u239f",c="\u23a0",u="Size4-Regular",m="rparen",p=875):"\\{"===e||"\\lbrace"===e?(i="\u23a7",a="\u23a8",c="\u23a9",h="\u23aa",u="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(i="\u23ab",a="\u23ac",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(i="\u23a7",c="\u23a9",h="\u23aa",u="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(i="\u23ab",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(i="\u23a7",c="\u23ad",h="\u23aa",u="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(i="\u23ab",c="\u23a9",h="\u23aa",u="Size4-Regular");const d=Jt(i,u,o),g=d.height+d.depth,f=Jt(h,u,o),b=f.height+f.depth,y=Jt(c,u,o),x=y.height+y.depth;let v=0,k=1;if(null!==a){const e=Jt(a,u,o);v=e.height+e.depth,k=2}const S=g+x+v,M=S+Math.max(0,Math.ceil((t-S)/(k*b)))*k*b;let z=n.fontMetrics().axisHeight;r&&(z*=n.sizeMultiplier);const A=M/2-z,T=[];if(m.length>0){const e=M-g-x,t=Math.round(1e3*M),r=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(m,Math.round(1e3*e)),o=new Q(m,r),s=(p/1e3).toFixed(3)+"em",i=(t/1e3).toFixed(3)+"em",a=new J([o],{width:s,height:i,viewBox:"0 0 "+p+" "+t}),l=Pe.makeSvgSpan([],[a],n);l.height=t/1e3,l.style.width=s,l.style.height=i,T.push({type:"elem",elem:l})}else{if(T.push(rr(c,u,o)),T.push(or),null===a){const e=M-g-x+.016;T.push(nr(h,e,n))}else{const e=(M-g-x-v)/2+.016;T.push(nr(h,e,n)),T.push(or),T.push(rr(a,u,o)),T.push(or),T.push(nr(h,e,n))}T.push(or),T.push(rr(i,u,o))}const B=n.havingBaseStyle(w.TEXT),C=Pe.makeVList({positionType:"bottom",positionData:A,children:T},B);return Qt(Pe.makeSpan(["delimsizing","mult"],[C],B),w.TEXT,n,s)},lr=.08,hr=function(e,t,r,n,o){const s=function(e,t,r){t*=1e3;let n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,M);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,M,r)}return n}(e,n,r),i=new Q(e,s),a=new J([i],{width:"400em",height:F(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Pe.makeSvgSpan(["hide-tail"],[a],o)},cr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],mr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],pr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],ur=[0,1.2,1.8,2.4,3],dr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],gr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"stack"}],fr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],br=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},yr=function(e,t,r,n){for(let o=Math.min(2,3-n.style.size);ot)return r[o]}return r[r.length-1]},xr=function(e,t,r,n,o,s){let i;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),i=l.contains(pr,e)?dr:l.contains(cr,e)?fr:gr;const a=yr(e,t,i,n);return"small"===a.type?function(e,t,r,n,o,s){const i=Pe.makeSymbol(e,"Main-Regular",o,n),a=Qt(i,t,n,s);return r&&er(a,n,t),a}(e,a.style,r,n,o,s):"large"===a.type?tr(e,a.size,r,n,o,s):ar(e,t,r,n,o,s)};var wr={sqrtImage:function(e,t){const r=t.havingBaseSizing(),n=yr("\\surd",e*r.sizeMultiplier,fr,r);let o=r.sizeMultiplier;const s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness);let i,a,l=0,h=0,c=0;return"small"===n.type?(c=1e3+1e3*s+80,e<1?o=1:e<1.4&&(o=.7),l=(1+s+lr)/o,h=(1+s)/o,i=hr("sqrtMain",l,c,s,t),i.style.minWidth="0.853em",a=.833/o):"large"===n.type?(c=1080*ur[n.size],h=(ur[n.size]+s)/o,l=(ur[n.size]+s+lr)/o,i=hr("sqrtSize"+n.size,l,c,s,t),i.style.minWidth="1.02em",a=1/o):(l=e+s+lr,h=e+s,c=Math.floor(1e3*e+s)+80,i=hr("sqrtTall",l,c,s,t),i.style.minWidth="0.742em",a=1.056),i.height=h,i.style.height=F(l),{span:i,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,o,s){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(cr,e)||l.contains(pr,e))return tr(e,t,!1,r,o,s);if(l.contains(mr,e))return ar(e,ur[t],!1,r,o,s);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:ur,customSizedDelim:xr,leftRightDelim:function(e,t,r,n,o,s){const i=n.fontMetrics().axisHeight*n.sizeMultiplier,a=5/n.fontMetrics().ptPerEm,l=Math.max(t-i,r+i),h=Math.max(l/500*901,2*l-a);return xr(e,h,!0,n,o,s)}};const vr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},kr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Sr(e,t){const r=Ot(e);if(r&&l.contains(kr,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Mr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}$e({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{const r=Sr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:vr[e.funcName].size,mclass:vr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Pe.makeSpan([e.mclass]):wr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{const t=[];"."!==e.delim&&t.push(bt(e.delim,e.mode));const r=new ft.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");const n=F(wr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),$e({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Sr(t[0],e).text,color:r}}}),$e({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=Sr(t[0],e),n=e.parser;++n.leftrightDepth;const o=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);const s=Rt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:o,left:r.text,right:s.delim,rightColor:s.color}},htmlBuilder:(e,t)=>{Mr(e);const r=ot(e.body,t,!0,["mopen","mclose"]);let n,o,s=0,i=0,a=!1;for(let e=0;e{Mr(e);const r=vt(e.body,t);if("."!==e.left){const t=new ft.MathNode("mo",[bt(e.left,e.mode)]);t.setAttribute("fence","true"),r.unshift(t)}if("."!==e.right){const t=new ft.MathNode("mo",[bt(e.right,e.mode)]);t.setAttribute("fence","true"),e.rightColor&&t.setAttribute("mathcolor",e.rightColor),r.push(t)}return yt(r)}}),$e({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{const r=Sr(t[0],e);if(!e.parser.leftrightDepth)throw new n("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{let r;if("."===e.delim)r=ht(t,[]);else{r=wr.sizedDelim(e.delim,1,t,e.mode,[]);const n={delim:e.delim,options:t};r.isMiddle=n}return r},mathmlBuilder:(e,t)=>{const r="\\vert"===e.delim||"|"===e.delim?bt("|","text"):bt(e.delim,e.mode),n=new ft.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n}});const zr=(e,t)=>{const r=Pe.wrapFragment(ct(e.body,t),t),n=e.label.slice(1);let o,s=t.sizeMultiplier,i=0;const a=l.isCharacterBox(e.body);if("sout"===n)o=Pe.makeSpan(["stretchy","sout"]),o.height=t.fontMetrics().defaultRuleThickness/s,i=-.5*t.fontMetrics().xHeight;else if("phase"===n){const e=P({number:.6,unit:"pt"},t),n=P({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;const a=r.height+r.depth+e+n;r.style.paddingLeft=F(a/2+e);const l=Math.floor(1e3*a*s),c="M400000 "+(h=l)+" H0 L"+h/2+" 0 l65 45 L145 "+(h-80)+" H400000z",m=new J([new Q("phase",c)],{width:"400em",height:F(l/1e3),viewBox:"0 0 400000 "+l,preserveAspectRatio:"xMinYMin slice"});o=Pe.makeSvgSpan(["hide-tail"],[m],t),o.style.height=F(a),i=r.depth+e+n}else{/cancel/.test(n)?a||r.classes.push("cancel-pad"):"angl"===n?r.classes.push("anglpad"):r.classes.push("boxpad");let s=0,l=0,h=0;/box/.test(n)?(h=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),s=t.fontMetrics().fboxsep+("colorbox"===n?0:h),l=s):"angl"===n?(h=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness),s=4*h,l=Math.max(0,.25-r.depth)):(s=a?.2:0,l=s),o=Nt(r,n,s,l,t),/fbox|boxed|fcolorbox/.test(n)?(o.style.borderStyle="solid",o.style.borderWidth=F(h)):"angl"===n&&.049!==h&&(o.style.borderTopWidth=F(h),o.style.borderRightWidth=F(h)),i=r.depth+l,e.backgroundColor&&(o.style.backgroundColor=e.backgroundColor,e.borderColor&&(o.style.borderColor=e.borderColor))}var h;let c;if(e.backgroundColor)c=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:i},{type:"elem",elem:r,shift:0}]},t);else{const e=/cancel|phase/.test(n)?["svg-align"]:[];c=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:o,shift:i,wrapperClasses:e}]},t)}return/cancel/.test(n)&&(c.height=r.height,c.depth=r.depth),/cancel/.test(n)&&!a?Pe.makeSpan(["mord","cancel-lap"],[c],t):Pe.makeSpan(["mord"],[c],t)},Ar=(e,t)=>{let r=0;const n=new ft.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[St(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){const r=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+r+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};$e({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){let{parser:n,funcName:o}=e;const s=Rt(t[0],"color-token").color,i=t[1];return{type:"enclose",mode:n.mode,label:o,backgroundColor:s,body:i}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){let{parser:n,funcName:o}=e;const s=Rt(t[0],"color-token").color,i=Rt(t[1],"color-token").color,a=t[2];return{type:"enclose",mode:n.mode,label:o,backgroundColor:i,borderColor:s,body:a}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),$e({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"enclose",mode:r.mode,label:n,body:o}},htmlBuilder:zr,mathmlBuilder:Ar}),$e({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){let{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});const Tr={};function Br(e){let{type:t,names:r,props:n,handler:o,htmlBuilder:s,mathmlBuilder:i}=e;const a={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:o};for(let e=0;e{if(!e.parser.settings.displayMode)throw new n("{"+e.envName+"} can be used only in display mode.")};function Or(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function Er(e,t,r){let{hskipBeforeAndAfter:o,addJot:s,cols:i,arraystretch:a,colSeparationType:l,autoTag:h,singleRow:c,emptySingleRow:m,maxNumCols:p,leqno:u}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!a){const t=e.gullet.expandMacroAsText("\\arraystretch");if(null==t)a=1;else if(a=parseFloat(t),!a||a<0)throw new n("Invalid \\arraystretch: "+t)}e.gullet.beginGroup();let d=[];const g=[d],f=[],b=[],y=null!=h?[]:void 0;function x(){h&&e.gullet.macros.set("\\@eqnsw","1",!0)}function w(){y&&(e.gullet.macros.get("\\df@tag")?(y.push(e.subparse([new Ir("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):y.push(Boolean(h)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(x(),b.push(Rr(e));;){let t=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),t={type:"ordgroup",mode:e.mode,body:t},r&&(t={type:"styling",mode:e.mode,style:r,body:[t]}),d.push(t);const o=e.fetch().text;if("&"===o){if(p&&d.length===p){if(c||l)throw new n("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===o){w(),1===d.length&&"styling"===t.type&&0===t.body[0].body.length&&(g.length>1||!m)&&g.pop(),b.length0&&(x+=.25),c.push({pos:x,isDashed:e[t]})}for(v(i[0]),r=0;r0&&(p+=y,le)))for(r=0;r=a)continue;(o>0||e.hskipBeforeAndAfter)&&(i=l.deflt(c.pregap,u),0!==i&&(z=Pe.makeSpan(["arraycolsep"],[]),z.style.width=F(i),M.push(z)));let d=[];for(r=0;r0){const e=Pe.makeLineSpan("hline",t,m),r=Pe.makeLineSpan("hdashline",t,m),n=[{type:"elem",elem:h,shift:0}];for(;c.length>0;){const t=c.pop(),o=t.pos-k;t.isDashed?n.push({type:"elem",elem:r,shift:o}):n.push({type:"elem",elem:e,shift:o})}h=Pe.makeVList({positionType:"individualShift",children:n},t)}if(0===T.length)return Pe.makeSpan(["mord"],[h],t);{let e=Pe.makeVList({positionType:"individualShift",children:T},t);return e=Pe.makeSpan(["tag"],[e],t),Pe.makeFragment([h,e])}},Vr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){const r=[],n=new ft.MathNode("mtd",[],["mtr-glue"]),o=new ft.MathNode("mtd",[],["mml-eqn-num"]);for(let s=0;s0){const t=e.cols;let r="",n=!1,o=0,i=t.length;"separator"===t[0].type&&(a+="top ",o=1),"separator"===t[t.length-1].type&&(a+="bottom ",i-=1);for(let e=o;e0?"left ":"",a+=c[c.length-1].length>0?"right ":"";for(let e=1;e-1?"alignat":"align",s="split"===e.envName,i=Er(e.parser,{cols:r,addJot:!0,autoTag:s?void 0:Or(e.envName),emptySingleRow:!0,colSeparationType:o,maxNumCols:s?2:void 0,leqno:e.parser.settings.leqno},"display");let a,l=0;const h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){let e="";for(let r=0;r0&&c&&(n=1),r[e]={type:"align",align:t,pregap:n,postgap:0}}return i.colSeparationType=c?"align":"alignat",i};Br({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){const r=(Ot(t[0])?[t[0]]:Rt(t[0],"ordgroup").body).map((function(e){const t=Ht(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),o={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,o,Lr(e.envName))},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){const t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")];let r="c";const o={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){const t=e.parser;if(t.consumeSpaces(),"["===t.fetch().text){if(t.consume(),t.consumeSpaces(),r=t.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",t.nextToken);t.consume(),t.consumeSpaces(),t.expect("]"),t.consume(),o.cols=[{type:"align",align:r}]}}const s=Er(e.parser,o,Lr(e.envName)),i=Math.max(0,...s.body.map((e=>e.length)));return s.cols=new Array(i).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[s],left:t[0],right:t[1],rightColor:void 0}:s},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){const t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){const r=(Ot(t[0])?[t[0]]:Rt(t[0],"ordgroup").body).map((function(e){const t=Ht(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");let o={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if(o=Er(e.parser,o,"script"),o.body.length>0&&o.body[0].length>1)throw new n("{subarray} can contain only one column");return o},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){const t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Lr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){l.contains(["gather","gather*"],e.envName)&&Hr(e);const t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Or(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Hr(e);const t={autoTag:Or(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Dr,mathmlBuilder:Pr}),Br({type:"array",names:["CD"],props:{numArgs:0},handler(e){return Hr(e),function(e){const t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();const r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}let r=[];const o=[r];for(let a=0;a-1);else{if(!("<>AV".indexOf(o)>-1))throw new n('Expected one of "<>AV=|." after @',l[t]);for(let e=0;e<2;e++){let r=!0;for(let h=t+1;h{const r=e.font,n=t.withFont(r);return ct(e.body,n)},Yr=(e,t)=>{const r=e.font,n=t.withFont(r);return St(e.body,n)},Xr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};$e({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=Ke(t[0]);let s=n;return s in Xr&&(s=Xr[s]),{type:"font",mode:r.mode,font:s.slice(1),body:o}},htmlBuilder:Ur,mathmlBuilder:Yr}),$e({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{let{parser:r}=e;const n=t[0],o=l.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:Ut(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:o}}}),$e({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{let{parser:r,funcName:n,breakOnTokenText:o}=e;const{mode:s}=r,i=r.parseExpression(!0,o);return{type:"font",mode:s,font:"math"+n.slice(1),body:{type:"ordgroup",mode:r.mode,body:i}}},htmlBuilder:Ur,mathmlBuilder:Yr});const Wr=(e,t)=>{let r=t;return"display"===e?r=r.id>=w.SCRIPT.id?r.text():w.DISPLAY:"text"===e&&r.size===w.DISPLAY.size?r=w.TEXT:"script"===e?r=w.SCRIPT:"scriptscript"===e&&(r=w.SCRIPTSCRIPT),r},_r=(e,t)=>{const r=Wr(e.size,t.style),n=r.fracNum(),o=r.fracDen();let s;s=t.havingStyle(n);const i=ct(e.numer,s,t);if(e.continued){const e=8.5/t.fontMetrics().ptPerEm,r=3.5/t.fontMetrics().ptPerEm;i.height=i.height0?3*c:7*c,u=t.fontMetrics().denom1):(h>0?(m=t.fontMetrics().num2,p=c):(m=t.fontMetrics().num3,p=3*c),u=t.fontMetrics().denom2),l){const e=t.fontMetrics().axisHeight;m-i.depth-(e+.5*h){let r=new ft.MathNode("mfrac",[St(e.numer,t),St(e.denom,t)]);if(e.hasBarLine){if(e.barSize){const n=P(e.barSize,t);r.setAttribute("linethickness",F(n))}}else r.setAttribute("linethickness","0px");const n=Wr(e.size,t.style);if(n.size!==t.style.size){r=new ft.MathNode("mstyle",[r]);const e=n.size===w.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",e),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){const t=[];if(null!=e.leftDelim){const r=new ft.MathNode("mo",[new ft.TextNode(e.leftDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}if(t.push(r),null!=e.rightDelim){const r=new ft.MathNode("mo",[new ft.TextNode(e.rightDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}return yt(t)}return r};$e({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];let i,a=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":i=!0;break;case"\\\\atopfrac":i=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":i=!1,a="(",l=")";break;case"\\\\bracefrac":i=!1,a="\\{",l="\\}";break;case"\\\\brackfrac":i=!1,a="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:r.mode,continued:!1,numer:o,denom:s,hasBarLine:i,leftDelim:a,rightDelim:l,size:h,barSize:null}},htmlBuilder:_r,mathmlBuilder:jr}),$e({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:o,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),$e({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){let t,{parser:r,funcName:n,token:o}=e;switch(n){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:o}}});const $r=["display","text","script","scriptscript"],Zr=function(e){let t=null;return e.length>0&&(t=e,t="."===t?null:t),t};$e({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){let{parser:r}=e;const n=t[4],o=t[5],s=Ke(t[0]),i="atom"===s.type&&"open"===s.family?Zr(s.text):null,a=Ke(t[1]),l="atom"===a.type&&"close"===a.family?Zr(a.text):null,h=Rt(t[2],"size");let c,m=null;h.isBlank?c=!0:(m=h.value,c=m.number>0);let p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){const e=Rt(u.body[0],"textord");p=$r[Number(e.text)]}}else u=Rt(u,"textord"),p=$r[Number(u.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:c,barSize:m,leftDelim:i,rightDelim:l,size:p}},htmlBuilder:_r,mathmlBuilder:jr}),$e({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){let{parser:r,funcName:n,token:o}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Rt(t[0],"size").value,token:o}}}),$e({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Rt(t[1],"infix").size),i=t[2],a=s.number>0;return{type:"genfrac",mode:r.mode,numer:o,denom:i,continued:!1,hasBarLine:a,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:_r,mathmlBuilder:jr});const Kr=(e,t)=>{const r=t.style;let n,o;"supsub"===e.type?(n=e.sup?ct(e.sup,t.havingStyle(r.sup()),t):ct(e.sub,t.havingStyle(r.sub()),t),o=Rt(e.base,"horizBrace")):o=Rt(e,"horizBrace");const s=ct(o.base,t.havingBaseStyle(w.DISPLAY)),i=It(o,t);let a;if(o.isOver?(a=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:i}]},t),a.children[0].children[0].children[1].classes.push("svg-align")):(a=Pe.makeVList({positionType:"bottom",positionData:s.depth+.1+i.height,children:[{type:"elem",elem:i},{type:"kern",size:.1},{type:"elem",elem:s}]},t),a.children[0].children[0].children[0].classes.push("svg-align")),n){const e=Pe.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t);a=o.isOver?Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"kern",size:.2},{type:"elem",elem:n}]},t):Pe.makeVList({positionType:"bottom",positionData:e.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:e}]},t)}return Pe.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t)};$e({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:Kr,mathmlBuilder:(e,t)=>{const r=qt(e.label);return new ft.MathNode(e.isOver?"mover":"munder",[St(e.base,t),r])}}),$e({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[1],o=Rt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:o})?{type:"href",mode:r.mode,href:o,body:Je(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{const r=ot(e.body,t,!1);return Pe.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{let r=kt(e.body,t);return r instanceof dt||(r=new dt("mrow",[r])),r.setAttribute("href",e.href),r}}),$e({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=Rt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");const o=[];for(let e=0;e{let{parser:r,funcName:o,token:s}=e;const i=Rt(t[0],"raw").string,a=t[1];let l;r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");const h={};switch(o){case"\\htmlClass":h.class=i,l={command:"\\htmlClass",class:i};break;case"\\htmlId":h.id=i,l={command:"\\htmlId",id:i};break;case"\\htmlStyle":h.style=i,l={command:"\\htmlStyle",style:i};break;case"\\htmlData":{const e=i.split(",");for(let t=0;t{const r=ot(e.body,t,!1),n=["enclosing"];e.attributes.class&&n.push(...e.attributes.class.trim().split(/\s+/));const o=Pe.makeSpan(n,r,t);for(const t in e.attributes)"class"!==t&&e.attributes.hasOwnProperty(t)&&o.setAttribute(t,e.attributes[t]);return o},mathmlBuilder:(e,t)=>kt(e.body,t)}),$e({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:Je(t[0]),mathml:Je(t[1])}},htmlBuilder:(e,t)=>{const r=ot(e.html,t,!1);return Pe.makeFragment(r)},mathmlBuilder:(e,t)=>kt(e.mathml,t)});const Jr=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};{const t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new n("Invalid size: '"+e+"' in \\includegraphics");const r={number:+(t[1]+t[2]),unit:t[3]};if(!V(r))throw new n("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r}};$e({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{let{parser:o}=e,s={number:0,unit:"em"},i={number:.9,unit:"em"},a={number:0,unit:"em"},l="";if(r[0]){const e=Rt(r[0],"raw").string.split(",");for(let t=0;t{const r=P(e.height,t);let n=0;e.totalheight.number>0&&(n=P(e.totalheight,t)-r);let o=0;e.width.number>0&&(o=P(e.width,t));const s={height:F(r+n)};o>0&&(s.width=F(o)),n>0&&(s.verticalAlign=F(-n));const i=new $(e.src,e.alt,s);return i.height=r,i.depth=n,i},mathmlBuilder:(e,t)=>{const r=new ft.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);const n=P(e.height,t);let o=0;if(e.totalheight.number>0&&(o=P(e.totalheight,t)-n,r.setAttribute("valign",F(-o))),r.setAttribute("height",F(n+o)),e.width.number>0){const n=P(e.width,t);r.setAttribute("width",F(n))}return r.setAttribute("src",e.src),r}}),$e({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=Rt(t[0],"size");if(r.settings.strict){const e="m"===n[1],t="mu"===o.value.unit;e?(t||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+o.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):t&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:o.value}},htmlBuilder(e,t){return Pe.makeGlue(e.dimension,t)},mathmlBuilder(e,t){const r=P(e.dimension,t);return new ft.SpaceNode(r)}}),$e({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:o}},htmlBuilder:(e,t)=>{let r;"clap"===e.alignment?(r=Pe.makeSpan([],[ct(e.body,t)]),r=Pe.makeSpan(["inner"],[r],t)):r=Pe.makeSpan(["inner"],[ct(e.body,t)]);const n=Pe.makeSpan(["fix"],[]);let o=Pe.makeSpan([e.alignment],[r,n],t);const s=Pe.makeSpan(["strut"]);return s.style.height=F(o.height+o.depth),o.depth&&(s.style.verticalAlign=F(-o.depth)),o.children.unshift(s),o=Pe.makeSpan(["thinbox"],[o],t),Pe.makeSpan(["mord","vbox"],[o],t)},mathmlBuilder:(e,t)=>{const r=new ft.MathNode("mpadded",[St(e.body,t)]);if("rlap"!==e.alignment){const t="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",t+"width")}return r.setAttribute("width","0px"),r}}),$e({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){let{funcName:r,parser:n}=e;const o=n.mode;n.switchMode("math");const s="\\("===r?"\\)":"$",i=n.parseExpression(!1,s);return n.expect(s),n.switchMode(o),{type:"styling",mode:n.mode,style:"text",body:i}}}),$e({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new n("Mismatched "+e.funcName)}});const Qr=(e,t)=>{switch(t.style.size){case w.DISPLAY.size:return e.display;case w.TEXT.size:return e.text;case w.SCRIPT.size:return e.script;case w.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};$e({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{let{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:Je(t[0]),text:Je(t[1]),script:Je(t[2]),scriptscript:Je(t[3])}},htmlBuilder:(e,t)=>{const r=Qr(e,t),n=ot(r,t,!1);return Pe.makeFragment(n)},mathmlBuilder:(e,t)=>{const r=Qr(e,t);return kt(r,t)}});const en=(e,t,r,n,o,s,i)=>{e=Pe.makeSpan([],[e]);const a=r&&l.isCharacterBox(r);let h,c,m;if(t){const e=ct(t,n.havingStyle(o.sup()),n);c={elem:e,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-e.depth)}}if(r){const e=ct(r,n.havingStyle(o.sub()),n);h={elem:e,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-e.height)}}if(c&&h){const t=n.fontMetrics().bigOpSpacing5+h.elem.height+h.elem.depth+h.kern+e.depth+i;m=Pe.makeVList({positionType:"bottom",positionData:t,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:h.elem,marginLeft:F(-s)},{type:"kern",size:h.kern},{type:"elem",elem:e},{type:"kern",size:c.kern},{type:"elem",elem:c.elem,marginLeft:F(s)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(h){const t=e.height-i;m=Pe.makeVList({positionType:"top",positionData:t,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:h.elem,marginLeft:F(-s)},{type:"kern",size:h.kern},{type:"elem",elem:e}]},n)}else{if(!c)return e;{const t=e.depth+i;m=Pe.makeVList({positionType:"bottom",positionData:t,children:[{type:"elem",elem:e},{type:"kern",size:c.kern},{type:"elem",elem:c.elem,marginLeft:F(s)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}}const p=[m];if(h&&0!==s&&!a){const e=Pe.makeSpan(["mspace"],[],n);e.style.marginRight=F(s),p.unshift(e)}return Pe.makeSpan(["mop","op-limits"],p,n)},tn=["\\smallint"],rn=(e,t)=>{let r,n,o,s=!1;"supsub"===e.type?(r=e.sup,n=e.sub,o=Rt(e.base,"op"),s=!0):o=Rt(e,"op");const i=t.style;let a,h=!1;if(i.size===w.DISPLAY.size&&o.symbol&&!l.contains(tn,o.name)&&(h=!0),o.symbol){const e=h?"Size2-Regular":"Size1-Regular";let r="";if("\\oiint"!==o.name&&"\\oiiint"!==o.name||(r=o.name.slice(1),o.name="oiint"===r?"\\iint":"\\iiint"),a=Pe.makeSymbol(o.name,e,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),r.length>0){const e=a.italic,n=Pe.staticSvg(r+"Size"+(h?"2":"1"),t);a=Pe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:0},{type:"elem",elem:n,shift:h?.08:0}]},t),o.name="\\"+r,a.classes.unshift("mop"),a.italic=e}}else if(o.body){const e=ot(o.body,t,!0);1===e.length&&e[0]instanceof K?(a=e[0],a.classes[0]="mop"):a=Pe.makeSpan(["mop"],e,t)}else{const e=[];for(let r=1;r{let r;if(e.symbol)r=new dt("mo",[bt(e.name,e.mode)]),l.contains(tn,e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new dt("mo",vt(e.body,t));else{r=new dt("mi",[new gt(e.name.slice(1))]);const t=new dt("mo",[bt("\u2061","text")]);r=e.parentIsSupSub?new dt("mrow",[r,t]):ut([r,t])}return r},on={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};$e({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{let{parser:r,funcName:n}=e,o=n;return 1===o.length&&(o=on[o]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:o}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:Je(n)}},htmlBuilder:rn,mathmlBuilder:nn});const sn={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};$e({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:rn,mathmlBuilder:nn}),$e({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){let{parser:t,funcName:r}=e,n=r;return 1===n.length&&(n=sn[n]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:rn,mathmlBuilder:nn});const an=(e,t)=>{let r,n,o,s,i=!1;if("supsub"===e.type?(r=e.sup,n=e.sub,o=Rt(e.base,"operatorname"),i=!0):o=Rt(e,"operatorname"),o.body.length>0){const e=o.body.map((e=>{const t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),r=ot(e,t.withFont("mathrm"),!0);for(let e=0;e{let{parser:r,funcName:n}=e;const o=t[0];return{type:"operatorname",mode:r.mode,body:Je(o),alwaysHandleSupSub:"\\operatornamewithlimits"===n,limits:!1,parentIsSupSub:!1}},htmlBuilder:an,mathmlBuilder:(e,t)=>{let r=vt(e.body,t.withFont("mathrm")),n=!0;for(let e=0;ee.toText())).join("");r=[new ft.TextNode(e)]}const o=new ft.MathNode("mi",r);o.setAttribute("mathvariant","normal");const s=new ft.MathNode("mo",[bt("\u2061","text")]);return e.parentIsSupSub?new ft.MathNode("mrow",[o,s]):ft.newDocumentFragment([o,s])}}),Nr("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),Ze({type:"ordgroup",htmlBuilder(e,t){return e.semisimple?Pe.makeFragment(ot(e.body,t,!1)):Pe.makeSpan(["mord"],ot(e.body,t,!0),t)},mathmlBuilder(e,t){return kt(e.body,t,!0)}}),$e({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){let{parser:r}=e;const n=t[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(e,t){const r=ct(e.body,t.havingCrampedStyle()),n=Pe.makeLineSpan("overline-line",t),o=t.fontMetrics().defaultRuleThickness,s=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*o},{type:"elem",elem:n},{type:"kern",size:o}]},t);return Pe.makeSpan(["mord","overline"],[s],t)},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[new ft.TextNode("\u203e")]);r.setAttribute("stretchy","true");const n=new ft.MathNode("mover",[St(e.body,t),r]);return n.setAttribute("accent","true"),n}}),$e({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"phantom",mode:r.mode,body:Je(n)}},htmlBuilder:(e,t)=>{const r=ot(e.body,t.withPhantom(),!1);return Pe.makeFragment(r)},mathmlBuilder:(e,t)=>{const r=vt(e.body,t);return new ft.MathNode("mphantom",r)}}),$e({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"hphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{let r=Pe.makeSpan([],[ct(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(let e=0;e{const r=vt(Je(e.body),t),n=new ft.MathNode("mphantom",r),o=new ft.MathNode("mpadded",[n]);return o.setAttribute("height","0px"),o.setAttribute("depth","0px"),o}}),$e({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[0];return{type:"vphantom",mode:r.mode,body:n}},htmlBuilder:(e,t)=>{const r=Pe.makeSpan(["inner"],[ct(e.body,t.withPhantom())]),n=Pe.makeSpan(["fix"],[]);return Pe.makeSpan(["mord","rlap"],[r,n],t)},mathmlBuilder:(e,t)=>{const r=vt(Je(e.body),t),n=new ft.MathNode("mphantom",r),o=new ft.MathNode("mpadded",[n]);return o.setAttribute("width","0px"),o}}),$e({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){let{parser:r}=e;const n=Rt(t[0],"size").value,o=t[1];return{type:"raisebox",mode:r.mode,dy:n,body:o}},htmlBuilder(e,t){const r=ct(e.body,t),n=P(e.dy,t);return Pe.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){const r=new ft.MathNode("mpadded",[St(e.body,t)]),n=e.dy.number+e.dy.unit;return r.setAttribute("voffset",n),r}}),$e({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(e){let{parser:t}=e;return{type:"internal",mode:t.mode}}}),$e({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(e,t,r){let{parser:n}=e;const o=r[0],s=Rt(t[0],"size"),i=Rt(t[1],"size");return{type:"rule",mode:n.mode,shift:o&&Rt(o,"size").value,width:s.value,height:i.value}},htmlBuilder(e,t){const r=Pe.makeSpan(["mord","rule"],[],t),n=P(e.width,t),o=P(e.height,t),s=e.shift?P(e.shift,t):0;return r.style.borderRightWidth=F(n),r.style.borderTopWidth=F(o),r.style.bottom=F(s),r.width=n,r.height=o+s,r.depth=-s,r.maxFontSize=1.125*o*t.sizeMultiplier,r},mathmlBuilder(e,t){const r=P(e.width,t),n=P(e.height,t),o=e.shift?P(e.shift,t):0,s=t.color&&t.getColor()||"black",i=new ft.MathNode("mspace");i.setAttribute("mathbackground",s),i.setAttribute("width",F(r)),i.setAttribute("height",F(n));const a=new ft.MathNode("mpadded",[i]);return o>=0?a.setAttribute("height",F(o)):(a.setAttribute("height",F(o)),a.setAttribute("depth",F(-o))),a.setAttribute("voffset",F(o)),a}});const hn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];$e({type:"sizing",names:hn,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{let{breakOnTokenText:r,funcName:n,parser:o}=e;const s=o.parseExpression(!1,r);return{type:"sizing",mode:o.mode,size:hn.indexOf(n)+1,body:s}},htmlBuilder:(e,t)=>{const r=t.havingSize(e.size);return ln(e.body,r,t)},mathmlBuilder:(e,t)=>{const r=t.havingSize(e.size),n=vt(e.body,r),o=new ft.MathNode("mstyle",n);return o.setAttribute("mathsize",F(r.sizeMultiplier)),o}}),$e({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{let{parser:n}=e,o=!1,s=!1;const i=r[0]&&Rt(r[0],"ordgroup");if(i){let e="";for(let t=0;t{const r=Pe.makeSpan([],[ct(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(let e=0;e{const r=new ft.MathNode("mpadded",[St(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),$e({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){let{parser:n}=e;const o=r[0],s=t[0];return{type:"sqrt",mode:n.mode,body:s,index:o}},htmlBuilder(e,t){let r=ct(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Pe.wrapFragment(r,t);const n=t.fontMetrics().defaultRuleThickness;let o=n;t.style.idr.height+r.depth+s&&(s=(s+c-r.height-r.depth)/2);const m=a.height-r.height-s-l;r.style.paddingLeft=F(h);const p=Pe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+m)},{type:"elem",elem:a},{type:"kern",size:l}]},t);if(e.index){const r=t.havingStyle(w.SCRIPTSCRIPT),n=ct(e.index,r,t),o=.6*(p.height-p.depth),s=Pe.makeVList({positionType:"shift",positionData:-o,children:[{type:"elem",elem:n}]},t),i=Pe.makeSpan(["root"],[s]);return Pe.makeSpan(["mord","sqrt"],[i,p],t)}return Pe.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){const{body:r,index:n}=e;return n?new ft.MathNode("mroot",[St(r,t),St(n,t)]):new ft.MathNode("msqrt",[St(r,t)])}});const cn={display:w.DISPLAY,text:w.TEXT,script:w.SCRIPT,scriptscript:w.SCRIPTSCRIPT};$e({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){let{breakOnTokenText:r,funcName:n,parser:o}=e;const s=o.parseExpression(!0,r),i=n.slice(1,n.length-5);return{type:"styling",mode:o.mode,style:i,body:s}},htmlBuilder(e,t){const r=cn[e.style],n=t.havingStyle(r).withFont("");return ln(e.body,n,t)},mathmlBuilder(e,t){const r=cn[e.style],n=t.havingStyle(r),o=vt(e.body,n),s=new ft.MathNode("mstyle",o),i={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return s.setAttribute("scriptlevel",i[0]),s.setAttribute("displaystyle",i[1]),s}});Ze({type:"supsub",htmlBuilder(e,t){const r=function(e,t){const r=e.base;if(r)return"op"===r.type?r.limits&&(t.style.size===w.DISPLAY.size||r.alwaysHandleSupSub)?rn:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===w.DISPLAY.size||r.limits)?an:null:"accent"===r.type?l.isCharacterBox(r.base)?Et:null:"horizBrace"===r.type&&!e.sub===r.isOver?Kr:null;return null}(e,t);if(r)return r(e,t);const{base:n,sup:o,sub:s}=e,i=ct(n,t);let a,h;const c=t.fontMetrics();let m=0,p=0;const u=n&&l.isCharacterBox(n);if(o){const e=t.havingStyle(t.style.sup());a=ct(o,e,t),u||(m=i.height-e.fontMetrics().supDrop*e.sizeMultiplier/t.sizeMultiplier)}if(s){const e=t.havingStyle(t.style.sub());h=ct(s,e,t),u||(p=i.depth+e.fontMetrics().subDrop*e.sizeMultiplier/t.sizeMultiplier)}let d;d=t.style===w.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;const g=t.sizeMultiplier,f=F(.5/c.ptPerEm/g);let b,y=null;if(h){const t=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(i instanceof K||t)&&(y=F(-i.italic))}if(a&&h){m=Math.max(m,d,a.depth+.25*c.xHeight),p=Math.max(p,c.sub2);const e=4*c.defaultRuleThickness;if(m-a.depth-(h.height-p)0&&(m+=t,p-=t)}const r=[{type:"elem",elem:h,shift:p,marginRight:f,marginLeft:y},{type:"elem",elem:a,shift:-m,marginRight:f}];b=Pe.makeVList({positionType:"individualShift",children:r},t)}else if(h){p=Math.max(p,c.sub1,h.height-.8*c.xHeight);const e=[{type:"elem",elem:h,marginLeft:y,marginRight:f}];b=Pe.makeVList({positionType:"shift",positionData:p,children:e},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");m=Math.max(m,d,a.depth+.25*c.xHeight),b=Pe.makeVList({positionType:"shift",positionData:-m,children:[{type:"elem",elem:a,marginRight:f}]},t)}const x=lt(i,"right")||"mord";return Pe.makeSpan([x],[i,Pe.makeSpan(["msupsub"],[b])],t)},mathmlBuilder(e,t){let r,n,o=!1;e.base&&"horizBrace"===e.base.type&&(n=!!e.sup,n===e.base.isOver&&(o=!0,r=e.base.isOver)),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);const s=[St(e.base,t)];let i;if(e.sub&&s.push(St(e.sub,t)),e.sup&&s.push(St(e.sup,t)),o)i=r?"mover":"munder";else if(e.sub)if(e.sup){const r=e.base;i=r&&"op"===r.type&&r.limits&&t.style===w.DISPLAY||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(t.style===w.DISPLAY||r.limits)?"munderover":"msubsup"}else{const r=e.base;i=r&&"op"===r.type&&r.limits&&(t.style===w.DISPLAY||r.alwaysHandleSupSub)||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(r.limits||t.style===w.DISPLAY)?"munder":"msub"}else{const r=e.base;i=r&&"op"===r.type&&r.limits&&(t.style===w.DISPLAY||r.alwaysHandleSupSub)||r&&"operatorname"===r.type&&r.alwaysHandleSupSub&&(r.limits||t.style===w.DISPLAY)?"mover":"msup"}return new ft.MathNode(i,s)}}),Ze({type:"atom",htmlBuilder(e,t){return Pe.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[bt(e.text,e.mode)]);if("bin"===e.family){const n=xt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});const mn={mi:"italic",mn:"normal",mtext:"normal"};Ze({type:"mathord",htmlBuilder(e,t){return Pe.makeOrd(e,t,"mathord")},mathmlBuilder(e,t){const r=new ft.MathNode("mi",[bt(e.text,e.mode,t)]),n=xt(e,t)||"italic";return n!==mn[r.type]&&r.setAttribute("mathvariant",n),r}}),Ze({type:"textord",htmlBuilder(e,t){return Pe.makeOrd(e,t,"textord")},mathmlBuilder(e,t){const r=bt(e.text,e.mode,t),n=xt(e,t)||"normal";let o;return o="text"===e.mode?new ft.MathNode("mtext",[r]):/[0-9]/.test(e.text)?new ft.MathNode("mn",[r]):"\\prime"===e.text?new ft.MathNode("mo",[r]):new ft.MathNode("mi",[r]),n!==mn[o.type]&&o.setAttribute("mathvariant",n),o}});const pn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},un={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};Ze({type:"spacing",htmlBuilder(e,t){if(un.hasOwnProperty(e.text)){const r=un[e.text].className||"";if("text"===e.mode){const n=Pe.makeOrd(e,t,"textord");return n.classes.push(r),n}return Pe.makeSpan(["mspace",r],[Pe.mathsym(e.text,e.mode,t)],t)}if(pn.hasOwnProperty(e.text))return Pe.makeSpan(["mspace",pn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){let r;if(!un.hasOwnProperty(e.text)){if(pn.hasOwnProperty(e.text))return new ft.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return r=new ft.MathNode("mtext",[new ft.TextNode("\xa0")]),r}});const dn=()=>{const e=new ft.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};Ze({type:"tag",mathmlBuilder(e,t){const r=new ft.MathNode("mtable",[new ft.MathNode("mtr",[dn(),new ft.MathNode("mtd",[kt(e.body,t)]),dn(),new ft.MathNode("mtd",[kt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});const gn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},fn={"\\textbf":"textbf","\\textmd":"textmd"},bn={"\\textit":"textit","\\textup":"textup"},yn=(e,t)=>{const r=e.font;return r?gn[r]?t.withTextFontFamily(gn[r]):fn[r]?t.withTextFontWeight(fn[r]):"\\emph"===r?"textit"===t.fontShape?t.withTextFontShape("textup"):t.withTextFontShape("textit"):t.withTextFontShape(bn[r]):t};$e({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){let{parser:r,funcName:n}=e;const o=t[0];return{type:"text",mode:r.mode,body:Je(o),font:n}},htmlBuilder(e,t){const r=yn(e,t),n=ot(e.body,r,!0);return Pe.makeSpan(["mord","text"],n,r)},mathmlBuilder(e,t){const r=yn(e,t);return kt(e.body,r)}}),$e({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){let{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){const r=ct(e.body,t),n=Pe.makeLineSpan("underline-line",t),o=t.fontMetrics().defaultRuleThickness,s=Pe.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:o},{type:"elem",elem:n},{type:"kern",size:3*o},{type:"elem",elem:r}]},t);return Pe.makeSpan(["mord","underline"],[s],t)},mathmlBuilder(e,t){const r=new ft.MathNode("mo",[new ft.TextNode("\u203e")]);r.setAttribute("stretchy","true");const n=new ft.MathNode("munder",[St(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),$e({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){let{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){const r=ct(e.body,t),n=t.fontMetrics().axisHeight,o=.5*(r.height-n-(r.depth+n));return Pe.makeVList({positionType:"shift",positionData:o,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){return new ft.MathNode("mpadded",[St(e.body,t)],["vcenter"])}}),$e({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){const r=xn(e),n=[],o=t.havingStyle(t.style.text());for(let t=0;te.body.replace(/ /g,e.star?"\u2423":"\xa0");var wn=We;const vn="[ \r\n\t]",kn="(\\\\[a-zA-Z@]+)"+vn+"*",Sn="[\u0300-\u036f]",Mn=new RegExp(Sn+"+$"),zn="("+vn+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Sn+"*|[\ud800-\udbff][\udc00-\udfff]"+Sn+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+kn+"|\\\\[^\ud800-\udfff])";class An{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(zn,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){const e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new Ir("EOF",new qr(this,t,t));const r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new n("Unexpected character: '"+e[t]+"'",new Ir(e[t],new qr(this,t,t+1)));const o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){const t=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===t?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=t+1,this.lex()}return new Ir(o,new qr(this,t,this.tokenRegex.lastIndex))}}class Tn{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new n("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");const e=this.undefStack.pop();for(const t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(let t=0;t0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{const t=this.undefStack[this.undefStack.length-1];t&&!t.hasOwnProperty(e)&&(t[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Bn=Cr;Nr("\\noexpand",(function(e){const t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Nr("\\expandafter",(function(e){const t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Nr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Nr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Nr("\\@ifnextchar",(function(e){const t=e.consumeArgs(3);e.consumeSpaces();const r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Nr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Nr("\\TextOrMath",(function(e){const t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));const Cn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Nr("\\char",(function(e){let t,r=e.popToken(),o="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if(r=e.popToken(),"\\"===r.text[0])o=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");o=r.text.charCodeAt(0)}else t=10;if(t){if(o=Cn[r.text],null==o||o>=t)throw new n("Invalid base-"+t+" digit "+r.text);let s;for(;null!=(s=Cn[e.future().text])&&s{let s=e.consumeArg().tokens;if(1!==s.length)throw new n("\\newcommand's first argument must be a macro name");const i=s[0].text,a=e.isDefined(i);if(a&&!t)throw new n("\\newcommand{"+i+"} attempting to redefine "+i+"; use \\renewcommand");if(!a&&!r)throw new n("\\renewcommand{"+i+"} when command "+i+" does not yet exist; use \\newcommand");let l=0;if(s=e.consumeArg().tokens,1===s.length&&"["===s[0].text){let t="",r=e.expandNextToken();for(;"]"!==r.text&&"EOF"!==r.text;)t+=r.text,r=e.expandNextToken();if(!t.match(/^\s*[0-9]+\s*$/))throw new n("Invalid number of arguments: "+t);l=parseInt(t),s=e.consumeArg().tokens}return a&&o||e.macros.set(i,{tokens:s,numArgs:l}),""};Nr("\\newcommand",(e=>Nn(e,!1,!0,!1))),Nr("\\renewcommand",(e=>Nn(e,!0,!1,!1))),Nr("\\providecommand",(e=>Nn(e,!0,!0,!0))),Nr("\\message",(e=>{const t=e.consumeArgs(1)[0];return console.log(t.reverse().map((e=>e.text)).join("")),""})),Nr("\\errmessage",(e=>{const t=e.consumeArgs(1)[0];return console.error(t.reverse().map((e=>e.text)).join("")),""})),Nr("\\show",(e=>{const t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),wn[r],se.math[r],se.text[r]),""})),Nr("\\bgroup","{"),Nr("\\egroup","}"),Nr("~","\\nobreakspace"),Nr("\\lq","`"),Nr("\\rq","'"),Nr("\\aa","\\r a"),Nr("\\AA","\\r A"),Nr("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Nr("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Nr("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Nr("\u212c","\\mathscr{B}"),Nr("\u2130","\\mathscr{E}"),Nr("\u2131","\\mathscr{F}"),Nr("\u210b","\\mathscr{H}"),Nr("\u2110","\\mathscr{I}"),Nr("\u2112","\\mathscr{L}"),Nr("\u2133","\\mathscr{M}"),Nr("\u211b","\\mathscr{R}"),Nr("\u212d","\\mathfrak{C}"),Nr("\u210c","\\mathfrak{H}"),Nr("\u2128","\\mathfrak{Z}"),Nr("\\Bbbk","\\Bbb{k}"),Nr("\xb7","\\cdotp"),Nr("\\llap","\\mathllap{\\textrm{#1}}"),Nr("\\rlap","\\mathrlap{\\textrm{#1}}"),Nr("\\clap","\\mathclap{\\textrm{#1}}"),Nr("\\mathstrut","\\vphantom{(}"),Nr("\\underbar","\\underline{\\text{#1}}"),Nr("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Nr("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Nr("\\ne","\\neq"),Nr("\u2260","\\neq"),Nr("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Nr("\u2209","\\notin"),Nr("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Nr("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Nr("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Nr("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Nr("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Nr("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Nr("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Nr("\u27c2","\\perp"),Nr("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Nr("\u220c","\\notni"),Nr("\u231c","\\ulcorner"),Nr("\u231d","\\urcorner"),Nr("\u231e","\\llcorner"),Nr("\u231f","\\lrcorner"),Nr("\xa9","\\copyright"),Nr("\xae","\\textregistered"),Nr("\ufe0f","\\textregistered"),Nr("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Nr("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Nr("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Nr("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Nr("\\vdots","{\\varvdots\\rule{0pt}{15pt}}"),Nr("\u22ee","\\vdots"),Nr("\\varGamma","\\mathit{\\Gamma}"),Nr("\\varDelta","\\mathit{\\Delta}"),Nr("\\varTheta","\\mathit{\\Theta}"),Nr("\\varLambda","\\mathit{\\Lambda}"),Nr("\\varXi","\\mathit{\\Xi}"),Nr("\\varPi","\\mathit{\\Pi}"),Nr("\\varSigma","\\mathit{\\Sigma}"),Nr("\\varUpsilon","\\mathit{\\Upsilon}"),Nr("\\varPhi","\\mathit{\\Phi}"),Nr("\\varPsi","\\mathit{\\Psi}"),Nr("\\varOmega","\\mathit{\\Omega}"),Nr("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Nr("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Nr("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Nr("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Nr("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Nr("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;"),Nr("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}"),Nr("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");const qn={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Nr("\\dots",(function(e){let t="\\dotso";const r=e.expandAfterFuture().text;return r in qn?t=qn[r]:("\\not"===r.slice(0,4)||r in se.math&&l.contains(["bin","rel"],se.math[r].group))&&(t="\\dotsb"),t}));const In={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Nr("\\dotso",(function(e){return e.future().text in In?"\\ldots\\,":"\\ldots"})),Nr("\\dotsc",(function(e){const t=e.future().text;return t in In&&","!==t?"\\ldots\\,":"\\ldots"})),Nr("\\cdots",(function(e){return e.future().text in In?"\\@cdots\\,":"\\@cdots"})),Nr("\\dotsb","\\cdots"),Nr("\\dotsm","\\cdots"),Nr("\\dotsi","\\!\\cdots"),Nr("\\dotsx","\\ldots\\,"),Nr("\\DOTSI","\\relax"),Nr("\\DOTSB","\\relax"),Nr("\\DOTSX","\\relax"),Nr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Nr("\\,","\\tmspace+{3mu}{.1667em}"),Nr("\\thinspace","\\,"),Nr("\\>","\\mskip{4mu}"),Nr("\\:","\\tmspace+{4mu}{.2222em}"),Nr("\\medspace","\\:"),Nr("\\;","\\tmspace+{5mu}{.2777em}"),Nr("\\thickspace","\\;"),Nr("\\!","\\tmspace-{3mu}{.1667em}"),Nr("\\negthinspace","\\!"),Nr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Nr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Nr("\\enspace","\\kern.5em "),Nr("\\enskip","\\hskip.5em\\relax"),Nr("\\quad","\\hskip1em\\relax"),Nr("\\qquad","\\hskip2em\\relax"),Nr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Nr("\\tag@paren","\\tag@literal{({#1})}"),Nr("\\tag@literal",(e=>{if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Nr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Nr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Nr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Nr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Nr("\\newline","\\\\\\relax"),Nr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");const Rn=F(T["Main-Regular"]["T".charCodeAt(0)][1]-.7*T["Main-Regular"]["A".charCodeAt(0)][1]);Nr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Rn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Nr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Rn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Nr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Nr("\\@hspace","\\hskip #1\\relax"),Nr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Nr("\\ordinarycolon",":"),Nr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Nr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Nr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Nr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Nr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Nr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Nr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Nr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Nr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Nr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Nr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Nr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Nr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Nr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Nr("\u2237","\\dblcolon"),Nr("\u2239","\\eqcolon"),Nr("\u2254","\\coloneqq"),Nr("\u2255","\\eqqcolon"),Nr("\u2a74","\\Coloneqq"),Nr("\\ratio","\\vcentcolon"),Nr("\\coloncolon","\\dblcolon"),Nr("\\colonequals","\\coloneqq"),Nr("\\coloncolonequals","\\Coloneqq"),Nr("\\equalscolon","\\eqqcolon"),Nr("\\equalscoloncolon","\\Eqqcolon"),Nr("\\colonminus","\\coloneq"),Nr("\\coloncolonminus","\\Coloneq"),Nr("\\minuscolon","\\eqcolon"),Nr("\\minuscoloncolon","\\Eqcolon"),Nr("\\coloncolonapprox","\\Colonapprox"),Nr("\\coloncolonsim","\\Colonsim"),Nr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Nr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Nr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Nr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Nr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Nr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Nr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Nr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Nr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Nr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Nr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Nr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Nr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Nr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Nr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Nr("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Nr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Nr("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Nr("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Nr("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Nr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Nr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Nr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Nr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Nr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Nr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Nr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Nr("\\imath","\\html@mathml{\\@imath}{\u0131}"),Nr("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Nr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Nr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Nr("\u27e6","\\llbracket"),Nr("\u27e7","\\rrbracket"),Nr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Nr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Nr("\u2983","\\lBrace"),Nr("\u2984","\\rBrace"),Nr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Nr("\u29b5","\\minuso"),Nr("\\darr","\\downarrow"),Nr("\\dArr","\\Downarrow"),Nr("\\Darr","\\Downarrow"),Nr("\\lang","\\langle"),Nr("\\rang","\\rangle"),Nr("\\uarr","\\uparrow"),Nr("\\uArr","\\Uparrow"),Nr("\\Uarr","\\Uparrow"),Nr("\\N","\\mathbb{N}"),Nr("\\R","\\mathbb{R}"),Nr("\\Z","\\mathbb{Z}"),Nr("\\alef","\\aleph"),Nr("\\alefsym","\\aleph"),Nr("\\Alpha","\\mathrm{A}"),Nr("\\Beta","\\mathrm{B}"),Nr("\\bull","\\bullet"),Nr("\\Chi","\\mathrm{X}"),Nr("\\clubs","\\clubsuit"),Nr("\\cnums","\\mathbb{C}"),Nr("\\Complex","\\mathbb{C}"),Nr("\\Dagger","\\ddagger"),Nr("\\diamonds","\\diamondsuit"),Nr("\\empty","\\emptyset"),Nr("\\Epsilon","\\mathrm{E}"),Nr("\\Eta","\\mathrm{H}"),Nr("\\exist","\\exists"),Nr("\\harr","\\leftrightarrow"),Nr("\\hArr","\\Leftrightarrow"),Nr("\\Harr","\\Leftrightarrow"),Nr("\\hearts","\\heartsuit"),Nr("\\image","\\Im"),Nr("\\infin","\\infty"),Nr("\\Iota","\\mathrm{I}"),Nr("\\isin","\\in"),Nr("\\Kappa","\\mathrm{K}"),Nr("\\larr","\\leftarrow"),Nr("\\lArr","\\Leftarrow"),Nr("\\Larr","\\Leftarrow"),Nr("\\lrarr","\\leftrightarrow"),Nr("\\lrArr","\\Leftrightarrow"),Nr("\\Lrarr","\\Leftrightarrow"),Nr("\\Mu","\\mathrm{M}"),Nr("\\natnums","\\mathbb{N}"),Nr("\\Nu","\\mathrm{N}"),Nr("\\Omicron","\\mathrm{O}"),Nr("\\plusmn","\\pm"),Nr("\\rarr","\\rightarrow"),Nr("\\rArr","\\Rightarrow"),Nr("\\Rarr","\\Rightarrow"),Nr("\\real","\\Re"),Nr("\\reals","\\mathbb{R}"),Nr("\\Reals","\\mathbb{R}"),Nr("\\Rho","\\mathrm{P}"),Nr("\\sdot","\\cdot"),Nr("\\sect","\\S"),Nr("\\spades","\\spadesuit"),Nr("\\sub","\\subset"),Nr("\\sube","\\subseteq"),Nr("\\supe","\\supseteq"),Nr("\\Tau","\\mathrm{T}"),Nr("\\thetasym","\\vartheta"),Nr("\\weierp","\\wp"),Nr("\\Zeta","\\mathrm{Z}"),Nr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Nr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Nr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Nr("\\bra","\\mathinner{\\langle{#1}|}"),Nr("\\ket","\\mathinner{|{#1}\\rangle}"),Nr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Nr("\\Bra","\\left\\langle#1\\right|"),Nr("\\Ket","\\left|#1\\right\\rangle");const Hn=e=>t=>{const r=t.consumeArg().tokens,n=t.consumeArg().tokens,o=t.consumeArg().tokens,s=t.consumeArg().tokens,i=t.macros.get("|"),a=t.macros.get("\\|");t.macros.beginGroup();const l=t=>r=>{e&&(r.macros.set("|",i),o.length&&r.macros.set("\\|",a));let s=t;if(!t&&o.length){"|"===r.future().text&&(r.popToken(),s=!0)}return{tokens:s?o:n,numArgs:0}};t.macros.set("|",l(!1)),o.length&&t.macros.set("\\|",l(!0));const h=t.consumeArg().tokens,c=t.expandTokens([...s,...h,...r]);return t.macros.endGroup(),{tokens:c.reverse(),numArgs:0}};Nr("\\bra@ket",Hn(!1)),Nr("\\bra@set",Hn(!0)),Nr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Nr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Nr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Nr("\\angln","{\\angl n}"),Nr("\\blue","\\textcolor{##6495ed}{#1}"),Nr("\\orange","\\textcolor{##ffa500}{#1}"),Nr("\\pink","\\textcolor{##ff00af}{#1}"),Nr("\\red","\\textcolor{##df0030}{#1}"),Nr("\\green","\\textcolor{##28ae7b}{#1}"),Nr("\\gray","\\textcolor{gray}{#1}"),Nr("\\purple","\\textcolor{##9d38bd}{#1}"),Nr("\\blueA","\\textcolor{##ccfaff}{#1}"),Nr("\\blueB","\\textcolor{##80f6ff}{#1}"),Nr("\\blueC","\\textcolor{##63d9ea}{#1}"),Nr("\\blueD","\\textcolor{##11accd}{#1}"),Nr("\\blueE","\\textcolor{##0c7f99}{#1}"),Nr("\\tealA","\\textcolor{##94fff5}{#1}"),Nr("\\tealB","\\textcolor{##26edd5}{#1}"),Nr("\\tealC","\\textcolor{##01d1c1}{#1}"),Nr("\\tealD","\\textcolor{##01a995}{#1}"),Nr("\\tealE","\\textcolor{##208170}{#1}"),Nr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Nr("\\greenB","\\textcolor{##8af281}{#1}"),Nr("\\greenC","\\textcolor{##74cf70}{#1}"),Nr("\\greenD","\\textcolor{##1fab54}{#1}"),Nr("\\greenE","\\textcolor{##0d923f}{#1}"),Nr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Nr("\\goldB","\\textcolor{##ffbb71}{#1}"),Nr("\\goldC","\\textcolor{##ff9c39}{#1}"),Nr("\\goldD","\\textcolor{##e07d10}{#1}"),Nr("\\goldE","\\textcolor{##a75a05}{#1}"),Nr("\\redA","\\textcolor{##fca9a9}{#1}"),Nr("\\redB","\\textcolor{##ff8482}{#1}"),Nr("\\redC","\\textcolor{##f9685d}{#1}"),Nr("\\redD","\\textcolor{##e84d39}{#1}"),Nr("\\redE","\\textcolor{##bc2612}{#1}"),Nr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Nr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Nr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Nr("\\maroonD","\\textcolor{##ca337c}{#1}"),Nr("\\maroonE","\\textcolor{##9e034e}{#1}"),Nr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Nr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Nr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Nr("\\purpleD","\\textcolor{##7854ab}{#1}"),Nr("\\purpleE","\\textcolor{##543b78}{#1}"),Nr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Nr("\\mintB","\\textcolor{##edf2df}{#1}"),Nr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Nr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Nr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Nr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Nr("\\grayD","\\textcolor{##d6d8da}{#1}"),Nr("\\grayE","\\textcolor{##babec2}{#1}"),Nr("\\grayF","\\textcolor{##888d93}{#1}"),Nr("\\grayG","\\textcolor{##626569}{#1}"),Nr("\\grayH","\\textcolor{##3b3e40}{#1}"),Nr("\\grayI","\\textcolor{##21242c}{#1}"),Nr("\\kaBlue","\\textcolor{##314453}{#1}"),Nr("\\kaGreen","\\textcolor{##71B307}{#1}");const On={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class En{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Tn(Bn,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new An(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){let t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:n,end:r}=this.consumeArg(["]"]))}else({tokens:n,start:t,end:r}=this.consumeArg());return this.pushToken(new Ir("EOF",r.loc)),this.pushTokens(n),t.range(r,"")}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){const t=[],r=e&&e.length>0;r||this.consumeSpaces();const o=this.future();let s,i=0,a=0;do{if(s=this.popToken(),t.push(s),"{"===s.text)++i;else if("}"===s.text){if(--i,-1===i)throw new n("Extra }",s)}else if("EOF"===s.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[a]:"}")+"'",s);if(e&&r)if((0===i||1===i&&"{"===e[a])&&s.text===e[a]){if(++a,a===e.length){t.splice(-a,a);break}}else a=0}while(0!==i||r);return"{"===o.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:o,end:s}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");const r=t[0];for(let e=0;ethis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){const t=this.popToken(),r=t.text,o=t.noexpand?null:this._getExpansion(r);if(null==o||e&&o.unexpandable){if(e&&null==o&&"\\"===r[0]&&!this.isDefined(r))throw new n("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);let s=o.tokens;const i=this.consumeArgs(o.numArgs,o.delimiters);if(o.numArgs){s=s.slice();for(let e=s.length-1;e>=0;--e){let t=s[e];if("#"===t.text){if(0===e)throw new n("Incomplete placeholder at end of macro body",t);if(t=s[--e],"#"===t.text)s.splice(e+1,1);else{if(!/^[1-9]$/.test(t.text))throw new n("Not a valid argument number",t);s.splice(e,2,...i[+t.text-1])}}}}return this.pushTokens(s),s.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){const e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new Ir(e)]):void 0}expandTokens(e){const t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){const e=this.stack.pop();e.treatAsRelax&&(e.noexpand=!1,e.treatAsRelax=!1),t.push(e)}return this.countExpansion(t.length),t}expandMacroAsText(e){const t=this.expandMacro(e);return t?t.map((e=>e.text)).join(""):t}_getExpansion(e){const t=this.macros.get(e);if(null==t)return t;if(1===e.length){const t=this.lexer.catcodes[e];if(null!=t&&13!==t)return}const r="function"==typeof t?t(this):t;if("string"==typeof r){let e=0;if(-1!==r.indexOf("#")){const t=r.replace(/##/g,"");for(;-1!==t.indexOf("#"+(e+1));)++e}const t=new An(r,this.settings),n=[];let o=t.lex();for(;"EOF"!==o.text;)n.push(o),o=t.lex();n.reverse();return{tokens:n,numArgs:e}}return r}isDefined(e){return this.macros.has(e)||wn.hasOwnProperty(e)||se.math.hasOwnProperty(e)||se.text.hasOwnProperty(e)||On.hasOwnProperty(e)}isExpandable(e){const t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:wn.hasOwnProperty(e)&&!wn[e].primitive}}const Ln=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Dn=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Vn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Pn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class Fn{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new En(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{const e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){const t=this.nextToken;this.consume(),this.gullet.pushToken(new Ir("}")),this.gullet.pushTokens(e);const r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){const r=[];for(;;){"math"===this.mode&&this.consumeSpaces();const n=this.fetch();if(-1!==Fn.endOfExpression.indexOf(n.text))break;if(t&&n.text===t)break;if(e&&wn[n.text]&&wn[n.text].infix)break;const o=this.parseAtom(t);if(!o)break;"internal"!==o.type&&r.push(o)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){let t,r=-1;for(let o=0;o=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);const r=se[this.mode][t].group,n=qr.range(e);let s;if(re.hasOwnProperty(r)){const e=r;s={type:"atom",mode:this.mode,family:e,loc:n,text:t}}else s={type:r,mode:this.mode,loc:n,text:t};o=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(S(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:qr.range(e),text:t}}if(this.consume(),r)for(let t=0;t{var abe=Object.create;var _y=Object.defineProperty;var sbe=Object.getOwnPropertyDescriptor;var obe=Object.getOwnPropertyNames;var lbe=Object.getPrototypeOf,cbe=Object.prototype.hasOwnProperty;var o=(t,e)=>_y(t,"name",{value:e,configurable:!0});var N=(t,e)=>()=>(t&&(e=t(t=0)),e);var Pi=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),ur=(t,e)=>{for(var r in e)_y(t,r,{get:e[r],enumerable:!0})},V4=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of obe(e))!cbe.call(t,i)&&i!==r&&_y(t,i,{get:()=>e[i],enumerable:!(n=sbe(e,i))||n.enumerable});return t},Cr=(t,e,r)=>(V4(t,e,"default"),r&&V4(r,e,"default")),Aa=(t,e,r)=>(r=t!=null?abe(lbe(t)):{},V4(e||!t||!t.__esModule?_y(r,"default",{value:t,enumerable:!0}):r,t)),ube=t=>V4(_y({},"__esModule",{value:!0}),t);var U4=Pi((HC,WC)=>{"use strict";(function(t,e){typeof HC=="object"&&typeof WC<"u"?WC.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs=e()})(HC,function(){"use strict";var t=1e3,e=6e4,r=36e5,n="millisecond",i="second",a="minute",s="hour",l="day",u="week",h="month",f="quarter",d="year",p="date",m="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,v={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:o(function(k){var L=["th","st","nd","rd"],A=k%100;return"["+k+(L[(A-20)%10]||L[A]||L[0])+"]"},"ordinal")},x=o(function(k,L,A){var I=String(k);return!I||I.length>=L?k:""+Array(L+1-I.length).join(A)+k},"m"),b={s:x,z:o(function(k){var L=-k.utcOffset(),A=Math.abs(L),I=Math.floor(A/60),M=A%60;return(L<=0?"+":"-")+x(I,2,"0")+":"+x(M,2,"0")},"z"),m:o(function k(L,A){if(L.date()1)return k(B[0])}else{var F=L.name;S[F]=L,M=F}return!I&&M&&(T=M),M||!I&&T},"t"),C=o(function(k,L){if(E(k))return k.clone();var A=typeof L=="object"?L:{};return A.date=k,A.args=arguments,new O(A)},"O"),D=b;D.l=_,D.i=E,D.w=function(k,L){return C(k,{locale:L.$L,utc:L.$u,x:L.$x,$offset:L.$offset})};var O=function(){function k(A){this.$L=_(A.locale,null,!0),this.parse(A),this.$x=this.$x||A.x||{},this[w]=!0}o(k,"M");var L=k.prototype;return L.parse=function(A){this.$d=function(I){var M=I.date,P=I.utc;if(M===null)return new Date(NaN);if(D.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var B=M.match(g);if(B){var F=B[2]-1||0,z=(B[7]||"0").substring(0,3);return P?new Date(Date.UTC(B[1],F,B[3]||1,B[4]||0,B[5]||0,B[6]||0,z)):new Date(B[1],F,B[3]||1,B[4]||0,B[5]||0,B[6]||0,z)}}return new Date(M)}(A),this.init()},L.init=function(){var A=this.$d;this.$y=A.getFullYear(),this.$M=A.getMonth(),this.$D=A.getDate(),this.$W=A.getDay(),this.$H=A.getHours(),this.$m=A.getMinutes(),this.$s=A.getSeconds(),this.$ms=A.getMilliseconds()},L.$utils=function(){return D},L.isValid=function(){return this.$d.toString()!==m},L.isSame=function(A,I){var M=C(A);return this.startOf(I)<=M&&M<=this.endOf(I)},L.isAfter=function(A,I){return C(A){"use strict";f$=Aa(U4(),1),iu={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},X={trace:o((...t)=>{},"trace"),debug:o((...t)=>{},"debug"),info:o((...t)=>{},"info"),warn:o((...t)=>{},"warn"),error:o((...t)=>{},"error"),fatal:o((...t)=>{},"fatal")},Dy=o(function(t="fatal"){let e=iu.fatal;typeof t=="string"?t.toLowerCase()in iu&&(e=iu[t]):typeof t=="number"&&(e=t),X.trace=()=>{},X.debug=()=>{},X.info=()=>{},X.warn=()=>{},X.error=()=>{},X.fatal=()=>{},e<=iu.fatal&&(X.fatal=console.error?console.error.bind(console,ko("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",ko("FATAL"))),e<=iu.error&&(X.error=console.error?console.error.bind(console,ko("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",ko("ERROR"))),e<=iu.warn&&(X.warn=console.warn?console.warn.bind(console,ko("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",ko("WARN"))),e<=iu.info&&(X.info=console.info?console.info.bind(console,ko("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",ko("INFO"))),e<=iu.debug&&(X.debug=console.debug?console.debug.bind(console,ko("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",ko("DEBUG"))),e<=iu.trace&&(X.trace=console.debug?console.debug.bind(console,ko("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",ko("TRACE")))},"setLogLevel"),ko=o(t=>`%c${(0,f$.default)().format("ss.SSS")} : ${t} : `,"format")});var hbe,u0,qC,d$,H4=N(()=>{"use strict";hbe=Object.freeze({left:0,top:0,width:16,height:16}),u0=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),qC=Object.freeze({...hbe,...u0}),d$=Object.freeze({...qC,body:"",hidden:!1})});var fbe,p$,m$=N(()=>{"use strict";H4();fbe=Object.freeze({width:null,height:null}),p$=Object.freeze({...fbe,...u0})});var YC,W4,g$=N(()=>{"use strict";YC=o((t,e,r,n="")=>{let i=t.split(":");if(t.slice(0,1)==="@"){if(i.length<2||i.length>3)return null;n=i.shift().slice(1)}if(i.length>3||!i.length)return null;if(i.length>1){let l=i.pop(),u=i.pop(),h={provider:i.length>0?i[0]:n,prefix:u,name:l};return e&&!W4(h)?null:h}let a=i[0],s=a.split("-");if(s.length>1){let l={provider:n,prefix:s.shift(),name:s.join("-")};return e&&!W4(l)?null:l}if(r&&n===""){let l={provider:n,prefix:"",name:a};return e&&!W4(l,r)?null:l}return null},"stringToIcon"),W4=o((t,e)=>t?!!((e&&t.prefix===""||t.prefix)&&t.name):!1,"validateIconName")});function y$(t,e){let r={};!t.hFlip!=!e.hFlip&&(r.hFlip=!0),!t.vFlip!=!e.vFlip&&(r.vFlip=!0);let n=((t.rotate||0)+(e.rotate||0))%4;return n&&(r.rotate=n),r}var v$=N(()=>{"use strict";o(y$,"mergeIconTransformations")});function XC(t,e){let r=y$(t,e);for(let n in d$)n in u0?n in t&&!(n in r)&&(r[n]=u0[n]):n in e?r[n]=e[n]:n in t&&(r[n]=t[n]);return r}var x$=N(()=>{"use strict";H4();v$();o(XC,"mergeIconData")});function b$(t,e){let r=t.icons,n=t.aliases||Object.create(null),i=Object.create(null);function a(s){if(r[s])return i[s]=[];if(!(s in i)){i[s]=null;let l=n[s]&&n[s].parent,u=l&&a(l);u&&(i[s]=[l].concat(u))}return i[s]}return o(a,"resolve"),(e||Object.keys(r).concat(Object.keys(n))).forEach(a),i}var T$=N(()=>{"use strict";o(b$,"getIconsTree")});function w$(t,e,r){let n=t.icons,i=t.aliases||Object.create(null),a={};function s(l){a=XC(n[l]||i[l],a)}return o(s,"parse"),s(e),r.forEach(s),XC(t,a)}function jC(t,e){if(t.icons[e])return w$(t,e,[]);let r=b$(t,[e])[e];return r?w$(t,e,r):null}var k$=N(()=>{"use strict";x$();T$();o(w$,"internalGetIconData");o(jC,"getIconData")});function KC(t,e,r){if(e===1)return t;if(r=r||100,typeof t=="number")return Math.ceil(t*e*r)/r;if(typeof t!="string")return t;let n=t.split(dbe);if(n===null||!n.length)return t;let i=[],a=n.shift(),s=pbe.test(a);for(;;){if(s){let l=parseFloat(a);isNaN(l)?i.push(a):i.push(Math.ceil(l*e*r)/r)}else i.push(a);if(a=n.shift(),a===void 0)return i.join("");s=!s}}var dbe,pbe,E$=N(()=>{"use strict";dbe=/(-?[0-9.]*[0-9]+[0-9.]*)/g,pbe=/^-?[0-9.]*[0-9]+[0-9.]*$/g;o(KC,"calculateSize")});function mbe(t,e="defs"){let r="",n=t.indexOf("<"+e);for(;n>=0;){let i=t.indexOf(">",n),a=t.indexOf("",a);if(s===-1)break;r+=t.slice(i+1,a).trim(),t=t.slice(0,n).trim()+t.slice(s+1)}return{defs:r,content:t}}function gbe(t,e){return t?""+t+""+e:e}function S$(t,e,r){let n=mbe(t);return gbe(n.defs,e+n.content+r)}var C$=N(()=>{"use strict";o(mbe,"splitSVGDefs");o(gbe,"mergeDefsAndContent");o(S$,"wrapSVGContent")});function QC(t,e){let r={...qC,...t},n={...p$,...e},i={left:r.left,top:r.top,width:r.width,height:r.height},a=r.body;[r,n].forEach(y=>{let v=[],x=y.hFlip,b=y.vFlip,T=y.rotate;x?b?T+=2:(v.push("translate("+(i.width+i.left).toString()+" "+(0-i.top).toString()+")"),v.push("scale(-1 1)"),i.top=i.left=0):b&&(v.push("translate("+(0-i.left).toString()+" "+(i.height+i.top).toString()+")"),v.push("scale(1 -1)"),i.top=i.left=0);let S;switch(T<0&&(T-=Math.floor(T/4)*4),T=T%4,T){case 1:S=i.height/2+i.top,v.unshift("rotate(90 "+S.toString()+" "+S.toString()+")");break;case 2:v.unshift("rotate(180 "+(i.width/2+i.left).toString()+" "+(i.height/2+i.top).toString()+")");break;case 3:S=i.width/2+i.left,v.unshift("rotate(-90 "+S.toString()+" "+S.toString()+")");break}T%2===1&&(i.left!==i.top&&(S=i.left,i.left=i.top,i.top=S),i.width!==i.height&&(S=i.width,i.width=i.height,i.height=S)),v.length&&(a=S$(a,'',""))});let s=n.width,l=n.height,u=i.width,h=i.height,f,d;s===null?(d=l===null?"1em":l==="auto"?h:l,f=KC(d,u/h)):(f=s==="auto"?u:s,d=l===null?KC(f,h/u):l==="auto"?h:l);let p={},m=o((y,v)=>{ybe(v)||(p[y]=v.toString())},"setAttr");m("width",f),m("height",d);let g=[i.left,i.top,u,h];return p.viewBox=g.join(" "),{attributes:p,viewBox:g,body:a}}var ybe,A$=N(()=>{"use strict";H4();m$();E$();C$();ybe=o(t=>t==="unset"||t==="undefined"||t==="none","isUnsetKeyword");o(QC,"iconToSVG")});function ZC(t,e=xbe){let r=[],n;for(;n=vbe.exec(t);)r.push(n[1]);if(!r.length)return t;let i="suffix"+(Math.random()*16777216|Date.now()).toString(16);return r.forEach(a=>{let s=typeof e=="function"?e(a):e+(bbe++).toString(),l=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");t=t.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+s+i+"$3")}),t=t.replace(new RegExp(i,"g"),""),t}var vbe,xbe,bbe,_$=N(()=>{"use strict";vbe=/\sid="(\S+)"/g,xbe="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16),bbe=0;o(ZC,"replaceIDs")});function JC(t,e){let r=t.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(let n in e)r+=" "+n+'="'+e[n]+'"';return'"+t+""}var D$=N(()=>{"use strict";o(JC,"iconToHTML")});var R$=Pi((Iat,L$)=>{"use strict";var h0=1e3,f0=h0*60,d0=f0*60,ed=d0*24,Tbe=ed*7,wbe=ed*365.25;L$.exports=function(t,e){e=e||{};var r=typeof t;if(r==="string"&&t.length>0)return kbe(t);if(r==="number"&&isFinite(t))return e.long?Sbe(t):Ebe(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))};function kbe(t){if(t=String(t),!(t.length>100)){var e=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(t);if(e){var r=parseFloat(e[1]),n=(e[2]||"ms").toLowerCase();switch(n){case"years":case"year":case"yrs":case"yr":case"y":return r*wbe;case"weeks":case"week":case"w":return r*Tbe;case"days":case"day":case"d":return r*ed;case"hours":case"hour":case"hrs":case"hr":case"h":return r*d0;case"minutes":case"minute":case"mins":case"min":case"m":return r*f0;case"seconds":case"second":case"secs":case"sec":case"s":return r*h0;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}o(kbe,"parse");function Ebe(t){var e=Math.abs(t);return e>=ed?Math.round(t/ed)+"d":e>=d0?Math.round(t/d0)+"h":e>=f0?Math.round(t/f0)+"m":e>=h0?Math.round(t/h0)+"s":t+"ms"}o(Ebe,"fmtShort");function Sbe(t){var e=Math.abs(t);return e>=ed?q4(t,e,ed,"day"):e>=d0?q4(t,e,d0,"hour"):e>=f0?q4(t,e,f0,"minute"):e>=h0?q4(t,e,h0,"second"):t+" ms"}o(Sbe,"fmtLong");function q4(t,e,r,n){var i=e>=r*1.5;return Math.round(t/r)+" "+n+(i?"s":"")}o(q4,"plural")});var M$=Pi((Pat,N$)=>{"use strict";function Cbe(t){r.debug=r,r.default=r,r.coerce=u,r.disable=s,r.enable=i,r.enabled=l,r.humanize=R$(),r.destroy=h,Object.keys(t).forEach(f=>{r[f]=t[f]}),r.names=[],r.skips=[],r.formatters={};function e(f){let d=0;for(let p=0;p{if(E==="%%")return"%";S++;let C=r.formatters[_];if(typeof C=="function"){let D=v[S];E=C.call(x,D),v.splice(S,1),S--}return E}),r.formatArgs.call(x,v),(x.log||r.log).apply(x,v)}return o(y,"debug"),y.namespace=f,y.useColors=r.useColors(),y.color=r.selectColor(f),y.extend=n,y.destroy=r.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:o(()=>p!==null?p:(m!==r.namespaces&&(m=r.namespaces,g=r.enabled(f)),g),"get"),set:o(v=>{p=v},"set")}),typeof r.init=="function"&&r.init(y),y}o(r,"createDebug");function n(f,d){let p=r(this.namespace+(typeof d>"u"?":":d)+f);return p.log=this.log,p}o(n,"extend");function i(f){r.save(f),r.namespaces=f,r.names=[],r.skips=[];let d=(typeof f=="string"?f:"").trim().replace(" ",",").split(",").filter(Boolean);for(let p of d)p[0]==="-"?r.skips.push(p.slice(1)):r.names.push(p)}o(i,"enable");function a(f,d){let p=0,m=0,g=-1,y=0;for(;p"-"+d)].join(",");return r.enable(""),f}o(s,"disable");function l(f){for(let d of r.skips)if(a(f,d))return!1;for(let d of r.names)if(a(f,d))return!0;return!1}o(l,"enabled");function u(f){return f instanceof Error?f.stack||f.message:f}o(u,"coerce");function h(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return o(h,"destroy"),r.enable(r.load()),r}o(Cbe,"setup");N$.exports=Cbe});var I$=Pi((js,Y4)=>{"use strict";js.formatArgs=_be;js.save=Dbe;js.load=Lbe;js.useColors=Abe;js.storage=Rbe();js.destroy=(()=>{let t=!1;return()=>{t||(t=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})();js.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function Abe(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let t;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(t=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(t[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}o(Abe,"useColors");function _be(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+Y4.exports.humanize(this.diff),!this.useColors)return;let e="color: "+this.color;t.splice(1,0,e,"color: inherit");let r=0,n=0;t[0].replace(/%[a-zA-Z%]/g,i=>{i!=="%%"&&(r++,i==="%c"&&(n=r))}),t.splice(n,0,e)}o(_be,"formatArgs");js.log=console.debug||console.log||(()=>{});function Dbe(t){try{t?js.storage.setItem("debug",t):js.storage.removeItem("debug")}catch{}}o(Dbe,"save");function Lbe(){let t;try{t=js.storage.getItem("debug")}catch{}return!t&&typeof process<"u"&&"env"in process&&(t=process.env.DEBUG),t}o(Lbe,"load");function Rbe(){try{return localStorage}catch{}}o(Rbe,"localstorage");Y4.exports=M$()(js);var{formatters:Nbe}=Y4.exports;Nbe.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}});var zat,O$=N(()=>{"use strict";g$();k$();A$();_$();D$();zat=Aa(I$(),1)});var t7,e7,P$,X4,B$,F$,Es,jl=N(()=>{"use strict";yt();O$();t7={body:'?',height:80,width:80},e7=new Map,P$=new Map,X4=o(t=>{for(let e of t){if(!e.name)throw new Error('Invalid icon loader. Must have a "name" property with non-empty string value.');if(X.debug("Registering icon pack:",e.name),"loader"in e)P$.set(e.name,e.loader);else if("icons"in e)e7.set(e.name,e.icons);else throw X.error("Invalid icon loader:",e),new Error('Invalid icon loader. Must have either "icons" or "loader" property.')}},"registerIconPacks"),B$=o(async(t,e)=>{let r=YC(t,!0,e!==void 0);if(!r)throw new Error(`Invalid icon name: ${t}`);let n=r.prefix||e;if(!n)throw new Error(`Icon name must contain a prefix: ${t}`);let i=e7.get(n);if(!i){let s=P$.get(n);if(!s)throw new Error(`Icon set not found: ${r.prefix}`);try{i={...await s(),prefix:n},e7.set(n,i)}catch(l){throw X.error(l),new Error(`Failed to load icon set: ${r.prefix}`)}}let a=jC(i,r.name);if(!a)throw new Error(`Icon not found: ${t}`);return a},"getRegisteredIconData"),F$=o(async t=>{try{return await B$(t),!0}catch{return!1}},"isIconAvailable"),Es=o(async(t,e,r)=>{let n;try{n=await B$(t,e?.fallbackPrefix)}catch(s){X.error(s),n=t7}let i=QC(n,e);return JC(ZC(i.body),{...i.attributes,...r})},"getIconSVG")});function j4(t){for(var e=[],r=1;r{"use strict";o(j4,"dedent")});var K4,td,$$,Q4=N(()=>{"use strict";K4=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,td=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,$$=/\s*%%.*\n/gm});var p0,n7=N(()=>{"use strict";p0=class extends Error{static{o(this,"UnknownDiagramError")}constructor(e){super(e),this.name="UnknownDiagramError"}}});var au,m0,Ly,i7,z$,rd=N(()=>{"use strict";yt();Q4();n7();au={},m0=o(function(t,e){t=t.replace(K4,"").replace(td,"").replace($$,` -`);for(let[r,{detector:n}]of Object.entries(au))if(n(t,e))return r;throw new p0(`No diagram type detected matching given configuration for text: ${t}`)},"detectType"),Ly=o((...t)=>{for(let{id:e,detector:r,loader:n}of t)i7(e,r,n)},"registerLazyLoadedDiagrams"),i7=o((t,e,r)=>{au[t]&&X.warn(`Detector with key ${t} already exists. Overwriting.`),au[t]={detector:e,loader:r},X.debug(`Detector with key ${t} added${r?" with loader":""}`)},"addDetector"),z$=o(t=>au[t].loader,"getDiagramLoader")});var Ry,G$,a7=N(()=>{"use strict";Ry=function(){var t=o(function(ze,Le,Ie,xe){for(Ie=Ie||{},xe=ze.length;xe--;Ie[ze[xe]]=Le);return Ie},"o"),e=[1,24],r=[1,25],n=[1,26],i=[1,27],a=[1,28],s=[1,63],l=[1,64],u=[1,65],h=[1,66],f=[1,67],d=[1,68],p=[1,69],m=[1,29],g=[1,30],y=[1,31],v=[1,32],x=[1,33],b=[1,34],T=[1,35],S=[1,36],w=[1,37],E=[1,38],_=[1,39],C=[1,40],D=[1,41],O=[1,42],R=[1,43],k=[1,44],L=[1,45],A=[1,46],I=[1,47],M=[1,48],P=[1,50],B=[1,51],F=[1,52],z=[1,53],$=[1,54],U=[1,55],K=[1,56],ee=[1,57],Y=[1,58],ce=[1,59],Z=[1,60],ue=[14,42],Q=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],j=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],ne=[1,82],te=[1,83],he=[1,84],le=[1,85],J=[12,14,42],Se=[12,14,33,42],se=[12,14,33,42,76,77,79,80],ae=[12,33],Oe=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],ye={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:o(function(Le,Ie,xe,q,de,ie,oe){var V=ie.length-1;switch(de){case 3:q.setDirection("TB");break;case 4:q.setDirection("BT");break;case 5:q.setDirection("RL");break;case 6:q.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:q.setC4Type(ie[V-3]);break;case 19:q.setTitle(ie[V].substring(6)),this.$=ie[V].substring(6);break;case 20:q.setAccDescription(ie[V].substring(15)),this.$=ie[V].substring(15);break;case 21:this.$=ie[V].trim(),q.setTitle(this.$);break;case 22:case 23:this.$=ie[V].trim(),q.setAccDescription(this.$);break;case 28:ie[V].splice(2,0,"ENTERPRISE"),q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 29:ie[V].splice(2,0,"SYSTEM"),q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 30:q.addPersonOrSystemBoundary(...ie[V]),this.$=ie[V];break;case 31:ie[V].splice(2,0,"CONTAINER"),q.addContainerBoundary(...ie[V]),this.$=ie[V];break;case 32:q.addDeploymentNode("node",...ie[V]),this.$=ie[V];break;case 33:q.addDeploymentNode("nodeL",...ie[V]),this.$=ie[V];break;case 34:q.addDeploymentNode("nodeR",...ie[V]),this.$=ie[V];break;case 35:q.popBoundaryParseStack();break;case 39:q.addPersonOrSystem("person",...ie[V]),this.$=ie[V];break;case 40:q.addPersonOrSystem("external_person",...ie[V]),this.$=ie[V];break;case 41:q.addPersonOrSystem("system",...ie[V]),this.$=ie[V];break;case 42:q.addPersonOrSystem("system_db",...ie[V]),this.$=ie[V];break;case 43:q.addPersonOrSystem("system_queue",...ie[V]),this.$=ie[V];break;case 44:q.addPersonOrSystem("external_system",...ie[V]),this.$=ie[V];break;case 45:q.addPersonOrSystem("external_system_db",...ie[V]),this.$=ie[V];break;case 46:q.addPersonOrSystem("external_system_queue",...ie[V]),this.$=ie[V];break;case 47:q.addContainer("container",...ie[V]),this.$=ie[V];break;case 48:q.addContainer("container_db",...ie[V]),this.$=ie[V];break;case 49:q.addContainer("container_queue",...ie[V]),this.$=ie[V];break;case 50:q.addContainer("external_container",...ie[V]),this.$=ie[V];break;case 51:q.addContainer("external_container_db",...ie[V]),this.$=ie[V];break;case 52:q.addContainer("external_container_queue",...ie[V]),this.$=ie[V];break;case 53:q.addComponent("component",...ie[V]),this.$=ie[V];break;case 54:q.addComponent("component_db",...ie[V]),this.$=ie[V];break;case 55:q.addComponent("component_queue",...ie[V]),this.$=ie[V];break;case 56:q.addComponent("external_component",...ie[V]),this.$=ie[V];break;case 57:q.addComponent("external_component_db",...ie[V]),this.$=ie[V];break;case 58:q.addComponent("external_component_queue",...ie[V]),this.$=ie[V];break;case 60:q.addRel("rel",...ie[V]),this.$=ie[V];break;case 61:q.addRel("birel",...ie[V]),this.$=ie[V];break;case 62:q.addRel("rel_u",...ie[V]),this.$=ie[V];break;case 63:q.addRel("rel_d",...ie[V]),this.$=ie[V];break;case 64:q.addRel("rel_l",...ie[V]),this.$=ie[V];break;case 65:q.addRel("rel_r",...ie[V]),this.$=ie[V];break;case 66:q.addRel("rel_b",...ie[V]),this.$=ie[V];break;case 67:ie[V].splice(0,1),q.addRel("rel",...ie[V]),this.$=ie[V];break;case 68:q.updateElStyle("update_el_style",...ie[V]),this.$=ie[V];break;case 69:q.updateRelStyle("update_rel_style",...ie[V]),this.$=ie[V];break;case 70:q.updateLayoutConfig("update_layout_config",...ie[V]),this.$=ie[V];break;case 71:this.$=[ie[V]];break;case 72:ie[V].unshift(ie[V-1]),this.$=ie[V];break;case 73:case 75:this.$=ie[V].trim();break;case 74:let Te={};Te[ie[V-1].trim()]=ie[V].trim(),this.$=Te;break;case 76:this.$="";break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:70,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:71,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:72,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{13:73,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{14:[1,74]},t(ue,[2,13],{43:23,29:49,30:61,32:62,20:75,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z}),t(ue,[2,14]),t(Q,[2,16],{12:[1,76]}),t(ue,[2,36],{12:[1,77]}),t(j,[2,19]),t(j,[2,20]),{25:[1,78]},{27:[1,79]},t(j,[2,23]),{35:80,75:81,76:ne,77:te,79:he,80:le},{35:86,75:81,76:ne,77:te,79:he,80:le},{35:87,75:81,76:ne,77:te,79:he,80:le},{35:88,75:81,76:ne,77:te,79:he,80:le},{35:89,75:81,76:ne,77:te,79:he,80:le},{35:90,75:81,76:ne,77:te,79:he,80:le},{35:91,75:81,76:ne,77:te,79:he,80:le},{35:92,75:81,76:ne,77:te,79:he,80:le},{35:93,75:81,76:ne,77:te,79:he,80:le},{35:94,75:81,76:ne,77:te,79:he,80:le},{35:95,75:81,76:ne,77:te,79:he,80:le},{35:96,75:81,76:ne,77:te,79:he,80:le},{35:97,75:81,76:ne,77:te,79:he,80:le},{35:98,75:81,76:ne,77:te,79:he,80:le},{35:99,75:81,76:ne,77:te,79:he,80:le},{35:100,75:81,76:ne,77:te,79:he,80:le},{35:101,75:81,76:ne,77:te,79:he,80:le},{35:102,75:81,76:ne,77:te,79:he,80:le},{35:103,75:81,76:ne,77:te,79:he,80:le},{35:104,75:81,76:ne,77:te,79:he,80:le},t(J,[2,59]),{35:105,75:81,76:ne,77:te,79:he,80:le},{35:106,75:81,76:ne,77:te,79:he,80:le},{35:107,75:81,76:ne,77:te,79:he,80:le},{35:108,75:81,76:ne,77:te,79:he,80:le},{35:109,75:81,76:ne,77:te,79:he,80:le},{35:110,75:81,76:ne,77:te,79:he,80:le},{35:111,75:81,76:ne,77:te,79:he,80:le},{35:112,75:81,76:ne,77:te,79:he,80:le},{35:113,75:81,76:ne,77:te,79:he,80:le},{35:114,75:81,76:ne,77:te,79:he,80:le},{35:115,75:81,76:ne,77:te,79:he,80:le},{20:116,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z},{12:[1,118],33:[1,117]},{35:119,75:81,76:ne,77:te,79:he,80:le},{35:120,75:81,76:ne,77:te,79:he,80:le},{35:121,75:81,76:ne,77:te,79:he,80:le},{35:122,75:81,76:ne,77:te,79:he,80:le},{35:123,75:81,76:ne,77:te,79:he,80:le},{35:124,75:81,76:ne,77:te,79:he,80:le},{35:125,75:81,76:ne,77:te,79:he,80:le},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(ue,[2,15]),t(Q,[2,17],{21:22,19:130,22:e,23:r,24:n,26:i,28:a}),t(ue,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:r,24:n,26:i,28:a,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T,51:S,52:w,53:E,54:_,55:C,56:D,57:O,58:R,59:k,60:L,61:A,62:I,63:M,64:P,65:B,66:F,67:z,68:$,69:U,70:K,71:ee,72:Y,73:ce,74:Z}),t(j,[2,21]),t(j,[2,22]),t(J,[2,39]),t(Se,[2,71],{75:81,35:132,76:ne,77:te,79:he,80:le}),t(se,[2,73]),{78:[1,133]},t(se,[2,75]),t(se,[2,76]),t(J,[2,40]),t(J,[2,41]),t(J,[2,42]),t(J,[2,43]),t(J,[2,44]),t(J,[2,45]),t(J,[2,46]),t(J,[2,47]),t(J,[2,48]),t(J,[2,49]),t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),t(J,[2,57]),t(J,[2,58]),t(J,[2,60]),t(J,[2,61]),t(J,[2,62]),t(J,[2,63]),t(J,[2,64]),t(J,[2,65]),t(J,[2,66]),t(J,[2,67]),t(J,[2,68]),t(J,[2,69]),t(J,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(ae,[2,28]),t(ae,[2,29]),t(ae,[2,30]),t(ae,[2,31]),t(ae,[2,32]),t(ae,[2,33]),t(ae,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t(Q,[2,18]),t(ue,[2,38]),t(Se,[2,72]),t(se,[2,74]),t(J,[2,24]),t(J,[2,35]),t(Oe,[2,25]),t(Oe,[2,26],{12:[1,138]}),t(Oe,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:o(function(Le,Ie){if(Ie.recoverable)this.trace(Le);else{var xe=new Error(Le);throw xe.hash=Ie,xe}},"parseError"),parse:o(function(Le){var Ie=this,xe=[0],q=[],de=[null],ie=[],oe=this.table,V="",Te=0,W=0,pe=0,ve=2,Pe=1,_e=ie.slice.call(arguments,1),be=Object.create(this.lexer),Ve={yy:{}};for(var De in this.yy)Object.prototype.hasOwnProperty.call(this.yy,De)&&(Ve.yy[De]=this.yy[De]);be.setInput(Le,Ve.yy),Ve.yy.lexer=be,Ve.yy.parser=this,typeof be.yylloc>"u"&&(be.yylloc={});var qe=be.yylloc;ie.push(qe);var at=be.options&&be.options.ranges;typeof Ve.yy.parseError=="function"?this.parseError=Ve.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Rt(nt){xe.length=xe.length-2*nt,de.length=de.length-nt,ie.length=ie.length-nt}o(Rt,"popStack");function st(){var nt;return nt=q.pop()||be.lex()||Pe,typeof nt!="number"&&(nt instanceof Array&&(q=nt,nt=q.pop()),nt=Ie.symbols_[nt]||nt),nt}o(st,"lex");for(var Ue,ct,We,ot,Yt,Tt,Mt={},bt,ut,St,ft;;){if(We=xe[xe.length-1],this.defaultActions[We]?ot=this.defaultActions[We]:((Ue===null||typeof Ue>"u")&&(Ue=st()),ot=oe[We]&&oe[We][Ue]),typeof ot>"u"||!ot.length||!ot[0]){var vt="";ft=[];for(bt in oe[We])this.terminals_[bt]&&bt>ve&&ft.push("'"+this.terminals_[bt]+"'");be.showPosition?vt="Parse error on line "+(Te+1)+`: -`+be.showPosition()+` -Expecting `+ft.join(", ")+", got '"+(this.terminals_[Ue]||Ue)+"'":vt="Parse error on line "+(Te+1)+": Unexpected "+(Ue==Pe?"end of input":"'"+(this.terminals_[Ue]||Ue)+"'"),this.parseError(vt,{text:be.match,token:this.terminals_[Ue]||Ue,line:be.yylineno,loc:qe,expected:ft})}if(ot[0]instanceof Array&&ot.length>1)throw new Error("Parse Error: multiple actions possible at state: "+We+", token: "+Ue);switch(ot[0]){case 1:xe.push(Ue),de.push(be.yytext),ie.push(be.yylloc),xe.push(ot[1]),Ue=null,ct?(Ue=ct,ct=null):(W=be.yyleng,V=be.yytext,Te=be.yylineno,qe=be.yylloc,pe>0&&pe--);break;case 2:if(ut=this.productions_[ot[1]][1],Mt.$=de[de.length-ut],Mt._$={first_line:ie[ie.length-(ut||1)].first_line,last_line:ie[ie.length-1].last_line,first_column:ie[ie.length-(ut||1)].first_column,last_column:ie[ie.length-1].last_column},at&&(Mt._$.range=[ie[ie.length-(ut||1)].range[0],ie[ie.length-1].range[1]]),Tt=this.performAction.apply(Mt,[V,W,Te,Ve.yy,ot[1],de,ie].concat(_e)),typeof Tt<"u")return Tt;ut&&(xe=xe.slice(0,-1*ut*2),de=de.slice(0,-1*ut),ie=ie.slice(0,-1*ut)),xe.push(this.productions_[ot[1]][0]),de.push(Mt.$),ie.push(Mt._$),St=oe[xe[xe.length-2]][xe[xe.length-1]],xe.push(St);break;case 3:return!0}}return!0},"parse")},Be=function(){var ze={EOF:1,parseError:o(function(Ie,xe){if(this.yy.parser)this.yy.parser.parseError(Ie,xe);else throw new Error(Ie)},"parseError"),setInput:o(function(Le,Ie){return this.yy=Ie||this.yy||{},this._input=Le,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var Le=this._input[0];this.yytext+=Le,this.yyleng++,this.offset++,this.match+=Le,this.matched+=Le;var Ie=Le.match(/(?:\r\n?|\n).*/g);return Ie?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Le},"input"),unput:o(function(Le){var Ie=Le.length,xe=Le.split(/(?:\r\n?|\n)/g);this._input=Le+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Ie),this.offset-=Ie;var q=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),xe.length-1&&(this.yylineno-=xe.length-1);var de=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:xe?(xe.length===q.length?this.yylloc.first_column:0)+q[q.length-xe.length].length-xe[0].length:this.yylloc.first_column-Ie},this.options.ranges&&(this.yylloc.range=[de[0],de[0]+this.yyleng-Ie]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(Le){this.unput(this.match.slice(Le))},"less"),pastInput:o(function(){var Le=this.matched.substr(0,this.matched.length-this.match.length);return(Le.length>20?"...":"")+Le.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var Le=this.match;return Le.length<20&&(Le+=this._input.substr(0,20-Le.length)),(Le.substr(0,20)+(Le.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var Le=this.pastInput(),Ie=new Array(Le.length+1).join("-");return Le+this.upcomingInput()+` -`+Ie+"^"},"showPosition"),test_match:o(function(Le,Ie){var xe,q,de;if(this.options.backtrack_lexer&&(de={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(de.yylloc.range=this.yylloc.range.slice(0))),q=Le[0].match(/(?:\r\n?|\n).*/g),q&&(this.yylineno+=q.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:q?q[q.length-1].length-q[q.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Le[0].length},this.yytext+=Le[0],this.match+=Le[0],this.matches=Le,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(Le[0].length),this.matched+=Le[0],xe=this.performAction.call(this,this.yy,this,Ie,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),xe)return xe;if(this._backtrack){for(var ie in de)this[ie]=de[ie];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Le,Ie,xe,q;this._more||(this.yytext="",this.match="");for(var de=this._currentRules(),ie=0;ieIe[0].length)){if(Ie=xe,q=ie,this.options.backtrack_lexer){if(Le=this.test_match(xe,de[ie]),Le!==!1)return Le;if(this._backtrack){Ie=!1;continue}else return!1}else if(!this.options.flex)break}return Ie?(Le=this.test_match(Ie,de[q]),Le!==!1?Le:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var Ie=this.next();return Ie||this.lex()},"lex"),begin:o(function(Ie){this.conditionStack.push(Ie)},"begin"),popState:o(function(){var Ie=this.conditionStack.length-1;return Ie>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(Ie){return Ie=this.conditionStack.length-1-Math.abs(Ie||0),Ie>=0?this.conditionStack[Ie]:"INITIAL"},"topState"),pushState:o(function(Ie){this.begin(Ie)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(Ie,xe,q,de){var ie=de;switch(q){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),26;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:break;case 14:c;break;case 15:return 12;case 16:break;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;break;case 23:return this.begin("person"),44;break;case 24:return this.begin("system_ext_queue"),51;break;case 25:return this.begin("system_ext_db"),50;break;case 26:return this.begin("system_ext"),49;break;case 27:return this.begin("system_queue"),48;break;case 28:return this.begin("system_db"),47;break;case 29:return this.begin("system"),46;break;case 30:return this.begin("boundary"),37;break;case 31:return this.begin("enterprise_boundary"),34;break;case 32:return this.begin("system_boundary"),36;break;case 33:return this.begin("container_ext_queue"),57;break;case 34:return this.begin("container_ext_db"),56;break;case 35:return this.begin("container_ext"),55;break;case 36:return this.begin("container_queue"),54;break;case 37:return this.begin("container_db"),53;break;case 38:return this.begin("container"),52;break;case 39:return this.begin("container_boundary"),38;break;case 40:return this.begin("component_ext_queue"),63;break;case 41:return this.begin("component_ext_db"),62;break;case 42:return this.begin("component_ext"),61;break;case 43:return this.begin("component_queue"),60;break;case 44:return this.begin("component_db"),59;break;case 45:return this.begin("component"),58;break;case 46:return this.begin("node"),39;break;case 47:return this.begin("node"),39;break;case 48:return this.begin("node_l"),40;break;case 49:return this.begin("node_r"),41;break;case 50:return this.begin("rel"),64;break;case 51:return this.begin("birel"),65;break;case 52:return this.begin("rel_u"),66;break;case 53:return this.begin("rel_u"),66;break;case 54:return this.begin("rel_d"),67;break;case 55:return this.begin("rel_d"),67;break;case 56:return this.begin("rel_l"),68;break;case 57:return this.begin("rel_l"),68;break;case 58:return this.begin("rel_r"),69;break;case 59:return this.begin("rel_r"),69;break;case 60:return this.begin("rel_b"),70;break;case 61:return this.begin("rel_index"),71;break;case 62:return this.begin("update_el_style"),72;break;case 63:return this.begin("update_rel_style"),73;break;case 64:return this.begin("update_layout_config"),74;break;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";break;case 67:this.begin("attribute");break;case 68:this.popState(),this.popState();break;case 69:return 80;case 70:break;case 71:return 80;case 72:this.begin("string");break;case 73:this.popState();break;case 74:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";break;case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 79:this.popState(),this.popState();break;case 80:return"STR";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};return ze}();ye.lexer=Be;function He(){this.yy={}}return o(He,"Parser"),He.prototype=ye,ye.Parser=He,new He}();Ry.parser=Ry;G$=Ry});var s7,Un,g0=N(()=>{"use strict";s7=o((t,e,{depth:r=2,clobber:n=!1}={})=>{let i={depth:r,clobber:n};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach(a=>s7(t,a,i)),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach(a=>{t.includes(a)||t.push(a)}),t):t===void 0||r<=0?t!=null&&typeof t=="object"&&typeof e=="object"?Object.assign(t,e):e:(e!==void 0&&typeof t=="object"&&typeof e=="object"&&Object.keys(e).forEach(a=>{typeof e[a]=="object"&&(t[a]===void 0||typeof t[a]=="object")?(t[a]===void 0&&(t[a]=Array.isArray(e[a])?[]:{}),t[a]=s7(t[a],e[a],{depth:r-1,clobber:n})):(n||typeof t[a]!="object"&&typeof e[a]!="object")&&(t[a]=e[a])}),t)},"assignWithDepth"),Un=s7});var Z4,V$,U$=N(()=>{"use strict";Z4={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:o(t=>t>=255?255:t<0?0:t,"r"),g:o(t=>t>=255?255:t<0?0:t,"g"),b:o(t=>t>=255?255:t<0?0:t,"b"),h:o(t=>t%360,"h"),s:o(t=>t>=100?100:t<0?0:t,"s"),l:o(t=>t>=100?100:t<0?0:t,"l"),a:o(t=>t>=1?1:t<0?0:t,"a")},toLinear:o(t=>{let e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},"toLinear"),hue2rgb:o((t,e,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<.16666666666666666?t+(e-t)*6*r:r<.5?e:r<.6666666666666666?t+(e-t)*(.6666666666666666-r)*6:t),"hue2rgb"),hsl2rgb:o(({h:t,s:e,l:r},n)=>{if(!e)return r*2.55;t/=360,e/=100,r/=100;let i=r<.5?r*(1+e):r+e-r*e,a=2*r-i;switch(n){case"r":return Z4.hue2rgb(a,i,t+.3333333333333333)*255;case"g":return Z4.hue2rgb(a,i,t)*255;case"b":return Z4.hue2rgb(a,i,t-.3333333333333333)*255}},"hsl2rgb"),rgb2hsl:o(({r:t,g:e,b:r},n)=>{t/=255,e/=255,r/=255;let i=Math.max(t,e,r),a=Math.min(t,e,r),s=(i+a)/2;if(n==="l")return s*100;if(i===a)return 0;let l=i-a,u=s>.5?l/(2-i-a):l/(i+a);if(n==="s")return u*100;switch(i){case t:return((e-r)/l+(e{"use strict";Mbe={clamp:o((t,e,r)=>e>r?Math.min(e,Math.max(r,t)):Math.min(r,Math.max(e,t)),"clamp"),round:o(t=>Math.round(t*1e10)/1e10,"round")},H$=Mbe});var Ibe,q$,Y$=N(()=>{"use strict";Ibe={dec2hex:o(t=>{let e=Math.round(t).toString(16);return e.length>1?e:`0${e}`},"dec2hex")},q$=Ibe});var Obe,jt,Kl=N(()=>{"use strict";U$();W$();Y$();Obe={channel:V$,lang:H$,unit:q$},jt=Obe});var su,Bi,Ny=N(()=>{"use strict";Kl();su={};for(let t=0;t<=255;t++)su[t]=jt.unit.dec2hex(t);Bi={ALL:0,RGB:1,HSL:2}});var o7,X$,j$=N(()=>{"use strict";Ny();o7=class{static{o(this,"Type")}constructor(){this.type=Bi.ALL}get(){return this.type}set(e){if(this.type&&this.type!==e)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=e}reset(){this.type=Bi.ALL}is(e){return this.type===e}},X$=o7});var l7,K$,Q$=N(()=>{"use strict";Kl();j$();Ny();l7=class{static{o(this,"Channels")}constructor(e,r){this.color=r,this.changed=!1,this.data=e,this.type=new X$}set(e,r){return this.color=r,this.changed=!1,this.data=e,this.type.type=Bi.ALL,this}_ensureHSL(){let e=this.data,{h:r,s:n,l:i}=e;r===void 0&&(e.h=jt.channel.rgb2hsl(e,"h")),n===void 0&&(e.s=jt.channel.rgb2hsl(e,"s")),i===void 0&&(e.l=jt.channel.rgb2hsl(e,"l"))}_ensureRGB(){let e=this.data,{r,g:n,b:i}=e;r===void 0&&(e.r=jt.channel.hsl2rgb(e,"r")),n===void 0&&(e.g=jt.channel.hsl2rgb(e,"g")),i===void 0&&(e.b=jt.channel.hsl2rgb(e,"b"))}get r(){let e=this.data,r=e.r;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"r"))}get g(){let e=this.data,r=e.g;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"g"))}get b(){let e=this.data,r=e.b;return!this.type.is(Bi.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"b"))}get h(){let e=this.data,r=e.h;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"h"))}get s(){let e=this.data,r=e.s;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"s"))}get l(){let e=this.data,r=e.l;return!this.type.is(Bi.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"l"))}get a(){return this.data.a}set r(e){this.type.set(Bi.RGB),this.changed=!0,this.data.r=e}set g(e){this.type.set(Bi.RGB),this.changed=!0,this.data.g=e}set b(e){this.type.set(Bi.RGB),this.changed=!0,this.data.b=e}set h(e){this.type.set(Bi.HSL),this.changed=!0,this.data.h=e}set s(e){this.type.set(Bi.HSL),this.changed=!0,this.data.s=e}set l(e){this.type.set(Bi.HSL),this.changed=!0,this.data.l=e}set a(e){this.changed=!0,this.data.a=e}},K$=l7});var Pbe,uh,My=N(()=>{"use strict";Q$();Pbe=new K$({r:0,g:0,b:0,a:0},"transparent"),uh=Pbe});var Z$,nd,c7=N(()=>{"use strict";My();Ny();Z$={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:o(t=>{if(t.charCodeAt(0)!==35)return;let e=t.match(Z$.re);if(!e)return;let r=e[1],n=parseInt(r,16),i=r.length,a=i%4===0,s=i>4,l=s?1:17,u=s?8:4,h=a?0:-1,f=s?255:15;return uh.set({r:(n>>u*(h+3)&f)*l,g:(n>>u*(h+2)&f)*l,b:(n>>u*(h+1)&f)*l,a:a?(n&f)*l/255:1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`#${su[Math.round(e)]}${su[Math.round(r)]}${su[Math.round(n)]}${su[Math.round(i*255)]}`:`#${su[Math.round(e)]}${su[Math.round(r)]}${su[Math.round(n)]}`},"stringify")},nd=Z$});var J4,Iy,J$=N(()=>{"use strict";Kl();My();J4={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:o(t=>{let e=t.match(J4.hueRe);if(e){let[,r,n]=e;switch(n){case"grad":return jt.channel.clamp.h(parseFloat(r)*.9);case"rad":return jt.channel.clamp.h(parseFloat(r)*180/Math.PI);case"turn":return jt.channel.clamp.h(parseFloat(r)*360)}}return jt.channel.clamp.h(parseFloat(t))},"_hue2deg"),parse:o(t=>{let e=t.charCodeAt(0);if(e!==104&&e!==72)return;let r=t.match(J4.re);if(!r)return;let[,n,i,a,s,l]=r;return uh.set({h:J4._hue2deg(n),s:jt.channel.clamp.s(parseFloat(i)),l:jt.channel.clamp.l(parseFloat(a)),a:s?jt.channel.clamp.a(l?parseFloat(s)/100:parseFloat(s)):1},t)},"parse"),stringify:o(t=>{let{h:e,s:r,l:n,a:i}=t;return i<1?`hsla(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%, ${i})`:`hsl(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%)`},"stringify")},Iy=J4});var e3,u7,ez=N(()=>{"use strict";c7();e3={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:o(t=>{t=t.toLowerCase();let e=e3.colors[t];if(e)return nd.parse(e)},"parse"),stringify:o(t=>{let e=nd.stringify(t);for(let r in e3.colors)if(e3.colors[r]===e)return r},"stringify")},u7=e3});var tz,Oy,rz=N(()=>{"use strict";Kl();My();tz={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:o(t=>{let e=t.charCodeAt(0);if(e!==114&&e!==82)return;let r=t.match(tz.re);if(!r)return;let[,n,i,a,s,l,u,h,f]=r;return uh.set({r:jt.channel.clamp.r(i?parseFloat(n)*2.55:parseFloat(n)),g:jt.channel.clamp.g(s?parseFloat(a)*2.55:parseFloat(a)),b:jt.channel.clamp.b(u?parseFloat(l)*2.55:parseFloat(l)),a:h?jt.channel.clamp.a(f?parseFloat(h)/100:parseFloat(h)):1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`rgba(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)}, ${jt.lang.round(i)})`:`rgb(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)})`},"stringify")},Oy=tz});var Bbe,Fi,ou=N(()=>{"use strict";c7();J$();ez();rz();Ny();Bbe={format:{keyword:u7,hex:nd,rgb:Oy,rgba:Oy,hsl:Iy,hsla:Iy},parse:o(t=>{if(typeof t!="string")return t;let e=nd.parse(t)||Oy.parse(t)||Iy.parse(t)||u7.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},"parse"),stringify:o(t=>!t.changed&&t.color?t.color:t.type.is(Bi.HSL)||t.data.r===void 0?Iy.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?Oy.stringify(t):nd.stringify(t),"stringify")},Fi=Bbe});var Fbe,t3,h7=N(()=>{"use strict";Kl();ou();Fbe=o((t,e)=>{let r=Fi.parse(t);for(let n in e)r[n]=jt.channel.clamp[n](e[n]);return Fi.stringify(r)},"change"),t3=Fbe});var $be,Qa,f7=N(()=>{"use strict";Kl();My();ou();h7();$be=o((t,e,r=0,n=1)=>{if(typeof t!="number")return t3(t,{a:e});let i=uh.set({r:jt.channel.clamp.r(t),g:jt.channel.clamp.g(e),b:jt.channel.clamp.b(r),a:jt.channel.clamp.a(n)});return Fi.stringify(i)},"rgba"),Qa=$be});var zbe,id,nz=N(()=>{"use strict";Kl();ou();zbe=o((t,e)=>jt.lang.round(Fi.parse(t)[e]),"channel"),id=zbe});var Gbe,iz,az=N(()=>{"use strict";Kl();ou();Gbe=o(t=>{let{r:e,g:r,b:n}=Fi.parse(t),i=.2126*jt.channel.toLinear(e)+.7152*jt.channel.toLinear(r)+.0722*jt.channel.toLinear(n);return jt.lang.round(i)},"luminance"),iz=Gbe});var Vbe,sz,oz=N(()=>{"use strict";az();Vbe=o(t=>iz(t)>=.5,"isLight"),sz=Vbe});var Ube,la,lz=N(()=>{"use strict";oz();Ube=o(t=>!sz(t),"isDark"),la=Ube});var Hbe,r3,d7=N(()=>{"use strict";Kl();ou();Hbe=o((t,e,r)=>{let n=Fi.parse(t),i=n[e],a=jt.channel.clamp[e](i+r);return i!==a&&(n[e]=a),Fi.stringify(n)},"adjustChannel"),r3=Hbe});var Wbe,Lt,cz=N(()=>{"use strict";d7();Wbe=o((t,e)=>r3(t,"l",e),"lighten"),Lt=Wbe});var qbe,Ot,uz=N(()=>{"use strict";d7();qbe=o((t,e)=>r3(t,"l",-e),"darken"),Ot=qbe});var Ybe,Me,hz=N(()=>{"use strict";ou();h7();Ybe=o((t,e)=>{let r=Fi.parse(t),n={};for(let i in e)e[i]&&(n[i]=r[i]+e[i]);return t3(t,n)},"adjust"),Me=Ybe});var Xbe,fz,dz=N(()=>{"use strict";ou();f7();Xbe=o((t,e,r=50)=>{let{r:n,g:i,b:a,a:s}=Fi.parse(t),{r:l,g:u,b:h,a:f}=Fi.parse(e),d=r/100,p=d*2-1,m=s-f,y=((p*m===-1?p:(p+m)/(1+p*m))+1)/2,v=1-y,x=n*y+l*v,b=i*y+u*v,T=a*y+h*v,S=s*d+f*(1-d);return Qa(x,b,T,S)},"mix"),fz=Xbe});var jbe,wt,pz=N(()=>{"use strict";ou();dz();jbe=o((t,e=100)=>{let r=Fi.parse(t);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,fz(r,t,e)},"invert"),wt=jbe});var mz=N(()=>{"use strict";f7();nz();lz();cz();uz();hz();pz()});var Ks=N(()=>{"use strict";mz()});var hh,fh,Py=N(()=>{"use strict";hh="#ffffff",fh="#f2f2f2"});var Si,y0=N(()=>{"use strict";Ks();Si=o((t,e)=>e?Me(t,{s:-40,l:10}):Me(t,{s:-40,l:-10}),"mkBorder")});var m7,gz,yz=N(()=>{"use strict";Ks();Py();y0();m7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||Me(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||Me(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Si(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Si(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||wt(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||wt(this.tertiaryColor),this.lineColor=this.lineColor||wt(this.background),this.arrowheadColor=this.arrowheadColor||wt(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?Ot(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||Ot(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||wt(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||Lt(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.vertLineColor=this.vertLineColor||"navy",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.darkMode?(this.rowOdd=this.rowOdd||Ot(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10)):(this.rowOdd=this.rowOdd||Lt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||Lt(this.mainBkg,5)),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.darkMode)for(let r=0;r{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},gz=o(t=>{let e=new m7;return e.calculate(t),e},"getThemeVariables")});var g7,vz,xz=N(()=>{"use strict";Ks();y0();g7=class{static{o(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=Lt(this.primaryColor,16),this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=wt(this.background),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=Lt(wt("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=Qa(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=Ot("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=Ot(this.sectionBkgColor,10),this.taskBorderColor=Qa(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=Qa(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Lt(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10),this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=Lt(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=Lt(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=Lt(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330});for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},vz=o(t=>{let e=new g7;return e.calculate(t),e},"getThemeVariables")});var y7,dh,By=N(()=>{"use strict";Ks();y0();Py();y7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=Me(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.sectionBkgColor=Qa(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="navy",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd="calculated",this.rowEven="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e{this[n]==="calculated"&&(this[n]=void 0)}),typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},dh=o(t=>{let e=new y7;return e.calculate(t),e},"getThemeVariables")});var v7,bz,Tz=N(()=>{"use strict";Ks();Py();y0();v7=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=Lt("#cde498",10),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.primaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=Ot(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},bz=o(t=>{let e=new v7;return e.calculate(t),e},"getThemeVariables")});var x7,wz,kz=N(()=>{"use strict";Ks();y0();Py();x7=class{static{o(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=Lt(this.contrast,55),this.background="#ffffff",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Si(this.primaryColor,this.darkMode),this.secondaryBorderColor=Si(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Si(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Lt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||"#f4f4f4",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=Lt(this.contrast,55),this.border2=this.contrast,this.actorBorder=Lt(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let e=0;e{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},wz=o(t=>{let e=new x7;return e.calculate(t),e},"getThemeVariables")});var Eo,n3=N(()=>{"use strict";yz();xz();By();Tz();kz();Eo={base:{getThemeVariables:gz},dark:{getThemeVariables:vz},default:{getThemeVariables:dh},forest:{getThemeVariables:bz},neutral:{getThemeVariables:wz}}});var ul,Ez=N(()=>{"use strict";ul={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200,inheritDir:!1},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,maxLabelWidth:360,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],titleColor:"",titleFontFamily:'"trebuchet ms", verdana, arial, sans-serif',titleFontSize:"4ex"},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,nodeSpacing:140,rankSpacing:80,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showDataLabel:!1,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16},radar:{useMaxWidth:!0,width:600,height:600,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,axisScaleFactor:1,axisLabelFactor:1.05,curveTension:.17},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1}});var Sz,Cz,Az,or,_a=N(()=>{"use strict";n3();Ez();Sz={...ul,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF"},themeCSS:void 0,themeVariables:Eo.default.getThemeVariables(),sequence:{...ul.sequence,messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont"),noteFont:o(function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},"noteFont"),actorFont:o(function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}},"actorFont")},class:{hideEmptyMembersBox:!1},gantt:{...ul.gantt,tickInterval:void 0,useWidth:void 0},c4:{...ul.c4,useWidth:void 0,personFont:o(function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},"personFont"),flowchart:{...ul.flowchart,inheritDir:!1},external_personFont:o(function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},"external_personFont"),systemFont:o(function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},"systemFont"),external_systemFont:o(function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},"external_systemFont"),system_dbFont:o(function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},"system_dbFont"),external_system_dbFont:o(function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},"external_system_dbFont"),system_queueFont:o(function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},"system_queueFont"),external_system_queueFont:o(function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},"external_system_queueFont"),containerFont:o(function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},"containerFont"),external_containerFont:o(function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},"external_containerFont"),container_dbFont:o(function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},"container_dbFont"),external_container_dbFont:o(function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},"external_container_dbFont"),container_queueFont:o(function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},"container_queueFont"),external_container_queueFont:o(function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},"external_container_queueFont"),componentFont:o(function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},"componentFont"),external_componentFont:o(function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},"external_componentFont"),component_dbFont:o(function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},"component_dbFont"),external_component_dbFont:o(function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},"external_component_dbFont"),component_queueFont:o(function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},"component_queueFont"),external_component_queueFont:o(function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},"external_component_queueFont"),boundaryFont:o(function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},"boundaryFont"),messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont")},pie:{...ul.pie,useWidth:984},xyChart:{...ul.xyChart,useWidth:void 0},requirement:{...ul.requirement,useWidth:void 0},packet:{...ul.packet},radar:{...ul.radar},treemap:{useMaxWidth:!0,padding:10,diagramPadding:8,showValues:!0,nodeWidth:100,nodeHeight:40,borderWidth:1,valueFontSize:12,labelFontSize:14,valueFormat:","}},Cz=o((t,e="")=>Object.keys(t).reduce((r,n)=>Array.isArray(t[n])?r:typeof t[n]=="object"&&t[n]!==null?[...r,e+n,...Cz(t[n],"")]:[...r,e+n],[]),"keyify"),Az=new Set(Cz(Sz,"")),or=Sz});var v0,Kbe,b7=N(()=>{"use strict";_a();yt();v0=o(t=>{if(X.debug("sanitizeDirective called with",t),!(typeof t!="object"||t==null)){if(Array.isArray(t)){t.forEach(e=>v0(e));return}for(let e of Object.keys(t)){if(X.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!Az.has(e)||t[e]==null){X.debug("sanitize deleting key: ",e),delete t[e];continue}if(typeof t[e]=="object"){X.debug("sanitizing object",e),v0(t[e]);continue}let r=["themeCSS","fontFamily","altFontFamily"];for(let n of r)e.includes(n)&&(X.debug("sanitizing css option",e),t[e]=Kbe(t[e]))}if(t.themeVariables)for(let e of Object.keys(t.themeVariables)){let r=t.themeVariables[e];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}X.debug("After sanitization",t)}},"sanitizeDirective"),Kbe=o(t=>{let e=0,r=0;for(let n of t){if(e{"use strict";g0();yt();n3();_a();b7();ph=Object.freeze(or),Ss=Un({},ph),x0=[],Fy=Un({},ph),i3=o((t,e)=>{let r=Un({},t),n={};for(let i of e)Nz(i),n=Un(n,i);if(r=Un(r,n),n.theme&&n.theme in Eo){let i=Un({},Dz),a=Un(i.themeVariables||{},n.themeVariables);r.theme&&r.theme in Eo&&(r.themeVariables=Eo[r.theme].getThemeVariables(a))}return Fy=r,Iz(Fy),Fy},"updateCurrentConfig"),T7=o(t=>(Ss=Un({},ph),Ss=Un(Ss,t),t.theme&&Eo[t.theme]&&(Ss.themeVariables=Eo[t.theme].getThemeVariables(t.themeVariables)),i3(Ss,x0),Ss),"setSiteConfig"),Lz=o(t=>{Dz=Un({},t)},"saveConfigFromInitialize"),Rz=o(t=>(Ss=Un(Ss,t),i3(Ss,x0),Ss),"updateSiteConfig"),w7=o(()=>Un({},Ss),"getSiteConfig"),a3=o(t=>(Iz(t),Un(Fy,t),tr()),"setConfig"),tr=o(()=>Un({},Fy),"getConfig"),Nz=o(t=>{t&&(["secure",...Ss.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(X.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{typeof t[e]=="string"&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],typeof t[e]=="object"&&Nz(t[e])}))},"sanitize"),Mz=o(t=>{v0(t),t.fontFamily&&!t.themeVariables?.fontFamily&&(t.themeVariables={...t.themeVariables,fontFamily:t.fontFamily}),x0.push(t),i3(Ss,x0)},"addDirective"),$y=o((t=Ss)=>{x0=[],i3(t,x0)},"reset"),Qbe={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},_z={},Zbe=o(t=>{_z[t]||(X.warn(Qbe[t]),_z[t]=!0)},"issueWarning"),Iz=o(t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&Zbe("LAZY_LOAD_DEPRECATED")},"checkConfig")});function es(t){return function(e){e instanceof RegExp&&(e.lastIndex=0);for(var r=arguments.length,n=new Array(r>1?r-1:0),i=1;i2&&arguments[2]!==void 0?arguments[2]:l3;Oz&&Oz(t,null);let n=e.length;for(;n--;){let i=e[n];if(typeof i=="string"){let a=r(i);a!==i&&(Jbe(e)||(e[n]=a),i=a)}t[i]=!0}return t}function o4e(t){for(let e=0;e0&&arguments[0]!==void 0?arguments[0]:v4e(),e=o(Dt=>Xz(Dt),"DOMPurify");if(e.version="3.2.5",e.removed=[],!t||!t.document||t.document.nodeType!==Hy.document||!t.Element)return e.isSupported=!1,e;let{document:r}=t,n=r,i=n.currentScript,{DocumentFragment:a,HTMLTemplateElement:s,Node:l,Element:u,NodeFilter:h,NamedNodeMap:f=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:d,DOMParser:p,trustedTypes:m}=t,g=u.prototype,y=Uy(g,"cloneNode"),v=Uy(g,"remove"),x=Uy(g,"nextSibling"),b=Uy(g,"childNodes"),T=Uy(g,"parentNode");if(typeof s=="function"){let Dt=r.createElement("template");Dt.content&&Dt.content.ownerDocument&&(r=Dt.content.ownerDocument)}let S,w="",{implementation:E,createNodeIterator:_,createDocumentFragment:C,getElementsByTagName:D}=r,{importNode:O}=n,R=Uz();e.isSupported=typeof Hz=="function"&&typeof T=="function"&&E&&E.createHTMLDocument!==void 0;let{MUSTACHE_EXPR:k,ERB_EXPR:L,TMPLIT_EXPR:A,DATA_ATTR:I,ARIA_ATTR:M,IS_SCRIPT_OR_DATA:P,ATTR_WHITESPACE:B,CUSTOM_ELEMENT:F}=Vz,{IS_ALLOWED_URI:z}=Vz,$=null,U=_r({},[...Fz,...E7,...S7,...C7,...$z]),K=null,ee=_r({},[...zz,...A7,...Gz,...o3]),Y=Object.seal(Wz(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ce=null,Z=null,ue=!0,Q=!0,j=!1,ne=!0,te=!1,he=!0,le=!1,J=!1,Se=!1,se=!1,ae=!1,Oe=!1,ye=!0,Be=!1,He="user-content-",ze=!0,Le=!1,Ie={},xe=null,q=_r({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),de=null,ie=_r({},["audio","video","img","source","image","track"]),oe=null,V=_r({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Te="http://www.w3.org/1998/Math/MathML",W="http://www.w3.org/2000/svg",pe="http://www.w3.org/1999/xhtml",ve=pe,Pe=!1,_e=null,be=_r({},[Te,W,pe],k7),Ve=_r({},["mi","mo","mn","ms","mtext"]),De=_r({},["annotation-xml"]),qe=_r({},["title","style","font","a","script"]),at=null,Rt=["application/xhtml+xml","text/html"],st="text/html",Ue=null,ct=null,We=r.createElement("form"),ot=o(function(Ce){return Ce instanceof RegExp||Ce instanceof Function},"isRegexOrFunction"),Yt=o(function(){let Ce=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(ct&&ct===Ce)){if((!Ce||typeof Ce!="object")&&(Ce={}),Ce=ad(Ce),at=Rt.indexOf(Ce.PARSER_MEDIA_TYPE)===-1?st:Ce.PARSER_MEDIA_TYPE,Ue=at==="application/xhtml+xml"?k7:l3,$=hl(Ce,"ALLOWED_TAGS")?_r({},Ce.ALLOWED_TAGS,Ue):U,K=hl(Ce,"ALLOWED_ATTR")?_r({},Ce.ALLOWED_ATTR,Ue):ee,_e=hl(Ce,"ALLOWED_NAMESPACES")?_r({},Ce.ALLOWED_NAMESPACES,k7):be,oe=hl(Ce,"ADD_URI_SAFE_ATTR")?_r(ad(V),Ce.ADD_URI_SAFE_ATTR,Ue):V,de=hl(Ce,"ADD_DATA_URI_TAGS")?_r(ad(ie),Ce.ADD_DATA_URI_TAGS,Ue):ie,xe=hl(Ce,"FORBID_CONTENTS")?_r({},Ce.FORBID_CONTENTS,Ue):q,ce=hl(Ce,"FORBID_TAGS")?_r({},Ce.FORBID_TAGS,Ue):{},Z=hl(Ce,"FORBID_ATTR")?_r({},Ce.FORBID_ATTR,Ue):{},Ie=hl(Ce,"USE_PROFILES")?Ce.USE_PROFILES:!1,ue=Ce.ALLOW_ARIA_ATTR!==!1,Q=Ce.ALLOW_DATA_ATTR!==!1,j=Ce.ALLOW_UNKNOWN_PROTOCOLS||!1,ne=Ce.ALLOW_SELF_CLOSE_IN_ATTR!==!1,te=Ce.SAFE_FOR_TEMPLATES||!1,he=Ce.SAFE_FOR_XML!==!1,le=Ce.WHOLE_DOCUMENT||!1,se=Ce.RETURN_DOM||!1,ae=Ce.RETURN_DOM_FRAGMENT||!1,Oe=Ce.RETURN_TRUSTED_TYPE||!1,Se=Ce.FORCE_BODY||!1,ye=Ce.SANITIZE_DOM!==!1,Be=Ce.SANITIZE_NAMED_PROPS||!1,ze=Ce.KEEP_CONTENT!==!1,Le=Ce.IN_PLACE||!1,z=Ce.ALLOWED_URI_REGEXP||qz,ve=Ce.NAMESPACE||pe,Ve=Ce.MATHML_TEXT_INTEGRATION_POINTS||Ve,De=Ce.HTML_INTEGRATION_POINTS||De,Y=Ce.CUSTOM_ELEMENT_HANDLING||{},Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Y.tagNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Y.attributeNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&typeof Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(Y.allowCustomizedBuiltInElements=Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),te&&(Q=!1),ae&&(se=!0),Ie&&($=_r({},$z),K=[],Ie.html===!0&&(_r($,Fz),_r(K,zz)),Ie.svg===!0&&(_r($,E7),_r(K,A7),_r(K,o3)),Ie.svgFilters===!0&&(_r($,S7),_r(K,A7),_r(K,o3)),Ie.mathMl===!0&&(_r($,C7),_r(K,Gz),_r(K,o3))),Ce.ADD_TAGS&&($===U&&($=ad($)),_r($,Ce.ADD_TAGS,Ue)),Ce.ADD_ATTR&&(K===ee&&(K=ad(K)),_r(K,Ce.ADD_ATTR,Ue)),Ce.ADD_URI_SAFE_ATTR&&_r(oe,Ce.ADD_URI_SAFE_ATTR,Ue),Ce.FORBID_CONTENTS&&(xe===q&&(xe=ad(xe)),_r(xe,Ce.FORBID_CONTENTS,Ue)),ze&&($["#text"]=!0),le&&_r($,["html","head","body"]),$.table&&(_r($,["tbody"]),delete ce.tbody),Ce.TRUSTED_TYPES_POLICY){if(typeof Ce.TRUSTED_TYPES_POLICY.createHTML!="function")throw Vy('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof Ce.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Vy('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');S=Ce.TRUSTED_TYPES_POLICY,w=S.createHTML("")}else S===void 0&&(S=x4e(m,i)),S!==null&&typeof w=="string"&&(w=S.createHTML(""));Ja&&Ja(Ce),ct=Ce}},"_parseConfig"),Tt=_r({},[...E7,...S7,...l4e]),Mt=_r({},[...C7,...c4e]),bt=o(function(Ce){let tt=T(Ce);(!tt||!tt.tagName)&&(tt={namespaceURI:ve,tagName:"template"});let Ct=l3(Ce.tagName),gr=l3(tt.tagName);return _e[Ce.namespaceURI]?Ce.namespaceURI===W?tt.namespaceURI===pe?Ct==="svg":tt.namespaceURI===Te?Ct==="svg"&&(gr==="annotation-xml"||Ve[gr]):!!Tt[Ct]:Ce.namespaceURI===Te?tt.namespaceURI===pe?Ct==="math":tt.namespaceURI===W?Ct==="math"&&De[gr]:!!Mt[Ct]:Ce.namespaceURI===pe?tt.namespaceURI===W&&!De[gr]||tt.namespaceURI===Te&&!Ve[gr]?!1:!Mt[Ct]&&(qe[Ct]||!Tt[Ct]):!!(at==="application/xhtml+xml"&&_e[Ce.namespaceURI]):!1},"_checkValidNamespace"),ut=o(function(Ce){zy(e.removed,{element:Ce});try{T(Ce).removeChild(Ce)}catch{v(Ce)}},"_forceRemove"),St=o(function(Ce,tt){try{zy(e.removed,{attribute:tt.getAttributeNode(Ce),from:tt})}catch{zy(e.removed,{attribute:null,from:tt})}if(tt.removeAttribute(Ce),Ce==="is")if(se||ae)try{ut(tt)}catch{}else try{tt.setAttribute(Ce,"")}catch{}},"_removeAttribute"),ft=o(function(Ce){let tt=null,Ct=null;if(Se)Ce=""+Ce;else{let yn=Bz(Ce,/^[\r\n\t ]+/);Ct=yn&&yn[0]}at==="application/xhtml+xml"&&ve===pe&&(Ce=''+Ce+"");let gr=S?S.createHTML(Ce):Ce;if(ve===pe)try{tt=new p().parseFromString(gr,at)}catch{}if(!tt||!tt.documentElement){tt=E.createDocument(ve,"template",null);try{tt.documentElement.innerHTML=Pe?w:gr}catch{}}let rn=tt.body||tt.documentElement;return Ce&&Ct&&rn.insertBefore(r.createTextNode(Ct),rn.childNodes[0]||null),ve===pe?D.call(tt,le?"html":"body")[0]:le?tt.documentElement:rn},"_initDocument"),vt=o(function(Ce){return _.call(Ce.ownerDocument||Ce,Ce,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT|h.SHOW_PROCESSING_INSTRUCTION|h.SHOW_CDATA_SECTION,null)},"_createNodeIterator"),nt=o(function(Ce){return Ce instanceof d&&(typeof Ce.nodeName!="string"||typeof Ce.textContent!="string"||typeof Ce.removeChild!="function"||!(Ce.attributes instanceof f)||typeof Ce.removeAttribute!="function"||typeof Ce.setAttribute!="function"||typeof Ce.namespaceURI!="string"||typeof Ce.insertBefore!="function"||typeof Ce.hasChildNodes!="function")},"_isClobbered"),pn=o(function(Ce){return typeof l=="function"&&Ce instanceof l},"_isNode");function kt(Dt,Ce,tt){s3(Dt,Ct=>{Ct.call(e,Ce,tt,ct)})}o(kt,"_executeHooks");let On=o(function(Ce){let tt=null;if(kt(R.beforeSanitizeElements,Ce,null),nt(Ce))return ut(Ce),!0;let Ct=Ue(Ce.nodeName);if(kt(R.uponSanitizeElement,Ce,{tagName:Ct,allowedTags:$}),Ce.hasChildNodes()&&!pn(Ce.firstElementChild)&&Za(/<[/\w!]/g,Ce.innerHTML)&&Za(/<[/\w!]/g,Ce.textContent)||Ce.nodeType===Hy.progressingInstruction||he&&Ce.nodeType===Hy.comment&&Za(/<[/\w]/g,Ce.data))return ut(Ce),!0;if(!$[Ct]||ce[Ct]){if(!ce[Ct]&&Mr(Ct)&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ct)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ct)))return!1;if(ze&&!xe[Ct]){let gr=T(Ce)||Ce.parentNode,rn=b(Ce)||Ce.childNodes;if(rn&&gr){let yn=rn.length;for(let Zr=yn-1;Zr>=0;--Zr){let Oi=y(rn[Zr],!0);Oi.__removalCount=(Ce.__removalCount||0)+1,gr.insertBefore(Oi,x(Ce))}}}return ut(Ce),!0}return Ce instanceof u&&!bt(Ce)||(Ct==="noscript"||Ct==="noembed"||Ct==="noframes")&&Za(/<\/no(script|embed|frames)/i,Ce.innerHTML)?(ut(Ce),!0):(te&&Ce.nodeType===Hy.text&&(tt=Ce.textContent,s3([k,L,A],gr=>{tt=Gy(tt,gr," ")}),Ce.textContent!==tt&&(zy(e.removed,{element:Ce.cloneNode()}),Ce.textContent=tt)),kt(R.afterSanitizeElements,Ce,null),!1)},"_sanitizeElements"),tn=o(function(Ce,tt,Ct){if(ye&&(tt==="id"||tt==="name")&&(Ct in r||Ct in We))return!1;if(!(Q&&!Z[tt]&&Za(I,tt))){if(!(ue&&Za(M,tt))){if(!K[tt]||Z[tt]){if(!(Mr(Ce)&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ce)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ce))&&(Y.attributeNameCheck instanceof RegExp&&Za(Y.attributeNameCheck,tt)||Y.attributeNameCheck instanceof Function&&Y.attributeNameCheck(tt))||tt==="is"&&Y.allowCustomizedBuiltInElements&&(Y.tagNameCheck instanceof RegExp&&Za(Y.tagNameCheck,Ct)||Y.tagNameCheck instanceof Function&&Y.tagNameCheck(Ct))))return!1}else if(!oe[tt]){if(!Za(z,Gy(Ct,B,""))){if(!((tt==="src"||tt==="xlink:href"||tt==="href")&&Ce!=="script"&&i4e(Ct,"data:")===0&&de[Ce])){if(!(j&&!Za(P,Gy(Ct,B,"")))){if(Ct)return!1}}}}}}return!0},"_isValidAttribute"),Mr=o(function(Ce){return Ce!=="annotation-xml"&&Bz(Ce,F)},"_isBasicCustomElement"),Ir=o(function(Ce){kt(R.beforeSanitizeAttributes,Ce,null);let{attributes:tt}=Ce;if(!tt||nt(Ce))return;let Ct={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:K,forceKeepAttr:void 0},gr=tt.length;for(;gr--;){let rn=tt[gr],{name:yn,namespaceURI:Zr,value:Oi}=rn,ei=Ue(yn),Sn=yn==="value"?Oi:a4e(Oi);if(Ct.attrName=ei,Ct.attrValue=Sn,Ct.keepAttr=!0,Ct.forceKeepAttr=void 0,kt(R.uponSanitizeAttribute,Ce,Ct),Sn=Ct.attrValue,Be&&(ei==="id"||ei==="name")&&(St(yn,Ce),Sn=He+Sn),he&&Za(/((--!?|])>)|<\/(style|title)/i,Sn)){St(yn,Ce);continue}if(Ct.forceKeepAttr||(St(yn,Ce),!Ct.keepAttr))continue;if(!ne&&Za(/\/>/i,Sn)){St(yn,Ce);continue}te&&s3([k,L,A],et=>{Sn=Gy(Sn,et," ")});let Hr=Ue(Ce.nodeName);if(tn(Hr,ei,Sn)){if(S&&typeof m=="object"&&typeof m.getAttributeType=="function"&&!Zr)switch(m.getAttributeType(Hr,ei)){case"TrustedHTML":{Sn=S.createHTML(Sn);break}case"TrustedScriptURL":{Sn=S.createScriptURL(Sn);break}}try{Zr?Ce.setAttributeNS(Zr,yn,Sn):Ce.setAttribute(yn,Sn),nt(Ce)?ut(Ce):Pz(e.removed)}catch{}}}kt(R.afterSanitizeAttributes,Ce,null)},"_sanitizeAttributes"),Pn=o(function Dt(Ce){let tt=null,Ct=vt(Ce);for(kt(R.beforeSanitizeShadowDOM,Ce,null);tt=Ct.nextNode();)kt(R.uponSanitizeShadowNode,tt,null),On(tt),Ir(tt),tt.content instanceof a&&Dt(tt.content);kt(R.afterSanitizeShadowDOM,Ce,null)},"_sanitizeShadowDOM");return e.sanitize=function(Dt){let Ce=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},tt=null,Ct=null,gr=null,rn=null;if(Pe=!Dt,Pe&&(Dt=""),typeof Dt!="string"&&!pn(Dt))if(typeof Dt.toString=="function"){if(Dt=Dt.toString(),typeof Dt!="string")throw Vy("dirty is not a string, aborting")}else throw Vy("toString is not a function");if(!e.isSupported)return Dt;if(J||Yt(Ce),e.removed=[],typeof Dt=="string"&&(Le=!1),Le){if(Dt.nodeName){let Oi=Ue(Dt.nodeName);if(!$[Oi]||ce[Oi])throw Vy("root node is forbidden and cannot be sanitized in-place")}}else if(Dt instanceof l)tt=ft(""),Ct=tt.ownerDocument.importNode(Dt,!0),Ct.nodeType===Hy.element&&Ct.nodeName==="BODY"||Ct.nodeName==="HTML"?tt=Ct:tt.appendChild(Ct);else{if(!se&&!te&&!le&&Dt.indexOf("<")===-1)return S&&Oe?S.createHTML(Dt):Dt;if(tt=ft(Dt),!tt)return se?null:Oe?w:""}tt&&Se&&ut(tt.firstChild);let yn=vt(Le?Dt:tt);for(;gr=yn.nextNode();)On(gr),Ir(gr),gr.content instanceof a&&Pn(gr.content);if(Le)return Dt;if(se){if(ae)for(rn=C.call(tt.ownerDocument);tt.firstChild;)rn.appendChild(tt.firstChild);else rn=tt;return(K.shadowroot||K.shadowrootmode)&&(rn=O.call(n,rn,!0)),rn}let Zr=le?tt.outerHTML:tt.innerHTML;return le&&$["!doctype"]&&tt.ownerDocument&&tt.ownerDocument.doctype&&tt.ownerDocument.doctype.name&&Za(Yz,tt.ownerDocument.doctype.name)&&(Zr=" -`+Zr),te&&s3([k,L,A],Oi=>{Zr=Gy(Zr,Oi," ")}),S&&Oe?S.createHTML(Zr):Zr},e.setConfig=function(){let Dt=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Yt(Dt),J=!0},e.clearConfig=function(){ct=null,J=!1},e.isValidAttribute=function(Dt,Ce,tt){ct||Yt({});let Ct=Ue(Dt),gr=Ue(Ce);return tn(Ct,gr,tt)},e.addHook=function(Dt,Ce){typeof Ce=="function"&&zy(R[Dt],Ce)},e.removeHook=function(Dt,Ce){if(Ce!==void 0){let tt=r4e(R[Dt],Ce);return tt===-1?void 0:n4e(R[Dt],tt,1)[0]}return Pz(R[Dt])},e.removeHooks=function(Dt){R[Dt]=[]},e.removeAllHooks=function(){R=Uz()},e}var Hz,Oz,Jbe,e4e,t4e,Ja,So,Wz,_7,D7,s3,r4e,Pz,zy,n4e,l3,k7,Bz,Gy,i4e,a4e,hl,Za,Vy,Fz,E7,S7,l4e,C7,c4e,$z,zz,A7,Gz,o3,u4e,h4e,f4e,d4e,p4e,qz,m4e,g4e,Yz,y4e,Vz,Hy,v4e,x4e,Uz,mh,L7=N(()=>{"use strict";({entries:Hz,setPrototypeOf:Oz,isFrozen:Jbe,getPrototypeOf:e4e,getOwnPropertyDescriptor:t4e}=Object),{freeze:Ja,seal:So,create:Wz}=Object,{apply:_7,construct:D7}=typeof Reflect<"u"&&Reflect;Ja||(Ja=o(function(e){return e},"freeze"));So||(So=o(function(e){return e},"seal"));_7||(_7=o(function(e,r,n){return e.apply(r,n)},"apply"));D7||(D7=o(function(e,r){return new e(...r)},"construct"));s3=es(Array.prototype.forEach),r4e=es(Array.prototype.lastIndexOf),Pz=es(Array.prototype.pop),zy=es(Array.prototype.push),n4e=es(Array.prototype.splice),l3=es(String.prototype.toLowerCase),k7=es(String.prototype.toString),Bz=es(String.prototype.match),Gy=es(String.prototype.replace),i4e=es(String.prototype.indexOf),a4e=es(String.prototype.trim),hl=es(Object.prototype.hasOwnProperty),Za=es(RegExp.prototype.test),Vy=s4e(TypeError);o(es,"unapply");o(s4e,"unconstruct");o(_r,"addToSet");o(o4e,"cleanArray");o(ad,"clone");o(Uy,"lookupGetter");Fz=Ja(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),E7=Ja(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),S7=Ja(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),l4e=Ja(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),C7=Ja(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),c4e=Ja(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),$z=Ja(["#text"]),zz=Ja(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),A7=Ja(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),Gz=Ja(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),o3=Ja(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),u4e=So(/\{\{[\w\W]*|[\w\W]*\}\}/gm),h4e=So(/<%[\w\W]*|[\w\W]*%>/gm),f4e=So(/\$\{[\w\W]*/gm),d4e=So(/^data-[\-\w.\u00B7-\uFFFF]+$/),p4e=So(/^aria-[\-\w]+$/),qz=So(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),m4e=So(/^(?:\w+script|data):/i),g4e=So(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Yz=So(/^html$/i),y4e=So(/^[a-z][.\w]*(-[.\w]+)+$/i),Vz=Object.freeze({__proto__:null,ARIA_ATTR:p4e,ATTR_WHITESPACE:g4e,CUSTOM_ELEMENT:y4e,DATA_ATTR:d4e,DOCTYPE_NAME:Yz,ERB_EXPR:h4e,IS_ALLOWED_URI:qz,IS_SCRIPT_OR_DATA:m4e,MUSTACHE_EXPR:u4e,TMPLIT_EXPR:f4e}),Hy={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},v4e=o(function(){return typeof window>"u"?null:window},"getGlobal"),x4e=o(function(e,r){if(typeof e!="object"||typeof e.createPolicy!="function")return null;let n=null,i="data-tt-policy-suffix";r&&r.hasAttribute(i)&&(n=r.getAttribute(i));let a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML(s){return s},createScriptURL(s){return s}})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}},"_createTrustedTypesPolicy"),Uz=o(function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},"_createHooksMap");o(Xz,"createDOMPurify");mh=Xz()});var CV={};ur(CV,{ParseError:()=>pt,SETTINGS_SCHEMA:()=>Xy,__defineFunction:()=>Nt,__defineMacro:()=>fe,__defineSymbol:()=>G,__domTree:()=>SV,__parse:()=>TV,__renderToDomTree:()=>O3,__renderToHTMLTree:()=>kV,__setFontMetrics:()=>_G,default:()=>u5e,render:()=>xA,renderToString:()=>bV,version:()=>EV});function C4e(t){return String(t).replace(S4e,e=>E4e[e])}function L4e(t){if(t.default)return t.default;var e=t.type,r=Array.isArray(e)?e[0]:e;if(typeof r!="string")return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}function B4e(t){for(var e=0;e=i[0]&&t<=i[1])return r.name}return null}function AG(t){for(var e=0;e=b3[e]&&t<=b3[e+1])return!0;return!1}function _G(t,e){Jl[t]=e}function nA(t,e,r){if(!Jl[e])throw new Error("Font metrics not found for font: "+e+".");var n=t.charCodeAt(0),i=Jl[e][n];if(!i&&t[0]in Kz&&(n=Kz[t[0]].charCodeAt(0),i=Jl[e][n]),!i&&r==="text"&&AG(n)&&(i=Jl[e][77]),i)return{depth:i[0],height:i[1],italic:i[2],skew:i[3],width:i[4]}}function X4e(t){var e;if(t>=5?e=0:t>=3?e=1:e=2,!R7[e]){var r=R7[e]={cssEmPerMu:c3.quad[e]/18};for(var n in c3)c3.hasOwnProperty(n)&&(r[n]=c3[n][e])}return R7[e]}function Jz(t){if(t instanceof As)return t;throw new Error("Expected symbolNode but got "+String(t)+".")}function J4e(t){if(t instanceof ld)return t;throw new Error("Expected span but got "+String(t)+".")}function G(t,e,r,n,i,a){An[t][i]={font:e,group:r,replace:n},a&&n&&(An[t][n]=An[t][i])}function Nt(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs,argTypes:n.argTypes,allowedInArgument:!!n.allowedInArgument,allowedInText:!!n.allowedInText,allowedInMath:n.allowedInMath===void 0?!0:n.allowedInMath,numOptionalArgs:n.numOptionalArgs||0,infix:!!n.infix,primitive:!!n.primitive,handler:i},u=0;u0&&(a.push(g3(s,e)),s=[]),a.push(n[l]));s.length>0&&a.push(g3(s,e));var h;r?(h=g3($i(r,e,!0)),h.classes=["tag"],a.push(h)):i&&a.push(i);var f=fu(["katex-html"],a);if(f.setAttribute("aria-hidden","true"),h){var d=h.children[0];d.style.height=Et(f.height+f.depth),f.depth&&(d.style.verticalAlign=Et(-f.depth))}return f}function zG(t){return new od(t)}function I7(t){if(!t)return!1;if(t.type==="mi"&&t.children.length===1){var e=t.children[0];return e instanceof Ao&&e.text==="."}else if(t.type==="mo"&&t.children.length===1&&t.getAttribute("separator")==="true"&&t.getAttribute("lspace")==="0em"&&t.getAttribute("rspace")==="0em"){var r=t.children[0];return r instanceof Ao&&r.text===","}else return!1}function iG(t,e,r,n,i){var a=_s(t,r),s;a.length===1&&a[0]instanceof ts&&Jt.contains(["mrow","mtable"],a[0].type)?s=a[0]:s=new dt.MathNode("mrow",a);var l=new dt.MathNode("annotation",[new dt.TextNode(e)]);l.setAttribute("encoding","application/x-tex");var u=new dt.MathNode("semantics",[s,l]),h=new dt.MathNode("math",[u]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&h.setAttribute("display","block");var f=i?"katex":"katex-mathml";return Fe.makeSpan([f],[h])}function xr(t,e){if(!t||t.type!==e)throw new Error("Expected node of type "+e+", but got "+(t?"node of type "+t.type:String(t)));return t}function oA(t){var e=R3(t);if(!e)throw new Error("Expected node of symbol group type, but got "+(t?"node of type "+t.type:String(t)));return e}function R3(t){return t&&(t.type==="atom"||t3e.hasOwnProperty(t.type))?t:null}function HG(t,e){var r=$i(t.body,e,!0);return R3e([t.mclass],r,e)}function WG(t,e){var r,n=_s(t.body,e);return t.mclass==="minner"?r=new dt.MathNode("mpadded",n):t.mclass==="mord"?t.isCharacterBox?(r=n[0],r.type="mi"):r=new dt.MathNode("mi",n):(t.isCharacterBox?(r=n[0],r.type="mo"):r=new dt.MathNode("mo",n),t.mclass==="mbin"?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):t.mclass==="mpunct"?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):t.mclass==="mopen"||t.mclass==="mclose"?(r.attributes.lspace="0em",r.attributes.rspace="0em"):t.mclass==="minner"&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}function I3e(t,e,r){var n=N3e[t];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var i=r.callFunction("\\\\cdleft",[e[0]],[]),a={type:"atom",text:n,mode:"math",family:"rel"},s=r.callFunction("\\Big",[a],[]),l=r.callFunction("\\\\cdright",[e[1]],[]),u={type:"ordgroup",mode:"math",body:[i,s,l]};return r.callFunction("\\\\cdparent",[u],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function O3e(t){var e=[];for(t.gullet.beginGroup(),t.gullet.macros.set("\\cr","\\\\\\relax"),t.gullet.beginGroup();;){e.push(t.parseExpression(!1,"\\\\")),t.gullet.endGroup(),t.gullet.beginGroup();var r=t.fetch().text;if(r==="&"||r==="\\\\")t.consume();else if(r==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new pt("Expected \\\\ or \\cr or \\end",t.nextToken)}for(var n=[],i=[n],a=0;a-1))if("<>AV".indexOf(h)>-1)for(var d=0;d<2;d++){for(var p=!0,m=u+1;mAV=|." after @',s[u]);var g=I3e(h,f,t),y={type:"styling",body:[g],mode:"math",style:"display"};n.push(y),l=aG()}a%2===0?n.push(l):n.shift(),n=[],i.push(n)}t.gullet.endGroup(),t.gullet.endGroup();var v=new Array(i[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:i,arraystretch:1,addJot:!0,rowGaps:[null],cols:v,colSeparationType:"CD",hLinesBeforeRow:new Array(i.length+1).fill([])}}function M3(t,e){var r=R3(t);if(r&&Jt.contains(X3e,r.text))return r;throw r?new pt("Invalid delimiter '"+r.text+"' after '"+e.funcName+"'",t):new pt("Invalid delimiter type '"+t.type+"'",t)}function lG(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}function tc(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:i},u=0;u1||!f)&&y.pop(),x.length{"use strict";Qs=class t{static{o(this,"SourceLocation")}constructor(e,r,n){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=r,this.end=n}static range(e,r){return r?!e||!e.loc||!r.loc||e.loc.lexer!==r.loc.lexer?null:new t(e.loc.lexer,e.loc.start,r.loc.end):e&&e.loc}},_o=class t{static{o(this,"Token")}constructor(e,r){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=r}range(e,r){return new t(r,Qs.range(this,e))}},pt=class t{static{o(this,"ParseError")}constructor(e,r){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var n="KaTeX parse error: "+e,i,a,s=r&&r.loc;if(s&&s.start<=s.end){var l=s.lexer.input;i=s.start,a=s.end,i===l.length?n+=" at end of input: ":n+=" at position "+(i+1)+": ";var u=l.slice(i,a).replace(/[^]/g,"$&\u0332"),h;i>15?h="\u2026"+l.slice(i-15,i):h=l.slice(0,i);var f;a+15":">","<":"<",'"':""","'":"'"},S4e=/[&><"']/g;o(C4e,"escape");CG=o(function t(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?t(e.body[0]):e:e.type==="font"?t(e.body):e},"getBaseElem"),A4e=o(function(e){var r=CG(e);return r.type==="mathord"||r.type==="textord"||r.type==="atom"},"isCharacterBox"),_4e=o(function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},"assert"),D4e=o(function(e){var r=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return r?r[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(r[1])?null:r[1].toLowerCase():"_relative"},"protocolFromUrl"),Jt={contains:b4e,deflt:T4e,escape:C4e,hyphenate:k4e,getBaseElem:CG,isCharacterBox:A4e,protocolFromUrl:D4e},Xy={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:o(t=>"#"+t,"cliProcessor")},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:o((t,e)=>(e.push(t),e),"cliProcessor")},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:o(t=>Math.max(0,t),"processor"),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:o(t=>Math.max(0,t),"processor"),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:o(t=>Math.max(0,t),"processor"),cli:"-e, --max-expand ",cliProcessor:o(t=>t==="Infinity"?1/0:parseInt(t),"cliProcessor")},globalGroup:{type:"boolean",cli:!1}};o(L4e,"getDefaultValue");Ky=class{static{o(this,"Settings")}constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var r in Xy)if(Xy.hasOwnProperty(r)){var n=Xy[r];this[r]=e[r]!==void 0?n.processor?n.processor(e[r]):e[r]:L4e(n)}}reportNonstrict(e,r,n){var i=this.strict;if(typeof i=="function"&&(i=i(e,r,n)),!(!i||i==="ignore")){if(i===!0||i==="error")throw new pt("LaTeX-incompatible input and strict mode is set to 'error': "+(r+" ["+e+"]"),n);i==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]"))}}useStrictBehavior(e,r,n){var i=this.strict;if(typeof i=="function")try{i=i(e,r,n)}catch{i="error"}return!i||i==="ignore"?!1:i===!0||i==="error"?!0:i==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var r=Jt.protocolFromUrl(e.url);if(r==null)return!1;e.protocol=r}var n=typeof this.trust=="function"?this.trust(e):this.trust;return!!n}},Ql=class{static{o(this,"Style")}constructor(e,r,n){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=r,this.cramped=n}sup(){return Zl[R4e[this.id]]}sub(){return Zl[N4e[this.id]]}fracNum(){return Zl[M4e[this.id]]}fracDen(){return Zl[I4e[this.id]]}cramp(){return Zl[O4e[this.id]]}text(){return Zl[P4e[this.id]]}isTight(){return this.size>=2}},rA=0,T3=1,w0=2,uu=3,Qy=4,Co=5,k0=6,rs=7,Zl=[new Ql(rA,0,!1),new Ql(T3,0,!0),new Ql(w0,1,!1),new Ql(uu,1,!0),new Ql(Qy,2,!1),new Ql(Co,2,!0),new Ql(k0,3,!1),new Ql(rs,3,!0)],R4e=[Qy,Co,Qy,Co,k0,rs,k0,rs],N4e=[Co,Co,Co,Co,rs,rs,rs,rs],M4e=[w0,uu,Qy,Co,k0,rs,k0,rs],I4e=[uu,uu,Co,Co,rs,rs,rs,rs],O4e=[T3,T3,uu,uu,Co,Co,rs,rs],P4e=[rA,T3,w0,uu,w0,uu,w0,uu],nr={DISPLAY:Zl[rA],TEXT:Zl[w0],SCRIPT:Zl[Qy],SCRIPTSCRIPT:Zl[k0]},H7=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];o(B4e,"scriptFromCodepoint");b3=[];H7.forEach(t=>t.blocks.forEach(e=>b3.push(...e)));o(AG,"supportedCodepoint");T0=80,F4e=o(function(e,r){return"M95,"+(622+e+r)+` -c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 -c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 -c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 -s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429 -c69,-144,104.5,-217.7,106.5,-221 -l`+e/2.075+" -"+e+` -c5.3,-9.3,12,-14,20,-14 -H400000v`+(40+e)+`H845.2724 -s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 -c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z -M`+(834+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtMain"),$4e=o(function(e,r){return"M263,"+(601+e+r)+`c0.7,0,18,39.7,52,119 -c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 -c340,-704.7,510.7,-1060.3,512,-1067 -l`+e/2.084+" -"+e+` -c4.7,-7.3,11,-11,19,-11 -H40000v`+(40+e)+`H1012.3 -s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232 -c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 -s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 -c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z -M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize1"),z4e=o(function(e,r){return"M983 "+(10+e+r)+` -l`+e/3.13+" -"+e+` -c4,-6.7,10,-10,18,-10 H400000v`+(40+e)+` -H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7 -s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744 -c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30 -c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722 -c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5 -c53.7,-170.3,84.5,-266.8,92.5,-289.5z -M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize2"),G4e=o(function(e,r){return"M424,"+(2398+e+r)+` -c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514 -c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20 -s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121 -s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081 -l`+e/4.223+" -"+e+`c4,-6.7,10,-10,18,-10 H400000 -v`+(40+e)+`H1014.6 -s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185 -c-2,6,-10,9,-24,9 -c-8,0,-12,-0.7,-12,-2z M`+(1001+e)+" "+r+` -h400000v`+(40+e)+"h-400000z"},"sqrtSize3"),V4e=o(function(e,r){return"M473,"+(2713+e+r)+` -c339.3,-1799.3,509.3,-2700,510,-2702 l`+e/5.298+" -"+e+` -c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+e)+`H1017.7 -s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9 -c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200 -c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26 -s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104, -606zM`+(1001+e)+" "+r+"h400000v"+(40+e)+"H1017.7z"},"sqrtSize4"),U4e=o(function(e){var r=e/2;return"M400000 "+e+" H0 L"+r+" 0 l65 45 L145 "+(e-80)+" H400000z"},"phasePath"),H4e=o(function(e,r,n){var i=n-54-r-e;return"M702 "+(e+r)+"H400000"+(40+e)+` -H742v`+i+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1 -h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170 -c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 -219 661 l218 661zM702 `+r+"H400000v"+(40+e)+"H742z"},"sqrtTall"),W4e=o(function(e,r,n){r=1e3*r;var i="";switch(e){case"sqrtMain":i=F4e(r,T0);break;case"sqrtSize1":i=$4e(r,T0);break;case"sqrtSize2":i=z4e(r,T0);break;case"sqrtSize3":i=G4e(r,T0);break;case"sqrtSize4":i=V4e(r,T0);break;case"sqrtTall":i=H4e(r,T0,n)}return i},"sqrtPath"),q4e=o(function(e,r){switch(e){case"\u239C":return"M291 0 H417 V"+r+" H291z M291 0 H417 V"+r+" H291z";case"\u2223":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z";case"\u2225":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z"+("M367 0 H410 V"+r+" H367z M367 0 H410 V"+r+" H367z");case"\u239F":return"M457 0 H583 V"+r+" H457z M457 0 H583 V"+r+" H457z";case"\u23A2":return"M319 0 H403 V"+r+" H319z M319 0 H403 V"+r+" H319z";case"\u23A5":return"M263 0 H347 V"+r+" H263z M263 0 H347 V"+r+" H263z";case"\u23AA":return"M384 0 H504 V"+r+" H384z M384 0 H504 V"+r+" H384z";case"\u23D0":return"M312 0 H355 V"+r+" H312z M312 0 H355 V"+r+" H312z";case"\u2016":return"M257 0 H300 V"+r+" H257z M257 0 H300 V"+r+" H257z"+("M478 0 H521 V"+r+" H478z M478 0 H521 V"+r+" H478z");default:return""}},"innerPath"),jz={doubleleftarrow:`M262 157 -l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 - 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28 - 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5 -c2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5 - 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87 --86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7 --2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z -m8 0v40h399730v-40zm0 194v40h399730v-40z`,doublerightarrow:`M399738 392l --10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5 - 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88 --33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68 --17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18 --13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782 -c-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3 --107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,leftarrow:`M400000 241H110l3-3c68.7-52.7 113.7-120 - 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8 --5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247 -c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208 - 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3 - 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202 - l-3-3h399890zM100 241v40h399900v-40z`,leftbrace:`M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117 --45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7 - 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,leftbraceunder:`M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13 - 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688 - 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7 --331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,leftgroup:`M400000 80 -H435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0 - 435 0h399565z`,leftgroupunder:`M400000 262 -H435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219 - 435 219h399565z`,leftharpoon:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3 --3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5 --18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7 --196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,leftharpoonplus:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5 - 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3 --4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7 --10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z -m0 0v40h400000v-40z`,leftharpoondown:`M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333 - 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5 - 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667 --152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,leftharpoondownplus:`M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12 - 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7 --2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0 -v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,lefthook:`M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5 --83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3 --68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21 - 71.5 23h399859zM103 281v-40h399897v40z`,leftlinesegment:`M40 281 V428 H0 V94 H40 V241 H400000 v40z -M40 281 V428 H0 V94 H40 V241 H400000 v40z`,leftmapsto:`M40 281 V448H0V74H40V241H400000v40z -M40 281 V448H0V74H40V241H400000v40z`,leftToFrom:`M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23 --.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8 -c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3 - 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,longequal:`M0 50 h400000 v40H0z m0 194h40000v40H0z -M0 50 h400000 v40H0z m0 194h40000v40H0z`,midbrace:`M200428 334 -c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14 --53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7 - 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11 - 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,midbraceunder:`M199572 214 -c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14 - 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3 - 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0 --5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,oiintSize1:`M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6 --320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z -m368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8 -60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,oiintSize2:`M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8 --451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z -m502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2 -c0 110 84 276 504 276s502.4-166 502.4-276z`,oiiintSize1:`M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6 --480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z -m525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0 -85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,oiiintSize2:`M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8 --707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z -m770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1 -c0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,rightarrow:`M0 241v40h399891c-47.3 35.3-84 78-110 128 --16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 - 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 - 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85 --40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 --12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 - 151.7 139 205zm0 0v40h399900v-40z`,rightbrace:`M400000 542l --6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5 -s-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1 -c124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,rightbraceunder:`M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3 - 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237 --174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,rightgroup:`M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0 - 3-1 3-3v-38c-76-158-257-219-435-219H0z`,rightgroupunder:`M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18 - 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,rightharpoon:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3 --3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2 --10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 - 69.2 92 94.5zm0 0v40h399900v-40z`,rightharpoonplus:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11 --18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7 - 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z -m0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,rightharpoondown:`M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8 - 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5 --7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95 --27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,rightharpoondownplus:`M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8 - 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 - 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3 --64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z -m0-194v40h400000v-40zm0 0v40h400000v-40z`,righthook:`M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3 - 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0 --13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21 - 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,rightlinesegment:`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z -M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,rightToFrom:`M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23 - 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32 --52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142 --167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,twoheadleftarrow:`M0 167c68 40 - 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69 --70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3 --40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19 --37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101 - 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,twoheadrightarrow:`M400000 167 -c-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3 - 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42 - 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333 --19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70 - 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,tilde1:`M200 55.538c-77 0-168 73.953-177 73.953-3 0-7 --2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0 - 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0 - 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128 --68.267.847-113-73.952-191-73.952z`,tilde2:`M344 55.266c-142 0-300.638 81.316-311.5 86.418 --8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9 - 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114 -c1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751 - 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,tilde3:`M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457 --11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0 - 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697 - 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696 - -338 0-409-156.573-744-156.573z`,tilde4:`M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345 --11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409 - 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9 - 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409 - -175.236-744-175.236z`,vec:`M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5 -3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11 -10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63 --1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1 --7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59 -H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359 -c-16-25.333-24-45-24-59z`,widehat1:`M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22 -c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,widehat2:`M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat3:`M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat4:`M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10 --11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widecheck1:`M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1, --5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,widecheck2:`M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck3:`M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck4:`M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, --11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,baraboveleftarrow:`M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202 -c4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5 -c-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130 -s-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47 -121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6 -s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11 -c0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z -M100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,rightarrowabovebar:`M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32 --27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0 -13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39 --84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5 --119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5 --12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67 -151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,baraboveshortleftharpoon:`M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 -c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17 -c2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21 -c-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40 -c-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z -M0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,rightharpoonaboveshortbar:`M0,241 l0,40c399126,0,399993,0,399993,0 -c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, --231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 -c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z -M0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,shortbaraboveleftharpoon:`M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11 -c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9, -1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7, --152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z -M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,shortrightharpoonabovebar:`M53,241l0,40c398570,0,399437,0,399437,0 -c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, --231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 -c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z -M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},Y4e=o(function(e,r){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v1759 h347 v-84 -H403z M403 1759 V0 H319 V1759 v`+r+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v1759 H0 v84 H347z -M347 1759 V0 H263 V1759 v`+r+" v1759 h84z";case"vert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+" v585 h43z";case"doublevert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+` v585 h43z -M367 15 v585 v`+r+` v585 c2.667,10,9.667,15,21,15 -c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15 -c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+r+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+r+` v1715 h263 v84 H319z -MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+r+` v1799 H0 v-84 H319z -MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v602 h84z -M403 1759 V0 H319 V1759 v`+r+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v602 h84z -M347 1759 V0 h-84 V1759 v`+r+" v602 h84z";case"lparen":return`M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1 -c-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349, --36,557 l0,`+(r+84)+`c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210, -949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9 -c0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5, --544.7,-112.5,-882c-2,-104,-3,-167,-3,-189 -l0,-`+(r+92)+`c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3, --210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z`;case"rparen":return`M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3, -63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5 -c11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,`+(r+9)+` -c-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664 -c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11 -c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17 -c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558 -l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7, --470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}},"tallDelim"),od=class{static{o(this,"DocumentFragment")}constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return Jt.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),r=0;rr.toText(),"toText");return this.children.map(e).join("")}},Jl={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},c3={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},Kz={\u00C5:"A",\u00D0:"D",\u00DE:"o",\u00E5:"a",\u00F0:"d",\u00FE:"o",\u0410:"A",\u0411:"B",\u0412:"B",\u0413:"F",\u0414:"A",\u0415:"E",\u0416:"K",\u0417:"3",\u0418:"N",\u0419:"N",\u041A:"K",\u041B:"N",\u041C:"M",\u041D:"H",\u041E:"O",\u041F:"N",\u0420:"P",\u0421:"C",\u0422:"T",\u0423:"y",\u0424:"O",\u0425:"X",\u0426:"U",\u0427:"h",\u0428:"W",\u0429:"W",\u042A:"B",\u042B:"X",\u042C:"B",\u042D:"3",\u042E:"X",\u042F:"R",\u0430:"a",\u0431:"b",\u0432:"a",\u0433:"r",\u0434:"y",\u0435:"e",\u0436:"m",\u0437:"e",\u0438:"n",\u0439:"n",\u043A:"n",\u043B:"n",\u043C:"m",\u043D:"n",\u043E:"o",\u043F:"n",\u0440:"p",\u0441:"c",\u0442:"o",\u0443:"y",\u0444:"b",\u0445:"x",\u0446:"n",\u0447:"n",\u0448:"w",\u0449:"w",\u044A:"a",\u044B:"m",\u044C:"a",\u044D:"e",\u044E:"m",\u044F:"r"};o(_G,"setFontMetrics");o(nA,"getCharacterMetrics");R7={};o(X4e,"getGlobalMetrics");j4e=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],Qz=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],Zz=o(function(e,r){return r.size<2?e:j4e[e-1][r.size-1]},"sizeAtStyle"),w3=class t{static{o(this,"Options")}constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||t.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=Qz[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);return new t(r)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:Zz(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:Qz[e-1]})}havingBaseStyle(e){e=e||this.style.text();var r=Zz(t.BASESIZE,e);return this.size===r&&this.textSize===t.BASESIZE&&this.style===e?this:this.extend({style:e,size:r})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==t.BASESIZE?["sizing","reset-size"+this.size,"size"+t.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=X4e(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}};w3.BASESIZE=6;W7={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},K4e={ex:!0,em:!0,mu:!0},DG=o(function(e){return typeof e!="string"&&(e=e.unit),e in W7||e in K4e||e==="ex"},"validUnit"),ni=o(function(e,r){var n;if(e.unit in W7)n=W7[e.unit]/r.fontMetrics().ptPerEm/r.sizeMultiplier;else if(e.unit==="mu")n=r.fontMetrics().cssEmPerMu;else{var i;if(r.style.isTight()?i=r.havingStyle(r.style.text()):i=r,e.unit==="ex")n=i.fontMetrics().xHeight;else if(e.unit==="em")n=i.fontMetrics().quad;else throw new pt("Invalid unit: '"+e.unit+"'");i!==r&&(n*=i.sizeMultiplier/r.sizeMultiplier)}return Math.min(e.number*n,r.maxSize)},"calculateSize"),Et=o(function(e){return+e.toFixed(4)+"em"},"makeEm"),vh=o(function(e){return e.filter(r=>r).join(" ")},"createClass"),LG=o(function(e,r,n){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=n||{},r){r.style.isTight()&&this.classes.push("mtight");var i=r.getColor();i&&(this.style.color=i)}},"initNode"),RG=o(function(e){var r=document.createElement(e);r.className=vh(this.classes);for(var n in this.style)this.style.hasOwnProperty(n)&&(r.style[n]=this.style[n]);for(var i in this.attributes)this.attributes.hasOwnProperty(i)&&r.setAttribute(i,this.attributes[i]);for(var a=0;a/=\x00-\x1f]/,NG=o(function(e){var r="<"+e;this.classes.length&&(r+=' class="'+Jt.escape(vh(this.classes))+'"');var n="";for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(r+=' style="'+Jt.escape(n)+'"');for(var a in this.attributes)if(this.attributes.hasOwnProperty(a)){if(Q4e.test(a))throw new pt("Invalid attribute name '"+a+"'");r+=" "+a+'="'+Jt.escape(this.attributes[a])+'"'}r+=">";for(var s=0;s",r},"toMarkup"),ld=class{static{o(this,"Span")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,LG.call(this,e,n,i),this.children=r||[]}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return RG.call(this,"span")}toMarkup(){return NG.call(this,"span")}},Zy=class{static{o(this,"Anchor")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,LG.call(this,r,i),this.children=n||[],this.setAttribute("href",e)}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return RG.call(this,"a")}toMarkup(){return NG.call(this,"a")}},q7=class{static{o(this,"Img")}constructor(e,r,n){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=r,this.src=e,this.classes=["mord"],this.style=n}hasClass(e){return Jt.contains(this.classes,e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var r in this.style)this.style.hasOwnProperty(r)&&(e.style[r]=this.style[r]);return e}toMarkup(){var e=''+Jt.escape(this.alt)+'0&&(r=document.createElement("span"),r.style.marginRight=Et(this.italic)),this.classes.length>0&&(r=r||document.createElement("span"),r.className=vh(this.classes));for(var n in this.style)this.style.hasOwnProperty(n)&&(r=r||document.createElement("span"),r.style[n]=this.style[n]);return r?(r.appendChild(e),r):e}toMarkup(){var e=!1,r="0&&(n+="margin-right:"+this.italic+"em;");for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(e=!0,r+=' style="'+Jt.escape(n)+'"');var a=Jt.escape(this.text);return e?(r+=">",r+=a,r+="",r):a}},dl=class{static{o(this,"SvgNode")}constructor(e,r){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=r||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"svg");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);for(var i=0;i':''}},Jy=class{static{o(this,"LineNode")}constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"line");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);return r}toMarkup(){var e="","\\gt",!0);G(H,re,Ee,"\u2208","\\in",!0);G(H,re,Ee,"\uE020","\\@not");G(H,re,Ee,"\u2282","\\subset",!0);G(H,re,Ee,"\u2283","\\supset",!0);G(H,re,Ee,"\u2286","\\subseteq",!0);G(H,re,Ee,"\u2287","\\supseteq",!0);G(H,ke,Ee,"\u2288","\\nsubseteq",!0);G(H,ke,Ee,"\u2289","\\nsupseteq",!0);G(H,re,Ee,"\u22A8","\\models");G(H,re,Ee,"\u2190","\\leftarrow",!0);G(H,re,Ee,"\u2264","\\le");G(H,re,Ee,"\u2264","\\leq",!0);G(H,re,Ee,"<","\\lt",!0);G(H,re,Ee,"\u2192","\\rightarrow",!0);G(H,re,Ee,"\u2192","\\to");G(H,ke,Ee,"\u2271","\\ngeq",!0);G(H,ke,Ee,"\u2270","\\nleq",!0);G(H,re,pu,"\xA0","\\ ");G(H,re,pu,"\xA0","\\space");G(H,re,pu,"\xA0","\\nobreakspace");G(it,re,pu,"\xA0","\\ ");G(it,re,pu,"\xA0"," ");G(it,re,pu,"\xA0","\\space");G(it,re,pu,"\xA0","\\nobreakspace");G(H,re,pu,null,"\\nobreak");G(H,re,pu,null,"\\allowbreak");G(H,re,D3,",",",");G(H,re,D3,";",";");G(H,ke,It,"\u22BC","\\barwedge",!0);G(H,ke,It,"\u22BB","\\veebar",!0);G(H,re,It,"\u2299","\\odot",!0);G(H,re,It,"\u2295","\\oplus",!0);G(H,re,It,"\u2297","\\otimes",!0);G(H,re,Re,"\u2202","\\partial",!0);G(H,re,It,"\u2298","\\oslash",!0);G(H,ke,It,"\u229A","\\circledcirc",!0);G(H,ke,It,"\u22A1","\\boxdot",!0);G(H,re,It,"\u25B3","\\bigtriangleup");G(H,re,It,"\u25BD","\\bigtriangledown");G(H,re,It,"\u2020","\\dagger");G(H,re,It,"\u22C4","\\diamond");G(H,re,It,"\u22C6","\\star");G(H,re,It,"\u25C3","\\triangleleft");G(H,re,It,"\u25B9","\\triangleright");G(H,re,Zs,"{","\\{");G(it,re,Re,"{","\\{");G(it,re,Re,"{","\\textbraceleft");G(H,re,ns,"}","\\}");G(it,re,Re,"}","\\}");G(it,re,Re,"}","\\textbraceright");G(H,re,Zs,"{","\\lbrace");G(H,re,ns,"}","\\rbrace");G(H,re,Zs,"[","\\lbrack",!0);G(it,re,Re,"[","\\lbrack",!0);G(H,re,ns,"]","\\rbrack",!0);G(it,re,Re,"]","\\rbrack",!0);G(H,re,Zs,"(","\\lparen",!0);G(H,re,ns,")","\\rparen",!0);G(it,re,Re,"<","\\textless",!0);G(it,re,Re,">","\\textgreater",!0);G(H,re,Zs,"\u230A","\\lfloor",!0);G(H,re,ns,"\u230B","\\rfloor",!0);G(H,re,Zs,"\u2308","\\lceil",!0);G(H,re,ns,"\u2309","\\rceil",!0);G(H,re,Re,"\\","\\backslash");G(H,re,Re,"\u2223","|");G(H,re,Re,"\u2223","\\vert");G(it,re,Re,"|","\\textbar",!0);G(H,re,Re,"\u2225","\\|");G(H,re,Re,"\u2225","\\Vert");G(it,re,Re,"\u2225","\\textbardbl");G(it,re,Re,"~","\\textasciitilde");G(it,re,Re,"\\","\\textbackslash");G(it,re,Re,"^","\\textasciicircum");G(H,re,Ee,"\u2191","\\uparrow",!0);G(H,re,Ee,"\u21D1","\\Uparrow",!0);G(H,re,Ee,"\u2193","\\downarrow",!0);G(H,re,Ee,"\u21D3","\\Downarrow",!0);G(H,re,Ee,"\u2195","\\updownarrow",!0);G(H,re,Ee,"\u21D5","\\Updownarrow",!0);G(H,re,Ci,"\u2210","\\coprod");G(H,re,Ci,"\u22C1","\\bigvee");G(H,re,Ci,"\u22C0","\\bigwedge");G(H,re,Ci,"\u2A04","\\biguplus");G(H,re,Ci,"\u22C2","\\bigcap");G(H,re,Ci,"\u22C3","\\bigcup");G(H,re,Ci,"\u222B","\\int");G(H,re,Ci,"\u222B","\\intop");G(H,re,Ci,"\u222C","\\iint");G(H,re,Ci,"\u222D","\\iiint");G(H,re,Ci,"\u220F","\\prod");G(H,re,Ci,"\u2211","\\sum");G(H,re,Ci,"\u2A02","\\bigotimes");G(H,re,Ci,"\u2A01","\\bigoplus");G(H,re,Ci,"\u2A00","\\bigodot");G(H,re,Ci,"\u222E","\\oint");G(H,re,Ci,"\u222F","\\oiint");G(H,re,Ci,"\u2230","\\oiiint");G(H,re,Ci,"\u2A06","\\bigsqcup");G(H,re,Ci,"\u222B","\\smallint");G(it,re,E0,"\u2026","\\textellipsis");G(H,re,E0,"\u2026","\\mathellipsis");G(it,re,E0,"\u2026","\\ldots",!0);G(H,re,E0,"\u2026","\\ldots",!0);G(H,re,E0,"\u22EF","\\@cdots",!0);G(H,re,E0,"\u22F1","\\ddots",!0);G(H,re,Re,"\u22EE","\\varvdots");G(it,re,Re,"\u22EE","\\varvdots");G(H,re,Hn,"\u02CA","\\acute");G(H,re,Hn,"\u02CB","\\grave");G(H,re,Hn,"\xA8","\\ddot");G(H,re,Hn,"~","\\tilde");G(H,re,Hn,"\u02C9","\\bar");G(H,re,Hn,"\u02D8","\\breve");G(H,re,Hn,"\u02C7","\\check");G(H,re,Hn,"^","\\hat");G(H,re,Hn,"\u20D7","\\vec");G(H,re,Hn,"\u02D9","\\dot");G(H,re,Hn,"\u02DA","\\mathring");G(H,re,rr,"\uE131","\\@imath");G(H,re,rr,"\uE237","\\@jmath");G(H,re,Re,"\u0131","\u0131");G(H,re,Re,"\u0237","\u0237");G(it,re,Re,"\u0131","\\i",!0);G(it,re,Re,"\u0237","\\j",!0);G(it,re,Re,"\xDF","\\ss",!0);G(it,re,Re,"\xE6","\\ae",!0);G(it,re,Re,"\u0153","\\oe",!0);G(it,re,Re,"\xF8","\\o",!0);G(it,re,Re,"\xC6","\\AE",!0);G(it,re,Re,"\u0152","\\OE",!0);G(it,re,Re,"\xD8","\\O",!0);G(it,re,Hn,"\u02CA","\\'");G(it,re,Hn,"\u02CB","\\`");G(it,re,Hn,"\u02C6","\\^");G(it,re,Hn,"\u02DC","\\~");G(it,re,Hn,"\u02C9","\\=");G(it,re,Hn,"\u02D8","\\u");G(it,re,Hn,"\u02D9","\\.");G(it,re,Hn,"\xB8","\\c");G(it,re,Hn,"\u02DA","\\r");G(it,re,Hn,"\u02C7","\\v");G(it,re,Hn,"\xA8",'\\"');G(it,re,Hn,"\u02DD","\\H");G(it,re,Hn,"\u25EF","\\textcircled");MG={"--":!0,"---":!0,"``":!0,"''":!0};G(it,re,Re,"\u2013","--",!0);G(it,re,Re,"\u2013","\\textendash");G(it,re,Re,"\u2014","---",!0);G(it,re,Re,"\u2014","\\textemdash");G(it,re,Re,"\u2018","`",!0);G(it,re,Re,"\u2018","\\textquoteleft");G(it,re,Re,"\u2019","'",!0);G(it,re,Re,"\u2019","\\textquoteright");G(it,re,Re,"\u201C","``",!0);G(it,re,Re,"\u201C","\\textquotedblleft");G(it,re,Re,"\u201D","''",!0);G(it,re,Re,"\u201D","\\textquotedblright");G(H,re,Re,"\xB0","\\degree",!0);G(it,re,Re,"\xB0","\\degree");G(it,re,Re,"\xB0","\\textdegree",!0);G(H,re,Re,"\xA3","\\pounds");G(H,re,Re,"\xA3","\\mathsterling",!0);G(it,re,Re,"\xA3","\\pounds");G(it,re,Re,"\xA3","\\textsterling",!0);G(H,ke,Re,"\u2720","\\maltese");G(it,ke,Re,"\u2720","\\maltese");eG='0123456789/@."';for(u3=0;u30)return fl(a,h,i,r,s.concat(f));if(u){var d,p;if(u==="boldsymbol"){var m=i3e(a,i,r,s,n);d=m.fontName,p=[m.fontClass]}else l?(d=PG[u].fontName,p=[u]):(d=m3(u,r.fontWeight,r.fontShape),p=[u,r.fontWeight,r.fontShape]);if(L3(a,d,i).metrics)return fl(a,d,i,r,s.concat(p));if(MG.hasOwnProperty(a)&&d.slice(0,10)==="Typewriter"){for(var g=[],y=0;y{if(vh(t.classes)!==vh(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;if(t.classes.length===1){var r=t.classes[0];if(r==="mbin"||r==="mord")return!1}for(var n in t.style)if(t.style.hasOwnProperty(n)&&t.style[n]!==e.style[n])return!1;for(var i in e.style)if(e.style.hasOwnProperty(i)&&t.style[i]!==e.style[i])return!1;return!0},"canCombine"),o3e=o(t=>{for(var e=0;er&&(r=s.height),s.depth>n&&(n=s.depth),s.maxFontSize>i&&(i=s.maxFontSize)}e.height=r,e.depth=n,e.maxFontSize=i},"sizeElementFromChildren"),Cs=o(function(e,r,n,i){var a=new ld(e,r,n,i);return iA(a),a},"makeSpan"),IG=o((t,e,r,n)=>new ld(t,e,r,n),"makeSvgSpan"),l3e=o(function(e,r,n){var i=Cs([e],[],r);return i.height=Math.max(n||r.fontMetrics().defaultRuleThickness,r.minRuleThickness),i.style.borderBottomWidth=Et(i.height),i.maxFontSize=1,i},"makeLineSpan"),c3e=o(function(e,r,n,i){var a=new Zy(e,r,n,i);return iA(a),a},"makeAnchor"),OG=o(function(e){var r=new od(e);return iA(r),r},"makeFragment"),u3e=o(function(e,r){return e instanceof od?Cs([],[e],r):e},"wrapFragment"),h3e=o(function(e){if(e.positionType==="individualShift"){for(var r=e.children,n=[r[0]],i=-r[0].shift-r[0].elem.depth,a=i,s=1;s{var r=Cs(["mspace"],[],e),n=ni(t,e);return r.style.marginRight=Et(n),r},"makeGlue"),m3=o(function(e,r,n){var i="";switch(e){case"amsrm":i="AMS";break;case"textrm":i="Main";break;case"textsf":i="SansSerif";break;case"texttt":i="Typewriter";break;default:i=e}var a;return r==="textbf"&&n==="textit"?a="BoldItalic":r==="textbf"?a="Bold":r==="textit"?a="Italic":a="Regular",i+"-"+a},"retrieveTextFontName"),PG={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},BG={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},p3e=o(function(e,r){var[n,i,a]=BG[e],s=new ec(n),l=new dl([s],{width:Et(i),height:Et(a),style:"width:"+Et(i),viewBox:"0 0 "+1e3*i+" "+1e3*a,preserveAspectRatio:"xMinYMin"}),u=IG(["overlay"],[l],r);return u.height=a,u.style.height=Et(a),u.style.width=Et(i),u},"staticSvg"),Fe={fontMap:PG,makeSymbol:fl,mathsym:n3e,makeSpan:Cs,makeSvgSpan:IG,makeLineSpan:l3e,makeAnchor:c3e,makeFragment:OG,wrapFragment:u3e,makeVList:f3e,makeOrd:a3e,makeGlue:d3e,staticSvg:p3e,svgData:BG,tryCombineChars:o3e},ri={number:3,unit:"mu"},sd={number:4,unit:"mu"},cu={number:5,unit:"mu"},m3e={mord:{mop:ri,mbin:sd,mrel:cu,minner:ri},mop:{mord:ri,mop:ri,mrel:cu,minner:ri},mbin:{mord:sd,mop:sd,mopen:sd,minner:sd},mrel:{mord:cu,mop:cu,mopen:cu,minner:cu},mopen:{},mclose:{mop:ri,mbin:sd,mrel:cu,minner:ri},mpunct:{mord:ri,mop:ri,mrel:cu,mopen:ri,mclose:ri,mpunct:ri,minner:ri},minner:{mord:ri,mop:ri,mbin:sd,mrel:cu,mopen:ri,mpunct:ri,minner:ri}},g3e={mord:{mop:ri},mop:{mord:ri,mop:ri},mbin:{},mrel:{},mopen:{},mclose:{mop:ri},mpunct:{},minner:{mop:ri}},FG={},E3={},S3={};o(Nt,"defineFunction");o(cd,"defineFunctionBuilders");C3=o(function(e){return e.type==="ordgroup"&&e.body.length===1?e.body[0]:e},"normalizeArgument"),gi=o(function(e){return e.type==="ordgroup"?e.body:[e]},"ordargument"),fu=Fe.makeSpan,y3e=["leftmost","mbin","mopen","mrel","mop","mpunct"],v3e=["rightmost","mrel","mclose","mpunct"],x3e={display:nr.DISPLAY,text:nr.TEXT,script:nr.SCRIPT,scriptscript:nr.SCRIPTSCRIPT},b3e={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},$i=o(function(e,r,n,i){i===void 0&&(i=[null,null]);for(var a=[],s=0;s{var v=y.classes[0],x=g.classes[0];v==="mbin"&&Jt.contains(v3e,x)?y.classes[0]="mord":x==="mbin"&&Jt.contains(y3e,v)&&(g.classes[0]="mord")},{node:d},p,m),nG(a,(g,y)=>{var v=X7(y),x=X7(g),b=v&&x?g.hasClass("mtight")?g3e[v][x]:m3e[v][x]:null;if(b)return Fe.makeGlue(b,h)},{node:d},p,m),a},"buildExpression"),nG=o(function t(e,r,n,i,a){i&&e.push(i);for(var s=0;sp=>{e.splice(d+1,0,p),s++})(s)}i&&e.pop()},"traverseNonSpaceNodes"),$G=o(function(e){return e instanceof od||e instanceof Zy||e instanceof ld&&e.hasClass("enclosing")?e:null},"checkPartialGroup"),T3e=o(function t(e,r){var n=$G(e);if(n){var i=n.children;if(i.length){if(r==="right")return t(i[i.length-1],"right");if(r==="left")return t(i[0],"left")}}return e},"getOutermostNode"),X7=o(function(e,r){return e?(r&&(e=T3e(e,r)),b3e[e.classes[0]]||null):null},"getTypeOfDomTree"),ev=o(function(e,r){var n=["nulldelimiter"].concat(e.baseSizingClasses());return fu(r.concat(n))},"makeNullDelimiter"),$r=o(function(e,r,n){if(!e)return fu();if(E3[e.type]){var i=E3[e.type](e,r);if(n&&r.size!==n.size){i=fu(r.sizingClasses(n),[i],r);var a=r.sizeMultiplier/n.sizeMultiplier;i.height*=a,i.depth*=a}return i}else throw new pt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(g3,"buildHTMLUnbreakable");o(j7,"buildHTML");o(zG,"newDocumentFragment");ts=class{static{o(this,"MathNode")}constructor(e,r,n){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=r||[],this.classes=n||[]}setAttribute(e,r){this.attributes[e]=r}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&e.setAttribute(r,this.attributes[r]);this.classes.length>0&&(e.className=vh(this.classes));for(var n=0;n0&&(e+=' class ="'+Jt.escape(vh(this.classes))+'"'),e+=">";for(var n=0;n",e}toText(){return this.children.map(e=>e.toText()).join("")}},Ao=class{static{o(this,"TextNode")}constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return Jt.escape(this.toText())}toText(){return this.text}},K7=class{static{o(this,"SpaceNode")}constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character="\u200A":e>=.1666&&e<=.1667?this.character="\u2009":e>=.2222&&e<=.2223?this.character="\u2005":e>=.2777&&e<=.2778?this.character="\u2005\u200A":e>=-.05556&&e<=-.05555?this.character="\u200A\u2063":e>=-.1667&&e<=-.1666?this.character="\u2009\u2063":e>=-.2223&&e<=-.2222?this.character="\u205F\u2063":e>=-.2778&&e<=-.2777?this.character="\u2005\u2063":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",Et(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},dt={MathNode:ts,TextNode:Ao,SpaceNode:K7,newDocumentFragment:zG},Do=o(function(e,r,n){return An[r][e]&&An[r][e].replace&&e.charCodeAt(0)!==55349&&!(MG.hasOwnProperty(e)&&n&&(n.fontFamily&&n.fontFamily.slice(4,6)==="tt"||n.font&&n.font.slice(4,6)==="tt"))&&(e=An[r][e].replace),new dt.TextNode(e)},"makeText"),aA=o(function(e){return e.length===1?e[0]:new dt.MathNode("mrow",e)},"makeRow"),sA=o(function(e,r){if(r.fontFamily==="texttt")return"monospace";if(r.fontFamily==="textsf")return r.fontShape==="textit"&&r.fontWeight==="textbf"?"sans-serif-bold-italic":r.fontShape==="textit"?"sans-serif-italic":r.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(r.fontShape==="textit"&&r.fontWeight==="textbf")return"bold-italic";if(r.fontShape==="textit")return"italic";if(r.fontWeight==="textbf")return"bold";var n=r.font;if(!n||n==="mathnormal")return null;var i=e.mode;if(n==="mathit")return"italic";if(n==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(n==="mathbf")return"bold";if(n==="mathbb")return"double-struck";if(n==="mathsfit")return"sans-serif-italic";if(n==="mathfrak")return"fraktur";if(n==="mathscr"||n==="mathcal")return"script";if(n==="mathsf")return"sans-serif";if(n==="mathtt")return"monospace";var a=e.text;if(Jt.contains(["\\imath","\\jmath"],a))return null;An[i][a]&&An[i][a].replace&&(a=An[i][a].replace);var s=Fe.fontMap[n].fontName;return nA(a,s,i)?Fe.fontMap[n].variant:null},"getVariant");o(I7,"isNumberPunctuation");_s=o(function(e,r,n){if(e.length===1){var i=vn(e[0],r);return n&&i instanceof ts&&i.type==="mo"&&(i.setAttribute("lspace","0em"),i.setAttribute("rspace","0em")),[i]}for(var a=[],s,l=0;l=1&&(s.type==="mn"||I7(s))){var h=u.children[0];h instanceof ts&&h.type==="mn"&&(h.children=[...s.children,...h.children],a.pop())}else if(s.type==="mi"&&s.children.length===1){var f=s.children[0];if(f instanceof Ao&&f.text==="\u0338"&&(u.type==="mo"||u.type==="mi"||u.type==="mn")){var d=u.children[0];d instanceof Ao&&d.text.length>0&&(d.text=d.text.slice(0,1)+"\u0338"+d.text.slice(1),a.pop())}}}a.push(u),s=u}return a},"buildExpression"),xh=o(function(e,r,n){return aA(_s(e,r,n))},"buildExpressionRow"),vn=o(function(e,r){if(!e)return new dt.MathNode("mrow");if(S3[e.type]){var n=S3[e.type](e,r);return n}else throw new pt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(iG,"buildMathML");GG=o(function(e){return new w3({style:e.displayMode?nr.DISPLAY:nr.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},"optionsFromSettings"),VG=o(function(e,r){if(r.displayMode){var n=["katex-display"];r.leqno&&n.push("leqno"),r.fleqn&&n.push("fleqn"),e=Fe.makeSpan(n,[e])}return e},"displayWrap"),w3e=o(function(e,r,n){var i=GG(n),a;if(n.output==="mathml")return iG(e,r,i,n.displayMode,!0);if(n.output==="html"){var s=j7(e,i);a=Fe.makeSpan(["katex"],[s])}else{var l=iG(e,r,i,n.displayMode,!1),u=j7(e,i);a=Fe.makeSpan(["katex"],[l,u])}return VG(a,n)},"buildTree"),k3e=o(function(e,r,n){var i=GG(n),a=j7(e,i),s=Fe.makeSpan(["katex"],[a]);return VG(s,n)},"buildHTMLTree"),E3e={widehat:"^",widecheck:"\u02C7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23DF",overbrace:"\u23DE",overgroup:"\u23E0",undergroup:"\u23E1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21D2",xRightarrow:"\u21D2",overleftharpoon:"\u21BC",xleftharpoonup:"\u21BC",overrightharpoon:"\u21C0",xrightharpoonup:"\u21C0",xLeftarrow:"\u21D0",xLeftrightarrow:"\u21D4",xhookleftarrow:"\u21A9",xhookrightarrow:"\u21AA",xmapsto:"\u21A6",xrightharpoondown:"\u21C1",xleftharpoondown:"\u21BD",xrightleftharpoons:"\u21CC",xleftrightharpoons:"\u21CB",xtwoheadleftarrow:"\u219E",xtwoheadrightarrow:"\u21A0",xlongequal:"=",xtofrom:"\u21C4",xrightleftarrows:"\u21C4",xrightequilibrium:"\u21CC",xleftequilibrium:"\u21CB","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},S3e=o(function(e){var r=new dt.MathNode("mo",[new dt.TextNode(E3e[e.replace(/^\\/,"")])]);return r.setAttribute("stretchy","true"),r},"mathMLnode"),C3e={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},A3e=o(function(e){return e.type==="ordgroup"?e.body.length:1},"groupLength"),_3e=o(function(e,r){function n(){var l=4e5,u=e.label.slice(1);if(Jt.contains(["widehat","widecheck","widetilde","utilde"],u)){var h=e,f=A3e(h.base),d,p,m;if(f>5)u==="widehat"||u==="widecheck"?(d=420,l=2364,m=.42,p=u+"4"):(d=312,l=2340,m=.34,p="tilde4");else{var g=[1,1,2,2,3,3][f];u==="widehat"||u==="widecheck"?(l=[0,1062,2364,2364,2364][g],d=[0,239,300,360,420][g],m=[0,.24,.3,.3,.36,.42][g],p=u+g):(l=[0,600,1033,2339,2340][g],d=[0,260,286,306,312][g],m=[0,.26,.286,.3,.306,.34][g],p="tilde"+g)}var y=new ec(p),v=new dl([y],{width:"100%",height:Et(m),viewBox:"0 0 "+l+" "+d,preserveAspectRatio:"none"});return{span:Fe.makeSvgSpan([],[v],r),minWidth:0,height:m}}else{var x=[],b=C3e[u],[T,S,w]=b,E=w/1e3,_=T.length,C,D;if(_===1){var O=b[3];C=["hide-tail"],D=[O]}else if(_===2)C=["halfarrow-left","halfarrow-right"],D=["xMinYMin","xMaxYMin"];else if(_===3)C=["brace-left","brace-center","brace-right"],D=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support - `+_+" children.");for(var R=0;R<_;R++){var k=new ec(T[R]),L=new dl([k],{width:"400em",height:Et(E),viewBox:"0 0 "+l+" "+w,preserveAspectRatio:D[R]+" slice"}),A=Fe.makeSvgSpan([C[R]],[L],r);if(_===1)return{span:A,minWidth:S,height:E};A.style.height=Et(E),x.push(A)}return{span:Fe.makeSpan(["stretchy"],x,r),minWidth:S,height:E}}}o(n,"buildSvgSpan_");var{span:i,minWidth:a,height:s}=n();return i.height=s,i.style.height=Et(s),a>0&&(i.style.minWidth=Et(a)),i},"svgSpan"),D3e=o(function(e,r,n,i,a){var s,l=e.height+e.depth+n+i;if(/fbox|color|angl/.test(r)){if(s=Fe.makeSpan(["stretchy",r],[],a),r==="fbox"){var u=a.color&&a.getColor();u&&(s.style.borderColor=u)}}else{var h=[];/^[bx]cancel$/.test(r)&&h.push(new Jy({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(r)&&h.push(new Jy({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var f=new dl(h,{width:"100%",height:Et(l)});s=Fe.makeSvgSpan([],[f],a)}return s.height=l,s.style.height=Et(l),s},"encloseSpan"),du={encloseSpan:D3e,mathMLnode:S3e,svgSpan:_3e};o(xr,"assertNodeType");o(oA,"assertSymbolNodeType");o(R3,"checkSymbolNodeType");lA=o((t,e)=>{var r,n,i;t&&t.type==="supsub"?(n=xr(t.base,"accent"),r=n.base,t.base=r,i=J4e($r(t,e)),t.base=n):(n=xr(t,"accent"),r=n.base);var a=$r(r,e.havingCrampedStyle()),s=n.isShifty&&Jt.isCharacterBox(r),l=0;if(s){var u=Jt.getBaseElem(r),h=$r(u,e.havingCrampedStyle());l=Jz(h).skew}var f=n.label==="\\c",d=f?a.height+a.depth:Math.min(a.height,e.fontMetrics().xHeight),p;if(n.isStretchy)p=du.svgSpan(n,e),p=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"elem",elem:p,wrapperClasses:["svg-align"],wrapperStyle:l>0?{width:"calc(100% - "+Et(2*l)+")",marginLeft:Et(2*l)}:void 0}]},e);else{var m,g;n.label==="\\vec"?(m=Fe.staticSvg("vec",e),g=Fe.svgData.vec[1]):(m=Fe.makeOrd({mode:n.mode,text:n.label},e,"textord"),m=Jz(m),m.italic=0,g=m.width,f&&(d+=m.depth)),p=Fe.makeSpan(["accent-body"],[m]);var y=n.label==="\\textcircled";y&&(p.classes.push("accent-full"),d=a.height);var v=l;y||(v-=g/2),p.style.left=Et(v),n.label==="\\textcircled"&&(p.style.top=".2em"),p=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:-d},{type:"elem",elem:p}]},e)}var x=Fe.makeSpan(["mord","accent"],[p],e);return i?(i.children[0]=x,i.height=Math.max(x.height,i.height),i.classes[0]="mord",i):x},"htmlBuilder$a"),UG=o((t,e)=>{var r=t.isStretchy?du.mathMLnode(t.label):new dt.MathNode("mo",[Do(t.label,t.mode)]),n=new dt.MathNode("mover",[vn(t.base,e),r]);return n.setAttribute("accent","true"),n},"mathmlBuilder$9"),L3e=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(t=>"\\"+t).join("|"));Nt({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:o((t,e)=>{var r=C3(e[0]),n=!L3e.test(t.funcName),i=!n||t.funcName==="\\widehat"||t.funcName==="\\widetilde"||t.funcName==="\\widecheck";return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:n,isShifty:i,base:r}},"handler"),htmlBuilder:lA,mathmlBuilder:UG});Nt({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:o((t,e)=>{var r=e[0],n=t.parser.mode;return n==="math"&&(t.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+t.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:t.funcName,isStretchy:!1,isShifty:!0,base:r}},"handler"),htmlBuilder:lA,mathmlBuilder:UG});Nt({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"accentUnder",mode:r.mode,label:n,base:i}},"handler"),htmlBuilder:o((t,e)=>{var r=$r(t.base,e),n=du.svgSpan(t,e),i=t.label==="\\utilde"?.12:0,a=Fe.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:i},{type:"elem",elem:r}]},e);return Fe.makeSpan(["mord","accentunder"],[a],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=du.mathMLnode(t.label),n=new dt.MathNode("munder",[vn(t.base,e),r]);return n.setAttribute("accentunder","true"),n},"mathmlBuilder")});y3=o(t=>{var e=new dt.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e},"paddedNode");Nt({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n,funcName:i}=t;return{type:"xArrow",mode:n.mode,label:i,body:e[0],below:r[0]}},htmlBuilder(t,e){var r=e.style,n=e.havingStyle(r.sup()),i=Fe.wrapFragment($r(t.body,n,e),e),a=t.label.slice(0,2)==="\\x"?"x":"cd";i.classes.push(a+"-arrow-pad");var s;t.below&&(n=e.havingStyle(r.sub()),s=Fe.wrapFragment($r(t.below,n,e),e),s.classes.push(a+"-arrow-pad"));var l=du.svgSpan(t,e),u=-e.fontMetrics().axisHeight+.5*l.height,h=-e.fontMetrics().axisHeight-.5*l.height-.111;(i.depth>.25||t.label==="\\xleftequilibrium")&&(h-=i.depth);var f;if(s){var d=-e.fontMetrics().axisHeight+s.height+.5*l.height+.111;f=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u},{type:"elem",elem:s,shift:d}]},e)}else f=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u}]},e);return f.children[0].children[0].children[1].classes.push("svg-align"),Fe.makeSpan(["mrel","x-arrow"],[f],e)},mathmlBuilder(t,e){var r=du.mathMLnode(t.label);r.setAttribute("minsize",t.label.charAt(0)==="x"?"1.75em":"3.0em");var n;if(t.body){var i=y3(vn(t.body,e));if(t.below){var a=y3(vn(t.below,e));n=new dt.MathNode("munderover",[r,a,i])}else n=new dt.MathNode("mover",[r,i])}else if(t.below){var s=y3(vn(t.below,e));n=new dt.MathNode("munder",[r,s])}else n=y3(),n=new dt.MathNode("mover",[r,n]);return n}});R3e=Fe.makeSpan;o(HG,"htmlBuilder$9");o(WG,"mathmlBuilder$8");Nt({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:gi(i),isCharacterBox:Jt.isCharacterBox(i)}},htmlBuilder:HG,mathmlBuilder:WG});N3=o(t=>{var e=t.type==="ordgroup"&&t.body.length?t.body[0]:t;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"},"binrelClass");Nt({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(t,e){var{parser:r}=t;return{type:"mclass",mode:r.mode,mclass:N3(e[0]),body:gi(e[1]),isCharacterBox:Jt.isCharacterBox(e[1])}}});Nt({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(t,e){var{parser:r,funcName:n}=t,i=e[1],a=e[0],s;n!=="\\stackrel"?s=N3(i):s="mrel";var l={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:n!=="\\stackrel",body:gi(i)},u={type:"supsub",mode:a.mode,base:l,sup:n==="\\underset"?null:a,sub:n==="\\underset"?a:null};return{type:"mclass",mode:r.mode,mclass:s,body:[u],isCharacterBox:Jt.isCharacterBox(u)}},htmlBuilder:HG,mathmlBuilder:WG});Nt({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"pmb",mode:r.mode,mclass:N3(e[0]),body:gi(e[0])}},htmlBuilder(t,e){var r=$i(t.body,e,!0),n=Fe.makeSpan([t.mclass],r,e);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(t,e){var r=_s(t.body,e),n=new dt.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});N3e={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},aG=o(()=>({type:"styling",body:[],mode:"math",style:"display"}),"newCell"),sG=o(t=>t.type==="textord"&&t.text==="@","isStartOfArrow"),M3e=o((t,e)=>(t.type==="mathord"||t.type==="atom")&&t.text===e,"isLabelEnd");o(I3e,"cdArrow");o(O3e,"parseCD");Nt({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:e[0]}},htmlBuilder(t,e){var r=e.havingStyle(e.style.sup()),n=Fe.wrapFragment($r(t.label,r,e),e);return n.classes.push("cd-label-"+t.side),n.style.bottom=Et(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(t,e){var r=new dt.MathNode("mrow",[vn(t.label,e)]);return r=new dt.MathNode("mpadded",[r]),r.setAttribute("width","0"),t.side==="left"&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new dt.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}});Nt({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(t,e){var{parser:r}=t;return{type:"cdlabelparent",mode:r.mode,fragment:e[0]}},htmlBuilder(t,e){var r=Fe.wrapFragment($r(t.fragment,e),e);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(t,e){return new dt.MathNode("mrow",[vn(t.fragment,e)])}});Nt({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(t,e){for(var{parser:r}=t,n=xr(e[0],"ordgroup"),i=n.body,a="",s=0;s=1114111)throw new pt("\\@char with invalid code point "+a);return u<=65535?h=String.fromCharCode(u):(u-=65536,h=String.fromCharCode((u>>10)+55296,(u&1023)+56320)),{type:"textord",mode:r.mode,text:h}}});qG=o((t,e)=>{var r=$i(t.body,e.withColor(t.color),!1);return Fe.makeFragment(r)},"htmlBuilder$8"),YG=o((t,e)=>{var r=_s(t.body,e.withColor(t.color)),n=new dt.MathNode("mstyle",r);return n.setAttribute("mathcolor",t.color),n},"mathmlBuilder$7");Nt({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(t,e){var{parser:r}=t,n=xr(e[0],"color-token").color,i=e[1];return{type:"color",mode:r.mode,color:n,body:gi(i)}},htmlBuilder:qG,mathmlBuilder:YG});Nt({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(t,e){var{parser:r,breakOnTokenText:n}=t,i=xr(e[0],"color-token").color;r.gullet.macros.set("\\current@color",i);var a=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:i,body:a}},htmlBuilder:qG,mathmlBuilder:YG});Nt({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(t,e,r){var{parser:n}=t,i=n.gullet.future().text==="["?n.parseSizeGroup(!0):null,a=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:a,size:i&&xr(i,"size").value}},htmlBuilder(t,e){var r=Fe.makeSpan(["mspace"],[],e);return t.newLine&&(r.classes.push("newline"),t.size&&(r.style.marginTop=Et(ni(t.size,e)))),r},mathmlBuilder(t,e){var r=new dt.MathNode("mspace");return t.newLine&&(r.setAttribute("linebreak","newline"),t.size&&r.setAttribute("height",Et(ni(t.size,e)))),r}});Q7={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},XG=o(t=>{var e=t.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new pt("Expected a control sequence",t);return e},"checkControlSequence"),P3e=o(t=>{var e=t.gullet.popToken();return e.text==="="&&(e=t.gullet.popToken(),e.text===" "&&(e=t.gullet.popToken())),e},"getRHS"),jG=o((t,e,r,n)=>{var i=t.gullet.macros.get(r.text);i==null&&(r.noexpand=!0,i={tokens:[r],numArgs:0,unexpandable:!t.gullet.isExpandable(r.text)}),t.gullet.macros.set(e,i,n)},"letCommand");Nt({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(t){var{parser:e,funcName:r}=t;e.consumeSpaces();var n=e.fetch();if(Q7[n.text])return(r==="\\global"||r==="\\\\globallong")&&(n.text=Q7[n.text]),xr(e.parseFunction(),"internal");throw new pt("Invalid token after macro prefix",n)}});Nt({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=e.gullet.popToken(),i=n.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new pt("Expected a control sequence",n);for(var a=0,s,l=[[]];e.gullet.future().text!=="{";)if(n=e.gullet.popToken(),n.text==="#"){if(e.gullet.future().text==="{"){s=e.gullet.future(),l[a].push("{");break}if(n=e.gullet.popToken(),!/^[1-9]$/.test(n.text))throw new pt('Invalid argument number "'+n.text+'"');if(parseInt(n.text)!==a+1)throw new pt('Argument number "'+n.text+'" out of order');a++,l.push([])}else{if(n.text==="EOF")throw new pt("Expected a macro definition");l[a].push(n.text)}var{tokens:u}=e.gullet.consumeArg();return s&&u.unshift(s),(r==="\\edef"||r==="\\xdef")&&(u=e.gullet.expandTokens(u),u.reverse()),e.gullet.macros.set(i,{tokens:u,numArgs:a,delimiters:l},r===Q7[r]),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=XG(e.gullet.popToken());e.gullet.consumeSpaces();var i=P3e(e);return jG(e,n,i,r==="\\\\globallet"),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=XG(e.gullet.popToken()),i=e.gullet.popToken(),a=e.gullet.popToken();return jG(e,n,a,r==="\\\\globalfuture"),e.gullet.pushToken(a),e.gullet.pushToken(i),{type:"internal",mode:e.mode}}});Yy=o(function(e,r,n){var i=An.math[e]&&An.math[e].replace,a=nA(i||e,r,n);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+r+".");return a},"getMetrics"),cA=o(function(e,r,n,i){var a=n.havingBaseStyle(r),s=Fe.makeSpan(i.concat(a.sizingClasses(n)),[e],n),l=a.sizeMultiplier/n.sizeMultiplier;return s.height*=l,s.depth*=l,s.maxFontSize=a.sizeMultiplier,s},"styleWrap"),KG=o(function(e,r,n){var i=r.havingBaseStyle(n),a=(1-r.sizeMultiplier/i.sizeMultiplier)*r.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=Et(a),e.height-=a,e.depth+=a},"centerSpan"),B3e=o(function(e,r,n,i,a,s){var l=Fe.makeSymbol(e,"Main-Regular",a,i),u=cA(l,r,i,s);return n&&KG(u,i,r),u},"makeSmallDelim"),F3e=o(function(e,r,n,i){return Fe.makeSymbol(e,"Size"+r+"-Regular",n,i)},"mathrmSize"),QG=o(function(e,r,n,i,a,s){var l=F3e(e,r,a,i),u=cA(Fe.makeSpan(["delimsizing","size"+r],[l],i),nr.TEXT,i,s);return n&&KG(u,i,nr.TEXT),u},"makeLargeDelim"),O7=o(function(e,r,n){var i;r==="Size1-Regular"?i="delim-size1":i="delim-size4";var a=Fe.makeSpan(["delimsizinginner",i],[Fe.makeSpan([],[Fe.makeSymbol(e,r,n)])]);return{type:"elem",elem:a}},"makeGlyphSpan"),P7=o(function(e,r,n){var i=Jl["Size4-Regular"][e.charCodeAt(0)]?Jl["Size4-Regular"][e.charCodeAt(0)][4]:Jl["Size1-Regular"][e.charCodeAt(0)][4],a=new ec("inner",q4e(e,Math.round(1e3*r))),s=new dl([a],{width:Et(i),height:Et(r),style:"width:"+Et(i),viewBox:"0 0 "+1e3*i+" "+Math.round(1e3*r),preserveAspectRatio:"xMinYMin"}),l=Fe.makeSvgSpan([],[s],n);return l.height=r,l.style.height=Et(r),l.style.width=Et(i),{type:"elem",elem:l}},"makeInner"),Z7=.008,v3={type:"kern",size:-1*Z7},$3e=["|","\\lvert","\\rvert","\\vert"],z3e=["\\|","\\lVert","\\rVert","\\Vert"],ZG=o(function(e,r,n,i,a,s){var l,u,h,f,d="",p=0;l=h=f=e,u=null;var m="Size1-Regular";e==="\\uparrow"?h=f="\u23D0":e==="\\Uparrow"?h=f="\u2016":e==="\\downarrow"?l=h="\u23D0":e==="\\Downarrow"?l=h="\u2016":e==="\\updownarrow"?(l="\\uparrow",h="\u23D0",f="\\downarrow"):e==="\\Updownarrow"?(l="\\Uparrow",h="\u2016",f="\\Downarrow"):Jt.contains($3e,e)?(h="\u2223",d="vert",p=333):Jt.contains(z3e,e)?(h="\u2225",d="doublevert",p=556):e==="["||e==="\\lbrack"?(l="\u23A1",h="\u23A2",f="\u23A3",m="Size4-Regular",d="lbrack",p=667):e==="]"||e==="\\rbrack"?(l="\u23A4",h="\u23A5",f="\u23A6",m="Size4-Regular",d="rbrack",p=667):e==="\\lfloor"||e==="\u230A"?(h=l="\u23A2",f="\u23A3",m="Size4-Regular",d="lfloor",p=667):e==="\\lceil"||e==="\u2308"?(l="\u23A1",h=f="\u23A2",m="Size4-Regular",d="lceil",p=667):e==="\\rfloor"||e==="\u230B"?(h=l="\u23A5",f="\u23A6",m="Size4-Regular",d="rfloor",p=667):e==="\\rceil"||e==="\u2309"?(l="\u23A4",h=f="\u23A5",m="Size4-Regular",d="rceil",p=667):e==="("||e==="\\lparen"?(l="\u239B",h="\u239C",f="\u239D",m="Size4-Regular",d="lparen",p=875):e===")"||e==="\\rparen"?(l="\u239E",h="\u239F",f="\u23A0",m="Size4-Regular",d="rparen",p=875):e==="\\{"||e==="\\lbrace"?(l="\u23A7",u="\u23A8",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(l="\u23AB",u="\u23AC",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lgroup"||e==="\u27EE"?(l="\u23A7",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\rgroup"||e==="\u27EF"?(l="\u23AB",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lmoustache"||e==="\u23B0"?(l="\u23A7",f="\u23AD",h="\u23AA",m="Size4-Regular"):(e==="\\rmoustache"||e==="\u23B1")&&(l="\u23AB",f="\u23A9",h="\u23AA",m="Size4-Regular");var g=Yy(l,m,a),y=g.height+g.depth,v=Yy(h,m,a),x=v.height+v.depth,b=Yy(f,m,a),T=b.height+b.depth,S=0,w=1;if(u!==null){var E=Yy(u,m,a);S=E.height+E.depth,w=2}var _=y+T+S,C=Math.max(0,Math.ceil((r-_)/(w*x))),D=_+C*w*x,O=i.fontMetrics().axisHeight;n&&(O*=i.sizeMultiplier);var R=D/2-O,k=[];if(d.length>0){var L=D-y-T,A=Math.round(D*1e3),I=Y4e(d,Math.round(L*1e3)),M=new ec(d,I),P=(p/1e3).toFixed(3)+"em",B=(A/1e3).toFixed(3)+"em",F=new dl([M],{width:P,height:B,viewBox:"0 0 "+p+" "+A}),z=Fe.makeSvgSpan([],[F],i);z.height=A/1e3,z.style.width=P,z.style.height=B,k.push({type:"elem",elem:z})}else{if(k.push(O7(f,m,a)),k.push(v3),u===null){var $=D-y-T+2*Z7;k.push(P7(h,$,i))}else{var U=(D-y-T-S)/2+2*Z7;k.push(P7(h,U,i)),k.push(v3),k.push(O7(u,m,a)),k.push(v3),k.push(P7(h,U,i))}k.push(v3),k.push(O7(l,m,a))}var K=i.havingBaseStyle(nr.TEXT),ee=Fe.makeVList({positionType:"bottom",positionData:R,children:k},K);return cA(Fe.makeSpan(["delimsizing","mult"],[ee],K),nr.TEXT,i,s)},"makeStackedDelim"),B7=80,F7=.08,$7=o(function(e,r,n,i,a){var s=W4e(e,i,n),l=new ec(e,s),u=new dl([l],{width:"400em",height:Et(r),viewBox:"0 0 400000 "+n,preserveAspectRatio:"xMinYMin slice"});return Fe.makeSvgSpan(["hide-tail"],[u],a)},"sqrtSvg"),G3e=o(function(e,r){var n=r.havingBaseSizing(),i=rV("\\surd",e*n.sizeMultiplier,tV,n),a=n.sizeMultiplier,s=Math.max(0,r.minRuleThickness-r.fontMetrics().sqrtRuleThickness),l,u=0,h=0,f=0,d;return i.type==="small"?(f=1e3+1e3*s+B7,e<1?a=1:e<1.4&&(a=.7),u=(1+s+F7)/a,h=(1+s)/a,l=$7("sqrtMain",u,f,s,r),l.style.minWidth="0.853em",d=.833/a):i.type==="large"?(f=(1e3+B7)*jy[i.size],h=(jy[i.size]+s)/a,u=(jy[i.size]+s+F7)/a,l=$7("sqrtSize"+i.size,u,f,s,r),l.style.minWidth="1.02em",d=1/a):(u=e+s+F7,h=e+s,f=Math.floor(1e3*e+s)+B7,l=$7("sqrtTall",u,f,s,r),l.style.minWidth="0.742em",d=1.056),l.height=h,l.style.height=Et(u),{span:l,advanceWidth:d,ruleWidth:(r.fontMetrics().sqrtRuleThickness+s)*a}},"makeSqrtImage"),JG=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","\\surd"],V3e=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1"],eV=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],jy=[0,1.2,1.8,2.4,3],U3e=o(function(e,r,n,i,a){if(e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle"),Jt.contains(JG,e)||Jt.contains(eV,e))return QG(e,r,!1,n,i,a);if(Jt.contains(V3e,e))return ZG(e,jy[r],!1,n,i,a);throw new pt("Illegal delimiter: '"+e+"'")},"makeSizedDelim"),H3e=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],W3e=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"stack"}],tV=[{type:"small",style:nr.SCRIPTSCRIPT},{type:"small",style:nr.SCRIPT},{type:"small",style:nr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],q3e=o(function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},"delimTypeToFont"),rV=o(function(e,r,n,i){for(var a=Math.min(2,3-i.style.size),s=a;sr)return n[s]}return n[n.length-1]},"traverseSequence"),nV=o(function(e,r,n,i,a,s){e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle");var l;Jt.contains(eV,e)?l=H3e:Jt.contains(JG,e)?l=tV:l=W3e;var u=rV(e,r,l,i);return u.type==="small"?B3e(e,u.style,n,i,a,s):u.type==="large"?QG(e,u.size,n,i,a,s):ZG(e,r,n,i,a,s)},"makeCustomSizedDelim"),Y3e=o(function(e,r,n,i,a,s){var l=i.fontMetrics().axisHeight*i.sizeMultiplier,u=901,h=5/i.fontMetrics().ptPerEm,f=Math.max(r-l,n+l),d=Math.max(f/500*u,2*f-h);return nV(e,d,!0,i,a,s)},"makeLeftRightDelim"),hu={sqrtImage:G3e,sizedDelim:U3e,sizeToMaxHeight:jy,customSizedDelim:nV,leftRightDelim:Y3e},oG={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},X3e=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27E8","\\rangle","\u27E9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];o(M3,"checkDelimiter");Nt({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:o((t,e)=>{var r=M3(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:oG[t.funcName].size,mclass:oG[t.funcName].mclass,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>t.delim==="."?Fe.makeSpan([t.mclass]):hu.sizedDelim(t.delim,t.size,e,t.mode,[t.mclass]),"htmlBuilder"),mathmlBuilder:o(t=>{var e=[];t.delim!=="."&&e.push(Do(t.delim,t.mode));var r=new dt.MathNode("mo",e);t.mclass==="mopen"||t.mclass==="mclose"?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=Et(hu.sizeToMaxHeight[t.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r},"mathmlBuilder")});o(lG,"assertParsed");Nt({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=t.parser.gullet.macros.get("\\current@color");if(r&&typeof r!="string")throw new pt("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:M3(e[0],t).text,color:r}},"handler")});Nt({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=M3(e[0],t),n=t.parser;++n.leftrightDepth;var i=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var a=xr(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:i,left:r.text,right:a.delim,rightColor:a.color}},"handler"),htmlBuilder:o((t,e)=>{lG(t);for(var r=$i(t.body,e,!0,["mopen","mclose"]),n=0,i=0,a=!1,s=0;s{lG(t);var r=_s(t.body,e);if(t.left!=="."){var n=new dt.MathNode("mo",[Do(t.left,t.mode)]);n.setAttribute("fence","true"),r.unshift(n)}if(t.right!=="."){var i=new dt.MathNode("mo",[Do(t.right,t.mode)]);i.setAttribute("fence","true"),t.rightColor&&i.setAttribute("mathcolor",t.rightColor),r.push(i)}return aA(r)},"mathmlBuilder")});Nt({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=M3(e[0],t);if(!t.parser.leftrightDepth)throw new pt("\\middle without preceding \\left",r);return{type:"middle",mode:t.parser.mode,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>{var r;if(t.delim===".")r=ev(e,[]);else{r=hu.sizedDelim(t.delim,1,e,t.mode,[]);var n={delim:t.delim,options:e};r.isMiddle=n}return r},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=t.delim==="\\vert"||t.delim==="|"?Do("|","text"):Do(t.delim,t.mode),n=new dt.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n},"mathmlBuilder")});uA=o((t,e)=>{var r=Fe.wrapFragment($r(t.body,e),e),n=t.label.slice(1),i=e.sizeMultiplier,a,s=0,l=Jt.isCharacterBox(t.body);if(n==="sout")a=Fe.makeSpan(["stretchy","sout"]),a.height=e.fontMetrics().defaultRuleThickness/i,s=-.5*e.fontMetrics().xHeight;else if(n==="phase"){var u=ni({number:.6,unit:"pt"},e),h=ni({number:.35,unit:"ex"},e),f=e.havingBaseSizing();i=i/f.sizeMultiplier;var d=r.height+r.depth+u+h;r.style.paddingLeft=Et(d/2+u);var p=Math.floor(1e3*d*i),m=U4e(p),g=new dl([new ec("phase",m)],{width:"400em",height:Et(p/1e3),viewBox:"0 0 400000 "+p,preserveAspectRatio:"xMinYMin slice"});a=Fe.makeSvgSpan(["hide-tail"],[g],e),a.style.height=Et(d),s=r.depth+u+h}else{/cancel/.test(n)?l||r.classes.push("cancel-pad"):n==="angl"?r.classes.push("anglpad"):r.classes.push("boxpad");var y=0,v=0,x=0;/box/.test(n)?(x=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),y=e.fontMetrics().fboxsep+(n==="colorbox"?0:x),v=y):n==="angl"?(x=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),y=4*x,v=Math.max(0,.25-r.depth)):(y=l?.2:0,v=y),a=du.encloseSpan(r,n,y,v,e),/fbox|boxed|fcolorbox/.test(n)?(a.style.borderStyle="solid",a.style.borderWidth=Et(x)):n==="angl"&&x!==.049&&(a.style.borderTopWidth=Et(x),a.style.borderRightWidth=Et(x)),s=r.depth+v,t.backgroundColor&&(a.style.backgroundColor=t.backgroundColor,t.borderColor&&(a.style.borderColor=t.borderColor))}var b;if(t.backgroundColor)b=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:s},{type:"elem",elem:r,shift:0}]},e);else{var T=/cancel|phase/.test(n)?["svg-align"]:[];b=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:a,shift:s,wrapperClasses:T}]},e)}return/cancel/.test(n)&&(b.height=r.height,b.depth=r.depth),/cancel/.test(n)&&!l?Fe.makeSpan(["mord","cancel-lap"],[b],e):Fe.makeSpan(["mord"],[b],e)},"htmlBuilder$7"),hA=o((t,e)=>{var r=0,n=new dt.MathNode(t.label.indexOf("colorbox")>-1?"mpadded":"menclose",[vn(t.body,e)]);switch(t.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),t.label==="\\fcolorbox"){var i=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);n.setAttribute("style","border: "+i+"em solid "+String(t.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return t.backgroundColor&&n.setAttribute("mathbackground",t.backgroundColor),n},"mathmlBuilder$6");Nt({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=e[1];return{type:"enclose",mode:n.mode,label:i,backgroundColor:a,body:s}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=xr(e[1],"color-token").color,l=e[2];return{type:"enclose",mode:n.mode,label:i,backgroundColor:s,borderColor:a,body:l}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\fbox",body:e[0]}}});Nt({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"enclose",mode:r.mode,label:n,body:i}},htmlBuilder:uA,mathmlBuilder:hA});Nt({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\angl",body:e[0]}}});iV={};o(tc,"defineEnvironment");aV={};o(fe,"defineMacro");o(cG,"getHLines");I3=o(t=>{var e=t.parser.settings;if(!e.displayMode)throw new pt("{"+t.envName+"} can be used only in display mode.")},"validateAmsEnvironmentContext");o(fA,"getAutoTag");o(bh,"parseArray");o(dA,"dCellStyle");rc=o(function(e,r){var n,i,a=e.body.length,s=e.hLinesBeforeRow,l=0,u=new Array(a),h=[],f=Math.max(r.fontMetrics().arrayRuleWidth,r.minRuleThickness),d=1/r.fontMetrics().ptPerEm,p=5*d;if(e.colSeparationType&&e.colSeparationType==="small"){var m=r.havingStyle(nr.SCRIPT).sizeMultiplier;p=.2778*(m/r.sizeMultiplier)}var g=e.colSeparationType==="CD"?ni({number:3,unit:"ex"},r):12*d,y=3*d,v=e.arraystretch*g,x=.7*v,b=.3*v,T=0;function S(ae){for(var Oe=0;Oe0&&(T+=.25),h.push({pos:T,isDashed:ae[Oe]})}for(o(S,"setHLinePos"),S(s[0]),n=0;n0&&(R+=b,_ae))for(n=0;n=l)){var Z=void 0;(i>0||e.hskipBeforeAndAfter)&&(Z=Jt.deflt(U.pregap,p),Z!==0&&(I=Fe.makeSpan(["arraycolsep"],[]),I.style.width=Et(Z),A.push(I)));var ue=[];for(n=0;n0){for(var te=Fe.makeLineSpan("hline",r,f),he=Fe.makeLineSpan("hdashline",r,f),le=[{type:"elem",elem:u,shift:0}];h.length>0;){var J=h.pop(),Se=J.pos-k;J.isDashed?le.push({type:"elem",elem:he,shift:Se}):le.push({type:"elem",elem:te,shift:Se})}u=Fe.makeVList({positionType:"individualShift",children:le},r)}if(P.length===0)return Fe.makeSpan(["mord"],[u],r);var se=Fe.makeVList({positionType:"individualShift",children:P},r);return se=Fe.makeSpan(["tag"],[se],r),Fe.makeFragment([u,se])},"htmlBuilder"),j3e={c:"center ",l:"left ",r:"right "},nc=o(function(e,r){for(var n=[],i=new dt.MathNode("mtd",[],["mtr-glue"]),a=new dt.MathNode("mtd",[],["mml-eqn-num"]),s=0;s0){var g=e.cols,y="",v=!1,x=0,b=g.length;g[0].type==="separator"&&(p+="top ",x=1),g[g.length-1].type==="separator"&&(p+="bottom ",b-=1);for(var T=x;T0?"left ":"",p+=C[C.length-1].length>0?"right ":"";for(var D=1;D-1?"alignat":"align",a=e.envName==="split",s=bh(e.parser,{cols:n,addJot:!0,autoTag:a?void 0:fA(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:a?2:void 0,leqno:e.parser.settings.leqno},"display"),l,u=0,h={type:"ordgroup",mode:e.mode,body:[]};if(r[0]&&r[0].type==="ordgroup"){for(var f="",d=0;d0&&m&&(v=1),n[g]={type:"align",align:y,pregap:v,postgap:0}}return s.colSeparationType=m?"align":"alignat",s},"alignedHandler");tc({type:"array",names:["array","darray"],props:{numArgs:1},handler(t,e){var r=R3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=oA(s),u=l.text;if("lcr".indexOf(u)!==-1)return{type:"align",align:u};if(u==="|")return{type:"separator",separator:"|"};if(u===":")return{type:"separator",separator:":"};throw new pt("Unknown column alignment: "+u,s)}),a={cols:i,hskipBeforeAndAfter:!0,maxNumCols:i.length};return bh(t.parser,a,dA(t.envName))},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName.replace("*","")],r="c",n={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if(t.envName.charAt(t.envName.length-1)==="*"){var i=t.parser;if(i.consumeSpaces(),i.fetch().text==="["){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,"lcr".indexOf(r)===-1)throw new pt("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),n.cols=[{type:"align",align:r}]}}var a=bh(t.parser,n,dA(t.envName)),s=Math.max(0,...a.body.map(l=>l.length));return a.cols=new Array(s).fill({type:"align",align:r}),e?{type:"leftright",mode:t.mode,body:[a],left:e[0],right:e[1],rightColor:void 0}:a},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(t){var e={arraystretch:.5},r=bh(t.parser,e,"script");return r.colSeparationType="small",r},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["subarray"],props:{numArgs:1},handler(t,e){var r=R3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=oA(s),u=l.text;if("lc".indexOf(u)!==-1)return{type:"align",align:u};throw new pt("Unknown column alignment: "+u,s)});if(i.length>1)throw new pt("{subarray} can contain only one column");var a={cols:i,hskipBeforeAndAfter:!1,arraystretch:.5};if(a=bh(t.parser,a,"script"),a.body.length>0&&a.body[0].length>1)throw new pt("{subarray} can contain only one column");return a},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(t){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},r=bh(t.parser,e,dA(t.envName));return{type:"leftright",mode:t.mode,body:[r],left:t.envName.indexOf("r")>-1?".":"\\{",right:t.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:sV,htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(t){Jt.contains(["gather","gather*"],t.envName)&&I3(t);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:fA(t.envName),emptySingleRow:!0,leqno:t.parser.settings.leqno};return bh(t.parser,e,"display")},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:sV,htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(t){I3(t);var e={autoTag:fA(t.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:t.parser.settings.leqno};return bh(t.parser,e,"display")},htmlBuilder:rc,mathmlBuilder:nc});tc({type:"array",names:["CD"],props:{numArgs:0},handler(t){return I3(t),O3e(t.parser)},htmlBuilder:rc,mathmlBuilder:nc});fe("\\nonumber","\\gdef\\@eqnsw{0}");fe("\\notag","\\nonumber");Nt({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(t,e){throw new pt(t.funcName+" valid only within array environment")}});uG=iV;Nt({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];if(i.type!=="ordgroup")throw new pt("Invalid environment name",i);for(var a="",s=0;s{var r=t.font,n=e.withFont(r);return $r(t.body,n)},"htmlBuilder$5"),lV=o((t,e)=>{var r=t.font,n=e.withFont(r);return vn(t.body,n)},"mathmlBuilder$4"),hG={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Nt({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=C3(e[0]),a=n;return a in hG&&(a=hG[a]),{type:"font",mode:r.mode,font:a.slice(1),body:i}},"handler"),htmlBuilder:oV,mathmlBuilder:lV});Nt({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r}=t,n=e[0],i=Jt.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:N3(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:i}},"handler")});Nt({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n,breakOnTokenText:i}=t,{mode:a}=r,s=r.parseExpression(!0,i),l="math"+n.slice(1);return{type:"font",mode:a,font:l,body:{type:"ordgroup",mode:r.mode,body:s}}},"handler"),htmlBuilder:oV,mathmlBuilder:lV});cV=o((t,e)=>{var r=e;return t==="display"?r=r.id>=nr.SCRIPT.id?r.text():nr.DISPLAY:t==="text"&&r.size===nr.DISPLAY.size?r=nr.TEXT:t==="script"?r=nr.SCRIPT:t==="scriptscript"&&(r=nr.SCRIPTSCRIPT),r},"adjustStyle"),pA=o((t,e)=>{var r=cV(t.size,e.style),n=r.fracNum(),i=r.fracDen(),a;a=e.havingStyle(n);var s=$r(t.numer,a,e);if(t.continued){var l=8.5/e.fontMetrics().ptPerEm,u=3.5/e.fontMetrics().ptPerEm;s.height=s.height0?g=3*p:g=7*p,y=e.fontMetrics().denom1):(d>0?(m=e.fontMetrics().num2,g=p):(m=e.fontMetrics().num3,g=3*p),y=e.fontMetrics().denom2);var v;if(f){var b=e.fontMetrics().axisHeight;m-s.depth-(b+.5*d){var r=new dt.MathNode("mfrac",[vn(t.numer,e),vn(t.denom,e)]);if(!t.hasBarLine)r.setAttribute("linethickness","0px");else if(t.barSize){var n=ni(t.barSize,e);r.setAttribute("linethickness",Et(n))}var i=cV(t.size,e.style);if(i.size!==e.style.size){r=new dt.MathNode("mstyle",[r]);var a=i.size===nr.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",a),r.setAttribute("scriptlevel","0")}if(t.leftDelim!=null||t.rightDelim!=null){var s=[];if(t.leftDelim!=null){var l=new dt.MathNode("mo",[new dt.TextNode(t.leftDelim.replace("\\",""))]);l.setAttribute("fence","true"),s.push(l)}if(s.push(r),t.rightDelim!=null){var u=new dt.MathNode("mo",[new dt.TextNode(t.rightDelim.replace("\\",""))]);u.setAttribute("fence","true"),s.push(u)}return aA(s)}return r},"mathmlBuilder$3");Nt({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1],s,l=null,u=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":s=!0;break;case"\\\\atopfrac":s=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":s=!1,l="(",u=")";break;case"\\\\bracefrac":s=!1,l="\\{",u="\\}";break;case"\\\\brackfrac":s=!1,l="[",u="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:r.mode,continued:!1,numer:i,denom:a,hasBarLine:s,leftDelim:l,rightDelim:u,size:h,barSize:null}},"handler"),htmlBuilder:pA,mathmlBuilder:mA});Nt({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:i,denom:a,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}},"handler")});Nt({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(t){var{parser:e,funcName:r,token:n}=t,i;switch(r){case"\\over":i="\\frac";break;case"\\choose":i="\\binom";break;case"\\atop":i="\\\\atopfrac";break;case"\\brace":i="\\\\bracefrac";break;case"\\brack":i="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:i,token:n}}});fG=["display","text","script","scriptscript"],dG=o(function(e){var r=null;return e.length>0&&(r=e,r=r==="."?null:r),r},"delimFromValue");Nt({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(t,e){var{parser:r}=t,n=e[4],i=e[5],a=C3(e[0]),s=a.type==="atom"&&a.family==="open"?dG(a.text):null,l=C3(e[1]),u=l.type==="atom"&&l.family==="close"?dG(l.text):null,h=xr(e[2],"size"),f,d=null;h.isBlank?f=!0:(d=h.value,f=d.number>0);var p="auto",m=e[3];if(m.type==="ordgroup"){if(m.body.length>0){var g=xr(m.body[0],"textord");p=fG[Number(g.text)]}}else m=xr(m,"textord"),p=fG[Number(m.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:f,barSize:d,leftDelim:s,rightDelim:u,size:p}},htmlBuilder:pA,mathmlBuilder:mA});Nt({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(t,e){var{parser:r,funcName:n,token:i}=t;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:xr(e[0],"size").value,token:i}}});Nt({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=_4e(xr(e[1],"infix").size),s=e[2],l=a.number>0;return{type:"genfrac",mode:r.mode,numer:i,denom:s,continued:!1,hasBarLine:l,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},"handler"),htmlBuilder:pA,mathmlBuilder:mA});uV=o((t,e)=>{var r=e.style,n,i;t.type==="supsub"?(n=t.sup?$r(t.sup,e.havingStyle(r.sup()),e):$r(t.sub,e.havingStyle(r.sub()),e),i=xr(t.base,"horizBrace")):i=xr(t,"horizBrace");var a=$r(i.base,e.havingBaseStyle(nr.DISPLAY)),s=du.svgSpan(i,e),l;if(i.isOver?(l=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:s}]},e),l.children[0].children[0].children[1].classes.push("svg-align")):(l=Fe.makeVList({positionType:"bottom",positionData:a.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:a}]},e),l.children[0].children[0].children[0].classes.push("svg-align")),n){var u=Fe.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e);i.isOver?l=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:u},{type:"kern",size:.2},{type:"elem",elem:n}]},e):l=Fe.makeVList({positionType:"bottom",positionData:u.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:u}]},e)}return Fe.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e)},"htmlBuilder$3"),K3e=o((t,e)=>{var r=du.mathMLnode(t.label);return new dt.MathNode(t.isOver?"mover":"munder",[vn(t.base,e),r])},"mathmlBuilder$2");Nt({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:e[0]}},htmlBuilder:uV,mathmlBuilder:K3e});Nt({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[1],i=xr(e[0],"url").url;return r.settings.isTrusted({command:"\\href",url:i})?{type:"href",mode:r.mode,href:i,body:gi(n)}:r.formatUnsupportedCmd("\\href")},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.body,e,!1);return Fe.makeAnchor(t.href,[],r,e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=xh(t.body,e);return r instanceof ts||(r=new ts("mrow",[r])),r.setAttribute("href",t.href),r},"mathmlBuilder")});Nt({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=xr(e[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var i=[],a=0;a{var{parser:r,funcName:n,token:i}=t,a=xr(e[0],"raw").string,s=e[1];r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var l,u={};switch(n){case"\\htmlClass":u.class=a,l={command:"\\htmlClass",class:a};break;case"\\htmlId":u.id=a,l={command:"\\htmlId",id:a};break;case"\\htmlStyle":u.style=a,l={command:"\\htmlStyle",style:a};break;case"\\htmlData":{for(var h=a.split(","),f=0;f{var r=$i(t.body,e,!1),n=["enclosing"];t.attributes.class&&n.push(...t.attributes.class.trim().split(/\s+/));var i=Fe.makeSpan(n,r,e);for(var a in t.attributes)a!=="class"&&t.attributes.hasOwnProperty(a)&&i.setAttribute(a,t.attributes[a]);return i},"htmlBuilder"),mathmlBuilder:o((t,e)=>xh(t.body,e),"mathmlBuilder")});Nt({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"htmlmathml",mode:r.mode,html:gi(e[0]),mathml:gi(e[1])}},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.html,e,!1);return Fe.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>xh(t.mathml,e),"mathmlBuilder")});z7=o(function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var r=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!r)throw new pt("Invalid size: '"+e+"' in \\includegraphics");var n={number:+(r[1]+r[2]),unit:r[3]};if(!DG(n))throw new pt("Invalid unit: '"+n.unit+"' in \\includegraphics.");return n},"sizeData");Nt({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:o((t,e,r)=>{var{parser:n}=t,i={number:0,unit:"em"},a={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var u=xr(r[0],"raw").string,h=u.split(","),f=0;f{var r=ni(t.height,e),n=0;t.totalheight.number>0&&(n=ni(t.totalheight,e)-r);var i=0;t.width.number>0&&(i=ni(t.width,e));var a={height:Et(r+n)};i>0&&(a.width=Et(i)),n>0&&(a.verticalAlign=Et(-n));var s=new q7(t.src,t.alt,a);return s.height=r,s.depth=n,s},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mglyph",[]);r.setAttribute("alt",t.alt);var n=ni(t.height,e),i=0;if(t.totalheight.number>0&&(i=ni(t.totalheight,e)-n,r.setAttribute("valign",Et(-i))),r.setAttribute("height",Et(n+i)),t.width.number>0){var a=ni(t.width,e);r.setAttribute("width",Et(a))}return r.setAttribute("src",t.src),r},"mathmlBuilder")});Nt({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=xr(e[0],"size");if(r.settings.strict){var a=n[1]==="m",s=i.value.unit==="mu";a?(s||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, "+("not "+i.value.unit+" units")),r.mode!=="math"&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):s&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:i.value}},htmlBuilder(t,e){return Fe.makeGlue(t.dimension,e)},mathmlBuilder(t,e){var r=ni(t.dimension,e);return new dt.SpaceNode(r)}});Nt({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:i}},"handler"),htmlBuilder:o((t,e)=>{var r;t.alignment==="clap"?(r=Fe.makeSpan([],[$r(t.body,e)]),r=Fe.makeSpan(["inner"],[r],e)):r=Fe.makeSpan(["inner"],[$r(t.body,e)]);var n=Fe.makeSpan(["fix"],[]),i=Fe.makeSpan([t.alignment],[r,n],e),a=Fe.makeSpan(["strut"]);return a.style.height=Et(i.height+i.depth),i.depth&&(a.style.verticalAlign=Et(-i.depth)),i.children.unshift(a),i=Fe.makeSpan(["thinbox"],[i],e),Fe.makeSpan(["mord","vbox"],[i],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mpadded",[vn(t.body,e)]);if(t.alignment!=="rlap"){var n=t.alignment==="llap"?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r},"mathmlBuilder")});Nt({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){var{funcName:r,parser:n}=t,i=n.mode;n.switchMode("math");var a=r==="\\("?"\\)":"$",s=n.parseExpression(!1,a);return n.expect(a),n.switchMode(i),{type:"styling",mode:n.mode,style:"text",body:s}}});Nt({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){throw new pt("Mismatched "+t.funcName)}});pG=o((t,e)=>{switch(e.style.size){case nr.DISPLAY.size:return t.display;case nr.TEXT.size:return t.text;case nr.SCRIPT.size:return t.script;case nr.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}},"chooseMathStyle");Nt({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"mathchoice",mode:r.mode,display:gi(e[0]),text:gi(e[1]),script:gi(e[2]),scriptscript:gi(e[3])}},"handler"),htmlBuilder:o((t,e)=>{var r=pG(t,e),n=$i(r,e,!1);return Fe.makeFragment(n)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=pG(t,e);return xh(r,e)},"mathmlBuilder")});hV=o((t,e,r,n,i,a,s)=>{t=Fe.makeSpan([],[t]);var l=r&&Jt.isCharacterBox(r),u,h;if(e){var f=$r(e,n.havingStyle(i.sup()),n);h={elem:f,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-f.depth)}}if(r){var d=$r(r,n.havingStyle(i.sub()),n);u={elem:d,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-d.height)}}var p;if(h&&u){var m=n.fontMetrics().bigOpSpacing5+u.elem.height+u.elem.depth+u.kern+t.depth+s;p=Fe.makeVList({positionType:"bottom",positionData:m,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:Et(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Et(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(u){var g=t.height-s;p=Fe.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:Et(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t}]},n)}else if(h){var y=t.depth+s;p=Fe.makeVList({positionType:"bottom",positionData:y,children:[{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:Et(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else return t;var v=[p];if(u&&a!==0&&!l){var x=Fe.makeSpan(["mspace"],[],n);x.style.marginRight=Et(a),v.unshift(x)}return Fe.makeSpan(["mop","op-limits"],v,n)},"assembleSupSub"),fV=["\\smallint"],S0=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"op"),i=!0):a=xr(t,"op");var s=e.style,l=!1;s.size===nr.DISPLAY.size&&a.symbol&&!Jt.contains(fV,a.name)&&(l=!0);var u;if(a.symbol){var h=l?"Size2-Regular":"Size1-Regular",f="";if((a.name==="\\oiint"||a.name==="\\oiiint")&&(f=a.name.slice(1),a.name=f==="oiint"?"\\iint":"\\iiint"),u=Fe.makeSymbol(a.name,h,"math",e,["mop","op-symbol",l?"large-op":"small-op"]),f.length>0){var d=u.italic,p=Fe.staticSvg(f+"Size"+(l?"2":"1"),e);u=Fe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:u,shift:0},{type:"elem",elem:p,shift:l?.08:0}]},e),a.name="\\"+f,u.classes.unshift("mop"),u.italic=d}}else if(a.body){var m=$i(a.body,e,!0);m.length===1&&m[0]instanceof As?(u=m[0],u.classes[0]="mop"):u=Fe.makeSpan(["mop"],m,e)}else{for(var g=[],y=1;y{var r;if(t.symbol)r=new ts("mo",[Do(t.name,t.mode)]),Jt.contains(fV,t.name)&&r.setAttribute("largeop","false");else if(t.body)r=new ts("mo",_s(t.body,e));else{r=new ts("mi",[new Ao(t.name.slice(1))]);var n=new ts("mo",[Do("\u2061","text")]);t.parentIsSupSub?r=new ts("mrow",[r,n]):r=zG([r,n])}return r},"mathmlBuilder$1"),Q3e={"\u220F":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22C0":"\\bigwedge","\u22C1":"\\bigvee","\u22C2":"\\bigcap","\u22C3":"\\bigcup","\u2A00":"\\bigodot","\u2A01":"\\bigoplus","\u2A02":"\\bigotimes","\u2A04":"\\biguplus","\u2A06":"\\bigsqcup"};Nt({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220F","\u2210","\u2211","\u22C0","\u22C1","\u22C2","\u22C3","\u2A00","\u2A01","\u2A02","\u2A04","\u2A06"],props:{numArgs:0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=n;return i.length===1&&(i=Q3e[i]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:i}},"handler"),htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:gi(n)}},"handler"),htmlBuilder:S0,mathmlBuilder:tv});Z3e={"\u222B":"\\int","\u222C":"\\iint","\u222D":"\\iiint","\u222E":"\\oint","\u222F":"\\oiint","\u2230":"\\oiiint"};Nt({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:S0,mathmlBuilder:tv});Nt({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222B","\u222C","\u222D","\u222E","\u222F","\u2230"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t,n=r;return n.length===1&&(n=Z3e[n]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:S0,mathmlBuilder:tv});dV=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"operatorname"),i=!0):a=xr(t,"operatorname");var s;if(a.body.length>0){for(var l=a.body.map(d=>{var p=d.text;return typeof p=="string"?{type:"textord",mode:d.mode,text:p}:d}),u=$i(l,e.withFont("mathrm"),!0),h=0;h{for(var r=_s(t.body,e.withFont("mathrm")),n=!0,i=0;if.toText()).join("");r=[new dt.TextNode(l)]}var u=new dt.MathNode("mi",r);u.setAttribute("mathvariant","normal");var h=new dt.MathNode("mo",[Do("\u2061","text")]);return t.parentIsSupSub?new dt.MathNode("mrow",[u,h]):dt.newDocumentFragment([u,h])},"mathmlBuilder");Nt({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"operatorname",mode:r.mode,body:gi(i),alwaysHandleSupSub:n==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},"handler"),htmlBuilder:dV,mathmlBuilder:J3e});fe("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");cd({type:"ordgroup",htmlBuilder(t,e){return t.semisimple?Fe.makeFragment($i(t.body,e,!1)):Fe.makeSpan(["mord"],$i(t.body,e,!0),e)},mathmlBuilder(t,e){return xh(t.body,e,!0)}});Nt({type:"overline",names:["\\overline"],props:{numArgs:1},handler(t,e){var{parser:r}=t,n=e[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(t,e){var r=$r(t.body,e.havingCrampedStyle()),n=Fe.makeLineSpan("overline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*i},{type:"elem",elem:n},{type:"kern",size:i}]},e);return Fe.makeSpan(["mord","overline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("mover",[vn(t.body,e),r]);return n.setAttribute("accent","true"),n}});Nt({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"phantom",mode:r.mode,body:gi(n)}},"handler"),htmlBuilder:o((t,e)=>{var r=$i(t.body,e.withPhantom(),!1);return Fe.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=_s(t.body,e);return new dt.MathNode("mphantom",r)},"mathmlBuilder")});Nt({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"hphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Fe.makeSpan([],[$r(t.body,e.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var n=0;n{var r=_s(gi(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("height","0px"),i.setAttribute("depth","0px"),i},"mathmlBuilder")});Nt({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"vphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Fe.makeSpan(["inner"],[$r(t.body,e.withPhantom())]),n=Fe.makeSpan(["fix"],[]);return Fe.makeSpan(["mord","rlap"],[r,n],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=_s(gi(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("width","0px"),i},"mathmlBuilder")});Nt({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t,n=xr(e[0],"size").value,i=e[1];return{type:"raisebox",mode:r.mode,dy:n,body:i}},htmlBuilder(t,e){var r=$r(t.body,e),n=ni(t.dy,e);return Fe.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){var r=new dt.MathNode("mpadded",[vn(t.body,e)]),n=t.dy.number+t.dy.unit;return r.setAttribute("voffset",n),r}});Nt({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(t){var{parser:e}=t;return{type:"internal",mode:e.mode}}});Nt({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(t,e,r){var{parser:n}=t,i=r[0],a=xr(e[0],"size"),s=xr(e[1],"size");return{type:"rule",mode:n.mode,shift:i&&xr(i,"size").value,width:a.value,height:s.value}},htmlBuilder(t,e){var r=Fe.makeSpan(["mord","rule"],[],e),n=ni(t.width,e),i=ni(t.height,e),a=t.shift?ni(t.shift,e):0;return r.style.borderRightWidth=Et(n),r.style.borderTopWidth=Et(i),r.style.bottom=Et(a),r.width=n,r.height=i+a,r.depth=-a,r.maxFontSize=i*1.125*e.sizeMultiplier,r},mathmlBuilder(t,e){var r=ni(t.width,e),n=ni(t.height,e),i=t.shift?ni(t.shift,e):0,a=e.color&&e.getColor()||"black",s=new dt.MathNode("mspace");s.setAttribute("mathbackground",a),s.setAttribute("width",Et(r)),s.setAttribute("height",Et(n));var l=new dt.MathNode("mpadded",[s]);return i>=0?l.setAttribute("height",Et(i)):(l.setAttribute("height",Et(i)),l.setAttribute("depth",Et(-i))),l.setAttribute("voffset",Et(i)),l}});o(pV,"sizingGroup");mG=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],e5e=o((t,e)=>{var r=e.havingSize(t.size);return pV(t.body,r,e)},"htmlBuilder");Nt({type:"sizing",names:mG,props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!1,r);return{type:"sizing",mode:i.mode,size:mG.indexOf(n)+1,body:a}},"handler"),htmlBuilder:e5e,mathmlBuilder:o((t,e)=>{var r=e.havingSize(t.size),n=_s(t.body,r),i=new dt.MathNode("mstyle",n);return i.setAttribute("mathsize",Et(r.sizeMultiplier)),i},"mathmlBuilder")});Nt({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:o((t,e,r)=>{var{parser:n}=t,i=!1,a=!1,s=r[0]&&xr(r[0],"ordgroup");if(s)for(var l="",u=0;u{var r=Fe.makeSpan([],[$r(t.body,e)]);if(!t.smashHeight&&!t.smashDepth)return r;if(t.smashHeight&&(r.height=0,r.children))for(var n=0;n{var r=new dt.MathNode("mpadded",[vn(t.body,e)]);return t.smashHeight&&r.setAttribute("height","0px"),t.smashDepth&&r.setAttribute("depth","0px"),r},"mathmlBuilder")});Nt({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n}=t,i=r[0],a=e[0];return{type:"sqrt",mode:n.mode,body:a,index:i}},htmlBuilder(t,e){var r=$r(t.body,e.havingCrampedStyle());r.height===0&&(r.height=e.fontMetrics().xHeight),r=Fe.wrapFragment(r,e);var n=e.fontMetrics(),i=n.defaultRuleThickness,a=i;e.style.idr.height+r.depth+s&&(s=(s+d-r.height-r.depth)/2);var p=u.height-r.height-s-h;r.style.paddingLeft=Et(f);var m=Fe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+p)},{type:"elem",elem:u},{type:"kern",size:h}]},e);if(t.index){var g=e.havingStyle(nr.SCRIPTSCRIPT),y=$r(t.index,g,e),v=.6*(m.height-m.depth),x=Fe.makeVList({positionType:"shift",positionData:-v,children:[{type:"elem",elem:y}]},e),b=Fe.makeSpan(["root"],[x]);return Fe.makeSpan(["mord","sqrt"],[b,m],e)}else return Fe.makeSpan(["mord","sqrt"],[m],e)},mathmlBuilder(t,e){var{body:r,index:n}=t;return n?new dt.MathNode("mroot",[vn(r,e),vn(n,e)]):new dt.MathNode("msqrt",[vn(r,e)])}});gG={display:nr.DISPLAY,text:nr.TEXT,script:nr.SCRIPT,scriptscript:nr.SCRIPTSCRIPT};Nt({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t,e){var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!0,r),s=n.slice(1,n.length-5);return{type:"styling",mode:i.mode,style:s,body:a}},htmlBuilder(t,e){var r=gG[t.style],n=e.havingStyle(r).withFont("");return pV(t.body,n,e)},mathmlBuilder(t,e){var r=gG[t.style],n=e.havingStyle(r),i=_s(t.body,n),a=new dt.MathNode("mstyle",i),s={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},l=s[t.style];return a.setAttribute("scriptlevel",l[0]),a.setAttribute("displaystyle",l[1]),a}});t5e=o(function(e,r){var n=e.base;if(n)if(n.type==="op"){var i=n.limits&&(r.style.size===nr.DISPLAY.size||n.alwaysHandleSupSub);return i?S0:null}else if(n.type==="operatorname"){var a=n.alwaysHandleSupSub&&(r.style.size===nr.DISPLAY.size||n.limits);return a?dV:null}else{if(n.type==="accent")return Jt.isCharacterBox(n.base)?lA:null;if(n.type==="horizBrace"){var s=!e.sub;return s===n.isOver?uV:null}else return null}else return null},"htmlBuilderDelegate");cd({type:"supsub",htmlBuilder(t,e){var r=t5e(t,e);if(r)return r(t,e);var{base:n,sup:i,sub:a}=t,s=$r(n,e),l,u,h=e.fontMetrics(),f=0,d=0,p=n&&Jt.isCharacterBox(n);if(i){var m=e.havingStyle(e.style.sup());l=$r(i,m,e),p||(f=s.height-m.fontMetrics().supDrop*m.sizeMultiplier/e.sizeMultiplier)}if(a){var g=e.havingStyle(e.style.sub());u=$r(a,g,e),p||(d=s.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}var y;e.style===nr.DISPLAY?y=h.sup1:e.style.cramped?y=h.sup3:y=h.sup2;var v=e.sizeMultiplier,x=Et(.5/h.ptPerEm/v),b=null;if(u){var T=t.base&&t.base.type==="op"&&t.base.name&&(t.base.name==="\\oiint"||t.base.name==="\\oiiint");(s instanceof As||T)&&(b=Et(-s.italic))}var S;if(l&&u){f=Math.max(f,y,l.depth+.25*h.xHeight),d=Math.max(d,h.sub2);var w=h.defaultRuleThickness,E=4*w;if(f-l.depth-(u.height-d)0&&(f+=_,d-=_)}var C=[{type:"elem",elem:u,shift:d,marginRight:x,marginLeft:b},{type:"elem",elem:l,shift:-f,marginRight:x}];S=Fe.makeVList({positionType:"individualShift",children:C},e)}else if(u){d=Math.max(d,h.sub1,u.height-.8*h.xHeight);var D=[{type:"elem",elem:u,marginLeft:b,marginRight:x}];S=Fe.makeVList({positionType:"shift",positionData:d,children:D},e)}else if(l)f=Math.max(f,y,l.depth+.25*h.xHeight),S=Fe.makeVList({positionType:"shift",positionData:-f,children:[{type:"elem",elem:l,marginRight:x}]},e);else throw new Error("supsub must have either sup or sub.");var O=X7(s,"right")||"mord";return Fe.makeSpan([O],[s,Fe.makeSpan(["msupsub"],[S])],e)},mathmlBuilder(t,e){var r=!1,n,i;t.base&&t.base.type==="horizBrace"&&(i=!!t.sup,i===t.base.isOver&&(r=!0,n=t.base.isOver)),t.base&&(t.base.type==="op"||t.base.type==="operatorname")&&(t.base.parentIsSupSub=!0);var a=[vn(t.base,e)];t.sub&&a.push(vn(t.sub,e)),t.sup&&a.push(vn(t.sup,e));var s;if(r)s=n?"mover":"munder";else if(t.sub)if(t.sup){var h=t.base;h&&h.type==="op"&&h.limits&&e.style===nr.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===nr.DISPLAY||h.limits)?s="munderover":s="msubsup"}else{var u=t.base;u&&u.type==="op"&&u.limits&&(e.style===nr.DISPLAY||u.alwaysHandleSupSub)||u&&u.type==="operatorname"&&u.alwaysHandleSupSub&&(u.limits||e.style===nr.DISPLAY)?s="munder":s="msub"}else{var l=t.base;l&&l.type==="op"&&l.limits&&(e.style===nr.DISPLAY||l.alwaysHandleSupSub)||l&&l.type==="operatorname"&&l.alwaysHandleSupSub&&(l.limits||e.style===nr.DISPLAY)?s="mover":s="msup"}return new dt.MathNode(s,a)}});cd({type:"atom",htmlBuilder(t,e){return Fe.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[Do(t.text,t.mode)]);if(t.family==="bin"){var n=sA(t,e);n==="bold-italic"&&r.setAttribute("mathvariant",n)}else t.family==="punct"?r.setAttribute("separator","true"):(t.family==="open"||t.family==="close")&&r.setAttribute("stretchy","false");return r}});mV={mi:"italic",mn:"normal",mtext:"normal"};cd({type:"mathord",htmlBuilder(t,e){return Fe.makeOrd(t,e,"mathord")},mathmlBuilder(t,e){var r=new dt.MathNode("mi",[Do(t.text,t.mode,e)]),n=sA(t,e)||"italic";return n!==mV[r.type]&&r.setAttribute("mathvariant",n),r}});cd({type:"textord",htmlBuilder(t,e){return Fe.makeOrd(t,e,"textord")},mathmlBuilder(t,e){var r=Do(t.text,t.mode,e),n=sA(t,e)||"normal",i;return t.mode==="text"?i=new dt.MathNode("mtext",[r]):/[0-9]/.test(t.text)?i=new dt.MathNode("mn",[r]):t.text==="\\prime"?i=new dt.MathNode("mo",[r]):i=new dt.MathNode("mi",[r]),n!==mV[i.type]&&i.setAttribute("mathvariant",n),i}});G7={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},V7={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};cd({type:"spacing",htmlBuilder(t,e){if(V7.hasOwnProperty(t.text)){var r=V7[t.text].className||"";if(t.mode==="text"){var n=Fe.makeOrd(t,e,"textord");return n.classes.push(r),n}else return Fe.makeSpan(["mspace",r],[Fe.mathsym(t.text,t.mode,e)],e)}else{if(G7.hasOwnProperty(t.text))return Fe.makeSpan(["mspace",G7[t.text]],[],e);throw new pt('Unknown type of space "'+t.text+'"')}},mathmlBuilder(t,e){var r;if(V7.hasOwnProperty(t.text))r=new dt.MathNode("mtext",[new dt.TextNode("\xA0")]);else{if(G7.hasOwnProperty(t.text))return new dt.MathNode("mspace");throw new pt('Unknown type of space "'+t.text+'"')}return r}});yG=o(()=>{var t=new dt.MathNode("mtd",[]);return t.setAttribute("width","50%"),t},"pad");cd({type:"tag",mathmlBuilder(t,e){var r=new dt.MathNode("mtable",[new dt.MathNode("mtr",[yG(),new dt.MathNode("mtd",[xh(t.body,e)]),yG(),new dt.MathNode("mtd",[xh(t.tag,e)])])]);return r.setAttribute("width","100%"),r}});vG={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},xG={"\\textbf":"textbf","\\textmd":"textmd"},r5e={"\\textit":"textit","\\textup":"textup"},bG=o((t,e)=>{var r=t.font;if(r){if(vG[r])return e.withTextFontFamily(vG[r]);if(xG[r])return e.withTextFontWeight(xG[r]);if(r==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(r5e[r])},"optionsWithFont");Nt({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"text",mode:r.mode,body:gi(i),font:n}},htmlBuilder(t,e){var r=bG(t,e),n=$i(t.body,r,!0);return Fe.makeSpan(["mord","text"],n,r)},mathmlBuilder(t,e){var r=bG(t,e);return xh(t.body,r)}});Nt({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"underline",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=$r(t.body,e),n=Fe.makeLineSpan("underline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Fe.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:i},{type:"elem",elem:n},{type:"kern",size:3*i},{type:"elem",elem:r}]},e);return Fe.makeSpan(["mord","underline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("munder",[vn(t.body,e),r]);return n.setAttribute("accentunder","true"),n}});Nt({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"vcenter",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=$r(t.body,e),n=e.fontMetrics().axisHeight,i=.5*(r.height-n-(r.depth+n));return Fe.makeVList({positionType:"shift",positionData:i,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){return new dt.MathNode("mpadded",[vn(t.body,e)],["vcenter"])}});Nt({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(t,e,r){throw new pt("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(t,e){for(var r=TG(t),n=[],i=e.havingStyle(e.style.text()),a=0;at.body.replace(/ /g,t.star?"\u2423":"\xA0"),"makeVerb"),yh=FG,gV=`[ \r - ]`,n5e="\\\\[a-zA-Z@]+",i5e="\\\\[^\uD800-\uDFFF]",a5e="("+n5e+")"+gV+"*",s5e=`\\\\( -|[ \r ]+ -?)[ \r ]*`,J7="[\u0300-\u036F]",o5e=new RegExp(J7+"+$"),l5e="("+gV+"+)|"+(s5e+"|")+"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]"+(J7+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(J7+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+a5e)+("|"+i5e+")"),A3=class{static{o(this,"Lexer")}constructor(e,r){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=r,this.tokenRegex=new RegExp(l5e,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,r){this.catcodes[e]=r}lex(){var e=this.input,r=this.tokenRegex.lastIndex;if(r===e.length)return new _o("EOF",new Qs(this,r,r));var n=this.tokenRegex.exec(e);if(n===null||n.index!==r)throw new pt("Unexpected character: '"+e[r]+"'",new _o(e[r],new Qs(this,r,r+1)));var i=n[6]||n[3]||(n[2]?"\\ ":" ");if(this.catcodes[i]===14){var a=e.indexOf(` -`,this.tokenRegex.lastIndex);return a===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=a+1,this.lex()}return new _o(i,new Qs(this,r,this.tokenRegex.lastIndex))}},eA=class{static{o(this,"Namespace")}constructor(e,r){e===void 0&&(e={}),r===void 0&&(r={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=r,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new pt("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var r in e)e.hasOwnProperty(r)&&(e[r]==null?delete this.current[r]:this.current[r]=e[r])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,r,n){if(n===void 0&&(n=!1),n){for(var i=0;i0&&(this.undefStack[this.undefStack.length-1][e]=r)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}r==null?delete this.current[e]:this.current[e]=r}},c5e=aV;fe("\\noexpand",function(t){var e=t.popToken();return t.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});fe("\\expandafter",function(t){var e=t.popToken();return t.expandOnce(!0),{tokens:[e],numArgs:0}});fe("\\@firstoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[0],numArgs:0}});fe("\\@secondoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[1],numArgs:0}});fe("\\@ifnextchar",function(t){var e=t.consumeArgs(3);t.consumeSpaces();var r=t.future();return e[0].length===1&&e[0][0].text===r.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});fe("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");fe("\\TextOrMath",function(t){var e=t.consumeArgs(2);return t.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});wG={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};fe("\\char",function(t){var e=t.popToken(),r,n="";if(e.text==="'")r=8,e=t.popToken();else if(e.text==='"')r=16,e=t.popToken();else if(e.text==="`")if(e=t.popToken(),e.text[0]==="\\")n=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new pt("\\char` missing argument");n=e.text.charCodeAt(0)}else r=10;if(r){if(n=wG[e.text],n==null||n>=r)throw new pt("Invalid base-"+r+" digit "+e.text);for(var i;(i=wG[t.future().text])!=null&&i{var i=t.consumeArg().tokens;if(i.length!==1)throw new pt("\\newcommand's first argument must be a macro name");var a=i[0].text,s=t.isDefined(a);if(s&&!e)throw new pt("\\newcommand{"+a+"} attempting to redefine "+(a+"; use \\renewcommand"));if(!s&&!r)throw new pt("\\renewcommand{"+a+"} when command "+a+" does not yet exist; use \\newcommand");var l=0;if(i=t.consumeArg().tokens,i.length===1&&i[0].text==="["){for(var u="",h=t.expandNextToken();h.text!=="]"&&h.text!=="EOF";)u+=h.text,h=t.expandNextToken();if(!u.match(/^\s*[0-9]+\s*$/))throw new pt("Invalid number of arguments: "+u);l=parseInt(u),i=t.consumeArg().tokens}return s&&n||t.macros.set(a,{tokens:i,numArgs:l}),""},"newcommand");fe("\\newcommand",t=>gA(t,!1,!0,!1));fe("\\renewcommand",t=>gA(t,!0,!1,!1));fe("\\providecommand",t=>gA(t,!0,!0,!0));fe("\\message",t=>{var e=t.consumeArgs(1)[0];return console.log(e.reverse().map(r=>r.text).join("")),""});fe("\\errmessage",t=>{var e=t.consumeArgs(1)[0];return console.error(e.reverse().map(r=>r.text).join("")),""});fe("\\show",t=>{var e=t.popToken(),r=e.text;return console.log(e,t.macros.get(r),yh[r],An.math[r],An.text[r]),""});fe("\\bgroup","{");fe("\\egroup","}");fe("~","\\nobreakspace");fe("\\lq","`");fe("\\rq","'");fe("\\aa","\\r a");fe("\\AA","\\r A");fe("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xA9}");fe("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");fe("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xAE}");fe("\u212C","\\mathscr{B}");fe("\u2130","\\mathscr{E}");fe("\u2131","\\mathscr{F}");fe("\u210B","\\mathscr{H}");fe("\u2110","\\mathscr{I}");fe("\u2112","\\mathscr{L}");fe("\u2133","\\mathscr{M}");fe("\u211B","\\mathscr{R}");fe("\u212D","\\mathfrak{C}");fe("\u210C","\\mathfrak{H}");fe("\u2128","\\mathfrak{Z}");fe("\\Bbbk","\\Bbb{k}");fe("\xB7","\\cdotp");fe("\\llap","\\mathllap{\\textrm{#1}}");fe("\\rlap","\\mathrlap{\\textrm{#1}}");fe("\\clap","\\mathclap{\\textrm{#1}}");fe("\\mathstrut","\\vphantom{(}");fe("\\underbar","\\underline{\\text{#1}}");fe("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');fe("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}");fe("\\ne","\\neq");fe("\u2260","\\neq");fe("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}");fe("\u2209","\\notin");fe("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}");fe("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");fe("\u225A","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");fe("\u225B","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225B}}");fe("\u225D","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225D}}");fe("\u225E","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225E}}");fe("\u225F","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}");fe("\u27C2","\\perp");fe("\u203C","\\mathclose{!\\mkern-0.8mu!}");fe("\u220C","\\notni");fe("\u231C","\\ulcorner");fe("\u231D","\\urcorner");fe("\u231E","\\llcorner");fe("\u231F","\\lrcorner");fe("\xA9","\\copyright");fe("\xAE","\\textregistered");fe("\uFE0F","\\textregistered");fe("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');fe("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');fe("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');fe("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');fe("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");fe("\u22EE","\\vdots");fe("\\varGamma","\\mathit{\\Gamma}");fe("\\varDelta","\\mathit{\\Delta}");fe("\\varTheta","\\mathit{\\Theta}");fe("\\varLambda","\\mathit{\\Lambda}");fe("\\varXi","\\mathit{\\Xi}");fe("\\varPi","\\mathit{\\Pi}");fe("\\varSigma","\\mathit{\\Sigma}");fe("\\varUpsilon","\\mathit{\\Upsilon}");fe("\\varPhi","\\mathit{\\Phi}");fe("\\varPsi","\\mathit{\\Psi}");fe("\\varOmega","\\mathit{\\Omega}");fe("\\substack","\\begin{subarray}{c}#1\\end{subarray}");fe("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");fe("\\boxed","\\fbox{$\\displaystyle{#1}$}");fe("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");fe("\\implies","\\DOTSB\\;\\Longrightarrow\\;");fe("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");fe("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");fe("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");kG={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};fe("\\dots",function(t){var e="\\dotso",r=t.expandAfterFuture().text;return r in kG?e=kG[r]:(r.slice(0,4)==="\\not"||r in An.math&&Jt.contains(["bin","rel"],An.math[r].group))&&(e="\\dotsb"),e});yA={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};fe("\\dotso",function(t){var e=t.future().text;return e in yA?"\\ldots\\,":"\\ldots"});fe("\\dotsc",function(t){var e=t.future().text;return e in yA&&e!==","?"\\ldots\\,":"\\ldots"});fe("\\cdots",function(t){var e=t.future().text;return e in yA?"\\@cdots\\,":"\\@cdots"});fe("\\dotsb","\\cdots");fe("\\dotsm","\\cdots");fe("\\dotsi","\\!\\cdots");fe("\\dotsx","\\ldots\\,");fe("\\DOTSI","\\relax");fe("\\DOTSB","\\relax");fe("\\DOTSX","\\relax");fe("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");fe("\\,","\\tmspace+{3mu}{.1667em}");fe("\\thinspace","\\,");fe("\\>","\\mskip{4mu}");fe("\\:","\\tmspace+{4mu}{.2222em}");fe("\\medspace","\\:");fe("\\;","\\tmspace+{5mu}{.2777em}");fe("\\thickspace","\\;");fe("\\!","\\tmspace-{3mu}{.1667em}");fe("\\negthinspace","\\!");fe("\\negmedspace","\\tmspace-{4mu}{.2222em}");fe("\\negthickspace","\\tmspace-{5mu}{.277em}");fe("\\enspace","\\kern.5em ");fe("\\enskip","\\hskip.5em\\relax");fe("\\quad","\\hskip1em\\relax");fe("\\qquad","\\hskip2em\\relax");fe("\\tag","\\@ifstar\\tag@literal\\tag@paren");fe("\\tag@paren","\\tag@literal{({#1})}");fe("\\tag@literal",t=>{if(t.macros.get("\\df@tag"))throw new pt("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});fe("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");fe("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");fe("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");fe("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");fe("\\newline","\\\\\\relax");fe("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");yV=Et(Jl["Main-Regular"][84][1]-.7*Jl["Main-Regular"][65][1]);fe("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+yV+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");fe("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+yV+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");fe("\\hspace","\\@ifstar\\@hspacer\\@hspace");fe("\\@hspace","\\hskip #1\\relax");fe("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");fe("\\ordinarycolon",":");fe("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");fe("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');fe("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');fe("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');fe("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');fe("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');fe("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');fe("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');fe("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');fe("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');fe("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');fe("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');fe("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');fe("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');fe("\u2237","\\dblcolon");fe("\u2239","\\eqcolon");fe("\u2254","\\coloneqq");fe("\u2255","\\eqqcolon");fe("\u2A74","\\Coloneqq");fe("\\ratio","\\vcentcolon");fe("\\coloncolon","\\dblcolon");fe("\\colonequals","\\coloneqq");fe("\\coloncolonequals","\\Coloneqq");fe("\\equalscolon","\\eqqcolon");fe("\\equalscoloncolon","\\Eqqcolon");fe("\\colonminus","\\coloneq");fe("\\coloncolonminus","\\Coloneq");fe("\\minuscolon","\\eqcolon");fe("\\minuscoloncolon","\\Eqcolon");fe("\\coloncolonapprox","\\Colonapprox");fe("\\coloncolonsim","\\Colonsim");fe("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");fe("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");fe("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");fe("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");fe("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");fe("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");fe("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");fe("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");fe("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");fe("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}");fe("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}");fe("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}");fe("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}");fe("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}");fe("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}");fe("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}");fe("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}");fe("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}");fe("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}");fe("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228A}");fe("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2ACB}");fe("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228B}");fe("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2ACC}");fe("\\imath","\\html@mathml{\\@imath}{\u0131}");fe("\\jmath","\\html@mathml{\\@jmath}{\u0237}");fe("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27E6}}");fe("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27E7}}");fe("\u27E6","\\llbracket");fe("\u27E7","\\rrbracket");fe("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}");fe("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}");fe("\u2983","\\lBrace");fe("\u2984","\\rBrace");fe("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29B5}}");fe("\u29B5","\\minuso");fe("\\darr","\\downarrow");fe("\\dArr","\\Downarrow");fe("\\Darr","\\Downarrow");fe("\\lang","\\langle");fe("\\rang","\\rangle");fe("\\uarr","\\uparrow");fe("\\uArr","\\Uparrow");fe("\\Uarr","\\Uparrow");fe("\\N","\\mathbb{N}");fe("\\R","\\mathbb{R}");fe("\\Z","\\mathbb{Z}");fe("\\alef","\\aleph");fe("\\alefsym","\\aleph");fe("\\Alpha","\\mathrm{A}");fe("\\Beta","\\mathrm{B}");fe("\\bull","\\bullet");fe("\\Chi","\\mathrm{X}");fe("\\clubs","\\clubsuit");fe("\\cnums","\\mathbb{C}");fe("\\Complex","\\mathbb{C}");fe("\\Dagger","\\ddagger");fe("\\diamonds","\\diamondsuit");fe("\\empty","\\emptyset");fe("\\Epsilon","\\mathrm{E}");fe("\\Eta","\\mathrm{H}");fe("\\exist","\\exists");fe("\\harr","\\leftrightarrow");fe("\\hArr","\\Leftrightarrow");fe("\\Harr","\\Leftrightarrow");fe("\\hearts","\\heartsuit");fe("\\image","\\Im");fe("\\infin","\\infty");fe("\\Iota","\\mathrm{I}");fe("\\isin","\\in");fe("\\Kappa","\\mathrm{K}");fe("\\larr","\\leftarrow");fe("\\lArr","\\Leftarrow");fe("\\Larr","\\Leftarrow");fe("\\lrarr","\\leftrightarrow");fe("\\lrArr","\\Leftrightarrow");fe("\\Lrarr","\\Leftrightarrow");fe("\\Mu","\\mathrm{M}");fe("\\natnums","\\mathbb{N}");fe("\\Nu","\\mathrm{N}");fe("\\Omicron","\\mathrm{O}");fe("\\plusmn","\\pm");fe("\\rarr","\\rightarrow");fe("\\rArr","\\Rightarrow");fe("\\Rarr","\\Rightarrow");fe("\\real","\\Re");fe("\\reals","\\mathbb{R}");fe("\\Reals","\\mathbb{R}");fe("\\Rho","\\mathrm{P}");fe("\\sdot","\\cdot");fe("\\sect","\\S");fe("\\spades","\\spadesuit");fe("\\sub","\\subset");fe("\\sube","\\subseteq");fe("\\supe","\\supseteq");fe("\\Tau","\\mathrm{T}");fe("\\thetasym","\\vartheta");fe("\\weierp","\\wp");fe("\\Zeta","\\mathrm{Z}");fe("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");fe("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");fe("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");fe("\\bra","\\mathinner{\\langle{#1}|}");fe("\\ket","\\mathinner{|{#1}\\rangle}");fe("\\braket","\\mathinner{\\langle{#1}\\rangle}");fe("\\Bra","\\left\\langle#1\\right|");fe("\\Ket","\\left|#1\\right\\rangle");vV=o(t=>e=>{var r=e.consumeArg().tokens,n=e.consumeArg().tokens,i=e.consumeArg().tokens,a=e.consumeArg().tokens,s=e.macros.get("|"),l=e.macros.get("\\|");e.macros.beginGroup();var u=o(d=>p=>{t&&(p.macros.set("|",s),i.length&&p.macros.set("\\|",l));var m=d;if(!d&&i.length){var g=p.future();g.text==="|"&&(p.popToken(),m=!0)}return{tokens:m?i:n,numArgs:0}},"midMacro");e.macros.set("|",u(!1)),i.length&&e.macros.set("\\|",u(!0));var h=e.consumeArg().tokens,f=e.expandTokens([...a,...h,...r]);return e.macros.endGroup(),{tokens:f.reverse(),numArgs:0}},"braketHelper");fe("\\bra@ket",vV(!1));fe("\\bra@set",vV(!0));fe("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");fe("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");fe("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");fe("\\angln","{\\angl n}");fe("\\blue","\\textcolor{##6495ed}{#1}");fe("\\orange","\\textcolor{##ffa500}{#1}");fe("\\pink","\\textcolor{##ff00af}{#1}");fe("\\red","\\textcolor{##df0030}{#1}");fe("\\green","\\textcolor{##28ae7b}{#1}");fe("\\gray","\\textcolor{gray}{#1}");fe("\\purple","\\textcolor{##9d38bd}{#1}");fe("\\blueA","\\textcolor{##ccfaff}{#1}");fe("\\blueB","\\textcolor{##80f6ff}{#1}");fe("\\blueC","\\textcolor{##63d9ea}{#1}");fe("\\blueD","\\textcolor{##11accd}{#1}");fe("\\blueE","\\textcolor{##0c7f99}{#1}");fe("\\tealA","\\textcolor{##94fff5}{#1}");fe("\\tealB","\\textcolor{##26edd5}{#1}");fe("\\tealC","\\textcolor{##01d1c1}{#1}");fe("\\tealD","\\textcolor{##01a995}{#1}");fe("\\tealE","\\textcolor{##208170}{#1}");fe("\\greenA","\\textcolor{##b6ffb0}{#1}");fe("\\greenB","\\textcolor{##8af281}{#1}");fe("\\greenC","\\textcolor{##74cf70}{#1}");fe("\\greenD","\\textcolor{##1fab54}{#1}");fe("\\greenE","\\textcolor{##0d923f}{#1}");fe("\\goldA","\\textcolor{##ffd0a9}{#1}");fe("\\goldB","\\textcolor{##ffbb71}{#1}");fe("\\goldC","\\textcolor{##ff9c39}{#1}");fe("\\goldD","\\textcolor{##e07d10}{#1}");fe("\\goldE","\\textcolor{##a75a05}{#1}");fe("\\redA","\\textcolor{##fca9a9}{#1}");fe("\\redB","\\textcolor{##ff8482}{#1}");fe("\\redC","\\textcolor{##f9685d}{#1}");fe("\\redD","\\textcolor{##e84d39}{#1}");fe("\\redE","\\textcolor{##bc2612}{#1}");fe("\\maroonA","\\textcolor{##ffbde0}{#1}");fe("\\maroonB","\\textcolor{##ff92c6}{#1}");fe("\\maroonC","\\textcolor{##ed5fa6}{#1}");fe("\\maroonD","\\textcolor{##ca337c}{#1}");fe("\\maroonE","\\textcolor{##9e034e}{#1}");fe("\\purpleA","\\textcolor{##ddd7ff}{#1}");fe("\\purpleB","\\textcolor{##c6b9fc}{#1}");fe("\\purpleC","\\textcolor{##aa87ff}{#1}");fe("\\purpleD","\\textcolor{##7854ab}{#1}");fe("\\purpleE","\\textcolor{##543b78}{#1}");fe("\\mintA","\\textcolor{##f5f9e8}{#1}");fe("\\mintB","\\textcolor{##edf2df}{#1}");fe("\\mintC","\\textcolor{##e0e5cc}{#1}");fe("\\grayA","\\textcolor{##f6f7f7}{#1}");fe("\\grayB","\\textcolor{##f0f1f2}{#1}");fe("\\grayC","\\textcolor{##e3e5e6}{#1}");fe("\\grayD","\\textcolor{##d6d8da}{#1}");fe("\\grayE","\\textcolor{##babec2}{#1}");fe("\\grayF","\\textcolor{##888d93}{#1}");fe("\\grayG","\\textcolor{##626569}{#1}");fe("\\grayH","\\textcolor{##3b3e40}{#1}");fe("\\grayI","\\textcolor{##21242c}{#1}");fe("\\kaBlue","\\textcolor{##314453}{#1}");fe("\\kaGreen","\\textcolor{##71B307}{#1}");xV={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},tA=class{static{o(this,"MacroExpander")}constructor(e,r,n){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=r,this.expansionCount=0,this.feed(e),this.macros=new eA(c5e,r.macros),this.mode=n,this.stack=[]}feed(e){this.lexer=new A3(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var r,n,i;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;r=this.popToken(),{tokens:i,end:n}=this.consumeArg(["]"])}else({tokens:i,start:r,end:n}=this.consumeArg());return this.pushToken(new _o("EOF",n.loc)),this.pushTokens(i),r.range(n,"")}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var r=[],n=e&&e.length>0;n||this.consumeSpaces();var i=this.future(),a,s=0,l=0;do{if(a=this.popToken(),r.push(a),a.text==="{")++s;else if(a.text==="}"){if(--s,s===-1)throw new pt("Extra }",a)}else if(a.text==="EOF")throw new pt("Unexpected end of input in a macro argument, expected '"+(e&&n?e[l]:"}")+"'",a);if(e&&n)if((s===0||s===1&&e[l]==="{")&&a.text===e[l]){if(++l,l===e.length){r.splice(-l,l);break}}else l=0}while(s!==0||n);return i.text==="{"&&r[r.length-1].text==="}"&&(r.pop(),r.shift()),r.reverse(),{tokens:r,start:i,end:a}}consumeArgs(e,r){if(r){if(r.length!==e+1)throw new pt("The length of delimiters doesn't match the number of args!");for(var n=r[0],i=0;ithis.settings.maxExpand)throw new pt("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var r=this.popToken(),n=r.text,i=r.noexpand?null:this._getExpansion(n);if(i==null||e&&i.unexpandable){if(e&&i==null&&n[0]==="\\"&&!this.isDefined(n))throw new pt("Undefined control sequence: "+n);return this.pushToken(r),!1}this.countExpansion(1);var a=i.tokens,s=this.consumeArgs(i.numArgs,i.delimiters);if(i.numArgs){a=a.slice();for(var l=a.length-1;l>=0;--l){var u=a[l];if(u.text==="#"){if(l===0)throw new pt("Incomplete placeholder at end of macro body",u);if(u=a[--l],u.text==="#")a.splice(l+1,1);else if(/^[1-9]$/.test(u.text))a.splice(l,2,...s[+u.text-1]);else throw new pt("Not a valid argument number",u)}}}return this.pushTokens(a),a.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new _o(e)]):void 0}expandTokens(e){var r=[],n=this.stack.length;for(this.pushTokens(e);this.stack.length>n;)if(this.expandOnce(!0)===!1){var i=this.stack.pop();i.treatAsRelax&&(i.noexpand=!1,i.treatAsRelax=!1),r.push(i)}return this.countExpansion(r.length),r}expandMacroAsText(e){var r=this.expandMacro(e);return r&&r.map(n=>n.text).join("")}_getExpansion(e){var r=this.macros.get(e);if(r==null)return r;if(e.length===1){var n=this.lexer.catcodes[e];if(n!=null&&n!==13)return}var i=typeof r=="function"?r(this):r;if(typeof i=="string"){var a=0;if(i.indexOf("#")!==-1)for(var s=i.replace(/##/g,"");s.indexOf("#"+(a+1))!==-1;)++a;for(var l=new A3(i,this.settings),u=[],h=l.lex();h.text!=="EOF";)u.push(h),h=l.lex();u.reverse();var f={tokens:u,numArgs:a};return f}return i}isDefined(e){return this.macros.has(e)||yh.hasOwnProperty(e)||An.math.hasOwnProperty(e)||An.text.hasOwnProperty(e)||xV.hasOwnProperty(e)}isExpandable(e){var r=this.macros.get(e);return r!=null?typeof r=="string"||typeof r=="function"||!r.unexpandable:yh.hasOwnProperty(e)&&!yh[e].primitive}},EG=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,x3=Object.freeze({"\u208A":"+","\u208B":"-","\u208C":"=","\u208D":"(","\u208E":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1D62":"i","\u2C7C":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209A":"p","\u1D63":"r","\u209B":"s","\u209C":"t","\u1D64":"u","\u1D65":"v","\u2093":"x","\u1D66":"\u03B2","\u1D67":"\u03B3","\u1D68":"\u03C1","\u1D69":"\u03D5","\u1D6A":"\u03C7","\u207A":"+","\u207B":"-","\u207C":"=","\u207D":"(","\u207E":")","\u2070":"0","\xB9":"1","\xB2":"2","\xB3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1D2C":"A","\u1D2E":"B","\u1D30":"D","\u1D31":"E","\u1D33":"G","\u1D34":"H","\u1D35":"I","\u1D36":"J","\u1D37":"K","\u1D38":"L","\u1D39":"M","\u1D3A":"N","\u1D3C":"O","\u1D3E":"P","\u1D3F":"R","\u1D40":"T","\u1D41":"U","\u2C7D":"V","\u1D42":"W","\u1D43":"a","\u1D47":"b","\u1D9C":"c","\u1D48":"d","\u1D49":"e","\u1DA0":"f","\u1D4D":"g",\u02B0:"h","\u2071":"i",\u02B2:"j","\u1D4F":"k",\u02E1:"l","\u1D50":"m",\u207F:"n","\u1D52":"o","\u1D56":"p",\u02B3:"r",\u02E2:"s","\u1D57":"t","\u1D58":"u","\u1D5B":"v",\u02B7:"w",\u02E3:"x",\u02B8:"y","\u1DBB":"z","\u1D5D":"\u03B2","\u1D5E":"\u03B3","\u1D5F":"\u03B4","\u1D60":"\u03D5","\u1D61":"\u03C7","\u1DBF":"\u03B8"}),U7={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030C":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030A":{text:"\\r",math:"\\mathring"},"\u030B":{text:"\\H"},"\u0327":{text:"\\c"}},SG={\u00E1:"a\u0301",\u00E0:"a\u0300",\u00E4:"a\u0308",\u01DF:"a\u0308\u0304",\u00E3:"a\u0303",\u0101:"a\u0304",\u0103:"a\u0306",\u1EAF:"a\u0306\u0301",\u1EB1:"a\u0306\u0300",\u1EB5:"a\u0306\u0303",\u01CE:"a\u030C",\u00E2:"a\u0302",\u1EA5:"a\u0302\u0301",\u1EA7:"a\u0302\u0300",\u1EAB:"a\u0302\u0303",\u0227:"a\u0307",\u01E1:"a\u0307\u0304",\u00E5:"a\u030A",\u01FB:"a\u030A\u0301",\u1E03:"b\u0307",\u0107:"c\u0301",\u1E09:"c\u0327\u0301",\u010D:"c\u030C",\u0109:"c\u0302",\u010B:"c\u0307",\u00E7:"c\u0327",\u010F:"d\u030C",\u1E0B:"d\u0307",\u1E11:"d\u0327",\u00E9:"e\u0301",\u00E8:"e\u0300",\u00EB:"e\u0308",\u1EBD:"e\u0303",\u0113:"e\u0304",\u1E17:"e\u0304\u0301",\u1E15:"e\u0304\u0300",\u0115:"e\u0306",\u1E1D:"e\u0327\u0306",\u011B:"e\u030C",\u00EA:"e\u0302",\u1EBF:"e\u0302\u0301",\u1EC1:"e\u0302\u0300",\u1EC5:"e\u0302\u0303",\u0117:"e\u0307",\u0229:"e\u0327",\u1E1F:"f\u0307",\u01F5:"g\u0301",\u1E21:"g\u0304",\u011F:"g\u0306",\u01E7:"g\u030C",\u011D:"g\u0302",\u0121:"g\u0307",\u0123:"g\u0327",\u1E27:"h\u0308",\u021F:"h\u030C",\u0125:"h\u0302",\u1E23:"h\u0307",\u1E29:"h\u0327",\u00ED:"i\u0301",\u00EC:"i\u0300",\u00EF:"i\u0308",\u1E2F:"i\u0308\u0301",\u0129:"i\u0303",\u012B:"i\u0304",\u012D:"i\u0306",\u01D0:"i\u030C",\u00EE:"i\u0302",\u01F0:"j\u030C",\u0135:"j\u0302",\u1E31:"k\u0301",\u01E9:"k\u030C",\u0137:"k\u0327",\u013A:"l\u0301",\u013E:"l\u030C",\u013C:"l\u0327",\u1E3F:"m\u0301",\u1E41:"m\u0307",\u0144:"n\u0301",\u01F9:"n\u0300",\u00F1:"n\u0303",\u0148:"n\u030C",\u1E45:"n\u0307",\u0146:"n\u0327",\u00F3:"o\u0301",\u00F2:"o\u0300",\u00F6:"o\u0308",\u022B:"o\u0308\u0304",\u00F5:"o\u0303",\u1E4D:"o\u0303\u0301",\u1E4F:"o\u0303\u0308",\u022D:"o\u0303\u0304",\u014D:"o\u0304",\u1E53:"o\u0304\u0301",\u1E51:"o\u0304\u0300",\u014F:"o\u0306",\u01D2:"o\u030C",\u00F4:"o\u0302",\u1ED1:"o\u0302\u0301",\u1ED3:"o\u0302\u0300",\u1ED7:"o\u0302\u0303",\u022F:"o\u0307",\u0231:"o\u0307\u0304",\u0151:"o\u030B",\u1E55:"p\u0301",\u1E57:"p\u0307",\u0155:"r\u0301",\u0159:"r\u030C",\u1E59:"r\u0307",\u0157:"r\u0327",\u015B:"s\u0301",\u1E65:"s\u0301\u0307",\u0161:"s\u030C",\u1E67:"s\u030C\u0307",\u015D:"s\u0302",\u1E61:"s\u0307",\u015F:"s\u0327",\u1E97:"t\u0308",\u0165:"t\u030C",\u1E6B:"t\u0307",\u0163:"t\u0327",\u00FA:"u\u0301",\u00F9:"u\u0300",\u00FC:"u\u0308",\u01D8:"u\u0308\u0301",\u01DC:"u\u0308\u0300",\u01D6:"u\u0308\u0304",\u01DA:"u\u0308\u030C",\u0169:"u\u0303",\u1E79:"u\u0303\u0301",\u016B:"u\u0304",\u1E7B:"u\u0304\u0308",\u016D:"u\u0306",\u01D4:"u\u030C",\u00FB:"u\u0302",\u016F:"u\u030A",\u0171:"u\u030B",\u1E7D:"v\u0303",\u1E83:"w\u0301",\u1E81:"w\u0300",\u1E85:"w\u0308",\u0175:"w\u0302",\u1E87:"w\u0307",\u1E98:"w\u030A",\u1E8D:"x\u0308",\u1E8B:"x\u0307",\u00FD:"y\u0301",\u1EF3:"y\u0300",\u00FF:"y\u0308",\u1EF9:"y\u0303",\u0233:"y\u0304",\u0177:"y\u0302",\u1E8F:"y\u0307",\u1E99:"y\u030A",\u017A:"z\u0301",\u017E:"z\u030C",\u1E91:"z\u0302",\u017C:"z\u0307",\u00C1:"A\u0301",\u00C0:"A\u0300",\u00C4:"A\u0308",\u01DE:"A\u0308\u0304",\u00C3:"A\u0303",\u0100:"A\u0304",\u0102:"A\u0306",\u1EAE:"A\u0306\u0301",\u1EB0:"A\u0306\u0300",\u1EB4:"A\u0306\u0303",\u01CD:"A\u030C",\u00C2:"A\u0302",\u1EA4:"A\u0302\u0301",\u1EA6:"A\u0302\u0300",\u1EAA:"A\u0302\u0303",\u0226:"A\u0307",\u01E0:"A\u0307\u0304",\u00C5:"A\u030A",\u01FA:"A\u030A\u0301",\u1E02:"B\u0307",\u0106:"C\u0301",\u1E08:"C\u0327\u0301",\u010C:"C\u030C",\u0108:"C\u0302",\u010A:"C\u0307",\u00C7:"C\u0327",\u010E:"D\u030C",\u1E0A:"D\u0307",\u1E10:"D\u0327",\u00C9:"E\u0301",\u00C8:"E\u0300",\u00CB:"E\u0308",\u1EBC:"E\u0303",\u0112:"E\u0304",\u1E16:"E\u0304\u0301",\u1E14:"E\u0304\u0300",\u0114:"E\u0306",\u1E1C:"E\u0327\u0306",\u011A:"E\u030C",\u00CA:"E\u0302",\u1EBE:"E\u0302\u0301",\u1EC0:"E\u0302\u0300",\u1EC4:"E\u0302\u0303",\u0116:"E\u0307",\u0228:"E\u0327",\u1E1E:"F\u0307",\u01F4:"G\u0301",\u1E20:"G\u0304",\u011E:"G\u0306",\u01E6:"G\u030C",\u011C:"G\u0302",\u0120:"G\u0307",\u0122:"G\u0327",\u1E26:"H\u0308",\u021E:"H\u030C",\u0124:"H\u0302",\u1E22:"H\u0307",\u1E28:"H\u0327",\u00CD:"I\u0301",\u00CC:"I\u0300",\u00CF:"I\u0308",\u1E2E:"I\u0308\u0301",\u0128:"I\u0303",\u012A:"I\u0304",\u012C:"I\u0306",\u01CF:"I\u030C",\u00CE:"I\u0302",\u0130:"I\u0307",\u0134:"J\u0302",\u1E30:"K\u0301",\u01E8:"K\u030C",\u0136:"K\u0327",\u0139:"L\u0301",\u013D:"L\u030C",\u013B:"L\u0327",\u1E3E:"M\u0301",\u1E40:"M\u0307",\u0143:"N\u0301",\u01F8:"N\u0300",\u00D1:"N\u0303",\u0147:"N\u030C",\u1E44:"N\u0307",\u0145:"N\u0327",\u00D3:"O\u0301",\u00D2:"O\u0300",\u00D6:"O\u0308",\u022A:"O\u0308\u0304",\u00D5:"O\u0303",\u1E4C:"O\u0303\u0301",\u1E4E:"O\u0303\u0308",\u022C:"O\u0303\u0304",\u014C:"O\u0304",\u1E52:"O\u0304\u0301",\u1E50:"O\u0304\u0300",\u014E:"O\u0306",\u01D1:"O\u030C",\u00D4:"O\u0302",\u1ED0:"O\u0302\u0301",\u1ED2:"O\u0302\u0300",\u1ED6:"O\u0302\u0303",\u022E:"O\u0307",\u0230:"O\u0307\u0304",\u0150:"O\u030B",\u1E54:"P\u0301",\u1E56:"P\u0307",\u0154:"R\u0301",\u0158:"R\u030C",\u1E58:"R\u0307",\u0156:"R\u0327",\u015A:"S\u0301",\u1E64:"S\u0301\u0307",\u0160:"S\u030C",\u1E66:"S\u030C\u0307",\u015C:"S\u0302",\u1E60:"S\u0307",\u015E:"S\u0327",\u0164:"T\u030C",\u1E6A:"T\u0307",\u0162:"T\u0327",\u00DA:"U\u0301",\u00D9:"U\u0300",\u00DC:"U\u0308",\u01D7:"U\u0308\u0301",\u01DB:"U\u0308\u0300",\u01D5:"U\u0308\u0304",\u01D9:"U\u0308\u030C",\u0168:"U\u0303",\u1E78:"U\u0303\u0301",\u016A:"U\u0304",\u1E7A:"U\u0304\u0308",\u016C:"U\u0306",\u01D3:"U\u030C",\u00DB:"U\u0302",\u016E:"U\u030A",\u0170:"U\u030B",\u1E7C:"V\u0303",\u1E82:"W\u0301",\u1E80:"W\u0300",\u1E84:"W\u0308",\u0174:"W\u0302",\u1E86:"W\u0307",\u1E8C:"X\u0308",\u1E8A:"X\u0307",\u00DD:"Y\u0301",\u1EF2:"Y\u0300",\u0178:"Y\u0308",\u1EF8:"Y\u0303",\u0232:"Y\u0304",\u0176:"Y\u0302",\u1E8E:"Y\u0307",\u0179:"Z\u0301",\u017D:"Z\u030C",\u1E90:"Z\u0302",\u017B:"Z\u0307",\u03AC:"\u03B1\u0301",\u1F70:"\u03B1\u0300",\u1FB1:"\u03B1\u0304",\u1FB0:"\u03B1\u0306",\u03AD:"\u03B5\u0301",\u1F72:"\u03B5\u0300",\u03AE:"\u03B7\u0301",\u1F74:"\u03B7\u0300",\u03AF:"\u03B9\u0301",\u1F76:"\u03B9\u0300",\u03CA:"\u03B9\u0308",\u0390:"\u03B9\u0308\u0301",\u1FD2:"\u03B9\u0308\u0300",\u1FD1:"\u03B9\u0304",\u1FD0:"\u03B9\u0306",\u03CC:"\u03BF\u0301",\u1F78:"\u03BF\u0300",\u03CD:"\u03C5\u0301",\u1F7A:"\u03C5\u0300",\u03CB:"\u03C5\u0308",\u03B0:"\u03C5\u0308\u0301",\u1FE2:"\u03C5\u0308\u0300",\u1FE1:"\u03C5\u0304",\u1FE0:"\u03C5\u0306",\u03CE:"\u03C9\u0301",\u1F7C:"\u03C9\u0300",\u038E:"\u03A5\u0301",\u1FEA:"\u03A5\u0300",\u03AB:"\u03A5\u0308",\u1FE9:"\u03A5\u0304",\u1FE8:"\u03A5\u0306",\u038F:"\u03A9\u0301",\u1FFA:"\u03A9\u0300"},_3=class t{static{o(this,"Parser")}constructor(e,r){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new tA(e,r,this.mode),this.settings=r,this.leftrightDepth=0}expect(e,r){if(r===void 0&&(r=!0),this.fetch().text!==e)throw new pt("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());r&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var r=this.nextToken;this.consume(),this.gullet.pushToken(new _o("}")),this.gullet.pushTokens(e);var n=this.parseExpression(!1);return this.expect("}"),this.nextToken=r,n}parseExpression(e,r){for(var n=[];;){this.mode==="math"&&this.consumeSpaces();var i=this.fetch();if(t.endOfExpression.indexOf(i.text)!==-1||r&&i.text===r||e&&yh[i.text]&&yh[i.text].infix)break;var a=this.parseAtom(r);if(a){if(a.type==="internal")continue}else break;n.push(a)}return this.mode==="text"&&this.formLigatures(n),this.handleInfixNodes(n)}handleInfixNodes(e){for(var r=-1,n,i=0;i=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+r[0]+'" used in math mode',e);var l=An[this.mode][r].group,u=Qs.range(e),h;if(e3e.hasOwnProperty(l)){var f=l;h={type:"atom",mode:this.mode,family:f,loc:u,text:r}}else h={type:l,mode:this.mode,loc:u,text:r};s=h}else if(r.charCodeAt(0)>=128)this.settings.strict&&(AG(r.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+r[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+r[0]+'"'+(" ("+r.charCodeAt(0)+")"),e)),s={type:"textord",mode:"text",loc:Qs.range(e),text:r};else return null;if(this.consume(),a)for(var d=0;d{e instanceof Element&&e.tagName==="A"&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")??"")}),mh.addHook("afterSanitizeAttributes",e=>{e instanceof Element&&e.tagName==="A"&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)??""),e.removeAttribute(t),e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener"))})}var ud,h5e,f5e,LV,_V,wr,p5e,m5e,g5e,y5e,RV,mu,dr,v5e,x5e,ic,bA,b5e,T5e,DV,P3,yi,hd,Th,Ze,pr=N(()=>{"use strict";L7();ud=//gi,h5e=o(t=>t?RV(t).replace(/\\n/g,"#br#").split("#br#"):[""],"getRows"),f5e=(()=>{let t=!1;return()=>{t||(d5e(),t=!0)}})();o(d5e,"setupDompurifyHooks");LV=o(t=>(f5e(),mh.sanitize(t)),"removeScript"),_V=o((t,e)=>{if(e.flowchart?.htmlLabels!==!1){let r=e.securityLevel;r==="antiscript"||r==="strict"?t=LV(t):r!=="loose"&&(t=RV(t),t=t.replace(//g,">"),t=t.replace(/=/g,"="),t=y5e(t))}return t},"sanitizeMore"),wr=o((t,e)=>t&&(e.dompurifyConfig?t=mh.sanitize(_V(t,e),e.dompurifyConfig).toString():t=mh.sanitize(_V(t,e),{FORBID_TAGS:["style"]}).toString(),t),"sanitizeText"),p5e=o((t,e)=>typeof t=="string"?wr(t,e):t.flat().map(r=>wr(r,e)),"sanitizeTextOrArray"),m5e=o(t=>ud.test(t),"hasBreaks"),g5e=o(t=>t.split(ud),"splitBreaks"),y5e=o(t=>t.replace(/#br#/g,"
    "),"placeholderToBreak"),RV=o(t=>t.replace(ud,"#br#"),"breakToPlaceholder"),mu=o(t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=CSS.escape(e)),e},"getUrl"),dr=o(t=>!(t===!1||["false","null","0"].includes(String(t).trim().toLowerCase())),"evaluate"),v5e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.max(...e)},"getMax"),x5e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.min(...e)},"getMin"),ic=o(function(t){let e=t.split(/(,)/),r=[];for(let n=0;n0&&n+1Math.max(0,t.split(e).length-1),"countOccurrence"),b5e=o((t,e)=>{let r=bA(t,"~"),n=bA(e,"~");return r===1&&n===1},"shouldCombineSets"),T5e=o(t=>{let e=bA(t,"~"),r=!1;if(e<=1)return t;e%2!==0&&t.startsWith("~")&&(t=t.substring(1),r=!0);let n=[...t],i=n.indexOf("~"),a=n.lastIndexOf("~");for(;i!==-1&&a!==-1&&i!==a;)n[i]="<",n[a]=">",i=n.indexOf("~"),a=n.lastIndexOf("~");return r&&n.unshift("~"),n.join("")},"processSet"),DV=o(()=>window.MathMLElement!==void 0,"isMathMLSupported"),P3=/\$\$(.*)\$\$/g,yi=o(t=>(t.match(P3)?.length??0)>0,"hasKatex"),hd=o(async(t,e)=>{t=await Th(t,e);let r=document.createElement("div");r.innerHTML=t,r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0",document.querySelector("body")?.insertAdjacentElement("beforeend",r);let i={width:r.clientWidth,height:r.clientHeight};return r.remove(),i},"calculateMathMLDimensions"),Th=o(async(t,e)=>{if(!yi(t))return t;if(!(DV()||e.legacyMathML||e.forceLegacyMathML))return t.replace(P3,"MathML is unsupported in this environment.");{let{default:r}=await Promise.resolve().then(()=>(AV(),CV)),n=e.forceLegacyMathML||!DV()&&e.legacyMathML?"htmlAndMathml":"mathml";return t.split(ud).map(i=>yi(i)?`

    ${i}
    `:`
    ${i}
    `).join("").replace(P3,(i,a)=>r.renderToString(a,{throwOnError:!0,displayMode:!0,output:n}).replace(/\n/g," ").replace(//g,""))}return t.replace(P3,"Katex is not supported in @mermaid-js/tiny. Please use the full mermaid library.")},"renderKatex"),Ze={getRows:h5e,sanitizeText:wr,sanitizeTextOrArray:p5e,hasBreaks:m5e,splitBreaks:g5e,lineBreakRegex:ud,removeScript:LV,getUrl:mu,evaluate:dr,getMax:v5e,getMin:x5e}});var w5e,k5e,fn,Lo,xi=N(()=>{"use strict";yt();w5e=o(function(t,e){for(let r of e)t.attr(r[0],r[1])},"d3Attrs"),k5e=o(function(t,e,r){let n=new Map;return r?(n.set("width","100%"),n.set("style",`max-width: ${e}px;`)):(n.set("height",t),n.set("width",e)),n},"calculateSvgSizeAttrs"),fn=o(function(t,e,r,n){let i=k5e(e,r,n);w5e(t,i)},"configureSvgSize"),Lo=o(function(t,e,r,n){let i=e.node().getBBox(),a=i.width,s=i.height;X.info(`SVG bounds: ${a}x${s}`,i);let l=0,u=0;X.info(`Graph bounds: ${l}x${u}`,t),l=a+r*2,u=s+r*2,X.info(`Calculated bounds: ${l}x${u}`),fn(e,u,l,n);let h=`${i.x-r} ${i.y-r} ${i.width+2*r} ${i.height+2*r}`;e.attr("viewBox",h)},"setupGraphViewbox")});var B3,E5e,NV,MV,TA=N(()=>{"use strict";yt();B3={},E5e=o((t,e,r)=>{let n="";return t in B3&&B3[t]?n=B3[t](r):X.warn(`No theme found for ${t}`),` & { - font-family: ${r.fontFamily}; - font-size: ${r.fontSize}; - fill: ${r.textColor} - } - @keyframes edge-animation-frame { - from { - stroke-dashoffset: 0; - } - } - @keyframes dash { - to { - stroke-dashoffset: 0; - } - } - & .edge-animation-slow { - stroke-dasharray: 9,5 !important; - stroke-dashoffset: 900; - animation: dash 50s linear infinite; - stroke-linecap: round; - } - & .edge-animation-fast { - stroke-dasharray: 9,5 !important; - stroke-dashoffset: 900; - animation: dash 20s linear infinite; - stroke-linecap: round; - } - /* Classes common for multiple diagrams */ - - & .error-icon { - fill: ${r.errorBkgColor}; - } - & .error-text { - fill: ${r.errorTextColor}; - stroke: ${r.errorTextColor}; - } - - & .edge-thickness-normal { - stroke-width: 1px; - } - & .edge-thickness-thick { - stroke-width: 3.5px - } - & .edge-pattern-solid { - stroke-dasharray: 0; - } - & .edge-thickness-invisible { - stroke-width: 0; - fill: none; - } - & .edge-pattern-dashed{ - stroke-dasharray: 3; - } - .edge-pattern-dotted { - stroke-dasharray: 2; - } - - & .marker { - fill: ${r.lineColor}; - stroke: ${r.lineColor}; - } - & .marker.cross { - stroke: ${r.lineColor}; - } - - & svg { - font-family: ${r.fontFamily}; - font-size: ${r.fontSize}; - } - & p { - margin: 0 - } - - ${n} - - ${e} -`},"getStyles"),NV=o((t,e)=>{e!==void 0&&(B3[t]=e)},"addStylesForDiagram"),MV=E5e});var rv={};ur(rv,{clear:()=>kr,getAccDescription:()=>Rr,getAccTitle:()=>Dr,getDiagramTitle:()=>Nr,setAccDescription:()=>Lr,setAccTitle:()=>Ar,setDiagramTitle:()=>Or});var wA,kA,EA,SA,kr,Ar,Dr,Lr,Rr,Or,Nr,ci=N(()=>{"use strict";pr();mi();wA="",kA="",EA="",SA=o(t=>wr(t,tr()),"sanitizeText"),kr=o(()=>{wA="",EA="",kA=""},"clear"),Ar=o(t=>{wA=SA(t).replace(/^\s+/g,"")},"setAccTitle"),Dr=o(()=>wA,"getAccTitle"),Lr=o(t=>{EA=SA(t).replace(/\n\s+/g,` -`)},"setAccDescription"),Rr=o(()=>EA,"getAccDescription"),Or=o(t=>{kA=SA(t)},"setDiagramTitle"),Nr=o(()=>kA,"getDiagramTitle")});var IV,S5e,me,nv,$3,fd,AA,C5e,F3,dd,iv,CA,Gt=N(()=>{"use strict";rd();yt();mi();pr();xi();TA();ci();IV=X,S5e=Dy,me=tr,nv=a3,$3=ph,fd=o(t=>wr(t,me()),"sanitizeText"),AA=Lo,C5e=o(()=>rv,"getCommonDb"),F3={},dd=o((t,e,r)=>{F3[t]&&IV.warn(`Diagram with id ${t} already registered. Overwriting.`),F3[t]=e,r&&i7(t,r),NV(t,e.styles),e.injectUtils?.(IV,S5e,me,fd,AA,C5e(),()=>{})},"registerDiagram"),iv=o(t=>{if(t in F3)return F3[t];throw new CA(t)},"getDiagram"),CA=class extends Error{static{o(this,"DiagramNotFoundError")}constructor(e){super(`Diagram ${e} not found.`)}}});var ml,wh,is,pl,ac,av,_A,DA,z3,G3,OV,A5e,_5e,D5e,L5e,R5e,N5e,M5e,I5e,O5e,P5e,B5e,F5e,$5e,z5e,G5e,V5e,U5e,PV,H5e,W5e,BV,q5e,Y5e,X5e,j5e,kh,K5e,Q5e,Z5e,J5e,eTe,sv,LA=N(()=>{"use strict";Gt();pr();ci();ml=[],wh=[""],is="global",pl="",ac=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],av=[],_A="",DA=!1,z3=4,G3=2,A5e=o(function(){return OV},"getC4Type"),_5e=o(function(t){OV=wr(t,me())},"setC4Type"),D5e=o(function(t,e,r,n,i,a,s,l,u){if(t==null||e===void 0||e===null||r===void 0||r===null||n===void 0||n===null)return;let h={},f=av.find(d=>d.from===e&&d.to===r);if(f?h=f:av.push(h),h.type=t,h.from=e,h.to=r,h.label={text:n},i==null)h.techn={text:""};else if(typeof i=="object"){let[d,p]=Object.entries(i)[0];h[d]={text:p}}else h.techn={text:i};if(a==null)h.descr={text:""};else if(typeof a=="object"){let[d,p]=Object.entries(a)[0];h[d]={text:p}}else h.descr={text:a};if(typeof s=="object"){let[d,p]=Object.entries(s)[0];h[d]=p}else h.sprite=s;if(typeof l=="object"){let[d,p]=Object.entries(l)[0];h[d]=p}else h.tags=l;if(typeof u=="object"){let[d,p]=Object.entries(u)[0];h[d]=p}else h.link=u;h.wrap=kh()},"addRel"),L5e=o(function(t,e,r,n,i,a,s){if(e===null||r===null)return;let l={},u=ml.find(h=>h.alias===e);if(u&&e===u.alias?l=u:(l.alias=e,ml.push(l)),r==null?l.label={text:""}:l.label={text:r},n==null)l.descr={text:""};else if(typeof n=="object"){let[h,f]=Object.entries(n)[0];l[h]={text:f}}else l.descr={text:n};if(typeof i=="object"){let[h,f]=Object.entries(i)[0];l[h]=f}else l.sprite=i;if(typeof a=="object"){let[h,f]=Object.entries(a)[0];l[h]=f}else l.tags=a;if(typeof s=="object"){let[h,f]=Object.entries(s)[0];l[h]=f}else l.link=s;l.typeC4Shape={text:t},l.parentBoundary=is,l.wrap=kh()},"addPersonOrSystem"),R5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ml.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ml.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=kh(),u.typeC4Shape={text:t},u.parentBoundary=is},"addContainer"),N5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ml.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ml.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=kh(),u.typeC4Shape={text:t},u.parentBoundary=is},"addComponent"),M5e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=ac.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,ac.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"system"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=is,a.wrap=kh(),pl=is,is=t,wh.push(pl)},"addPersonOrSystemBoundary"),I5e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=ac.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,ac.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"container"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=is,a.wrap=kh(),pl=is,is=t,wh.push(pl)},"addContainerBoundary"),O5e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ac.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ac.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.type={text:"node"};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.type={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.nodeType=t,u.parentBoundary=is,u.wrap=kh(),pl=is,is=e,wh.push(pl)},"addDeploymentNode"),P5e=o(function(){is=pl,wh.pop(),pl=wh.pop(),wh.push(pl)},"popBoundaryParseStack"),B5e=o(function(t,e,r,n,i,a,s,l,u,h,f){let d=ml.find(p=>p.alias===e);if(!(d===void 0&&(d=ac.find(p=>p.alias===e),d===void 0))){if(r!=null)if(typeof r=="object"){let[p,m]=Object.entries(r)[0];d[p]=m}else d.bgColor=r;if(n!=null)if(typeof n=="object"){let[p,m]=Object.entries(n)[0];d[p]=m}else d.fontColor=n;if(i!=null)if(typeof i=="object"){let[p,m]=Object.entries(i)[0];d[p]=m}else d.borderColor=i;if(a!=null)if(typeof a=="object"){let[p,m]=Object.entries(a)[0];d[p]=m}else d.shadowing=a;if(s!=null)if(typeof s=="object"){let[p,m]=Object.entries(s)[0];d[p]=m}else d.shape=s;if(l!=null)if(typeof l=="object"){let[p,m]=Object.entries(l)[0];d[p]=m}else d.sprite=l;if(u!=null)if(typeof u=="object"){let[p,m]=Object.entries(u)[0];d[p]=m}else d.techn=u;if(h!=null)if(typeof h=="object"){let[p,m]=Object.entries(h)[0];d[p]=m}else d.legendText=h;if(f!=null)if(typeof f=="object"){let[p,m]=Object.entries(f)[0];d[p]=m}else d.legendSprite=f}},"updateElStyle"),F5e=o(function(t,e,r,n,i,a,s){let l=av.find(u=>u.from===e&&u.to===r);if(l!==void 0){if(n!=null)if(typeof n=="object"){let[u,h]=Object.entries(n)[0];l[u]=h}else l.textColor=n;if(i!=null)if(typeof i=="object"){let[u,h]=Object.entries(i)[0];l[u]=h}else l.lineColor=i;if(a!=null)if(typeof a=="object"){let[u,h]=Object.entries(a)[0];l[u]=parseInt(h)}else l.offsetX=parseInt(a);if(s!=null)if(typeof s=="object"){let[u,h]=Object.entries(s)[0];l[u]=parseInt(h)}else l.offsetY=parseInt(s)}},"updateRelStyle"),$5e=o(function(t,e,r){let n=z3,i=G3;if(typeof e=="object"){let a=Object.values(e)[0];n=parseInt(a)}else n=parseInt(e);if(typeof r=="object"){let a=Object.values(r)[0];i=parseInt(a)}else i=parseInt(r);n>=1&&(z3=n),i>=1&&(G3=i)},"updateLayoutConfig"),z5e=o(function(){return z3},"getC4ShapeInRow"),G5e=o(function(){return G3},"getC4BoundaryInRow"),V5e=o(function(){return is},"getCurrentBoundaryParse"),U5e=o(function(){return pl},"getParentBoundaryParse"),PV=o(function(t){return t==null?ml:ml.filter(e=>e.parentBoundary===t)},"getC4ShapeArray"),H5e=o(function(t){return ml.find(e=>e.alias===t)},"getC4Shape"),W5e=o(function(t){return Object.keys(PV(t))},"getC4ShapeKeys"),BV=o(function(t){return t==null?ac:ac.filter(e=>e.parentBoundary===t)},"getBoundaries"),q5e=BV,Y5e=o(function(){return av},"getRels"),X5e=o(function(){return _A},"getTitle"),j5e=o(function(t){DA=t},"setWrap"),kh=o(function(){return DA},"autoWrap"),K5e=o(function(){ml=[],ac=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],pl="",is="global",wh=[""],av=[],wh=[""],_A="",DA=!1,z3=4,G3=2},"clear"),Q5e={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},Z5e={FILLED:0,OPEN:1},J5e={LEFTOF:0,RIGHTOF:1,OVER:2},eTe=o(function(t){_A=wr(t,me())},"setTitle"),sv={addPersonOrSystem:L5e,addPersonOrSystemBoundary:M5e,addContainer:R5e,addContainerBoundary:I5e,addComponent:N5e,addDeploymentNode:O5e,popBoundaryParseStack:P5e,addRel:D5e,updateElStyle:B5e,updateRelStyle:F5e,updateLayoutConfig:$5e,autoWrap:kh,setWrap:j5e,getC4ShapeArray:PV,getC4Shape:H5e,getC4ShapeKeys:W5e,getBoundaries:BV,getBoundarys:q5e,getCurrentBoundaryParse:V5e,getParentBoundaryParse:U5e,getRels:Y5e,getTitle:X5e,getC4Type:A5e,getC4ShapeInRow:z5e,getC4BoundaryInRow:G5e,setAccTitle:Ar,getAccTitle:Dr,getAccDescription:Rr,setAccDescription:Lr,getConfig:o(()=>me().c4,"getConfig"),clear:K5e,LINETYPE:Q5e,ARROWTYPE:Z5e,PLACEMENT:J5e,setTitle:eTe,setC4Type:_5e}});function pd(t,e){return t==null||e==null?NaN:te?1:t>=e?0:NaN}var RA=N(()=>{"use strict";o(pd,"ascending")});function NA(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}var FV=N(()=>{"use strict";o(NA,"descending")});function md(t){let e,r,n;t.length!==2?(e=pd,r=o((l,u)=>pd(t(l),u),"compare2"),n=o((l,u)=>t(l)-u,"delta")):(e=t===pd||t===NA?t:tTe,r=t,n=t);function i(l,u,h=0,f=l.length){if(h>>1;r(l[d],u)<0?h=d+1:f=d}while(h>>1;r(l[d],u)<=0?h=d+1:f=d}while(hh&&n(l[d-1],u)>-n(l[d],u)?d-1:d}return o(s,"center"),{left:i,center:s,right:a}}function tTe(){return 0}var MA=N(()=>{"use strict";RA();FV();o(md,"bisector");o(tTe,"zero")});function IA(t){return t===null?NaN:+t}var $V=N(()=>{"use strict";o(IA,"number")});var zV,GV,rTe,nTe,OA,VV=N(()=>{"use strict";RA();MA();$V();zV=md(pd),GV=zV.right,rTe=zV.left,nTe=md(IA).center,OA=GV});function UV({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):r}function iTe({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function aTe({_intern:t,_key:e},r){let n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function sTe(t){return t!==null&&typeof t=="object"?t.valueOf():t}var C0,HV=N(()=>{"use strict";C0=class extends Map{static{o(this,"InternMap")}constructor(e,r=sTe){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(let[n,i]of e)this.set(n,i)}get(e){return super.get(UV(this,e))}has(e){return super.has(UV(this,e))}set(e,r){return super.set(iTe(this,e),r)}delete(e){return super.delete(aTe(this,e))}};o(UV,"intern_get");o(iTe,"intern_set");o(aTe,"intern_delete");o(sTe,"keyof")});function V3(t,e,r){let n=(e-t)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),s=a>=oTe?10:a>=lTe?5:a>=cTe?2:1,l,u,h;return i<0?(h=Math.pow(10,-i)/s,l=Math.round(t*h),u=Math.round(e*h),l/he&&--u,h=-h):(h=Math.pow(10,i)*s,l=Math.round(t/h),u=Math.round(e/h),l*he&&--u),u0))return[];if(t===e)return[t];let n=e=i))return[];let l=a-i+1,u=new Array(l);if(n)if(s<0)for(let h=0;h{"use strict";oTe=Math.sqrt(50),lTe=Math.sqrt(10),cTe=Math.sqrt(2);o(V3,"tickSpec");o(U3,"ticks");o(ov,"tickIncrement");o(A0,"tickStep")});function H3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}var qV=N(()=>{"use strict";o(H3,"max")});function W3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var YV=N(()=>{"use strict";o(W3,"min")});function q3(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((e-t)/r))|0,a=new Array(i);++n{"use strict";o(q3,"range")});var Eh=N(()=>{"use strict";VV();MA();qV();YV();XV();WV();HV()});function PA(t){return t}var jV=N(()=>{"use strict";o(PA,"default")});function uTe(t){return"translate("+t+",0)"}function hTe(t){return"translate(0,"+t+")"}function fTe(t){return e=>+t(e)}function dTe(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function pTe(){return!this.__axis}function QV(t,e){var r=[],n=null,i=null,a=6,s=6,l=3,u=typeof window<"u"&&window.devicePixelRatio>1?0:.5,h=t===X3||t===Y3?-1:1,f=t===Y3||t===BA?"x":"y",d=t===X3||t===FA?uTe:hTe;function p(m){var g=n??(e.ticks?e.ticks.apply(e,r):e.domain()),y=i??(e.tickFormat?e.tickFormat.apply(e,r):PA),v=Math.max(a,0)+l,x=e.range(),b=+x[0]+u,T=+x[x.length-1]+u,S=(e.bandwidth?dTe:fTe)(e.copy(),u),w=m.selection?m.selection():m,E=w.selectAll(".domain").data([null]),_=w.selectAll(".tick").data(g,e).order(),C=_.exit(),D=_.enter().append("g").attr("class","tick"),O=_.select("line"),R=_.select("text");E=E.merge(E.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),_=_.merge(D),O=O.merge(D.append("line").attr("stroke","currentColor").attr(f+"2",h*a)),R=R.merge(D.append("text").attr("fill","currentColor").attr(f,h*v).attr("dy",t===X3?"0em":t===FA?"0.71em":"0.32em")),m!==w&&(E=E.transition(m),_=_.transition(m),O=O.transition(m),R=R.transition(m),C=C.transition(m).attr("opacity",KV).attr("transform",function(k){return isFinite(k=S(k))?d(k+u):this.getAttribute("transform")}),D.attr("opacity",KV).attr("transform",function(k){var L=this.parentNode.__axis;return d((L&&isFinite(L=L(k))?L:S(k))+u)})),C.remove(),E.attr("d",t===Y3||t===BA?s?"M"+h*s+","+b+"H"+u+"V"+T+"H"+h*s:"M"+u+","+b+"V"+T:s?"M"+b+","+h*s+"V"+u+"H"+T+"V"+h*s:"M"+b+","+u+"H"+T),_.attr("opacity",1).attr("transform",function(k){return d(S(k)+u)}),O.attr(f+"2",h*a),R.attr(f,h*v).text(y),w.filter(pTe).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===BA?"start":t===Y3?"end":"middle"),w.each(function(){this.__axis=S})}return o(p,"axis"),p.scale=function(m){return arguments.length?(e=m,p):e},p.ticks=function(){return r=Array.from(arguments),p},p.tickArguments=function(m){return arguments.length?(r=m==null?[]:Array.from(m),p):r.slice()},p.tickValues=function(m){return arguments.length?(n=m==null?null:Array.from(m),p):n&&n.slice()},p.tickFormat=function(m){return arguments.length?(i=m,p):i},p.tickSize=function(m){return arguments.length?(a=s=+m,p):a},p.tickSizeInner=function(m){return arguments.length?(a=+m,p):a},p.tickSizeOuter=function(m){return arguments.length?(s=+m,p):s},p.tickPadding=function(m){return arguments.length?(l=+m,p):l},p.offset=function(m){return arguments.length?(u=+m,p):u},p}function $A(t){return QV(X3,t)}function zA(t){return QV(FA,t)}var X3,BA,FA,Y3,KV,ZV=N(()=>{"use strict";jV();X3=1,BA=2,FA=3,Y3=4,KV=1e-6;o(uTe,"translateX");o(hTe,"translateY");o(fTe,"number");o(dTe,"center");o(pTe,"entering");o(QV,"axis");o($A,"axisTop");o(zA,"axisBottom")});var JV=N(()=>{"use strict";ZV()});function tU(){for(var t=0,e=arguments.length,r={},n;t=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!e.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}function yTe(t,e){for(var r=0,n=t.length,i;r{"use strict";mTe={value:o(()=>{},"value")};o(tU,"dispatch");o(j3,"Dispatch");o(gTe,"parseTypenames");j3.prototype=tU.prototype={constructor:j3,on:o(function(t,e){var r=this._,n=gTe(t+"",r),i,a=-1,s=n.length;if(arguments.length<2){for(;++a0)for(var r=new Array(i),n=0,i,a;n{"use strict";rU()});var K3,UA,HA=N(()=>{"use strict";K3="http://www.w3.org/1999/xhtml",UA={svg:"http://www.w3.org/2000/svg",xhtml:K3,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"}});function sc(t){var e=t+="",r=e.indexOf(":");return r>=0&&(e=t.slice(0,r))!=="xmlns"&&(t=t.slice(r+1)),UA.hasOwnProperty(e)?{space:UA[e],local:t}:t}var Q3=N(()=>{"use strict";HA();o(sc,"default")});function vTe(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===K3&&e.documentElement.namespaceURI===K3?e.createElement(t):e.createElementNS(r,t)}}function xTe(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function lv(t){var e=sc(t);return(e.local?xTe:vTe)(e)}var WA=N(()=>{"use strict";Q3();HA();o(vTe,"creatorInherit");o(xTe,"creatorFixed");o(lv,"default")});function bTe(){}function Sh(t){return t==null?bTe:function(){return this.querySelector(t)}}var Z3=N(()=>{"use strict";o(bTe,"none");o(Sh,"default")});function qA(t){typeof t!="function"&&(t=Sh(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";gl();Z3();o(qA,"default")});function YA(t){return t==null?[]:Array.isArray(t)?t:Array.from(t)}var iU=N(()=>{"use strict";o(YA,"array")});function TTe(){return[]}function _0(t){return t==null?TTe:function(){return this.querySelectorAll(t)}}var XA=N(()=>{"use strict";o(TTe,"empty");o(_0,"default")});function wTe(t){return function(){return YA(t.apply(this,arguments))}}function jA(t){typeof t=="function"?t=wTe(t):t=_0(t);for(var e=this._groups,r=e.length,n=[],i=[],a=0;a{"use strict";gl();iU();XA();o(wTe,"arrayAll");o(jA,"default")});function D0(t){return function(){return this.matches(t)}}function J3(t){return function(e){return e.matches(t)}}var cv=N(()=>{"use strict";o(D0,"default");o(J3,"childMatcher")});function ETe(t){return function(){return kTe.call(this.children,t)}}function STe(){return this.firstElementChild}function KA(t){return this.select(t==null?STe:ETe(typeof t=="function"?t:J3(t)))}var kTe,sU=N(()=>{"use strict";cv();kTe=Array.prototype.find;o(ETe,"childFind");o(STe,"childFirst");o(KA,"default")});function ATe(){return Array.from(this.children)}function _Te(t){return function(){return CTe.call(this.children,t)}}function QA(t){return this.selectAll(t==null?ATe:_Te(typeof t=="function"?t:J3(t)))}var CTe,oU=N(()=>{"use strict";cv();CTe=Array.prototype.filter;o(ATe,"children");o(_Te,"childrenFilter");o(QA,"default")});function ZA(t){typeof t!="function"&&(t=D0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";gl();cv();o(ZA,"default")});function uv(t){return new Array(t.length)}var JA=N(()=>{"use strict";o(uv,"default")});function e8(){return new ui(this._enter||this._groups.map(uv),this._parents)}function hv(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}var t8=N(()=>{"use strict";JA();gl();o(e8,"default");o(hv,"EnterNode");hv.prototype={constructor:hv,appendChild:o(function(t){return this._parent.insertBefore(t,this._next)},"appendChild"),insertBefore:o(function(t,e){return this._parent.insertBefore(t,e)},"insertBefore"),querySelector:o(function(t){return this._parent.querySelector(t)},"querySelector"),querySelectorAll:o(function(t){return this._parent.querySelectorAll(t)},"querySelectorAll")}});function r8(t){return function(){return t}}var cU=N(()=>{"use strict";o(r8,"default")});function DTe(t,e,r,n,i,a){for(var s=0,l,u=e.length,h=a.length;s=T&&(T=b+1);!(w=v[T])&&++T{"use strict";gl();t8();cU();o(DTe,"bindIndex");o(LTe,"bindKey");o(RTe,"datum");o(n8,"default");o(NTe,"arraylike")});function i8(){return new ui(this._exit||this._groups.map(uv),this._parents)}var hU=N(()=>{"use strict";JA();gl();o(i8,"default")});function a8(t,e,r){var n=this.enter(),i=this,a=this.exit();return typeof t=="function"?(n=t(n),n&&(n=n.selection())):n=n.append(t+""),e!=null&&(i=e(i),i&&(i=i.selection())),r==null?a.remove():r(a),n&&i?n.merge(i).order():i}var fU=N(()=>{"use strict";o(a8,"default")});function s8(t){for(var e=t.selection?t.selection():t,r=this._groups,n=e._groups,i=r.length,a=n.length,s=Math.min(i,a),l=new Array(i),u=0;u{"use strict";gl();o(s8,"default")});function o8(){for(var t=this._groups,e=-1,r=t.length;++e=0;)(s=n[i])&&(a&&s.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(s,a),a=s);return this}var pU=N(()=>{"use strict";o(o8,"default")});function l8(t){t||(t=MTe);function e(d,p){return d&&p?t(d.__data__,p.__data__):!d-!p}o(e,"compareNode");for(var r=this._groups,n=r.length,i=new Array(n),a=0;ae?1:t>=e?0:NaN}var mU=N(()=>{"use strict";gl();o(l8,"default");o(MTe,"ascending")});function c8(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}var gU=N(()=>{"use strict";o(c8,"default")});function u8(){return Array.from(this)}var yU=N(()=>{"use strict";o(u8,"default")});function h8(){for(var t=this._groups,e=0,r=t.length;e{"use strict";o(h8,"default")});function f8(){let t=0;for(let e of this)++t;return t}var xU=N(()=>{"use strict";o(f8,"default")});function d8(){return!this.node()}var bU=N(()=>{"use strict";o(d8,"default")});function p8(t){for(var e=this._groups,r=0,n=e.length;r{"use strict";o(p8,"default")});function ITe(t){return function(){this.removeAttribute(t)}}function OTe(t){return function(){this.removeAttributeNS(t.space,t.local)}}function PTe(t,e){return function(){this.setAttribute(t,e)}}function BTe(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function FTe(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttribute(t):this.setAttribute(t,r)}}function $Te(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,r)}}function m8(t,e){var r=sc(t);if(arguments.length<2){var n=this.node();return r.local?n.getAttributeNS(r.space,r.local):n.getAttribute(r)}return this.each((e==null?r.local?OTe:ITe:typeof e=="function"?r.local?$Te:FTe:r.local?BTe:PTe)(r,e))}var wU=N(()=>{"use strict";Q3();o(ITe,"attrRemove");o(OTe,"attrRemoveNS");o(PTe,"attrConstant");o(BTe,"attrConstantNS");o(FTe,"attrFunction");o($Te,"attrFunctionNS");o(m8,"default")});function fv(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}var g8=N(()=>{"use strict";o(fv,"default")});function zTe(t){return function(){this.style.removeProperty(t)}}function GTe(t,e,r){return function(){this.style.setProperty(t,e,r)}}function VTe(t,e,r){return function(){var n=e.apply(this,arguments);n==null?this.style.removeProperty(t):this.style.setProperty(t,n,r)}}function y8(t,e,r){return arguments.length>1?this.each((e==null?zTe:typeof e=="function"?VTe:GTe)(t,e,r??"")):Ch(this.node(),t)}function Ch(t,e){return t.style.getPropertyValue(e)||fv(t).getComputedStyle(t,null).getPropertyValue(e)}var v8=N(()=>{"use strict";g8();o(zTe,"styleRemove");o(GTe,"styleConstant");o(VTe,"styleFunction");o(y8,"default");o(Ch,"styleValue")});function UTe(t){return function(){delete this[t]}}function HTe(t,e){return function(){this[t]=e}}function WTe(t,e){return function(){var r=e.apply(this,arguments);r==null?delete this[t]:this[t]=r}}function x8(t,e){return arguments.length>1?this.each((e==null?UTe:typeof e=="function"?WTe:HTe)(t,e)):this.node()[t]}var kU=N(()=>{"use strict";o(UTe,"propertyRemove");o(HTe,"propertyConstant");o(WTe,"propertyFunction");o(x8,"default")});function EU(t){return t.trim().split(/^|\s+/)}function b8(t){return t.classList||new SU(t)}function SU(t){this._node=t,this._names=EU(t.getAttribute("class")||"")}function CU(t,e){for(var r=b8(t),n=-1,i=e.length;++n{"use strict";o(EU,"classArray");o(b8,"classList");o(SU,"ClassList");SU.prototype={add:o(function(t){var e=this._names.indexOf(t);e<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},"add"),remove:o(function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},"remove"),contains:o(function(t){return this._names.indexOf(t)>=0},"contains")};o(CU,"classedAdd");o(AU,"classedRemove");o(qTe,"classedTrue");o(YTe,"classedFalse");o(XTe,"classedFunction");o(T8,"default")});function jTe(){this.textContent=""}function KTe(t){return function(){this.textContent=t}}function QTe(t){return function(){var e=t.apply(this,arguments);this.textContent=e??""}}function w8(t){return arguments.length?this.each(t==null?jTe:(typeof t=="function"?QTe:KTe)(t)):this.node().textContent}var DU=N(()=>{"use strict";o(jTe,"textRemove");o(KTe,"textConstant");o(QTe,"textFunction");o(w8,"default")});function ZTe(){this.innerHTML=""}function JTe(t){return function(){this.innerHTML=t}}function ewe(t){return function(){var e=t.apply(this,arguments);this.innerHTML=e??""}}function k8(t){return arguments.length?this.each(t==null?ZTe:(typeof t=="function"?ewe:JTe)(t)):this.node().innerHTML}var LU=N(()=>{"use strict";o(ZTe,"htmlRemove");o(JTe,"htmlConstant");o(ewe,"htmlFunction");o(k8,"default")});function twe(){this.nextSibling&&this.parentNode.appendChild(this)}function E8(){return this.each(twe)}var RU=N(()=>{"use strict";o(twe,"raise");o(E8,"default")});function rwe(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function S8(){return this.each(rwe)}var NU=N(()=>{"use strict";o(rwe,"lower");o(S8,"default")});function C8(t){var e=typeof t=="function"?t:lv(t);return this.select(function(){return this.appendChild(e.apply(this,arguments))})}var MU=N(()=>{"use strict";WA();o(C8,"default")});function nwe(){return null}function A8(t,e){var r=typeof t=="function"?t:lv(t),n=e==null?nwe:typeof e=="function"?e:Sh(e);return this.select(function(){return this.insertBefore(r.apply(this,arguments),n.apply(this,arguments)||null)})}var IU=N(()=>{"use strict";WA();Z3();o(nwe,"constantNull");o(A8,"default")});function iwe(){var t=this.parentNode;t&&t.removeChild(this)}function _8(){return this.each(iwe)}var OU=N(()=>{"use strict";o(iwe,"remove");o(_8,"default")});function awe(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function swe(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function D8(t){return this.select(t?swe:awe)}var PU=N(()=>{"use strict";o(awe,"selection_cloneShallow");o(swe,"selection_cloneDeep");o(D8,"default")});function L8(t){return arguments.length?this.property("__data__",t):this.node().__data__}var BU=N(()=>{"use strict";o(L8,"default")});function owe(t){return function(e){t.call(this,e,this.__data__)}}function lwe(t){return t.trim().split(/^|\s+/).map(function(e){var r="",n=e.indexOf(".");return n>=0&&(r=e.slice(n+1),e=e.slice(0,n)),{type:e,name:r}})}function cwe(t){return function(){var e=this.__on;if(e){for(var r=0,n=-1,i=e.length,a;r{"use strict";o(owe,"contextListener");o(lwe,"parseTypenames");o(cwe,"onRemove");o(uwe,"onAdd");o(R8,"default")});function $U(t,e,r){var n=fv(t),i=n.CustomEvent;typeof i=="function"?i=new i(e,r):(i=n.document.createEvent("Event"),r?(i.initEvent(e,r.bubbles,r.cancelable),i.detail=r.detail):i.initEvent(e,!1,!1)),t.dispatchEvent(i)}function hwe(t,e){return function(){return $U(this,t,e)}}function fwe(t,e){return function(){return $U(this,t,e.apply(this,arguments))}}function N8(t,e){return this.each((typeof e=="function"?fwe:hwe)(t,e))}var zU=N(()=>{"use strict";g8();o($U,"dispatchEvent");o(hwe,"dispatchConstant");o(fwe,"dispatchFunction");o(N8,"default")});function*M8(){for(var t=this._groups,e=0,r=t.length;e{"use strict";o(M8,"default")});function ui(t,e){this._groups=t,this._parents=e}function VU(){return new ui([[document.documentElement]],I8)}function dwe(){return this}var I8,gu,gl=N(()=>{"use strict";nU();aU();sU();oU();lU();uU();t8();hU();fU();dU();pU();mU();gU();yU();vU();xU();bU();TU();wU();v8();kU();_U();DU();LU();RU();NU();MU();IU();OU();PU();BU();FU();zU();GU();I8=[null];o(ui,"Selection");o(VU,"selection");o(dwe,"selection_selection");ui.prototype=VU.prototype={constructor:ui,select:qA,selectAll:jA,selectChild:KA,selectChildren:QA,filter:ZA,data:n8,enter:e8,exit:i8,join:a8,merge:s8,selection:dwe,order:o8,sort:l8,call:c8,nodes:u8,node:h8,size:f8,empty:d8,each:p8,attr:m8,style:y8,property:x8,classed:T8,text:w8,html:k8,raise:E8,lower:S8,append:C8,insert:A8,remove:_8,clone:D8,datum:L8,on:R8,dispatch:N8,[Symbol.iterator]:M8};gu=VU});function Ge(t){return typeof t=="string"?new ui([[document.querySelector(t)]],[document.documentElement]):new ui([[t]],I8)}var UU=N(()=>{"use strict";gl();o(Ge,"default")});var yl=N(()=>{"use strict";cv();Q3();UU();gl();Z3();XA();v8()});var HU=N(()=>{"use strict"});function Ah(t,e,r){t.prototype=e.prototype=r,r.constructor=t}function L0(t,e){var r=Object.create(t.prototype);for(var n in e)r[n]=e[n];return r}var O8=N(()=>{"use strict";o(Ah,"default");o(L0,"extend")});function _h(){}function qU(){return this.rgb().formatHex()}function Twe(){return this.rgb().formatHex8()}function wwe(){return JU(this).formatHsl()}function YU(){return this.rgb().formatRgb()}function xl(t){var e,r;return t=(t+"").trim().toLowerCase(),(e=pwe.exec(t))?(r=e[1].length,e=parseInt(e[1],16),r===6?XU(e):r===3?new ca(e>>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):r===8?e5(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):r===4?e5(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=mwe.exec(t))?new ca(e[1],e[2],e[3],1):(e=gwe.exec(t))?new ca(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=ywe.exec(t))?e5(e[1],e[2],e[3],e[4]):(e=vwe.exec(t))?e5(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=xwe.exec(t))?QU(e[1],e[2]/100,e[3]/100,1):(e=bwe.exec(t))?QU(e[1],e[2]/100,e[3]/100,e[4]):WU.hasOwnProperty(t)?XU(WU[t]):t==="transparent"?new ca(NaN,NaN,NaN,0):null}function XU(t){return new ca(t>>16&255,t>>8&255,t&255,1)}function e5(t,e,r,n){return n<=0&&(t=e=r=NaN),new ca(t,e,r,n)}function B8(t){return t instanceof _h||(t=xl(t)),t?(t=t.rgb(),new ca(t.r,t.g,t.b,t.opacity)):new ca}function N0(t,e,r,n){return arguments.length===1?B8(t):new ca(t,e,r,n??1)}function ca(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function jU(){return`#${gd(this.r)}${gd(this.g)}${gd(this.b)}`}function kwe(){return`#${gd(this.r)}${gd(this.g)}${gd(this.b)}${gd((isNaN(this.opacity)?1:this.opacity)*255)}`}function KU(){let t=n5(this.opacity);return`${t===1?"rgb(":"rgba("}${yd(this.r)}, ${yd(this.g)}, ${yd(this.b)}${t===1?")":`, ${t})`}`}function n5(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function yd(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function gd(t){return t=yd(t),(t<16?"0":"")+t.toString(16)}function QU(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new vl(t,e,r,n)}function JU(t){if(t instanceof vl)return new vl(t.h,t.s,t.l,t.opacity);if(t instanceof _h||(t=xl(t)),!t)return new vl;if(t instanceof vl)return t;t=t.rgb();var e=t.r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),s=NaN,l=a-i,u=(a+i)/2;return l?(e===a?s=(r-n)/l+(r0&&u<1?0:s,new vl(s,l,u,t.opacity)}function eH(t,e,r,n){return arguments.length===1?JU(t):new vl(t,e,r,n??1)}function vl(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function ZU(t){return t=(t||0)%360,t<0?t+360:t}function t5(t){return Math.max(0,Math.min(1,t||0))}function P8(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}var dv,r5,R0,pv,oc,pwe,mwe,gwe,ywe,vwe,xwe,bwe,WU,F8=N(()=>{"use strict";O8();o(_h,"Color");dv=.7,r5=1/dv,R0="\\s*([+-]?\\d+)\\s*",pv="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",oc="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",pwe=/^#([0-9a-f]{3,8})$/,mwe=new RegExp(`^rgb\\(${R0},${R0},${R0}\\)$`),gwe=new RegExp(`^rgb\\(${oc},${oc},${oc}\\)$`),ywe=new RegExp(`^rgba\\(${R0},${R0},${R0},${pv}\\)$`),vwe=new RegExp(`^rgba\\(${oc},${oc},${oc},${pv}\\)$`),xwe=new RegExp(`^hsl\\(${pv},${oc},${oc}\\)$`),bwe=new RegExp(`^hsla\\(${pv},${oc},${oc},${pv}\\)$`),WU={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Ah(_h,xl,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:qU,formatHex:qU,formatHex8:Twe,formatHsl:wwe,formatRgb:YU,toString:YU});o(qU,"color_formatHex");o(Twe,"color_formatHex8");o(wwe,"color_formatHsl");o(YU,"color_formatRgb");o(xl,"color");o(XU,"rgbn");o(e5,"rgba");o(B8,"rgbConvert");o(N0,"rgb");o(ca,"Rgb");Ah(ca,N0,L0(_h,{brighter(t){return t=t==null?r5:Math.pow(r5,t),new ca(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?dv:Math.pow(dv,t),new ca(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new ca(yd(this.r),yd(this.g),yd(this.b),n5(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:jU,formatHex:jU,formatHex8:kwe,formatRgb:KU,toString:KU}));o(jU,"rgb_formatHex");o(kwe,"rgb_formatHex8");o(KU,"rgb_formatRgb");o(n5,"clampa");o(yd,"clampi");o(gd,"hex");o(QU,"hsla");o(JU,"hslConvert");o(eH,"hsl");o(vl,"Hsl");Ah(vl,eH,L0(_h,{brighter(t){return t=t==null?r5:Math.pow(r5,t),new vl(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?dv:Math.pow(dv,t),new vl(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new ca(P8(t>=240?t-240:t+120,i,n),P8(t,i,n),P8(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new vl(ZU(this.h),t5(this.s),t5(this.l),n5(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let t=n5(this.opacity);return`${t===1?"hsl(":"hsla("}${ZU(this.h)}, ${t5(this.s)*100}%, ${t5(this.l)*100}%${t===1?")":`, ${t})`}`}}));o(ZU,"clamph");o(t5,"clampt");o(P8,"hsl2rgb")});var tH,rH,nH=N(()=>{"use strict";tH=Math.PI/180,rH=180/Math.PI});function cH(t){if(t instanceof lc)return new lc(t.l,t.a,t.b,t.opacity);if(t instanceof yu)return uH(t);t instanceof ca||(t=B8(t));var e=V8(t.r),r=V8(t.g),n=V8(t.b),i=$8((.2225045*e+.7168786*r+.0606169*n)/aH),a,s;return e===r&&r===n?a=s=i:(a=$8((.4360747*e+.3850649*r+.1430804*n)/iH),s=$8((.0139322*e+.0971045*r+.7141733*n)/sH)),new lc(116*i-16,500*(a-i),200*(i-s),t.opacity)}function U8(t,e,r,n){return arguments.length===1?cH(t):new lc(t,e,r,n??1)}function lc(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}function $8(t){return t>Ewe?Math.pow(t,1/3):t/lH+oH}function z8(t){return t>M0?t*t*t:lH*(t-oH)}function G8(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function V8(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Swe(t){if(t instanceof yu)return new yu(t.h,t.c,t.l,t.opacity);if(t instanceof lc||(t=cH(t)),t.a===0&&t.b===0)return new yu(NaN,0{"use strict";O8();F8();nH();i5=18,iH=.96422,aH=1,sH=.82521,oH=4/29,M0=6/29,lH=3*M0*M0,Ewe=M0*M0*M0;o(cH,"labConvert");o(U8,"lab");o(lc,"Lab");Ah(lc,U8,L0(_h,{brighter(t){return new lc(this.l+i5*(t??1),this.a,this.b,this.opacity)},darker(t){return new lc(this.l-i5*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return e=iH*z8(e),t=aH*z8(t),r=sH*z8(r),new ca(G8(3.1338561*e-1.6168667*t-.4906146*r),G8(-.9787684*e+1.9161415*t+.033454*r),G8(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}}));o($8,"xyz2lab");o(z8,"lab2xyz");o(G8,"lrgb2rgb");o(V8,"rgb2lrgb");o(Swe,"hclConvert");o(mv,"hcl");o(yu,"Hcl");o(uH,"hcl2lab");Ah(yu,mv,L0(_h,{brighter(t){return new yu(this.h,this.c,this.l+i5*(t??1),this.opacity)},darker(t){return new yu(this.h,this.c,this.l-i5*(t??1),this.opacity)},rgb(){return uH(this).rgb()}}))});var I0=N(()=>{"use strict";F8();hH()});function H8(t,e,r,n,i){var a=t*t,s=a*t;return((1-3*t+3*a-s)*e+(4-6*a+3*s)*r+(1+3*t+3*a-3*s)*n+s*i)/6}function W8(t){var e=t.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],s=n>0?t[n-1]:2*i-a,l=n{"use strict";o(H8,"basis");o(W8,"default")});function Y8(t){var e=t.length;return function(r){var n=Math.floor(((r%=1)<0?++r:r)*e),i=t[(n+e-1)%e],a=t[n%e],s=t[(n+1)%e],l=t[(n+2)%e];return H8((r-n/e)*e,i,a,s,l)}}var fH=N(()=>{"use strict";q8();o(Y8,"default")});var O0,X8=N(()=>{"use strict";O0=o(t=>()=>t,"default")});function dH(t,e){return function(r){return t+r*e}}function Cwe(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}function pH(t,e){var r=e-t;return r?dH(t,r>180||r<-180?r-360*Math.round(r/360):r):O0(isNaN(t)?e:t)}function mH(t){return(t=+t)==1?vu:function(e,r){return r-e?Cwe(e,r,t):O0(isNaN(e)?r:e)}}function vu(t,e){var r=e-t;return r?dH(t,r):O0(isNaN(t)?e:t)}var j8=N(()=>{"use strict";X8();o(dH,"linear");o(Cwe,"exponential");o(pH,"hue");o(mH,"gamma");o(vu,"nogamma")});function gH(t){return function(e){var r=e.length,n=new Array(r),i=new Array(r),a=new Array(r),s,l;for(s=0;s{"use strict";I0();q8();fH();j8();vd=o(function t(e){var r=mH(e);function n(i,a){var s=r((i=N0(i)).r,(a=N0(a)).r),l=r(i.g,a.g),u=r(i.b,a.b),h=vu(i.opacity,a.opacity);return function(f){return i.r=s(f),i.g=l(f),i.b=u(f),i.opacity=h(f),i+""}}return o(n,"rgb"),n.gamma=t,n},"rgbGamma")(1);o(gH,"rgbSpline");Awe=gH(W8),_we=gH(Y8)});function Q8(t,e){e||(e=[]);var r=t?Math.min(e.length,t.length):0,n=e.slice(),i;return function(a){for(i=0;i{"use strict";o(Q8,"default");o(yH,"isNumberArray")});function xH(t,e){var r=e?e.length:0,n=t?Math.min(r,t.length):0,i=new Array(n),a=new Array(r),s;for(s=0;s{"use strict";a5();o(xH,"genericArray")});function Z8(t,e){var r=new Date;return t=+t,e=+e,function(n){return r.setTime(t*(1-n)+e*n),r}}var TH=N(()=>{"use strict";o(Z8,"default")});function Ki(t,e){return t=+t,e=+e,function(r){return t*(1-r)+e*r}}var gv=N(()=>{"use strict";o(Ki,"default")});function J8(t,e){var r={},n={},i;(t===null||typeof t!="object")&&(t={}),(e===null||typeof e!="object")&&(e={});for(i in e)i in t?r[i]=Dh(t[i],e[i]):n[i]=e[i];return function(a){for(i in r)n[i]=r[i](a);return n}}var wH=N(()=>{"use strict";a5();o(J8,"default")});function Dwe(t){return function(){return t}}function Lwe(t){return function(e){return t(e)+""}}function P0(t,e){var r=t_.lastIndex=e_.lastIndex=0,n,i,a,s=-1,l=[],u=[];for(t=t+"",e=e+"";(n=t_.exec(t))&&(i=e_.exec(e));)(a=i.index)>r&&(a=e.slice(r,a),l[s]?l[s]+=a:l[++s]=a),(n=n[0])===(i=i[0])?l[s]?l[s]+=i:l[++s]=i:(l[++s]=null,u.push({i:s,x:Ki(n,i)})),r=e_.lastIndex;return r{"use strict";gv();t_=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,e_=new RegExp(t_.source,"g");o(Dwe,"zero");o(Lwe,"one");o(P0,"default")});function Dh(t,e){var r=typeof e,n;return e==null||r==="boolean"?O0(e):(r==="number"?Ki:r==="string"?(n=xl(e))?(e=n,vd):P0:e instanceof xl?vd:e instanceof Date?Z8:yH(e)?Q8:Array.isArray(e)?xH:typeof e.valueOf!="function"&&typeof e.toString!="function"||isNaN(e)?J8:Ki)(t,e)}var a5=N(()=>{"use strict";I0();K8();bH();TH();gv();wH();r_();X8();vH();o(Dh,"default")});function s5(t,e){return t=+t,e=+e,function(r){return Math.round(t*(1-r)+e*r)}}var kH=N(()=>{"use strict";o(s5,"default")});function l5(t,e,r,n,i,a){var s,l,u;return(s=Math.sqrt(t*t+e*e))&&(t/=s,e/=s),(u=t*r+e*n)&&(r-=t*u,n-=e*u),(l=Math.sqrt(r*r+n*n))&&(r/=l,n/=l,u/=l),t*n{"use strict";EH=180/Math.PI,o5={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};o(l5,"default")});function CH(t){let e=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?o5:l5(e.a,e.b,e.c,e.d,e.e,e.f)}function AH(t){return t==null?o5:(c5||(c5=document.createElementNS("http://www.w3.org/2000/svg","g")),c5.setAttribute("transform",t),(t=c5.transform.baseVal.consolidate())?(t=t.matrix,l5(t.a,t.b,t.c,t.d,t.e,t.f)):o5)}var c5,_H=N(()=>{"use strict";SH();o(CH,"parseCss");o(AH,"parseSvg")});function DH(t,e,r,n){function i(h){return h.length?h.pop()+" ":""}o(i,"pop");function a(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push("translate(",null,e,null,r);g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d||p)&&m.push("translate("+d+e+p+r)}o(a,"translate");function s(h,f,d,p){h!==f?(h-f>180?f+=360:f-h>180&&(h+=360),p.push({i:d.push(i(d)+"rotate(",null,n)-2,x:Ki(h,f)})):f&&d.push(i(d)+"rotate("+f+n)}o(s,"rotate");function l(h,f,d,p){h!==f?p.push({i:d.push(i(d)+"skewX(",null,n)-2,x:Ki(h,f)}):f&&d.push(i(d)+"skewX("+f+n)}o(l,"skewX");function u(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push(i(m)+"scale(",null,",",null,")");g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d!==1||p!==1)&&m.push(i(m)+"scale("+d+","+p+")")}return o(u,"scale"),function(h,f){var d=[],p=[];return h=t(h),f=t(f),a(h.translateX,h.translateY,f.translateX,f.translateY,d,p),s(h.rotate,f.rotate,d,p),l(h.skewX,f.skewX,d,p),u(h.scaleX,h.scaleY,f.scaleX,f.scaleY,d,p),h=f=null,function(m){for(var g=-1,y=p.length,v;++g{"use strict";gv();_H();o(DH,"interpolateTransform");n_=DH(CH,"px, ","px)","deg)"),i_=DH(AH,", ",")",")")});function RH(t){return function(e,r){var n=t((e=mv(e)).h,(r=mv(r)).h),i=vu(e.c,r.c),a=vu(e.l,r.l),s=vu(e.opacity,r.opacity);return function(l){return e.h=n(l),e.c=i(l),e.l=a(l),e.opacity=s(l),e+""}}}var a_,Rwe,NH=N(()=>{"use strict";I0();j8();o(RH,"hcl");a_=RH(pH),Rwe=RH(vu)});var B0=N(()=>{"use strict";a5();gv();kH();r_();LH();K8();NH()});function wv(){return xd||(OH(Nwe),xd=bv.now()+f5)}function Nwe(){xd=0}function Tv(){this._call=this._time=this._next=null}function d5(t,e,r){var n=new Tv;return n.restart(t,e,r),n}function PH(){wv(),++F0;for(var t=u5,e;t;)(e=xd-t._time)>=0&&t._call.call(void 0,e),t=t._next;--F0}function MH(){xd=(h5=bv.now())+f5,F0=vv=0;try{PH()}finally{F0=0,Iwe(),xd=0}}function Mwe(){var t=bv.now(),e=t-h5;e>IH&&(f5-=e,h5=t)}function Iwe(){for(var t,e=u5,r,n=1/0;e;)e._call?(n>e._time&&(n=e._time),t=e,e=e._next):(r=e._next,e._next=null,e=t?t._next=r:u5=r);xv=t,s_(n)}function s_(t){if(!F0){vv&&(vv=clearTimeout(vv));var e=t-xd;e>24?(t<1/0&&(vv=setTimeout(MH,t-bv.now()-f5)),yv&&(yv=clearInterval(yv))):(yv||(h5=bv.now(),yv=setInterval(Mwe,IH)),F0=1,OH(MH))}}var F0,vv,yv,IH,u5,xv,h5,xd,f5,bv,OH,o_=N(()=>{"use strict";F0=0,vv=0,yv=0,IH=1e3,h5=0,xd=0,f5=0,bv=typeof performance=="object"&&performance.now?performance:Date,OH=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};o(wv,"now");o(Nwe,"clearNow");o(Tv,"Timer");Tv.prototype=d5.prototype={constructor:Tv,restart:o(function(t,e,r){if(typeof t!="function")throw new TypeError("callback is not a function");r=(r==null?wv():+r)+(e==null?0:+e),!this._next&&xv!==this&&(xv?xv._next=this:u5=this,xv=this),this._call=t,this._time=r,s_()},"restart"),stop:o(function(){this._call&&(this._call=null,this._time=1/0,s_())},"stop")};o(d5,"timer");o(PH,"timerFlush");o(MH,"wake");o(Mwe,"poke");o(Iwe,"nap");o(s_,"sleep")});function kv(t,e,r){var n=new Tv;return e=e==null?0:+e,n.restart(i=>{n.stop(),t(i+e)},e,r),n}var BH=N(()=>{"use strict";o_();o(kv,"default")});var p5=N(()=>{"use strict";o_();BH()});function xu(t,e,r,n,i,a){var s=t.__transition;if(!s)t.__transition={};else if(r in s)return;Bwe(t,r,{name:e,index:n,group:i,on:Owe,tween:Pwe,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:zH})}function Sv(t,e){var r=zi(t,e);if(r.state>zH)throw new Error("too late; already scheduled");return r}function ua(t,e){var r=zi(t,e);if(r.state>m5)throw new Error("too late; already running");return r}function zi(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function Bwe(t,e,r){var n=t.__transition,i;n[e]=r,r.timer=d5(a,0,r.time);function a(h){r.state=FH,r.timer.restart(s,r.delay,r.time),r.delay<=h&&s(h-r.delay)}o(a,"schedule");function s(h){var f,d,p,m;if(r.state!==FH)return u();for(f in n)if(m=n[f],m.name===r.name){if(m.state===m5)return kv(s);m.state===$H?(m.state=Ev,m.timer.stop(),m.on.call("interrupt",t,t.__data__,m.index,m.group),delete n[f]):+f{"use strict";VA();p5();Owe=GA("start","end","cancel","interrupt"),Pwe=[],zH=0,FH=1,g5=2,m5=3,$H=4,y5=5,Ev=6;o(xu,"default");o(Sv,"init");o(ua,"set");o(zi,"get");o(Bwe,"create")});function Cv(t,e){var r=t.__transition,n,i,a=!0,s;if(r){e=e==null?null:e+"";for(s in r){if((n=r[s]).name!==e){a=!1;continue}i=n.state>g5&&n.state{"use strict";Ds();o(Cv,"default")});function l_(t){return this.each(function(){Cv(this,t)})}var VH=N(()=>{"use strict";GH();o(l_,"default")});function Fwe(t,e){var r,n;return function(){var i=ua(this,t),a=i.tween;if(a!==r){n=r=a;for(var s=0,l=n.length;s{"use strict";Ds();o(Fwe,"tweenRemove");o($we,"tweenFunction");o(c_,"default");o($0,"tweenValue")});function _v(t,e){var r;return(typeof e=="number"?Ki:e instanceof xl?vd:(r=xl(e))?(e=r,vd):P0)(t,e)}var u_=N(()=>{"use strict";I0();B0();o(_v,"default")});function zwe(t){return function(){this.removeAttribute(t)}}function Gwe(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Vwe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttribute(t);return s===i?null:s===n?a:a=e(n=s,r)}}function Uwe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttributeNS(t.space,t.local);return s===i?null:s===n?a:a=e(n=s,r)}}function Hwe(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttribute(t):(s=this.getAttribute(t),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function Wwe(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttributeNS(t.space,t.local):(s=this.getAttributeNS(t.space,t.local),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function h_(t,e){var r=sc(t),n=r==="transform"?i_:_v;return this.attrTween(t,typeof e=="function"?(r.local?Wwe:Hwe)(r,n,$0(this,"attr."+t,e)):e==null?(r.local?Gwe:zwe)(r):(r.local?Uwe:Vwe)(r,n,e))}var UH=N(()=>{"use strict";B0();yl();Av();u_();o(zwe,"attrRemove");o(Gwe,"attrRemoveNS");o(Vwe,"attrConstant");o(Uwe,"attrConstantNS");o(Hwe,"attrFunction");o(Wwe,"attrFunctionNS");o(h_,"default")});function qwe(t,e){return function(r){this.setAttribute(t,e.call(this,r))}}function Ywe(t,e){return function(r){this.setAttributeNS(t.space,t.local,e.call(this,r))}}function Xwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&Ywe(t,a)),r}return o(i,"tween"),i._value=e,i}function jwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&qwe(t,a)),r}return o(i,"tween"),i._value=e,i}function f_(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(e==null)return this.tween(r,null);if(typeof e!="function")throw new Error;var n=sc(t);return this.tween(r,(n.local?Xwe:jwe)(n,e))}var HH=N(()=>{"use strict";yl();o(qwe,"attrInterpolate");o(Ywe,"attrInterpolateNS");o(Xwe,"attrTweenNS");o(jwe,"attrTween");o(f_,"default")});function Kwe(t,e){return function(){Sv(this,t).delay=+e.apply(this,arguments)}}function Qwe(t,e){return e=+e,function(){Sv(this,t).delay=e}}function d_(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Kwe:Qwe)(e,t)):zi(this.node(),e).delay}var WH=N(()=>{"use strict";Ds();o(Kwe,"delayFunction");o(Qwe,"delayConstant");o(d_,"default")});function Zwe(t,e){return function(){ua(this,t).duration=+e.apply(this,arguments)}}function Jwe(t,e){return e=+e,function(){ua(this,t).duration=e}}function p_(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Zwe:Jwe)(e,t)):zi(this.node(),e).duration}var qH=N(()=>{"use strict";Ds();o(Zwe,"durationFunction");o(Jwe,"durationConstant");o(p_,"default")});function eke(t,e){if(typeof e!="function")throw new Error;return function(){ua(this,t).ease=e}}function m_(t){var e=this._id;return arguments.length?this.each(eke(e,t)):zi(this.node(),e).ease}var YH=N(()=>{"use strict";Ds();o(eke,"easeConstant");o(m_,"default")});function tke(t,e){return function(){var r=e.apply(this,arguments);if(typeof r!="function")throw new Error;ua(this,t).ease=r}}function g_(t){if(typeof t!="function")throw new Error;return this.each(tke(this._id,t))}var XH=N(()=>{"use strict";Ds();o(tke,"easeVarying");o(g_,"default")});function y_(t){typeof t!="function"&&(t=D0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i{"use strict";yl();bd();o(y_,"default")});function v_(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,r=t._groups,n=e.length,i=r.length,a=Math.min(n,i),s=new Array(n),l=0;l{"use strict";bd();o(v_,"default")});function rke(t){return(t+"").trim().split(/^|\s+/).every(function(e){var r=e.indexOf(".");return r>=0&&(e=e.slice(0,r)),!e||e==="start"})}function nke(t,e,r){var n,i,a=rke(e)?Sv:ua;return function(){var s=a(this,t),l=s.on;l!==n&&(i=(n=l).copy()).on(e,r),s.on=i}}function x_(t,e){var r=this._id;return arguments.length<2?zi(this.node(),r).on.on(t):this.each(nke(r,t,e))}var QH=N(()=>{"use strict";Ds();o(rke,"start");o(nke,"onFunction");o(x_,"default")});function ike(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}function b_(){return this.on("end.remove",ike(this._id))}var ZH=N(()=>{"use strict";o(ike,"removeFunction");o(b_,"default")});function T_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=Sh(t));for(var n=this._groups,i=n.length,a=new Array(i),s=0;s{"use strict";yl();bd();Ds();o(T_,"default")});function w_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=_0(t));for(var n=this._groups,i=n.length,a=[],s=[],l=0;l{"use strict";yl();bd();Ds();o(w_,"default")});function k_(){return new ake(this._groups,this._parents)}var ake,tW=N(()=>{"use strict";yl();ake=gu.prototype.constructor;o(k_,"default")});function ske(t,e){var r,n,i;return function(){var a=Ch(this,t),s=(this.style.removeProperty(t),Ch(this,t));return a===s?null:a===r&&s===n?i:i=e(r=a,n=s)}}function rW(t){return function(){this.style.removeProperty(t)}}function oke(t,e,r){var n,i=r+"",a;return function(){var s=Ch(this,t);return s===i?null:s===n?a:a=e(n=s,r)}}function lke(t,e,r){var n,i,a;return function(){var s=Ch(this,t),l=r(this),u=l+"";return l==null&&(u=l=(this.style.removeProperty(t),Ch(this,t))),s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l))}}function cke(t,e){var r,n,i,a="style."+e,s="end."+a,l;return function(){var u=ua(this,t),h=u.on,f=u.value[a]==null?l||(l=rW(e)):void 0;(h!==r||i!==f)&&(n=(r=h).copy()).on(s,i=f),u.on=n}}function E_(t,e,r){var n=(t+="")=="transform"?n_:_v;return e==null?this.styleTween(t,ske(t,n)).on("end.style."+t,rW(t)):typeof e=="function"?this.styleTween(t,lke(t,n,$0(this,"style."+t,e))).each(cke(this._id,t)):this.styleTween(t,oke(t,n,e),r).on("end.style."+t,null)}var nW=N(()=>{"use strict";B0();yl();Ds();Av();u_();o(ske,"styleNull");o(rW,"styleRemove");o(oke,"styleConstant");o(lke,"styleFunction");o(cke,"styleMaybeRemove");o(E_,"default")});function uke(t,e,r){return function(n){this.style.setProperty(t,e.call(this,n),r)}}function hke(t,e,r){var n,i;function a(){var s=e.apply(this,arguments);return s!==i&&(n=(i=s)&&uke(t,s,r)),n}return o(a,"tween"),a._value=e,a}function S_(t,e,r){var n="style."+(t+="");if(arguments.length<2)return(n=this.tween(n))&&n._value;if(e==null)return this.tween(n,null);if(typeof e!="function")throw new Error;return this.tween(n,hke(t,e,r??""))}var iW=N(()=>{"use strict";o(uke,"styleInterpolate");o(hke,"styleTween");o(S_,"default")});function fke(t){return function(){this.textContent=t}}function dke(t){return function(){var e=t(this);this.textContent=e??""}}function C_(t){return this.tween("text",typeof t=="function"?dke($0(this,"text",t)):fke(t==null?"":t+""))}var aW=N(()=>{"use strict";Av();o(fke,"textConstant");o(dke,"textFunction");o(C_,"default")});function pke(t){return function(e){this.textContent=t.call(this,e)}}function mke(t){var e,r;function n(){var i=t.apply(this,arguments);return i!==r&&(e=(r=i)&&pke(i)),e}return o(n,"tween"),n._value=t,n}function A_(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(t==null)return this.tween(e,null);if(typeof t!="function")throw new Error;return this.tween(e,mke(t))}var sW=N(()=>{"use strict";o(pke,"textInterpolate");o(mke,"textTween");o(A_,"default")});function __(){for(var t=this._name,e=this._id,r=v5(),n=this._groups,i=n.length,a=0;a{"use strict";bd();Ds();o(__,"default")});function D_(){var t,e,r=this,n=r._id,i=r.size();return new Promise(function(a,s){var l={value:s},u={value:o(function(){--i===0&&a()},"value")};r.each(function(){var h=ua(this,n),f=h.on;f!==t&&(e=(t=f).copy(),e._.cancel.push(l),e._.interrupt.push(l),e._.end.push(u)),h.on=e}),i===0&&a()})}var lW=N(()=>{"use strict";Ds();o(D_,"default")});function as(t,e,r,n){this._groups=t,this._parents=e,this._name=r,this._id=n}function cW(t){return gu().transition(t)}function v5(){return++gke}var gke,bu,bd=N(()=>{"use strict";yl();UH();HH();WH();qH();YH();XH();jH();KH();QH();ZH();JH();eW();tW();nW();iW();aW();sW();oW();Av();lW();gke=0;o(as,"Transition");o(cW,"transition");o(v5,"newId");bu=gu.prototype;as.prototype=cW.prototype={constructor:as,select:T_,selectAll:w_,selectChild:bu.selectChild,selectChildren:bu.selectChildren,filter:y_,merge:v_,selection:k_,transition:__,call:bu.call,nodes:bu.nodes,node:bu.node,size:bu.size,empty:bu.empty,each:bu.each,on:x_,attr:h_,attrTween:f_,style:E_,styleTween:S_,text:C_,textTween:A_,remove:b_,tween:c_,delay:d_,duration:p_,ease:m_,easeVarying:g_,end:D_,[Symbol.iterator]:bu[Symbol.iterator]}});function x5(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var uW=N(()=>{"use strict";o(x5,"cubicInOut")});var L_=N(()=>{"use strict";uW()});function vke(t,e){for(var r;!(r=t.__transition)||!(r=r[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return r}function R_(t){var e,r;t instanceof as?(e=t._id,t=t._name):(e=v5(),(r=yke).time=wv(),t=t==null?null:t+"");for(var n=this._groups,i=n.length,a=0;a{"use strict";bd();Ds();L_();p5();yke={time:null,delay:0,duration:250,ease:x5};o(vke,"inherit");o(R_,"default")});var fW=N(()=>{"use strict";yl();VH();hW();gu.prototype.interrupt=l_;gu.prototype.transition=R_});var b5=N(()=>{"use strict";fW()});var dW=N(()=>{"use strict"});var pW=N(()=>{"use strict"});var mW=N(()=>{"use strict"});function gW(t){return[+t[0],+t[1]]}function xke(t){return[gW(t[0]),gW(t[1])]}function N_(t){return{type:t}}var _gt,Dgt,Lgt,Rgt,Ngt,Mgt,yW=N(()=>{"use strict";b5();dW();pW();mW();({abs:_gt,max:Dgt,min:Lgt}=Math);o(gW,"number1");o(xke,"number2");Rgt={name:"x",handles:["w","e"].map(N_),input:o(function(t,e){return t==null?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},"input"),output:o(function(t){return t&&[t[0][0],t[1][0]]},"output")},Ngt={name:"y",handles:["n","s"].map(N_),input:o(function(t,e){return t==null?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},"input"),output:o(function(t){return t&&[t[0][1],t[1][1]]},"output")},Mgt={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(N_),input:o(function(t){return t==null?null:xke(t)},"input"),output:o(function(t){return t},"output")};o(N_,"type")});var vW=N(()=>{"use strict";yW()});function xW(t){this._+=t[0];for(let e=1,r=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return xW;let r=10**e;return function(n){this._+=n[0];for(let i=1,a=n.length;i{"use strict";M_=Math.PI,I_=2*M_,Td=1e-6,bke=I_-Td;o(xW,"append");o(Tke,"appendRound");wd=class{static{o(this,"Path")}constructor(e){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=e==null?xW:Tke(e)}moveTo(e,r){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(e,r){this._append`L${this._x1=+e},${this._y1=+r}`}quadraticCurveTo(e,r,n,i){this._append`Q${+e},${+r},${this._x1=+n},${this._y1=+i}`}bezierCurveTo(e,r,n,i,a,s){this._append`C${+e},${+r},${+n},${+i},${this._x1=+a},${this._y1=+s}`}arcTo(e,r,n,i,a){if(e=+e,r=+r,n=+n,i=+i,a=+a,a<0)throw new Error(`negative radius: ${a}`);let s=this._x1,l=this._y1,u=n-e,h=i-r,f=s-e,d=l-r,p=f*f+d*d;if(this._x1===null)this._append`M${this._x1=e},${this._y1=r}`;else if(p>Td)if(!(Math.abs(d*u-h*f)>Td)||!a)this._append`L${this._x1=e},${this._y1=r}`;else{let m=n-s,g=i-l,y=u*u+h*h,v=m*m+g*g,x=Math.sqrt(y),b=Math.sqrt(p),T=a*Math.tan((M_-Math.acos((y+p-v)/(2*x*b)))/2),S=T/b,w=T/x;Math.abs(S-1)>Td&&this._append`L${e+S*f},${r+S*d}`,this._append`A${a},${a},0,0,${+(d*m>f*g)},${this._x1=e+w*u},${this._y1=r+w*h}`}}arc(e,r,n,i,a,s){if(e=+e,r=+r,n=+n,s=!!s,n<0)throw new Error(`negative radius: ${n}`);let l=n*Math.cos(i),u=n*Math.sin(i),h=e+l,f=r+u,d=1^s,p=s?i-a:a-i;this._x1===null?this._append`M${h},${f}`:(Math.abs(this._x1-h)>Td||Math.abs(this._y1-f)>Td)&&this._append`L${h},${f}`,n&&(p<0&&(p=p%I_+I_),p>bke?this._append`A${n},${n},0,1,${d},${e-l},${r-u}A${n},${n},0,1,${d},${this._x1=h},${this._y1=f}`:p>Td&&this._append`A${n},${n},0,${+(p>=M_)},${d},${this._x1=e+n*Math.cos(a)},${this._y1=r+n*Math.sin(a)}`)}rect(e,r,n,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}};o(bW,"path");bW.prototype=wd.prototype});var O_=N(()=>{"use strict";TW()});var wW=N(()=>{"use strict"});var kW=N(()=>{"use strict"});var EW=N(()=>{"use strict"});var SW=N(()=>{"use strict"});var CW=N(()=>{"use strict"});var AW=N(()=>{"use strict"});var _W=N(()=>{"use strict"});function P_(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function kd(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}var Dv=N(()=>{"use strict";o(P_,"default");o(kd,"formatDecimalParts")});function bl(t){return t=kd(Math.abs(t)),t?t[1]:NaN}var Lv=N(()=>{"use strict";Dv();o(bl,"default")});function B_(t,e){return function(r,n){for(var i=r.length,a=[],s=0,l=t[0],u=0;i>0&&l>0&&(u+l+1>n&&(l=Math.max(1,n-u)),a.push(r.substring(i-=l,i+l)),!((u+=l+1)>n));)l=t[s=(s+1)%t.length];return a.reverse().join(e)}}var DW=N(()=>{"use strict";o(B_,"default")});function F_(t){return function(e){return e.replace(/[0-9]/g,function(r){return t[+r]})}}var LW=N(()=>{"use strict";o(F_,"default")});function Lh(t){if(!(e=wke.exec(t)))throw new Error("invalid format: "+t);var e;return new T5({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function T5(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}var wke,$_=N(()=>{"use strict";wke=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;o(Lh,"formatSpecifier");Lh.prototype=T5.prototype;o(T5,"FormatSpecifier");T5.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type}});function z_(t){e:for(var e=t.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?t.slice(0,n)+t.slice(i+1):t}var RW=N(()=>{"use strict";o(z_,"default")});function V_(t,e){var r=kd(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(G_=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=n.length;return a===s?n:a>s?n+new Array(a-s+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+kd(t,Math.max(0,e+a-1))[0]}var G_,U_=N(()=>{"use strict";Dv();o(V_,"default")});function w5(t,e){var r=kd(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}var NW=N(()=>{"use strict";Dv();o(w5,"default")});var H_,MW=N(()=>{"use strict";Dv();U_();NW();H_={"%":o((t,e)=>(t*100).toFixed(e),"%"),b:o(t=>Math.round(t).toString(2),"b"),c:o(t=>t+"","c"),d:P_,e:o((t,e)=>t.toExponential(e),"e"),f:o((t,e)=>t.toFixed(e),"f"),g:o((t,e)=>t.toPrecision(e),"g"),o:o(t=>Math.round(t).toString(8),"o"),p:o((t,e)=>w5(t*100,e),"p"),r:w5,s:V_,X:o(t=>Math.round(t).toString(16).toUpperCase(),"X"),x:o(t=>Math.round(t).toString(16),"x")}});function k5(t){return t}var IW=N(()=>{"use strict";o(k5,"default")});function W_(t){var e=t.grouping===void 0||t.thousands===void 0?k5:B_(OW.call(t.grouping,Number),t.thousands+""),r=t.currency===void 0?"":t.currency[0]+"",n=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?k5:F_(OW.call(t.numerals,String)),s=t.percent===void 0?"%":t.percent+"",l=t.minus===void 0?"\u2212":t.minus+"",u=t.nan===void 0?"NaN":t.nan+"";function h(d){d=Lh(d);var p=d.fill,m=d.align,g=d.sign,y=d.symbol,v=d.zero,x=d.width,b=d.comma,T=d.precision,S=d.trim,w=d.type;w==="n"?(b=!0,w="g"):H_[w]||(T===void 0&&(T=12),S=!0,w="g"),(v||p==="0"&&m==="=")&&(v=!0,p="0",m="=");var E=y==="$"?r:y==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",_=y==="$"?n:/[%p]/.test(w)?s:"",C=H_[w],D=/[defgprs%]/.test(w);T=T===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,T)):Math.max(0,Math.min(20,T));function O(R){var k=E,L=_,A,I,M;if(w==="c")L=C(R)+L,R="";else{R=+R;var P=R<0||1/R<0;if(R=isNaN(R)?u:C(Math.abs(R),T),S&&(R=z_(R)),P&&+R==0&&g!=="+"&&(P=!1),k=(P?g==="("?g:l:g==="-"||g==="("?"":g)+k,L=(w==="s"?PW[8+G_/3]:"")+L+(P&&g==="("?")":""),D){for(A=-1,I=R.length;++AM||M>57){L=(M===46?i+R.slice(A+1):R.slice(A))+L,R=R.slice(0,A);break}}}b&&!v&&(R=e(R,1/0));var B=k.length+R.length+L.length,F=B>1)+k+R+L+F.slice(B);break;default:R=F+k+R+L;break}return a(R)}return o(O,"format"),O.toString=function(){return d+""},O}o(h,"newFormat");function f(d,p){var m=h((d=Lh(d),d.type="f",d)),g=Math.max(-8,Math.min(8,Math.floor(bl(p)/3)))*3,y=Math.pow(10,-g),v=PW[8+g/3];return function(x){return m(y*x)+v}}return o(f,"formatPrefix"),{format:h,formatPrefix:f}}var OW,PW,BW=N(()=>{"use strict";Lv();DW();LW();$_();RW();MW();U_();IW();OW=Array.prototype.map,PW=["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"];o(W_,"default")});function q_(t){return E5=W_(t),cc=E5.format,S5=E5.formatPrefix,E5}var E5,cc,S5,FW=N(()=>{"use strict";BW();q_({thousands:",",grouping:[3],currency:["$",""]});o(q_,"defaultLocale")});function C5(t){return Math.max(0,-bl(Math.abs(t)))}var $W=N(()=>{"use strict";Lv();o(C5,"default")});function A5(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(bl(e)/3)))*3-bl(Math.abs(t)))}var zW=N(()=>{"use strict";Lv();o(A5,"default")});function _5(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,bl(e)-bl(t))+1}var GW=N(()=>{"use strict";Lv();o(_5,"default")});var Y_=N(()=>{"use strict";FW();$_();$W();zW();GW()});var VW=N(()=>{"use strict"});function kke(t){var e=0,r=t.children,n=r&&r.length;if(!n)e=1;else for(;--n>=0;)e+=r[n].value;t.value=e}function X_(){return this.eachAfter(kke)}var UW=N(()=>{"use strict";o(kke,"count");o(X_,"default")});function j_(t,e){let r=-1;for(let n of this)t.call(e,n,++r,this);return this}var HW=N(()=>{"use strict";o(j_,"default")});function K_(t,e){for(var r=this,n=[r],i,a,s=-1;r=n.pop();)if(t.call(e,r,++s,this),i=r.children)for(a=i.length-1;a>=0;--a)n.push(i[a]);return this}var WW=N(()=>{"use strict";o(K_,"default")});function Q_(t,e){for(var r=this,n=[r],i=[],a,s,l,u=-1;r=n.pop();)if(i.push(r),a=r.children)for(s=0,l=a.length;s{"use strict";o(Q_,"default")});function Z_(t,e){let r=-1;for(let n of this)if(t.call(e,n,++r,this))return n}var YW=N(()=>{"use strict";o(Z_,"default")});function J_(t){return this.eachAfter(function(e){for(var r=+t(e.data)||0,n=e.children,i=n&&n.length;--i>=0;)r+=n[i].value;e.value=r})}var XW=N(()=>{"use strict";o(J_,"default")});function eD(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}var jW=N(()=>{"use strict";o(eD,"default")});function tD(t){for(var e=this,r=Eke(e,t),n=[e];e!==r;)e=e.parent,n.push(e);for(var i=n.length;t!==r;)n.splice(i,0,t),t=t.parent;return n}function Eke(t,e){if(t===e)return t;var r=t.ancestors(),n=e.ancestors(),i=null;for(t=r.pop(),e=n.pop();t===e;)i=t,t=r.pop(),e=n.pop();return i}var KW=N(()=>{"use strict";o(tD,"default");o(Eke,"leastCommonAncestor")});function rD(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}var QW=N(()=>{"use strict";o(rD,"default")});function nD(){return Array.from(this)}var ZW=N(()=>{"use strict";o(nD,"default")});function iD(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}var JW=N(()=>{"use strict";o(iD,"default")});function aD(){var t=this,e=[];return t.each(function(r){r!==t&&e.push({source:r.parent,target:r})}),e}var eq=N(()=>{"use strict";o(aD,"default")});function*sD(){var t=this,e,r=[t],n,i,a;do for(e=r.reverse(),r=[];t=e.pop();)if(yield t,n=t.children)for(i=0,a=n.length;i{"use strict";o(sD,"default")});function z0(t,e){t instanceof Map?(t=[void 0,t],e===void 0&&(e=Ake)):e===void 0&&(e=Cke);for(var r=new Rv(t),n,i=[r],a,s,l,u;n=i.pop();)if((s=e(n.data))&&(u=(s=Array.from(s)).length))for(n.children=s,l=u-1;l>=0;--l)i.push(a=s[l]=new Rv(s[l])),a.parent=n,a.depth=n.depth+1;return r.eachBefore(Dke)}function Ske(){return z0(this).eachBefore(_ke)}function Cke(t){return t.children}function Ake(t){return Array.isArray(t)?t[1]:null}function _ke(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function Dke(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Rv(t){this.data=t,this.depth=this.height=0,this.parent=null}var rq=N(()=>{"use strict";UW();HW();WW();qW();YW();XW();jW();KW();QW();ZW();JW();eq();tq();o(z0,"hierarchy");o(Ske,"node_copy");o(Cke,"objectChildren");o(Ake,"mapChildren");o(_ke,"copyData");o(Dke,"computeHeight");o(Rv,"Node");Rv.prototype=z0.prototype={constructor:Rv,count:X_,each:j_,eachAfter:Q_,eachBefore:K_,find:Z_,sum:J_,sort:eD,path:tD,ancestors:rD,descendants:nD,leaves:iD,links:aD,copy:Ske,[Symbol.iterator]:sD}});function nq(t){if(typeof t!="function")throw new Error;return t}var iq=N(()=>{"use strict";o(nq,"required")});function G0(){return 0}function Ed(t){return function(){return t}}var aq=N(()=>{"use strict";o(G0,"constantZero");o(Ed,"default")});function oD(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)}var sq=N(()=>{"use strict";o(oD,"default")});function lD(t,e,r,n,i){for(var a=t.children,s,l=-1,u=a.length,h=t.value&&(n-e)/t.value;++l{"use strict";o(lD,"default")});function cD(t,e,r,n,i){for(var a=t.children,s,l=-1,u=a.length,h=t.value&&(i-r)/t.value;++l{"use strict";o(cD,"default")});function Rke(t,e,r,n,i,a){for(var s=[],l=e.children,u,h,f=0,d=0,p=l.length,m,g,y=e.value,v,x,b,T,S,w,E;fb&&(b=h),E=v*v*w,T=Math.max(b/E,E/x),T>S){v-=h;break}S=T}s.push(u={value:v,dice:m{"use strict";oq();lq();Lke=(1+Math.sqrt(5))/2;o(Rke,"squarifyRatio");cq=o(function t(e){function r(n,i,a,s,l){Rke(e,n,i,a,s,l)}return o(r,"squarify"),r.ratio=function(n){return t((n=+n)>1?n:1)},r},"custom")(Lke)});function D5(){var t=cq,e=!1,r=1,n=1,i=[0],a=G0,s=G0,l=G0,u=G0,h=G0;function f(p){return p.x0=p.y0=0,p.x1=r,p.y1=n,p.eachBefore(d),i=[0],e&&p.eachBefore(oD),p}o(f,"treemap");function d(p){var m=i[p.depth],g=p.x0+m,y=p.y0+m,v=p.x1-m,x=p.y1-m;v{"use strict";sq();uq();iq();aq();o(D5,"default")});var fq=N(()=>{"use strict";rq();hq()});var dq=N(()=>{"use strict"});var pq=N(()=>{"use strict"});function Rh(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}var Nv=N(()=>{"use strict";o(Rh,"initRange")});function Js(){var t=new C0,e=[],r=[],n=uD;function i(a){let s=t.get(a);if(s===void 0){if(n!==uD)return n;t.set(a,s=e.push(a)-1)}return r[s%r.length]}return o(i,"scale"),i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new C0;for(let s of a)t.has(s)||t.set(s,e.push(s)-1);return i},i.range=function(a){return arguments.length?(r=Array.from(a),i):r.slice()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return Js(e,r).unknown(n)},Rh.apply(i,arguments),i}var uD,hD=N(()=>{"use strict";Eh();Nv();uD=Symbol("implicit");o(Js,"ordinal")});function V0(){var t=Js().unknown(void 0),e=t.domain,r=t.range,n=0,i=1,a,s,l=!1,u=0,h=0,f=.5;delete t.unknown;function d(){var p=e().length,m=i{"use strict";Eh();Nv();hD();o(V0,"band")});function fD(t){return function(){return t}}var gq=N(()=>{"use strict";o(fD,"constants")});function dD(t){return+t}var yq=N(()=>{"use strict";o(dD,"number")});function U0(t){return t}function pD(t,e){return(e-=t=+t)?function(r){return(r-t)/e}:fD(isNaN(e)?NaN:.5)}function Nke(t,e){var r;return t>e&&(r=t,t=e,e=r),function(n){return Math.max(t,Math.min(e,n))}}function Mke(t,e,r){var n=t[0],i=t[1],a=e[0],s=e[1];return i2?Ike:Mke,u=h=null,d}o(f,"rescale");function d(p){return p==null||isNaN(p=+p)?a:(u||(u=l(t.map(n),e,r)))(n(s(p)))}return o(d,"scale"),d.invert=function(p){return s(i((h||(h=l(e,t.map(n),Ki)))(p)))},d.domain=function(p){return arguments.length?(t=Array.from(p,dD),f()):t.slice()},d.range=function(p){return arguments.length?(e=Array.from(p),f()):e.slice()},d.rangeRound=function(p){return e=Array.from(p),r=s5,f()},d.clamp=function(p){return arguments.length?(s=p?!0:U0,f()):s!==U0},d.interpolate=function(p){return arguments.length?(r=p,f()):r},d.unknown=function(p){return arguments.length?(a=p,d):a},function(p,m){return n=p,i=m,f()}}function Mv(){return Oke()(U0,U0)}var vq,mD=N(()=>{"use strict";Eh();B0();gq();yq();vq=[0,1];o(U0,"identity");o(pD,"normalize");o(Nke,"clamper");o(Mke,"bimap");o(Ike,"polymap");o(L5,"copy");o(Oke,"transformer");o(Mv,"continuous")});function gD(t,e,r,n){var i=A0(t,e,r),a;switch(n=Lh(n??",f"),n.type){case"s":{var s=Math.max(Math.abs(t),Math.abs(e));return n.precision==null&&!isNaN(a=A5(i,s))&&(n.precision=a),S5(n,s)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=_5(i,Math.max(Math.abs(t),Math.abs(e))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=C5(i))&&(n.precision=a-(n.type==="%")*2);break}}return cc(n)}var xq=N(()=>{"use strict";Eh();Y_();o(gD,"tickFormat")});function Pke(t){var e=t.domain;return t.ticks=function(r){var n=e();return U3(n[0],n[n.length-1],r??10)},t.tickFormat=function(r,n){var i=e();return gD(i[0],i[i.length-1],r??10,n)},t.nice=function(r){r==null&&(r=10);var n=e(),i=0,a=n.length-1,s=n[i],l=n[a],u,h,f=10;for(l0;){if(h=ov(s,l,r),h===u)return n[i]=s,n[a]=l,e(n);if(h>0)s=Math.floor(s/h)*h,l=Math.ceil(l/h)*h;else if(h<0)s=Math.ceil(s*h)/h,l=Math.floor(l*h)/h;else break;u=h}return t},t}function Tl(){var t=Mv();return t.copy=function(){return L5(t,Tl())},Rh.apply(t,arguments),Pke(t)}var bq=N(()=>{"use strict";Eh();mD();Nv();xq();o(Pke,"linearish");o(Tl,"linear")});function yD(t,e){t=t.slice();var r=0,n=t.length-1,i=t[r],a=t[n],s;return a{"use strict";o(yD,"nice")});function xn(t,e,r,n){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return o(i,"interval"),i.floor=a=>(t(a=new Date(+a)),a),i.ceil=a=>(t(a=new Date(a-1)),e(a,1),t(a),a),i.round=a=>{let s=i(a),l=i.ceil(a);return a-s(e(a=new Date(+a),s==null?1:Math.floor(s)),a),i.range=(a,s,l)=>{let u=[];if(a=i.ceil(a),l=l==null?1:Math.floor(l),!(a0))return u;let h;do u.push(h=new Date(+a)),e(a,l),t(a);while(hxn(s=>{if(s>=s)for(;t(s),!a(s);)s.setTime(s-1)},(s,l)=>{if(s>=s)if(l<0)for(;++l<=0;)for(;e(s,-1),!a(s););else for(;--l>=0;)for(;e(s,1),!a(s););}),r&&(i.count=(a,s)=>(vD.setTime(+a),xD.setTime(+s),t(vD),t(xD),Math.floor(r(vD,xD))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?s=>n(s)%a===0:s=>i.count(0,s)%a===0):i)),i}var vD,xD,Tu=N(()=>{"use strict";vD=new Date,xD=new Date;o(xn,"timeInterval")});var uc,wq,bD=N(()=>{"use strict";Tu();uc=xn(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);uc.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?xn(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):uc);wq=uc.range});var eo,kq,TD=N(()=>{"use strict";Tu();eo=xn(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*1e3)},(t,e)=>(e-t)/1e3,t=>t.getUTCSeconds()),kq=eo.range});var wu,Bke,R5,Fke,wD=N(()=>{"use strict";Tu();wu=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getMinutes()),Bke=wu.range,R5=xn(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getUTCMinutes()),Fke=R5.range});var ku,$ke,N5,zke,kD=N(()=>{"use strict";Tu();ku=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3-t.getMinutes()*6e4)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getHours()),$ke=ku.range,N5=xn(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getUTCHours()),zke=N5.range});var Ro,Gke,Ov,Vke,M5,Uke,ED=N(()=>{"use strict";Tu();Ro=xn(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5,t=>t.getDate()-1),Gke=Ro.range,Ov=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>t.getUTCDate()-1),Vke=Ov.range,M5=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>Math.floor(t/864e5)),Uke=M5.range});function Ad(t){return xn(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,r)=>{e.setDate(e.getDate()+r*7)},(e,r)=>(r-e-(r.getTimezoneOffset()-e.getTimezoneOffset())*6e4)/6048e5)}function _d(t){return xn(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCDate(e.getUTCDate()+r*7)},(e,r)=>(r-e)/6048e5)}var wl,Nh,I5,O5,fc,P5,B5,Sq,Hke,Wke,qke,Yke,Xke,jke,Dd,H0,Cq,Aq,Mh,_q,Dq,Lq,Kke,Qke,Zke,Jke,eEe,tEe,SD=N(()=>{"use strict";Tu();o(Ad,"timeWeekday");wl=Ad(0),Nh=Ad(1),I5=Ad(2),O5=Ad(3),fc=Ad(4),P5=Ad(5),B5=Ad(6),Sq=wl.range,Hke=Nh.range,Wke=I5.range,qke=O5.range,Yke=fc.range,Xke=P5.range,jke=B5.range;o(_d,"utcWeekday");Dd=_d(0),H0=_d(1),Cq=_d(2),Aq=_d(3),Mh=_d(4),_q=_d(5),Dq=_d(6),Lq=Dd.range,Kke=H0.range,Qke=Cq.range,Zke=Aq.range,Jke=Mh.range,eEe=_q.range,tEe=Dq.range});var Eu,rEe,F5,nEe,CD=N(()=>{"use strict";Tu();Eu=xn(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth()),rEe=Eu.range,F5=xn(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth()),nEe=F5.range});var to,iEe,kl,aEe,AD=N(()=>{"use strict";Tu();to=xn(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());to.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)});iEe=to.range,kl=xn(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());kl.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)});aEe=kl.range});function Nq(t,e,r,n,i,a){let s=[[eo,1,1e3],[eo,5,5*1e3],[eo,15,15*1e3],[eo,30,30*1e3],[a,1,6e4],[a,5,5*6e4],[a,15,15*6e4],[a,30,30*6e4],[i,1,36e5],[i,3,3*36e5],[i,6,6*36e5],[i,12,12*36e5],[n,1,864e5],[n,2,2*864e5],[r,1,6048e5],[e,1,2592e6],[e,3,3*2592e6],[t,1,31536e6]];function l(h,f,d){let p=fv).right(s,p);if(m===s.length)return t.every(A0(h/31536e6,f/31536e6,d));if(m===0)return uc.every(Math.max(A0(h,f,d),1));let[g,y]=s[p/s[m-1][2]{"use strict";Eh();bD();TD();wD();kD();ED();SD();CD();AD();o(Nq,"ticker");[oEe,lEe]=Nq(kl,F5,Dd,M5,N5,R5),[_D,DD]=Nq(to,Eu,wl,Ro,ku,wu)});var $5=N(()=>{"use strict";bD();TD();wD();kD();ED();SD();CD();AD();Mq()});function LD(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function RD(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Pv(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}function ND(t){var e=t.dateTime,r=t.date,n=t.time,i=t.periods,a=t.days,s=t.shortDays,l=t.months,u=t.shortMonths,h=Bv(i),f=Fv(i),d=Bv(a),p=Fv(a),m=Bv(s),g=Fv(s),y=Bv(l),v=Fv(l),x=Bv(u),b=Fv(u),T={a:P,A:B,b:F,B:z,c:null,d:$q,e:$q,f:REe,g:GEe,G:UEe,H:_Ee,I:DEe,j:LEe,L:Hq,m:NEe,M:MEe,p:$,q:U,Q:Vq,s:Uq,S:IEe,u:OEe,U:PEe,V:BEe,w:FEe,W:$Ee,x:null,X:null,y:zEe,Y:VEe,Z:HEe,"%":Gq},S={a:K,A:ee,b:Y,B:ce,c:null,d:zq,e:zq,f:XEe,g:iSe,G:sSe,H:WEe,I:qEe,j:YEe,L:qq,m:jEe,M:KEe,p:Z,q:ue,Q:Vq,s:Uq,S:QEe,u:ZEe,U:JEe,V:eSe,w:tSe,W:rSe,x:null,X:null,y:nSe,Y:aSe,Z:oSe,"%":Gq},w={a:O,A:R,b:k,B:L,c:A,d:Bq,e:Bq,f:EEe,g:Pq,G:Oq,H:Fq,I:Fq,j:bEe,L:kEe,m:xEe,M:TEe,p:D,q:vEe,Q:CEe,s:AEe,S:wEe,u:dEe,U:pEe,V:mEe,w:fEe,W:gEe,x:I,X:M,y:Pq,Y:Oq,Z:yEe,"%":SEe};T.x=E(r,T),T.X=E(n,T),T.c=E(e,T),S.x=E(r,S),S.X=E(n,S),S.c=E(e,S);function E(Q,j){return function(ne){var te=[],he=-1,le=0,J=Q.length,Se,se,ae;for(ne instanceof Date||(ne=new Date(+ne));++he53)return null;"w"in te||(te.w=1),"Z"in te?(le=RD(Pv(te.y,0,1)),J=le.getUTCDay(),le=J>4||J===0?H0.ceil(le):H0(le),le=Ov.offset(le,(te.V-1)*7),te.y=le.getUTCFullYear(),te.m=le.getUTCMonth(),te.d=le.getUTCDate()+(te.w+6)%7):(le=LD(Pv(te.y,0,1)),J=le.getDay(),le=J>4||J===0?Nh.ceil(le):Nh(le),le=Ro.offset(le,(te.V-1)*7),te.y=le.getFullYear(),te.m=le.getMonth(),te.d=le.getDate()+(te.w+6)%7)}else("W"in te||"U"in te)&&("w"in te||(te.w="u"in te?te.u%7:"W"in te?1:0),J="Z"in te?RD(Pv(te.y,0,1)).getUTCDay():LD(Pv(te.y,0,1)).getDay(),te.m=0,te.d="W"in te?(te.w+6)%7+te.W*7-(J+5)%7:te.w+te.U*7-(J+6)%7);return"Z"in te?(te.H+=te.Z/100|0,te.M+=te.Z%100,RD(te)):LD(te)}}o(_,"newParse");function C(Q,j,ne,te){for(var he=0,le=j.length,J=ne.length,Se,se;he=J)return-1;if(Se=j.charCodeAt(he++),Se===37){if(Se=j.charAt(he++),se=w[Se in Iq?j.charAt(he++):Se],!se||(te=se(Q,ne,te))<0)return-1}else if(Se!=ne.charCodeAt(te++))return-1}return te}o(C,"parseSpecifier");function D(Q,j,ne){var te=h.exec(j.slice(ne));return te?(Q.p=f.get(te[0].toLowerCase()),ne+te[0].length):-1}o(D,"parsePeriod");function O(Q,j,ne){var te=m.exec(j.slice(ne));return te?(Q.w=g.get(te[0].toLowerCase()),ne+te[0].length):-1}o(O,"parseShortWeekday");function R(Q,j,ne){var te=d.exec(j.slice(ne));return te?(Q.w=p.get(te[0].toLowerCase()),ne+te[0].length):-1}o(R,"parseWeekday");function k(Q,j,ne){var te=x.exec(j.slice(ne));return te?(Q.m=b.get(te[0].toLowerCase()),ne+te[0].length):-1}o(k,"parseShortMonth");function L(Q,j,ne){var te=y.exec(j.slice(ne));return te?(Q.m=v.get(te[0].toLowerCase()),ne+te[0].length):-1}o(L,"parseMonth");function A(Q,j,ne){return C(Q,e,j,ne)}o(A,"parseLocaleDateTime");function I(Q,j,ne){return C(Q,r,j,ne)}o(I,"parseLocaleDate");function M(Q,j,ne){return C(Q,n,j,ne)}o(M,"parseLocaleTime");function P(Q){return s[Q.getDay()]}o(P,"formatShortWeekday");function B(Q){return a[Q.getDay()]}o(B,"formatWeekday");function F(Q){return u[Q.getMonth()]}o(F,"formatShortMonth");function z(Q){return l[Q.getMonth()]}o(z,"formatMonth");function $(Q){return i[+(Q.getHours()>=12)]}o($,"formatPeriod");function U(Q){return 1+~~(Q.getMonth()/3)}o(U,"formatQuarter");function K(Q){return s[Q.getUTCDay()]}o(K,"formatUTCShortWeekday");function ee(Q){return a[Q.getUTCDay()]}o(ee,"formatUTCWeekday");function Y(Q){return u[Q.getUTCMonth()]}o(Y,"formatUTCShortMonth");function ce(Q){return l[Q.getUTCMonth()]}o(ce,"formatUTCMonth");function Z(Q){return i[+(Q.getUTCHours()>=12)]}o(Z,"formatUTCPeriod");function ue(Q){return 1+~~(Q.getUTCMonth()/3)}return o(ue,"formatUTCQuarter"),{format:o(function(Q){var j=E(Q+="",T);return j.toString=function(){return Q},j},"format"),parse:o(function(Q){var j=_(Q+="",!1);return j.toString=function(){return Q},j},"parse"),utcFormat:o(function(Q){var j=E(Q+="",S);return j.toString=function(){return Q},j},"utcFormat"),utcParse:o(function(Q){var j=_(Q+="",!0);return j.toString=function(){return Q},j},"utcParse")}}function Wr(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a[e.toLowerCase(),r]))}function fEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function dEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function pEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function mEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function gEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function Oq(t,e,r){var n=Qi.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function Pq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function yEe(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function vEe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.q=n[0]*3-3,r+n[0].length):-1}function xEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function Bq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function bEe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function Fq(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function TEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function wEe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function kEe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function EEe(t,e,r){var n=Qi.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function SEe(t,e,r){var n=cEe.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function CEe(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function AEe(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function $q(t,e){return Wr(t.getDate(),e,2)}function _Ee(t,e){return Wr(t.getHours(),e,2)}function DEe(t,e){return Wr(t.getHours()%12||12,e,2)}function LEe(t,e){return Wr(1+Ro.count(to(t),t),e,3)}function Hq(t,e){return Wr(t.getMilliseconds(),e,3)}function REe(t,e){return Hq(t,e)+"000"}function NEe(t,e){return Wr(t.getMonth()+1,e,2)}function MEe(t,e){return Wr(t.getMinutes(),e,2)}function IEe(t,e){return Wr(t.getSeconds(),e,2)}function OEe(t){var e=t.getDay();return e===0?7:e}function PEe(t,e){return Wr(wl.count(to(t)-1,t),e,2)}function Wq(t){var e=t.getDay();return e>=4||e===0?fc(t):fc.ceil(t)}function BEe(t,e){return t=Wq(t),Wr(fc.count(to(t),t)+(to(t).getDay()===4),e,2)}function FEe(t){return t.getDay()}function $Ee(t,e){return Wr(Nh.count(to(t)-1,t),e,2)}function zEe(t,e){return Wr(t.getFullYear()%100,e,2)}function GEe(t,e){return t=Wq(t),Wr(t.getFullYear()%100,e,2)}function VEe(t,e){return Wr(t.getFullYear()%1e4,e,4)}function UEe(t,e){var r=t.getDay();return t=r>=4||r===0?fc(t):fc.ceil(t),Wr(t.getFullYear()%1e4,e,4)}function HEe(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Wr(e/60|0,"0",2)+Wr(e%60,"0",2)}function zq(t,e){return Wr(t.getUTCDate(),e,2)}function WEe(t,e){return Wr(t.getUTCHours(),e,2)}function qEe(t,e){return Wr(t.getUTCHours()%12||12,e,2)}function YEe(t,e){return Wr(1+Ov.count(kl(t),t),e,3)}function qq(t,e){return Wr(t.getUTCMilliseconds(),e,3)}function XEe(t,e){return qq(t,e)+"000"}function jEe(t,e){return Wr(t.getUTCMonth()+1,e,2)}function KEe(t,e){return Wr(t.getUTCMinutes(),e,2)}function QEe(t,e){return Wr(t.getUTCSeconds(),e,2)}function ZEe(t){var e=t.getUTCDay();return e===0?7:e}function JEe(t,e){return Wr(Dd.count(kl(t)-1,t),e,2)}function Yq(t){var e=t.getUTCDay();return e>=4||e===0?Mh(t):Mh.ceil(t)}function eSe(t,e){return t=Yq(t),Wr(Mh.count(kl(t),t)+(kl(t).getUTCDay()===4),e,2)}function tSe(t){return t.getUTCDay()}function rSe(t,e){return Wr(H0.count(kl(t)-1,t),e,2)}function nSe(t,e){return Wr(t.getUTCFullYear()%100,e,2)}function iSe(t,e){return t=Yq(t),Wr(t.getUTCFullYear()%100,e,2)}function aSe(t,e){return Wr(t.getUTCFullYear()%1e4,e,4)}function sSe(t,e){var r=t.getUTCDay();return t=r>=4||r===0?Mh(t):Mh.ceil(t),Wr(t.getUTCFullYear()%1e4,e,4)}function oSe(){return"+0000"}function Gq(){return"%"}function Vq(t){return+t}function Uq(t){return Math.floor(+t/1e3)}var Iq,Qi,cEe,uEe,Xq=N(()=>{"use strict";$5();o(LD,"localDate");o(RD,"utcDate");o(Pv,"newDate");o(ND,"formatLocale");Iq={"-":"",_:" ",0:"0"},Qi=/^\s*\d+/,cEe=/^%/,uEe=/[\\^$*+?|[\]().{}]/g;o(Wr,"pad");o(hEe,"requote");o(Bv,"formatRe");o(Fv,"formatLookup");o(fEe,"parseWeekdayNumberSunday");o(dEe,"parseWeekdayNumberMonday");o(pEe,"parseWeekNumberSunday");o(mEe,"parseWeekNumberISO");o(gEe,"parseWeekNumberMonday");o(Oq,"parseFullYear");o(Pq,"parseYear");o(yEe,"parseZone");o(vEe,"parseQuarter");o(xEe,"parseMonthNumber");o(Bq,"parseDayOfMonth");o(bEe,"parseDayOfYear");o(Fq,"parseHour24");o(TEe,"parseMinutes");o(wEe,"parseSeconds");o(kEe,"parseMilliseconds");o(EEe,"parseMicroseconds");o(SEe,"parseLiteralPercent");o(CEe,"parseUnixTimestamp");o(AEe,"parseUnixTimestampSeconds");o($q,"formatDayOfMonth");o(_Ee,"formatHour24");o(DEe,"formatHour12");o(LEe,"formatDayOfYear");o(Hq,"formatMilliseconds");o(REe,"formatMicroseconds");o(NEe,"formatMonthNumber");o(MEe,"formatMinutes");o(IEe,"formatSeconds");o(OEe,"formatWeekdayNumberMonday");o(PEe,"formatWeekNumberSunday");o(Wq,"dISO");o(BEe,"formatWeekNumberISO");o(FEe,"formatWeekdayNumberSunday");o($Ee,"formatWeekNumberMonday");o(zEe,"formatYear");o(GEe,"formatYearISO");o(VEe,"formatFullYear");o(UEe,"formatFullYearISO");o(HEe,"formatZone");o(zq,"formatUTCDayOfMonth");o(WEe,"formatUTCHour24");o(qEe,"formatUTCHour12");o(YEe,"formatUTCDayOfYear");o(qq,"formatUTCMilliseconds");o(XEe,"formatUTCMicroseconds");o(jEe,"formatUTCMonthNumber");o(KEe,"formatUTCMinutes");o(QEe,"formatUTCSeconds");o(ZEe,"formatUTCWeekdayNumberMonday");o(JEe,"formatUTCWeekNumberSunday");o(Yq,"UTCdISO");o(eSe,"formatUTCWeekNumberISO");o(tSe,"formatUTCWeekdayNumberSunday");o(rSe,"formatUTCWeekNumberMonday");o(nSe,"formatUTCYear");o(iSe,"formatUTCYearISO");o(aSe,"formatUTCFullYear");o(sSe,"formatUTCFullYearISO");o(oSe,"formatUTCZone");o(Gq,"formatLiteralPercent");o(Vq,"formatUnixTimestamp");o(Uq,"formatUnixTimestampSeconds")});function MD(t){return W0=ND(t),Ld=W0.format,jq=W0.parse,Kq=W0.utcFormat,Qq=W0.utcParse,W0}var W0,Ld,jq,Kq,Qq,Zq=N(()=>{"use strict";Xq();MD({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});o(MD,"defaultLocale")});var ID=N(()=>{"use strict";Zq()});function lSe(t){return new Date(t)}function cSe(t){return t instanceof Date?+t:+new Date(+t)}function Jq(t,e,r,n,i,a,s,l,u,h){var f=Mv(),d=f.invert,p=f.domain,m=h(".%L"),g=h(":%S"),y=h("%I:%M"),v=h("%I %p"),x=h("%a %d"),b=h("%b %d"),T=h("%B"),S=h("%Y");function w(E){return(u(E){"use strict";$5();ID();mD();Nv();Tq();o(lSe,"date");o(cSe,"number");o(Jq,"calendar");o(z5,"time")});var tY=N(()=>{"use strict";mq();bq();hD();eY()});function OD(t){for(var e=t.length/6|0,r=new Array(e),n=0;n{"use strict";o(OD,"default")});var PD,nY=N(()=>{"use strict";rY();PD=OD("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab")});var iY=N(()=>{"use strict";nY()});function Bn(t){return o(function(){return t},"constant")}var G5=N(()=>{"use strict";o(Bn,"default")});function sY(t){return t>1?0:t<-1?q0:Math.acos(t)}function FD(t){return t>=1?$v:t<=-1?-$v:Math.asin(t)}var BD,ha,Ih,aY,V5,El,Rd,Zi,q0,$v,Y0,U5=N(()=>{"use strict";BD=Math.abs,ha=Math.atan2,Ih=Math.cos,aY=Math.max,V5=Math.min,El=Math.sin,Rd=Math.sqrt,Zi=1e-12,q0=Math.PI,$v=q0/2,Y0=2*q0;o(sY,"acos");o(FD,"asin")});function H5(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(r==null)e=null;else{let n=Math.floor(r);if(!(n>=0))throw new RangeError(`invalid digits: ${r}`);e=n}return t},()=>new wd(e)}var $D=N(()=>{"use strict";O_();o(H5,"withPath")});function uSe(t){return t.innerRadius}function hSe(t){return t.outerRadius}function fSe(t){return t.startAngle}function dSe(t){return t.endAngle}function pSe(t){return t&&t.padAngle}function mSe(t,e,r,n,i,a,s,l){var u=r-t,h=n-e,f=s-i,d=l-a,p=d*u-f*h;if(!(p*pA*A+I*I&&(C=O,D=R),{cx:C,cy:D,x01:-f,y01:-d,x11:C*(i/w-1),y11:D*(i/w-1)}}function Sl(){var t=uSe,e=hSe,r=Bn(0),n=null,i=fSe,a=dSe,s=pSe,l=null,u=H5(h);function h(){var f,d,p=+t.apply(this,arguments),m=+e.apply(this,arguments),g=i.apply(this,arguments)-$v,y=a.apply(this,arguments)-$v,v=BD(y-g),x=y>g;if(l||(l=f=u()),mZi))l.moveTo(0,0);else if(v>Y0-Zi)l.moveTo(m*Ih(g),m*El(g)),l.arc(0,0,m,g,y,!x),p>Zi&&(l.moveTo(p*Ih(y),p*El(y)),l.arc(0,0,p,y,g,x));else{var b=g,T=y,S=g,w=y,E=v,_=v,C=s.apply(this,arguments)/2,D=C>Zi&&(n?+n.apply(this,arguments):Rd(p*p+m*m)),O=V5(BD(m-p)/2,+r.apply(this,arguments)),R=O,k=O,L,A;if(D>Zi){var I=FD(D/p*El(C)),M=FD(D/m*El(C));(E-=I*2)>Zi?(I*=x?1:-1,S+=I,w-=I):(E=0,S=w=(g+y)/2),(_-=M*2)>Zi?(M*=x?1:-1,b+=M,T-=M):(_=0,b=T=(g+y)/2)}var P=m*Ih(b),B=m*El(b),F=p*Ih(w),z=p*El(w);if(O>Zi){var $=m*Ih(T),U=m*El(T),K=p*Ih(S),ee=p*El(S),Y;if(vZi?k>Zi?(L=W5(K,ee,P,B,m,k,x),A=W5($,U,F,z,m,k,x),l.moveTo(L.cx+L.x01,L.cy+L.y01),kZi)||!(E>Zi)?l.lineTo(F,z):R>Zi?(L=W5(F,z,$,U,p,-R,x),A=W5(P,B,K,ee,p,-R,x),l.lineTo(L.cx+L.x01,L.cy+L.y01),R{"use strict";G5();U5();$D();o(uSe,"arcInnerRadius");o(hSe,"arcOuterRadius");o(fSe,"arcStartAngle");o(dSe,"arcEndAngle");o(pSe,"arcPadAngle");o(mSe,"intersect");o(W5,"cornerTangents");o(Sl,"default")});function zv(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}var yxt,zD=N(()=>{"use strict";yxt=Array.prototype.slice;o(zv,"default")});function lY(t){this._context=t}function Su(t){return new lY(t)}var GD=N(()=>{"use strict";o(lY,"Linear");lY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e);break}},"point")};o(Su,"default")});function cY(t){return t[0]}function uY(t){return t[1]}var hY=N(()=>{"use strict";o(cY,"x");o(uY,"y")});function Cl(t,e){var r=Bn(!0),n=null,i=Su,a=null,s=H5(l);t=typeof t=="function"?t:t===void 0?cY:Bn(t),e=typeof e=="function"?e:e===void 0?uY:Bn(e);function l(u){var h,f=(u=zv(u)).length,d,p=!1,m;for(n==null&&(a=i(m=s())),h=0;h<=f;++h)!(h{"use strict";zD();G5();GD();$D();hY();o(Cl,"default")});function VD(t,e){return et?1:e>=t?0:NaN}var dY=N(()=>{"use strict";o(VD,"default")});function UD(t){return t}var pY=N(()=>{"use strict";o(UD,"default")});function q5(){var t=UD,e=VD,r=null,n=Bn(0),i=Bn(Y0),a=Bn(0);function s(l){var u,h=(l=zv(l)).length,f,d,p=0,m=new Array(h),g=new Array(h),y=+n.apply(this,arguments),v=Math.min(Y0,Math.max(-Y0,i.apply(this,arguments)-y)),x,b=Math.min(Math.abs(v)/h,a.apply(this,arguments)),T=b*(v<0?-1:1),S;for(u=0;u0&&(p+=S);for(e!=null?m.sort(function(w,E){return e(g[w],g[E])}):r!=null&&m.sort(function(w,E){return r(l[w],l[E])}),u=0,d=p?(v-h*T)/p:0;u0?S*d:0)+T,g[f]={data:l[f],index:u,value:S,startAngle:y,endAngle:x,padAngle:b};return g}return o(s,"pie"),s.value=function(l){return arguments.length?(t=typeof l=="function"?l:Bn(+l),s):t},s.sortValues=function(l){return arguments.length?(e=l,r=null,s):e},s.sort=function(l){return arguments.length?(r=l,e=null,s):r},s.startAngle=function(l){return arguments.length?(n=typeof l=="function"?l:Bn(+l),s):n},s.endAngle=function(l){return arguments.length?(i=typeof l=="function"?l:Bn(+l),s):i},s.padAngle=function(l){return arguments.length?(a=typeof l=="function"?l:Bn(+l),s):a},s}var mY=N(()=>{"use strict";zD();G5();dY();pY();U5();o(q5,"default")});function Gv(t){return new Y5(t,!0)}function Vv(t){return new Y5(t,!1)}var Y5,gY=N(()=>{"use strict";Y5=class{static{o(this,"Bump")}constructor(e,r){this._context=e,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,r){switch(e=+e,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,r,e,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,e,this._y0,e,r);break}}this._x0=e,this._y0=r}};o(Gv,"bumpX");o(Vv,"bumpY")});function ro(){}var Uv=N(()=>{"use strict";o(ro,"default")});function X0(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function Hv(t){this._context=t}function No(t){return new Hv(t)}var Wv=N(()=>{"use strict";o(X0,"point");o(Hv,"Basis");Hv.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 3:X0(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(No,"default")});function yY(t){this._context=t}function X5(t){return new yY(t)}var vY=N(()=>{"use strict";Uv();Wv();o(yY,"BasisClosed");yY.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(X5,"default")});function xY(t){this._context=t}function j5(t){return new xY(t)}var bY=N(()=>{"use strict";Wv();o(xY,"BasisOpen");xY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:X0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(j5,"default")});function TY(t,e){this._basis=new Hv(t),this._beta=e}var HD,wY=N(()=>{"use strict";Wv();o(TY,"Bundle");TY.prototype={lineStart:o(function(){this._x=[],this._y=[],this._basis.lineStart()},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n=t[0],i=e[0],a=t[r]-n,s=e[r]-i,l=-1,u;++l<=r;)u=l/r,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+u*a),this._beta*e[l]+(1-this._beta)*(i+u*s));this._x=this._y=null,this._basis.lineEnd()},"lineEnd"),point:o(function(t,e){this._x.push(+t),this._y.push(+e)},"point")};HD=o(function t(e){function r(n){return e===1?new Hv(n):new TY(n,e)}return o(r,"bundle"),r.beta=function(n){return t(+n)},r},"custom")(.85)});function j0(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function K5(t,e){this._context=t,this._k=(1-e)/6}var qv,Yv=N(()=>{"use strict";o(j0,"point");o(K5,"Cardinal");K5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:j0(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};qv=o(function t(e){function r(n){return new K5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Q5(t,e){this._context=t,this._k=(1-e)/6}var WD,qD=N(()=>{"use strict";Uv();Yv();o(Q5,"CardinalClosed");Q5.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};WD=o(function t(e){function r(n){return new Q5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Z5(t,e){this._context=t,this._k=(1-e)/6}var YD,XD=N(()=>{"use strict";Yv();o(Z5,"CardinalOpen");Z5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:j0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};YD=o(function t(e){function r(n){return new Z5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Xv(t,e,r){var n=t._x1,i=t._y1,a=t._x2,s=t._y2;if(t._l01_a>Zi){var l=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,u=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*l-t._x0*t._l12_2a+t._x2*t._l01_2a)/u,i=(i*l-t._y0*t._l12_2a+t._y2*t._l01_2a)/u}if(t._l23_a>Zi){var h=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*h+t._x1*t._l23_2a-e*t._l12_2a)/f,s=(s*h+t._y1*t._l23_2a-r*t._l12_2a)/f}t._context.bezierCurveTo(n,i,a,s,t._x2,t._y2)}function kY(t,e){this._context=t,this._alpha=e}var jv,J5=N(()=>{"use strict";U5();Yv();o(Xv,"point");o(kY,"CatmullRom");kY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};jv=o(function t(e){function r(n){return e?new kY(n,e):new K5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function EY(t,e){this._context=t,this._alpha=e}var jD,SY=N(()=>{"use strict";qD();Uv();J5();o(EY,"CatmullRomClosed");EY.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};jD=o(function t(e){function r(n){return e?new EY(n,e):new Q5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function CY(t,e){this._context=t,this._alpha=e}var KD,AY=N(()=>{"use strict";XD();J5();o(CY,"CatmullRomOpen");CY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Xv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};KD=o(function t(e){function r(n){return e?new CY(n,e):new Z5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function _Y(t){this._context=t}function eT(t){return new _Y(t)}var DY=N(()=>{"use strict";Uv();o(_Y,"LinearClosed");_Y.prototype={areaStart:ro,areaEnd:ro,lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){this._point&&this._context.closePath()},"lineEnd"),point:o(function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))},"point")};o(eT,"default")});function LY(t){return t<0?-1:1}function RY(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),s=(r-t._y1)/(i||n<0&&-0),l=(a*i+s*n)/(n+i);return(LY(a)+LY(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(l))||0}function NY(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function QD(t,e,r){var n=t._x0,i=t._y0,a=t._x1,s=t._y1,l=(a-n)/3;t._context.bezierCurveTo(n+l,i+l*e,a-l,s-l*r,a,s)}function tT(t){this._context=t}function MY(t){this._context=new IY(t)}function IY(t){this._context=t}function Kv(t){return new tT(t)}function Qv(t){return new MY(t)}var OY=N(()=>{"use strict";o(LY,"sign");o(RY,"slope3");o(NY,"slope2");o(QD,"point");o(tT,"MonotoneX");tT.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:QD(this,this._t0,NY(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){var r=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,QD(this,NY(this,r=RY(this,t,e)),r);break;default:QD(this,this._t0,r=RY(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}},"point")};o(MY,"MonotoneY");(MY.prototype=Object.create(tT.prototype)).point=function(t,e){tT.prototype.point.call(this,e,t)};o(IY,"ReflectContext");IY.prototype={moveTo:o(function(t,e){this._context.moveTo(e,t)},"moveTo"),closePath:o(function(){this._context.closePath()},"closePath"),lineTo:o(function(t,e){this._context.lineTo(e,t)},"lineTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)},"bezierCurveTo")};o(Kv,"monotoneX");o(Qv,"monotoneY")});function BY(t){this._context=t}function PY(t){var e,r=t.length-1,n,i=new Array(r),a=new Array(r),s=new Array(r);for(i[0]=0,a[0]=2,s[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(s[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e{"use strict";o(BY,"Natural");BY.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=[],this._y=[]},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),r===2)this._context.lineTo(t[1],e[1]);else for(var n=PY(t),i=PY(e),a=0,s=1;s{"use strict";o(rT,"Step");rT.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=this._y=NaN,this._point=0},"lineStart"),lineEnd:o(function(){0=0&&(this._t=1-this._t,this._line=1-this._line)},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}break}}this._x=t,this._y=e},"point")};o(Q0,"default");o(Zv,"stepBefore");o(Jv,"stepAfter")});var zY=N(()=>{"use strict";oY();fY();mY();vY();bY();Wv();gY();wY();qD();XD();Yv();SY();AY();J5();DY();GD();OY();FY();$Y()});var GY=N(()=>{"use strict"});var VY=N(()=>{"use strict"});function Oh(t,e,r){this.k=t,this.x=e,this.y=r}function JD(t){for(;!t.__zoom;)if(!(t=t.parentNode))return ZD;return t.__zoom}var ZD,e9=N(()=>{"use strict";o(Oh,"Transform");Oh.prototype={constructor:Oh,scale:o(function(t){return t===1?this:new Oh(this.k*t,this.x,this.y)},"scale"),translate:o(function(t,e){return t===0&e===0?this:new Oh(this.k,this.x+this.k*t,this.y+this.k*e)},"translate"),apply:o(function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},"apply"),applyX:o(function(t){return t*this.k+this.x},"applyX"),applyY:o(function(t){return t*this.k+this.y},"applyY"),invert:o(function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},"invert"),invertX:o(function(t){return(t-this.x)/this.k},"invertX"),invertY:o(function(t){return(t-this.y)/this.k},"invertY"),rescaleX:o(function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},"rescaleX"),rescaleY:o(function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},"rescaleY"),toString:o(function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"},"toString")};ZD=new Oh(1,0,0);JD.prototype=Oh.prototype;o(JD,"transform")});var UY=N(()=>{"use strict"});var HY=N(()=>{"use strict";b5();GY();VY();e9();UY()});var WY=N(()=>{"use strict";HY();e9()});var fr=N(()=>{"use strict";Eh();JV();vW();wW();I0();kW();EW();VA();HU();SW();L_();CW();_W();Y_();VW();fq();B0();O_();dq();AW();pq();tY();iY();yl();zY();$5();ID();p5();b5();WY()});var qY=Pi(Ji=>{"use strict";Object.defineProperty(Ji,"__esModule",{value:!0});Ji.BLANK_URL=Ji.relativeFirstCharacters=Ji.whitespaceEscapeCharsRegex=Ji.urlSchemeRegex=Ji.ctrlCharactersRegex=Ji.htmlCtrlEntityRegex=Ji.htmlEntitiesRegex=Ji.invalidProtocolRegex=void 0;Ji.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im;Ji.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g;Ji.htmlCtrlEntityRegex=/&(newline|tab);/gi;Ji.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim;Ji.urlSchemeRegex=/^.+(:|:)/gim;Ji.whitespaceEscapeCharsRegex=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g;Ji.relativeFirstCharacters=[".","/"];Ji.BLANK_URL="about:blank"});var Z0=Pi(nT=>{"use strict";Object.defineProperty(nT,"__esModule",{value:!0});nT.sanitizeUrl=void 0;var La=qY();function gSe(t){return La.relativeFirstCharacters.indexOf(t[0])>-1}o(gSe,"isRelativeUrlWithoutProtocol");function ySe(t){var e=t.replace(La.ctrlCharactersRegex,"");return e.replace(La.htmlEntitiesRegex,function(r,n){return String.fromCharCode(n)})}o(ySe,"decodeHtmlCharacters");function vSe(t){return URL.canParse(t)}o(vSe,"isValidUrl");function YY(t){try{return decodeURIComponent(t)}catch{return t}}o(YY,"decodeURI");function xSe(t){if(!t)return La.BLANK_URL;var e,r=YY(t.trim());do r=ySe(r).replace(La.htmlCtrlEntityRegex,"").replace(La.ctrlCharactersRegex,"").replace(La.whitespaceEscapeCharsRegex,"").trim(),r=YY(r),e=r.match(La.ctrlCharactersRegex)||r.match(La.htmlEntitiesRegex)||r.match(La.htmlCtrlEntityRegex)||r.match(La.whitespaceEscapeCharsRegex);while(e&&e.length>0);var n=r;if(!n)return La.BLANK_URL;if(gSe(n))return n;var i=n.trimStart(),a=i.match(La.urlSchemeRegex);if(!a)return n;var s=a[0].toLowerCase().trim();if(La.invalidProtocolRegex.test(s))return La.BLANK_URL;var l=i.replace(/\\/g,"/");if(s==="mailto:"||s.includes("://"))return l;if(s==="http:"||s==="https:"){if(!vSe(l))return La.BLANK_URL;var u=new URL(l);return u.protocol=u.protocol.toLowerCase(),u.hostname=u.hostname.toLowerCase(),u.toString()}return l}o(xSe,"sanitizeUrl");nT.sanitizeUrl=xSe});var t9,Nd,iT,XY,jY,KY,Al,e2,t2=N(()=>{"use strict";t9=Aa(Z0(),1);pr();Nd=o((t,e)=>{let r=t.append("rect");if(r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),e.name&&r.attr("name",e.name),e.rx&&r.attr("rx",e.rx),e.ry&&r.attr("ry",e.ry),e.attrs!==void 0)for(let n in e.attrs)r.attr(n,e.attrs[n]);return e.class&&r.attr("class",e.class),r},"drawRect"),iT=o((t,e)=>{let r={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};Nd(t,r).lower()},"drawBackgroundRect"),XY=o((t,e)=>{let r=e.text.replace(ud," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),jY=o((t,e,r,n)=>{let i=t.append("image");i.attr("x",e),i.attr("y",r);let a=(0,t9.sanitizeUrl)(n);i.attr("xlink:href",a)},"drawImage"),KY=o((t,e,r,n)=>{let i=t.append("use");i.attr("x",e),i.attr("y",r);let a=(0,t9.sanitizeUrl)(n);i.attr("xlink:href",`#${a}`)},"drawEmbeddedImage"),Al=o(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),e2=o(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")});var QY,r9,ZY,bSe,TSe,wSe,kSe,ESe,SSe,CSe,ASe,_Se,DSe,LSe,RSe,Cu,_l,JY=N(()=>{"use strict";pr();t2();QY=Aa(Z0(),1),r9=o(function(t,e){return Nd(t,e)},"drawRect"),ZY=o(function(t,e,r,n,i,a){let s=t.append("image");s.attr("width",e),s.attr("height",r),s.attr("x",n),s.attr("y",i);let l=a.startsWith("data:image/png;base64")?a:(0,QY.sanitizeUrl)(a);s.attr("xlink:href",l)},"drawImage"),bSe=o((t,e,r)=>{let n=t.append("g"),i=0;for(let a of e){let s=a.textColor?a.textColor:"#444444",l=a.lineColor?a.lineColor:"#444444",u=a.offsetX?parseInt(a.offsetX):0,h=a.offsetY?parseInt(a.offsetY):0,f="";if(i===0){let p=n.append("line");p.attr("x1",a.startPoint.x),p.attr("y1",a.startPoint.y),p.attr("x2",a.endPoint.x),p.attr("y2",a.endPoint.y),p.attr("stroke-width","1"),p.attr("stroke",l),p.style("fill","none"),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)"),i=-1}else{let p=n.append("path");p.attr("fill","none").attr("stroke-width","1").attr("stroke",l).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",a.startPoint.x).replaceAll("starty",a.startPoint.y).replaceAll("controlx",a.startPoint.x+(a.endPoint.x-a.startPoint.x)/2-(a.endPoint.x-a.startPoint.x)/4).replaceAll("controly",a.startPoint.y+(a.endPoint.y-a.startPoint.y)/2).replaceAll("stopx",a.endPoint.x).replaceAll("stopy",a.endPoint.y)),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)")}let d=r.messageFont();Cu(r)(a.label.text,n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+h,a.label.width,a.label.height,{fill:s},d),a.techn&&a.techn.text!==""&&(d=r.messageFont(),Cu(r)("["+a.techn.text+"]",n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+r.messageFontSize+5+h,Math.max(a.label.width,a.techn.width),a.techn.height,{fill:s,"font-style":"italic"},d))}},"drawRels"),TSe=o(function(t,e,r){let n=t.append("g"),i=e.bgColor?e.bgColor:"none",a=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let u={x:e.x,y:e.y,fill:i,stroke:a,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};r9(n,u);let h=r.boundaryFont();h.fontWeight="bold",h.fontSize=h.fontSize+2,h.fontColor=s,Cu(r)(e.label.text,n,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},h),e.type&&e.type.text!==""&&(h=r.boundaryFont(),h.fontColor=s,Cu(r)(e.type.text,n,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},h)),e.descr&&e.descr.text!==""&&(h=r.boundaryFont(),h.fontSize=h.fontSize-2,h.fontColor=s,Cu(r)(e.descr.text,n,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},h))},"drawBoundary"),wSe=o(function(t,e,r){let n=e.bgColor?e.bgColor:r[e.typeC4Shape.text+"_bg_color"],i=e.borderColor?e.borderColor:r[e.typeC4Shape.text+"_border_color"],a=e.fontColor?e.fontColor:"#FFFFFF",s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII=";break}let l=t.append("g");l.attr("class","person-man");let u=Al();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":u.x=e.x,u.y=e.y,u.fill=n,u.width=e.width,u.height=e.height,u.stroke=i,u.rx=2.5,u.ry=2.5,u.attrs={"stroke-width":.5},r9(l,u);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2));break}let h=RSe(r,e.typeC4Shape.text);switch(l.append("text").attr("fill",a).attr("font-family",h.fontFamily).attr("font-size",h.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":ZY(l,48,48,e.x+e.width/2-24,e.y+e.image.Y,s);break}let f=r[e.typeC4Shape.text+"Font"]();return f.fontWeight="bold",f.fontSize=f.fontSize+2,f.fontColor=a,Cu(r)(e.label.text,l,e.x,e.y+e.label.Y,e.width,e.height,{fill:a},f),f=r[e.typeC4Shape.text+"Font"](),f.fontColor=a,e.techn&&e.techn?.text!==""?Cu(r)(e.techn.text,l,e.x,e.y+e.techn.Y,e.width,e.height,{fill:a,"font-style":"italic"},f):e.type&&e.type.text!==""&&Cu(r)(e.type.text,l,e.x,e.y+e.type.Y,e.width,e.height,{fill:a,"font-style":"italic"},f),e.descr&&e.descr.text!==""&&(f=r.personFont(),f.fontColor=a,Cu(r)(e.descr.text,l,e.x,e.y+e.descr.Y,e.width,e.height,{fill:a},f)),e.height},"drawC4Shape"),kSe=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),ESe=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),SSe=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),CSe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},"insertArrowHead"),ASe=o(function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},"insertArrowEnd"),_Se=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),DSe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertDynamicNumber"),LSe=o(function(t){let r=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);r.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),r.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},"insertArrowCrossHead"),RSe=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"getC4ShapeFont"),Cu=function(){function t(i,a,s,l,u,h,f){let d=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("text-anchor","middle").text(i);n(d,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d){let{fontSize:p,fontFamily:m,fontWeight:g}=d,y=i.split(Ze.lineBreakRegex);for(let v=0;v{"use strict";NSe=typeof global=="object"&&global&&global.Object===Object&&global,sT=NSe});var MSe,ISe,hi,Mo=N(()=>{"use strict";n9();MSe=typeof self=="object"&&self&&self.Object===Object&&self,ISe=sT||MSe||Function("return this")(),hi=ISe});var OSe,ea,Md=N(()=>{"use strict";Mo();OSe=hi.Symbol,ea=OSe});function FSe(t){var e=PSe.call(t,r2),r=t[r2];try{t[r2]=void 0;var n=!0}catch{}var i=BSe.call(t);return n&&(e?t[r2]=r:delete t[r2]),i}var eX,PSe,BSe,r2,tX,rX=N(()=>{"use strict";Md();eX=Object.prototype,PSe=eX.hasOwnProperty,BSe=eX.toString,r2=ea?ea.toStringTag:void 0;o(FSe,"getRawTag");tX=FSe});function GSe(t){return zSe.call(t)}var $Se,zSe,nX,iX=N(()=>{"use strict";$Se=Object.prototype,zSe=$Se.toString;o(GSe,"objectToString");nX=GSe});function HSe(t){return t==null?t===void 0?USe:VSe:aX&&aX in Object(t)?tX(t):nX(t)}var VSe,USe,aX,fa,Au=N(()=>{"use strict";Md();rX();iX();VSe="[object Null]",USe="[object Undefined]",aX=ea?ea.toStringTag:void 0;o(HSe,"baseGetTag");fa=HSe});function WSe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}var bn,no=N(()=>{"use strict";o(WSe,"isObject");bn=WSe});function KSe(t){if(!bn(t))return!1;var e=fa(t);return e==YSe||e==XSe||e==qSe||e==jSe}var qSe,YSe,XSe,jSe,Ai,n2=N(()=>{"use strict";Au();no();qSe="[object AsyncFunction]",YSe="[object Function]",XSe="[object GeneratorFunction]",jSe="[object Proxy]";o(KSe,"isFunction");Ai=KSe});var QSe,oT,sX=N(()=>{"use strict";Mo();QSe=hi["__core-js_shared__"],oT=QSe});function ZSe(t){return!!oX&&oX in t}var oX,lX,cX=N(()=>{"use strict";sX();oX=function(){var t=/[^.]+$/.exec(oT&&oT.keys&&oT.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();o(ZSe,"isMasked");lX=ZSe});function t6e(t){if(t!=null){try{return e6e.call(t)}catch{}try{return t+""}catch{}}return""}var JSe,e6e,_u,i9=N(()=>{"use strict";JSe=Function.prototype,e6e=JSe.toString;o(t6e,"toSource");_u=t6e});function c6e(t){if(!bn(t)||lX(t))return!1;var e=Ai(t)?l6e:n6e;return e.test(_u(t))}var r6e,n6e,i6e,a6e,s6e,o6e,l6e,uX,hX=N(()=>{"use strict";n2();cX();no();i9();r6e=/[\\^$.*+?()[\]{}|]/g,n6e=/^\[object .+?Constructor\]$/,i6e=Function.prototype,a6e=Object.prototype,s6e=i6e.toString,o6e=a6e.hasOwnProperty,l6e=RegExp("^"+s6e.call(o6e).replace(r6e,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");o(c6e,"baseIsNative");uX=c6e});function u6e(t,e){return t?.[e]}var fX,dX=N(()=>{"use strict";o(u6e,"getValue");fX=u6e});function h6e(t,e){var r=fX(t,e);return uX(r)?r:void 0}var Ls,Ph=N(()=>{"use strict";hX();dX();o(h6e,"getNative");Ls=h6e});var f6e,Du,i2=N(()=>{"use strict";Ph();f6e=Ls(Object,"create"),Du=f6e});function d6e(){this.__data__=Du?Du(null):{},this.size=0}var pX,mX=N(()=>{"use strict";i2();o(d6e,"hashClear");pX=d6e});function p6e(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}var gX,yX=N(()=>{"use strict";o(p6e,"hashDelete");gX=p6e});function v6e(t){var e=this.__data__;if(Du){var r=e[t];return r===m6e?void 0:r}return y6e.call(e,t)?e[t]:void 0}var m6e,g6e,y6e,vX,xX=N(()=>{"use strict";i2();m6e="__lodash_hash_undefined__",g6e=Object.prototype,y6e=g6e.hasOwnProperty;o(v6e,"hashGet");vX=v6e});function T6e(t){var e=this.__data__;return Du?e[t]!==void 0:b6e.call(e,t)}var x6e,b6e,bX,TX=N(()=>{"use strict";i2();x6e=Object.prototype,b6e=x6e.hasOwnProperty;o(T6e,"hashHas");bX=T6e});function k6e(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=Du&&e===void 0?w6e:e,this}var w6e,wX,kX=N(()=>{"use strict";i2();w6e="__lodash_hash_undefined__";o(k6e,"hashSet");wX=k6e});function J0(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";mX();yX();xX();TX();kX();o(J0,"Hash");J0.prototype.clear=pX;J0.prototype.delete=gX;J0.prototype.get=vX;J0.prototype.has=bX;J0.prototype.set=wX;a9=J0});function E6e(){this.__data__=[],this.size=0}var SX,CX=N(()=>{"use strict";o(E6e,"listCacheClear");SX=E6e});function S6e(t,e){return t===e||t!==t&&e!==e}var Io,Id=N(()=>{"use strict";o(S6e,"eq");Io=S6e});function C6e(t,e){for(var r=t.length;r--;)if(Io(t[r][0],e))return r;return-1}var Bh,a2=N(()=>{"use strict";Id();o(C6e,"assocIndexOf");Bh=C6e});function D6e(t){var e=this.__data__,r=Bh(e,t);if(r<0)return!1;var n=e.length-1;return r==n?e.pop():_6e.call(e,r,1),--this.size,!0}var A6e,_6e,AX,_X=N(()=>{"use strict";a2();A6e=Array.prototype,_6e=A6e.splice;o(D6e,"listCacheDelete");AX=D6e});function L6e(t){var e=this.__data__,r=Bh(e,t);return r<0?void 0:e[r][1]}var DX,LX=N(()=>{"use strict";a2();o(L6e,"listCacheGet");DX=L6e});function R6e(t){return Bh(this.__data__,t)>-1}var RX,NX=N(()=>{"use strict";a2();o(R6e,"listCacheHas");RX=R6e});function N6e(t,e){var r=this.__data__,n=Bh(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}var MX,IX=N(()=>{"use strict";a2();o(N6e,"listCacheSet");MX=N6e});function em(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";CX();_X();LX();NX();IX();o(em,"ListCache");em.prototype.clear=SX;em.prototype.delete=AX;em.prototype.get=DX;em.prototype.has=RX;em.prototype.set=MX;Fh=em});var M6e,$h,lT=N(()=>{"use strict";Ph();Mo();M6e=Ls(hi,"Map"),$h=M6e});function I6e(){this.size=0,this.__data__={hash:new a9,map:new($h||Fh),string:new a9}}var OX,PX=N(()=>{"use strict";EX();s2();lT();o(I6e,"mapCacheClear");OX=I6e});function O6e(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}var BX,FX=N(()=>{"use strict";o(O6e,"isKeyable");BX=O6e});function P6e(t,e){var r=t.__data__;return BX(e)?r[typeof e=="string"?"string":"hash"]:r.map}var zh,o2=N(()=>{"use strict";FX();o(P6e,"getMapData");zh=P6e});function B6e(t){var e=zh(this,t).delete(t);return this.size-=e?1:0,e}var $X,zX=N(()=>{"use strict";o2();o(B6e,"mapCacheDelete");$X=B6e});function F6e(t){return zh(this,t).get(t)}var GX,VX=N(()=>{"use strict";o2();o(F6e,"mapCacheGet");GX=F6e});function $6e(t){return zh(this,t).has(t)}var UX,HX=N(()=>{"use strict";o2();o($6e,"mapCacheHas");UX=$6e});function z6e(t,e){var r=zh(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this}var WX,qX=N(()=>{"use strict";o2();o(z6e,"mapCacheSet");WX=z6e});function tm(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{"use strict";PX();zX();VX();HX();qX();o(tm,"MapCache");tm.prototype.clear=OX;tm.prototype.delete=$X;tm.prototype.get=GX;tm.prototype.has=UX;tm.prototype.set=WX;Od=tm});function s9(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(G6e);var r=o(function(){var n=arguments,i=e?e.apply(this,n):n[0],a=r.cache;if(a.has(i))return a.get(i);var s=t.apply(this,n);return r.cache=a.set(i,s)||a,s},"memoized");return r.cache=new(s9.Cache||Od),r}var G6e,rm,o9=N(()=>{"use strict";cT();G6e="Expected a function";o(s9,"memoize");s9.Cache=Od;rm=s9});function V6e(){this.__data__=new Fh,this.size=0}var YX,XX=N(()=>{"use strict";s2();o(V6e,"stackClear");YX=V6e});function U6e(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}var jX,KX=N(()=>{"use strict";o(U6e,"stackDelete");jX=U6e});function H6e(t){return this.__data__.get(t)}var QX,ZX=N(()=>{"use strict";o(H6e,"stackGet");QX=H6e});function W6e(t){return this.__data__.has(t)}var JX,ej=N(()=>{"use strict";o(W6e,"stackHas");JX=W6e});function Y6e(t,e){var r=this.__data__;if(r instanceof Fh){var n=r.__data__;if(!$h||n.length{"use strict";s2();lT();cT();q6e=200;o(Y6e,"stackSet");tj=Y6e});function nm(t){var e=this.__data__=new Fh(t);this.size=e.size}var dc,l2=N(()=>{"use strict";s2();XX();KX();ZX();ej();rj();o(nm,"Stack");nm.prototype.clear=YX;nm.prototype.delete=jX;nm.prototype.get=QX;nm.prototype.has=JX;nm.prototype.set=tj;dc=nm});var X6e,im,l9=N(()=>{"use strict";Ph();X6e=function(){try{var t=Ls(Object,"defineProperty");return t({},"",{}),t}catch{}}(),im=X6e});function j6e(t,e,r){e=="__proto__"&&im?im(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}var pc,am=N(()=>{"use strict";l9();o(j6e,"baseAssignValue");pc=j6e});function K6e(t,e,r){(r!==void 0&&!Io(t[e],r)||r===void 0&&!(e in t))&&pc(t,e,r)}var c2,c9=N(()=>{"use strict";am();Id();o(K6e,"assignMergeValue");c2=K6e});function Q6e(t){return function(e,r,n){for(var i=-1,a=Object(e),s=n(e),l=s.length;l--;){var u=s[t?l:++i];if(r(a[u],u,a)===!1)break}return e}}var nj,ij=N(()=>{"use strict";o(Q6e,"createBaseFor");nj=Q6e});var Z6e,sm,uT=N(()=>{"use strict";ij();Z6e=nj(),sm=Z6e});function eCe(t,e){if(e)return t.slice();var r=t.length,n=oj?oj(r):new t.constructor(r);return t.copy(n),n}var lj,aj,J6e,sj,oj,hT,u9=N(()=>{"use strict";Mo();lj=typeof exports=="object"&&exports&&!exports.nodeType&&exports,aj=lj&&typeof module=="object"&&module&&!module.nodeType&&module,J6e=aj&&aj.exports===lj,sj=J6e?hi.Buffer:void 0,oj=sj?sj.allocUnsafe:void 0;o(eCe,"cloneBuffer");hT=eCe});var tCe,om,h9=N(()=>{"use strict";Mo();tCe=hi.Uint8Array,om=tCe});function rCe(t){var e=new t.constructor(t.byteLength);return new om(e).set(new om(t)),e}var lm,fT=N(()=>{"use strict";h9();o(rCe,"cloneArrayBuffer");lm=rCe});function nCe(t,e){var r=e?lm(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}var dT,f9=N(()=>{"use strict";fT();o(nCe,"cloneTypedArray");dT=nCe});function iCe(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r{"use strict";o(iCe,"copyArray");pT=iCe});var cj,aCe,uj,hj=N(()=>{"use strict";no();cj=Object.create,aCe=function(){function t(){}return o(t,"object"),function(e){if(!bn(e))return{};if(cj)return cj(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}(),uj=aCe});function sCe(t,e){return function(r){return t(e(r))}}var mT,p9=N(()=>{"use strict";o(sCe,"overArg");mT=sCe});var oCe,cm,gT=N(()=>{"use strict";p9();oCe=mT(Object.getPrototypeOf,Object),cm=oCe});function cCe(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||lCe;return t===r}var lCe,mc,um=N(()=>{"use strict";lCe=Object.prototype;o(cCe,"isPrototype");mc=cCe});function uCe(t){return typeof t.constructor=="function"&&!mc(t)?uj(cm(t)):{}}var yT,m9=N(()=>{"use strict";hj();gT();um();o(uCe,"initCloneObject");yT=uCe});function hCe(t){return t!=null&&typeof t=="object"}var ii,Oo=N(()=>{"use strict";o(hCe,"isObjectLike");ii=hCe});function dCe(t){return ii(t)&&fa(t)==fCe}var fCe,g9,fj=N(()=>{"use strict";Au();Oo();fCe="[object Arguments]";o(dCe,"baseIsArguments");g9=dCe});var dj,pCe,mCe,gCe,Dl,hm=N(()=>{"use strict";fj();Oo();dj=Object.prototype,pCe=dj.hasOwnProperty,mCe=dj.propertyIsEnumerable,gCe=g9(function(){return arguments}())?g9:function(t){return ii(t)&&pCe.call(t,"callee")&&!mCe.call(t,"callee")},Dl=gCe});var yCe,Pt,Wn=N(()=>{"use strict";yCe=Array.isArray,Pt=yCe});function xCe(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=vCe}var vCe,fm,vT=N(()=>{"use strict";vCe=9007199254740991;o(xCe,"isLength");fm=xCe});function bCe(t){return t!=null&&fm(t.length)&&!Ai(t)}var fi,Po=N(()=>{"use strict";n2();vT();o(bCe,"isArrayLike");fi=bCe});function TCe(t){return ii(t)&&fi(t)}var Pd,xT=N(()=>{"use strict";Po();Oo();o(TCe,"isArrayLikeObject");Pd=TCe});function wCe(){return!1}var pj,mj=N(()=>{"use strict";o(wCe,"stubFalse");pj=wCe});var vj,gj,kCe,yj,ECe,SCe,Ll,dm=N(()=>{"use strict";Mo();mj();vj=typeof exports=="object"&&exports&&!exports.nodeType&&exports,gj=vj&&typeof module=="object"&&module&&!module.nodeType&&module,kCe=gj&&gj.exports===vj,yj=kCe?hi.Buffer:void 0,ECe=yj?yj.isBuffer:void 0,SCe=ECe||pj,Ll=SCe});function RCe(t){if(!ii(t)||fa(t)!=CCe)return!1;var e=cm(t);if(e===null)return!0;var r=DCe.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&xj.call(r)==LCe}var CCe,ACe,_Ce,xj,DCe,LCe,bj,Tj=N(()=>{"use strict";Au();gT();Oo();CCe="[object Object]",ACe=Function.prototype,_Ce=Object.prototype,xj=ACe.toString,DCe=_Ce.hasOwnProperty,LCe=xj.call(Object);o(RCe,"isPlainObject");bj=RCe});function r7e(t){return ii(t)&&fm(t.length)&&!!Fn[fa(t)]}var NCe,MCe,ICe,OCe,PCe,BCe,FCe,$Ce,zCe,GCe,VCe,UCe,HCe,WCe,qCe,YCe,XCe,jCe,KCe,QCe,ZCe,JCe,e7e,t7e,Fn,wj,kj=N(()=>{"use strict";Au();vT();Oo();NCe="[object Arguments]",MCe="[object Array]",ICe="[object Boolean]",OCe="[object Date]",PCe="[object Error]",BCe="[object Function]",FCe="[object Map]",$Ce="[object Number]",zCe="[object Object]",GCe="[object RegExp]",VCe="[object Set]",UCe="[object String]",HCe="[object WeakMap]",WCe="[object ArrayBuffer]",qCe="[object DataView]",YCe="[object Float32Array]",XCe="[object Float64Array]",jCe="[object Int8Array]",KCe="[object Int16Array]",QCe="[object Int32Array]",ZCe="[object Uint8Array]",JCe="[object Uint8ClampedArray]",e7e="[object Uint16Array]",t7e="[object Uint32Array]",Fn={};Fn[YCe]=Fn[XCe]=Fn[jCe]=Fn[KCe]=Fn[QCe]=Fn[ZCe]=Fn[JCe]=Fn[e7e]=Fn[t7e]=!0;Fn[NCe]=Fn[MCe]=Fn[WCe]=Fn[ICe]=Fn[qCe]=Fn[OCe]=Fn[PCe]=Fn[BCe]=Fn[FCe]=Fn[$Ce]=Fn[zCe]=Fn[GCe]=Fn[VCe]=Fn[UCe]=Fn[HCe]=!1;o(r7e,"baseIsTypedArray");wj=r7e});function n7e(t){return function(e){return t(e)}}var Bo,Bd=N(()=>{"use strict";o(n7e,"baseUnary");Bo=n7e});var Ej,u2,i7e,y9,a7e,Fo,h2=N(()=>{"use strict";n9();Ej=typeof exports=="object"&&exports&&!exports.nodeType&&exports,u2=Ej&&typeof module=="object"&&module&&!module.nodeType&&module,i7e=u2&&u2.exports===Ej,y9=i7e&&sT.process,a7e=function(){try{var t=u2&&u2.require&&u2.require("util").types;return t||y9&&y9.binding&&y9.binding("util")}catch{}}(),Fo=a7e});var Sj,s7e,Gh,f2=N(()=>{"use strict";kj();Bd();h2();Sj=Fo&&Fo.isTypedArray,s7e=Sj?Bo(Sj):wj,Gh=s7e});function o7e(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}var d2,v9=N(()=>{"use strict";o(o7e,"safeGet");d2=o7e});function u7e(t,e,r){var n=t[e];(!(c7e.call(t,e)&&Io(n,r))||r===void 0&&!(e in t))&&pc(t,e,r)}var l7e,c7e,gc,pm=N(()=>{"use strict";am();Id();l7e=Object.prototype,c7e=l7e.hasOwnProperty;o(u7e,"assignValue");gc=u7e});function h7e(t,e,r,n){var i=!r;r||(r={});for(var a=-1,s=e.length;++a{"use strict";pm();am();o(h7e,"copyObject");$o=h7e});function f7e(t,e){for(var r=-1,n=Array(t);++r{"use strict";o(f7e,"baseTimes");Cj=f7e});function m7e(t,e){var r=typeof t;return e=e??d7e,!!e&&(r=="number"||r!="symbol"&&p7e.test(t))&&t>-1&&t%1==0&&t{"use strict";d7e=9007199254740991,p7e=/^(?:0|[1-9]\d*)$/;o(m7e,"isIndex");Vh=m7e});function v7e(t,e){var r=Pt(t),n=!r&&Dl(t),i=!r&&!n&&Ll(t),a=!r&&!n&&!i&&Gh(t),s=r||n||i||a,l=s?Cj(t.length,String):[],u=l.length;for(var h in t)(e||y7e.call(t,h))&&!(s&&(h=="length"||i&&(h=="offset"||h=="parent")||a&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||Vh(h,u)))&&l.push(h);return l}var g7e,y7e,bT,x9=N(()=>{"use strict";Aj();hm();Wn();dm();p2();f2();g7e=Object.prototype,y7e=g7e.hasOwnProperty;o(v7e,"arrayLikeKeys");bT=v7e});function x7e(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}var _j,Dj=N(()=>{"use strict";o(x7e,"nativeKeysIn");_j=x7e});function w7e(t){if(!bn(t))return _j(t);var e=mc(t),r=[];for(var n in t)n=="constructor"&&(e||!T7e.call(t,n))||r.push(n);return r}var b7e,T7e,Lj,Rj=N(()=>{"use strict";no();um();Dj();b7e=Object.prototype,T7e=b7e.hasOwnProperty;o(w7e,"baseKeysIn");Lj=w7e});function k7e(t){return fi(t)?bT(t,!0):Lj(t)}var Rs,Uh=N(()=>{"use strict";x9();Rj();Po();o(k7e,"keysIn");Rs=k7e});function E7e(t){return $o(t,Rs(t))}var Nj,Mj=N(()=>{"use strict";Fd();Uh();o(E7e,"toPlainObject");Nj=E7e});function S7e(t,e,r,n,i,a,s){var l=d2(t,r),u=d2(e,r),h=s.get(u);if(h){c2(t,r,h);return}var f=a?a(l,u,r+"",t,e,s):void 0,d=f===void 0;if(d){var p=Pt(u),m=!p&&Ll(u),g=!p&&!m&&Gh(u);f=u,p||m||g?Pt(l)?f=l:Pd(l)?f=pT(l):m?(d=!1,f=hT(u,!0)):g?(d=!1,f=dT(u,!0)):f=[]:bj(u)||Dl(u)?(f=l,Dl(l)?f=Nj(l):(!bn(l)||Ai(l))&&(f=yT(u))):d=!1}d&&(s.set(u,f),i(f,u,n,a,s),s.delete(u)),c2(t,r,f)}var Ij,Oj=N(()=>{"use strict";c9();u9();f9();d9();m9();hm();Wn();xT();dm();n2();no();Tj();f2();v9();Mj();o(S7e,"baseMergeDeep");Ij=S7e});function Pj(t,e,r,n,i){t!==e&&sm(e,function(a,s){if(i||(i=new dc),bn(a))Ij(t,e,s,r,Pj,n,i);else{var l=n?n(d2(t,s),a,s+"",t,e,i):void 0;l===void 0&&(l=a),c2(t,s,l)}},Rs)}var Bj,Fj=N(()=>{"use strict";l2();c9();uT();Oj();no();Uh();v9();o(Pj,"baseMerge");Bj=Pj});function C7e(t){return t}var ta,Lu=N(()=>{"use strict";o(C7e,"identity");ta=C7e});function A7e(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}var $j,zj=N(()=>{"use strict";o(A7e,"apply");$j=A7e});function _7e(t,e,r){return e=Gj(e===void 0?t.length-1:e,0),function(){for(var n=arguments,i=-1,a=Gj(n.length-e,0),s=Array(a);++i{"use strict";zj();Gj=Math.max;o(_7e,"overRest");TT=_7e});function D7e(t){return function(){return t}}var Ns,T9=N(()=>{"use strict";o(D7e,"constant");Ns=D7e});var L7e,Vj,Uj=N(()=>{"use strict";T9();l9();Lu();L7e=im?function(t,e){return im(t,"toString",{configurable:!0,enumerable:!1,value:Ns(e),writable:!0})}:ta,Vj=L7e});function I7e(t){var e=0,r=0;return function(){var n=M7e(),i=N7e-(n-r);if(r=n,i>0){if(++e>=R7e)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}var R7e,N7e,M7e,Hj,Wj=N(()=>{"use strict";R7e=800,N7e=16,M7e=Date.now;o(I7e,"shortOut");Hj=I7e});var O7e,wT,w9=N(()=>{"use strict";Uj();Wj();O7e=Hj(Vj),wT=O7e});function P7e(t,e){return wT(TT(t,e,ta),t+"")}var yc,mm=N(()=>{"use strict";Lu();b9();w9();o(P7e,"baseRest");yc=P7e});function B7e(t,e,r){if(!bn(r))return!1;var n=typeof e;return(n=="number"?fi(r)&&Vh(e,r.length):n=="string"&&e in r)?Io(r[e],t):!1}var io,$d=N(()=>{"use strict";Id();Po();p2();no();o(B7e,"isIterateeCall");io=B7e});function F7e(t){return yc(function(e,r){var n=-1,i=r.length,a=i>1?r[i-1]:void 0,s=i>2?r[2]:void 0;for(a=t.length>3&&typeof a=="function"?(i--,a):void 0,s&&io(r[0],r[1],s)&&(a=i<3?void 0:a,i=1),e=Object(e);++n{"use strict";mm();$d();o(F7e,"createAssigner");kT=F7e});var $7e,Hh,E9=N(()=>{"use strict";Fj();k9();$7e=kT(function(t,e,r){Bj(t,e,r)}),Hh=$7e});function A9(t,e){if(!t)return e;let r=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return z7e[r]??e}function H7e(t,e){let r=t.trim();if(r)return e.securityLevel!=="loose"?(0,Xj.sanitizeUrl)(r):r}function Qj(t,e){return!t||!e?0:Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function q7e(t){let e,r=0;t.forEach(i=>{r+=Qj(i,e),e=i});let n=r/2;return _9(t,n)}function Y7e(t){return t.length===1?t[0]:q7e(t)}function j7e(t,e,r){let n=structuredClone(r);X.info("our points",n),e!=="start_left"&&e!=="start_right"&&n.reverse();let i=25+t,a=_9(n,i),s=10+t*.5,l=Math.atan2(n[0].y-a.y,n[0].x-a.x),u={x:0,y:0};return e==="start_left"?(u.x=Math.sin(l+Math.PI)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l+Math.PI)*s+(n[0].y+a.y)/2):e==="end_right"?(u.x=Math.sin(l-Math.PI)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l-Math.PI)*s+(n[0].y+a.y)/2-5):e==="end_left"?(u.x=Math.sin(l)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2-5):(u.x=Math.sin(l)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2),u}function D9(t){let e="",r="";for(let n of t)n!==void 0&&(n.startsWith("color:")||n.startsWith("text-align:")?r=r+n+";":e=e+n+";");return{style:e,labelStyle:r}}function K7e(t){let e="",r="0123456789abcdef",n=r.length;for(let i=0;i{"use strict";Xj=Aa(Z0(),1);fr();pr();b7();yt();rd();g0();o9();E9();Q4();C9="\u200B",z7e={curveBasis:No,curveBasisClosed:X5,curveBasisOpen:j5,curveBumpX:Gv,curveBumpY:Vv,curveBundle:HD,curveCardinalClosed:WD,curveCardinalOpen:YD,curveCardinal:qv,curveCatmullRomClosed:jD,curveCatmullRomOpen:KD,curveCatmullRom:jv,curveLinear:Su,curveLinearClosed:eT,curveMonotoneX:Kv,curveMonotoneY:Qv,curveNatural:K0,curveStep:Q0,curveStepAfter:Jv,curveStepBefore:Zv},G7e=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,V7e=o(function(t,e){let r=jj(t,/(?:init\b)|(?:initialize\b)/),n={};if(Array.isArray(r)){let s=r.map(l=>l.args);v0(s),n=Un(n,[...s])}else n=r.args;if(!n)return;let i=m0(t,e),a="config";return n[a]!==void 0&&(i==="flowchart-v2"&&(i="flowchart"),n[i]=n[a],delete n[a]),n},"detectInit"),jj=o(function(t,e=null){try{let r=new RegExp(`[%]{2}(?![{]${G7e.source})(?=[}][%]{2}).* -`,"ig");t=t.trim().replace(r,"").replace(/'/gm,'"'),X.debug(`Detecting diagram directive${e!==null?" type:"+e:""} based on the text:${t}`);let n,i=[];for(;(n=td.exec(t))!==null;)if(n.index===td.lastIndex&&td.lastIndex++,n&&!e||e&&n[1]?.match(e)||e&&n[2]?.match(e)){let a=n[1]?n[1]:n[2],s=n[3]?n[3].trim():n[4]?JSON.parse(n[4].trim()):null;i.push({type:a,args:s})}return i.length===0?{type:t,args:null}:i.length===1?i[0]:i}catch(r){return X.error(`ERROR: ${r.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},"detectDirective"),Kj=o(function(t){return t.replace(td,"")},"removeDirectives"),U7e=o(function(t,e){for(let[r,n]of e.entries())if(n.match(t))return r;return-1},"isSubstringInArray");o(A9,"interpolateToCurve");o(H7e,"formatUrl");W7e=o((t,...e)=>{let r=t.split("."),n=r.length-1,i=r[n],a=window;for(let s=0;s{let r=Math.pow(10,e);return Math.round(t*r)/r},"roundNumber"),_9=o((t,e)=>{let r,n=e;for(let i of t){if(r){let a=Qj(i,r);if(a===0)return r;if(a=1)return{x:i.x,y:i.y};if(s>0&&s<1)return{x:qj((1-s)*r.x+s*i.x,5),y:qj((1-s)*r.y+s*i.y,5)}}}r=i}throw new Error("Could not find a suitable point for the given distance")},"calculatePoint"),X7e=o((t,e,r)=>{X.info(`our points ${JSON.stringify(e)}`),e[0]!==r&&(e=e.reverse());let i=_9(e,25),a=t?10:5,s=Math.atan2(e[0].y-i.y,e[0].x-i.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+i.x)/2,l.y=-Math.cos(s)*a+(e[0].y+i.y)/2,l},"calcCardinalityPosition");o(j7e,"calcTerminalLabelPosition");o(D9,"getStylesFromArray");Yj=0,L9=o(()=>(Yj++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Yj),"generateId");o(K7e,"makeRandomHex");R9=o(t=>K7e(t.length),"random"),Q7e=o(function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},"getTextObj"),Z7e=o(function(t,e){let r=e.text.replace(Ze.lineBreakRegex," "),[,n]=zo(e.fontSize),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.style("text-anchor",e.anchor),i.style("font-family",e.fontFamily),i.style("font-size",n),i.style("font-weight",e.fontWeight),i.attr("fill",e.fill),e.class!==void 0&&i.attr("class",e.class);let a=i.append("tspan");return a.attr("x",e.x+e.textMargin*2),a.attr("fill",e.fill),a.text(r),i},"drawSimpleText"),N9=rm((t,e,r)=>{if(!t||(r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
    "},r),Ze.lineBreakRegex.test(t)))return t;let n=t.split(" ").filter(Boolean),i=[],a="";return n.forEach((s,l)=>{let u=ra(`${s} `,r),h=ra(a,r);if(u>e){let{hyphenatedStrings:p,remainingWord:m}=J7e(s,e,"-",r);i.push(a,...p),a=m}else h+u>=e?(i.push(a),a=s):a=[a,s].filter(Boolean).join(" ");l+1===n.length&&i.push(a)}),i.filter(s=>s!=="").join(r.joinWith)},(t,e,r)=>`${t}${e}${r.fontSize}${r.fontWeight}${r.fontFamily}${r.joinWith}`),J7e=rm((t,e,r="-",n)=>{n=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},n);let i=[...t],a=[],s="";return i.forEach((l,u)=>{let h=`${s}${l}`;if(ra(h,n)>=e){let d=u+1,p=i.length===d,m=`${h}${r}`;a.push(p?h:m),s=""}else s=h}),{hyphenatedStrings:a,remainingWord:s}},(t,e,r="-",n)=>`${t}${e}${r}${n.fontSize}${n.fontWeight}${n.fontFamily}`);o(ST,"calculateTextHeight");o(ra,"calculateTextWidth");M9=rm((t,e)=>{let{fontSize:r=12,fontFamily:n="Arial",fontWeight:i=400}=e;if(!t)return{width:0,height:0};let[,a]=zo(r),s=["sans-serif",n],l=t.split(Ze.lineBreakRegex),u=[],h=Ge("body");if(!h.remove)return{width:0,height:0,lineHeight:0};let f=h.append("svg");for(let p of s){let m=0,g={width:0,height:0,lineHeight:0};for(let y of l){let v=Q7e();v.text=y||C9;let x=Z7e(f,v).style("font-size",a).style("font-weight",i).style("font-family",p),b=(x._groups||x)[0][0].getBBox();if(b.width===0&&b.height===0)throw new Error("svg element not in render tree");g.width=Math.round(Math.max(g.width,b.width)),m=Math.round(b.height),g.height+=m,g.lineHeight=Math.round(Math.max(g.lineHeight,m))}u.push(g)}f.remove();let d=isNaN(u[1].height)||isNaN(u[1].width)||isNaN(u[1].lineHeight)||u[0].height>u[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1;return u[d]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`),S9=class{constructor(e=!1,r){this.count=0;this.count=r?r.length:0,this.next=e?()=>this.count++:()=>Date.now()}static{o(this,"InitIDGenerator")}},eAe=o(function(t){return ET=ET||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),ET.innerHTML=t,unescape(ET.textContent)},"entityDecode");o(I9,"isDetailedError");tAe=o((t,e,r,n)=>{if(!n)return;let i=t.node()?.getBBox();i&&t.append("text").text(n).attr("text-anchor","middle").attr("x",i.x+i.width/2).attr("y",-r).attr("class",e)},"insertTitle"),zo=o(t=>{if(typeof t=="number")return[t,t+"px"];let e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]},"parseFontSize");o($n,"cleanAndMerge");Vt={assignWithDepth:Un,wrapLabel:N9,calculateTextHeight:ST,calculateTextWidth:ra,calculateTextDimensions:M9,cleanAndMerge:$n,detectInit:V7e,detectDirective:jj,isSubstringInArray:U7e,interpolateToCurve:A9,calcLabelPosition:Y7e,calcCardinalityPosition:X7e,calcTerminalLabelPosition:j7e,formatUrl:H7e,getStylesFromArray:D9,generateId:L9,random:R9,runFunc:W7e,entityDecode:eAe,insertTitle:tAe,parseFontSize:zo,InitIDGenerator:S9},Zj=o(function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/#\w+;/g,function(r){let n=r.substring(1,r.length-1);return/^\+?\d+$/.test(n)?"\uFB02\xB0\xB0"+n+"\xB6\xDF":"\uFB02\xB0"+n+"\xB6\xDF"}),e},"encodeEntities"),na=o(function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},"decodeEntities"),Wh=o((t,e,{counter:r=0,prefix:n,suffix:i},a)=>a||`${n?`${n}_`:""}${t}_${e}_${r}${i?`_${i}`:""}`,"getEdgeId");o(zn,"handleUndefinedAttr")});function Rl(t,e,r,n,i){if(!e[t].width)if(r)e[t].text=N9(e[t].text,i,n),e[t].textLines=e[t].text.split(Ze.lineBreakRegex).length,e[t].width=i,e[t].height=ST(e[t].text,n);else{let a=e[t].text.split(Ze.lineBreakRegex);e[t].textLines=a.length;let s=0;e[t].height=0,e[t].width=0;for(let l of a)e[t].width=Math.max(ra(l,n),e[t].width),s=ST(l,n),e[t].height=e[t].height+s}}function nK(t,e,r,n,i){let a=new DT(i);a.data.widthLimit=r.data.widthLimit/Math.min(O9,n.length);for(let[s,l]of n.entries()){let u=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=u,u=l.image.Y+l.image.height);let h=l.wrap&&Ut.wrap,f=CT(Ut);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Rl("label",l,h,f,a.data.widthLimit),l.label.Y=u+8,u=l.label.Y+l.label.height,l.type&&l.type.text!==""){l.type.text="["+l.type.text+"]";let g=CT(Ut);Rl("type",l,h,g,a.data.widthLimit),l.type.Y=u+5,u=l.type.Y+l.type.height}if(l.descr&&l.descr.text!==""){let g=CT(Ut);g.fontSize=g.fontSize-2,Rl("descr",l,h,g,a.data.widthLimit),l.descr.Y=u+20,u=l.descr.Y+l.descr.height}if(s==0||s%O9===0){let g=r.data.startx+Ut.diagramMarginX,y=r.data.stopy+Ut.diagramMarginY+u;a.setData(g,g,y,y)}else{let g=a.data.stopx!==a.data.startx?a.data.stopx+Ut.diagramMarginX:a.data.startx,y=a.data.starty;a.setData(g,g,y,y)}a.name=l.alias;let d=i.db.getC4ShapeArray(l.alias),p=i.db.getC4ShapeKeys(l.alias);p.length>0&&rK(a,t,d,p),e=l.alias;let m=i.db.getBoundaries(e);m.length>0&&nK(t,e,a,m,i),l.alias!=="global"&&tK(t,l,a),r.data.stopy=Math.max(a.data.stopy+Ut.c4ShapeMargin,r.data.stopy),r.data.stopx=Math.max(a.data.stopx+Ut.c4ShapeMargin,r.data.stopx),AT=Math.max(AT,r.data.stopx),_T=Math.max(_T,r.data.stopy)}}var AT,_T,eK,O9,Ut,DT,P9,m2,CT,rAe,tK,rK,Ms,Jj,nAe,iAe,aAe,B9,iK=N(()=>{"use strict";fr();JY();yt();a7();pr();LA();Gt();g0();er();xi();AT=0,_T=0,eK=4,O9=2;Ry.yy=sv;Ut={},DT=class{static{o(this,"Bounds")}constructor(e){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,P9(e.db.getConfig())}setData(e,r,n,i){this.nextData.startx=this.data.startx=e,this.nextData.stopx=this.data.stopx=r,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=i}updateVal(e,r,n,i){e[r]===void 0?e[r]=n:e[r]=i(n,e[r])}insert(e){this.nextData.cnt=this.nextData.cnt+1;let r=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+e.margin:this.nextData.stopx+e.margin*2,n=r+e.width,i=this.nextData.starty+e.margin*2,a=i+e.height;(r>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>eK)&&(r=this.nextData.startx+e.margin+Ut.nextLinePaddingX,i=this.nextData.stopy+e.margin*2,this.nextData.stopx=n=r+e.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=i+e.height,this.nextData.cnt=1),e.x=r,e.y=i,this.updateVal(this.data,"startx",r,Math.min),this.updateVal(this.data,"starty",i,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",r,Math.min),this.updateVal(this.nextData,"starty",i,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(e){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},P9(e.db.getConfig())}bumpLastMargin(e){this.data.stopx+=e,this.data.stopy+=e}},P9=o(function(t){Un(Ut,t),t.fontFamily&&(Ut.personFontFamily=Ut.systemFontFamily=Ut.messageFontFamily=t.fontFamily),t.fontSize&&(Ut.personFontSize=Ut.systemFontSize=Ut.messageFontSize=t.fontSize),t.fontWeight&&(Ut.personFontWeight=Ut.systemFontWeight=Ut.messageFontWeight=t.fontWeight)},"setConf"),m2=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"c4ShapeFont"),CT=o(t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight}),"boundaryFont"),rAe=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont");o(Rl,"calcC4ShapeTextWH");tK=o(function(t,e,r){e.x=r.data.startx,e.y=r.data.starty,e.width=r.data.stopx-r.data.startx,e.height=r.data.stopy-r.data.starty,e.label.y=Ut.c4ShapeMargin-35;let n=e.wrap&&Ut.wrap,i=CT(Ut);i.fontSize=i.fontSize+2,i.fontWeight="bold";let a=ra(e.label.text,i);Rl("label",e,n,i,a),_l.drawBoundary(t,e,Ut)},"drawBoundary"),rK=o(function(t,e,r,n){let i=0;for(let a of n){i=0;let s=r[a],l=m2(Ut,s.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,s.typeC4Shape.width=ra("\xAB"+s.typeC4Shape.text+"\xBB",l),s.typeC4Shape.height=l.fontSize+2,s.typeC4Shape.Y=Ut.c4ShapePadding,i=s.typeC4Shape.Y+s.typeC4Shape.height-4,s.image={width:0,height:0,Y:0},s.typeC4Shape.text){case"person":case"external_person":s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height;break}s.sprite&&(s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height);let u=s.wrap&&Ut.wrap,h=Ut.width-Ut.c4ShapePadding*2,f=m2(Ut,s.typeC4Shape.text);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Rl("label",s,u,f,h),s.label.Y=i+8,i=s.label.Y+s.label.height,s.type&&s.type.text!==""){s.type.text="["+s.type.text+"]";let m=m2(Ut,s.typeC4Shape.text);Rl("type",s,u,m,h),s.type.Y=i+5,i=s.type.Y+s.type.height}else if(s.techn&&s.techn.text!==""){s.techn.text="["+s.techn.text+"]";let m=m2(Ut,s.techn.text);Rl("techn",s,u,m,h),s.techn.Y=i+5,i=s.techn.Y+s.techn.height}let d=i,p=s.label.width;if(s.descr&&s.descr.text!==""){let m=m2(Ut,s.typeC4Shape.text);Rl("descr",s,u,m,h),s.descr.Y=i+20,i=s.descr.Y+s.descr.height,p=Math.max(s.label.width,s.descr.width),d=i-s.descr.textLines*5}p=p+Ut.c4ShapePadding,s.width=Math.max(s.width||Ut.width,p,Ut.width),s.height=Math.max(s.height||Ut.height,d,Ut.height),s.margin=s.margin||Ut.c4ShapeMargin,t.insert(s),_l.drawC4Shape(e,s,Ut)}t.bumpLastMargin(Ut.c4ShapeMargin)},"drawC4ShapeArray"),Ms=class{static{o(this,"Point")}constructor(e,r){this.x=e,this.y=r}},Jj=o(function(t,e){let r=t.x,n=t.y,i=e.x,a=e.y,s=r+t.width/2,l=n+t.height/2,u=Math.abs(r-i),h=Math.abs(n-a),f=h/u,d=t.height/t.width,p=null;return n==a&&ri?p=new Ms(r,l):r==i&&na&&(p=new Ms(s,n)),r>i&&n=f?p=new Ms(r,l+f*t.width/2):p=new Ms(s-u/h*t.height/2,n+t.height):r=f?p=new Ms(r+t.width,l+f*t.width/2):p=new Ms(s+u/h*t.height/2,n+t.height):ra?d>=f?p=new Ms(r+t.width,l-f*t.width/2):p=new Ms(s+t.height/2*u/h,n):r>i&&n>a&&(d>=f?p=new Ms(r,l-t.width/2*f):p=new Ms(s-t.height/2*u/h,n)),p},"getIntersectPoint"),nAe=o(function(t,e){let r={x:0,y:0};r.x=e.x+e.width/2,r.y=e.y+e.height/2;let n=Jj(t,r);r.x=t.x+t.width/2,r.y=t.y+t.height/2;let i=Jj(e,r);return{startPoint:n,endPoint:i}},"getIntersectPoints"),iAe=o(function(t,e,r,n){let i=0;for(let a of e){i=i+1;let s=a.wrap&&Ut.wrap,l=rAe(Ut);n.db.getC4Type()==="C4Dynamic"&&(a.label.text=i+": "+a.label.text);let h=ra(a.label.text,l);Rl("label",a,s,l,h),a.techn&&a.techn.text!==""&&(h=ra(a.techn.text,l),Rl("techn",a,s,l,h)),a.descr&&a.descr.text!==""&&(h=ra(a.descr.text,l),Rl("descr",a,s,l,h));let f=r(a.from),d=r(a.to),p=nAe(f,d);a.startPoint=p.startPoint,a.endPoint=p.endPoint}_l.drawRels(t,e,Ut)},"drawRels");o(nK,"drawInsideBoundary");aAe=o(function(t,e,r,n){Ut=me().c4;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=n.db;n.db.setWrap(Ut.wrap),eK=l.getC4ShapeInRow(),O9=l.getC4BoundaryInRow(),X.debug(`C:${JSON.stringify(Ut,null,2)}`);let u=i==="sandbox"?s.select(`[id="${e}"]`):Ge(`[id="${e}"]`);_l.insertComputerIcon(u),_l.insertDatabaseIcon(u),_l.insertClockIcon(u);let h=new DT(n);h.setData(Ut.diagramMarginX,Ut.diagramMarginX,Ut.diagramMarginY,Ut.diagramMarginY),h.data.widthLimit=screen.availWidth,AT=Ut.diagramMarginX,_T=Ut.diagramMarginY;let f=n.db.getTitle(),d=n.db.getBoundaries("");nK(u,"",h,d,n),_l.insertArrowHead(u),_l.insertArrowEnd(u),_l.insertArrowCrossHead(u),_l.insertArrowFilledHead(u),iAe(u,n.db.getRels(),n.db.getC4Shape,n),h.data.stopx=AT,h.data.stopy=_T;let p=h.data,g=p.stopy-p.starty+2*Ut.diagramMarginY,v=p.stopx-p.startx+2*Ut.diagramMarginX;f&&u.append("text").text(f).attr("x",(p.stopx-p.startx)/2-4*Ut.diagramMarginX).attr("y",p.starty+Ut.diagramMarginY),fn(u,g,v,Ut.useMaxWidth);let x=f?60:0;u.attr("viewBox",p.startx-Ut.diagramMarginX+" -"+(Ut.diagramMarginY+x)+" "+v+" "+(g+x)),X.debug("models:",p)},"draw"),B9={drawPersonOrSystemArray:rK,drawBoundary:tK,setConf:P9,draw:aAe}});var sAe,aK,sK=N(()=>{"use strict";sAe=o(t=>`.person { - stroke: ${t.personBorder}; - fill: ${t.personBkg}; - } -`,"getStyles"),aK=sAe});var oK={};ur(oK,{diagram:()=>oAe});var oAe,lK=N(()=>{"use strict";a7();LA();iK();sK();oAe={parser:G$,db:sv,renderer:B9,styles:aK,init:o(({c4:t,wrap:e})=>{B9.setConf(t),sv.setWrap(e)},"init")}});function CK(t){return typeof t>"u"||t===null}function hAe(t){return typeof t=="object"&&t!==null}function fAe(t){return Array.isArray(t)?t:CK(t)?[]:[t]}function dAe(t,e){var r,n,i,a;if(e)for(a=Object.keys(e),r=0,n=a.length;rl&&(a=" ... ",e=n-l+a.length),r-n>l&&(s=" ...",r=n+l-s.length),{str:a+t.slice(e,r).replace(/\t/g,"\u2192")+s,pos:n-e+a.length}}function $9(t,e){return Gi.repeat(" ",e-t.length)+t}function wAe(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),typeof e.indent!="number"&&(e.indent=1),typeof e.linesBefore!="number"&&(e.linesBefore=3),typeof e.linesAfter!="number"&&(e.linesAfter=2);for(var r=/\r?\n|\r|\0/g,n=[0],i=[],a,s=-1;a=r.exec(t.buffer);)i.push(a.index),n.push(a.index+a[0].length),t.position<=a.index&&s<0&&(s=n.length-2);s<0&&(s=n.length-1);var l="",u,h,f=Math.min(t.line+e.linesAfter,i.length).toString().length,d=e.maxLength-(e.indent+f+3);for(u=1;u<=e.linesBefore&&!(s-u<0);u++)h=F9(t.buffer,n[s-u],i[s-u],t.position-(n[s]-n[s-u]),d),l=Gi.repeat(" ",e.indent)+$9((t.line-u+1).toString(),f)+" | "+h.str+` -`+l;for(h=F9(t.buffer,n[s],i[s],t.position,d),l+=Gi.repeat(" ",e.indent)+$9((t.line+1).toString(),f)+" | "+h.str+` -`,l+=Gi.repeat("-",e.indent+f+3+h.pos)+`^ -`,u=1;u<=e.linesAfter&&!(s+u>=i.length);u++)h=F9(t.buffer,n[s+u],i[s+u],t.position-(n[s]-n[s+u]),d),l+=Gi.repeat(" ",e.indent)+$9((t.line+u+1).toString(),f)+" | "+h.str+` -`;return l.replace(/\n$/,"")}function CAe(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(n){e[String(n)]=r})}),e}function AAe(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(EAe.indexOf(r)===-1)throw new Is('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=CAe(e.styleAliases||null),SAe.indexOf(this.kind)===-1)throw new Is('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}function hK(t,e){var r=[];return t[e].forEach(function(n){var i=r.length;r.forEach(function(a,s){a.tag===n.tag&&a.kind===n.kind&&a.multi===n.multi&&(i=s)}),r[i]=n}),r}function _Ae(){var t={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},e,r;function n(i){i.multi?(t.multi[i.kind].push(i),t.multi.fallback.push(i)):t[i.kind][i.tag]=t.fallback[i.tag]=i}for(o(n,"collectType"),e=0,r=arguments.length;e=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:r*parseFloat(e,10)}function JAe(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(Gi.isNegativeZero(t))return"-0.0";return r=t.toString(10),ZAe.test(r)?r.replace("e",".e"):r}function e8e(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!==0||Gi.isNegativeZero(t))}function n8e(t){return t===null?!1:DK.exec(t)!==null||LK.exec(t)!==null}function i8e(t){var e,r,n,i,a,s,l,u=0,h=null,f,d,p;if(e=DK.exec(t),e===null&&(e=LK.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],n=+e[2]-1,i=+e[3],!e[4])return new Date(Date.UTC(r,n,i));if(a=+e[4],s=+e[5],l=+e[6],e[7]){for(u=e[7].slice(0,3);u.length<3;)u+="0";u=+u}return e[9]&&(f=+e[10],d=+(e[11]||0),h=(f*60+d)*6e4,e[9]==="-"&&(h=-h)),p=new Date(Date.UTC(r,n,i,a,s,l,u)),h&&p.setTime(p.getTime()-h),p}function a8e(t){return t.toISOString()}function o8e(t){return t==="<<"||t===null}function c8e(t){if(t===null)return!1;var e,r,n=0,i=t.length,a=q9;for(r=0;r64)){if(e<0)return!1;n+=6}return n%8===0}function u8e(t){var e,r,n=t.replace(/[\r\n=]/g,""),i=n.length,a=q9,s=0,l=[];for(e=0;e>16&255),l.push(s>>8&255),l.push(s&255)),s=s<<6|a.indexOf(n.charAt(e));return r=i%4*6,r===0?(l.push(s>>16&255),l.push(s>>8&255),l.push(s&255)):r===18?(l.push(s>>10&255),l.push(s>>2&255)):r===12&&l.push(s>>4&255),new Uint8Array(l)}function h8e(t){var e="",r=0,n,i,a=t.length,s=q9;for(n=0;n>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]),r=(r<<8)+t[n];return i=a%3,i===0?(e+=s[r>>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]):i===2?(e+=s[r>>10&63],e+=s[r>>4&63],e+=s[r<<2&63],e+=s[64]):i===1&&(e+=s[r>>2&63],e+=s[r<<4&63],e+=s[64],e+=s[64]),e}function f8e(t){return Object.prototype.toString.call(t)==="[object Uint8Array]"}function g8e(t){if(t===null)return!0;var e=[],r,n,i,a,s,l=t;for(r=0,n=l.length;r>10)+55296,(t-65536&1023)+56320)}function O8e(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||RK,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function FK(t,e){var r={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return r.snippet=kAe(r),new Is(e,r)}function Qt(t,e){throw FK(t,e)}function NT(t,e){t.onWarning&&t.onWarning.call(null,FK(t,e))}function qh(t,e,r,n){var i,a,s,l;if(e1&&(t.result+=Gi.repeat(` -`,e-1))}function P8e(t,e,r){var n,i,a,s,l,u,h,f,d=t.kind,p=t.result,m;if(m=t.input.charCodeAt(t.position),Os(m)||ym(m)||m===35||m===38||m===42||m===33||m===124||m===62||m===39||m===34||m===37||m===64||m===96||(m===63||m===45)&&(i=t.input.charCodeAt(t.position+1),Os(i)||r&&ym(i)))return!1;for(t.kind="scalar",t.result="",a=s=t.position,l=!1;m!==0;){if(m===58){if(i=t.input.charCodeAt(t.position+1),Os(i)||r&&ym(i))break}else if(m===35){if(n=t.input.charCodeAt(t.position-1),Os(n))break}else{if(t.position===t.lineStart&&OT(t)||r&&ym(m))break;if(vc(m))if(u=t.line,h=t.lineStart,f=t.lineIndent,_i(t,!1,-1),t.lineIndent>=e){l=!0,m=t.input.charCodeAt(t.position);continue}else{t.position=s,t.line=u,t.lineStart=h,t.lineIndent=f;break}}l&&(qh(t,a,s,!1),X9(t,t.line-u),a=s=t.position,l=!1),Gd(m)||(s=t.position+1),m=t.input.charCodeAt(++t.position)}return qh(t,a,s,!1),t.result?!0:(t.kind=d,t.result=p,!1)}function B8e(t,e){var r,n,i;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,n=i=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(qh(t,n,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)n=t.position,t.position++,i=t.position;else return!0;else vc(r)?(qh(t,n,i,!0),X9(t,_i(t,!1,e)),n=i=t.position):t.position===t.lineStart&&OT(t)?Qt(t,"unexpected end of the document within a single quoted scalar"):(t.position++,i=t.position);Qt(t,"unexpected end of the stream within a single quoted scalar")}function F8e(t,e){var r,n,i,a,s,l;if(l=t.input.charCodeAt(t.position),l!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;(l=t.input.charCodeAt(t.position))!==0;){if(l===34)return qh(t,r,t.position,!0),t.position++,!0;if(l===92){if(qh(t,r,t.position,!0),l=t.input.charCodeAt(++t.position),vc(l))_i(t,!1,e);else if(l<256&&PK[l])t.result+=BK[l],t.position++;else if((s=N8e(l))>0){for(i=s,a=0;i>0;i--)l=t.input.charCodeAt(++t.position),(s=R8e(l))>=0?a=(a<<4)+s:Qt(t,"expected hexadecimal character");t.result+=I8e(a),t.position++}else Qt(t,"unknown escape sequence");r=n=t.position}else vc(l)?(qh(t,r,n,!0),X9(t,_i(t,!1,e)),r=n=t.position):t.position===t.lineStart&&OT(t)?Qt(t,"unexpected end of the document within a double quoted scalar"):(t.position++,n=t.position)}Qt(t,"unexpected end of the stream within a double quoted scalar")}function $8e(t,e){var r=!0,n,i,a,s=t.tag,l,u=t.anchor,h,f,d,p,m,g=Object.create(null),y,v,x,b;if(b=t.input.charCodeAt(t.position),b===91)f=93,m=!1,l=[];else if(b===123)f=125,m=!0,l={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=l),b=t.input.charCodeAt(++t.position);b!==0;){if(_i(t,!0,e),b=t.input.charCodeAt(t.position),b===f)return t.position++,t.tag=s,t.anchor=u,t.kind=m?"mapping":"sequence",t.result=l,!0;r?b===44&&Qt(t,"expected the node content, but found ','"):Qt(t,"missed comma between flow collection entries"),v=y=x=null,d=p=!1,b===63&&(h=t.input.charCodeAt(t.position+1),Os(h)&&(d=p=!0,t.position++,_i(t,!0,e))),n=t.line,i=t.lineStart,a=t.position,xm(t,e,LT,!1,!0),v=t.tag,y=t.result,_i(t,!0,e),b=t.input.charCodeAt(t.position),(p||t.line===n)&&b===58&&(d=!0,b=t.input.charCodeAt(++t.position),_i(t,!0,e),xm(t,e,LT,!1,!0),x=t.result),m?vm(t,l,g,v,y,x,n,i,a):d?l.push(vm(t,null,g,v,y,x,n,i,a)):l.push(y),_i(t,!0,e),b=t.input.charCodeAt(t.position),b===44?(r=!0,b=t.input.charCodeAt(++t.position)):r=!1}Qt(t,"unexpected end of the stream within a flow collection")}function z8e(t,e){var r,n,i=z9,a=!1,s=!1,l=e,u=0,h=!1,f,d;if(d=t.input.charCodeAt(t.position),d===124)n=!1;else if(d===62)n=!0;else return!1;for(t.kind="scalar",t.result="";d!==0;)if(d=t.input.charCodeAt(++t.position),d===43||d===45)z9===i?i=d===43?fK:A8e:Qt(t,"repeat of a chomping mode identifier");else if((f=M8e(d))>=0)f===0?Qt(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):s?Qt(t,"repeat of an indentation width identifier"):(l=e+f-1,s=!0);else break;if(Gd(d)){do d=t.input.charCodeAt(++t.position);while(Gd(d));if(d===35)do d=t.input.charCodeAt(++t.position);while(!vc(d)&&d!==0)}for(;d!==0;){for(Y9(t),t.lineIndent=0,d=t.input.charCodeAt(t.position);(!s||t.lineIndentl&&(l=t.lineIndent),vc(d)){u++;continue}if(t.lineIndente)&&u!==0)Qt(t,"bad indentation of a sequence entry");else if(t.lineIndente)&&(v&&(s=t.line,l=t.lineStart,u=t.position),xm(t,e,RT,!0,i)&&(v?g=t.result:y=t.result),v||(vm(t,d,p,m,g,y,s,l,u),m=g=y=null),_i(t,!0,-1),b=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&b!==0)Qt(t,"bad indentation of a mapping entry");else if(t.lineIndente?u=1:t.lineIndent===e?u=0:t.lineIndente?u=1:t.lineIndent===e?u=0:t.lineIndent tag; it should be "scalar", not "'+t.kind+'"'),d=0,p=t.implicitTypes.length;d"),t.result!==null&&g.kind!==t.kind&&Qt(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+g.kind+'", not "'+t.kind+'"'),g.resolve(t.result,t.tag)?(t.result=g.construct(t.result,t.tag),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):Qt(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||f}function W8e(t){var e=t.position,r,n,i,a=!1,s;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);(s=t.input.charCodeAt(t.position))!==0&&(_i(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||s!==37));){for(a=!0,s=t.input.charCodeAt(++t.position),r=t.position;s!==0&&!Os(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(r,t.position),i=[],n.length<1&&Qt(t,"directive name must not be less than one character in length");s!==0;){for(;Gd(s);)s=t.input.charCodeAt(++t.position);if(s===35){do s=t.input.charCodeAt(++t.position);while(s!==0&&!vc(s));break}if(vc(s))break;for(r=t.position;s!==0&&!Os(s);)s=t.input.charCodeAt(++t.position);i.push(t.input.slice(r,t.position))}s!==0&&Y9(t),Yh.call(mK,n)?mK[n](t,n,i):NT(t,'unknown document directive "'+n+'"')}if(_i(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,_i(t,!0,-1)):a&&Qt(t,"directives end mark is expected"),xm(t,t.lineIndent-1,RT,!1,!0),_i(t,!0,-1),t.checkLineBreaks&&D8e.test(t.input.slice(e,t.position))&&NT(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&OT(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,_i(t,!0,-1));return}if(t.position"u"&&(r=e,e=null);var n=$K(t,r);if(typeof e!="function")return n;for(var i=0,a=n.length;i=55296&&r<=56319&&e+1=56320&&n<=57343)?(r-55296)*1024+n-56320+65536:r}function XK(t){var e=/^\n* /;return e.test(t)}function T_e(t,e,r,n,i,a,s,l){var u,h=0,f=null,d=!1,p=!1,m=n!==-1,g=-1,y=x_e(g2(t,0))&&b_e(g2(t,t.length-1));if(e||s)for(u=0;u=65536?u+=2:u++){if(h=g2(t,u),!b2(h))return gm;y=y&&bK(h,f,l),f=h}else{for(u=0;u=65536?u+=2:u++){if(h=g2(t,u),h===v2)d=!0,m&&(p=p||u-g-1>n&&t[g+1]!==" ",g=u);else if(!b2(h))return gm;y=y&&bK(h,f,l),f=h}p=p||m&&u-g-1>n&&t[g+1]!==" "}return!d&&!p?y&&!s&&!i(t)?jK:a===x2?gm:H9:r>9&&XK(t)?gm:s?a===x2?gm:H9:p?QK:KK}function w_e(t,e,r,n,i){t.dump=function(){if(e.length===0)return t.quotingType===x2?'""':"''";if(!t.noCompatMode&&(f_e.indexOf(e)!==-1||d_e.test(e)))return t.quotingType===x2?'"'+e+'"':"'"+e+"'";var a=t.indent*Math.max(1,r),s=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-a),l=n||t.flowLevel>-1&&r>=t.flowLevel;function u(h){return v_e(t,h)}switch(o(u,"testAmbiguity"),T_e(e,l,t.indent,s,u,t.quotingType,t.forceQuotes&&!n,i)){case jK:return e;case H9:return"'"+e.replace(/'/g,"''")+"'";case KK:return"|"+TK(e,t.indent)+wK(vK(e,a));case QK:return">"+TK(e,t.indent)+wK(vK(k_e(e,s),a));case gm:return'"'+E_e(e)+'"';default:throw new Is("impossible error: invalid scalar style")}}()}function TK(t,e){var r=XK(t)?String(e):"",n=t[t.length-1]===` -`,i=n&&(t[t.length-2]===` -`||t===` -`),a=i?"+":n?"":"-";return r+a+` -`}function wK(t){return t[t.length-1]===` -`?t.slice(0,-1):t}function k_e(t,e){for(var r=/(\n+)([^\n]*)/g,n=function(){var h=t.indexOf(` -`);return h=h!==-1?h:t.length,r.lastIndex=h,kK(t.slice(0,h),e)}(),i=t[0]===` -`||t[0]===" ",a,s;s=r.exec(t);){var l=s[1],u=s[2];a=u[0]===" ",n+=l+(!i&&!a&&u!==""?` -`:"")+kK(u,e),i=a}return n}function kK(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,n,i=0,a,s=0,l=0,u="";n=r.exec(t);)l=n.index,l-i>e&&(a=s>i?s:l,u+=` -`+t.slice(i,a),i=a+1),s=l;return u+=` -`,t.length-i>e&&s>i?u+=t.slice(i,s)+` -`+t.slice(s+1):u+=t.slice(i),u.slice(1)}function E_e(t){for(var e="",r=0,n,i=0;i=65536?i+=2:i++)r=g2(t,i),n=Na[r],!n&&b2(r)?(e+=t[i],r>=65536&&(e+=t[i+1])):e+=n||m_e(r);return e}function S_e(t,e,r){var n="",i=t.tag,a,s,l;for(a=0,s=r.length;a"u"&&Ru(t,e,null,!1,!1))&&(n!==""&&(n+=","+(t.condenseFlow?"":" ")),n+=t.dump);t.tag=i,t.dump="["+n+"]"}function EK(t,e,r,n){var i="",a=t.tag,s,l,u;for(s=0,l=r.length;s"u"&&Ru(t,e+1,null,!0,!0,!1,!0))&&((!n||i!=="")&&(i+=U9(t,e)),t.dump&&v2===t.dump.charCodeAt(0)?i+="-":i+="- ",i+=t.dump);t.tag=a,t.dump=i||"[]"}function C_e(t,e,r){var n="",i=t.tag,a=Object.keys(r),s,l,u,h,f;for(s=0,l=a.length;s1024&&(f+="? "),f+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Ru(t,e,h,!1,!1)&&(f+=t.dump,n+=f));t.tag=i,t.dump="{"+n+"}"}function A_e(t,e,r,n){var i="",a=t.tag,s=Object.keys(r),l,u,h,f,d,p;if(t.sortKeys===!0)s.sort();else if(typeof t.sortKeys=="function")s.sort(t.sortKeys);else if(t.sortKeys)throw new Is("sortKeys must be a boolean or a function");for(l=0,u=s.length;l1024,d&&(t.dump&&v2===t.dump.charCodeAt(0)?p+="?":p+="? "),p+=t.dump,d&&(p+=U9(t,e)),Ru(t,e+1,f,!0,d)&&(t.dump&&v2===t.dump.charCodeAt(0)?p+=":":p+=": ",p+=t.dump,i+=p));t.tag=a,t.dump=i||"{}"}function SK(t,e,r){var n,i,a,s,l,u;for(i=r?t.explicitTypes:t.implicitTypes,a=0,s=i.length;a tag resolver accepts not "'+u+'" style');t.dump=n}return!0}return!1}function Ru(t,e,r,n,i,a,s){t.tag=null,t.dump=r,SK(t,r,!1)||SK(t,r,!0);var l=GK.call(t.dump),u=n,h;n&&(n=t.flowLevel<0||t.flowLevel>e);var f=l==="[object Object]"||l==="[object Array]",d,p;if(f&&(d=t.duplicates.indexOf(r),p=d!==-1),(t.tag!==null&&t.tag!=="?"||p||t.indent!==2&&e>0)&&(i=!1),p&&t.usedDuplicates[d])t.dump="*ref_"+d;else{if(f&&p&&!t.usedDuplicates[d]&&(t.usedDuplicates[d]=!0),l==="[object Object]")n&&Object.keys(t.dump).length!==0?(A_e(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(C_e(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object Array]")n&&t.dump.length!==0?(t.noArrayIndent&&!s&&e>0?EK(t,e-1,t.dump,i):EK(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(S_e(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object String]")t.tag!=="?"&&w_e(t,t.dump,e,a,u);else{if(l==="[object Undefined]")return!1;if(t.skipInvalid)return!1;throw new Is("unacceptable kind of an object to dump "+l)}t.tag!==null&&t.tag!=="?"&&(h=encodeURI(t.tag[0]==="!"?t.tag.slice(1):t.tag).replace(/!/g,"%21"),t.tag[0]==="!"?h="!"+h:h.slice(0,18)==="tag:yaml.org,2002:"?h="!!"+h.slice(18):h="!<"+h+">",t.dump=h+" "+t.dump)}return!0}function __e(t,e){var r=[],n=[],i,a;for(W9(t,r,n),i=0,a=n.length;i{"use strict";o(CK,"isNothing");o(hAe,"isObject");o(fAe,"toArray");o(dAe,"extend");o(pAe,"repeat");o(mAe,"isNegativeZero");gAe=CK,yAe=hAe,vAe=fAe,xAe=pAe,bAe=mAe,TAe=dAe,Gi={isNothing:gAe,isObject:yAe,toArray:vAe,repeat:xAe,isNegativeZero:bAe,extend:TAe};o(AK,"formatError");o(y2,"YAMLException$1");y2.prototype=Object.create(Error.prototype);y2.prototype.constructor=y2;y2.prototype.toString=o(function(e){return this.name+": "+AK(this,e)},"toString");Is=y2;o(F9,"getLine");o($9,"padStart");o(wAe,"makeSnippet");kAe=wAe,EAe=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],SAe=["scalar","sequence","mapping"];o(CAe,"compileStyleAliases");o(AAe,"Type$1");Ra=AAe;o(hK,"compileList");o(_Ae,"compileMap");o(G9,"Schema$1");G9.prototype.extend=o(function(e){var r=[],n=[];if(e instanceof Ra)n.push(e);else if(Array.isArray(e))n=n.concat(e);else if(e&&(Array.isArray(e.implicit)||Array.isArray(e.explicit)))e.implicit&&(r=r.concat(e.implicit)),e.explicit&&(n=n.concat(e.explicit));else throw new Is("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");r.forEach(function(a){if(!(a instanceof Ra))throw new Is("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(a.loadKind&&a.loadKind!=="scalar")throw new Is("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(a.multi)throw new Is("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),n.forEach(function(a){if(!(a instanceof Ra))throw new Is("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var i=Object.create(G9.prototype);return i.implicit=(this.implicit||[]).concat(r),i.explicit=(this.explicit||[]).concat(n),i.compiledImplicit=hK(i,"implicit"),i.compiledExplicit=hK(i,"explicit"),i.compiledTypeMap=_Ae(i.compiledImplicit,i.compiledExplicit),i},"extend");DAe=G9,LAe=new Ra("tag:yaml.org,2002:str",{kind:"scalar",construct:o(function(t){return t!==null?t:""},"construct")}),RAe=new Ra("tag:yaml.org,2002:seq",{kind:"sequence",construct:o(function(t){return t!==null?t:[]},"construct")}),NAe=new Ra("tag:yaml.org,2002:map",{kind:"mapping",construct:o(function(t){return t!==null?t:{}},"construct")}),MAe=new DAe({explicit:[LAe,RAe,NAe]});o(IAe,"resolveYamlNull");o(OAe,"constructYamlNull");o(PAe,"isNull");BAe=new Ra("tag:yaml.org,2002:null",{kind:"scalar",resolve:IAe,construct:OAe,predicate:PAe,represent:{canonical:o(function(){return"~"},"canonical"),lowercase:o(function(){return"null"},"lowercase"),uppercase:o(function(){return"NULL"},"uppercase"),camelcase:o(function(){return"Null"},"camelcase"),empty:o(function(){return""},"empty")},defaultStyle:"lowercase"});o(FAe,"resolveYamlBoolean");o($Ae,"constructYamlBoolean");o(zAe,"isBoolean");GAe=new Ra("tag:yaml.org,2002:bool",{kind:"scalar",resolve:FAe,construct:$Ae,predicate:zAe,represent:{lowercase:o(function(t){return t?"true":"false"},"lowercase"),uppercase:o(function(t){return t?"TRUE":"FALSE"},"uppercase"),camelcase:o(function(t){return t?"True":"False"},"camelcase")},defaultStyle:"lowercase"});o(VAe,"isHexCode");o(UAe,"isOctCode");o(HAe,"isDecCode");o(WAe,"resolveYamlInteger");o(qAe,"constructYamlInteger");o(YAe,"isInteger");XAe=new Ra("tag:yaml.org,2002:int",{kind:"scalar",resolve:WAe,construct:qAe,predicate:YAe,represent:{binary:o(function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},"binary"),octal:o(function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},"octal"),decimal:o(function(t){return t.toString(10)},"decimal"),hexadecimal:o(function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)},"hexadecimal")},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),jAe=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");o(KAe,"resolveYamlFloat");o(QAe,"constructYamlFloat");ZAe=/^[-+]?[0-9]+e/;o(JAe,"representYamlFloat");o(e8e,"isFloat");t8e=new Ra("tag:yaml.org,2002:float",{kind:"scalar",resolve:KAe,construct:QAe,predicate:e8e,represent:JAe,defaultStyle:"lowercase"}),_K=MAe.extend({implicit:[BAe,GAe,XAe,t8e]}),r8e=_K,DK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),LK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");o(n8e,"resolveYamlTimestamp");o(i8e,"constructYamlTimestamp");o(a8e,"representYamlTimestamp");s8e=new Ra("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:n8e,construct:i8e,instanceOf:Date,represent:a8e});o(o8e,"resolveYamlMerge");l8e=new Ra("tag:yaml.org,2002:merge",{kind:"scalar",resolve:o8e}),q9=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= -\r`;o(c8e,"resolveYamlBinary");o(u8e,"constructYamlBinary");o(h8e,"representYamlBinary");o(f8e,"isBinary");d8e=new Ra("tag:yaml.org,2002:binary",{kind:"scalar",resolve:c8e,construct:u8e,predicate:f8e,represent:h8e}),p8e=Object.prototype.hasOwnProperty,m8e=Object.prototype.toString;o(g8e,"resolveYamlOmap");o(y8e,"constructYamlOmap");v8e=new Ra("tag:yaml.org,2002:omap",{kind:"sequence",resolve:g8e,construct:y8e}),x8e=Object.prototype.toString;o(b8e,"resolveYamlPairs");o(T8e,"constructYamlPairs");w8e=new Ra("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:b8e,construct:T8e}),k8e=Object.prototype.hasOwnProperty;o(E8e,"resolveYamlSet");o(S8e,"constructYamlSet");C8e=new Ra("tag:yaml.org,2002:set",{kind:"mapping",resolve:E8e,construct:S8e}),RK=r8e.extend({implicit:[s8e,l8e],explicit:[d8e,v8e,w8e,C8e]}),Yh=Object.prototype.hasOwnProperty,LT=1,NK=2,MK=3,RT=4,z9=1,A8e=2,fK=3,_8e=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,D8e=/[\x85\u2028\u2029]/,L8e=/[,\[\]\{\}]/,IK=/^(?:!|!!|![a-z\-]+!)$/i,OK=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;o(dK,"_class");o(vc,"is_EOL");o(Gd,"is_WHITE_SPACE");o(Os,"is_WS_OR_EOL");o(ym,"is_FLOW_INDICATOR");o(R8e,"fromHexCode");o(N8e,"escapedHexLen");o(M8e,"fromDecimalCode");o(pK,"simpleEscapeSequence");o(I8e,"charFromCodepoint");PK=new Array(256),BK=new Array(256);for(zd=0;zd<256;zd++)PK[zd]=pK(zd)?1:0,BK[zd]=pK(zd);o(O8e,"State$1");o(FK,"generateError");o(Qt,"throwError");o(NT,"throwWarning");mK={YAML:o(function(e,r,n){var i,a,s;e.version!==null&&Qt(e,"duplication of %YAML directive"),n.length!==1&&Qt(e,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),i===null&&Qt(e,"ill-formed argument of the YAML directive"),a=parseInt(i[1],10),s=parseInt(i[2],10),a!==1&&Qt(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=s<2,s!==1&&s!==2&&NT(e,"unsupported YAML version of the document")},"handleYamlDirective"),TAG:o(function(e,r,n){var i,a;n.length!==2&&Qt(e,"TAG directive accepts exactly two arguments"),i=n[0],a=n[1],IK.test(i)||Qt(e,"ill-formed tag handle (first argument) of the TAG directive"),Yh.call(e.tagMap,i)&&Qt(e,'there is a previously declared suffix for "'+i+'" tag handle'),OK.test(a)||Qt(e,"ill-formed tag prefix (second argument) of the TAG directive");try{a=decodeURIComponent(a)}catch{Qt(e,"tag prefix is malformed: "+a)}e.tagMap[i]=a},"handleTagDirective")};o(qh,"captureSegment");o(gK,"mergeMappings");o(vm,"storeMappingPair");o(Y9,"readLineBreak");o(_i,"skipSeparationSpace");o(OT,"testDocumentSeparator");o(X9,"writeFoldedLines");o(P8e,"readPlainScalar");o(B8e,"readSingleQuotedScalar");o(F8e,"readDoubleQuotedScalar");o($8e,"readFlowCollection");o(z8e,"readBlockScalar");o(yK,"readBlockSequence");o(G8e,"readBlockMapping");o(V8e,"readTagProperty");o(U8e,"readAnchorProperty");o(H8e,"readAlias");o(xm,"composeNode");o(W8e,"readDocument");o($K,"loadDocuments");o(q8e,"loadAll$1");o(Y8e,"load$1");X8e=q8e,j8e=Y8e,zK={loadAll:X8e,load:j8e},GK=Object.prototype.toString,VK=Object.prototype.hasOwnProperty,j9=65279,K8e=9,v2=10,Q8e=13,Z8e=32,J8e=33,e_e=34,V9=35,t_e=37,r_e=38,n_e=39,i_e=42,UK=44,a_e=45,MT=58,s_e=61,o_e=62,l_e=63,c_e=64,HK=91,WK=93,u_e=96,qK=123,h_e=124,YK=125,Na={};Na[0]="\\0";Na[7]="\\a";Na[8]="\\b";Na[9]="\\t";Na[10]="\\n";Na[11]="\\v";Na[12]="\\f";Na[13]="\\r";Na[27]="\\e";Na[34]='\\"';Na[92]="\\\\";Na[133]="\\N";Na[160]="\\_";Na[8232]="\\L";Na[8233]="\\P";f_e=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],d_e=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;o(p_e,"compileStyleMap");o(m_e,"encodeHex");g_e=1,x2=2;o(y_e,"State");o(vK,"indentString");o(U9,"generateNextLine");o(v_e,"testImplicitResolving");o(IT,"isWhitespace");o(b2,"isPrintable");o(xK,"isNsCharOrWhitespace");o(bK,"isPlainSafe");o(x_e,"isPlainSafeFirst");o(b_e,"isPlainSafeLast");o(g2,"codePointAt");o(XK,"needIndentIndicator");jK=1,H9=2,KK=3,QK=4,gm=5;o(T_e,"chooseScalarStyle");o(w_e,"writeScalar");o(TK,"blockHeader");o(wK,"dropEndingNewline");o(k_e,"foldString");o(kK,"foldLine");o(E_e,"escapeString");o(S_e,"writeFlowSequence");o(EK,"writeBlockSequence");o(C_e,"writeFlowMapping");o(A_e,"writeBlockMapping");o(SK,"detectType");o(Ru,"writeNode");o(__e,"getDuplicateReferences");o(W9,"inspectNode");o(D_e,"dump$1");L_e=D_e,R_e={dump:L_e};o(K9,"renamed");bm=_K,Tm=zK.load,qSt=zK.loadAll,YSt=R_e.dump,XSt=K9("safeLoad","load"),jSt=K9("safeLoadAll","loadAll"),KSt=K9("safeDump","dump")});function tL(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function nQ(t){Ud=t}function nn(t,e=""){let r=typeof t=="string"?t:t.source,n={replace:o((i,a)=>{let s=typeof a=="string"?a:a.source;return s=s.replace(ss.caret,"$1"),r=r.replace(i,s),n},"replace"),getRegex:o(()=>new RegExp(r,e),"getRegex")};return n}function xc(t,e){if(e){if(ss.escapeTest.test(t))return t.replace(ss.escapeReplace,JK)}else if(ss.escapeTestNoEncode.test(t))return t.replace(ss.escapeReplaceNoEncode,JK);return t}function eQ(t){try{t=encodeURI(t).replace(ss.percentDecode,"%")}catch{return null}return t}function tQ(t,e){let r=t.replace(ss.findPipe,(a,s,l)=>{let u=!1,h=s;for(;--h>=0&&l[h]==="\\";)u=!u;return u?"|":" |"}),n=r.split(ss.splitPipe),i=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length0?-2:-1}function rQ(t,e,r,n,i){let a=e.href,s=e.title||null,l=t[1].replace(i.other.outputLinkReplace,"$1");n.state.inLink=!0;let u={type:t[0].charAt(0)==="!"?"image":"link",raw:r,href:a,title:s,text:l,tokens:n.inlineTokens(l)};return n.state.inLink=!1,u}function fDe(t,e,r){let n=t.match(r.other.indentCodeCompensation);if(n===null)return e;let i=n[1];return e.split(` -`).map(a=>{let s=a.match(r.other.beginningSpace);if(s===null)return a;let[l]=s;return l.length>=i.length?a.slice(i.length):a}).join(` -`)}function Jr(t,e){return Vd.parse(t,e)}var Ud,k2,ss,N_e,M_e,I_e,E2,O_e,rL,iQ,aQ,P_e,nL,B_e,iL,F_e,$_e,VT,aL,z_e,sQ,G_e,sL,ZK,V_e,U_e,H_e,W_e,oQ,q_e,UT,oL,lQ,Y_e,cQ,X_e,j_e,K_e,uQ,Q_e,Z_e,hQ,J_e,eDe,tDe,rDe,nDe,iDe,aDe,$T,sDe,fQ,dQ,oDe,lL,lDe,Z9,cDe,BT,T2,uDe,JK,zT,Nu,GT,cL,Mu,FT,dDe,Vd,ZSt,JSt,e6t,t6t,r6t,n6t,i6t,pQ=N(()=>{"use strict";o(tL,"M");Ud=tL();o(nQ,"H");k2={exec:o(()=>null,"exec")};o(nn,"h");ss={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:o(t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\n]*)?(?:\\n|$))`),"listItemRegex"),nextBulletRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),"nextBulletRegex"),hrRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),"hrRegex"),fencesBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:\`\`\`|~~~)`),"fencesBeginRegex"),headingBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}#`),"headingBeginRegex"),htmlBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}<(?:[a-z].*>|!--)`,"i"),"htmlBeginRegex")},N_e=/^(?:[ \t]*(?:\n|$))+/,M_e=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,I_e=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,E2=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,O_e=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,rL=/(?:[*+-]|\d{1,9}[.)])/,iQ=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,aQ=nn(iQ).replace(/bull/g,rL).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),P_e=nn(iQ).replace(/bull/g,rL).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),nL=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,B_e=/^[^\n]+/,iL=/(?!\s*\])(?:\\.|[^\[\]\\])+/,F_e=nn(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",iL).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),$_e=nn(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,rL).getRegex(),VT="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",aL=/|$))/,z_e=nn("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",aL).replace("tag",VT).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),sQ=nn(nL).replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex(),G_e=nn(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",sQ).getRegex(),sL={blockquote:G_e,code:M_e,def:F_e,fences:I_e,heading:O_e,hr:E2,html:z_e,lheading:aQ,list:$_e,newline:N_e,paragraph:sQ,table:k2,text:B_e},ZK=nn("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex(),V_e={...sL,lheading:P_e,table:ZK,paragraph:nn(nL).replace("hr",E2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",ZK).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",VT).getRegex()},U_e={...sL,html:nn(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",aL).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:k2,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:nn(nL).replace("hr",E2).replace("heading",` *#{1,6} *[^ -]`).replace("lheading",aQ).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},H_e=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,W_e=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,oQ=/^( {2,}|\\)\n(?!\s*$)/,q_e=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\]*?>/g,uQ=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,Q_e=nn(uQ,"u").replace(/punct/g,UT).getRegex(),Z_e=nn(uQ,"u").replace(/punct/g,cQ).getRegex(),hQ="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",J_e=nn(hQ,"gu").replace(/notPunctSpace/g,lQ).replace(/punctSpace/g,oL).replace(/punct/g,UT).getRegex(),eDe=nn(hQ,"gu").replace(/notPunctSpace/g,j_e).replace(/punctSpace/g,X_e).replace(/punct/g,cQ).getRegex(),tDe=nn("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,lQ).replace(/punctSpace/g,oL).replace(/punct/g,UT).getRegex(),rDe=nn(/\\(punct)/,"gu").replace(/punct/g,UT).getRegex(),nDe=nn(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),iDe=nn(aL).replace("(?:-->|$)","-->").getRegex(),aDe=nn("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",iDe).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),$T=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,sDe=nn(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",$T).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),fQ=nn(/^!?\[(label)\]\[(ref)\]/).replace("label",$T).replace("ref",iL).getRegex(),dQ=nn(/^!?\[(ref)\](?:\[\])?/).replace("ref",iL).getRegex(),oDe=nn("reflink|nolink(?!\\()","g").replace("reflink",fQ).replace("nolink",dQ).getRegex(),lL={_backpedal:k2,anyPunctuation:rDe,autolink:nDe,blockSkip:K_e,br:oQ,code:W_e,del:k2,emStrongLDelim:Q_e,emStrongRDelimAst:J_e,emStrongRDelimUnd:tDe,escape:H_e,link:sDe,nolink:dQ,punctuation:Y_e,reflink:fQ,reflinkSearch:oDe,tag:aDe,text:q_e,url:k2},lDe={...lL,link:nn(/^!?\[(label)\]\((.*?)\)/).replace("label",$T).getRegex(),reflink:nn(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",$T).getRegex()},Z9={...lL,emStrongRDelimAst:eDe,emStrongLDelim:Z_e,url:nn(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},JK=o(t=>uDe[t],"ge");o(xc,"R");o(eQ,"J");o(tQ,"V");o(w2,"A");o(hDe,"fe");o(rQ,"de");o(fDe,"Je");zT=class{static{o(this,"S")}options;rules;lexer;constructor(t){this.options=t||Ud}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let r=e[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?r:w2(r,` -`)}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let r=e[0],n=fDe(r,e[3]||"",this.rules);return{type:"code",raw:r,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:n}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let r=e[2].trim();if(this.rules.other.endingHash.test(r)){let n=w2(r,"#");(this.options.pedantic||!n||this.rules.other.endingSpaceChar.test(n))&&(r=n.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:r,tokens:this.lexer.inline(r)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:w2(e[0],` -`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let r=w2(e[0],` -`).split(` -`),n="",i="",a=[];for(;r.length>0;){let s=!1,l=[],u;for(u=0;u1,i={type:"list",raw:"",ordered:n,start:n?+r.slice(0,-1):"",loose:!1,items:[]};r=n?`\\d{1,9}\\${r.slice(-1)}`:`\\${r}`,this.options.pedantic&&(r=n?r:"[*+-]");let a=this.rules.other.listItemRegex(r),s=!1;for(;t;){let u=!1,h="",f="";if(!(e=a.exec(t))||this.rules.block.hr.test(t))break;h=e[0],t=t.substring(h.length);let d=e[2].split(` -`,1)[0].replace(this.rules.other.listReplaceTabs,x=>" ".repeat(3*x.length)),p=t.split(` -`,1)[0],m=!d.trim(),g=0;if(this.options.pedantic?(g=2,f=d.trimStart()):m?g=e[1].length+1:(g=e[2].search(this.rules.other.nonSpaceChar),g=g>4?1:g,f=d.slice(g),g+=e[1].length),m&&this.rules.other.blankLine.test(p)&&(h+=p+` -`,t=t.substring(p.length+1),u=!0),!u){let x=this.rules.other.nextBulletRegex(g),b=this.rules.other.hrRegex(g),T=this.rules.other.fencesBeginRegex(g),S=this.rules.other.headingBeginRegex(g),w=this.rules.other.htmlBeginRegex(g);for(;t;){let E=t.split(` -`,1)[0],_;if(p=E,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),_=p):_=p.replace(this.rules.other.tabCharGlobal," "),T.test(p)||S.test(p)||w.test(p)||x.test(p)||b.test(p))break;if(_.search(this.rules.other.nonSpaceChar)>=g||!p.trim())f+=` -`+_.slice(g);else{if(m||d.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||T.test(d)||S.test(d)||b.test(d))break;f+=` -`+p}!m&&!p.trim()&&(m=!0),h+=E+` -`,t=t.substring(E.length+1),d=_.slice(g)}}i.loose||(s?i.loose=!0:this.rules.other.doubleBlankLine.test(h)&&(s=!0));let y=null,v;this.options.gfm&&(y=this.rules.other.listIsTask.exec(f),y&&(v=y[0]!=="[ ] ",f=f.replace(this.rules.other.listReplaceTask,""))),i.items.push({type:"list_item",raw:h,task:!!y,checked:v,loose:!1,text:f,tokens:[]}),i.raw+=h}let l=i.items.at(-1);if(l)l.raw=l.raw.trimEnd(),l.text=l.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let u=0;ud.type==="space"),f=h.length>0&&h.some(d=>this.rules.other.anyLine.test(d.raw));i.loose=f}if(i.loose)for(let u=0;u({text:l,tokens:this.lexer.inline(l),header:!1,align:a.align[u]})));return a}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e)return{type:"heading",raw:e[0],depth:e[2].charAt(0)==="="?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let r=e[1].charAt(e[1].length-1)===` -`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:r,tokens:this.lexer.inline(r)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){let e=this.rules.inline.link.exec(t);if(e){let r=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(r)){if(!this.rules.other.endAngleBracket.test(r))return;let a=w2(r.slice(0,-1),"\\");if((r.length-a.length)%2===0)return}else{let a=hDe(e[2],"()");if(a===-2)return;if(a>-1){let s=(e[0].indexOf("!")===0?5:4)+e[1].length+a;e[2]=e[2].substring(0,a),e[0]=e[0].substring(0,s).trim(),e[3]=""}}let n=e[2],i="";if(this.options.pedantic){let a=this.rules.other.pedanticHrefTitle.exec(n);a&&(n=a[1],i=a[3])}else i=e[3]?e[3].slice(1,-1):"";return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(r)?n=n.slice(1):n=n.slice(1,-1)),rQ(e,{href:n&&n.replace(this.rules.inline.anyPunctuation,"$1"),title:i&&i.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let r;if((r=this.rules.inline.reflink.exec(t))||(r=this.rules.inline.nolink.exec(t))){let n=(r[2]||r[1]).replace(this.rules.other.multipleSpaceGlobal," "),i=e[n.toLowerCase()];if(!i){let a=r[0].charAt(0);return{type:"text",raw:a,text:a}}return rQ(r,i,r[0],this.lexer,this.rules)}}emStrong(t,e,r=""){let n=this.rules.inline.emStrongLDelim.exec(t);if(!(!n||n[3]&&r.match(this.rules.other.unicodeAlphaNumeric))&&(!(n[1]||n[2])||!r||this.rules.inline.punctuation.exec(r))){let i=[...n[0]].length-1,a,s,l=i,u=0,h=n[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(h.lastIndex=0,e=e.slice(-1*t.length+i);(n=h.exec(e))!=null;){if(a=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!a)continue;if(s=[...a].length,n[3]||n[4]){l+=s;continue}else if((n[5]||n[6])&&i%3&&!((i+s)%3)){u+=s;continue}if(l-=s,l>0)continue;s=Math.min(s,s+l+u);let f=[...n[0]][0].length,d=t.slice(0,i+n.index+f+s);if(Math.min(i,s)%2){let m=d.slice(1,-1);return{type:"em",raw:d,text:m,tokens:this.lexer.inlineTokens(m)}}let p=d.slice(2,-2);return{type:"strong",raw:d,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let r=e[2].replace(this.rules.other.newLineCharGlobal," "),n=this.rules.other.nonSpaceChar.test(r),i=this.rules.other.startingSpaceChar.test(r)&&this.rules.other.endingSpaceChar.test(r);return n&&i&&(r=r.substring(1,r.length-1)),{type:"codespan",raw:e[0],text:r}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t){let e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let r,n;return e[2]==="@"?(r=e[1],n="mailto:"+r):(r=e[1],n=r),{type:"link",raw:e[0],text:r,href:n,tokens:[{type:"text",raw:r,text:r}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let r,n;if(e[2]==="@")r=e[0],n="mailto:"+r;else{let i;do i=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(i!==e[0]);r=e[0],e[1]==="www."?n="http://"+e[0]:n=e[0]}return{type:"link",raw:e[0],text:r,href:n,tokens:[{type:"text",raw:r,text:r}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let r=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:r}}}},Nu=class J9{static{o(this,"a")}tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||Ud,this.options.tokenizer=this.options.tokenizer||new zT,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let r={other:ss,block:BT.normal,inline:T2.normal};this.options.pedantic?(r.block=BT.pedantic,r.inline=T2.pedantic):this.options.gfm&&(r.block=BT.gfm,this.options.breaks?r.inline=T2.breaks:r.inline=T2.gfm),this.tokenizer.rules=r}static get rules(){return{block:BT,inline:T2}}static lex(e,r){return new J9(r).lex(e)}static lexInline(e,r){return new J9(r).inlineTokens(e)}lex(e){e=e.replace(ss.carriageReturn,` -`),this.blockTokens(e,this.tokens);for(let r=0;r(i=s.call({lexer:this},e,r))?(e=e.substring(i.raw.length),r.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let s=r.at(-1);i.raw.length===1&&s!==void 0?s.raw+=` -`:r.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=` -`+i.raw,s.text+=` -`+i.text,this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=` -`+i.raw,s.text+=` -`+i.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title});continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),r.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let s=1/0,l=e.slice(1),u;this.options.extensions.startBlock.forEach(h=>{u=h.call({lexer:this},l),typeof u=="number"&&u>=0&&(s=Math.min(s,u))}),s<1/0&&s>=0&&(a=e.substring(0,s+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let s=r.at(-1);n&&s?.type==="paragraph"?(s.raw+=` -`+i.raw,s.text+=` -`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i),n=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="text"?(s.raw+=` -`+i.raw,s.text+=` -`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(e){let s="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,r}inline(e,r=[]){return this.inlineQueue.push({src:e,tokens:r}),r}inlineTokens(e,r=[]){let n=e,i=null;if(this.tokens.links){let l=Object.keys(this.tokens.links);if(l.length>0)for(;(i=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)l.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(i=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,i.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(i=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);let a=!1,s="";for(;e;){a||(s=""),a=!1;let l;if(this.options.extensions?.inline?.some(h=>(l=h.call({lexer:this},e,r))?(e=e.substring(l.raw.length),r.push(l),!0):!1))continue;if(l=this.tokenizer.escape(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.tag(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.link(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(l.raw.length);let h=r.at(-1);l.type==="text"&&h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(l=this.tokenizer.emStrong(e,n,s)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.codespan(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.br(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.del(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.autolink(e)){e=e.substring(l.raw.length),r.push(l);continue}if(!this.state.inLink&&(l=this.tokenizer.url(e))){e=e.substring(l.raw.length),r.push(l);continue}let u=e;if(this.options.extensions?.startInline){let h=1/0,f=e.slice(1),d;this.options.extensions.startInline.forEach(p=>{d=p.call({lexer:this},f),typeof d=="number"&&d>=0&&(h=Math.min(h,d))}),h<1/0&&h>=0&&(u=e.substring(0,h+1))}if(l=this.tokenizer.inlineText(u)){e=e.substring(l.raw.length),l.raw.slice(-1)!=="_"&&(s=l.raw.slice(-1)),a=!0;let h=r.at(-1);h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(e){let h="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(h);break}else throw new Error(h)}}return r}},GT=class{static{o(this,"$")}options;parser;constructor(t){this.options=t||Ud}space(t){return""}code({text:t,lang:e,escaped:r}){let n=(e||"").match(ss.notSpaceStart)?.[0],i=t.replace(ss.endingNewline,"")+` -`;return n?'
    '+(r?i:xc(i,!0))+`
    -`:"
    "+(r?i:xc(i,!0))+`
    -`}blockquote({tokens:t}){return`
    -${this.parser.parse(t)}
    -`}html({text:t}){return t}heading({tokens:t,depth:e}){return`${this.parser.parseInline(t)} -`}hr(t){return`
    -`}list(t){let e=t.ordered,r=t.start,n="";for(let s=0;s -`+n+" -`}listitem(t){let e="";if(t.task){let r=this.checkbox({checked:!!t.checked});t.loose?t.tokens[0]?.type==="paragraph"?(t.tokens[0].text=r+" "+t.tokens[0].text,t.tokens[0].tokens&&t.tokens[0].tokens.length>0&&t.tokens[0].tokens[0].type==="text"&&(t.tokens[0].tokens[0].text=r+" "+xc(t.tokens[0].tokens[0].text),t.tokens[0].tokens[0].escaped=!0)):t.tokens.unshift({type:"text",raw:r+" ",text:r+" ",escaped:!0}):e+=r+" "}return e+=this.parser.parse(t.tokens,!!t.loose),`
  • ${e}
  • -`}checkbox({checked:t}){return"'}paragraph({tokens:t}){return`

    ${this.parser.parseInline(t)}

    -`}table(t){let e="",r="";for(let i=0;i${n}`),` - -`+e+` -`+n+`
    -`}tablerow({text:t}){return` -${t} -`}tablecell(t){let e=this.parser.parseInline(t.tokens),r=t.header?"th":"td";return(t.align?`<${r} align="${t.align}">`:`<${r}>`)+e+` -`}strong({tokens:t}){return`${this.parser.parseInline(t)}`}em({tokens:t}){return`${this.parser.parseInline(t)}`}codespan({text:t}){return`${xc(t,!0)}`}br(t){return"
    "}del({tokens:t}){return`${this.parser.parseInline(t)}`}link({href:t,title:e,tokens:r}){let n=this.parser.parseInline(r),i=eQ(t);if(i===null)return n;t=i;let a='
    ",a}image({href:t,title:e,text:r,tokens:n}){n&&(r=this.parser.parseInline(n,this.parser.textRenderer));let i=eQ(t);if(i===null)return xc(r);t=i;let a=`${r}{let s=i[a].flat(1/0);r=r.concat(this.walkTokens(s,e))}):i.tokens&&(r=r.concat(this.walkTokens(i.tokens,e)))}}return r}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(r=>{let n={...r};if(n.async=this.defaults.async||n.async||!1,r.extensions&&(r.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let a=e.renderers[i.name];a?e.renderers[i.name]=function(...s){let l=i.renderer.apply(this,s);return l===!1&&(l=a.apply(this,s)),l}:e.renderers[i.name]=i.renderer}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let a=e[i.level];a?a.unshift(i.tokenizer):e[i.level]=[i.tokenizer],i.start&&(i.level==="block"?e.startBlock?e.startBlock.push(i.start):e.startBlock=[i.start]:i.level==="inline"&&(e.startInline?e.startInline.push(i.start):e.startInline=[i.start]))}"childTokens"in i&&i.childTokens&&(e.childTokens[i.name]=i.childTokens)}),n.extensions=e),r.renderer){let i=this.defaults.renderer||new GT(this.defaults);for(let a in r.renderer){if(!(a in i))throw new Error(`renderer '${a}' does not exist`);if(["options","parser"].includes(a))continue;let s=a,l=r.renderer[s],u=i[s];i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f||""}}n.renderer=i}if(r.tokenizer){let i=this.defaults.tokenizer||new zT(this.defaults);for(let a in r.tokenizer){if(!(a in i))throw new Error(`tokenizer '${a}' does not exist`);if(["options","rules","lexer"].includes(a))continue;let s=a,l=r.tokenizer[s],u=i[s];i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f}}n.tokenizer=i}if(r.hooks){let i=this.defaults.hooks||new FT;for(let a in r.hooks){if(!(a in i))throw new Error(`hook '${a}' does not exist`);if(["options","block"].includes(a))continue;let s=a,l=r.hooks[s],u=i[s];FT.passThroughHooks.has(a)?i[s]=h=>{if(this.defaults.async)return Promise.resolve(l.call(i,h)).then(d=>u.call(i,d));let f=l.call(i,h);return u.call(i,f)}:i[s]=(...h)=>{let f=l.apply(i,h);return f===!1&&(f=u.apply(i,h)),f}}n.hooks=i}if(r.walkTokens){let i=this.defaults.walkTokens,a=r.walkTokens;n.walkTokens=function(s){let l=[];return l.push(a.call(this,s)),i&&(l=l.concat(i.call(this,s))),l}}this.defaults={...this.defaults,...n}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return Nu.lex(t,e??this.defaults)}parser(t,e){return Mu.parse(t,e??this.defaults)}parseMarkdown(t){return(e,r)=>{let n={...r},i={...this.defaults,...n},a=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&n.async===!1)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return a(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return a(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));i.hooks&&(i.hooks.options=i,i.hooks.block=t);let s=i.hooks?i.hooks.provideLexer():t?Nu.lex:Nu.lexInline,l=i.hooks?i.hooks.provideParser():t?Mu.parse:Mu.parseInline;if(i.async)return Promise.resolve(i.hooks?i.hooks.preprocess(e):e).then(u=>s(u,i)).then(u=>i.hooks?i.hooks.processAllTokens(u):u).then(u=>i.walkTokens?Promise.all(this.walkTokens(u,i.walkTokens)).then(()=>u):u).then(u=>l(u,i)).then(u=>i.hooks?i.hooks.postprocess(u):u).catch(a);try{i.hooks&&(e=i.hooks.preprocess(e));let u=s(e,i);i.hooks&&(u=i.hooks.processAllTokens(u)),i.walkTokens&&this.walkTokens(u,i.walkTokens);let h=l(u,i);return i.hooks&&(h=i.hooks.postprocess(h)),h}catch(u){return a(u)}}}onError(t,e){return r=>{if(r.message+=` -Please report this to https://github.com/markedjs/marked.`,t){let n="

    An error occurred:

    "+xc(r.message+"",!0)+"
    ";return e?Promise.resolve(n):n}if(e)return Promise.reject(r);throw r}}},Vd=new dDe;o(Jr,"k");Jr.options=Jr.setOptions=function(t){return Vd.setOptions(t),Jr.defaults=Vd.defaults,nQ(Jr.defaults),Jr};Jr.getDefaults=tL;Jr.defaults=Ud;Jr.use=function(...t){return Vd.use(...t),Jr.defaults=Vd.defaults,nQ(Jr.defaults),Jr};Jr.walkTokens=function(t,e){return Vd.walkTokens(t,e)};Jr.parseInline=Vd.parseInline;Jr.Parser=Mu;Jr.parser=Mu.parse;Jr.Renderer=GT;Jr.TextRenderer=cL;Jr.Lexer=Nu;Jr.lexer=Nu.lex;Jr.Tokenizer=zT;Jr.Hooks=FT;Jr.parse=Jr;ZSt=Jr.options,JSt=Jr.setOptions,e6t=Jr.use,t6t=Jr.walkTokens,r6t=Jr.parseInline,n6t=Mu.parse,i6t=Nu.lex});function pDe(t,{markdownAutoWrap:e}){let n=t.replace(//g,` -`).replace(/\n{2,}/g,` -`),i=j4(n);return e===!1?i.replace(/ /g," "):i}function mQ(t,e={}){let r=pDe(t,e),n=Jr.lexer(r),i=[[]],a=0;function s(l,u="normal"){l.type==="text"?l.text.split(` -`).forEach((f,d)=>{d!==0&&(a++,i.push([])),f.split(" ").forEach(p=>{p=p.replace(/'/g,"'"),p&&i[a].push({content:p,type:u})})}):l.type==="strong"||l.type==="em"?l.tokens.forEach(h=>{s(h,l.type)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}return o(s,"processNode"),n.forEach(l=>{l.type==="paragraph"?l.tokens?.forEach(u=>{s(u)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}),i}function gQ(t,{markdownAutoWrap:e}={}){let r=Jr.lexer(t);function n(i){return i.type==="text"?e===!1?i.text.replace(/\n */g,"
    ").replace(/ /g," "):i.text.replace(/\n */g,"
    "):i.type==="strong"?`${i.tokens?.map(n).join("")}`:i.type==="em"?`${i.tokens?.map(n).join("")}`:i.type==="paragraph"?`

    ${i.tokens?.map(n).join("")}

    `:i.type==="space"?"":i.type==="html"?`${i.text}`:i.type==="escape"?i.text:`Unsupported markdown: ${i.type}`}return o(n,"output"),r.map(n).join("")}var yQ=N(()=>{"use strict";pQ();r7();o(pDe,"preprocessMarkdown");o(mQ,"markdownToLines");o(gQ,"markdownToHTML")});function mDe(t){return Intl.Segmenter?[...new Intl.Segmenter().segment(t)].map(e=>e.segment):[...t]}function gDe(t,e){let r=mDe(e.content);return vQ(t,[],r,e.type)}function vQ(t,e,r,n){if(r.length===0)return[{content:e.join(""),type:n},{content:"",type:n}];let[i,...a]=r,s=[...e,i];return t([{content:s.join(""),type:n}])?vQ(t,s,a,n):(e.length===0&&i&&(e.push(i),r.shift()),[{content:e.join(""),type:n},{content:r.join(""),type:n}])}function xQ(t,e){if(t.some(({content:r})=>r.includes(` -`)))throw new Error("splitLineToFitWidth does not support newlines in the line");return uL(t,e)}function uL(t,e,r=[],n=[]){if(t.length===0)return n.length>0&&r.push(n),r.length>0?r:[];let i="";t[0].content===" "&&(i=" ",t.shift());let a=t.shift()??{content:" ",type:"normal"},s=[...n];if(i!==""&&s.push({content:i,type:"normal"}),s.push(a),e(s))return uL(t,e,r,s);if(n.length>0)r.push(n),t.unshift(a);else if(a.content){let[l,u]=gDe(e,a);r.push([l]),u.content&&t.unshift(u)}return uL(t,e,r)}var bQ=N(()=>{"use strict";o(mDe,"splitTextToChars");o(gDe,"splitWordToFitWidth");o(vQ,"splitWordToFitWidthRecursion");o(xQ,"splitLineToFitWidth");o(uL,"splitLineToFitWidthRecursion")});function TQ(t,e){e&&t.attr("style",e)}async function yDe(t,e,r,n,i=!1){let a=t.append("foreignObject");a.attr("width",`${10*r}px`),a.attr("height",`${10*r}px`);let s=a.append("xhtml:div"),l=e.label;e.label&&yi(e.label)&&(l=await Th(e.label.replace(Ze.lineBreakRegex,` -`),me()));let u=e.isNode?"nodeLabel":"edgeLabel",h=s.append("span");h.html(l),TQ(h,e.labelStyle),h.attr("class",`${u} ${n}`),TQ(s,e.labelStyle),s.style("display","table-cell"),s.style("white-space","nowrap"),s.style("line-height","1.5"),s.style("max-width",r+"px"),s.style("text-align","center"),s.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&s.attr("class","labelBkg");let f=s.node().getBoundingClientRect();return f.width===r&&(s.style("display","table"),s.style("white-space","break-spaces"),s.style("width",r+"px"),f=s.node().getBoundingClientRect()),a.node()}function hL(t,e,r){return t.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",e*r-.1+"em").attr("dy",r+"em")}function vDe(t,e,r){let n=t.append("text"),i=hL(n,1,e);fL(i,r);let a=i.node().getComputedTextLength();return n.remove(),a}function wQ(t,e,r){let n=t.append("text"),i=hL(n,1,e);fL(i,[{content:r,type:"normal"}]);let a=i.node()?.getBoundingClientRect();return a&&n.remove(),a}function xDe(t,e,r,n=!1){let a=e.append("g"),s=a.insert("rect").attr("class","background").attr("style","stroke: none"),l=a.append("text").attr("y","-10.1"),u=0;for(let h of r){let f=o(p=>vDe(a,1.1,p)<=t,"checkWidth"),d=f(h)?[h]:xQ(h,f);for(let p of d){let m=hL(l,u,1.1);fL(m,p),u++}}if(n){let h=l.node().getBBox(),f=2;return s.attr("x",h.x-f).attr("y",h.y-f).attr("width",h.width+2*f).attr("height",h.height+2*f),a.node()}else return l.node()}function fL(t,e){t.text(""),e.forEach((r,n)=>{let i=t.append("tspan").attr("font-style",r.type==="em"?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight",r.type==="strong"?"bold":"normal");n===0?i.text(r.content):i.text(" "+r.content)})}async function dL(t){let e=[];t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,(n,i,a)=>(e.push((async()=>{let s=`${i}:${a}`;return await F$(s)?await Es(s,void 0,{class:"label-icon"}):``})()),n));let r=await Promise.all(e);return t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,()=>r.shift()??"")}var qn,ao=N(()=>{"use strict";fr();Gt();pr();yt();yQ();er();jl();bQ();o(TQ,"applyStyle");o(yDe,"addHtmlSpan");o(hL,"createTspan");o(vDe,"computeWidthOfText");o(wQ,"computeDimensionOfText");o(xDe,"createFormattedText");o(fL,"updateTextContentAndStyles");o(dL,"replaceIconSubstring");qn=o(async(t,e="",{style:r="",isTitle:n=!1,classes:i="",useHtmlLabels:a=!0,isNode:s=!0,width:l=200,addSvgBackground:u=!1}={},h)=>{if(X.debug("XYZ createText",e,r,n,i,a,s,"addSvgBackground: ",u),a){let f=gQ(e,h),d=await dL(na(f)),p=e.replace(/\\\\/g,"\\"),m={isNode:s,label:yi(e)?p:d,labelStyle:r.replace("fill:","color:")};return await yDe(t,m,l,i,u)}else{let f=e.replace(//g,"
    "),d=mQ(f.replace("
    ","
    "),h),p=xDe(l,t,d,e?u:!1);if(s){/stroke:/.exec(r)&&(r=r.replace("stroke:","lineColor:"));let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).attr("style",m)}else{let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/background:/g,"fill:");Ge(p).select("rect").attr("style",m.replace(/background:/g,"fill:"));let g=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).select("text").attr("style",g)}return p}},"createText")});function Xt(t){let e=t.map((r,n)=>`${n===0?"M":"L"}${r.x},${r.y}`);return e.push("Z"),e.join(" ")}function Go(t,e,r,n,i,a){let s=[],u=r-t,h=n-e,f=u/a,d=2*Math.PI/f,p=e+h/2;for(let m=0;m<=50;m++){let g=m/50,y=t+g*u,v=p+i*Math.sin(d*(y-t));s.push({x:y,y:v})}return s}function WT(t,e,r,n,i,a){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d{"use strict";ao();Gt();fr();_a();pr();er();mt=o(async(t,e,r)=>{let n,i=e.useHtmlLabels||dr(me()?.htmlLabels);r?n=r:n="node default";let a=t.insert("g").attr("class",n).attr("id",e.domId||e.id),s=a.insert("g").attr("class","label").attr("style",zn(e.labelStyle)),l;e.label===void 0?l="":l=typeof e.label=="string"?e.label:e.label[0];let u=await qn(s,wr(na(l),me()),{useHtmlLabels:i,width:e.width||me().flowchart?.wrappingWidth,cssClasses:"markdown-node-label",style:e.labelStyle,addSvgBackground:!!e.icon||!!e.img}),h=u.getBBox(),f=(e?.padding??0)/2;if(i){let d=u.children[0],p=Ge(u),m=d.getElementsByTagName("img");if(m){let g=l.replace(/]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=me().fontSize?me().fontSize:window.getComputedStyle(document.body).fontSize,T=5,[S=or.fontSize]=zo(b),w=S*T+"px";y.style.minWidth=w,y.style.maxWidth=w}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}return i?s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"):s.attr("transform","translate(0, "+-h.height/2+")"),e.centerLabel&&s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),s.insert("rect",":first-child"),{shapeSvg:a,bbox:h,halfPadding:f,label:s}},"labelHelper"),HT=o(async(t,e,r)=>{let n=r.useHtmlLabels||dr(me()?.flowchart?.htmlLabels),i=t.insert("g").attr("class","label").attr("style",r.labelStyle||""),a=await qn(i,wr(na(e),me()),{useHtmlLabels:n,width:r.width||me()?.flowchart?.wrappingWidth,style:r.labelStyle,addSvgBackground:!!r.icon||!!r.img}),s=a.getBBox(),l=r.padding/2;if(dr(me()?.flowchart?.htmlLabels)){let u=a.children[0],h=Ge(a);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}return n?i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"):i.attr("transform","translate(0, "+-s.height/2+")"),r.centerLabel&&i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),i.insert("rect",":first-child"),{shapeSvg:t,bbox:s,halfPadding:l,label:i}},"insertLabel"),Ke=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds"),ht=o((t,e)=>(t.look==="handDrawn"?"rough-node":"node")+" "+t.cssClasses+" "+(e||""),"getNodeClasses");o(Xt,"createPathFromPoints");o(Go,"generateFullSineWavePoints");o(WT,"generateCirclePoints")});function bDe(t,e){return t.intersect(e)}var kQ,EQ=N(()=>{"use strict";o(bDe,"intersectNode");kQ=bDe});function TDe(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x{"use strict";o(TDe,"intersectEllipse");qT=TDe});function wDe(t,e,r){return qT(t,e,e,r)}var SQ,CQ=N(()=>{"use strict";pL();o(wDe,"intersectCircle");SQ=wDe});function kDe(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&AQ(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&AQ(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function AQ(t,e){return t*e>0}var _Q,DQ=N(()=>{"use strict";o(kDe,"intersectLine");o(AQ,"sameSign");_Q=kDe});function EDe(t,e,r){let n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(f){s=Math.min(s,f.x),l=Math.min(l,f.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));let u=n-t.width/2-s,h=i-t.height/2-l;for(let f=0;f1&&a.sort(function(f,d){let p=f.x-r.x,m=f.y-r.y,g=Math.sqrt(p*p+m*m),y=d.x-r.x,v=d.y-r.y,x=Math.sqrt(y*y+v*v);return g{"use strict";DQ();o(EDe,"intersectPolygon");LQ=EDe});var SDe,Xh,mL=N(()=>{"use strict";SDe=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),Xh=SDe});var Xe,Ht=N(()=>{"use strict";EQ();CQ();pL();RQ();mL();Xe={node:kQ,circle:SQ,ellipse:qT,polygon:LQ,rect:Xh}});var NQ,bc,CDe,S2,Ye,Qe,zt=N(()=>{"use strict";Gt();NQ=o(t=>{let{handDrawnSeed:e}=me();return{fill:t,hachureAngle:120,hachureGap:4,fillWeight:2,roughness:.7,stroke:t,seed:e}},"solidStateFill"),bc=o(t=>{let e=CDe([...t.cssCompiledStyles||[],...t.cssStyles||[]]);return{stylesMap:e,stylesArray:[...e]}},"compileStyles"),CDe=o(t=>{let e=new Map;return t.forEach(r=>{let[n,i]=r.split(":");e.set(n.trim(),i?.trim())}),e},"styles2Map"),S2=o(t=>t==="color"||t==="font-size"||t==="font-family"||t==="font-weight"||t==="font-style"||t==="text-decoration"||t==="text-align"||t==="text-transform"||t==="line-height"||t==="letter-spacing"||t==="word-spacing"||t==="text-shadow"||t==="text-overflow"||t==="white-space"||t==="word-wrap"||t==="word-break"||t==="overflow-wrap"||t==="hyphens","isLabelStyle"),Ye=o(t=>{let{stylesArray:e}=bc(t),r=[],n=[],i=[],a=[];return e.forEach(s=>{let l=s[0];S2(l)?r.push(s.join(":")+" !important"):(n.push(s.join(":")+" !important"),l.includes("stroke")&&i.push(s.join(":")+" !important"),l==="fill"&&a.push(s.join(":")+" !important"))}),{labelStyles:r.join(";"),nodeStyles:n.join(";"),stylesArray:e,borderStyles:i,backgroundStyles:a}},"styles2String"),Qe=o((t,e)=>{let{themeVariables:r,handDrawnSeed:n}=me(),{nodeBorder:i,mainBkg:a}=r,{stylesMap:s}=bc(t);return Object.assign({roughness:.7,fill:s.get("fill")||a,fillStyle:"hachure",fillWeight:4,hachureGap:5.2,stroke:s.get("stroke")||i,seed:n,strokeWidth:s.get("stroke-width")?.replace("px","")||1.3,fillLineDash:[0,0]},e)},"userNodeOverrides")});function gL(t,e,r){if(t&&t.length){let[n,i]=e,a=Math.PI/180*r,s=Math.cos(a),l=Math.sin(a);for(let u of t){let[h,f]=u;u[0]=(h-n)*s-(f-i)*l+n,u[1]=(h-n)*l+(f-i)*s+i}}}function ADe(t,e){return t[0]===e[0]&&t[1]===e[1]}function _De(t,e,r,n=1){let i=r,a=Math.max(e,.1),s=t[0]&&t[0][0]&&typeof t[0][0]=="number"?[t]:t,l=[0,0];if(i)for(let h of s)gL(h,l,i);let u=function(h,f,d){let p=[];for(let b of h){let T=[...b];ADe(T[0],T[T.length-1])||T.push([T[0][0],T[0][1]]),T.length>2&&p.push(T)}let m=[];f=Math.max(f,.1);let g=[];for(let b of p)for(let T=0;Tb.yminT.ymin?1:b.xT.x?1:b.ymax===T.ymax?0:(b.ymax-T.ymax)/Math.abs(b.ymax-T.ymax)),!g.length)return m;let y=[],v=g[0].ymin,x=0;for(;y.length||g.length;){if(g.length){let b=-1;for(let T=0;Tv);T++)b=T;g.splice(0,b+1).forEach(T=>{y.push({s:v,edge:T})})}if(y=y.filter(b=>!(b.edge.ymax<=v)),y.sort((b,T)=>b.edge.x===T.edge.x?0:(b.edge.x-T.edge.x)/Math.abs(b.edge.x-T.edge.x)),(d!==1||x%f==0)&&y.length>1)for(let b=0;b=y.length)break;let S=y[b].edge,w=y[T].edge;m.push([[Math.round(S.x),v],[Math.round(w.x),v]])}v+=d,y.forEach(b=>{b.edge.x=b.edge.x+d*b.edge.islope}),x++}return m}(s,a,n);if(i){for(let h of s)gL(h,l,-i);(function(h,f,d){let p=[];h.forEach(m=>p.push(...m)),gL(p,f,d)})(u,l,-i)}return u}function D2(t,e){var r;let n=e.hachureAngle+90,i=e.hachureGap;i<0&&(i=4*e.strokeWidth),i=Math.round(Math.max(i,.1));let a=1;return e.roughness>=1&&(((r=e.randomizer)===null||r===void 0?void 0:r.next())||Math.random())>.7&&(a=i),_De(t,i,n,a||1)}function tw(t){let e=t[0],r=t[1];return Math.sqrt(Math.pow(e[0]-r[0],2)+Math.pow(e[1]-r[1],2))}function vL(t,e){return t.type===e}function NL(t){let e=[],r=function(s){let l=new Array;for(;s!=="";)if(s.match(/^([ \t\r\n,]+)/))s=s.substr(RegExp.$1.length);else if(s.match(/^([aAcChHlLmMqQsStTvVzZ])/))l[l.length]={type:DDe,text:RegExp.$1},s=s.substr(RegExp.$1.length);else{if(!s.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];l[l.length]={type:yL,text:`${parseFloat(RegExp.$1)}`},s=s.substr(RegExp.$1.length)}return l[l.length]={type:MQ,text:""},l}(t),n="BOD",i=0,a=r[i];for(;!vL(a,MQ);){let s=0,l=[];if(n==="BOD"){if(a.text!=="M"&&a.text!=="m")return NL("M0,0"+t);i++,s=YT[a.text],n=a.text}else vL(a,yL)?s=YT[n]:(i++,s=YT[a.text],n=a.text);if(!(i+sf%2?h+r:h+e);a.push({key:"C",data:u}),e=u[4],r=u[5];break}case"Q":a.push({key:"Q",data:[...l]}),e=l[2],r=l[3];break;case"q":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"Q",data:u}),e=u[2],r=u[3];break}case"A":a.push({key:"A",data:[...l]}),e=l[5],r=l[6];break;case"a":e+=l[5],r+=l[6],a.push({key:"A",data:[l[0],l[1],l[2],l[3],l[4],e,r]});break;case"H":a.push({key:"H",data:[...l]}),e=l[0];break;case"h":e+=l[0],a.push({key:"H",data:[e]});break;case"V":a.push({key:"V",data:[...l]}),r=l[0];break;case"v":r+=l[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...l]}),e=l[2],r=l[3];break;case"s":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"S",data:u}),e=u[2],r=u[3];break}case"T":a.push({key:"T",data:[...l]}),e=l[0],r=l[1];break;case"t":e+=l[0],r+=l[1],a.push({key:"T",data:[e,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),e=n,r=i}return a}function VQ(t){let e=[],r="",n=0,i=0,a=0,s=0,l=0,u=0;for(let{key:h,data:f}of t){switch(h){case"M":e.push({key:"M",data:[...f]}),[n,i]=f,[a,s]=f;break;case"C":e.push({key:"C",data:[...f]}),n=f[4],i=f[5],l=f[2],u=f[3];break;case"L":e.push({key:"L",data:[...f]}),[n,i]=f;break;case"H":n=f[0],e.push({key:"L",data:[n,i]});break;case"V":i=f[0],e.push({key:"L",data:[n,i]});break;case"S":{let d=0,p=0;r==="C"||r==="S"?(d=n+(n-l),p=i+(i-u)):(d=n,p=i),e.push({key:"C",data:[d,p,...f]}),l=f[0],u=f[1],n=f[2],i=f[3];break}case"T":{let[d,p]=f,m=0,g=0;r==="Q"||r==="T"?(m=n+(n-l),g=i+(i-u)):(m=n,g=i);let y=n+2*(m-n)/3,v=i+2*(g-i)/3,x=d+2*(m-d)/3,b=p+2*(g-p)/3;e.push({key:"C",data:[y,v,x,b,d,p]}),l=m,u=g,n=d,i=p;break}case"Q":{let[d,p,m,g]=f,y=n+2*(d-n)/3,v=i+2*(p-i)/3,x=m+2*(d-m)/3,b=g+2*(p-g)/3;e.push({key:"C",data:[y,v,x,b,m,g]}),l=d,u=p,n=m,i=g;break}case"A":{let d=Math.abs(f[0]),p=Math.abs(f[1]),m=f[2],g=f[3],y=f[4],v=f[5],x=f[6];d===0||p===0?(e.push({key:"C",data:[n,i,v,x,v,x]}),n=v,i=x):(n!==v||i!==x)&&(UQ(n,i,v,x,d,p,m,g,y).forEach(function(b){e.push({key:"C",data:b})}),n=v,i=x);break}case"Z":e.push({key:"Z",data:[]}),n=a,i=s}r=h}return e}function C2(t,e,r){return[t*Math.cos(r)-e*Math.sin(r),t*Math.sin(r)+e*Math.cos(r)]}function UQ(t,e,r,n,i,a,s,l,u,h){let f=(d=s,Math.PI*d/180);var d;let p=[],m=0,g=0,y=0,v=0;if(h)[m,g,y,v]=h;else{[t,e]=C2(t,e,-f),[r,n]=C2(r,n,-f);let L=(t-r)/2,A=(e-n)/2,I=L*L/(i*i)+A*A/(a*a);I>1&&(I=Math.sqrt(I),i*=I,a*=I);let M=i*i,P=a*a,B=M*P-M*A*A-P*L*L,F=M*A*A+P*L*L,z=(l===u?-1:1)*Math.sqrt(Math.abs(B/F));y=z*i*A/a+(t+r)/2,v=z*-a*L/i+(e+n)/2,m=Math.asin(parseFloat(((e-v)/a).toFixed(9))),g=Math.asin(parseFloat(((n-v)/a).toFixed(9))),tg&&(m-=2*Math.PI),!u&&g>m&&(g-=2*Math.PI)}let x=g-m;if(Math.abs(x)>120*Math.PI/180){let L=g,A=r,I=n;g=u&&g>m?m+120*Math.PI/180*1:m+120*Math.PI/180*-1,p=UQ(r=y+i*Math.cos(g),n=v+a*Math.sin(g),A,I,i,a,s,0,u,[g,L,y,v])}x=g-m;let b=Math.cos(m),T=Math.sin(m),S=Math.cos(g),w=Math.sin(g),E=Math.tan(x/4),_=4/3*i*E,C=4/3*a*E,D=[t,e],O=[t+_*T,e-C*b],R=[r+_*w,n-C*S],k=[r,n];if(O[0]=2*D[0]-O[0],O[1]=2*D[1]-O[1],h)return[O,R,k].concat(p);{p=[O,R,k].concat(p);let L=[];for(let A=0;A2){let i=[];for(let a=0;a2*Math.PI&&(m=0,g=2*Math.PI);let y=2*Math.PI/u.curveStepCount,v=Math.min(y/2,(g-m)/2),x=$Q(v,h,f,d,p,m,g,1,u);if(!u.disableMultiStroke){let b=$Q(v,h,f,d,p,m,g,1.5,u);x.push(...b)}return s&&(l?x.push(...jh(h,f,h+d*Math.cos(m),f+p*Math.sin(m),u),...jh(h,f,h+d*Math.cos(g),f+p*Math.sin(g),u)):x.push({op:"lineTo",data:[h,f]},{op:"lineTo",data:[h+d*Math.cos(m),f+p*Math.sin(m)]})),{type:"path",ops:x}}function PQ(t,e){let r=VQ(GQ(NL(t))),n=[],i=[0,0],a=[0,0];for(let{key:s,data:l}of r)switch(s){case"M":a=[l[0],l[1]],i=[l[0],l[1]];break;case"L":n.push(...jh(a[0],a[1],l[0],l[1],e)),a=[l[0],l[1]];break;case"C":{let[u,h,f,d,p,m]=l;n.push(...NDe(u,h,f,d,p,m,a,e)),a=[p,m];break}case"Z":n.push(...jh(a[0],a[1],i[0],i[1],e)),a=[i[0],i[1]]}return{type:"path",ops:n}}function xL(t,e){let r=[];for(let n of t)if(n.length){let i=e.maxRandomnessOffset||0,a=n.length;if(a>2){r.push({op:"move",data:[n[0][0]+ar(i,e),n[0][1]+ar(i,e)]});for(let s=1;s500?.4:-.0016668*u+1.233334;let f=i.maxRandomnessOffset||0;f*f*100>l&&(f=u/10);let d=f/2,p=.2+.2*qQ(i),m=i.bowing*i.maxRandomnessOffset*(n-e)/200,g=i.bowing*i.maxRandomnessOffset*(t-r)/200;m=ar(m,i,h),g=ar(g,i,h);let y=[],v=o(()=>ar(d,i,h),"M"),x=o(()=>ar(f,i,h),"k"),b=i.preserveVertices;return a&&(s?y.push({op:"move",data:[t+(b?0:v()),e+(b?0:v())]}):y.push({op:"move",data:[t+(b?0:ar(f,i,h)),e+(b?0:ar(f,i,h))]})),s?y.push({op:"bcurveTo",data:[m+t+(r-t)*p+v(),g+e+(n-e)*p+v(),m+t+2*(r-t)*p+v(),g+e+2*(n-e)*p+v(),r+(b?0:v()),n+(b?0:v())]}):y.push({op:"bcurveTo",data:[m+t+(r-t)*p+x(),g+e+(n-e)*p+x(),m+t+2*(r-t)*p+x(),g+e+2*(n-e)*p+x(),r+(b?0:x()),n+(b?0:x())]}),y}function XT(t,e,r){if(!t.length)return[];let n=[];n.push([t[0][0]+ar(e,r),t[0][1]+ar(e,r)]),n.push([t[0][0]+ar(e,r),t[0][1]+ar(e,r)]);for(let i=1;i3){let a=[],s=1-r.curveTightness;i.push({op:"move",data:[t[1][0],t[1][1]]});for(let l=1;l+21&&i.push(l)):i.push(l),i.push(t[e+3])}else{let u=t[e+0],h=t[e+1],f=t[e+2],d=t[e+3],p=Hd(u,h,.5),m=Hd(h,f,.5),g=Hd(f,d,.5),y=Hd(p,m,.5),v=Hd(m,g,.5),x=Hd(y,v,.5);DL([u,p,y,x],0,r,i),DL([x,v,g,d],0,r,i)}var a,s;return i}function IDe(t,e){return ew(t,0,t.length,e)}function ew(t,e,r,n,i){let a=i||[],s=t[e],l=t[r-1],u=0,h=1;for(let f=e+1;fu&&(u=d,h=f)}return Math.sqrt(u)>n?(ew(t,e,h+1,n,a),ew(t,h,r,n,a)):(a.length||a.push(s),a.push(l)),a}function bL(t,e=.15,r){let n=[],i=(t.length-1)/3;for(let a=0;a0?ew(n,0,n.length,r):n}var _2,TL,wL,kL,EL,SL,Ps,CL,DDe,yL,MQ,YT,LDe,so,km,LL,jT,RL,je,Wt=N(()=>{"use strict";o(gL,"t");o(ADe,"e");o(_De,"s");o(D2,"n");_2=class{static{o(this,"o")}constructor(e){this.helper=e}fillPolygons(e,r){return this._fillPolygons(e,r)}_fillPolygons(e,r){let n=D2(e,r);return{type:"fillSketch",ops:this.renderLines(n,r)}}renderLines(e,r){let n=[];for(let i of e)n.push(...this.helper.doubleLineOps(i[0][0],i[0][1],i[1][0],i[1][1],r));return n}};o(tw,"a");TL=class extends _2{static{o(this,"h")}fillPolygons(e,r){let n=r.hachureGap;n<0&&(n=4*r.strokeWidth),n=Math.max(n,.1);let i=D2(e,Object.assign({},r,{hachureGap:n})),a=Math.PI/180*r.hachureAngle,s=[],l=.5*n*Math.cos(a),u=.5*n*Math.sin(a);for(let[h,f]of i)tw([h,f])&&s.push([[h[0]-l,h[1]+u],[...f]],[[h[0]+l,h[1]-u],[...f]]);return{type:"fillSketch",ops:this.renderLines(s,r)}}},wL=class extends _2{static{o(this,"r")}fillPolygons(e,r){let n=this._fillPolygons(e,r),i=Object.assign({},r,{hachureAngle:r.hachureAngle+90}),a=this._fillPolygons(e,i);return n.ops=n.ops.concat(a.ops),n}},kL=class{static{o(this,"i")}constructor(e){this.helper=e}fillPolygons(e,r){let n=D2(e,r=Object.assign({},r,{hachureAngle:0}));return this.dotsOnLines(n,r)}dotsOnLines(e,r){let n=[],i=r.hachureGap;i<0&&(i=4*r.strokeWidth),i=Math.max(i,.1);let a=r.fillWeight;a<0&&(a=r.strokeWidth/2);let s=i/4;for(let l of e){let u=tw(l),h=u/i,f=Math.ceil(h)-1,d=u-f*i,p=(l[0][0]+l[1][0])/2-i/4,m=Math.min(l[0][1],l[1][1]);for(let g=0;g{let l=tw(s),u=Math.floor(l/(n+i)),h=(l+i-u*(n+i))/2,f=s[0],d=s[1];f[0]>d[0]&&(f=s[1],d=s[0]);let p=Math.atan((d[1]-f[1])/(d[0]-f[0]));for(let m=0;m{let s=tw(a),l=Math.round(s/(2*r)),u=a[0],h=a[1];u[0]>h[0]&&(u=a[1],h=a[0]);let f=Math.atan((h[1]-u[1])/(h[0]-u[0]));for(let d=0;d2*Math.PI&&(_=0,C=2*Math.PI);let D=(C-_)/b.curveStepCount,O=[];for(let R=_;R<=C;R+=D)O.push([T+w*Math.cos(R),S+E*Math.sin(R)]);return O.push([T+w*Math.cos(C),S+E*Math.sin(C)]),O.push([T,S]),wm([O],b)}(e,r,n,i,a,s,h));return h.stroke!==so&&f.push(d),this._d("arc",f,h)}curve(e,r){let n=this._o(r),i=[],a=IQ(e,n);if(n.fill&&n.fill!==so)if(n.fillStyle==="solid"){let s=IQ(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(s.ops)})}else{let s=[],l=e;if(l.length){let u=typeof l[0][0]=="number"?[l]:l;for(let h of u)h.length<3?s.push(...h):h.length===3?s.push(...bL(zQ([h[0],h[0],h[1],h[2]]),10,(1+n.roughness)/2)):s.push(...bL(zQ(h),10,(1+n.roughness)/2))}s.length&&i.push(wm([s],n))}return n.stroke!==so&&i.push(a),this._d("curve",i,n)}polygon(e,r){let n=this._o(r),i=[],a=KT(e,!0,n);return n.fill&&(n.fillStyle==="solid"?i.push(xL([e],n)):i.push(wm([e],n))),n.stroke!==so&&i.push(a),this._d("polygon",i,n)}path(e,r){let n=this._o(r),i=[];if(!e)return this._d("path",i,n);e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");let a=n.fill&&n.fill!=="transparent"&&n.fill!==so,s=n.stroke!==so,l=!!(n.simplification&&n.simplification<1),u=function(f,d,p){let m=VQ(GQ(NL(f))),g=[],y=[],v=[0,0],x=[],b=o(()=>{x.length>=4&&y.push(...bL(x,d)),x=[]},"i"),T=o(()=>{b(),y.length&&(g.push(y),y=[])},"c");for(let{key:w,data:E}of m)switch(w){case"M":T(),v=[E[0],E[1]],y.push(v);break;case"L":b(),y.push([E[0],E[1]]);break;case"C":if(!x.length){let _=y.length?y[y.length-1]:v;x.push([_[0],_[1]])}x.push([E[0],E[1]]),x.push([E[2],E[3]]),x.push([E[4],E[5]]);break;case"Z":b(),y.push([v[0],v[1]])}if(T(),!p)return g;let S=[];for(let w of g){let E=IDe(w,p);E.length&&S.push(E)}return S}(e,1,l?4-4*(n.simplification||1):(1+n.roughness)/2),h=PQ(e,n);if(a)if(n.fillStyle==="solid")if(u.length===1){let f=PQ(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(f.ops)})}else i.push(xL(u,n));else i.push(wm(u,n));return s&&(l?u.forEach(f=>{i.push(KT(f,!1,n))}):i.push(h)),this._d("path",i,n)}opsToPath(e,r){let n="";for(let i of e.ops){let a=typeof r=="number"&&r>=0?i.data.map(s=>+s.toFixed(r)):i.data;switch(i.op){case"move":n+=`M${a[0]} ${a[1]} `;break;case"bcurveTo":n+=`C${a[0]} ${a[1]}, ${a[2]} ${a[3]}, ${a[4]} ${a[5]} `;break;case"lineTo":n+=`L${a[0]} ${a[1]} `}}return n.trim()}toPaths(e){let r=e.sets||[],n=e.options||this.defaultOptions,i=[];for(let a of r){let s=null;switch(a.type){case"path":s={d:this.opsToPath(a),stroke:n.stroke,strokeWidth:n.strokeWidth,fill:so};break;case"fillPath":s={d:this.opsToPath(a),stroke:so,strokeWidth:0,fill:n.fill||so};break;case"fillSketch":s=this.fillSketch(a,n)}s&&i.push(s)}return i}fillSketch(e,r){let n=r.fillWeight;return n<0&&(n=r.strokeWidth/2),{d:this.opsToPath(e),stroke:r.fill||so,strokeWidth:n,fill:so}}_mergedShape(e){return e.filter((r,n)=>n===0||r.op!=="move")}},LL=class{static{o(this,"st")}constructor(e,r){this.canvas=e,this.ctx=this.canvas.getContext("2d"),this.gen=new km(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.ctx,a=e.options.fixedDecimalPlaceDigits;for(let s of r)switch(s.type){case"path":i.save(),i.strokeStyle=n.stroke==="none"?"transparent":n.stroke,i.lineWidth=n.strokeWidth,n.strokeLineDash&&i.setLineDash(n.strokeLineDash),n.strokeLineDashOffset&&(i.lineDashOffset=n.strokeLineDashOffset),this._drawToContext(i,s,a),i.restore();break;case"fillPath":{i.save(),i.fillStyle=n.fill||"";let l=e.shape==="curve"||e.shape==="polygon"||e.shape==="path"?"evenodd":"nonzero";this._drawToContext(i,s,a,l),i.restore();break}case"fillSketch":this.fillSketch(i,s,n)}}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2),e.save(),n.fillLineDash&&e.setLineDash(n.fillLineDash),n.fillLineDashOffset&&(e.lineDashOffset=n.fillLineDashOffset),e.strokeStyle=n.fill||"",e.lineWidth=i,this._drawToContext(e,r,n.fixedDecimalPlaceDigits),e.restore()}_drawToContext(e,r,n,i="nonzero"){e.beginPath();for(let a of r.ops){let s=typeof n=="number"&&n>=0?a.data.map(l=>+l.toFixed(n)):a.data;switch(a.op){case"move":e.moveTo(s[0],s[1]);break;case"bcurveTo":e.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5]);break;case"lineTo":e.lineTo(s[0],s[1])}}r.type==="fillPath"?e.fill(i):e.stroke()}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s),s}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s),s}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s),s}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a),a}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n),n}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n),n}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h),h}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n),n}path(e,r){let n=this.gen.path(e,r);return this.draw(n),n}},jT="http://www.w3.org/2000/svg",RL=class{static{o(this,"ot")}constructor(e,r){this.svg=e,this.gen=new km(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.svg.ownerDocument||window.document,a=i.createElementNS(jT,"g"),s=e.options.fixedDecimalPlaceDigits;for(let l of r){let u=null;switch(l.type){case"path":u=i.createElementNS(jT,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke",n.stroke),u.setAttribute("stroke-width",n.strokeWidth+""),u.setAttribute("fill","none"),n.strokeLineDash&&u.setAttribute("stroke-dasharray",n.strokeLineDash.join(" ").trim()),n.strokeLineDashOffset&&u.setAttribute("stroke-dashoffset",`${n.strokeLineDashOffset}`);break;case"fillPath":u=i.createElementNS(jT,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke","none"),u.setAttribute("stroke-width","0"),u.setAttribute("fill",n.fill||""),e.shape!=="curve"&&e.shape!=="polygon"||u.setAttribute("fill-rule","evenodd");break;case"fillSketch":u=this.fillSketch(i,l,n)}u&&a.appendChild(u)}return a}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2);let a=e.createElementNS(jT,"path");return a.setAttribute("d",this.opsToPath(r,n.fixedDecimalPlaceDigits)),a.setAttribute("stroke",n.fill||""),a.setAttribute("stroke-width",i+""),a.setAttribute("fill","none"),n.fillLineDash&&a.setAttribute("stroke-dasharray",n.fillLineDash.join(" ").trim()),n.fillLineDashOffset&&a.setAttribute("stroke-dashoffset",`${n.fillLineDashOffset}`),a}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e,r){return this.gen.opsToPath(e,r)}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s)}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s)}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s)}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a)}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n)}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n)}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h)}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n)}path(e,r){let n=this.gen.path(e,r);return this.draw(n)}},je={canvas:o((t,e)=>new LL(t,e),"canvas"),svg:o((t,e)=>new RL(t,e),"svg"),generator:o(t=>new km(t),"generator"),newSeed:o(()=>km.newSeed(),"newSeed")}});function YQ(t,e){let{labelStyles:r}=Ye(e);e.labelStyle=r;let n=ht(e),i=n;n||(i="anchor");let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=1,{cssStyles:l}=e,u=je.svg(a),h=Qe(e,{fill:"black",stroke:"none",fillStyle:"solid"});e.look!=="handDrawn"&&(h.roughness=0);let f=u.circle(0,0,s*2,h),d=a.insert(()=>f,":first-child");return d.attr("class","anchor").attr("style",zn(l)),Ke(e,d),e.intersect=function(p){return X.info("Circle intersect",e,s,p),Xe.circle(e,s,p)},a}var XQ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(YQ,"anchor")});function jQ(t,e,r,n,i,a,s){let u=(t+r)/2,h=(e+n)/2,f=Math.atan2(n-e,r-t),d=(r-t)/2,p=(n-e)/2,m=d/i,g=p/a,y=Math.sqrt(m**2+g**2);if(y>1)throw new Error("The given radii are too small to create an arc between the points.");let v=Math.sqrt(1-y**2),x=u+v*a*Math.sin(f)*(s?-1:1),b=h-v*i*Math.cos(f)*(s?-1:1),T=Math.atan2((e-b)/a,(t-x)/i),w=Math.atan2((n-b)/a,(r-x)/i)-T;s&&w<0&&(w+=2*Math.PI),!s&&w>0&&(w-=2*Math.PI);let E=[];for(let _=0;_<20;_++){let C=_/19,D=T+C*w,O=x+i*Math.cos(D),R=b+a*Math.sin(D);E.push({x:O,y:R})}return E}async function KQ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding+20,l=a.height+e.padding,u=l/2,h=u/(2.5+l/50),{cssStyles:f}=e,d=[{x:s/2,y:-l/2},{x:-s/2,y:-l/2},...jQ(-s/2,-l/2,-s/2,l/2,h,u,!1),{x:s/2,y:l/2},...jQ(s/2,l/2,s/2,-l/2,h,u,!0)],p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(d),y=p.path(g,m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(${h/2}, 0)`),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,d,x)},i}var QQ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(jQ,"generateArcPoints");o(KQ,"bowTieRect")});function Ma(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var Iu=N(()=>{"use strict";o(Ma,"insertPolygonShape")});async function ZQ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.height+e.padding,l=12,u=a.width+e.padding+l,h=0,f=u,d=-s,p=0,m=[{x:h+l,y:d},{x:f,y:d},{x:f,y:p},{x:h,y:p},{x:h,y:d+l},{x:h+l,y:d}],g,{cssStyles:y}=e;if(e.look==="handDrawn"){let v=je.svg(i),x=Qe(e,{}),b=Xt(m),T=v.path(b,x);g=i.insert(()=>T,":first-child").attr("transform",`translate(${-u/2}, ${s/2})`),y&&g.attr("style",y)}else g=Ma(i,u,s,m);return n&&g.attr("style",n),Ke(e,g),e.intersect=function(v){return Xe.polygon(e,m,v)},i}var JQ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();Ft();o(ZQ,"card")});function eZ(t,e){let{nodeStyles:r}=Ye(e);e.label="";let n=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:i}=e,a=Math.max(28,e.width??0),s=[{x:0,y:a/2},{x:a/2,y:0},{x:0,y:-a/2},{x:-a/2,y:0}],l=je.svg(n),u=Qe(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=Xt(s),f=l.path(h,u),d=n.insert(()=>f,":first-child");return i&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",i),r&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",r),e.width=28,e.height=28,e.intersect=function(p){return Xe.polygon(e,s,p)},n}var tZ=N(()=>{"use strict";Ht();Wt();zt();Ft();o(eZ,"choice")});async function rZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await mt(t,e,ht(e)),l=a.width/2+s,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=je.svg(i),d=Qe(e,{}),p=f.circle(0,0,l*2,d);u=i.insert(()=>p,":first-child"),u.attr("class","basic label-container").attr("style",zn(h))}else u=i.insert("circle",":first-child").attr("class","basic label-container").attr("style",n).attr("r",l).attr("cx",0).attr("cy",0);return Ke(e,u),e.intersect=function(f){return X.info("Circle intersect",e,l,f),Xe.circle(e,l,f)},i}var nZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(rZ,"circle")});function ODe(t){let e=Math.cos(Math.PI/4),r=Math.sin(Math.PI/4),n=t*2,i={x:n/2*e,y:n/2*r},a={x:-(n/2)*e,y:n/2*r},s={x:-(n/2)*e,y:-(n/2)*r},l={x:n/2*e,y:-(n/2)*r};return`M ${a.x},${a.y} L ${l.x},${l.y} - M ${i.x},${i.y} L ${s.x},${s.y}`}function iZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r,e.label="";let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),a=Math.max(30,e?.width??0),{cssStyles:s}=e,l=je.svg(i),u=Qe(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=l.circle(0,0,a*2,u),f=ODe(a),d=l.path(f,u),p=i.insert(()=>h,":first-child");return p.insert(()=>d),s&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",s),n&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",n),Ke(e,p),e.intersect=function(m){return X.info("crossedCircle intersect",e,{radius:a,point:m}),Xe.circle(e,a,m)},i}var aZ=N(()=>{"use strict";yt();Ft();zt();Wt();Ht();o(ODe,"createLine");o(iZ,"crossedCircle")});function Kh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;dT,":first-child").attr("stroke-opacity",0),S.insert(()=>x,":first-child"),S.attr("class","text"),f&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(${h}, 0)`),s.attr("transform",`translate(${-l/2+h-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,p,w)},i}var oZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Kh,"generateCirclePoints");o(sZ,"curlyBraceLeft")});function Qh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;dT,":first-child").attr("stroke-opacity",0),S.insert(()=>x,":first-child"),S.attr("class","text"),f&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(${-h}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,p,w)},i}var cZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Qh,"generateCirclePoints");o(lZ,"curlyBraceRight")});function Ia(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d_,":first-child").attr("stroke-opacity",0),C.insert(()=>b,":first-child"),C.insert(()=>w,":first-child"),C.attr("class","text"),f&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${h-h/4}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,C),e.intersect=function(D){return Xe.polygon(e,m,D)},i}var hZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(Ia,"generateCirclePoints");o(uZ,"curlyBraces")});async function fZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=80,l=20,u=Math.max(s,(a.width+(e.padding??0)*2)*1.25,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=u,y=h,v=g-f,x=y/4,b=[{x:v,y:0},{x,y:0},{x:0,y:y/2},{x,y},{x:v,y},...WT(-v,-y/2,f,50,270,90)],T=Xt(b),S=p.path(T,m),w=i.insert(()=>S,":first-child");return w.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&w.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&w.selectChildren("path").attr("style",n),w.attr("transform",`translate(${-u/2}, ${-h/2})`),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,b,E)},i}var dZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(fZ,"curvedTrapezoid")});async function pZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+e.padding,e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+e.padding,e.height??0),d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=je.svg(i),g=BDe(0,0,l,f,u,h),y=FDe(0,h,l,f,u,h),v=m.path(g,Qe(e,{})),x=m.path(y,Qe(e,{fill:"none"}));d=i.insert(()=>x,":first-child"),d=i.insert(()=>v,":first-child"),d.attr("class","basic label-container"),p&&d.attr("style",p)}else{let m=PDe(0,0,l,f,u,h);d=i.insert("path",":first-child").attr("d",m).attr("class","basic label-container").attr("style",zn(p)).attr("style",n)}return d.attr("label-offset-y",h),d.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),Ke(e,d),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+(e.padding??0)/1.5-(a.y-(a.top??0))})`),e.intersect=function(m){let g=Xe.rect(e,m),y=g.x-(e.x??0);if(u!=0&&(Math.abs(y)<(e.width??0)/2||Math.abs(y)==(e.width??0)/2&&Math.abs(g.y-(e.y??0))>(e.height??0)/2-h)){let v=h*h*(1-y*y/(u*u));v>0&&(v=Math.sqrt(v)),v=h-v,m.y-(e.y??0)>0&&(v=-v),g.y+=v}return g},i}var PDe,BDe,FDe,mZ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();PDe=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createCylinderPathD"),BDe=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createOuterCylinderPathD"),FDe=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(pZ,"cylinder")});async function gZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=a.width+e.padding,u=a.height+e.padding,h=u*.2,f=-l/2,d=-u/2-h/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d+h},{x:-f,y:d+h},{x:-f,y:-d},{x:f,y:-d},{x:f,y:d},{x:-f,y:d},{x:-f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${f+(e.padding??0)/2-(a.x-(a.left??0))}, ${d+h+(e.padding??0)/2-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},i}var yZ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(gZ,"dividedRectangle")});async function vZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await mt(t,e,ht(e)),u=a.width/2+s+5,h=a.width/2+s,f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{roughness:.2,strokeWidth:2.5}),g=Qe(e,{roughness:.2,strokeWidth:1.5}),y=p.circle(0,0,u*2,m),v=p.circle(0,0,h*2,g);f=i.insert("g",":first-child"),f.attr("class",zn(e.cssClasses)).attr("style",zn(d)),f.node()?.appendChild(y),f.node()?.appendChild(v)}else{f=i.insert("g",":first-child");let p=f.insert("circle",":first-child"),m=f.insert("circle");f.attr("class","basic label-container").attr("style",n),p.attr("class","outer-circle").attr("style",n).attr("r",u).attr("cx",0).attr("cy",0),m.attr("class","inner-circle").attr("style",n).attr("r",h).attr("cx",0).attr("cy",0)}return Ke(e,f),e.intersect=function(p){return X.info("DoubleCircle intersect",e,u,p),Xe.circle(e,u,p)},i}var xZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();er();o(vZ,"doublecircle")});function bZ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.label="",e.labelStyle=n;let a=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),s=7,{cssStyles:l}=e,u=je.svg(a),{nodeBorder:h}=r,f=Qe(e,{fillStyle:"solid"});e.look!=="handDrawn"&&(f.roughness=0);let d=u.circle(0,0,s*2,f),p=a.insert(()=>d,":first-child");return p.selectAll("path").attr("style",`fill: ${h} !important;`),l&&l.length>0&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",l),i&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",i),Ke(e,p),e.intersect=function(m){return X.info("filledCircle intersect",e,{radius:s,point:m}),Xe.circle(e,s,m)},a}var TZ=N(()=>{"use strict";Wt();yt();Ht();zt();Ft();o(bZ,"filledCircle")});async function wZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=a.width+(e.padding??0),u=l+a.height,h=l+a.height,f=[{x:0,y:-u},{x:h,y:-u},{x:h/2,y:0}],{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(f),y=p.path(g,m),v=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`);return d&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),e.width=l,e.height=u,Ke(e,v),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-u/2+(e.padding??0)/2+(a.y-(a.top??0))})`),e.intersect=function(x){return X.info("Triangle intersect",e,f,x),Xe.polygon(e,f,x)},i}var kZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Ft();o(wZ,"flippedTriangle")});function EZ(t,e,{dir:r,config:{state:n,themeVariables:i}}){let{nodeStyles:a}=Ye(e);e.label="";let s=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:l}=e,u=Math.max(70,e?.width??0),h=Math.max(10,e?.height??0);r==="LR"&&(u=Math.max(10,e?.width??0),h=Math.max(70,e?.height??0));let f=-1*u/2,d=-1*h/2,p=je.svg(s),m=Qe(e,{stroke:i.lineColor,fill:i.lineColor});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=p.rectangle(f,d,u,h,m),y=s.insert(()=>g,":first-child");l&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",l),a&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",a),Ke(e,y);let v=n?.padding??0;return e.width&&e.height&&(e.width+=v/2||0,e.height+=v/2||0),e.intersect=function(x){return Xe.rect(e,x)},s}var SZ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(EZ,"forkJoin")});async function CZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i=80,a=50,{shapeSvg:s,bbox:l}=await mt(t,e,ht(e)),u=Math.max(i,l.width+(e.padding??0)*2,e?.width??0),h=Math.max(a,l.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=je.svg(s),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-u/2,y:-h/2},{x:u/2-f,y:-h/2},...WT(-u/2+f,0,f,50,90,270),{x:u/2-f,y:h/2},{x:-u/2,y:h/2}],y=Xt(g),v=p.path(y,m),x=s.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),Ke(e,x),e.intersect=function(b){return X.info("Pill intersect",e,{radius:f,point:b}),Xe.polygon(e,g,b)},s}var AZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();o(CZ,"halfRoundedRectangle")});async function _Z(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=4,l=a.height+e.padding,u=l/s,h=a.width+2*u+e.padding,f=[{x:u,y:0},{x:h-u,y:0},{x:h,y:-l/2},{x:h-u,y:-l},{x:u,y:-l},{x:0,y:-l/2}],d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=je.svg(i),g=Qe(e,{}),y=$De(0,0,h,l,u),v=m.path(y,g);d=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${l/2})`),p&&d.attr("style",p)}else d=Ma(i,h,l,f);return n&&d.attr("style",n),e.width=h,e.height=l,Ke(e,d),e.intersect=function(m){return Xe.polygon(e,f,m)},i}var $De,DZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();$De=o((t,e,r,n,i)=>[`M${t+i},${e}`,`L${t+r-i},${e}`,`L${t+r},${e-n/2}`,`L${t+r-i},${e-n}`,`L${t+i},${e-n}`,`L${t},${e-n/2}`,"Z"].join(" "),"createHexagonPathD");o(_Z,"hexagon")});async function LZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.label="",e.labelStyle=r;let{shapeSvg:i}=await mt(t,e,ht(e)),a=Math.max(30,e?.width??0),s=Math.max(30,e?.height??0),{cssStyles:l}=e,u=je.svg(i),h=Qe(e,{});e.look!=="handDrawn"&&(h.roughness=0,h.fillStyle="solid");let f=[{x:0,y:0},{x:a,y:0},{x:0,y:s},{x:a,y:s}],d=Xt(f),p=u.path(d,h),m=i.insert(()=>p,":first-child");return m.attr("class","basic label-container"),l&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",l),n&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",n),m.attr("transform",`translate(${-a/2}, ${-s/2})`),Ke(e,m),e.intersect=function(g){return X.info("Pill intersect",e,{points:f}),Xe.polygon(e,f,g)},i}var RZ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();o(LZ,"hourglass")});async function NZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await mt(t,e,"icon-shape default"),p=e.pos==="t",m=l,g=l,{nodeBorder:y}=r,{stylesMap:v}=bc(e),x=-g/2,b=-m/2,T=e.label?8:0,S=je.svg(h),w=Qe(e,{stroke:"none",fill:"none"});e.look!=="handDrawn"&&(w.roughness=0,w.fillStyle="solid");let E=S.rectangle(x,b,g,m,w),_=Math.max(g,f.width),C=m+f.height+T,D=S.rectangle(-_/2,-C/2,_,C,{...w,fill:"transparent",stroke:"none"}),O=h.insert(()=>E,":first-child"),R=h.insert(()=>D);if(e.icon){let k=h.append("g");k.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let L=k.node().getBBox(),A=L.width,I=L.height,M=L.x,P=L.y;k.attr("transform",`translate(${-A/2-M},${p?f.height/2+T/2-I/2-P:-f.height/2-T/2-I/2-P})`),k.attr("style",`color: ${v.get("stroke")??y};`)}return d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${p?-C/2:C/2-f.height})`),O.attr("transform",`translate(0,${p?f.height/2+T/2:-f.height/2-T/2})`),Ke(e,R),e.intersect=function(k){if(X.info("iconSquare intersect",e,k),!e.label)return Xe.rect(e,k);let L=e.x??0,A=e.y??0,I=e.height??0,M=[];return p?M=[{x:L-f.width/2,y:A-I/2},{x:L+f.width/2,y:A-I/2},{x:L+f.width/2,y:A-I/2+f.height+T},{x:L+g/2,y:A-I/2+f.height+T},{x:L+g/2,y:A+I/2},{x:L-g/2,y:A+I/2},{x:L-g/2,y:A-I/2+f.height+T},{x:L-f.width/2,y:A-I/2+f.height+T}]:M=[{x:L-g/2,y:A-I/2},{x:L+g/2,y:A-I/2},{x:L+g/2,y:A-I/2+m},{x:L+f.width/2,y:A-I/2+m},{x:L+f.width/2/2,y:A+I/2},{x:L-f.width/2,y:A+I/2},{x:L-f.width/2,y:A-I/2+m},{x:L-g/2,y:A-I/2+m}],Xe.polygon(e,M,k)},h}var MZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Ft();o(NZ,"icon")});async function IZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await mt(t,e,"icon-shape default"),p=20,m=e.label?8:0,g=e.pos==="t",{nodeBorder:y,mainBkg:v}=r,{stylesMap:x}=bc(e),b=je.svg(h),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=x.get("fill");T.stroke=S??v;let w=h.append("g");e.icon&&w.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let E=w.node().getBBox(),_=E.width,C=E.height,D=E.x,O=E.y,R=Math.max(_,C)*Math.SQRT2+p*2,k=b.circle(0,0,R,T),L=Math.max(R,f.width),A=R+f.height+m,I=b.rectangle(-L/2,-A/2,L,A,{...T,fill:"transparent",stroke:"none"}),M=h.insert(()=>k,":first-child"),P=h.insert(()=>I);return w.attr("transform",`translate(${-_/2-D},${g?f.height/2+m/2-C/2-O:-f.height/2-m/2-C/2-O})`),w.attr("style",`color: ${x.get("stroke")??y};`),d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${g?-A/2:A/2-f.height})`),M.attr("transform",`translate(0,${g?f.height/2+m/2:-f.height/2-m/2})`),Ke(e,P),e.intersect=function(B){return X.info("iconSquare intersect",e,B),Xe.rect(e,B)},h}var OZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Ft();o(IZ,"iconCircle")});var Oa,Zh=N(()=>{"use strict";Oa=o((t,e,r,n,i)=>["M",t+i,e,"H",t+r-i,"A",i,i,0,0,1,t+r,e+i,"V",e+n-i,"A",i,i,0,0,1,t+r-i,e+n,"H",t+i,"A",i,i,0,0,1,t,e+n-i,"V",e+i,"A",i,i,0,0,1,t+i,e,"Z"].join(" "),"createRoundedRectPathD")});async function PZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await mt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=bc(e),T=-y/2,S=-g/2,w=e.label?8:0,E=je.svg(h),_=Qe(e,{});e.look!=="handDrawn"&&(_.roughness=0,_.fillStyle="solid");let C=b.get("fill");_.stroke=C??x;let D=E.path(Oa(T,S,y,g,5),_),O=Math.max(y,f.width),R=g+f.height+w,k=E.rectangle(-O/2,-R/2,O,R,{..._,fill:"transparent",stroke:"none"}),L=h.insert(()=>D,":first-child").attr("class","icon-shape2"),A=h.insert(()=>k);if(e.icon){let I=h.append("g");I.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let M=I.node().getBBox(),P=M.width,B=M.height,F=M.x,z=M.y;I.attr("transform",`translate(${-P/2-F},${m?f.height/2+w/2-B/2-z:-f.height/2-w/2-B/2-z})`),I.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-R/2:R/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+w/2:-f.height/2-w/2})`),Ke(e,A),e.intersect=function(I){if(X.info("iconSquare intersect",e,I),!e.label)return Xe.rect(e,I);let M=e.x??0,P=e.y??0,B=e.height??0,F=[];return m?F=[{x:M-f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2+f.height+w},{x:M+y/2,y:P-B/2+f.height+w},{x:M+y/2,y:P+B/2},{x:M-y/2,y:P+B/2},{x:M-y/2,y:P-B/2+f.height+w},{x:M-f.width/2,y:P-B/2+f.height+w}]:F=[{x:M-y/2,y:P-B/2},{x:M+y/2,y:P-B/2},{x:M+y/2,y:P-B/2+g},{x:M+f.width/2,y:P-B/2+g},{x:M+f.width/2/2,y:P+B/2},{x:M-f.width/2,y:P+B/2},{x:M-f.width/2,y:P-B/2+g},{x:M-y/2,y:P-B/2+g}],Xe.polygon(e,F,I)},h}var BZ=N(()=>{"use strict";Wt();yt();jl();Ht();zt();Zh();Ft();o(PZ,"iconRounded")});async function FZ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Ye(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await mt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=bc(e),T=-y/2,S=-g/2,w=e.label?8:0,E=je.svg(h),_=Qe(e,{});e.look!=="handDrawn"&&(_.roughness=0,_.fillStyle="solid");let C=b.get("fill");_.stroke=C??x;let D=E.path(Oa(T,S,y,g,.1),_),O=Math.max(y,f.width),R=g+f.height+w,k=E.rectangle(-O/2,-R/2,O,R,{..._,fill:"transparent",stroke:"none"}),L=h.insert(()=>D,":first-child"),A=h.insert(()=>k);if(e.icon){let I=h.append("g");I.html(`${await Es(e.icon,{height:l,width:l,fallbackPrefix:""})}`);let M=I.node().getBBox(),P=M.width,B=M.height,F=M.x,z=M.y;I.attr("transform",`translate(${-P/2-F},${m?f.height/2+w/2-B/2-z:-f.height/2-w/2-B/2-z})`),I.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-R/2:R/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+w/2:-f.height/2-w/2})`),Ke(e,A),e.intersect=function(I){if(X.info("iconSquare intersect",e,I),!e.label)return Xe.rect(e,I);let M=e.x??0,P=e.y??0,B=e.height??0,F=[];return m?F=[{x:M-f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2},{x:M+f.width/2,y:P-B/2+f.height+w},{x:M+y/2,y:P-B/2+f.height+w},{x:M+y/2,y:P+B/2},{x:M-y/2,y:P+B/2},{x:M-y/2,y:P-B/2+f.height+w},{x:M-f.width/2,y:P-B/2+f.height+w}]:F=[{x:M-y/2,y:P-B/2},{x:M+y/2,y:P-B/2},{x:M+y/2,y:P-B/2+g},{x:M+f.width/2,y:P-B/2+g},{x:M+f.width/2/2,y:P+B/2},{x:M-f.width/2,y:P+B/2},{x:M-f.width/2,y:P-B/2+g},{x:M-y/2,y:P-B/2+g}],Xe.polygon(e,F,I)},h}var $Z=N(()=>{"use strict";Wt();yt();jl();Ht();Zh();zt();Ft();o(FZ,"iconSquare")});async function zZ(t,e,{config:{flowchart:r}}){let n=new Image;n.src=e?.img??"",await n.decode();let i=Number(n.naturalWidth.toString().replace("px","")),a=Number(n.naturalHeight.toString().replace("px",""));e.imageAspectRatio=i/a;let{labelStyles:s}=Ye(e);e.labelStyle=s;let l=r?.wrappingWidth;e.defaultWidth=r?.wrappingWidth;let u=Math.max(e.label?l??0:0,e?.assetWidth??i),h=e.constraint==="on"&&e?.assetHeight?e.assetHeight*e.imageAspectRatio:u,f=e.constraint==="on"?h/e.imageAspectRatio:e?.assetHeight??a;e.width=Math.max(h,l??0);let{shapeSvg:d,bbox:p,label:m}=await mt(t,e,"image-shape default"),g=e.pos==="t",y=-h/2,v=-f/2,x=e.label?8:0,b=je.svg(d),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=b.rectangle(y,v,h,f,T),w=Math.max(h,p.width),E=f+p.height+x,_=b.rectangle(-w/2,-E/2,w,E,{...T,fill:"none",stroke:"none"}),C=d.insert(()=>S,":first-child"),D=d.insert(()=>_);if(e.img){let O=d.append("image");O.attr("href",e.img),O.attr("width",h),O.attr("height",f),O.attr("preserveAspectRatio","none"),O.attr("transform",`translate(${-h/2},${g?E/2-f:-E/2})`)}return m.attr("transform",`translate(${-p.width/2-(p.x-(p.left??0))},${g?-f/2-p.height/2-x/2:f/2-p.height/2+x/2})`),C.attr("transform",`translate(0,${g?p.height/2+x/2:-p.height/2-x/2})`),Ke(e,D),e.intersect=function(O){if(X.info("iconSquare intersect",e,O),!e.label)return Xe.rect(e,O);let R=e.x??0,k=e.y??0,L=e.height??0,A=[];return g?A=[{x:R-p.width/2,y:k-L/2},{x:R+p.width/2,y:k-L/2},{x:R+p.width/2,y:k-L/2+p.height+x},{x:R+h/2,y:k-L/2+p.height+x},{x:R+h/2,y:k+L/2},{x:R-h/2,y:k+L/2},{x:R-h/2,y:k-L/2+p.height+x},{x:R-p.width/2,y:k-L/2+p.height+x}]:A=[{x:R-h/2,y:k-L/2},{x:R+h/2,y:k-L/2},{x:R+h/2,y:k-L/2+f},{x:R+p.width/2,y:k-L/2+f},{x:R+p.width/2/2,y:k+L/2},{x:R-p.width/2,y:k+L/2},{x:R-p.width/2,y:k-L/2+f},{x:R-h/2,y:k-L/2+f}],Xe.polygon(e,A,O)},d}var GZ=N(()=>{"use strict";Wt();yt();Ht();zt();Ft();o(zZ,"imageSquare")});async function VZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=[{x:0,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:-3*l/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var UZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(VZ,"inv_trapezoid")});async function Ou(t,e,r){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n;let{shapeSvg:a,bbox:s}=await mt(t,e,ht(e)),l=Math.max(s.width+r.labelPaddingX*2,e?.width||0),u=Math.max(s.height+r.labelPaddingY*2,e?.height||0),h=-l/2,f=-u/2,d,{rx:p,ry:m}=e,{cssStyles:g}=e;if(r?.rx&&r.ry&&(p=r.rx,m=r.ry),e.look==="handDrawn"){let y=je.svg(a),v=Qe(e,{}),x=p||m?y.path(Oa(h,f,l,u,p||0),v):y.rectangle(h,f,l,u,v);d=a.insert(()=>x,":first-child"),d.attr("class","basic label-container").attr("style",zn(g))}else d=a.insert("rect",":first-child"),d.attr("class","basic label-container").attr("style",i).attr("rx",zn(p)).attr("ry",zn(m)).attr("x",h).attr("y",f).attr("width",l).attr("height",u);return Ke(e,d),e.intersect=function(y){return Xe.rect(e,y)},a}var Em=N(()=>{"use strict";Ft();Ht();Zh();zt();Wt();er();o(Ou,"drawRect")});async function HZ(t,e){let{shapeSvg:r,bbox:n,label:i}=await mt(t,e,"label"),a=r.insert("rect",":first-child");return a.attr("width",.1).attr("height",.1),r.attr("class","label edgeLabel"),i.attr("transform",`translate(${-(n.width/2)-(n.x-(n.left??0))}, ${-(n.height/2)-(n.y-(n.top??0))})`),Ke(e,a),e.intersect=function(u){return Xe.rect(e,u)},r}var WZ=N(()=>{"use strict";Em();Ft();Ht();o(HZ,"labelRect")});async function qZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:0,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:-(3*l)/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var YZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(qZ,"lean_left")});async function XZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:-3*l/6,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var jZ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(XZ,"lean_right")});function KZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.label="",e.labelStyle=r;let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:a}=e,s=Math.max(35,e?.width??0),l=Math.max(35,e?.height??0),u=7,h=[{x:s,y:0},{x:0,y:l+u/2},{x:s-2*u,y:l+u/2},{x:0,y:2*l},{x:s,y:l-u/2},{x:2*u,y:l-u/2}],f=je.svg(i),d=Qe(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=Xt(h),m=f.path(p,d),g=i.insert(()=>m,":first-child");return a&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",a),n&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",n),g.attr("transform",`translate(-${s/2},${-l})`),Ke(e,g),e.intersect=function(y){return X.info("lightningBolt intersect",e,y),Xe.polygon(e,h,y)},i}var QZ=N(()=>{"use strict";yt();Ft();zt();Wt();Ht();Ft();o(KZ,"lightningBolt")});async function ZZ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+(e.padding??0),e.height??0),d=f*.1,p,{cssStyles:m}=e;if(e.look==="handDrawn"){let g=je.svg(i),y=GDe(0,0,l,f,u,h,d),v=VDe(0,h,l,f,u,h),x=Qe(e,{}),b=g.path(y,x),T=g.path(v,x);i.insert(()=>T,":first-child").attr("class","line"),p=i.insert(()=>b,":first-child"),p.attr("class","basic label-container"),m&&p.attr("style",m)}else{let g=zDe(0,0,l,f,u,h,d);p=i.insert("path",":first-child").attr("d",g).attr("class","basic label-container").attr("style",zn(m)).attr("style",n)}return p.attr("label-offset-y",h),p.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),Ke(e,p),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),e.intersect=function(g){let y=Xe.rect(e,g),v=y.x-(e.x??0);if(u!=0&&(Math.abs(v)<(e.width??0)/2||Math.abs(v)==(e.width??0)/2&&Math.abs(y.y-(e.y??0))>(e.height??0)/2-h)){let x=h*h*(1-v*v/(u*u));x>0&&(x=Math.sqrt(x)),x=h-x,g.y-(e.y??0)>0&&(x=-x),y.y+=x}return y},i}var zDe,GDe,VDe,JZ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();zDe=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createCylinderPathD"),GDe=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createOuterCylinderPathD"),VDe=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(ZZ,"linedCylinder")});async function eJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-l/2-l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:f/2},...Go(-l/2-l/2*.1,f/2,l/2+l/2*.1,f/2,h,.8),{x:l/2+l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:-f/2},{x:-l/2,y:-f/2},{x:-l/2,y:f/2*1.1},{x:-l/2,y:-f/2}],y=p.polygon(g.map(x=>[x.x,x.y]),m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)+l/2*.1/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,g,x)},i}var tJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(eJ,"linedWaveEdgedRect")});async function rJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:f-h,y:d+h},{x:f-h,y:d+u+h},{x:f+l-h,y:d+u+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d+u-h},{x:f+l+h,y:d+u-h},{x:f+l+h,y:d-h},{x:f+h,y:d-h},{x:f+h,y:d},{x:f,y:d},{x:f,y:d+h}],v=[{x:f,y:d+h},{x:f+l-h,y:d+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d},{x:f,y:d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),T=Xt(v),S=m.path(T,{...g,fill:"none"}),w=i.insert(()=>S,":first-child");return w.insert(()=>b,":first-child"),w.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)-h-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,y,E)},i}var nJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(rJ,"multiRect")});async function iJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,d=-l/2,p=-f/2,m=5,{cssStyles:g}=e,y=Go(d-m,p+f+m,d+l-m,p+f+m,h,.8),v=y?.[y.length-1],x=[{x:d-m,y:p+m},{x:d-m,y:p+f+m},...y,{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:v.y-2*m},{x:d+l+m,y:v.y-2*m},{x:d+l+m,y:p-m},{x:d+m,y:p-m},{x:d+m,y:p},{x:d,y:p},{x:d,y:p+m}],b=[{x:d,y:p+m},{x:d+l-m,y:p+m},{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:p},{x:d,y:p}],T=je.svg(i),S=Qe(e,{});e.look!=="handDrawn"&&(S.roughness=0,S.fillStyle="solid");let w=Xt(x),E=T.path(w,S),_=Xt(b),C=T.path(_,S),D=i.insert(()=>E,":first-child");return D.insert(()=>C),D.attr("class","basic label-container"),g&&e.look!=="handDrawn"&&D.selectAll("path").attr("style",g),n&&e.look!=="handDrawn"&&D.selectAll("path").attr("style",n),D.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-(a.width/2)-m-(a.x-(a.left??0))}, ${-(a.height/2)+m-h/2-(a.y-(a.top??0))})`),Ke(e,D),e.intersect=function(O){return Xe.polygon(e,x,O)},i}var aJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(iJ,"multiWaveEdgedRectangle")});async function sJ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n,e.useHtmlLabels||tr().flowchart?.htmlLabels!==!1||(e.centerLabel=!0);let{shapeSvg:s,bbox:l,label:u}=await mt(t,e,ht(e)),h=Math.max(l.width+(e.padding??0)*2,e?.width??0),f=Math.max(l.height+(e.padding??0)*2,e?.height??0),d=-h/2,p=-f/2,{cssStyles:m}=e,g=je.svg(s),y=Qe(e,{fill:r.noteBkgColor,stroke:r.noteBorderColor});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=g.rectangle(d,p,h,f,y),x=s.insert(()=>v,":first-child");return x.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",m),i&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",i),u.attr("transform",`translate(${-l.width/2-(l.x-(l.left??0))}, ${-(l.height/2)-(l.y-(l.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},s}var oJ=N(()=>{"use strict";Wt();Ht();zt();Ft();mi();o(sJ,"note")});async function lJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=s+l,h=[{x:u/2,y:0},{x:u,y:-u/2},{x:u/2,y:-u},{x:0,y:-u/2}],f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{}),g=UDe(0,0,u),y=p.path(g,m);f=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`),d&&f.attr("style",d)}else f=Ma(i,u,u,h);return n&&f.attr("style",n),Ke(e,f),e.intersect=function(p){return X.debug(`APA12 Intersect called SPLIT -point:`,p,` -node: -`,e,` -res:`,Xe.polygon(e,h,p)),Xe.polygon(e,h,p)},i}var UDe,cJ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Iu();UDe=o((t,e,r)=>[`M${t+r/2},${e}`,`L${t+r},${e-r/2}`,`L${t+r/2},${e-r}`,`L${t},${e-r/2}`,"Z"].join(" "),"createDecisionBoxPathD");o(lJ,"question")});async function uJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e?.width??0),u=Math.max(a.height+(e.padding??0),e?.height??0),h=-l/2,f=-u/2,d=f/2,p=[{x:h+d,y:f},{x:h,y:0},{x:h+d,y:-f},{x:-h,y:-f},{x:-h,y:f}],{cssStyles:m}=e,g=je.svg(i),y=Qe(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=Xt(p),x=g.path(v,y),b=i.insert(()=>x,":first-child");return b.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),b.attr("transform",`translate(${-d/2},0)`),s.attr("transform",`translate(${-d/2-a.width/2-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),Ke(e,b),e.intersect=function(T){return Xe.polygon(e,p,T)},i}var hJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(uJ,"rect_left_inv_arrow")});function HDe(t,e){e&&t.attr("style",e)}async function WDe(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label;t.label&&yi(t.label)&&(n=await Th(t.label.replace(Ze.lineBreakRegex,` -`),me()));let i=t.isNode?"nodeLabel":"edgeLabel";return r.html('"+n+""),HDe(r,t.labelStyle),r.style("display","inline-block"),r.style("padding-right","1px"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var qDe,Tc,rw=N(()=>{"use strict";fr();yt();Gt();pr();er();o(HDe,"applyStyle");o(WDe,"addHtmlLabel");qDe=o(async(t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),dr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"
    "),X.info("vertexText"+i);let a={isNode:n,label:na(i).replace(/fa[blrs]?:fa-[\w-]+/g,l=>``),labelStyle:e&&e.replace("fill:","color:")};return await WDe(a)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),Tc=qDe});async function fJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i;e.cssClasses?i="node "+e.cssClasses:i="node default";let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=a.insert("g"),l=a.insert("g").attr("class","label").attr("style",n),u=e.description,h=e.label,f=l.node().appendChild(await Tc(h,e.labelStyle,!0,!0)),d={width:0,height:0};if(dr(me()?.flowchart?.htmlLabels)){let C=f.children[0],D=Ge(f);d=C.getBoundingClientRect(),D.attr("width",d.width),D.attr("height",d.height)}X.info("Text 2",u);let p=u||[],m=f.getBBox(),g=l.node().appendChild(await Tc(p.join?p.join("
    "):p,e.labelStyle,!0,!0)),y=g.children[0],v=Ge(g);d=y.getBoundingClientRect(),v.attr("width",d.width),v.attr("height",d.height);let x=(e.padding||0)/2;Ge(g).attr("transform","translate( "+(d.width>m.width?0:(m.width-d.width)/2)+", "+(m.height+x+5)+")"),Ge(f).attr("transform","translate( "+(d.width(X.debug("Rough node insert CXC",O),R),":first-child"),E=a.insert(()=>(X.debug("Rough node insert CXC",O),O),":first-child")}else E=s.insert("rect",":first-child"),_=s.insert("line"),E.attr("class","outer title-state").attr("style",n).attr("x",-d.width/2-x).attr("y",-d.height/2-x).attr("width",d.width+(e.padding||0)).attr("height",d.height+(e.padding||0)),_.attr("class","divider").attr("x1",-d.width/2-x).attr("x2",d.width/2+x).attr("y1",-d.height/2-x+m.height+x).attr("y2",-d.height/2-x+m.height+x);return Ke(e,E),e.intersect=function(C){return Xe.rect(e,C)},a}var dJ=N(()=>{"use strict";fr();pr();Ft();rw();Ht();zt();Wt();Gt();Zh();yt();o(fJ,"rectWithTitle")});async function pJ(t,e){let r={rx:5,ry:5,classes:"",labelPaddingX:(e?.padding||0)*1,labelPaddingY:(e?.padding||0)*1};return Ou(t,e,r)}var mJ=N(()=>{"use strict";Em();o(pJ,"roundedRect")});async function gJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=e?.padding??0,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=-a.width/2-l,d=-a.height/2-l,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d},{x:f+u+8,y:d},{x:f+u+8,y:d+h},{x:f-8,y:d+h},{x:f-8,y:d},{x:f,y:d},{x:f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container").attr("style",zn(p)),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${-u/2+4+(e.padding??0)-(a.x-(a.left??0))},${-h/2+(e.padding??0)-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.rect(e,b)},i}var yJ=N(()=>{"use strict";Ft();Ht();zt();Wt();er();o(gJ,"shadedProcess")});async function vJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=-l/2,f=-u/2,{cssStyles:d}=e,p=je.svg(i),m=Qe(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:h,y:f},{x:h,y:f+u},{x:h+l,y:f+u},{x:h+l,y:f-u/2}],y=Xt(g),v=p.path(y,m),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),x.attr("transform",`translate(0, ${u/4})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))}, ${-u/4+(e.padding??0)-(a.y-(a.top??0))})`),Ke(e,x),e.intersect=function(b){return Xe.polygon(e,g,b)},i}var xJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(vJ,"slopedRect")});async function bJ(t,e){let r={rx:0,ry:0,classes:"",labelPaddingX:(e?.padding||0)*2,labelPaddingY:(e?.padding||0)*1};return Ou(t,e,r)}var TJ=N(()=>{"use strict";Em();o(bJ,"squareRect")});async function wJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.height+e.padding,l=a.width+s/4+e.padding,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=je.svg(i),d=Qe(e,{}),p=Oa(-l/2,-s/2,l,s,s/2),m=f.path(p,d);u=i.insert(()=>m,":first-child"),u.attr("class","basic label-container").attr("style",zn(h))}else u=i.insert("rect",":first-child"),u.attr("class","basic label-container").attr("style",n).attr("rx",s/2).attr("ry",s/2).attr("x",-l/2).attr("y",-s/2).attr("width",l).attr("height",s);return Ke(e,u),e.intersect=function(f){return Xe.rect(e,f)},i}var kJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Zh();er();o(wJ,"stadium")});async function EJ(t,e){return Ou(t,e,{rx:5,ry:5,classes:"flowchart-node"})}var SJ=N(()=>{"use strict";Em();o(EJ,"state")});function CJ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n;let{cssStyles:a}=e,{lineColor:s,stateBorder:l,nodeBorder:u}=r,h=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),f=je.svg(h),d=Qe(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=f.circle(0,0,14,{...d,stroke:s,strokeWidth:2}),m=l??u,g=f.circle(0,0,5,{...d,fill:m,stroke:m,strokeWidth:2,fillStyle:"solid"}),y=h.insert(()=>p,":first-child");return y.insert(()=>g),a&&y.selectAll("path").attr("style",a),i&&y.selectAll("path").attr("style",i),Ke(e,y),e.intersect=function(v){return Xe.circle(e,7,v)},h}var AJ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(CJ,"stateEnd")});function _J(t,e,{config:{themeVariables:r}}){let{lineColor:n}=r,i=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a;if(e.look==="handDrawn"){let l=je.svg(i).circle(0,0,14,NQ(n));a=i.insert(()=>l),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14)}else a=i.insert("circle",":first-child"),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14);return Ke(e,a),e.intersect=function(s){return Xe.circle(e,7,s)},i}var DJ=N(()=>{"use strict";Wt();Ht();zt();Ft();o(_J,"stateStart")});async function LJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=(e?.padding||0)/2,l=a.width+e.padding,u=a.height+e.padding,h=-a.width/2-s,f=-a.height/2-s,d=[{x:0,y:0},{x:l,y:0},{x:l,y:-u},{x:0,y:-u},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-u},{x:-8,y:-u},{x:-8,y:0}];if(e.look==="handDrawn"){let p=je.svg(i),m=Qe(e,{}),g=p.rectangle(h-8,f,l+16,u,m),y=p.line(h,f,h,f+u,m),v=p.line(h+l,f,h+l,f+u,m);i.insert(()=>y,":first-child"),i.insert(()=>v,":first-child");let x=i.insert(()=>g,":first-child"),{cssStyles:b}=e;x.attr("class","basic label-container").attr("style",zn(b)),Ke(e,x)}else{let p=Ma(i,l,u,d);n&&p.attr("style",n),Ke(e,p)}return e.intersect=function(p){return Xe.polygon(e,d,p)},i}var RJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();er();o(LJ,"subroutine")});async function NJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=-s/2,h=-l/2,f=.2*l,d=.2*l,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:u-f/2,y:h},{x:u+s+f/2,y:h},{x:u+s+f/2,y:h+l},{x:u-f/2,y:h+l}],v=[{x:u+s-f/2,y:h+l},{x:u+s+f/2,y:h+l},{x:u+s+f/2,y:h+l-d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),T=Xt(v),S=m.path(T,{...g,fillStyle:"solid"}),w=i.insert(()=>S,":first-child");return w.insert(()=>b,":first-child"),w.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,y,E)},i}var MJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(NJ,"taggedRect")});async function IJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=.2*l,d=.2*u,p=u+h,{cssStyles:m}=e,g=je.svg(i),y=Qe(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=[{x:-l/2-l/2*.1,y:p/2},...Go(-l/2-l/2*.1,p/2,l/2+l/2*.1,p/2,h,.8),{x:l/2+l/2*.1,y:-p/2},{x:-l/2-l/2*.1,y:-p/2}],x=-l/2+l/2*.1,b=-p/2-d*.4,T=[{x:x+l-f,y:(b+u)*1.4},{x:x+l,y:b+u-d},{x:x+l,y:(b+u)*.9},...Go(x+l,(b+u)*1.3,x+l-f,(b+u)*1.5,-u*.03,.5)],S=Xt(v),w=g.path(S,y),E=Xt(T),_=g.path(E,{...y,fillStyle:"solid"}),C=i.insert(()=>_,":first-child");return C.insert(()=>w,":first-child"),C.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),Ke(e,C),e.intersect=function(D){return Xe.polygon(e,v,D)},i}var OJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(IJ,"taggedWaveEdgedRectangle")});async function PJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=Math.max(a.width+e.padding,e?.width||0),l=Math.max(a.height+e.padding,e?.height||0),u=-s/2,h=-l/2,f=i.insert("rect",":first-child");return f.attr("class","text").attr("style",n).attr("rx",0).attr("ry",0).attr("x",u).attr("y",h).attr("width",s).attr("height",l),Ke(e,f),e.intersect=function(d){return Xe.rect(e,d)},i}var BJ=N(()=>{"use strict";Ft();Ht();zt();o(PJ,"text")});async function FJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s,halfPadding:l}=await mt(t,e,ht(e)),u=e.look==="neo"?l*2:l,h=a.height+u,f=h/2,d=f/(2.5+h/50),p=a.width+d+u,{cssStyles:m}=e,g;if(e.look==="handDrawn"){let y=je.svg(i),v=XDe(0,0,p,h,d,f),x=jDe(0,0,p,h,d,f),b=y.path(v,Qe(e,{})),T=y.path(x,Qe(e,{fill:"none"}));g=i.insert(()=>T,":first-child"),g=i.insert(()=>b,":first-child"),g.attr("class","basic label-container"),m&&g.attr("style",m)}else{let y=YDe(0,0,p,h,d,f);g=i.insert("path",":first-child").attr("d",y).attr("class","basic label-container").attr("style",zn(m)).attr("style",n),g.attr("class","basic label-container"),m&&g.selectAll("path").attr("style",m),n&&g.selectAll("path").attr("style",n)}return g.attr("label-offset-x",d),g.attr("transform",`translate(${-p/2}, ${h/2} )`),s.attr("transform",`translate(${-(a.width/2)-d-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),Ke(e,g),e.intersect=function(y){let v=Xe.rect(e,y),x=v.y-(e.y??0);if(f!=0&&(Math.abs(x)<(e.height??0)/2||Math.abs(x)==(e.height??0)/2&&Math.abs(v.x-(e.x??0))>(e.width??0)/2-d)){let b=d*d*(1-x*x/(f*f));b!=0&&(b=Math.sqrt(Math.abs(b))),b=d-b,y.x-(e.x??0)>0&&(b=-b),v.x+=b}return v},i}var YDe,XDe,jDe,$J=N(()=>{"use strict";Ft();zt();Wt();Ht();er();YDe=o((t,e,r,n,i,a)=>`M${t},${e} - a${i},${a} 0,0,1 0,${-n} - l${r},0 - a${i},${a} 0,0,1 0,${n} - M${r},${-n} - a${i},${a} 0,0,0 0,${n} - l${-r},0`,"createCylinderPathD"),XDe=o((t,e,r,n,i,a)=>[`M${t},${e}`,`M${t+r},${e}`,`a${i},${a} 0,0,0 0,${-n}`,`l${-r},0`,`a${i},${a} 0,0,0 0,${n}`,`l${r},0`].join(" "),"createOuterCylinderPathD"),jDe=o((t,e,r,n,i,a)=>[`M${t+r/2},${-n/2}`,`a${i},${a} 0,0,0 0,${n}`].join(" "),"createInnerCylinderPathD");o(FJ,"tiltedCylinder")});async function zJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=[{x:-3*l/6,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=je.svg(i),p=Qe(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=Ma(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,Ke(e,h),e.intersect=function(d){return Xe.polygon(e,u,d)},i}var GJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Iu();o(zJ,"trapezoid")});async function VJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=60,l=20,u=Math.max(s,a.width+(e.padding??0)*2,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),{cssStyles:f}=e,d=je.svg(i),p=Qe(e,{});e.look!=="handDrawn"&&(p.roughness=0,p.fillStyle="solid");let m=[{x:-u/2*.8,y:-h/2},{x:u/2*.8,y:-h/2},{x:u/2,y:-h/2*.6},{x:u/2,y:h/2},{x:-u/2,y:h/2},{x:-u/2,y:-h/2*.6}],g=Xt(m),y=d.path(g,p),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),Ke(e,v),e.intersect=function(x){return Xe.polygon(e,m,x)},i}var UJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(VJ,"trapezoidalPentagon")});async function HJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=dr(me().flowchart?.htmlLabels),u=a.width+(e.padding??0),h=u+a.height,f=u+a.height,d=[{x:0,y:0},{x:f,y:0},{x:f/2,y:-h}],{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=Xt(d),v=m.path(y,g),x=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${h/2})`);return p&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),e.width=u,e.height=h,Ke(e,x),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${h/2-(a.height+(e.padding??0)/(l?2:1)-(a.y-(a.top??0)))})`),e.intersect=function(b){return X.info("Triangle intersect",e,d,b),Xe.polygon(e,d,b)},i}var WJ=N(()=>{"use strict";yt();Ft();Ht();zt();Wt();Ft();pr();Gt();o(HJ,"triangle")});async function qJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/8,f=u+h,{cssStyles:d}=e,m=70-l,g=m>0?m/2:0,y=je.svg(i),v=Qe(e,{});e.look!=="handDrawn"&&(v.roughness=0,v.fillStyle="solid");let x=[{x:-l/2-g,y:f/2},...Go(-l/2-g,f/2,l/2+g,f/2,h,.8),{x:l/2+g,y:-f/2},{x:-l/2-g,y:-f/2}],b=Xt(x),T=y.path(b,v),S=i.insert(()=>T,":first-child");return S.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h-(a.y-(a.top??0))})`),Ke(e,S),e.intersect=function(w){return Xe.polygon(e,x,w)},i}var YJ=N(()=>{"use strict";Ft();Ht();Wt();zt();o(qJ,"waveEdgedRectangle")});async function XJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await mt(t,e,ht(e)),s=100,l=50,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=u/h,d=u,p=h;d>p*f?p=d/f:d=p*f,d=Math.max(d,s),p=Math.max(p,l);let m=Math.min(p*.2,p/4),g=p+m*2,{cssStyles:y}=e,v=je.svg(i),x=Qe(e,{});e.look!=="handDrawn"&&(x.roughness=0,x.fillStyle="solid");let b=[{x:-d/2,y:g/2},...Go(-d/2,g/2,d/2,g/2,m,1),{x:d/2,y:-g/2},...Go(d/2,-g/2,-d/2,-g/2,m,-1)],T=Xt(b),S=v.path(T,x),w=i.insert(()=>S,":first-child");return w.attr("class","basic label-container"),y&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",y),n&&e.look!=="handDrawn"&&w.selectAll("path").attr("style",n),Ke(e,w),e.intersect=function(E){return Xe.polygon(e,b,E)},i}var jJ=N(()=>{"use strict";Ft();Ht();zt();Wt();o(XJ,"waveRectangle")});async function KJ(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await mt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=je.svg(i),g=Qe(e,{}),y=[{x:f-h,y:d-h},{x:f-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d-h}],v=`M${f-h},${d-h} L${f+l},${d-h} L${f+l},${d+u} L${f-h},${d+u} L${f-h},${d-h} - M${f-h},${d} L${f+l},${d} - M${f},${d-h} L${f},${d+u}`;e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=m.path(v,g),b=i.insert(()=>x,":first-child");return b.attr("transform",`translate(${h/2}, ${h/2})`),b.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)+h/2-(a.x-(a.left??0))}, ${-(a.height/2)+h/2-(a.y-(a.top??0))})`),Ke(e,b),e.intersect=function(T){return Xe.polygon(e,y,T)},i}var QJ=N(()=>{"use strict";Ft();zt();Wt();Ht();o(KJ,"windowPane")});async function ML(t,e){let r=e;if(r.alias&&(e.label=r.alias),e.look==="handDrawn"){let{themeVariables:U}=tr(),{background:K}=U,ee={...e,id:e.id+"-background",look:"default",cssStyles:["stroke: none",`fill: ${K}`]};await ML(t,ee)}let n=tr();e.useHtmlLabels=n.htmlLabels;let i=n.er?.diagramPadding??10,a=n.er?.entityPadding??6,{cssStyles:s}=e,{labelStyles:l,nodeStyles:u}=Ye(e);if(r.attributes.length===0&&e.label){let U={rx:0,ry:0,labelPaddingX:i,labelPaddingY:i*1.5,classes:""};ra(e.label,n)+U.labelPaddingX*20){let U=d.width+i*2-(y+v+x+b);y+=U/w,v+=U/w,x>0&&(x+=U/w),b>0&&(b+=U/w)}let _=y+v+x+b,C=je.svg(f),D=Qe(e,{});e.look!=="handDrawn"&&(D.roughness=0,D.fillStyle="solid");let O=0;g.length>0&&(O=g.reduce((U,K)=>U+(K?.rowHeight??0),0));let R=Math.max(E.width+i*2,e?.width||0,_),k=Math.max((O??0)+d.height,e?.height||0),L=-R/2,A=-k/2;f.selectAll("g:not(:first-child)").each((U,K,ee)=>{let Y=Ge(ee[K]),ce=Y.attr("transform"),Z=0,ue=0;if(ce){let j=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(ce);j&&(Z=parseFloat(j[1]),ue=parseFloat(j[2]),Y.attr("class").includes("attribute-name")?Z+=y:Y.attr("class").includes("attribute-keys")?Z+=y+v:Y.attr("class").includes("attribute-comment")&&(Z+=y+v+x))}Y.attr("transform",`translate(${L+i/2+Z}, ${ue+A+d.height+a/2})`)}),f.select(".name").attr("transform","translate("+-d.width/2+", "+(A+a/2)+")");let I=C.rectangle(L,A,R,k,D),M=f.insert(()=>I,":first-child").attr("style",s.join("")),{themeVariables:P}=tr(),{rowEven:B,rowOdd:F,nodeBorder:z}=P;m.push(0);for(let[U,K]of g.entries()){let Y=(U+1)%2===0&&K.yOffset!==0,ce=C.rectangle(L,d.height+A+K?.yOffset,R,K?.rowHeight,{...D,fill:Y?B:F,stroke:z});f.insert(()=>ce,"g.label").attr("style",s.join("")).attr("class",`row-rect-${Y?"even":"odd"}`)}let $=C.line(L,d.height+A,R+L,d.height+A,D);f.insert(()=>$).attr("class","divider"),$=C.line(y+L,d.height+A,y+L,k+A,D),f.insert(()=>$).attr("class","divider"),T&&($=C.line(y+v+L,d.height+A,y+v+L,k+A,D),f.insert(()=>$).attr("class","divider")),S&&($=C.line(y+v+x+L,d.height+A,y+v+x+L,k+A,D),f.insert(()=>$).attr("class","divider"));for(let U of m)$=C.line(L,d.height+A+U,R+L,d.height+A+U,D),f.insert(()=>$).attr("class","divider");if(Ke(e,M),u&&e.look!=="handDrawn"){let K=u.split(";")?.filter(ee=>ee.includes("stroke"))?.map(ee=>`${ee}`).join("; ");f.selectAll("path").attr("style",K??""),f.selectAll(".row-rect-even path").attr("style",u)}return e.intersect=function(U){return Xe.rect(e,U)},f}async function L2(t,e,r,n=0,i=0,a=[],s=""){let l=t.insert("g").attr("class",`label ${a.join(" ")}`).attr("transform",`translate(${n}, ${i})`).attr("style",s);e!==ic(e)&&(e=ic(e),e=e.replaceAll("<","<").replaceAll(">",">"));let u=l.node().appendChild(await qn(l,e,{width:ra(e,r)+100,style:s,useHtmlLabels:r.htmlLabels},r));if(e.includes("<")||e.includes(">")){let f=u.children[0];for(f.textContent=f.textContent.replaceAll("<","<").replaceAll(">",">");f.childNodes[0];)f=f.childNodes[0],f.textContent=f.textContent.replaceAll("<","<").replaceAll(">",">")}let h=u.getBBox();if(dr(r.htmlLabels)){let f=u.children[0];f.style.textAlign="start";let d=Ge(u);h=f.getBoundingClientRect(),d.attr("width",h.width),d.attr("height",h.height)}return h}var ZJ=N(()=>{"use strict";Ft();Ht();zt();Wt();Em();mi();ao();pr();fr();er();o(ML,"erBox");o(L2,"addText")});async function JJ(t,e,r,n,i=r.class.padding??12){let a=n?0:3,s=t.insert("g").attr("class",ht(e)).attr("id",e.domId||e.id),l=null,u=null,h=null,f=null,d=0,p=0,m=0;if(l=s.insert("g").attr("class","annotation-group text"),e.annotations.length>0){let b=e.annotations[0];await nw(l,{text:`\xAB${b}\xBB`},0),d=l.node().getBBox().height}u=s.insert("g").attr("class","label-group text"),await nw(u,e,0,["font-weight: bolder"]);let g=u.node().getBBox();p=g.height,h=s.insert("g").attr("class","members-group text");let y=0;for(let b of e.members){let T=await nw(h,b,y,[b.parseClassifier()]);y+=T+a}m=h.node().getBBox().height,m<=0&&(m=i/2),f=s.insert("g").attr("class","methods-group text");let v=0;for(let b of e.methods){let T=await nw(f,b,v,[b.parseClassifier()]);v+=T+a}let x=s.node().getBBox();if(l!==null){let b=l.node().getBBox();l.attr("transform",`translate(${-b.width/2})`)}return u.attr("transform",`translate(${-g.width/2}, ${d})`),x=s.node().getBBox(),h.attr("transform",`translate(0, ${d+p+i*2})`),x=s.node().getBBox(),f.attr("transform",`translate(0, ${d+p+(m?m+i*4:i*2)})`),x=s.node().getBBox(),{shapeSvg:s,bbox:x}}async function nw(t,e,r,n=[]){let i=t.insert("g").attr("class","label").attr("style",n.join("; ")),a=tr(),s="useHtmlLabels"in e?e.useHtmlLabels:dr(a.htmlLabels)??!0,l="";"text"in e?l=e.text:l=e.label,!s&&l.startsWith("\\")&&(l=l.substring(1)),yi(l)&&(s=!0);let u=await qn(i,fd(na(l)),{width:ra(l,a)+50,classes:"markdown-node-label",useHtmlLabels:s},a),h,f=1;if(s){let d=u.children[0],p=Ge(u);f=d.innerHTML.split("
    ").length,d.innerHTML.includes("")&&(f+=d.innerHTML.split("").length-1);let m=d.getElementsByTagName("img");if(m){let g=l.replace(/]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=a.fontSize?.toString()??window.getComputedStyle(document.body).fontSize,S=parseInt(b,10)*5+"px";y.style.minWidth=S,y.style.maxWidth=S}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}else{n.includes("font-weight: bolder")&&Ge(u).selectAll("tspan").attr("font-weight",""),f=u.children.length;let d=u.children[0];(u.textContent===""||u.textContent.includes(">"))&&(d.textContent=l[0]+l.substring(1).replaceAll(">",">").replaceAll("<","<").trim(),l[1]===" "&&(d.textContent=d.textContent[0]+" "+d.textContent.substring(1))),d.textContent==="undefined"&&(d.textContent=""),h=u.getBBox()}return i.attr("transform","translate(0,"+(-h.height/(2*f)+r)+")"),h.height}var eee=N(()=>{"use strict";fr();mi();Ft();er();Gt();ao();pr();o(JJ,"textHelper");o(nw,"addText")});async function tee(t,e){let r=me(),n=r.class.padding??12,i=n,a=e.useHtmlLabels??dr(r.htmlLabels)??!0,s=e;s.annotations=s.annotations??[],s.members=s.members??[],s.methods=s.methods??[];let{shapeSvg:l,bbox:u}=await JJ(t,e,r,a,i),{labelStyles:h,nodeStyles:f}=Ye(e);e.labelStyle=h,e.cssStyles=s.styles||"";let d=s.styles?.join(";")||f||"";e.cssStyles||(e.cssStyles=d.replaceAll("!important","").split(";"));let p=s.members.length===0&&s.methods.length===0&&!r.class?.hideEmptyMembersBox,m=je.svg(l),g=Qe(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=u.width,v=u.height;s.members.length===0&&s.methods.length===0?v+=i:s.members.length>0&&s.methods.length===0&&(v+=i*2);let x=-y/2,b=-v/2,T=m.rectangle(x-n,b-n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0),y+2*n,v+2*n+(p?n*2:s.members.length===0&&s.methods.length===0?-n:0),g),S=l.insert(()=>T,":first-child");S.attr("class","basic label-container");let w=S.node().getBBox();l.selectAll(".text").each((D,O,R)=>{let k=Ge(R[O]),L=k.attr("transform"),A=0;if(L){let B=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(L);B&&(A=parseFloat(B[2]))}let I=A+b+n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0);a||(I-=4);let M=x;(k.attr("class").includes("label-group")||k.attr("class").includes("annotation-group"))&&(M=-k.node()?.getBBox().width/2||0,l.selectAll("text").each(function(P,B,F){window.getComputedStyle(F[B]).textAnchor==="middle"&&(M=0)})),k.attr("transform",`translate(${M}, ${I})`)});let E=l.select(".annotation-group").node().getBBox().height-(p?n/2:0)||0,_=l.select(".label-group").node().getBBox().height-(p?n/2:0)||0,C=l.select(".members-group").node().getBBox().height-(p?n/2:0)||0;if(s.members.length>0||s.methods.length>0||p){let D=m.line(w.x,E+_+b+n,w.x+w.width,E+_+b+n,g);l.insert(()=>D).attr("class","divider").attr("style",d)}if(p||s.members.length>0||s.methods.length>0){let D=m.line(w.x,E+_+C+b+i*2+n,w.x+w.width,E+_+C+b+n+i*2,g);l.insert(()=>D).attr("class","divider").attr("style",d)}if(s.look!=="handDrawn"&&l.selectAll("path").attr("style",d),S.select(":nth-child(2)").attr("style",d),l.selectAll(".divider").select("path").attr("style",d),e.labelStyle?l.selectAll("span").attr("style",e.labelStyle):l.selectAll("span").attr("style",d),!a){let D=RegExp(/color\s*:\s*([^;]*)/),O=D.exec(d);if(O){let R=O[0].replace("color","fill");l.selectAll("tspan").attr("style",R)}else if(h){let R=D.exec(h);if(R){let k=R[0].replace("color","fill");l.selectAll("tspan").attr("style",k)}}}return Ke(e,S),e.intersect=function(D){return Xe.rect(e,D)},l}var ree=N(()=>{"use strict";Ft();Gt();fr();Wt();zt();Ht();eee();pr();o(tee,"classBox")});async function nee(t,e){let{labelStyles:r,nodeStyles:n}=Ye(e);e.labelStyle=r;let i=e,a=e,s=20,l=20,u="verifyMethod"in e,h=ht(e),f=t.insert("g").attr("class",h).attr("id",e.domId??e.id),d;u?d=await Pu(f,`<<${i.type}>>`,0,e.labelStyle):d=await Pu(f,"<<Element>>",0,e.labelStyle);let p=d,m=await Pu(f,i.name,p,e.labelStyle+"; font-weight: bold;");if(p+=m+l,u){let E=await Pu(f,`${i.requirementId?`id: ${i.requirementId}`:""}`,p,e.labelStyle);p+=E;let _=await Pu(f,`${i.text?`Text: ${i.text}`:""}`,p,e.labelStyle);p+=_;let C=await Pu(f,`${i.risk?`Risk: ${i.risk}`:""}`,p,e.labelStyle);p+=C,await Pu(f,`${i.verifyMethod?`Verification: ${i.verifyMethod}`:""}`,p,e.labelStyle)}else{let E=await Pu(f,`${a.type?`Type: ${a.type}`:""}`,p,e.labelStyle);p+=E,await Pu(f,`${a.docRef?`Doc Ref: ${a.docRef}`:""}`,p,e.labelStyle)}let g=(f.node()?.getBBox().width??200)+s,y=(f.node()?.getBBox().height??200)+s,v=-g/2,x=-y/2,b=je.svg(f),T=Qe(e,{});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let S=b.rectangle(v,x,g,y,T),w=f.insert(()=>S,":first-child");if(w.attr("class","basic label-container").attr("style",n),f.selectAll(".label").each((E,_,C)=>{let D=Ge(C[_]),O=D.attr("transform"),R=0,k=0;if(O){let M=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(O);M&&(R=parseFloat(M[1]),k=parseFloat(M[2]))}let L=k-y/2,A=v+s/2;(_===0||_===1)&&(A=R),D.attr("transform",`translate(${A}, ${L+s})`)}),p>d+m+l){let E=b.line(v,x+d+m+l,v+g,x+d+m+l,T);f.insert(()=>E).attr("style",n)}return Ke(e,w),e.intersect=function(E){return Xe.rect(e,E)},f}async function Pu(t,e,r,n=""){if(e==="")return 0;let i=t.insert("g").attr("class","label").attr("style",n),a=me(),s=a.htmlLabels??!0,l=await qn(i,fd(na(e)),{width:ra(e,a)+50,classes:"markdown-node-label",useHtmlLabels:s,style:n},a),u;if(s){let h=l.children[0],f=Ge(l);u=h.getBoundingClientRect(),f.attr("width",u.width),f.attr("height",u.height)}else{let h=l.children[0];for(let f of h.children)f.textContent=f.textContent.replaceAll(">",">").replaceAll("<","<"),n&&f.setAttribute("style",n);u=l.getBBox(),u.height+=6}return i.attr("transform",`translate(${-u.width/2},${-u.height/2+r})`),u.height}var iee=N(()=>{"use strict";Ft();Ht();zt();Wt();er();Gt();ao();fr();o(nee,"requirementBox");o(Pu,"addText")});async function aee(t,e,{config:r}){let{labelStyles:n,nodeStyles:i}=Ye(e);e.labelStyle=n||"";let a=10,s=e.width;e.width=(e.width??200)-10;let{shapeSvg:l,bbox:u,label:h}=await mt(t,e,ht(e)),f=e.padding||10,d="",p;"ticket"in e&&e.ticket&&r?.kanban?.ticketBaseUrl&&(d=r?.kanban?.ticketBaseUrl.replace("#TICKET#",e.ticket),p=l.insert("svg:a",":first-child").attr("class","kanban-ticket-link").attr("xlink:href",d).attr("target","_blank"));let m={useHtmlLabels:e.useHtmlLabels,labelStyle:e.labelStyle||"",width:e.width,img:e.img,padding:e.padding||8,centerLabel:!1},g,y;p?{label:g,bbox:y}=await HT(p,"ticket"in e&&e.ticket||"",m):{label:g,bbox:y}=await HT(l,"ticket"in e&&e.ticket||"",m);let{label:v,bbox:x}=await HT(l,"assigned"in e&&e.assigned||"",m);e.width=s;let b=10,T=e?.width||0,S=Math.max(y.height,x.height)/2,w=Math.max(u.height+b*2,e?.height||0)+S,E=-T/2,_=-w/2;h.attr("transform","translate("+(f-T/2)+", "+(-S-u.height/2)+")"),g.attr("transform","translate("+(f-T/2)+", "+(-S+u.height/2)+")"),v.attr("transform","translate("+(f+T/2-x.width-2*a)+", "+(-S+u.height/2)+")");let C,{rx:D,ry:O}=e,{cssStyles:R}=e;if(e.look==="handDrawn"){let k=je.svg(l),L=Qe(e,{}),A=D||O?k.path(Oa(E,_,T,w,D||0),L):k.rectangle(E,_,T,w,L);C=l.insert(()=>A,":first-child"),C.attr("class","basic label-container").attr("style",R||null)}else{C=l.insert("rect",":first-child"),C.attr("class","basic label-container __APA__").attr("style",i).attr("rx",D??5).attr("ry",O??5).attr("x",E).attr("y",_).attr("width",T).attr("height",w);let k="priority"in e&&e.priority;if(k){let L=l.append("line"),A=E+2,I=_+Math.floor((D??0)/2),M=_+w-Math.floor((D??0)/2);L.attr("x1",A).attr("y1",I).attr("x2",A).attr("y2",M).attr("stroke-width","4").attr("stroke",KDe(k))}}return Ke(e,C),e.height=w,e.intersect=function(k){return Xe.rect(e,k)},l}var KDe,see=N(()=>{"use strict";Ft();Ht();Zh();zt();Wt();KDe=o(t=>{switch(t){case"Very High":return"red";case"High":return"orange";case"Medium":return null;case"Low":return"blue";case"Very Low":return"lightblue"}},"colorFromPriority");o(aee,"kanbanItem")});function oee(t){return t in IL}var QDe,ZDe,IL,OL=N(()=>{"use strict";XQ();QQ();JQ();tZ();nZ();aZ();oZ();cZ();hZ();dZ();mZ();yZ();xZ();TZ();kZ();SZ();AZ();DZ();RZ();MZ();OZ();BZ();$Z();GZ();UZ();WZ();YZ();jZ();QZ();JZ();tJ();nJ();aJ();oJ();cJ();hJ();dJ();mJ();yJ();xJ();TJ();kJ();SJ();AJ();DJ();RJ();MJ();OJ();BJ();$J();GJ();UJ();WJ();YJ();jJ();QJ();ZJ();ree();iee();see();QDe=[{semanticName:"Process",name:"Rectangle",shortName:"rect",description:"Standard process shape",aliases:["proc","process","rectangle"],internalAliases:["squareRect"],handler:bJ},{semanticName:"Event",name:"Rounded Rectangle",shortName:"rounded",description:"Represents an event",aliases:["event"],internalAliases:["roundedRect"],handler:pJ},{semanticName:"Terminal Point",name:"Stadium",shortName:"stadium",description:"Terminal point",aliases:["terminal","pill"],handler:wJ},{semanticName:"Subprocess",name:"Framed Rectangle",shortName:"fr-rect",description:"Subprocess",aliases:["subprocess","subproc","framed-rectangle","subroutine"],handler:LJ},{semanticName:"Database",name:"Cylinder",shortName:"cyl",description:"Database storage",aliases:["db","database","cylinder"],handler:pZ},{semanticName:"Start",name:"Circle",shortName:"circle",description:"Starting point",aliases:["circ"],handler:rZ},{semanticName:"Decision",name:"Diamond",shortName:"diam",description:"Decision-making step",aliases:["decision","diamond","question"],handler:lJ},{semanticName:"Prepare Conditional",name:"Hexagon",shortName:"hex",description:"Preparation or condition step",aliases:["hexagon","prepare"],handler:_Z},{semanticName:"Data Input/Output",name:"Lean Right",shortName:"lean-r",description:"Represents input or output",aliases:["lean-right","in-out"],internalAliases:["lean_right"],handler:XZ},{semanticName:"Data Input/Output",name:"Lean Left",shortName:"lean-l",description:"Represents output or input",aliases:["lean-left","out-in"],internalAliases:["lean_left"],handler:qZ},{semanticName:"Priority Action",name:"Trapezoid Base Bottom",shortName:"trap-b",description:"Priority action",aliases:["priority","trapezoid-bottom","trapezoid"],handler:zJ},{semanticName:"Manual Operation",name:"Trapezoid Base Top",shortName:"trap-t",description:"Represents a manual task",aliases:["manual","trapezoid-top","inv-trapezoid"],internalAliases:["inv_trapezoid"],handler:VZ},{semanticName:"Stop",name:"Double Circle",shortName:"dbl-circ",description:"Represents a stop point",aliases:["double-circle"],internalAliases:["doublecircle"],handler:vZ},{semanticName:"Text Block",name:"Text Block",shortName:"text",description:"Text block",handler:PJ},{semanticName:"Card",name:"Notched Rectangle",shortName:"notch-rect",description:"Represents a card",aliases:["card","notched-rectangle"],handler:ZQ},{semanticName:"Lined/Shaded Process",name:"Lined Rectangle",shortName:"lin-rect",description:"Lined process shape",aliases:["lined-rectangle","lined-process","lin-proc","shaded-process"],handler:gJ},{semanticName:"Start",name:"Small Circle",shortName:"sm-circ",description:"Small starting point",aliases:["start","small-circle"],internalAliases:["stateStart"],handler:_J},{semanticName:"Stop",name:"Framed Circle",shortName:"fr-circ",description:"Stop point",aliases:["stop","framed-circle"],internalAliases:["stateEnd"],handler:CJ},{semanticName:"Fork/Join",name:"Filled Rectangle",shortName:"fork",description:"Fork or join in process flow",aliases:["join"],internalAliases:["forkJoin"],handler:EZ},{semanticName:"Collate",name:"Hourglass",shortName:"hourglass",description:"Represents a collate operation",aliases:["hourglass","collate"],handler:LZ},{semanticName:"Comment",name:"Curly Brace",shortName:"brace",description:"Adds a comment",aliases:["comment","brace-l"],handler:sZ},{semanticName:"Comment Right",name:"Curly Brace",shortName:"brace-r",description:"Adds a comment",handler:lZ},{semanticName:"Comment with braces on both sides",name:"Curly Braces",shortName:"braces",description:"Adds a comment",handler:uZ},{semanticName:"Com Link",name:"Lightning Bolt",shortName:"bolt",description:"Communication link",aliases:["com-link","lightning-bolt"],handler:KZ},{semanticName:"Document",name:"Document",shortName:"doc",description:"Represents a document",aliases:["doc","document"],handler:qJ},{semanticName:"Delay",name:"Half-Rounded Rectangle",shortName:"delay",description:"Represents a delay",aliases:["half-rounded-rectangle"],handler:CZ},{semanticName:"Direct Access Storage",name:"Horizontal Cylinder",shortName:"h-cyl",description:"Direct access storage",aliases:["das","horizontal-cylinder"],handler:FJ},{semanticName:"Disk Storage",name:"Lined Cylinder",shortName:"lin-cyl",description:"Disk storage",aliases:["disk","lined-cylinder"],handler:ZZ},{semanticName:"Display",name:"Curved Trapezoid",shortName:"curv-trap",description:"Represents a display",aliases:["curved-trapezoid","display"],handler:fZ},{semanticName:"Divided Process",name:"Divided Rectangle",shortName:"div-rect",description:"Divided process shape",aliases:["div-proc","divided-rectangle","divided-process"],handler:gZ},{semanticName:"Extract",name:"Triangle",shortName:"tri",description:"Extraction process",aliases:["extract","triangle"],handler:HJ},{semanticName:"Internal Storage",name:"Window Pane",shortName:"win-pane",description:"Internal storage",aliases:["internal-storage","window-pane"],handler:KJ},{semanticName:"Junction",name:"Filled Circle",shortName:"f-circ",description:"Junction point",aliases:["junction","filled-circle"],handler:bZ},{semanticName:"Loop Limit",name:"Trapezoidal Pentagon",shortName:"notch-pent",description:"Loop limit step",aliases:["loop-limit","notched-pentagon"],handler:VJ},{semanticName:"Manual File",name:"Flipped Triangle",shortName:"flip-tri",description:"Manual file operation",aliases:["manual-file","flipped-triangle"],handler:wZ},{semanticName:"Manual Input",name:"Sloped Rectangle",shortName:"sl-rect",description:"Manual input step",aliases:["manual-input","sloped-rectangle"],handler:vJ},{semanticName:"Multi-Document",name:"Stacked Document",shortName:"docs",description:"Multiple documents",aliases:["documents","st-doc","stacked-document"],handler:iJ},{semanticName:"Multi-Process",name:"Stacked Rectangle",shortName:"st-rect",description:"Multiple processes",aliases:["procs","processes","stacked-rectangle"],handler:rJ},{semanticName:"Stored Data",name:"Bow Tie Rectangle",shortName:"bow-rect",description:"Stored data",aliases:["stored-data","bow-tie-rectangle"],handler:KQ},{semanticName:"Summary",name:"Crossed Circle",shortName:"cross-circ",description:"Summary",aliases:["summary","crossed-circle"],handler:iZ},{semanticName:"Tagged Document",name:"Tagged Document",shortName:"tag-doc",description:"Tagged document",aliases:["tag-doc","tagged-document"],handler:IJ},{semanticName:"Tagged Process",name:"Tagged Rectangle",shortName:"tag-rect",description:"Tagged process",aliases:["tagged-rectangle","tag-proc","tagged-process"],handler:NJ},{semanticName:"Paper Tape",name:"Flag",shortName:"flag",description:"Paper tape",aliases:["paper-tape"],handler:XJ},{semanticName:"Odd",name:"Odd",shortName:"odd",description:"Odd shape",internalAliases:["rect_left_inv_arrow"],handler:uJ},{semanticName:"Lined Document",name:"Lined Document",shortName:"lin-doc",description:"Lined document",aliases:["lined-document"],handler:eJ}],ZDe=o(()=>{let e=[...Object.entries({state:EJ,choice:eZ,note:sJ,rectWithTitle:fJ,labelRect:HZ,iconSquare:FZ,iconCircle:IZ,icon:NZ,iconRounded:PZ,imageSquare:zZ,anchor:YQ,kanbanItem:aee,classBox:tee,erBox:ML,requirementBox:nee}),...QDe.flatMap(r=>[r.shortName,..."aliases"in r?r.aliases:[],..."internalAliases"in r?r.internalAliases:[]].map(i=>[i,r.handler]))];return Object.fromEntries(e)},"generateShapeMap"),IL=ZDe();o(oee,"isValidShape")});var JDe,iw,lee=N(()=>{"use strict";fr();PT();Gt();yt();OL();er();pr();ci();JDe="flowchart-",iw=class{constructor(){this.vertexCounter=0;this.config=me();this.vertices=new Map;this.edges=[];this.classes=new Map;this.subGraphs=[];this.subGraphLookup=new Map;this.tooltips=new Map;this.subCount=0;this.firstGraphFlag=!0;this.secCount=-1;this.posCrossRef=[];this.funs=[];this.setAccTitle=Ar;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getAccTitle=Dr;this.getAccDescription=Rr;this.getDiagramTitle=Nr;this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{o(this,"FlowDB")}sanitizeText(e){return Ze.sanitizeText(e,this.config)}lookUpDomId(e){for(let r of this.vertices.values())if(r.id===e)return r.domId;return e}addVertex(e,r,n,i,a,s,l={},u){if(!e||e.trim().length===0)return;let h;if(u!==void 0){let m;u.includes(` -`)?m=u+` -`:m=`{ -`+u+` -}`,h=Tm(m,{schema:bm})}let f=this.edges.find(m=>m.id===e);if(f){let m=h;m?.animate!==void 0&&(f.animate=m.animate),m?.animation!==void 0&&(f.animation=m.animation);return}let d,p=this.vertices.get(e);if(p===void 0&&(p={id:e,labelType:"text",domId:JDe+e+"-"+this.vertexCounter,styles:[],classes:[]},this.vertices.set(e,p)),this.vertexCounter++,r!==void 0?(this.config=me(),d=this.sanitizeText(r.text.trim()),p.labelType=r.type,d.startsWith('"')&&d.endsWith('"')&&(d=d.substring(1,d.length-1)),p.text=d):p.text===void 0&&(p.text=e),n!==void 0&&(p.type=n),i?.forEach(m=>{p.styles.push(m)}),a?.forEach(m=>{p.classes.push(m)}),s!==void 0&&(p.dir=s),p.props===void 0?p.props=l:l!==void 0&&Object.assign(p.props,l),h!==void 0){if(h.shape){if(h.shape!==h.shape.toLowerCase()||h.shape.includes("_"))throw new Error(`No such shape: ${h.shape}. Shape names should be lowercase.`);if(!oee(h.shape))throw new Error(`No such shape: ${h.shape}.`);p.type=h?.shape}h?.label&&(p.text=h?.label),h?.icon&&(p.icon=h?.icon,!h.label?.trim()&&p.text===e&&(p.text="")),h?.form&&(p.form=h?.form),h?.pos&&(p.pos=h?.pos),h?.img&&(p.img=h?.img,!h.label?.trim()&&p.text===e&&(p.text="")),h?.constraint&&(p.constraint=h.constraint),h.w&&(p.assetWidth=Number(h.w)),h.h&&(p.assetHeight=Number(h.h))}}addSingleLink(e,r,n,i){let l={start:e,end:r,type:void 0,text:"",labelType:"text",classes:[],isUserDefinedId:!1,interpolate:this.edges.defaultInterpolate};X.info("abc78 Got edge...",l);let u=n.text;if(u!==void 0&&(l.text=this.sanitizeText(u.text.trim()),l.text.startsWith('"')&&l.text.endsWith('"')&&(l.text=l.text.substring(1,l.text.length-1)),l.labelType=u.type),n!==void 0&&(l.type=n.type,l.stroke=n.stroke,l.length=n.length>10?10:n.length),i&&!this.edges.some(h=>h.id===i))l.id=i,l.isUserDefinedId=!0;else{let h=this.edges.filter(f=>f.start===l.start&&f.end===l.end);h.length===0?l.id=Wh(l.start,l.end,{counter:0,prefix:"L"}):l.id=Wh(l.start,l.end,{counter:h.length+1,prefix:"L"})}if(this.edges.length<(this.config.maxEdges??500))X.info("Pushing edge..."),this.edges.push(l);else throw new Error(`Edge limit exceeded. ${this.edges.length} edges found, but the limit is ${this.config.maxEdges}. - -Initialize mermaid with maxEdges set to a higher number to allow more edges. -You cannot set this config via configuration inside the diagram as it is a secure config. -You have to call mermaid.initialize.`)}isLinkData(e){return e!==null&&typeof e=="object"&&"id"in e&&typeof e.id=="string"}addLink(e,r,n){let i=this.isLinkData(n)?n.id.replace("@",""):void 0;X.info("addLink",e,r,i);for(let a of e)for(let s of r){let l=a===e[e.length-1],u=s===r[0];l&&u?this.addSingleLink(a,s,n,i):this.addSingleLink(a,s,n,void 0)}}updateLinkInterpolate(e,r){e.forEach(n=>{n==="default"?this.edges.defaultInterpolate=r:this.edges[n].interpolate=r})}updateLink(e,r){e.forEach(n=>{if(typeof n=="number"&&n>=this.edges.length)throw new Error(`The index ${n} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${this.edges.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);n==="default"?this.edges.defaultStyle=r:(this.edges[n].style=r,(this.edges[n]?.style?.length??0)>0&&!this.edges[n]?.style?.some(i=>i?.startsWith("fill"))&&this.edges[n]?.style?.push("fill:none"))})}addClass(e,r){let n=r.join().replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");e.split(",").forEach(i=>{let a=this.classes.get(i);a===void 0&&(a={id:i,styles:[],textStyles:[]},this.classes.set(i,a)),n?.forEach(s=>{if(/color/.exec(s)){let l=s.replace("fill","bgFill");a.textStyles.push(l)}a.styles.push(s)})})}setDirection(e){this.direction=e,/.*/.exec(this.direction)&&(this.direction="LR"),/.*v/.exec(this.direction)&&(this.direction="TB"),this.direction==="TD"&&(this.direction="TB")}setClass(e,r){for(let n of e.split(",")){let i=this.vertices.get(n);i&&i.classes.push(r);let a=this.edges.find(l=>l.id===n);a&&a.classes.push(r);let s=this.subGraphLookup.get(n);s&&s.classes.push(r)}}setTooltip(e,r){if(r!==void 0){r=this.sanitizeText(r);for(let n of e.split(","))this.tooltips.set(this.version==="gen-1"?this.lookUpDomId(n):n,r)}}setClickFun(e,r,n){let i=this.lookUpDomId(e);if(me().securityLevel!=="loose"||r===void 0)return;let a=[];if(typeof n=="string"){a=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let l=0;l{let l=document.querySelector(`[id="${i}"]`);l!==null&&l.addEventListener("click",()=>{Vt.runFunc(r,...a)},!1)}))}setLink(e,r,n){e.split(",").forEach(i=>{let a=this.vertices.get(i);a!==void 0&&(a.link=Vt.formatUrl(r,this.config),a.linkTarget=n)}),this.setClass(e,"clickable")}getTooltip(e){return this.tooltips.get(e)}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFun(i,r,n)}),this.setClass(e,"clickable")}bindFunctions(e){this.funs.forEach(r=>{r(e)})}getDirection(){return this.direction?.trim()}getVertices(){return this.vertices}getEdges(){return this.edges}getClasses(){return this.classes}setupToolTips(e){let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=a.currentTarget?.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.bottom+"px"),r.html(r.html().replace(/<br\/>/g,"
    ")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})}clear(e="gen-2"){this.vertices=new Map,this.classes=new Map,this.edges=[],this.funs=[this.setupToolTips.bind(this)],this.subGraphs=[],this.subGraphLookup=new Map,this.subCount=0,this.tooltips=new Map,this.firstGraphFlag=!0,this.version=e,this.config=me(),kr()}setGen(e){this.version=e||"gen-2"}defaultStyle(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"}addSubGraph(e,r,n){let i=e.text.trim(),a=n.text;e===n&&/\s/.exec(n.text)&&(i=void 0);let l=o(p=>{let m={boolean:{},number:{},string:{}},g=[],y;return{nodeList:p.filter(function(x){let b=typeof x;return x.stmt&&x.stmt==="dir"?(y=x.value,!1):x.trim()===""?!1:b in m?m[b].hasOwnProperty(x)?!1:m[b][x]=!0:g.includes(x)?!1:g.push(x)}),dir:y}},"uniq")(r.flat()),u=l.nodeList,h=l.dir,f=me().flowchart??{};if(h=h??(f.inheritDir?this.getDirection()??me().direction??void 0:void 0),this.version==="gen-1")for(let p=0;p2e3)return{result:!1,count:0};if(this.posCrossRef[this.secCount]=r,this.subGraphs[r].id===e)return{result:!0,count:0};let i=0,a=1;for(;i=0){let l=this.indexNodes2(e,s);if(l.result)return{result:!0,count:a+l.count};a=a+l.count}i=i+1}return{result:!1,count:a}}getDepthFirstPos(e){return this.posCrossRef[e]}indexNodes(){this.secCount=-1,this.subGraphs.length>0&&this.indexNodes2("none",this.subGraphs.length-1)}getSubGraphs(){return this.subGraphs}firstGraph(){return this.firstGraphFlag?(this.firstGraphFlag=!1,!0):!1}destructStartLink(e){let r=e.trim(),n="arrow_open";switch(r[0]){case"<":n="arrow_point",r=r.slice(1);break;case"x":n="arrow_cross",r=r.slice(1);break;case"o":n="arrow_circle",r=r.slice(1);break}let i="normal";return r.includes("=")&&(i="thick"),r.includes(".")&&(i="dotted"),{type:n,stroke:i}}countChar(e,r){let n=r.length,i=0;for(let a=0;a":i="arrow_point",r.startsWith("<")&&(i="double_"+i,n=n.slice(1));break;case"o":i="arrow_circle",r.startsWith("o")&&(i="double_"+i,n=n.slice(1));break}let a="normal",s=n.length-1;n.startsWith("=")&&(a="thick"),n.startsWith("~")&&(a="invisible");let l=this.countChar(".",n);return l&&(a="dotted",s=l),{type:i,stroke:a,length:s}}destructLink(e,r){let n=this.destructEndLink(e),i;if(r){if(i=this.destructStartLink(r),i.stroke!==n.stroke)return{type:"INVALID",stroke:"INVALID"};if(i.type==="arrow_open")i.type=n.type;else{if(i.type!==n.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return i.type==="double_arrow"&&(i.type="double_arrow_point"),i.length=n.length,i}return n}exists(e,r){for(let n of e)if(n.nodes.includes(r))return!0;return!1}makeUniq(e,r){let n=[];return e.nodes.forEach((i,a)=>{this.exists(r,i)||n.push(e.nodes[a])}),{nodes:n}}getTypeFromVertex(e){if(e.img)return"imageSquare";if(e.icon)return e.form==="circle"?"iconCircle":e.form==="square"?"iconSquare":e.form==="rounded"?"iconRounded":"icon";switch(e.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";case"ellipse":return"ellipse";default:return e.type}}findNode(e,r){return e.find(n=>n.id===r)}destructEdgeType(e){let r="none",n="arrow_point";switch(e){case"arrow_point":case"arrow_circle":case"arrow_cross":n=e;break;case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":r=e.replace("double_",""),n=r;break}return{arrowTypeStart:r,arrowTypeEnd:n}}addNodeFromVertex(e,r,n,i,a,s){let l=n.get(e.id),u=i.get(e.id)??!1,h=this.findNode(r,e.id);if(h)h.cssStyles=e.styles,h.cssCompiledStyles=this.getCompiledStyles(e.classes),h.cssClasses=e.classes.join(" ");else{let f={id:e.id,label:e.text,labelStyle:"",parentId:l,padding:a.flowchart?.padding||8,cssStyles:e.styles,cssCompiledStyles:this.getCompiledStyles(["default","node",...e.classes]),cssClasses:"default "+e.classes.join(" "),dir:e.dir,domId:e.domId,look:s,link:e.link,linkTarget:e.linkTarget,tooltip:this.getTooltip(e.id),icon:e.icon,pos:e.pos,img:e.img,assetWidth:e.assetWidth,assetHeight:e.assetHeight,constraint:e.constraint};u?r.push({...f,isGroup:!0,shape:"rect"}):r.push({...f,isGroup:!1,shape:this.getTypeFromVertex(e)})}}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}getData(){let e=me(),r=[],n=[],i=this.getSubGraphs(),a=new Map,s=new Map;for(let h=i.length-1;h>=0;h--){let f=i[h];f.nodes.length>0&&s.set(f.id,!0);for(let d of f.nodes)a.set(d,f.id)}for(let h=i.length-1;h>=0;h--){let f=i[h];r.push({id:f.id,label:f.title,labelStyle:"",parentId:a.get(f.id),padding:8,cssCompiledStyles:this.getCompiledStyles(f.classes),cssClasses:f.classes.join(" "),shape:"rect",dir:f.dir,isGroup:!0,look:e.look})}this.getVertices().forEach(h=>{this.addNodeFromVertex(h,r,a,s,e,e.look||"classic")});let u=this.getEdges();return u.forEach((h,f)=>{let{arrowTypeStart:d,arrowTypeEnd:p}=this.destructEdgeType(h.type),m=[...u.defaultStyle??[]];h.style&&m.push(...h.style);let g={id:Wh(h.start,h.end,{counter:f,prefix:"L"},h.id),isUserDefinedId:h.isUserDefinedId,start:h.start,end:h.end,type:h.type??"normal",label:h.text,labelpos:"c",thickness:h.stroke,minlen:h.length,classes:h?.stroke==="invisible"?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":d,arrowTypeEnd:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":p,arrowheadStyle:"fill: #333",cssCompiledStyles:this.getCompiledStyles(h.classes),labelStyle:m,style:m,pattern:h.stroke,look:e.look,animate:h.animate,animation:h.animation,curve:h.interpolate||this.edges.defaultInterpolate||e.flowchart?.curve};n.push(g)}),{nodes:r,edges:n,other:{},config:e}}defaultConfig(){return $3.flowchart}}});var wc,Sm=N(()=>{"use strict";fr();wc=o((t,e)=>{let r;return e==="sandbox"&&(r=Ge("#i"+t)),(e==="sandbox"?Ge(r.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${t}"]`)},"getDiagramElement")});var Bu,R2=N(()=>{"use strict";Bu=o(({flowchart:t})=>{let e=t?.subGraphTitleMargin?.top??0,r=t?.subGraphTitleMargin?.bottom??0,n=e+r;return{subGraphTitleTopMargin:e,subGraphTitleBottomMargin:r,subGraphTitleTotalMargin:n}},"getSubGraphTitleMargins")});var cee,e9e,t9e,r9e,n9e,i9e,a9e,uee,Cm,hee,aw=N(()=>{"use strict";Gt();pr();yt();R2();fr();Wt();ao();mL();rw();Zh();zt();cee=o(async(t,e)=>{X.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Ye(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=dr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await qn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0}),y=g.getBBox();if(dr(r.flowchart.htmlLabels)){let _=g.children[0],C=Ge(g);y=_.getBoundingClientRect(),C.attr("width",y.width),C.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,T=e.y-x/2;X.trace("Data ",e,JSON.stringify(e));let S;if(e.look==="handDrawn"){let _=je.svg(d),C=Qe(e,{roughness:.7,fill:a,stroke:s,fillWeight:3,seed:i}),D=_.path(Oa(b,T,v,x,0),C);S=d.insert(()=>(X.debug("Rough node insert CXC",D),D),":first-child"),S.select("path:nth-child(2)").attr("style",h.join(";")),S.select("path").attr("style",f.join(";").replace("fill","stroke"))}else S=d.insert("rect",":first-child"),S.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",T).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:w}=Bu(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+w})`),l){let _=m.select("span");_&&_.attr("style",l)}let E=S.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(_){return Xh(e,_)},{cluster:d,labelBBox:y}},"rect"),e9e=o((t,e)=>{let r=t.insert("g").attr("class","note-cluster").attr("id",e.id),n=r.insert("rect",":first-child"),i=0*e.padding,a=i/2;n.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+i).attr("height",e.height+i).attr("fill","none");let s=n.node().getBBox();return e.width=s.width,e.height=s.height,e.intersect=function(l){return Xh(e,l)},{cluster:r,labelBBox:{width:0,height:0}}},"noteGroup"),t9e=o(async(t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{altBackground:a,compositeBackground:s,compositeTitleBackground:l,nodeBorder:u}=n,h=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-id",e.id).attr("data-look",e.look),f=h.insert("g",":first-child"),d=h.insert("g").attr("class","cluster-label"),p=h.append("rect"),m=d.node().appendChild(await Tc(e.label,e.labelStyle,void 0,!0)),g=m.getBBox();if(dr(r.flowchart.htmlLabels)){let D=m.children[0],O=Ge(m);g=D.getBoundingClientRect(),O.attr("width",g.width),O.attr("height",g.height)}let y=0*e.padding,v=y/2,x=(e.width<=g.width+e.padding?g.width+e.padding:e.width)+y;e.width<=g.width+e.padding?e.diff=(x-e.width)/2-e.padding:e.diff=-e.padding;let b=e.height+y,T=e.height+y-g.height-6,S=e.x-x/2,w=e.y-b/2;e.width=x;let E=e.y-e.height/2-v+g.height+2,_;if(e.look==="handDrawn"){let D=e.cssClasses.includes("statediagram-cluster-alt"),O=je.svg(h),R=e.rx||e.ry?O.path(Oa(S,w,x,b,10),{roughness:.7,fill:l,fillStyle:"solid",stroke:u,seed:i}):O.rectangle(S,w,x,b,{seed:i});_=h.insert(()=>R,":first-child");let k=O.rectangle(S,E,x,T,{fill:D?a:s,fillStyle:D?"hachure":"solid",stroke:u,seed:i});_=h.insert(()=>R,":first-child"),p=h.insert(()=>k)}else _=f.insert("rect",":first-child"),_.attr("class","outer").attr("x",S).attr("y",w).attr("width",x).attr("height",b).attr("data-look",e.look),p.attr("class","inner").attr("x",S).attr("y",E).attr("width",x).attr("height",T);d.attr("transform",`translate(${e.x-g.width/2}, ${w+1-(dr(r.flowchart.htmlLabels)?0:3)})`);let C=_.node().getBBox();return e.height=C.height,e.offsetX=0,e.offsetY=g.height-e.padding/2,e.labelBBox=g,e.intersect=function(D){return Xh(e,D)},{cluster:h,labelBBox:g}},"roundedWithTitle"),r9e=o(async(t,e)=>{X.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Ye(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=dr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await qn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0,width:e.width}),y=g.getBBox();if(dr(r.flowchart.htmlLabels)){let _=g.children[0],C=Ge(g);y=_.getBoundingClientRect(),C.attr("width",y.width),C.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,T=e.y-x/2;X.trace("Data ",e,JSON.stringify(e));let S;if(e.look==="handDrawn"){let _=je.svg(d),C=Qe(e,{roughness:.7,fill:a,stroke:s,fillWeight:4,seed:i}),D=_.path(Oa(b,T,v,x,e.rx),C);S=d.insert(()=>(X.debug("Rough node insert CXC",D),D),":first-child"),S.select("path:nth-child(2)").attr("style",h.join(";")),S.select("path").attr("style",f.join(";").replace("fill","stroke"))}else S=d.insert("rect",":first-child"),S.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",T).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:w}=Bu(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+w})`),l){let _=m.select("span");_&&_.attr("style",l)}let E=S.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(_){return Xh(e,_)},{cluster:d,labelBBox:y}},"kanbanSection"),n9e=o((t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{nodeBorder:a}=n,s=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-look",e.look),l=s.insert("g",":first-child"),u=0*e.padding,h=e.width+u;e.diff=-e.padding;let f=e.height+u,d=e.x-h/2,p=e.y-f/2;e.width=h;let m;if(e.look==="handDrawn"){let v=je.svg(s).rectangle(d,p,h,f,{fill:"lightgrey",roughness:.5,strokeLineDash:[5],stroke:a,seed:i});m=s.insert(()=>v,":first-child")}else m=l.insert("rect",":first-child"),m.attr("class","divider").attr("x",d).attr("y",p).attr("width",h).attr("height",f).attr("data-look",e.look);let g=m.node().getBBox();return e.height=g.height,e.offsetX=0,e.offsetY=0,e.intersect=function(y){return Xh(e,y)},{cluster:s,labelBBox:{}}},"divider"),i9e=cee,a9e={rect:cee,squareRect:i9e,roundedWithTitle:t9e,noteGroup:e9e,divider:n9e,kanbanSection:r9e},uee=new Map,Cm=o(async(t,e)=>{let r=e.shape||"rect",n=await a9e[r](t,e);return uee.set(e.id,n),n},"insertCluster"),hee=o(()=>{uee=new Map},"clear")});function sw(t,e){if(t===void 0||e===void 0)return{angle:0,deltaX:0,deltaY:0};t=Yn(t),e=Yn(e);let[r,n]=[t.x,t.y],[i,a]=[e.x,e.y],s=i-r,l=a-n;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}var Vo,Yn,ow,PL=N(()=>{"use strict";Vo={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:4};o(sw,"calculateDeltaAndAngle");Yn=o(t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,"pointTransformer"),ow=o(t=>({x:o(function(e,r,n){let i=0,a=Yn(n[0]).x=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(Vo,t.arrowTypeEnd)){let{angle:m,deltaX:g}=sw(n[n.length-1],n[n.length-2]);i=Vo[t.arrowTypeEnd]*Math.cos(m)*(g>=0?1:-1)}let s=Math.abs(Yn(e).x-Yn(n[n.length-1]).x),l=Math.abs(Yn(e).y-Yn(n[n.length-1]).y),u=Math.abs(Yn(e).x-Yn(n[0]).x),h=Math.abs(Yn(e).y-Yn(n[0]).y),f=Vo[t.arrowTypeStart],d=Vo[t.arrowTypeEnd],p=1;if(s0&&l0&&h=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(Vo,t.arrowTypeEnd)){let{angle:m,deltaY:g}=sw(n[n.length-1],n[n.length-2]);i=Vo[t.arrowTypeEnd]*Math.abs(Math.sin(m))*(g>=0?1:-1)}let s=Math.abs(Yn(e).y-Yn(n[n.length-1]).y),l=Math.abs(Yn(e).x-Yn(n[n.length-1]).x),u=Math.abs(Yn(e).y-Yn(n[0]).y),h=Math.abs(Yn(e).x-Yn(n[0]).x),f=Vo[t.arrowTypeStart],d=Vo[t.arrowTypeEnd],p=1;if(s0&&l0&&h{"use strict";yt();dee=o((t,e,r,n,i,a)=>{e.arrowTypeStart&&fee(t,"start",e.arrowTypeStart,r,n,i,a),e.arrowTypeEnd&&fee(t,"end",e.arrowTypeEnd,r,n,i,a)},"addEdgeMarkers"),s9e={arrow_cross:{type:"cross",fill:!1},arrow_point:{type:"point",fill:!0},arrow_barb:{type:"barb",fill:!0},arrow_circle:{type:"circle",fill:!1},aggregation:{type:"aggregation",fill:!1},extension:{type:"extension",fill:!1},composition:{type:"composition",fill:!0},dependency:{type:"dependency",fill:!0},lollipop:{type:"lollipop",fill:!1},only_one:{type:"onlyOne",fill:!1},zero_or_one:{type:"zeroOrOne",fill:!1},one_or_more:{type:"oneOrMore",fill:!1},zero_or_more:{type:"zeroOrMore",fill:!1},requirement_arrow:{type:"requirement_arrow",fill:!1},requirement_contains:{type:"requirement_contains",fill:!1}},fee=o((t,e,r,n,i,a,s)=>{let l=s9e[r];if(!l){X.warn(`Unknown arrow type: ${r}`);return}let u=l.type,f=`${i}_${a}-${u}${e==="start"?"Start":"End"}`;if(s&&s.trim()!==""){let d=s.replace(/[^\dA-Za-z]/g,"_"),p=`${f}_${d}`;if(!document.getElementById(p)){let m=document.getElementById(f);if(m){let g=m.cloneNode(!0);g.id=p,g.querySelectorAll("path, circle, line").forEach(v=>{v.setAttribute("stroke",s),l.fill&&v.setAttribute("fill",s)}),m.parentNode?.appendChild(g)}}t.attr(`marker-${e}`,`url(${n}#${p})`)}else t.attr(`marker-${e}`,`url(${n}#${f})`)},"addEdgeMarker")});function lw(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}function c9e(t){let e=[],r=[];for(let n=1;n5&&Math.abs(a.y-i.y)>5||i.y===a.y&&a.x===s.x&&Math.abs(a.x-i.x)>5&&Math.abs(a.y-s.y)>5)&&(e.push(a),r.push(n))}return{cornerPoints:e,cornerPointPositions:r}}var cw,da,yee,N2,uw,hw,o9e,l9e,mee,gee,u9e,fw,BL=N(()=>{"use strict";Gt();pr();yt();ao();er();PL();R2();fr();Wt();rw();pee();zt();cw=new Map,da=new Map,yee=o(()=>{cw.clear(),da.clear()},"clear"),N2=o(t=>t?t.reduce((r,n)=>r+";"+n,""):"","getLabelStyles"),uw=o(async(t,e)=>{let r=dr(me().flowchart.htmlLabels),n=await qn(t,e.label,{style:N2(e.labelStyle),useHtmlLabels:r,addSvgBackground:!0,isNode:!1});X.info("abc82",e,e.labelType);let i=t.insert("g").attr("class","edgeLabel"),a=i.insert("g").attr("class","label");a.node().appendChild(n);let s=n.getBBox();if(r){let u=n.children[0],h=Ge(n);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}a.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),cw.set(e.id,i),e.width=s.width,e.height=s.height;let l;if(e.startLabelLeft){let u=await Tc(e.startLabelLeft,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),da.get(e.id)||da.set(e.id,{}),da.get(e.id).startLeft=h,lw(l,e.startLabelLeft)}if(e.startLabelRight){let u=await Tc(e.startLabelRight,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=h.node().appendChild(u),f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),da.get(e.id)||da.set(e.id,{}),da.get(e.id).startRight=h,lw(l,e.startLabelRight)}if(e.endLabelLeft){let u=await Tc(e.endLabelLeft,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),da.get(e.id)||da.set(e.id,{}),da.get(e.id).endLeft=h,lw(l,e.endLabelLeft)}if(e.endLabelRight){let u=await Tc(e.endLabelRight,N2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),da.get(e.id)||da.set(e.id,{}),da.get(e.id).endRight=h,lw(l,e.endLabelRight)}return n},"insertEdgeLabel");o(lw,"setTerminalWidth");hw=o((t,e)=>{X.debug("Moving label abc88 ",t.id,t.label,cw.get(t.id),e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Bu(n);if(t.label){let a=cw.get(t.id),s=t.x,l=t.y;if(r){let u=Vt.calcLabelPosition(r);X.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=da.get(t.id).startLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=da.get(t.id).startRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=da.get(t.id).endLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=da.get(t.id).endRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),o9e=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),l9e=o((t,e,r)=>{X.debug(`intersection calc abc89: - outsidePoint: ${JSON.stringify(e)} - insidePoint : ${JSON.stringify(r)} - node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.xMath.abs(n-e.x)*u){let d=r.y{X.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(X.info("abc88 checking point",a,e),!o9e(e,a)&&!i){let s=l9e(e,n,a);X.debug("abc88 inside",a,n,s),X.debug("abc88 intersection",s,e);let l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)?X.warn("abc88 no intersect",s,r):r.push(s),i=!0}else X.warn("abc88 outside",a,n),n=a,i||r.push(a)}),X.debug("returning points",r),r},"cutPathAtIntersect");o(c9e,"extractCornerPoints");gee=o(function(t,e,r){let n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),s=r/a;return{x:e.x-s*n,y:e.y-s*i}},"findAdjacentPoint"),u9e=o(function(t){let{cornerPointPositions:e}=c9e(t),r=[];for(let n=0;n10&&Math.abs(a.y-i.y)>=10){X.debug("Corner point fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));let m=5;s.x===l.x?p={x:h<0?l.x-m+d:l.x+m-d,y:f<0?l.y-d:l.y+d}:p={x:h<0?l.x-d:l.x+d,y:f<0?l.y-m+d:l.y+m-d}}else X.debug("Corner point skipping fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));r.push(p,u)}else r.push(t[n]);return r},"fixCorners"),fw=o(function(t,e,r,n,i,a,s){let{handDrawnSeed:l}=me(),u=e.points,h=!1,f=i;var d=a;let p=[];for(let D in e.cssCompiledStyles)S2(D)||p.push(e.cssCompiledStyles[D]);d.intersect&&f.intersect&&(u=u.slice(1,e.points.length-1),u.unshift(f.intersect(u[0])),X.debug("Last point APA12",e.start,"-->",e.end,u[u.length-1],d,d.intersect(u[u.length-1])),u.push(d.intersect(u[u.length-1]))),e.toCluster&&(X.info("to cluster abc88",r.get(e.toCluster)),u=mee(e.points,r.get(e.toCluster).node),h=!0),e.fromCluster&&(X.debug("from cluster abc88",r.get(e.fromCluster),JSON.stringify(u,null,2)),u=mee(u.reverse(),r.get(e.fromCluster).node).reverse(),h=!0);let m=u.filter(D=>!Number.isNaN(D.y));m=u9e(m);let g=No;switch(g=Su,e.curve){case"linear":g=Su;break;case"basis":g=No;break;case"cardinal":g=qv;break;case"bumpX":g=Gv;break;case"bumpY":g=Vv;break;case"catmullRom":g=jv;break;case"monotoneX":g=Kv;break;case"monotoneY":g=Qv;break;case"natural":g=K0;break;case"step":g=Q0;break;case"stepAfter":g=Jv;break;case"stepBefore":g=Zv;break;default:g=No}let{x:y,y:v}=ow(e),x=Cl().x(y).y(v).curve(g),b;switch(e.thickness){case"normal":b="edge-thickness-normal";break;case"thick":b="edge-thickness-thick";break;case"invisible":b="edge-thickness-invisible";break;default:b="edge-thickness-normal"}switch(e.pattern){case"solid":b+=" edge-pattern-solid";break;case"dotted":b+=" edge-pattern-dotted";break;case"dashed":b+=" edge-pattern-dashed";break;default:b+=" edge-pattern-solid"}let T,S=x(m),w=Array.isArray(e.style)?e.style:e.style?[e.style]:[],E=w.find(D=>D?.startsWith("stroke:"));if(e.look==="handDrawn"){let D=je.svg(t);Object.assign([],m);let O=D.path(S,{roughness:.3,seed:l});b+=" transition",T=Ge(O).select("path").attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")).attr("style",w?w.reduce((k,L)=>k+";"+L,""):"");let R=T.attr("d");T.attr("d",R),t.node().appendChild(T.node())}else{let D=p.join(";"),O=w?w.reduce((L,A)=>L+A+";",""):"",R="";e.animate&&(R=" edge-animation-fast"),e.animation&&(R=" edge-animation-"+e.animation);let k=D?D+";"+O+";":O;T=t.append("path").attr("d",S).attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")+(R??"")).attr("style",k),E=k.match(/stroke:([^;]+)/)?.[1]}let _="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(_=mu(!0)),X.info("arrowTypeStart",e.arrowTypeStart),X.info("arrowTypeEnd",e.arrowTypeEnd),dee(T,e,_,s,n,E);let C={};return h&&(C.updatedPath=u),C.originalPath=e.points,C},"insertEdge")});var h9e,f9e,d9e,p9e,m9e,g9e,y9e,v9e,x9e,b9e,T9e,w9e,k9e,E9e,S9e,C9e,A9e,dw,FL=N(()=>{"use strict";yt();h9e=o((t,e,r,n)=>{e.forEach(i=>{A9e[i](t,r,n)})},"insertMarkers"),f9e=o((t,e,r)=>{X.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),d9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),p9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),m9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),g9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),y9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),v9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),x9e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),b9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","userSpaceOnUse").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),T9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneStart").attr("class","marker onlyOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneEnd").attr("class","marker onlyOne "+e).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M3,0 L3,18 M9,0 L9,18")},"only_one"),w9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneStart").attr("class","marker zeroOrOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),n.append("path").attr("d","M9,0 L9,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneEnd").attr("class","marker zeroOrOne "+e).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),i.append("path").attr("d","M21,0 L21,18")},"zero_or_one"),k9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreStart").attr("class","marker oneOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreEnd").attr("class","marker oneOrMore "+e).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18")},"one_or_more"),E9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreStart").attr("class","marker zeroOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),n.append("path").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreEnd").attr("class","marker zeroOrMore "+e).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),i.append("path").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},"zero_or_more"),S9e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_arrowEnd").attr("refX",20).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("path").attr("d",`M0,0 - L20,10 - M20,10 - L0,20`)},"requirement_arrow"),C9e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");n.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),n.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),n.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains"),A9e={extension:f9e,composition:d9e,aggregation:p9e,dependency:m9e,lollipop:g9e,point:y9e,circle:v9e,cross:x9e,barb:b9e,only_one:T9e,zero_or_one:w9e,one_or_more:k9e,zero_or_more:E9e,requirement_arrow:S9e,requirement_contains:C9e},dw=h9e});async function Am(t,e,r){let n,i;e.shape==="rect"&&(e.rx&&e.ry?e.shape="roundedRect":e.shape="squareRect");let a=e.shape?IL[e.shape]:void 0;if(!a)throw new Error(`No such shape: ${e.shape}. Please check your syntax.`);if(e.link){let s;r.config.securityLevel==="sandbox"?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s??null),i=await a(n,e,r)}else i=await a(t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),pw.set(e.id,n),e.haveCallback&&n.attr("class",n.attr("class")+" clickable"),n}var pw,vee,xee,M2,mw=N(()=>{"use strict";yt();OL();pw=new Map;o(Am,"insertNode");vee=o((t,e)=>{pw.set(e.id,t)},"setNodeElem"),xee=o(()=>{pw.clear()},"clear"),M2=o(t=>{let e=pw.get(t.id);X.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});var bee,Tee=N(()=>{"use strict";mi();pr();yt();aw();BL();FL();mw();Ft();er();bee={common:Ze,getConfig:tr,insertCluster:Cm,insertEdge:fw,insertEdgeLabel:uw,insertMarkers:dw,insertNode:Am,interpolateToCurve:A9,labelHelper:mt,log:X,positionEdgeLabel:hw}});function D9e(t){return typeof t=="symbol"||ii(t)&&fa(t)==_9e}var _9e,oo,Wd=N(()=>{"use strict";Au();Oo();_9e="[object Symbol]";o(D9e,"isSymbol");oo=D9e});function L9e(t,e){for(var r=-1,n=t==null?0:t.length,i=Array(n);++r{"use strict";o(L9e,"arrayMap");Bs=L9e});function Eee(t){if(typeof t=="string")return t;if(Pt(t))return Bs(t,Eee)+"";if(oo(t))return kee?kee.call(t):"";var e=t+"";return e=="0"&&1/t==-R9e?"-0":e}var R9e,wee,kee,See,Cee=N(()=>{"use strict";Md();qd();Wn();Wd();R9e=1/0,wee=ea?ea.prototype:void 0,kee=wee?wee.toString:void 0;o(Eee,"baseToString");See=Eee});function M9e(t){for(var e=t.length;e--&&N9e.test(t.charAt(e)););return e}var N9e,Aee,_ee=N(()=>{"use strict";N9e=/\s/;o(M9e,"trimmedEndIndex");Aee=M9e});function O9e(t){return t&&t.slice(0,Aee(t)+1).replace(I9e,"")}var I9e,Dee,Lee=N(()=>{"use strict";_ee();I9e=/^\s+/;o(O9e,"baseTrim");Dee=O9e});function z9e(t){if(typeof t=="number")return t;if(oo(t))return Ree;if(bn(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=bn(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=Dee(t);var r=B9e.test(t);return r||F9e.test(t)?$9e(t.slice(2),r?2:8):P9e.test(t)?Ree:+t}var Ree,P9e,B9e,F9e,$9e,Nee,Mee=N(()=>{"use strict";Lee();no();Wd();Ree=NaN,P9e=/^[-+]0x[0-9a-f]+$/i,B9e=/^0b[01]+$/i,F9e=/^0o[0-7]+$/i,$9e=parseInt;o(z9e,"toNumber");Nee=z9e});function V9e(t){if(!t)return t===0?t:0;if(t=Nee(t),t===Iee||t===-Iee){var e=t<0?-1:1;return e*G9e}return t===t?t:0}var Iee,G9e,_m,$L=N(()=>{"use strict";Mee();Iee=1/0,G9e=17976931348623157e292;o(V9e,"toFinite");_m=V9e});function U9e(t){var e=_m(t),r=e%1;return e===e?r?e-r:e:0}var kc,Dm=N(()=>{"use strict";$L();o(U9e,"toInteger");kc=U9e});var H9e,gw,Oee=N(()=>{"use strict";Ph();Mo();H9e=Ls(hi,"WeakMap"),gw=H9e});function W9e(){}var ai,zL=N(()=>{"use strict";o(W9e,"noop");ai=W9e});function q9e(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(q9e,"arrayEach");yw=q9e});function Y9e(t,e,r,n){for(var i=t.length,a=r+(n?1:-1);n?a--:++a{"use strict";o(Y9e,"baseFindIndex");vw=Y9e});function X9e(t){return t!==t}var Pee,Bee=N(()=>{"use strict";o(X9e,"baseIsNaN");Pee=X9e});function j9e(t,e,r){for(var n=r-1,i=t.length;++n{"use strict";o(j9e,"strictIndexOf");Fee=j9e});function K9e(t,e,r){return e===e?Fee(t,e,r):vw(t,Pee,r)}var Lm,xw=N(()=>{"use strict";VL();Bee();$ee();o(K9e,"baseIndexOf");Lm=K9e});function Q9e(t,e){var r=t==null?0:t.length;return!!r&&Lm(t,e,0)>-1}var bw,UL=N(()=>{"use strict";xw();o(Q9e,"arrayIncludes");bw=Q9e});var Z9e,zee,Gee=N(()=>{"use strict";p9();Z9e=mT(Object.keys,Object),zee=Z9e});function tLe(t){if(!mc(t))return zee(t);var e=[];for(var r in Object(t))eLe.call(t,r)&&r!="constructor"&&e.push(r);return e}var J9e,eLe,Rm,Tw=N(()=>{"use strict";um();Gee();J9e=Object.prototype,eLe=J9e.hasOwnProperty;o(tLe,"baseKeys");Rm=tLe});function rLe(t){return fi(t)?bT(t):Rm(t)}var zr,Ec=N(()=>{"use strict";x9();Tw();Po();o(rLe,"keys");zr=rLe});var nLe,iLe,aLe,pa,Vee=N(()=>{"use strict";pm();Fd();k9();Po();um();Ec();nLe=Object.prototype,iLe=nLe.hasOwnProperty,aLe=kT(function(t,e){if(mc(e)||fi(e)){$o(e,zr(e),t);return}for(var r in e)iLe.call(e,r)&&gc(t,r,e[r])}),pa=aLe});function lLe(t,e){if(Pt(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||oo(t)?!0:oLe.test(t)||!sLe.test(t)||e!=null&&t in Object(e)}var sLe,oLe,Nm,ww=N(()=>{"use strict";Wn();Wd();sLe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,oLe=/^\w*$/;o(lLe,"isKey");Nm=lLe});function uLe(t){var e=rm(t,function(n){return r.size===cLe&&r.clear(),n}),r=e.cache;return e}var cLe,Uee,Hee=N(()=>{"use strict";o9();cLe=500;o(uLe,"memoizeCapped");Uee=uLe});var hLe,fLe,dLe,Wee,qee=N(()=>{"use strict";Hee();hLe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,fLe=/\\(\\)?/g,dLe=Uee(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(hLe,function(r,n,i,a){e.push(i?a.replace(fLe,"$1"):n||r)}),e}),Wee=dLe});function pLe(t){return t==null?"":See(t)}var kw,HL=N(()=>{"use strict";Cee();o(pLe,"toString");kw=pLe});function mLe(t,e){return Pt(t)?t:Nm(t,e)?[t]:Wee(kw(t))}var Jh,I2=N(()=>{"use strict";Wn();ww();qee();HL();o(mLe,"castPath");Jh=mLe});function yLe(t){if(typeof t=="string"||oo(t))return t;var e=t+"";return e=="0"&&1/t==-gLe?"-0":e}var gLe,Sc,Mm=N(()=>{"use strict";Wd();gLe=1/0;o(yLe,"toKey");Sc=yLe});function vLe(t,e){e=Jh(e,t);for(var r=0,n=e.length;t!=null&&r{"use strict";I2();Mm();o(vLe,"baseGet");ef=vLe});function xLe(t,e,r){var n=t==null?void 0:ef(t,e);return n===void 0?r:n}var Yee,Xee=N(()=>{"use strict";O2();o(xLe,"get");Yee=xLe});function bLe(t,e){for(var r=-1,n=e.length,i=t.length;++r{"use strict";o(bLe,"arrayPush");Im=bLe});function TLe(t){return Pt(t)||Dl(t)||!!(jee&&t&&t[jee])}var jee,Kee,Qee=N(()=>{"use strict";Md();hm();Wn();jee=ea?ea.isConcatSpreadable:void 0;o(TLe,"isFlattenable");Kee=TLe});function Zee(t,e,r,n,i){var a=-1,s=t.length;for(r||(r=Kee),i||(i=[]);++a0&&r(l)?e>1?Zee(l,e-1,r,n,i):Im(i,l):n||(i[i.length]=l)}return i}var Cc,Om=N(()=>{"use strict";Ew();Qee();o(Zee,"baseFlatten");Cc=Zee});function wLe(t){var e=t==null?0:t.length;return e?Cc(t,1):[]}var qr,Sw=N(()=>{"use strict";Om();o(wLe,"flatten");qr=wLe});function kLe(t){return wT(TT(t,void 0,qr),t+"")}var Jee,ete=N(()=>{"use strict";Sw();b9();w9();o(kLe,"flatRest");Jee=kLe});function ELe(t,e,r){var n=-1,i=t.length;e<0&&(e=-e>i?0:i+e),r=r>i?i:r,r<0&&(r+=i),i=e>r?0:r-e>>>0,e>>>=0;for(var a=Array(i);++n{"use strict";o(ELe,"baseSlice");Cw=ELe});function MLe(t){return NLe.test(t)}var SLe,CLe,ALe,_Le,DLe,LLe,RLe,NLe,tte,rte=N(()=>{"use strict";SLe="\\ud800-\\udfff",CLe="\\u0300-\\u036f",ALe="\\ufe20-\\ufe2f",_Le="\\u20d0-\\u20ff",DLe=CLe+ALe+_Le,LLe="\\ufe0e\\ufe0f",RLe="\\u200d",NLe=RegExp("["+RLe+SLe+DLe+LLe+"]");o(MLe,"hasUnicode");tte=MLe});function ILe(t,e,r,n){var i=-1,a=t==null?0:t.length;for(n&&a&&(r=t[++i]);++i{"use strict";o(ILe,"arrayReduce");nte=ILe});function OLe(t,e){return t&&$o(e,zr(e),t)}var ate,ste=N(()=>{"use strict";Fd();Ec();o(OLe,"baseAssign");ate=OLe});function PLe(t,e){return t&&$o(e,Rs(e),t)}var ote,lte=N(()=>{"use strict";Fd();Uh();o(PLe,"baseAssignIn");ote=PLe});function BLe(t,e){for(var r=-1,n=t==null?0:t.length,i=0,a=[];++r{"use strict";o(BLe,"arrayFilter");Pm=BLe});function FLe(){return[]}var _w,qL=N(()=>{"use strict";o(FLe,"stubArray");_w=FLe});var $Le,zLe,cte,GLe,Bm,Dw=N(()=>{"use strict";Aw();qL();$Le=Object.prototype,zLe=$Le.propertyIsEnumerable,cte=Object.getOwnPropertySymbols,GLe=cte?function(t){return t==null?[]:(t=Object(t),Pm(cte(t),function(e){return zLe.call(t,e)}))}:_w,Bm=GLe});function VLe(t,e){return $o(t,Bm(t),e)}var ute,hte=N(()=>{"use strict";Fd();Dw();o(VLe,"copySymbols");ute=VLe});var ULe,HLe,Lw,YL=N(()=>{"use strict";Ew();gT();Dw();qL();ULe=Object.getOwnPropertySymbols,HLe=ULe?function(t){for(var e=[];t;)Im(e,Bm(t)),t=cm(t);return e}:_w,Lw=HLe});function WLe(t,e){return $o(t,Lw(t),e)}var fte,dte=N(()=>{"use strict";Fd();YL();o(WLe,"copySymbolsIn");fte=WLe});function qLe(t,e,r){var n=e(t);return Pt(t)?n:Im(n,r(t))}var Rw,XL=N(()=>{"use strict";Ew();Wn();o(qLe,"baseGetAllKeys");Rw=qLe});function YLe(t){return Rw(t,zr,Bm)}var P2,jL=N(()=>{"use strict";XL();Dw();Ec();o(YLe,"getAllKeys");P2=YLe});function XLe(t){return Rw(t,Rs,Lw)}var Nw,KL=N(()=>{"use strict";XL();YL();Uh();o(XLe,"getAllKeysIn");Nw=XLe});var jLe,Mw,pte=N(()=>{"use strict";Ph();Mo();jLe=Ls(hi,"DataView"),Mw=jLe});var KLe,Iw,mte=N(()=>{"use strict";Ph();Mo();KLe=Ls(hi,"Promise"),Iw=KLe});var QLe,tf,QL=N(()=>{"use strict";Ph();Mo();QLe=Ls(hi,"Set"),tf=QLe});var gte,ZLe,yte,vte,xte,bte,JLe,eRe,tRe,rRe,nRe,Yd,lo,Xd=N(()=>{"use strict";pte();lT();mte();QL();Oee();Au();i9();gte="[object Map]",ZLe="[object Object]",yte="[object Promise]",vte="[object Set]",xte="[object WeakMap]",bte="[object DataView]",JLe=_u(Mw),eRe=_u($h),tRe=_u(Iw),rRe=_u(tf),nRe=_u(gw),Yd=fa;(Mw&&Yd(new Mw(new ArrayBuffer(1)))!=bte||$h&&Yd(new $h)!=gte||Iw&&Yd(Iw.resolve())!=yte||tf&&Yd(new tf)!=vte||gw&&Yd(new gw)!=xte)&&(Yd=o(function(t){var e=fa(t),r=e==ZLe?t.constructor:void 0,n=r?_u(r):"";if(n)switch(n){case JLe:return bte;case eRe:return gte;case tRe:return yte;case rRe:return vte;case nRe:return xte}return e},"getTag"));lo=Yd});function sRe(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&aRe.call(t,"index")&&(r.index=t.index,r.input=t.input),r}var iRe,aRe,Tte,wte=N(()=>{"use strict";iRe=Object.prototype,aRe=iRe.hasOwnProperty;o(sRe,"initCloneArray");Tte=sRe});function oRe(t,e){var r=e?lm(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}var kte,Ete=N(()=>{"use strict";fT();o(oRe,"cloneDataView");kte=oRe});function cRe(t){var e=new t.constructor(t.source,lRe.exec(t));return e.lastIndex=t.lastIndex,e}var lRe,Ste,Cte=N(()=>{"use strict";lRe=/\w*$/;o(cRe,"cloneRegExp");Ste=cRe});function uRe(t){return _te?Object(_te.call(t)):{}}var Ate,_te,Dte,Lte=N(()=>{"use strict";Md();Ate=ea?ea.prototype:void 0,_te=Ate?Ate.valueOf:void 0;o(uRe,"cloneSymbol");Dte=uRe});function LRe(t,e,r){var n=t.constructor;switch(e){case xRe:return lm(t);case hRe:case fRe:return new n(+t);case bRe:return kte(t,r);case TRe:case wRe:case kRe:case ERe:case SRe:case CRe:case ARe:case _Re:case DRe:return dT(t,r);case dRe:return new n;case pRe:case yRe:return new n(t);case mRe:return Ste(t);case gRe:return new n;case vRe:return Dte(t)}}var hRe,fRe,dRe,pRe,mRe,gRe,yRe,vRe,xRe,bRe,TRe,wRe,kRe,ERe,SRe,CRe,ARe,_Re,DRe,Rte,Nte=N(()=>{"use strict";fT();Ete();Cte();Lte();f9();hRe="[object Boolean]",fRe="[object Date]",dRe="[object Map]",pRe="[object Number]",mRe="[object RegExp]",gRe="[object Set]",yRe="[object String]",vRe="[object Symbol]",xRe="[object ArrayBuffer]",bRe="[object DataView]",TRe="[object Float32Array]",wRe="[object Float64Array]",kRe="[object Int8Array]",ERe="[object Int16Array]",SRe="[object Int32Array]",CRe="[object Uint8Array]",ARe="[object Uint8ClampedArray]",_Re="[object Uint16Array]",DRe="[object Uint32Array]";o(LRe,"initCloneByTag");Rte=LRe});function NRe(t){return ii(t)&&lo(t)==RRe}var RRe,Mte,Ite=N(()=>{"use strict";Xd();Oo();RRe="[object Map]";o(NRe,"baseIsMap");Mte=NRe});var Ote,MRe,Pte,Bte=N(()=>{"use strict";Ite();Bd();h2();Ote=Fo&&Fo.isMap,MRe=Ote?Bo(Ote):Mte,Pte=MRe});function ORe(t){return ii(t)&&lo(t)==IRe}var IRe,Fte,$te=N(()=>{"use strict";Xd();Oo();IRe="[object Set]";o(ORe,"baseIsSet");Fte=ORe});var zte,PRe,Gte,Vte=N(()=>{"use strict";$te();Bd();h2();zte=Fo&&Fo.isSet,PRe=zte?Bo(zte):Fte,Gte=PRe});function Ow(t,e,r,n,i,a){var s,l=e&BRe,u=e&FRe,h=e&$Re;if(r&&(s=i?r(t,n,i,a):r(t)),s!==void 0)return s;if(!bn(t))return t;var f=Pt(t);if(f){if(s=Tte(t),!l)return pT(t,s)}else{var d=lo(t),p=d==Hte||d==HRe;if(Ll(t))return hT(t,l);if(d==Wte||d==Ute||p&&!i){if(s=u||p?{}:yT(t),!l)return u?fte(t,ote(s,t)):ute(t,ate(s,t))}else{if(!_n[d])return i?t:{};s=Rte(t,d,l)}}a||(a=new dc);var m=a.get(t);if(m)return m;a.set(t,s),Gte(t)?t.forEach(function(v){s.add(Ow(v,e,r,v,t,a))}):Pte(t)&&t.forEach(function(v,x){s.set(x,Ow(v,e,r,x,t,a))});var g=h?u?Nw:P2:u?Rs:zr,y=f?void 0:g(t);return yw(y||t,function(v,x){y&&(x=v,v=t[x]),gc(s,x,Ow(v,e,r,x,t,a))}),s}var BRe,FRe,$Re,Ute,zRe,GRe,VRe,URe,Hte,HRe,WRe,qRe,Wte,YRe,XRe,jRe,KRe,QRe,ZRe,JRe,eNe,tNe,rNe,nNe,iNe,aNe,sNe,oNe,lNe,_n,Pw,ZL=N(()=>{"use strict";l2();GL();pm();ste();lte();u9();d9();hte();dte();jL();KL();Xd();wte();Nte();m9();Wn();dm();Bte();no();Vte();Ec();Uh();BRe=1,FRe=2,$Re=4,Ute="[object Arguments]",zRe="[object Array]",GRe="[object Boolean]",VRe="[object Date]",URe="[object Error]",Hte="[object Function]",HRe="[object GeneratorFunction]",WRe="[object Map]",qRe="[object Number]",Wte="[object Object]",YRe="[object RegExp]",XRe="[object Set]",jRe="[object String]",KRe="[object Symbol]",QRe="[object WeakMap]",ZRe="[object ArrayBuffer]",JRe="[object DataView]",eNe="[object Float32Array]",tNe="[object Float64Array]",rNe="[object Int8Array]",nNe="[object Int16Array]",iNe="[object Int32Array]",aNe="[object Uint8Array]",sNe="[object Uint8ClampedArray]",oNe="[object Uint16Array]",lNe="[object Uint32Array]",_n={};_n[Ute]=_n[zRe]=_n[ZRe]=_n[JRe]=_n[GRe]=_n[VRe]=_n[eNe]=_n[tNe]=_n[rNe]=_n[nNe]=_n[iNe]=_n[WRe]=_n[qRe]=_n[Wte]=_n[YRe]=_n[XRe]=_n[jRe]=_n[KRe]=_n[aNe]=_n[sNe]=_n[oNe]=_n[lNe]=!0;_n[URe]=_n[Hte]=_n[QRe]=!1;o(Ow,"baseClone");Pw=Ow});function uNe(t){return Pw(t,cNe)}var cNe,an,JL=N(()=>{"use strict";ZL();cNe=4;o(uNe,"clone");an=uNe});function dNe(t){return Pw(t,hNe|fNe)}var hNe,fNe,eR,qte=N(()=>{"use strict";ZL();hNe=1,fNe=4;o(dNe,"cloneDeep");eR=dNe});function pNe(t){for(var e=-1,r=t==null?0:t.length,n=0,i=[];++e{"use strict";o(pNe,"compact");Ac=pNe});function gNe(t){return this.__data__.set(t,mNe),this}var mNe,Xte,jte=N(()=>{"use strict";mNe="__lodash_hash_undefined__";o(gNe,"setCacheAdd");Xte=gNe});function yNe(t){return this.__data__.has(t)}var Kte,Qte=N(()=>{"use strict";o(yNe,"setCacheHas");Kte=yNe});function Bw(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new Od;++e{"use strict";cT();jte();Qte();o(Bw,"SetCache");Bw.prototype.add=Bw.prototype.push=Xte;Bw.prototype.has=Kte;Fm=Bw});function vNe(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(vNe,"arraySome");$w=vNe});function xNe(t,e){return t.has(e)}var $m,zw=N(()=>{"use strict";o(xNe,"cacheHas");$m=xNe});function wNe(t,e,r,n,i,a){var s=r&bNe,l=t.length,u=e.length;if(l!=u&&!(s&&u>l))return!1;var h=a.get(t),f=a.get(e);if(h&&f)return h==e&&f==t;var d=-1,p=!0,m=r&TNe?new Fm:void 0;for(a.set(t,e),a.set(e,t);++d{"use strict";Fw();tR();zw();bNe=1,TNe=2;o(wNe,"equalArrays");Gw=wNe});function kNe(t){var e=-1,r=Array(t.size);return t.forEach(function(n,i){r[++e]=[i,n]}),r}var Zte,Jte=N(()=>{"use strict";o(kNe,"mapToArray");Zte=kNe});function ENe(t){var e=-1,r=Array(t.size);return t.forEach(function(n){r[++e]=n}),r}var zm,Vw=N(()=>{"use strict";o(ENe,"setToArray");zm=ENe});function FNe(t,e,r,n,i,a,s){switch(r){case BNe:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case PNe:return!(t.byteLength!=e.byteLength||!a(new om(t),new om(e)));case ANe:case _Ne:case RNe:return Io(+t,+e);case DNe:return t.name==e.name&&t.message==e.message;case NNe:case INe:return t==e+"";case LNe:var l=Zte;case MNe:var u=n&SNe;if(l||(l=zm),t.size!=e.size&&!u)return!1;var h=s.get(t);if(h)return h==e;n|=CNe,s.set(t,e);var f=Gw(l(t),l(e),n,i,a,s);return s.delete(t),f;case ONe:if(nR)return nR.call(t)==nR.call(e)}return!1}var SNe,CNe,ANe,_Ne,DNe,LNe,RNe,NNe,MNe,INe,ONe,PNe,BNe,ere,nR,tre,rre=N(()=>{"use strict";Md();h9();Id();rR();Jte();Vw();SNe=1,CNe=2,ANe="[object Boolean]",_Ne="[object Date]",DNe="[object Error]",LNe="[object Map]",RNe="[object Number]",NNe="[object RegExp]",MNe="[object Set]",INe="[object String]",ONe="[object Symbol]",PNe="[object ArrayBuffer]",BNe="[object DataView]",ere=ea?ea.prototype:void 0,nR=ere?ere.valueOf:void 0;o(FNe,"equalByTag");tre=FNe});function VNe(t,e,r,n,i,a){var s=r&$Ne,l=P2(t),u=l.length,h=P2(e),f=h.length;if(u!=f&&!s)return!1;for(var d=u;d--;){var p=l[d];if(!(s?p in e:GNe.call(e,p)))return!1}var m=a.get(t),g=a.get(e);if(m&&g)return m==e&&g==t;var y=!0;a.set(t,e),a.set(e,t);for(var v=s;++d{"use strict";jL();$Ne=1,zNe=Object.prototype,GNe=zNe.hasOwnProperty;o(VNe,"equalObjects");nre=VNe});function WNe(t,e,r,n,i,a){var s=Pt(t),l=Pt(e),u=s?sre:lo(t),h=l?sre:lo(e);u=u==are?Uw:u,h=h==are?Uw:h;var f=u==Uw,d=h==Uw,p=u==h;if(p&&Ll(t)){if(!Ll(e))return!1;s=!0,f=!1}if(p&&!f)return a||(a=new dc),s||Gh(t)?Gw(t,e,r,n,i,a):tre(t,e,u,r,n,i,a);if(!(r&UNe)){var m=f&&ore.call(t,"__wrapped__"),g=d&&ore.call(e,"__wrapped__");if(m||g){var y=m?t.value():t,v=g?e.value():e;return a||(a=new dc),i(y,v,r,n,a)}}return p?(a||(a=new dc),nre(t,e,r,n,i,a)):!1}var UNe,are,sre,Uw,HNe,ore,lre,cre=N(()=>{"use strict";l2();rR();rre();ire();Xd();Wn();dm();f2();UNe=1,are="[object Arguments]",sre="[object Array]",Uw="[object Object]",HNe=Object.prototype,ore=HNe.hasOwnProperty;o(WNe,"baseIsEqualDeep");lre=WNe});function ure(t,e,r,n,i){return t===e?!0:t==null||e==null||!ii(t)&&!ii(e)?t!==t&&e!==e:lre(t,e,r,n,ure,i)}var Hw,iR=N(()=>{"use strict";cre();Oo();o(ure,"baseIsEqual");Hw=ure});function XNe(t,e,r,n){var i=r.length,a=i,s=!n;if(t==null)return!a;for(t=Object(t);i--;){var l=r[i];if(s&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++i{"use strict";l2();iR();qNe=1,YNe=2;o(XNe,"baseIsMatch");hre=XNe});function jNe(t){return t===t&&!bn(t)}var Ww,aR=N(()=>{"use strict";no();o(jNe,"isStrictComparable");Ww=jNe});function KNe(t){for(var e=zr(t),r=e.length;r--;){var n=e[r],i=t[n];e[r]=[n,i,Ww(i)]}return e}var dre,pre=N(()=>{"use strict";aR();Ec();o(KNe,"getMatchData");dre=KNe});function QNe(t,e){return function(r){return r==null?!1:r[t]===e&&(e!==void 0||t in Object(r))}}var qw,sR=N(()=>{"use strict";o(QNe,"matchesStrictComparable");qw=QNe});function ZNe(t){var e=dre(t);return e.length==1&&e[0][2]?qw(e[0][0],e[0][1]):function(r){return r===t||hre(r,t,e)}}var mre,gre=N(()=>{"use strict";fre();pre();sR();o(ZNe,"baseMatches");mre=ZNe});function JNe(t,e){return t!=null&&e in Object(t)}var yre,vre=N(()=>{"use strict";o(JNe,"baseHasIn");yre=JNe});function eMe(t,e,r){e=Jh(e,t);for(var n=-1,i=e.length,a=!1;++n{"use strict";I2();hm();Wn();p2();vT();Mm();o(eMe,"hasPath");Yw=eMe});function tMe(t,e){return t!=null&&Yw(t,e,yre)}var Xw,lR=N(()=>{"use strict";vre();oR();o(tMe,"hasIn");Xw=tMe});function iMe(t,e){return Nm(t)&&Ww(e)?qw(Sc(t),e):function(r){var n=Yee(r,t);return n===void 0&&n===e?Xw(r,t):Hw(e,n,rMe|nMe)}}var rMe,nMe,xre,bre=N(()=>{"use strict";iR();Xee();lR();ww();aR();sR();Mm();rMe=1,nMe=2;o(iMe,"baseMatchesProperty");xre=iMe});function aMe(t){return function(e){return e?.[t]}}var jw,cR=N(()=>{"use strict";o(aMe,"baseProperty");jw=aMe});function sMe(t){return function(e){return ef(e,t)}}var Tre,wre=N(()=>{"use strict";O2();o(sMe,"basePropertyDeep");Tre=sMe});function oMe(t){return Nm(t)?jw(Sc(t)):Tre(t)}var kre,Ere=N(()=>{"use strict";cR();wre();ww();Mm();o(oMe,"property");kre=oMe});function lMe(t){return typeof t=="function"?t:t==null?ta:typeof t=="object"?Pt(t)?xre(t[0],t[1]):mre(t):kre(t)}var mn,os=N(()=>{"use strict";gre();bre();Lu();Wn();Ere();o(lMe,"baseIteratee");mn=lMe});function cMe(t,e,r,n){for(var i=-1,a=t==null?0:t.length;++i{"use strict";o(cMe,"arrayAggregator");Sre=cMe});function uMe(t,e){return t&&sm(t,e,zr)}var Gm,Kw=N(()=>{"use strict";uT();Ec();o(uMe,"baseForOwn");Gm=uMe});function hMe(t,e){return function(r,n){if(r==null)return r;if(!fi(r))return t(r,n);for(var i=r.length,a=e?i:-1,s=Object(r);(e?a--:++a{"use strict";Po();o(hMe,"createBaseEach");Are=hMe});var fMe,Fs,rf=N(()=>{"use strict";Kw();_re();fMe=Are(Gm),Fs=fMe});function dMe(t,e,r,n){return Fs(t,function(i,a,s){e(n,i,r(i),s)}),n}var Dre,Lre=N(()=>{"use strict";rf();o(dMe,"baseAggregator");Dre=dMe});function pMe(t,e){return function(r,n){var i=Pt(r)?Sre:Dre,a=e?e():{};return i(r,t,mn(n,2),a)}}var Rre,Nre=N(()=>{"use strict";Cre();Lre();os();Wn();o(pMe,"createAggregator");Rre=pMe});var mMe,Qw,Mre=N(()=>{"use strict";Mo();mMe=o(function(){return hi.Date.now()},"now"),Qw=mMe});var Ire,gMe,yMe,nf,Ore=N(()=>{"use strict";mm();Id();$d();Uh();Ire=Object.prototype,gMe=Ire.hasOwnProperty,yMe=yc(function(t,e){t=Object(t);var r=-1,n=e.length,i=n>2?e[2]:void 0;for(i&&io(e[0],e[1],i)&&(n=1);++r{"use strict";o(vMe,"arrayIncludesWith");Zw=vMe});function bMe(t,e,r,n){var i=-1,a=bw,s=!0,l=t.length,u=[],h=e.length;if(!l)return u;r&&(e=Bs(e,Bo(r))),n?(a=Zw,s=!1):e.length>=xMe&&(a=$m,s=!1,e=new Fm(e));e:for(;++i{"use strict";Fw();UL();uR();qd();Bd();zw();xMe=200;o(bMe,"baseDifference");Pre=bMe});var TMe,af,Fre=N(()=>{"use strict";Bre();Om();mm();xT();TMe=yc(function(t,e){return Pd(t)?Pre(t,Cc(e,1,Pd,!0)):[]}),af=TMe});function wMe(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}var ma,$re=N(()=>{"use strict";o(wMe,"last");ma=wMe});function kMe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:kc(e),Cw(t,e<0?0:e,n)):[]}var bi,zre=N(()=>{"use strict";WL();Dm();o(kMe,"drop");bi=kMe});function EMe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:kc(e),e=n-e,Cw(t,0,e<0?0:e)):[]}var Fu,Gre=N(()=>{"use strict";WL();Dm();o(EMe,"dropRight");Fu=EMe});function SMe(t){return typeof t=="function"?t:ta}var Vm,Jw=N(()=>{"use strict";Lu();o(SMe,"castFunction");Vm=SMe});function CMe(t,e){var r=Pt(t)?yw:Fs;return r(t,Vm(e))}var Ae,ek=N(()=>{"use strict";GL();rf();Jw();Wn();o(CMe,"forEach");Ae=CMe});var Vre=N(()=>{"use strict";ek()});function AMe(t,e){for(var r=-1,n=t==null?0:t.length;++r{"use strict";o(AMe,"arrayEvery");Ure=AMe});function _Me(t,e){var r=!0;return Fs(t,function(n,i,a){return r=!!e(n,i,a),r}),r}var Wre,qre=N(()=>{"use strict";rf();o(_Me,"baseEvery");Wre=_Me});function DMe(t,e,r){var n=Pt(t)?Ure:Wre;return r&&io(t,e,r)&&(e=void 0),n(t,mn(e,3))}var Pa,Yre=N(()=>{"use strict";Hre();qre();os();Wn();$d();o(DMe,"every");Pa=DMe});function LMe(t,e){var r=[];return Fs(t,function(n,i,a){e(n,i,a)&&r.push(n)}),r}var tk,hR=N(()=>{"use strict";rf();o(LMe,"baseFilter");tk=LMe});function RMe(t,e){var r=Pt(t)?Pm:tk;return r(t,mn(e,3))}var Yr,fR=N(()=>{"use strict";Aw();hR();os();Wn();o(RMe,"filter");Yr=RMe});function NMe(t){return function(e,r,n){var i=Object(e);if(!fi(e)){var a=mn(r,3);e=zr(e),r=o(function(l){return a(i[l],l,i)},"predicate")}var s=t(e,r,n);return s>-1?i[a?e[s]:s]:void 0}}var Xre,jre=N(()=>{"use strict";os();Po();Ec();o(NMe,"createFind");Xre=NMe});function IMe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:kc(r);return i<0&&(i=MMe(n+i,0)),vw(t,mn(e,3),i)}var MMe,Kre,Qre=N(()=>{"use strict";VL();os();Dm();MMe=Math.max;o(IMe,"findIndex");Kre=IMe});var OMe,ls,Zre=N(()=>{"use strict";jre();Qre();OMe=Xre(Kre),ls=OMe});function PMe(t){return t&&t.length?t[0]:void 0}var ia,Jre=N(()=>{"use strict";o(PMe,"head");ia=PMe});var ene=N(()=>{"use strict";Jre()});function BMe(t,e){var r=-1,n=fi(t)?Array(t.length):[];return Fs(t,function(i,a,s){n[++r]=e(i,a,s)}),n}var rk,dR=N(()=>{"use strict";rf();Po();o(BMe,"baseMap");rk=BMe});function FMe(t,e){var r=Pt(t)?Bs:rk;return r(t,mn(e,3))}var Je,Um=N(()=>{"use strict";qd();os();dR();Wn();o(FMe,"map");Je=FMe});function $Me(t,e){return Cc(Je(t,e),1)}var ga,pR=N(()=>{"use strict";Om();Um();o($Me,"flatMap");ga=$Me});function zMe(t,e){return t==null?t:sm(t,Vm(e),Rs)}var mR,tne=N(()=>{"use strict";uT();Jw();Uh();o(zMe,"forIn");mR=zMe});function GMe(t,e){return t&&Gm(t,Vm(e))}var gR,rne=N(()=>{"use strict";Kw();Jw();o(GMe,"forOwn");gR=GMe});var VMe,UMe,HMe,yR,nne=N(()=>{"use strict";am();Nre();VMe=Object.prototype,UMe=VMe.hasOwnProperty,HMe=Rre(function(t,e,r){UMe.call(t,r)?t[r].push(e):pc(t,r,[e])}),yR=HMe});function WMe(t,e){return t>e}var ine,ane=N(()=>{"use strict";o(WMe,"baseGt");ine=WMe});function XMe(t,e){return t!=null&&YMe.call(t,e)}var qMe,YMe,sne,one=N(()=>{"use strict";qMe=Object.prototype,YMe=qMe.hasOwnProperty;o(XMe,"baseHas");sne=XMe});function jMe(t,e){return t!=null&&Yw(t,e,sne)}var Bt,lne=N(()=>{"use strict";one();oR();o(jMe,"has");Bt=jMe});function QMe(t){return typeof t=="string"||!Pt(t)&&ii(t)&&fa(t)==KMe}var KMe,Ti,nk=N(()=>{"use strict";Au();Wn();Oo();KMe="[object String]";o(QMe,"isString");Ti=QMe});function ZMe(t,e){return Bs(e,function(r){return t[r]})}var cne,une=N(()=>{"use strict";qd();o(ZMe,"baseValues");cne=ZMe});function JMe(t){return t==null?[]:cne(t,zr(t))}var br,vR=N(()=>{"use strict";une();Ec();o(JMe,"values");br=JMe});function tIe(t,e,r,n){t=fi(t)?t:br(t),r=r&&!n?kc(r):0;var i=t.length;return r<0&&(r=eIe(i+r,0)),Ti(t)?r<=i&&t.indexOf(e,r)>-1:!!i&&Lm(t,e,r)>-1}var eIe,Xn,hne=N(()=>{"use strict";xw();Po();nk();Dm();vR();eIe=Math.max;o(tIe,"includes");Xn=tIe});function nIe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:kc(r);return i<0&&(i=rIe(n+i,0)),Lm(t,e,i)}var rIe,ik,fne=N(()=>{"use strict";xw();Dm();rIe=Math.max;o(nIe,"indexOf");ik=nIe});function lIe(t){if(t==null)return!0;if(fi(t)&&(Pt(t)||typeof t=="string"||typeof t.splice=="function"||Ll(t)||Gh(t)||Dl(t)))return!t.length;var e=lo(t);if(e==iIe||e==aIe)return!t.size;if(mc(t))return!Rm(t).length;for(var r in t)if(oIe.call(t,r))return!1;return!0}var iIe,aIe,sIe,oIe,hr,ak=N(()=>{"use strict";Tw();Xd();hm();Wn();Po();dm();um();f2();iIe="[object Map]",aIe="[object Set]",sIe=Object.prototype,oIe=sIe.hasOwnProperty;o(lIe,"isEmpty");hr=lIe});function uIe(t){return ii(t)&&fa(t)==cIe}var cIe,dne,pne=N(()=>{"use strict";Au();Oo();cIe="[object RegExp]";o(uIe,"baseIsRegExp");dne=uIe});var mne,hIe,Uo,gne=N(()=>{"use strict";pne();Bd();h2();mne=Fo&&Fo.isRegExp,hIe=mne?Bo(mne):dne,Uo=hIe});function fIe(t){return t===void 0}var mr,yne=N(()=>{"use strict";o(fIe,"isUndefined");mr=fIe});function dIe(t,e){return t{"use strict";o(dIe,"baseLt");sk=dIe});function pIe(t,e){var r={};return e=mn(e,3),Gm(t,function(n,i,a){pc(r,i,e(n,i,a))}),r}var jd,vne=N(()=>{"use strict";am();Kw();os();o(pIe,"mapValues");jd=pIe});function mIe(t,e,r){for(var n=-1,i=t.length;++n{"use strict";Wd();o(mIe,"baseExtremum");Hm=mIe});function gIe(t){return t&&t.length?Hm(t,ta,ine):void 0}var $s,xne=N(()=>{"use strict";ok();ane();Lu();o(gIe,"max");$s=gIe});function yIe(t){return t&&t.length?Hm(t,ta,sk):void 0}var Nl,bR=N(()=>{"use strict";ok();xR();Lu();o(yIe,"min");Nl=yIe});function vIe(t,e){return t&&t.length?Hm(t,mn(e,2),sk):void 0}var Kd,bne=N(()=>{"use strict";ok();os();xR();o(vIe,"minBy");Kd=vIe});function bIe(t){if(typeof t!="function")throw new TypeError(xIe);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}var xIe,Tne,wne=N(()=>{"use strict";xIe="Expected a function";o(bIe,"negate");Tne=bIe});function TIe(t,e,r,n){if(!bn(t))return t;e=Jh(e,t);for(var i=-1,a=e.length,s=a-1,l=t;l!=null&&++i{"use strict";pm();I2();p2();no();Mm();o(TIe,"baseSet");kne=TIe});function wIe(t,e,r){for(var n=-1,i=e.length,a={};++n{"use strict";O2();Ene();I2();o(wIe,"basePickBy");lk=wIe});function kIe(t,e){if(t==null)return{};var r=Bs(Nw(t),function(n){return[n]});return e=mn(e),lk(t,r,function(n,i){return e(n,i[0])})}var zs,Sne=N(()=>{"use strict";qd();os();TR();KL();o(kIe,"pickBy");zs=kIe});function EIe(t,e){var r=t.length;for(t.sort(e);r--;)t[r]=t[r].value;return t}var Cne,Ane=N(()=>{"use strict";o(EIe,"baseSortBy");Cne=EIe});function SIe(t,e){if(t!==e){var r=t!==void 0,n=t===null,i=t===t,a=oo(t),s=e!==void 0,l=e===null,u=e===e,h=oo(e);if(!l&&!h&&!a&&t>e||a&&s&&u&&!l&&!h||n&&s&&u||!r&&u||!i)return 1;if(!n&&!a&&!h&&t{"use strict";Wd();o(SIe,"compareAscending");_ne=SIe});function CIe(t,e,r){for(var n=-1,i=t.criteria,a=e.criteria,s=i.length,l=r.length;++n=l)return u;var h=r[n];return u*(h=="desc"?-1:1)}}return t.index-e.index}var Lne,Rne=N(()=>{"use strict";Dne();o(CIe,"compareMultiple");Lne=CIe});function AIe(t,e,r){e.length?e=Bs(e,function(a){return Pt(a)?function(s){return ef(s,a.length===1?a[0]:a)}:a}):e=[ta];var n=-1;e=Bs(e,Bo(mn));var i=rk(t,function(a,s,l){var u=Bs(e,function(h){return h(a)});return{criteria:u,index:++n,value:a}});return Cne(i,function(a,s){return Lne(a,s,r)})}var Nne,Mne=N(()=>{"use strict";qd();O2();os();dR();Ane();Bd();Rne();Lu();Wn();o(AIe,"baseOrderBy");Nne=AIe});var _Ie,Ine,One=N(()=>{"use strict";cR();_Ie=jw("length"),Ine=_Ie});function zIe(t){for(var e=Pne.lastIndex=0;Pne.test(t);)++e;return e}var Bne,DIe,LIe,RIe,NIe,MIe,IIe,wR,kR,OIe,Fne,$ne,zne,PIe,Gne,Vne,BIe,FIe,$Ie,Pne,Une,Hne=N(()=>{"use strict";Bne="\\ud800-\\udfff",DIe="\\u0300-\\u036f",LIe="\\ufe20-\\ufe2f",RIe="\\u20d0-\\u20ff",NIe=DIe+LIe+RIe,MIe="\\ufe0e\\ufe0f",IIe="["+Bne+"]",wR="["+NIe+"]",kR="\\ud83c[\\udffb-\\udfff]",OIe="(?:"+wR+"|"+kR+")",Fne="[^"+Bne+"]",$ne="(?:\\ud83c[\\udde6-\\uddff]){2}",zne="[\\ud800-\\udbff][\\udc00-\\udfff]",PIe="\\u200d",Gne=OIe+"?",Vne="["+MIe+"]?",BIe="(?:"+PIe+"(?:"+[Fne,$ne,zne].join("|")+")"+Vne+Gne+")*",FIe=Vne+Gne+BIe,$Ie="(?:"+[Fne+wR+"?",wR,$ne,zne,IIe].join("|")+")",Pne=RegExp(kR+"(?="+kR+")|"+$Ie+FIe,"g");o(zIe,"unicodeSize");Une=zIe});function GIe(t){return tte(t)?Une(t):Ine(t)}var Wne,qne=N(()=>{"use strict";One();rte();Hne();o(GIe,"stringSize");Wne=GIe});function VIe(t,e){return lk(t,e,function(r,n){return Xw(t,n)})}var Yne,Xne=N(()=>{"use strict";TR();lR();o(VIe,"basePick");Yne=VIe});var UIe,Qd,jne=N(()=>{"use strict";Xne();ete();UIe=Jee(function(t,e){return t==null?{}:Yne(t,e)}),Qd=UIe});function qIe(t,e,r,n){for(var i=-1,a=WIe(HIe((e-t)/(r||1)),0),s=Array(a);a--;)s[n?a:++i]=t,t+=r;return s}var HIe,WIe,Kne,Qne=N(()=>{"use strict";HIe=Math.ceil,WIe=Math.max;o(qIe,"baseRange");Kne=qIe});function YIe(t){return function(e,r,n){return n&&typeof n!="number"&&io(e,r,n)&&(r=n=void 0),e=_m(e),r===void 0?(r=e,e=0):r=_m(r),n=n===void 0?e{"use strict";Qne();$d();$L();o(YIe,"createRange");Zne=YIe});var XIe,Ho,eie=N(()=>{"use strict";Jne();XIe=Zne(),Ho=XIe});function jIe(t,e,r,n,i){return i(t,function(a,s,l){r=n?(n=!1,a):e(r,a,s,l)}),r}var tie,rie=N(()=>{"use strict";o(jIe,"baseReduce");tie=jIe});function KIe(t,e,r){var n=Pt(t)?nte:tie,i=arguments.length<3;return n(t,mn(e,4),r,i,Fs)}var Xr,ER=N(()=>{"use strict";ite();rf();os();rie();Wn();o(KIe,"reduce");Xr=KIe});function QIe(t,e){var r=Pt(t)?Pm:tk;return r(t,Tne(mn(e,3)))}var sf,nie=N(()=>{"use strict";Aw();hR();os();Wn();wne();o(QIe,"reject");sf=QIe});function eOe(t){if(t==null)return 0;if(fi(t))return Ti(t)?Wne(t):t.length;var e=lo(t);return e==ZIe||e==JIe?t.size:Rm(t).length}var ZIe,JIe,SR,iie=N(()=>{"use strict";Tw();Xd();Po();nk();qne();ZIe="[object Map]",JIe="[object Set]";o(eOe,"size");SR=eOe});function tOe(t,e){var r;return Fs(t,function(n,i,a){return r=e(n,i,a),!r}),!!r}var aie,sie=N(()=>{"use strict";rf();o(tOe,"baseSome");aie=tOe});function rOe(t,e,r){var n=Pt(t)?$w:aie;return r&&io(t,e,r)&&(e=void 0),n(t,mn(e,3))}var B2,oie=N(()=>{"use strict";tR();os();sie();Wn();$d();o(rOe,"some");B2=rOe});var nOe,_c,lie=N(()=>{"use strict";Om();Mne();mm();$d();nOe=yc(function(t,e){if(t==null)return[];var r=e.length;return r>1&&io(t,e[0],e[1])?e=[]:r>2&&io(e[0],e[1],e[2])&&(e=[e[0]]),Nne(t,Cc(e,1),[])}),_c=nOe});var iOe,aOe,cie,uie=N(()=>{"use strict";QL();zL();Vw();iOe=1/0,aOe=tf&&1/zm(new tf([,-0]))[1]==iOe?function(t){return new tf(t)}:ai,cie=aOe});function oOe(t,e,r){var n=-1,i=bw,a=t.length,s=!0,l=[],u=l;if(r)s=!1,i=Zw;else if(a>=sOe){var h=e?null:cie(t);if(h)return zm(h);s=!1,i=$m,u=new Fm}else u=e?[]:l;e:for(;++n{"use strict";Fw();UL();uR();zw();uie();Vw();sOe=200;o(oOe,"baseUniq");Wm=oOe});var lOe,CR,hie=N(()=>{"use strict";Om();mm();ck();xT();lOe=yc(function(t){return Wm(Cc(t,1,Pd,!0))}),CR=lOe});function cOe(t){return t&&t.length?Wm(t):[]}var qm,fie=N(()=>{"use strict";ck();o(cOe,"uniq");qm=cOe});function uOe(t,e){return t&&t.length?Wm(t,mn(e,2)):[]}var die,pie=N(()=>{"use strict";os();ck();o(uOe,"uniqBy");die=uOe});function fOe(t){var e=++hOe;return kw(t)+e}var hOe,Zd,mie=N(()=>{"use strict";HL();hOe=0;o(fOe,"uniqueId");Zd=fOe});function dOe(t,e,r){for(var n=-1,i=t.length,a=e.length,s={};++n{"use strict";o(dOe,"baseZipObject");gie=dOe});function pOe(t,e){return gie(t||[],e||[],gc)}var uk,vie=N(()=>{"use strict";pm();yie();o(pOe,"zipObject");uk=pOe});var qt=N(()=>{"use strict";Vee();JL();qte();Yte();T9();Ore();Fre();zre();Gre();Vre();Yre();fR();Zre();ene();pR();Sw();ek();tne();rne();nne();lne();Lu();hne();fne();Wn();ak();n2();no();gne();nk();yne();Ec();$re();Um();vne();xne();E9();bR();bne();zL();Mre();jne();Sne();eie();ER();nie();iie();oie();lie();hie();fie();mie();vR();vie();});function bie(t,e){t[e]?t[e]++:t[e]=1}function Tie(t,e){--t[e]||delete t[e]}function F2(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}return i+xie+a+xie+(mr(n)?mOe:n)}function gOe(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}var l={v:i,w:a};return n&&(l.name=n),l}function AR(t,e){return F2(t,e.v,e.w,e.name)}var mOe,Jd,xie,sn,hk=N(()=>{"use strict";qt();mOe="\0",Jd="\0",xie="",sn=class{static{o(this,"Graph")}constructor(e={}){this._isDirected=Object.prototype.hasOwnProperty.call(e,"directed")?e.directed:!0,this._isMultigraph=Object.prototype.hasOwnProperty.call(e,"multigraph")?e.multigraph:!1,this._isCompound=Object.prototype.hasOwnProperty.call(e,"compound")?e.compound:!1,this._label=void 0,this._defaultNodeLabelFn=Ns(void 0),this._defaultEdgeLabelFn=Ns(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[Jd]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(e){return this._label=e,this}graph(){return this._label}setDefaultNodeLabel(e){return Ai(e)||(e=Ns(e)),this._defaultNodeLabelFn=e,this}nodeCount(){return this._nodeCount}nodes(){return zr(this._nodes)}sources(){var e=this;return Yr(this.nodes(),function(r){return hr(e._in[r])})}sinks(){var e=this;return Yr(this.nodes(),function(r){return hr(e._out[r])})}setNodes(e,r){var n=arguments,i=this;return Ae(e,function(a){n.length>1?i.setNode(a,r):i.setNode(a)}),this}setNode(e,r){return Object.prototype.hasOwnProperty.call(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=r),this):(this._nodes[e]=arguments.length>1?r:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]=Jd,this._children[e]={},this._children[Jd][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return Object.prototype.hasOwnProperty.call(this._nodes,e)}removeNode(e){if(Object.prototype.hasOwnProperty.call(this._nodes,e)){var r=o(n=>this.removeEdge(this._edgeObjs[n]),"removeEdge");delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],Ae(this.children(e),n=>{this.setParent(n)}),delete this._children[e]),Ae(zr(this._in[e]),r),delete this._in[e],delete this._preds[e],Ae(zr(this._out[e]),r),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(mr(r))r=Jd;else{r+="";for(var n=r;!mr(n);n=this.parent(n))if(n===e)throw new Error("Setting "+r+" as parent of "+e+" would create a cycle");this.setNode(r)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=r,this._children[r][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var r=this._parent[e];if(r!==Jd)return r}}children(e){if(mr(e)&&(e=Jd),this._isCompound){var r=this._children[e];if(r)return zr(r)}else{if(e===Jd)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var r=this._preds[e];if(r)return zr(r)}successors(e){var r=this._sucs[e];if(r)return zr(r)}neighbors(e){var r=this.predecessors(e);if(r)return CR(r,this.successors(e))}isLeaf(e){var r;return this.isDirected()?r=this.successors(e):r=this.neighbors(e),r.length===0}filterNodes(e){var r=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});r.setGraph(this.graph());var n=this;Ae(this._nodes,function(s,l){e(l)&&r.setNode(l,s)}),Ae(this._edgeObjs,function(s){r.hasNode(s.v)&&r.hasNode(s.w)&&r.setEdge(s,n.edge(s))});var i={};function a(s){var l=n.parent(s);return l===void 0||r.hasNode(l)?(i[s]=l,l):l in i?i[l]:a(l)}return o(a,"findParent"),this._isCompound&&Ae(r.nodes(),function(s){r.setParent(s,a(s))}),r}setDefaultEdgeLabel(e){return Ai(e)||(e=Ns(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return br(this._edgeObjs)}setPath(e,r){var n=this,i=arguments;return Xr(e,function(a,s){return i.length>1?n.setEdge(a,s,r):n.setEdge(a,s),s}),this}setEdge(){var e,r,n,i,a=!1,s=arguments[0];typeof s=="object"&&s!==null&&"v"in s?(e=s.v,r=s.w,n=s.name,arguments.length===2&&(i=arguments[1],a=!0)):(e=s,r=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],a=!0)),e=""+e,r=""+r,mr(n)||(n=""+n);var l=F2(this._isDirected,e,r,n);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,l))return a&&(this._edgeLabels[l]=i),this;if(!mr(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(r),this._edgeLabels[l]=a?i:this._defaultEdgeLabelFn(e,r,n);var u=gOe(this._isDirected,e,r,n);return e=u.v,r=u.w,Object.freeze(u),this._edgeObjs[l]=u,bie(this._preds[r],e),bie(this._sucs[e],r),this._in[r][l]=u,this._out[e][l]=u,this._edgeCount++,this}edge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n);return this._edgeLabels[i]}hasEdge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n);return Object.prototype.hasOwnProperty.call(this._edgeLabels,i)}removeEdge(e,r,n){var i=arguments.length===1?AR(this._isDirected,arguments[0]):F2(this._isDirected,e,r,n),a=this._edgeObjs[i];return a&&(e=a.v,r=a.w,delete this._edgeLabels[i],delete this._edgeObjs[i],Tie(this._preds[r],e),Tie(this._sucs[e],r),delete this._in[r][i],delete this._out[e][i],this._edgeCount--),this}inEdges(e,r){var n=this._in[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.v===r}):i}}outEdges(e,r){var n=this._out[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.w===r}):i}}nodeEdges(e,r){var n=this.inEdges(e,r);if(n)return n.concat(this.outEdges(e,r))}};sn.prototype._nodeCount=0;sn.prototype._edgeCount=0;o(bie,"incrementOrInitEntry");o(Tie,"decrementOrRemoveEntry");o(F2,"edgeArgsToId");o(gOe,"edgeArgsToObj");o(AR,"edgeObjToId")});var Wo=N(()=>{"use strict";hk()});function wie(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function yOe(t,e){if(t!=="_next"&&t!=="_prev")return e}var dk,kie=N(()=>{"use strict";dk=class{static{o(this,"List")}constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,r=e._prev;if(r!==e)return wie(r),r}enqueue(e){var r=this._sentinel;e._prev&&e._next&&wie(e),e._next=r._next,r._next._prev=e,r._next=e,e._prev=r}toString(){for(var e=[],r=this._sentinel,n=r._prev;n!==r;)e.push(JSON.stringify(n,yOe)),n=n._prev;return"["+e.join(", ")+"]"}};o(wie,"unlink");o(yOe,"filterOutLinks")});function Eie(t,e){if(t.nodeCount()<=1)return[];var r=bOe(t,e||vOe),n=xOe(r.graph,r.buckets,r.zeroIdx);return qr(Je(n,function(i){return t.outEdges(i.v,i.w)}))}function xOe(t,e,r){for(var n=[],i=e[e.length-1],a=e[0],s;t.nodeCount();){for(;s=a.dequeue();)_R(t,e,r,s);for(;s=i.dequeue();)_R(t,e,r,s);if(t.nodeCount()){for(var l=e.length-2;l>0;--l)if(s=e[l].dequeue(),s){n=n.concat(_R(t,e,r,s,!0));break}}}return n}function _R(t,e,r,n,i){var a=i?[]:void 0;return Ae(t.inEdges(n.v),function(s){var l=t.edge(s),u=t.node(s.v);i&&a.push({v:s.v,w:s.w}),u.out-=l,DR(e,r,u)}),Ae(t.outEdges(n.v),function(s){var l=t.edge(s),u=s.w,h=t.node(u);h.in-=l,DR(e,r,h)}),t.removeNode(n.v),a}function bOe(t,e){var r=new sn,n=0,i=0;Ae(t.nodes(),function(l){r.setNode(l,{v:l,in:0,out:0})}),Ae(t.edges(),function(l){var u=r.edge(l.v,l.w)||0,h=e(l),f=u+h;r.setEdge(l.v,l.w,f),i=Math.max(i,r.node(l.v).out+=h),n=Math.max(n,r.node(l.w).in+=h)});var a=Ho(i+n+3).map(function(){return new dk}),s=n+1;return Ae(r.nodes(),function(l){DR(a,s,r.node(l))}),{graph:r,buckets:a,zeroIdx:s}}function DR(t,e,r){r.out?r.in?t[r.out-r.in+e].enqueue(r):t[t.length-1].enqueue(r):t[0].enqueue(r)}var vOe,Sie=N(()=>{"use strict";qt();Wo();kie();vOe=Ns(1);o(Eie,"greedyFAS");o(xOe,"doGreedyFAS");o(_R,"removeNode");o(bOe,"buildState");o(DR,"assignBucket")});function Cie(t){var e=t.graph().acyclicer==="greedy"?Eie(t,r(t)):TOe(t);Ae(e,function(n){var i=t.edge(n);t.removeEdge(n),i.forwardName=n.name,i.reversed=!0,t.setEdge(n.w,n.v,i,Zd("rev"))});function r(n){return function(i){return n.edge(i).weight}}o(r,"weightFn")}function TOe(t){var e=[],r={},n={};function i(a){Object.prototype.hasOwnProperty.call(n,a)||(n[a]=!0,r[a]=!0,Ae(t.outEdges(a),function(s){Object.prototype.hasOwnProperty.call(r,s.w)?e.push(s):i(s.w)}),delete r[a])}return o(i,"dfs"),Ae(t.nodes(),i),e}function Aie(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.reversed){t.removeEdge(e);var n=r.forwardName;delete r.reversed,delete r.forwardName,t.setEdge(e.w,e.v,r,n)}})}var LR=N(()=>{"use strict";qt();Sie();o(Cie,"run");o(TOe,"dfsFAS");o(Aie,"undo")});function Dc(t,e,r,n){var i;do i=Zd(n);while(t.hasNode(i));return r.dummy=e,t.setNode(i,r),i}function Die(t){var e=new sn().setGraph(t.graph());return Ae(t.nodes(),function(r){e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){var n=e.edge(r.v,r.w)||{weight:0,minlen:1},i=t.edge(r);e.setEdge(r.v,r.w,{weight:n.weight+i.weight,minlen:Math.max(n.minlen,i.minlen)})}),e}function pk(t){var e=new sn({multigraph:t.isMultigraph()}).setGraph(t.graph());return Ae(t.nodes(),function(r){t.children(r).length||e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){e.setEdge(r,t.edge(r))}),e}function RR(t,e){var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2;if(!i&&!a)throw new Error("Not possible to find intersection inside of the rectangle");var u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=l*i/a,h=l):(i<0&&(s=-s),u=s,h=s*a/i),{x:r+u,y:n+h}}function of(t){var e=Je(Ho(MR(t)+1),function(){return[]});return Ae(t.nodes(),function(r){var n=t.node(r),i=n.rank;mr(i)||(e[i][n.order]=r)}),e}function Lie(t){var e=Nl(Je(t.nodes(),function(r){return t.node(r).rank}));Ae(t.nodes(),function(r){var n=t.node(r);Bt(n,"rank")&&(n.rank-=e)})}function Rie(t){var e=Nl(Je(t.nodes(),function(a){return t.node(a).rank})),r=[];Ae(t.nodes(),function(a){var s=t.node(a).rank-e;r[s]||(r[s]=[]),r[s].push(a)});var n=0,i=t.graph().nodeRankFactor;Ae(r,function(a,s){mr(a)&&s%i!==0?--n:n&&Ae(a,function(l){t.node(l).rank+=n})})}function NR(t,e,r,n){var i={width:0,height:0};return arguments.length>=4&&(i.rank=r,i.order=n),Dc(t,"border",i,e)}function MR(t){return $s(Je(t.nodes(),function(e){var r=t.node(e).rank;if(!mr(r))return r}))}function Nie(t,e){var r={lhs:[],rhs:[]};return Ae(t,function(n){e(n)?r.lhs.push(n):r.rhs.push(n)}),r}function Mie(t,e){var r=Qw();try{return e()}finally{console.log(t+" time: "+(Qw()-r)+"ms")}}function Iie(t,e){return e()}var Lc=N(()=>{"use strict";qt();Wo();o(Dc,"addDummyNode");o(Die,"simplify");o(pk,"asNonCompoundGraph");o(RR,"intersectRect");o(of,"buildLayerMatrix");o(Lie,"normalizeRanks");o(Rie,"removeEmptyRanks");o(NR,"addBorderNode");o(MR,"maxRank");o(Nie,"partition");o(Mie,"time");o(Iie,"notime")});function Pie(t){function e(r){var n=t.children(r),i=t.node(r);if(n.length&&Ae(n,e),Object.prototype.hasOwnProperty.call(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var a=i.minRank,s=i.maxRank+1;a{"use strict";qt();Lc();o(Pie,"addBorderSegments");o(Oie,"addBorderNode")});function $ie(t){var e=t.graph().rankdir.toLowerCase();(e==="lr"||e==="rl")&&Gie(t)}function zie(t){var e=t.graph().rankdir.toLowerCase();(e==="bt"||e==="rl")&&wOe(t),(e==="lr"||e==="rl")&&(kOe(t),Gie(t))}function Gie(t){Ae(t.nodes(),function(e){Fie(t.node(e))}),Ae(t.edges(),function(e){Fie(t.edge(e))})}function Fie(t){var e=t.width;t.width=t.height,t.height=e}function wOe(t){Ae(t.nodes(),function(e){IR(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,IR),Object.prototype.hasOwnProperty.call(r,"y")&&IR(r)})}function IR(t){t.y=-t.y}function kOe(t){Ae(t.nodes(),function(e){OR(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,OR),Object.prototype.hasOwnProperty.call(r,"x")&&OR(r)})}function OR(t){var e=t.x;t.x=t.y,t.y=e}var Vie=N(()=>{"use strict";qt();o($ie,"adjust");o(zie,"undo");o(Gie,"swapWidthHeight");o(Fie,"swapWidthHeightOne");o(wOe,"reverseY");o(IR,"reverseYOne");o(kOe,"swapXY");o(OR,"swapXYOne")});function Uie(t){t.graph().dummyChains=[],Ae(t.edges(),function(e){SOe(t,e)})}function SOe(t,e){var r=e.v,n=t.node(r).rank,i=e.w,a=t.node(i).rank,s=e.name,l=t.edge(e),u=l.labelRank;if(a!==n+1){t.removeEdge(e);var h=void 0,f,d;for(d=0,++n;n{"use strict";qt();Lc();o(Uie,"run");o(SOe,"normalizeEdge");o(Hie,"undo")});function $2(t){var e={};function r(n){var i=t.node(n);if(Object.prototype.hasOwnProperty.call(e,n))return i.rank;e[n]=!0;var a=Nl(Je(t.outEdges(n),function(s){return r(s.w)-t.edge(s).minlen}));return(a===Number.POSITIVE_INFINITY||a===void 0||a===null)&&(a=0),i.rank=a}o(r,"dfs"),Ae(t.sources(),r)}function ep(t,e){return t.node(e.w).rank-t.node(e.v).rank-t.edge(e).minlen}var mk=N(()=>{"use strict";qt();o($2,"longestPath");o(ep,"slack")});function gk(t){var e=new sn({directed:!1}),r=t.nodes()[0],n=t.nodeCount();e.setNode(r,{});for(var i,a;COe(e,t){"use strict";qt();Wo();mk();o(gk,"feasibleTree");o(COe,"tightTree");o(AOe,"findMinSlackEdge");o(_Oe,"shiftRanks")});var qie=N(()=>{"use strict"});var FR=N(()=>{"use strict"});var eXt,$R=N(()=>{"use strict";qt();FR();eXt=Ns(1)});var Yie=N(()=>{"use strict";$R()});var zR=N(()=>{"use strict"});var Xie=N(()=>{"use strict";zR()});var hXt,jie=N(()=>{"use strict";qt();hXt=Ns(1)});function GR(t){var e={},r={},n=[];function i(a){if(Object.prototype.hasOwnProperty.call(r,a))throw new z2;Object.prototype.hasOwnProperty.call(e,a)||(r[a]=!0,e[a]=!0,Ae(t.predecessors(a),i),delete r[a],n.push(a))}if(o(i,"visit"),Ae(t.sinks(),i),SR(e)!==t.nodeCount())throw new z2;return n}function z2(){}var VR=N(()=>{"use strict";qt();GR.CycleException=z2;o(GR,"topsort");o(z2,"CycleException");z2.prototype=new Error});var Kie=N(()=>{"use strict";VR()});function yk(t,e,r){Pt(e)||(e=[e]);var n=(t.isDirected()?t.successors:t.neighbors).bind(t),i=[],a={};return Ae(e,function(s){if(!t.hasNode(s))throw new Error("Graph does not have node: "+s);Qie(t,s,r==="post",a,n,i)}),i}function Qie(t,e,r,n,i,a){Object.prototype.hasOwnProperty.call(n,e)||(n[e]=!0,r||a.push(e),Ae(i(e),function(s){Qie(t,s,r,n,i,a)}),r&&a.push(e))}var UR=N(()=>{"use strict";qt();o(yk,"dfs");o(Qie,"doDfs")});function HR(t,e){return yk(t,e,"post")}var Zie=N(()=>{"use strict";UR();o(HR,"postorder")});function WR(t,e){return yk(t,e,"pre")}var Jie=N(()=>{"use strict";UR();o(WR,"preorder")});var eae=N(()=>{"use strict";FR();hk()});var tae=N(()=>{"use strict";qie();$R();Yie();Xie();jie();Kie();Zie();Jie();eae();zR();VR()});function cf(t){t=Die(t),$2(t);var e=gk(t);YR(e),qR(e,t);for(var r,n;r=aae(e);)n=sae(e,t,r),oae(e,t,r,n)}function qR(t,e){var r=HR(t,t.nodes());r=r.slice(0,r.length-1),Ae(r,function(n){MOe(t,e,n)})}function MOe(t,e,r){var n=t.node(r),i=n.parent;t.edge(r,i).cutvalue=nae(t,e,r)}function nae(t,e,r){var n=t.node(r),i=n.parent,a=!0,s=e.edge(r,i),l=0;return s||(a=!1,s=e.edge(i,r)),l=s.weight,Ae(e.nodeEdges(r),function(u){var h=u.v===r,f=h?u.w:u.v;if(f!==i){var d=h===a,p=e.edge(u).weight;if(l+=d?p:-p,OOe(t,r,f)){var m=t.edge(r,f).cutvalue;l+=d?-m:m}}}),l}function YR(t,e){arguments.length<2&&(e=t.nodes()[0]),iae(t,{},1,e)}function iae(t,e,r,n,i){var a=r,s=t.node(n);return e[n]=!0,Ae(t.neighbors(n),function(l){Object.prototype.hasOwnProperty.call(e,l)||(r=iae(t,e,r,l,n))}),s.low=a,s.lim=r++,i?s.parent=i:delete s.parent,r}function aae(t){return ls(t.edges(),function(e){return t.edge(e).cutvalue<0})}function sae(t,e,r){var n=r.v,i=r.w;e.hasEdge(n,i)||(n=r.w,i=r.v);var a=t.node(n),s=t.node(i),l=a,u=!1;a.lim>s.lim&&(l=s,u=!0);var h=Yr(e.edges(),function(f){return u===rae(t,t.node(f.v),l)&&u!==rae(t,t.node(f.w),l)});return Kd(h,function(f){return ep(e,f)})}function oae(t,e,r,n){var i=r.v,a=r.w;t.removeEdge(i,a),t.setEdge(n.v,n.w,{}),YR(t),qR(t,e),IOe(t,e)}function IOe(t,e){var r=ls(t.nodes(),function(i){return!e.node(i).parent}),n=WR(t,r);n=n.slice(1),Ae(n,function(i){var a=t.node(i).parent,s=e.edge(i,a),l=!1;s||(s=e.edge(a,i),l=!0),e.node(i).rank=e.node(a).rank+(l?s.minlen:-s.minlen)})}function OOe(t,e,r){return t.hasEdge(e,r)}function rae(t,e,r){return r.low<=e.lim&&e.lim<=r.lim}var lae=N(()=>{"use strict";qt();tae();Lc();BR();mk();cf.initLowLimValues=YR;cf.initCutValues=qR;cf.calcCutValue=nae;cf.leaveEdge=aae;cf.enterEdge=sae;cf.exchangeEdges=oae;o(cf,"networkSimplex");o(qR,"initCutValues");o(MOe,"assignCutValue");o(nae,"calcCutValue");o(YR,"initLowLimValues");o(iae,"dfsAssignLowLim");o(aae,"leaveEdge");o(sae,"enterEdge");o(oae,"exchangeEdges");o(IOe,"updateRanks");o(OOe,"isTreeEdge");o(rae,"isDescendant")});function XR(t){switch(t.graph().ranker){case"network-simplex":cae(t);break;case"tight-tree":BOe(t);break;case"longest-path":POe(t);break;default:cae(t)}}function BOe(t){$2(t),gk(t)}function cae(t){cf(t)}var POe,jR=N(()=>{"use strict";BR();lae();mk();o(XR,"rank");POe=$2;o(BOe,"tightTreeRanker");o(cae,"networkSimplexRanker")});function uae(t){var e=Dc(t,"root",{},"_root"),r=FOe(t),n=$s(br(r))-1,i=2*n+1;t.graph().nestingRoot=e,Ae(t.edges(),function(s){t.edge(s).minlen*=i});var a=$Oe(t)+1;Ae(t.children(),function(s){hae(t,e,i,a,n,r,s)}),t.graph().nodeRankFactor=i}function hae(t,e,r,n,i,a,s){var l=t.children(s);if(!l.length){s!==e&&t.setEdge(e,s,{weight:0,minlen:r});return}var u=NR(t,"_bt"),h=NR(t,"_bb"),f=t.node(s);t.setParent(u,s),f.borderTop=u,t.setParent(h,s),f.borderBottom=h,Ae(l,function(d){hae(t,e,r,n,i,a,d);var p=t.node(d),m=p.borderTop?p.borderTop:d,g=p.borderBottom?p.borderBottom:d,y=p.borderTop?n:2*n,v=m!==g?1:i-a[s]+1;t.setEdge(u,m,{weight:y,minlen:v,nestingEdge:!0}),t.setEdge(g,h,{weight:y,minlen:v,nestingEdge:!0})}),t.parent(s)||t.setEdge(e,u,{weight:0,minlen:i+a[s]})}function FOe(t){var e={};function r(n,i){var a=t.children(n);a&&a.length&&Ae(a,function(s){r(s,i+1)}),e[n]=i}return o(r,"dfs"),Ae(t.children(),function(n){r(n,1)}),e}function $Oe(t){return Xr(t.edges(),function(e,r){return e+t.edge(r).weight},0)}function fae(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,Ae(t.edges(),function(r){var n=t.edge(r);n.nestingEdge&&t.removeEdge(r)})}var dae=N(()=>{"use strict";qt();Lc();o(uae,"run");o(hae,"dfs");o(FOe,"treeDepths");o($Oe,"sumWeights");o(fae,"cleanup")});function pae(t,e,r){var n={},i;Ae(r,function(a){for(var s=t.parent(a),l,u;s;){if(l=t.parent(s),l?(u=n[l],n[l]=s):(u=i,i=s),u&&u!==s){e.setEdge(u,s);return}s=l}})}var mae=N(()=>{"use strict";qt();o(pae,"addSubgraphConstraints")});function gae(t,e,r){var n=GOe(t),i=new sn({compound:!0}).setGraph({root:n}).setDefaultNodeLabel(function(a){return t.node(a)});return Ae(t.nodes(),function(a){var s=t.node(a),l=t.parent(a);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(i.setNode(a),i.setParent(a,l||n),Ae(t[r](a),function(u){var h=u.v===a?u.w:u.v,f=i.edge(h,a),d=mr(f)?0:f.weight;i.setEdge(h,a,{weight:t.edge(u).weight+d})}),Object.prototype.hasOwnProperty.call(s,"minRank")&&i.setNode(a,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))}),i}function GOe(t){for(var e;t.hasNode(e=Zd("_root")););return e}var yae=N(()=>{"use strict";qt();Wo();o(gae,"buildLayerGraph");o(GOe,"createRootNode")});function vae(t,e){for(var r=0,n=1;n0;)f%2&&(d+=l[f+1]),f=f-1>>1,l[f]+=h.weight;u+=h.weight*d})),u}var xae=N(()=>{"use strict";qt();o(vae,"crossCount");o(VOe,"twoLayerCrossCount")});function bae(t){var e={},r=Yr(t.nodes(),function(l){return!t.children(l).length}),n=$s(Je(r,function(l){return t.node(l).rank})),i=Je(Ho(n+1),function(){return[]});function a(l){if(!Bt(e,l)){e[l]=!0;var u=t.node(l);i[u.rank].push(l),Ae(t.successors(l),a)}}o(a,"dfs");var s=_c(r,function(l){return t.node(l).rank});return Ae(s,a),i}var Tae=N(()=>{"use strict";qt();o(bae,"initOrder")});function wae(t,e){return Je(e,function(r){var n=t.inEdges(r);if(n.length){var i=Xr(n,function(a,s){var l=t.edge(s),u=t.node(s.v);return{sum:a.sum+l.weight*u.order,weight:a.weight+l.weight}},{sum:0,weight:0});return{v:r,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:r}})}var kae=N(()=>{"use strict";qt();o(wae,"barycenter")});function Eae(t,e){var r={};Ae(t,function(i,a){var s=r[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:a};mr(i.barycenter)||(s.barycenter=i.barycenter,s.weight=i.weight)}),Ae(e.edges(),function(i){var a=r[i.v],s=r[i.w];!mr(a)&&!mr(s)&&(s.indegree++,a.out.push(r[i.w]))});var n=Yr(r,function(i){return!i.indegree});return UOe(n)}function UOe(t){var e=[];function r(a){return function(s){s.merged||(mr(s.barycenter)||mr(a.barycenter)||s.barycenter>=a.barycenter)&&HOe(a,s)}}o(r,"handleIn");function n(a){return function(s){s.in.push(a),--s.indegree===0&&t.push(s)}}for(o(n,"handleOut");t.length;){var i=t.pop();e.push(i),Ae(i.in.reverse(),r(i)),Ae(i.out,n(i))}return Je(Yr(e,function(a){return!a.merged}),function(a){return Qd(a,["vs","i","barycenter","weight"])})}function HOe(t,e){var r=0,n=0;t.weight&&(r+=t.barycenter*t.weight,n+=t.weight),e.weight&&(r+=e.barycenter*e.weight,n+=e.weight),t.vs=e.vs.concat(t.vs),t.barycenter=r/n,t.weight=n,t.i=Math.min(e.i,t.i),e.merged=!0}var Sae=N(()=>{"use strict";qt();o(Eae,"resolveConflicts");o(UOe,"doResolveConflicts");o(HOe,"mergeEntries")});function Aae(t,e){var r=Nie(t,function(f){return Object.prototype.hasOwnProperty.call(f,"barycenter")}),n=r.lhs,i=_c(r.rhs,function(f){return-f.i}),a=[],s=0,l=0,u=0;n.sort(WOe(!!e)),u=Cae(a,i,u),Ae(n,function(f){u+=f.vs.length,a.push(f.vs),s+=f.barycenter*f.weight,l+=f.weight,u=Cae(a,i,u)});var h={vs:qr(a)};return l&&(h.barycenter=s/l,h.weight=l),h}function Cae(t,e,r){for(var n;e.length&&(n=ma(e)).i<=r;)e.pop(),t.push(n.vs),r++;return r}function WOe(t){return function(e,r){return e.barycenterr.barycenter?1:t?r.i-e.i:e.i-r.i}}var _ae=N(()=>{"use strict";qt();Lc();o(Aae,"sort");o(Cae,"consumeUnsortable");o(WOe,"compareWithBias")});function KR(t,e,r,n){var i=t.children(e),a=t.node(e),s=a?a.borderLeft:void 0,l=a?a.borderRight:void 0,u={};s&&(i=Yr(i,function(g){return g!==s&&g!==l}));var h=wae(t,i);Ae(h,function(g){if(t.children(g.v).length){var y=KR(t,g.v,r,n);u[g.v]=y,Object.prototype.hasOwnProperty.call(y,"barycenter")&&YOe(g,y)}});var f=Eae(h,r);qOe(f,u);var d=Aae(f,n);if(s&&(d.vs=qr([s,d.vs,l]),t.predecessors(s).length)){var p=t.node(t.predecessors(s)[0]),m=t.node(t.predecessors(l)[0]);Object.prototype.hasOwnProperty.call(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+p.order+m.order)/(d.weight+2),d.weight+=2}return d}function qOe(t,e){Ae(t,function(r){r.vs=qr(r.vs.map(function(n){return e[n]?e[n].vs:n}))})}function YOe(t,e){mr(t.barycenter)?(t.barycenter=e.barycenter,t.weight=e.weight):(t.barycenter=(t.barycenter*t.weight+e.barycenter*e.weight)/(t.weight+e.weight),t.weight+=e.weight)}var Dae=N(()=>{"use strict";qt();kae();Sae();_ae();o(KR,"sortSubgraph");o(qOe,"expandSubgraphs");o(YOe,"mergeBarycenters")});function Nae(t){var e=MR(t),r=Lae(t,Ho(1,e+1),"inEdges"),n=Lae(t,Ho(e-1,-1,-1),"outEdges"),i=bae(t);Rae(t,i);for(var a=Number.POSITIVE_INFINITY,s,l=0,u=0;u<4;++l,++u){XOe(l%2?r:n,l%4>=2),i=of(t);var h=vae(t,i);h{"use strict";qt();Wo();Lc();mae();yae();xae();Tae();Dae();o(Nae,"order");o(Lae,"buildLayerGraphs");o(XOe,"sweepLayerGraphs");o(Rae,"assignOrder")});function Iae(t){var e=KOe(t);Ae(t.graph().dummyChains,function(r){for(var n=t.node(r),i=n.edgeObj,a=jOe(t,e,i.v,i.w),s=a.path,l=a.lca,u=0,h=s[u],f=!0;r!==i.w;){if(n=t.node(r),f){for(;(h=s[u])!==l&&t.node(h).maxRanks||l>e[u].lim));for(h=u,u=n;(u=t.parent(u))!==h;)a.push(u);return{path:i.concat(a.reverse()),lca:h}}function KOe(t){var e={},r=0;function n(i){var a=r;Ae(t.children(i),n),e[i]={low:a,lim:r++}}return o(n,"dfs"),Ae(t.children(),n),e}var Oae=N(()=>{"use strict";qt();o(Iae,"parentDummyChains");o(jOe,"findPath");o(KOe,"postorder")});function QOe(t,e){var r={};function n(i,a){var s=0,l=0,u=i.length,h=ma(a);return Ae(a,function(f,d){var p=JOe(t,f),m=p?t.node(p).order:u;(p||f===h)&&(Ae(a.slice(l,d+1),function(g){Ae(t.predecessors(g),function(y){var v=t.node(y),x=v.order;(xh)&&Pae(r,p,f)})})}o(n,"scan");function i(a,s){var l=-1,u,h=0;return Ae(s,function(f,d){if(t.node(f).dummy==="border"){var p=t.predecessors(f);p.length&&(u=t.node(p[0]).order,n(s,h,d,l,u),h=d,l=u)}n(s,h,s.length,u,a.length)}),s}return o(i,"visitLayer"),Xr(e,i),r}function JOe(t,e){if(t.node(e).dummy)return ls(t.predecessors(e),function(r){return t.node(r).dummy})}function Pae(t,e,r){if(e>r){var n=e;e=r,r=n}var i=t[e];i||(t[e]=i={}),i[r]=!0}function ePe(t,e,r){if(e>r){var n=e;e=r,r=n}return!!t[e]&&Object.prototype.hasOwnProperty.call(t[e],r)}function tPe(t,e,r,n){var i={},a={},s={};return Ae(e,function(l){Ae(l,function(u,h){i[u]=u,a[u]=u,s[u]=h})}),Ae(e,function(l){var u=-1;Ae(l,function(h){var f=n(h);if(f.length){f=_c(f,function(y){return s[y]});for(var d=(f.length-1)/2,p=Math.floor(d),m=Math.ceil(d);p<=m;++p){var g=f[p];a[h]===h&&u{"use strict";qt();Wo();Lc();o(QOe,"findType1Conflicts");o(ZOe,"findType2Conflicts");o(JOe,"findOtherInnerSegmentNode");o(Pae,"addConflict");o(ePe,"hasConflict");o(tPe,"verticalAlignment");o(rPe,"horizontalCompaction");o(nPe,"buildBlockGraph");o(iPe,"findSmallestWidthAlignment");o(aPe,"alignCoordinates");o(sPe,"balance");o(Bae,"positionX");o(oPe,"sep");o(lPe,"width")});function $ae(t){t=pk(t),cPe(t),gR(Bae(t),function(e,r){t.node(r).x=e})}function cPe(t){var e=of(t),r=t.graph().ranksep,n=0;Ae(e,function(i){var a=$s(Je(i,function(s){return t.node(s).height}));Ae(i,function(s){t.node(s).y=n+a/2}),n+=a+r})}var zae=N(()=>{"use strict";qt();Lc();Fae();o($ae,"position");o(cPe,"positionY")});function G2(t,e){var r=e&&e.debugTiming?Mie:Iie;r("layout",()=>{var n=r(" buildLayoutGraph",()=>bPe(t));r(" runLayout",()=>uPe(n,r)),r(" updateInputGraph",()=>hPe(t,n))})}function uPe(t,e){e(" makeSpaceForEdgeLabels",()=>TPe(t)),e(" removeSelfEdges",()=>LPe(t)),e(" acyclic",()=>Cie(t)),e(" nestingGraph.run",()=>uae(t)),e(" rank",()=>XR(pk(t))),e(" injectEdgeLabelProxies",()=>wPe(t)),e(" removeEmptyRanks",()=>Rie(t)),e(" nestingGraph.cleanup",()=>fae(t)),e(" normalizeRanks",()=>Lie(t)),e(" assignRankMinMax",()=>kPe(t)),e(" removeEdgeLabelProxies",()=>EPe(t)),e(" normalize.run",()=>Uie(t)),e(" parentDummyChains",()=>Iae(t)),e(" addBorderSegments",()=>Pie(t)),e(" order",()=>Nae(t)),e(" insertSelfEdges",()=>RPe(t)),e(" adjustCoordinateSystem",()=>$ie(t)),e(" position",()=>$ae(t)),e(" positionSelfEdges",()=>NPe(t)),e(" removeBorderNodes",()=>DPe(t)),e(" normalize.undo",()=>Hie(t)),e(" fixupEdgeLabelCoords",()=>APe(t)),e(" undoCoordinateSystem",()=>zie(t)),e(" translateGraph",()=>SPe(t)),e(" assignNodeIntersects",()=>CPe(t)),e(" reversePoints",()=>_Pe(t)),e(" acyclic.undo",()=>Aie(t))}function hPe(t,e){Ae(t.nodes(),function(r){var n=t.node(r),i=e.node(r);n&&(n.x=i.x,n.y=i.y,e.children(r).length&&(n.width=i.width,n.height=i.height))}),Ae(t.edges(),function(r){var n=t.edge(r),i=e.edge(r);n.points=i.points,Object.prototype.hasOwnProperty.call(i,"x")&&(n.x=i.x,n.y=i.y)}),t.graph().width=e.graph().width,t.graph().height=e.graph().height}function bPe(t){var e=new sn({multigraph:!0,compound:!0}),r=ZR(t.graph());return e.setGraph(Hh({},dPe,QR(r,fPe),Qd(r,pPe))),Ae(t.nodes(),function(n){var i=ZR(t.node(n));e.setNode(n,nf(QR(i,mPe),gPe)),e.setParent(n,t.parent(n))}),Ae(t.edges(),function(n){var i=ZR(t.edge(n));e.setEdge(n,Hh({},vPe,QR(i,yPe),Qd(i,xPe)))}),e}function TPe(t){var e=t.graph();e.ranksep/=2,Ae(t.edges(),function(r){var n=t.edge(r);n.minlen*=2,n.labelpos.toLowerCase()!=="c"&&(e.rankdir==="TB"||e.rankdir==="BT"?n.width+=n.labeloffset:n.height+=n.labeloffset)})}function wPe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.width&&r.height){var n=t.node(e.v),i=t.node(e.w),a={rank:(i.rank-n.rank)/2+n.rank,e};Dc(t,"edge-proxy",a,"_ep")}})}function kPe(t){var e=0;Ae(t.nodes(),function(r){var n=t.node(r);n.borderTop&&(n.minRank=t.node(n.borderTop).rank,n.maxRank=t.node(n.borderBottom).rank,e=$s(e,n.maxRank))}),t.graph().maxRank=e}function EPe(t){Ae(t.nodes(),function(e){var r=t.node(e);r.dummy==="edge-proxy"&&(t.edge(r.e).labelRank=r.rank,t.removeNode(e))})}function SPe(t){var e=Number.POSITIVE_INFINITY,r=0,n=Number.POSITIVE_INFINITY,i=0,a=t.graph(),s=a.marginx||0,l=a.marginy||0;function u(h){var f=h.x,d=h.y,p=h.width,m=h.height;e=Math.min(e,f-p/2),r=Math.max(r,f+p/2),n=Math.min(n,d-m/2),i=Math.max(i,d+m/2)}o(u,"getExtremes"),Ae(t.nodes(),function(h){u(t.node(h))}),Ae(t.edges(),function(h){var f=t.edge(h);Object.prototype.hasOwnProperty.call(f,"x")&&u(f)}),e-=s,n-=l,Ae(t.nodes(),function(h){var f=t.node(h);f.x-=e,f.y-=n}),Ae(t.edges(),function(h){var f=t.edge(h);Ae(f.points,function(d){d.x-=e,d.y-=n}),Object.prototype.hasOwnProperty.call(f,"x")&&(f.x-=e),Object.prototype.hasOwnProperty.call(f,"y")&&(f.y-=n)}),a.width=r-e+s,a.height=i-n+l}function CPe(t){Ae(t.edges(),function(e){var r=t.edge(e),n=t.node(e.v),i=t.node(e.w),a,s;r.points?(a=r.points[0],s=r.points[r.points.length-1]):(r.points=[],a=i,s=n),r.points.unshift(RR(n,a)),r.points.push(RR(i,s))})}function APe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(Object.prototype.hasOwnProperty.call(r,"x"))switch((r.labelpos==="l"||r.labelpos==="r")&&(r.width-=r.labeloffset),r.labelpos){case"l":r.x-=r.width/2+r.labeloffset;break;case"r":r.x+=r.width/2+r.labeloffset;break}})}function _Pe(t){Ae(t.edges(),function(e){var r=t.edge(e);r.reversed&&r.points.reverse()})}function DPe(t){Ae(t.nodes(),function(e){if(t.children(e).length){var r=t.node(e),n=t.node(r.borderTop),i=t.node(r.borderBottom),a=t.node(ma(r.borderLeft)),s=t.node(ma(r.borderRight));r.width=Math.abs(s.x-a.x),r.height=Math.abs(i.y-n.y),r.x=a.x+r.width/2,r.y=n.y+r.height/2}}),Ae(t.nodes(),function(e){t.node(e).dummy==="border"&&t.removeNode(e)})}function LPe(t){Ae(t.edges(),function(e){if(e.v===e.w){var r=t.node(e.v);r.selfEdges||(r.selfEdges=[]),r.selfEdges.push({e,label:t.edge(e)}),t.removeEdge(e)}})}function RPe(t){var e=of(t);Ae(e,function(r){var n=0;Ae(r,function(i,a){var s=t.node(i);s.order=a+n,Ae(s.selfEdges,function(l){Dc(t,"selfedge",{width:l.label.width,height:l.label.height,rank:s.rank,order:a+ ++n,e:l.e,label:l.label},"_se")}),delete s.selfEdges})})}function NPe(t){Ae(t.nodes(),function(e){var r=t.node(e);if(r.dummy==="selfedge"){var n=t.node(r.e.v),i=n.x+n.width/2,a=n.y,s=r.x-i,l=n.height/2;t.setEdge(r.e,r.label),t.removeNode(e),r.label.points=[{x:i+2*s/3,y:a-l},{x:i+5*s/6,y:a-l},{x:i+s,y:a},{x:i+5*s/6,y:a+l},{x:i+2*s/3,y:a+l}],r.label.x=r.x,r.label.y=r.y}})}function QR(t,e){return jd(Qd(t,e),Number)}function ZR(t){var e={};return Ae(t,function(r,n){e[n.toLowerCase()]=r}),e}var fPe,dPe,pPe,mPe,gPe,yPe,vPe,xPe,Gae=N(()=>{"use strict";qt();Wo();Bie();Vie();LR();PR();jR();dae();Mae();Oae();zae();Lc();o(G2,"layout");o(uPe,"runLayout");o(hPe,"updateInputGraph");fPe=["nodesep","edgesep","ranksep","marginx","marginy"],dPe={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},pPe=["acyclicer","ranker","rankdir","align"],mPe=["width","height"],gPe={width:0,height:0},yPe=["minlen","weight","width","height","labeloffset"],vPe={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},xPe=["labelpos"];o(bPe,"buildLayoutGraph");o(TPe,"makeSpaceForEdgeLabels");o(wPe,"injectEdgeLabelProxies");o(kPe,"assignRankMinMax");o(EPe,"removeEdgeLabelProxies");o(SPe,"translateGraph");o(CPe,"assignNodeIntersects");o(APe,"fixupEdgeLabelCoords");o(_Pe,"reversePointsForReversedEdges");o(DPe,"removeBorderNodes");o(LPe,"removeSelfEdges");o(RPe,"insertSelfEdges");o(NPe,"positionSelfEdges");o(QR,"selectNumberAttrs");o(ZR,"canonicalize")});var JR=N(()=>{"use strict";LR();Gae();PR();jR()});function qo(t){var e={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:MPe(t),edges:IPe(t)};return mr(t.graph())||(e.value=an(t.graph())),e}function MPe(t){return Je(t.nodes(),function(e){var r=t.node(e),n=t.parent(e),i={v:e};return mr(r)||(i.value=r),mr(n)||(i.parent=n),i})}function IPe(t){return Je(t.edges(),function(e){var r=t.edge(e),n={v:e.v,w:e.w};return mr(e.name)||(n.name=e.name),mr(r)||(n.value=r),n})}var eN=N(()=>{"use strict";qt();hk();o(qo,"write");o(MPe,"writeNodes");o(IPe,"writeEdges")});var Tr,tp,Hae,Wae,vk,OPe,qae,Yae,PPe,Ym,Uae,Xae,jae,Kae,Qae,Zae=N(()=>{"use strict";yt();Wo();eN();Tr=new Map,tp=new Map,Hae=new Map,Wae=o(()=>{tp.clear(),Hae.clear(),Tr.clear()},"clear"),vk=o((t,e)=>{let r=tp.get(e)||[];return X.trace("In isDescendant",e," ",t," = ",r.includes(t)),r.includes(t)},"isDescendant"),OPe=o((t,e)=>{let r=tp.get(e)||[];return X.info("Descendants of ",e," is ",r),X.info("Edge is ",t),t.v===e||t.w===e?!1:r?r.includes(t.v)||vk(t.v,e)||vk(t.w,e)||r.includes(t.w):(X.debug("Tilt, ",e,",not in descendants"),!1)},"edgeInCluster"),qae=o((t,e,r,n)=>{X.warn("Copying children of ",t,"root",n,"data",e.node(t),n);let i=e.children(t)||[];t!==n&&i.push(t),X.warn("Copying (nodes) clusterId",t,"nodes",i),i.forEach(a=>{if(e.children(a).length>0)qae(a,e,r,n);else{let s=e.node(a);X.info("cp ",a," to ",n," with parent ",t),r.setNode(a,s),n!==e.parent(a)&&(X.warn("Setting parent",a,e.parent(a)),r.setParent(a,e.parent(a))),t!==n&&a!==t?(X.debug("Setting parent",a,t),r.setParent(a,t)):(X.info("In copy ",t,"root",n,"data",e.node(t),n),X.debug("Not Setting parent for node=",a,"cluster!==rootId",t!==n,"node!==clusterId",a!==t));let l=e.edges(a);X.debug("Copying Edges",l),l.forEach(u=>{X.info("Edge",u);let h=e.edge(u.v,u.w,u.name);X.info("Edge data",h,n);try{OPe(u,n)?(X.info("Copying as ",u.v,u.w,h,u.name),r.setEdge(u.v,u.w,h,u.name),X.info("newGraph edges ",r.edges(),r.edge(r.edges()[0]))):X.info("Skipping copy of edge ",u.v,"-->",u.w," rootId: ",n," clusterId:",t)}catch(f){X.error(f)}})}X.debug("Removing node",a),e.removeNode(a)})},"copy"),Yae=o((t,e)=>{let r=e.children(t),n=[...r];for(let i of r)Hae.set(i,t),n=[...n,...Yae(i,e)];return n},"extractDescendants"),PPe=o((t,e,r)=>{let n=t.edges().filter(u=>u.v===e||u.w===e),i=t.edges().filter(u=>u.v===r||u.w===r),a=n.map(u=>({v:u.v===e?r:u.v,w:u.w===e?e:u.w})),s=i.map(u=>({v:u.v,w:u.w}));return a.filter(u=>s.some(h=>u.v===h.v&&u.w===h.w))},"findCommonEdges"),Ym=o((t,e,r)=>{let n=e.children(t);if(X.trace("Searching children of id ",t,n),n.length<1)return t;let i;for(let a of n){let s=Ym(a,e,r),l=PPe(e,r,s);if(s)if(l.length>0)i=s;else return s}return i},"findNonClusterChild"),Uae=o(t=>!Tr.has(t)||!Tr.get(t).externalConnections?t:Tr.has(t)?Tr.get(t).id:t,"getAnchorId"),Xae=o((t,e)=>{if(!t||e>10){X.debug("Opting out, no graph ");return}else X.debug("Opting in, graph ");t.nodes().forEach(function(r){t.children(r).length>0&&(X.warn("Cluster identified",r," Replacement id in edges: ",Ym(r,t,r)),tp.set(r,Yae(r,t)),Tr.set(r,{id:Ym(r,t,r),clusterData:t.node(r)}))}),t.nodes().forEach(function(r){let n=t.children(r),i=t.edges();n.length>0?(X.debug("Cluster identified",r,tp),i.forEach(a=>{let s=vk(a.v,r),l=vk(a.w,r);s^l&&(X.warn("Edge: ",a," leaves cluster ",r),X.warn("Descendants of XXX ",r,": ",tp.get(r)),Tr.get(r).externalConnections=!0)})):X.debug("Not a cluster ",r,tp)});for(let r of Tr.keys()){let n=Tr.get(r).id,i=t.parent(n);i!==r&&Tr.has(i)&&!Tr.get(i).externalConnections&&(Tr.get(r).id=i)}t.edges().forEach(function(r){let n=t.edge(r);X.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(r)),X.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(t.edge(r)));let i=r.v,a=r.w;if(X.warn("Fix XXX",Tr,"ids:",r.v,r.w,"Translating: ",Tr.get(r.v)," --- ",Tr.get(r.w)),Tr.get(r.v)||Tr.get(r.w)){if(X.warn("Fixing and trying - removing XXX",r.v,r.w,r.name),i=Uae(r.v),a=Uae(r.w),t.removeEdge(r.v,r.w,r.name),i!==r.v){let s=t.parent(i);Tr.get(s).externalConnections=!0,n.fromCluster=r.v}if(a!==r.w){let s=t.parent(a);Tr.get(s).externalConnections=!0,n.toCluster=r.w}X.warn("Fix Replacing with XXX",i,a,r.name),t.setEdge(i,a,n,r.name)}}),X.warn("Adjusted Graph",qo(t)),jae(t,0),X.trace(Tr)},"adjustClustersAndEdges"),jae=o((t,e)=>{if(X.warn("extractor - ",e,qo(t),t.children("D")),e>10){X.error("Bailing out");return}let r=t.nodes(),n=!1;for(let i of r){let a=t.children(i);n=n||a.length>0}if(!n){X.debug("Done, no node has children",t.nodes());return}X.debug("Nodes = ",r,e);for(let i of r)if(X.debug("Extracting node",i,Tr,Tr.has(i)&&!Tr.get(i).externalConnections,!t.parent(i),t.node(i),t.children("D")," Depth ",e),!Tr.has(i))X.debug("Not a cluster",i,e);else if(!Tr.get(i).externalConnections&&t.children(i)&&t.children(i).length>0){X.warn("Cluster without external connections, without a parent and with children",i,e);let s=t.graph().rankdir==="TB"?"LR":"TB";Tr.get(i)?.clusterData?.dir&&(s=Tr.get(i).clusterData.dir,X.warn("Fixing dir",Tr.get(i).clusterData.dir,s));let l=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:s,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});X.warn("Old graph before copy",qo(t)),qae(i,t,l,i),t.setNode(i,{clusterNode:!0,id:i,clusterData:Tr.get(i).clusterData,label:Tr.get(i).label,graph:l}),X.warn("New graph after copy node: (",i,")",qo(l)),X.debug("Old graph after copy",qo(t))}else X.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!Tr.get(i).externalConnections," no parent: ",!t.parent(i)," children ",t.children(i)&&t.children(i).length>0,t.children("D"),e),X.debug(Tr);r=t.nodes(),X.warn("New list of nodes",r);for(let i of r){let a=t.node(i);X.warn(" Now next level",i,a),a?.clusterNode&&jae(a.graph,e+1)}},"extractor"),Kae=o((t,e)=>{if(e.length===0)return[];let r=Object.assign([],e);return e.forEach(n=>{let i=t.children(n),a=Kae(t,i);r=[...r,...a]}),r},"sorter"),Qae=o(t=>Kae(t,t.children()),"sortNodesByHierarchy")});var ese={};ur(ese,{render:()=>BPe});var Jae,BPe,tse=N(()=>{"use strict";JR();eN();Wo();FL();Ft();Zae();mw();aw();BL();yt();R2();Gt();Jae=o(async(t,e,r,n,i,a)=>{X.warn("Graph in recursive render:XAX",qo(e),i);let s=e.graph().rankdir;X.trace("Dir in recursive render - dir:",s);let l=t.insert("g").attr("class","root");e.nodes()?X.info("Recursive render XXX",e.nodes()):X.info("No nodes found for",e),e.edges().length>0&&X.info("Recursive edges",e.edge(e.edges()[0]));let u=l.insert("g").attr("class","clusters"),h=l.insert("g").attr("class","edgePaths"),f=l.insert("g").attr("class","edgeLabels"),d=l.insert("g").attr("class","nodes");await Promise.all(e.nodes().map(async function(y){let v=e.node(y);if(i!==void 0){let x=JSON.parse(JSON.stringify(i.clusterData));X.trace(`Setting data for parent cluster XXX - Node.id = `,y,` - data=`,x.height,` -Parent cluster`,i.height),e.setNode(i.id,x),e.parent(y)||(X.trace("Setting parent",y,i.id),e.setParent(y,i.id,x))}if(X.info("(Insert) Node XXX"+y+": "+JSON.stringify(e.node(y))),v?.clusterNode){X.info("Cluster identified XBX",y,v.width,e.node(y));let{ranksep:x,nodesep:b}=e.graph();v.graph.setGraph({...v.graph.graph(),ranksep:x+25,nodesep:b});let T=await Jae(d,v.graph,r,n,e.node(y),a),S=T.elem;Ke(v,S),v.diff=T.diff||0,X.info("New compound node after recursive render XAX",y,"width",v.width,"height",v.height),vee(S,v)}else e.children(y).length>0?(X.trace("Cluster - the non recursive path XBX",y,v.id,v,v.width,"Graph:",e),X.trace(Ym(v.id,e)),Tr.set(v.id,{id:Ym(v.id,e),node:v})):(X.trace("Node - the non recursive path XAX",y,d,e.node(y),s),await Am(d,e.node(y),{config:a,dir:s}))})),await o(async()=>{let y=e.edges().map(async function(v){let x=e.edge(v.v,v.w,v.name);X.info("Edge "+v.v+" -> "+v.w+": "+JSON.stringify(v)),X.info("Edge "+v.v+" -> "+v.w+": ",v," ",JSON.stringify(e.edge(v))),X.info("Fix",Tr,"ids:",v.v,v.w,"Translating: ",Tr.get(v.v),Tr.get(v.w)),await uw(f,x)});await Promise.all(y)},"processEdges")(),X.info("Graph before layout:",JSON.stringify(qo(e))),X.info("############################################# XXX"),X.info("### Layout ### XXX"),X.info("############################################# XXX"),G2(e),X.info("Graph after layout:",JSON.stringify(qo(e)));let m=0,{subGraphTitleTotalMargin:g}=Bu(a);return await Promise.all(Qae(e).map(async function(y){let v=e.node(y);if(X.info("Position XBX => "+y+": ("+v.x,","+v.y,") width: ",v.width," height: ",v.height),v?.clusterNode)v.y+=g,X.info("A tainted cluster node XBX1",y,v.id,v.width,v.height,v.x,v.y,e.parent(y)),Tr.get(v.id).node=v,M2(v);else if(e.children(y).length>0){X.info("A pure cluster node XBX1",y,v.id,v.x,v.y,v.width,v.height,e.parent(y)),v.height+=g,e.node(v.parentId);let x=v?.padding/2||0,b=v?.labelBBox?.height||0,T=b-x||0;X.debug("OffsetY",T,"labelHeight",b,"halfPadding",x),await Cm(u,v),Tr.get(v.id).node=v}else{let x=e.node(v.parentId);v.y+=g/2,X.info("A regular node XBX1 - using the padding",v.id,"parent",v.parentId,v.width,v.height,v.x,v.y,"offsetY",v.offsetY,"parent",x,x?.offsetY,v),M2(v)}})),e.edges().forEach(function(y){let v=e.edge(y);X.info("Edge "+y.v+" -> "+y.w+": "+JSON.stringify(v),v),v.points.forEach(S=>S.y+=g/2);let x=e.node(y.v);var b=e.node(y.w);let T=fw(h,v,Tr,r,x,b,n);hw(v,T)}),e.nodes().forEach(function(y){let v=e.node(y);X.info(y,v.type,v.diff),v.isGroup&&(m=v.diff)}),X.warn("Returning from recursive render XAX",l,m),{elem:l,diff:m}},"recursiveRender"),BPe=o(async(t,e)=>{let r=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:t.direction,nodesep:t.config?.nodeSpacing||t.config?.flowchart?.nodeSpacing||t.nodeSpacing,ranksep:t.config?.rankSpacing||t.config?.flowchart?.rankSpacing||t.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),n=e.select("g");dw(n,t.markers,t.type,t.diagramId),xee(),yee(),hee(),Wae(),t.nodes.forEach(a=>{r.setNode(a.id,{...a}),a.parentId&&r.setParent(a.id,a.parentId)}),X.debug("Edges:",t.edges),t.edges.forEach(a=>{if(a.start===a.end){let s=a.start,l=s+"---"+s+"---1",u=s+"---"+s+"---2",h=r.node(s);r.setNode(l,{domId:l,id:l,parentId:h.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),r.setParent(l,h.parentId),r.setNode(u,{domId:u,id:u,parentId:h.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),r.setParent(u,h.parentId);let f=structuredClone(a),d=structuredClone(a),p=structuredClone(a);f.label="",f.arrowTypeEnd="none",f.id=s+"-cyclic-special-1",d.arrowTypeStart="none",d.arrowTypeEnd="none",d.id=s+"-cyclic-special-mid",p.label="",h.isGroup&&(f.fromCluster=s,p.toCluster=s),p.id=s+"-cyclic-special-2",p.arrowTypeStart="none",r.setEdge(s,l,f,s+"-cyclic-special-0"),r.setEdge(l,u,d,s+"-cyclic-special-1"),r.setEdge(u,s,p,s+"-cyc{"use strict";Tee();yt();V2={},tN=o(t=>{for(let e of t)V2[e.name]=e},"registerLayoutLoaders"),FPe=o(()=>{tN([{name:"dagre",loader:o(async()=>await Promise.resolve().then(()=>(tse(),ese)),"loader")}])},"registerDefaultLayoutLoaders");FPe();Rc=o(async(t,e)=>{if(!(t.layoutAlgorithm in V2))throw new Error(`Unknown layout algorithm: ${t.layoutAlgorithm}`);let r=V2[t.layoutAlgorithm];return(await r.loader()).render(t,e,bee,{algorithm:r.algorithm})},"render"),uf=o((t="",{fallback:e="dagre"}={})=>{if(t in V2)return t;if(e in V2)return X.warn(`Layout algorithm ${t} is not registered. Using ${e} as fallback.`),e;throw new Error(`Both layout algorithms ${t} and ${e} are not registered.`)},"getRegisteredLayoutAlgorithm")});var Yo,$Pe,zPe,np=N(()=>{"use strict";xi();yt();Yo=o((t,e,r,n)=>{t.attr("class",r);let{width:i,height:a,x:s,y:l}=$Pe(t,e);fn(t,a,i,n);let u=zPe(s,l,i,a,e);t.attr("viewBox",u),X.debug(`viewBox configured: ${u} with padding: ${e}`)},"setupViewPortForSVG"),$Pe=o((t,e)=>{let r=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:r.width+e*2,height:r.height+e*2,x:r.x,y:r.y}},"calculateDimensionsWithPadding"),zPe=o((t,e,r,n,i)=>`${t-i} ${e-i} ${r} ${n}`,"createViewBox")});var GPe,VPe,rse,nse=N(()=>{"use strict";fr();Gt();yt();Sm();rp();np();er();GPe=o(function(t,e){return e.db.getClasses()},"getClasses"),VPe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing state diagram (v2)",e);let{securityLevel:i,flowchart:a,layout:s}=me(),l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?l.nodes()[0].contentDocument:document;X.debug("Before getData: ");let h=n.db.getData();X.debug("Data: ",h);let f=wc(e,i),d=n.db.getDirection();h.type=n.type,h.layoutAlgorithm=uf(s),h.layoutAlgorithm==="dagre"&&s==="elk"&&X.warn("flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0) for more details. This diagram will be rendered using `dagre` layout as a fallback."),h.direction=d,h.nodeSpacing=a?.nodeSpacing||50,h.rankSpacing=a?.rankSpacing||50,h.markers=["point","circle","cross"],h.diagramId=e,X.debug("REF1:",h),await Rc(h,f);let p=h.config.flowchart?.diagramPadding??8;Vt.insertTitle(f,"flowchartTitleText",a?.titleTopMargin||0,n.db.getDiagramTitle()),Yo(f,p,"flowchart",a?.useMaxWidth||!1);for(let m of h.nodes){let g=Ge(`#${e} [id="${m.id}"]`);if(!g||!m.link)continue;let y=u.createElementNS("http://www.w3.org/2000/svg","a");y.setAttributeNS("http://www.w3.org/2000/svg","class",m.cssClasses),y.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),i==="sandbox"?y.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):m.linkTarget&&y.setAttributeNS("http://www.w3.org/2000/svg","target",m.linkTarget);let v=g.insert(function(){return y},":first-child"),x=g.select(".label-container");x&&v.append(function(){return x.node()});let b=g.select(".label");b&&v.append(function(){return b.node()})}},"draw"),rse={getClasses:GPe,draw:VPe}});var rN,nN,ise=N(()=>{"use strict";rN=function(){var t=o(function(Hr,et,gt,Kt){for(gt=gt||{},Kt=Hr.length;Kt--;gt[Hr[Kt]]=et);return gt},"o"),e=[1,4],r=[1,3],n=[1,5],i=[1,8,9,10,11,27,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],a=[2,2],s=[1,13],l=[1,14],u=[1,15],h=[1,16],f=[1,23],d=[1,25],p=[1,26],m=[1,27],g=[1,49],y=[1,48],v=[1,29],x=[1,30],b=[1,31],T=[1,32],S=[1,33],w=[1,44],E=[1,46],_=[1,42],C=[1,47],D=[1,43],O=[1,50],R=[1,45],k=[1,51],L=[1,52],A=[1,34],I=[1,35],M=[1,36],P=[1,37],B=[1,57],F=[1,8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],z=[1,61],$=[1,60],U=[1,62],K=[8,9,11,75,77,78],ee=[1,78],Y=[1,91],ce=[1,96],Z=[1,95],ue=[1,92],Q=[1,88],j=[1,94],ne=[1,90],te=[1,97],he=[1,93],le=[1,98],J=[1,89],Se=[8,9,10,11,40,75,77,78],se=[8,9,10,11,40,46,75,77,78],ae=[8,9,10,11,29,40,44,46,48,50,52,54,56,58,60,63,65,67,68,70,75,77,78,89,102,105,106,109,111,114,115,116],Oe=[8,9,11,44,60,75,77,78,89,102,105,106,109,111,114,115,116],ye=[44,60,89,102,105,106,109,111,114,115,116],Be=[1,121],He=[1,122],ze=[1,124],Le=[1,123],Ie=[44,60,62,74,89,102,105,106,109,111,114,115,116],xe=[1,133],q=[1,147],de=[1,148],ie=[1,149],oe=[1,150],V=[1,135],Te=[1,137],W=[1,141],pe=[1,142],ve=[1,143],Pe=[1,144],_e=[1,145],be=[1,146],Ve=[1,151],De=[1,152],qe=[1,131],at=[1,132],Rt=[1,139],st=[1,134],Ue=[1,138],ct=[1,136],We=[8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],ot=[1,154],Yt=[1,156],Tt=[8,9,11],Mt=[8,9,10,11,14,44,60,89,105,106,109,111,114,115,116],bt=[1,176],ut=[1,172],St=[1,173],ft=[1,177],vt=[1,174],nt=[1,175],pn=[77,116,119],kt=[8,9,10,11,12,14,27,29,32,44,60,75,84,85,86,87,88,89,90,105,109,111,114,115,116],On=[10,106],tn=[31,49,51,53,55,57,62,64,66,67,69,71,116,117,118],Mr=[1,247],Ir=[1,245],Pn=[1,249],Dt=[1,243],Ce=[1,244],tt=[1,246],Ct=[1,248],gr=[1,250],rn=[1,268],yn=[8,9,11,106],Zr=[8,9,10,11,60,84,105,106,109,110,111,112],Oi={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,shapeData:39,SHAPE_DATA:40,link:41,node:42,styledVertex:43,AMP:44,vertex:45,STYLE_SEPARATOR:46,idString:47,DOUBLECIRCLESTART:48,DOUBLECIRCLEEND:49,PS:50,PE:51,"(-":52,"-)":53,STADIUMSTART:54,STADIUMEND:55,SUBROUTINESTART:56,SUBROUTINEEND:57,VERTEX_WITH_PROPS_START:58,"NODE_STRING[field]":59,COLON:60,"NODE_STRING[value]":61,PIPE:62,CYLINDERSTART:63,CYLINDEREND:64,DIAMOND_START:65,DIAMOND_STOP:66,TAGEND:67,TRAPSTART:68,TRAPEND:69,INVTRAPSTART:70,INVTRAPEND:71,linkStatement:72,arrowText:73,TESTSTR:74,START_LINK:75,edgeText:76,LINK:77,LINK_ID:78,edgeTextToken:79,STR:80,MD_STR:81,textToken:82,keywords:83,STYLE:84,LINKSTYLE:85,CLASSDEF:86,CLASS:87,CLICK:88,DOWN:89,UP:90,textNoTagsToken:91,stylesOpt:92,"idString[vertex]":93,"idString[class]":94,CALLBACKNAME:95,CALLBACKARGS:96,HREF:97,LINK_TARGET:98,"STR[link]":99,"STR[tooltip]":100,alphaNum:101,DEFAULT:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,NODE_STRING:109,UNIT:110,BRKT:111,PCT:112,idStringToken:113,MINUS:114,MULT:115,UNICODE_TEXT:116,TEXT:117,TAGSTART:118,EDGE_TEXT:119,alphaNumToken:120,direction_tb:121,direction_bt:122,direction_rl:123,direction_lr:124,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",40:"SHAPE_DATA",44:"AMP",46:"STYLE_SEPARATOR",48:"DOUBLECIRCLESTART",49:"DOUBLECIRCLEEND",50:"PS",51:"PE",52:"(-",53:"-)",54:"STADIUMSTART",55:"STADIUMEND",56:"SUBROUTINESTART",57:"SUBROUTINEEND",58:"VERTEX_WITH_PROPS_START",59:"NODE_STRING[field]",60:"COLON",61:"NODE_STRING[value]",62:"PIPE",63:"CYLINDERSTART",64:"CYLINDEREND",65:"DIAMOND_START",66:"DIAMOND_STOP",67:"TAGEND",68:"TRAPSTART",69:"TRAPEND",70:"INVTRAPSTART",71:"INVTRAPEND",74:"TESTSTR",75:"START_LINK",77:"LINK",78:"LINK_ID",80:"STR",81:"MD_STR",84:"STYLE",85:"LINKSTYLE",86:"CLASSDEF",87:"CLASS",88:"CLICK",89:"DOWN",90:"UP",93:"idString[vertex]",94:"idString[class]",95:"CALLBACKNAME",96:"CALLBACKARGS",97:"HREF",98:"LINK_TARGET",99:"STR[link]",100:"STR[tooltip]",102:"DEFAULT",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"NODE_STRING",110:"UNIT",111:"BRKT",112:"PCT",114:"MINUS",115:"MULT",116:"UNICODE_TEXT",117:"TEXT",118:"TAGSTART",119:"EDGE_TEXT",121:"direction_tb",122:"direction_bt",123:"direction_rl",124:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[39,2],[39,1],[20,4],[20,3],[20,4],[20,2],[20,2],[20,1],[42,1],[42,6],[42,5],[43,1],[43,3],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,8],[45,4],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,4],[45,4],[45,1],[41,2],[41,3],[41,3],[41,1],[41,3],[41,4],[76,1],[76,2],[76,1],[76,1],[72,1],[72,2],[73,3],[30,1],[30,2],[30,1],[30,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[103,1],[103,3],[92,1],[92,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[82,1],[82,1],[82,1],[82,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[79,1],[79,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[47,1],[47,2],[101,1],[101,2],[33,1],[33,1],[33,1],[33,1]],performAction:o(function(et,gt,Kt,lt,Cn,ge,Qf){var we=ge.length-1;switch(Cn){case 2:this.$=[];break;case 3:(!Array.isArray(ge[we])||ge[we].length>0)&&ge[we-1].push(ge[we]),this.$=ge[we-1];break;case 4:case 183:this.$=ge[we];break;case 11:lt.setDirection("TB"),this.$="TB";break;case 12:lt.setDirection(ge[we-1]),this.$=ge[we-1];break;case 27:this.$=ge[we-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=lt.addSubGraph(ge[we-6],ge[we-1],ge[we-4]);break;case 34:this.$=lt.addSubGraph(ge[we-3],ge[we-1],ge[we-3]);break;case 35:this.$=lt.addSubGraph(void 0,ge[we-1],void 0);break;case 37:this.$=ge[we].trim(),lt.setAccTitle(this.$);break;case 38:case 39:this.$=ge[we].trim(),lt.setAccDescription(this.$);break;case 43:this.$=ge[we-1]+ge[we];break;case 44:this.$=ge[we];break;case 45:lt.addVertex(ge[we-1][ge[we-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we]),lt.addLink(ge[we-3].stmt,ge[we-1],ge[we-2]),this.$={stmt:ge[we-1],nodes:ge[we-1].concat(ge[we-3].nodes)};break;case 46:lt.addLink(ge[we-2].stmt,ge[we],ge[we-1]),this.$={stmt:ge[we],nodes:ge[we].concat(ge[we-2].nodes)};break;case 47:lt.addLink(ge[we-3].stmt,ge[we-1],ge[we-2]),this.$={stmt:ge[we-1],nodes:ge[we-1].concat(ge[we-3].nodes)};break;case 48:this.$={stmt:ge[we-1],nodes:ge[we-1]};break;case 49:lt.addVertex(ge[we-1][ge[we-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we]),this.$={stmt:ge[we-1],nodes:ge[we-1],shapeData:ge[we]};break;case 50:this.$={stmt:ge[we],nodes:ge[we]};break;case 51:this.$=[ge[we]];break;case 52:lt.addVertex(ge[we-5][ge[we-5].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ge[we-4]),this.$=ge[we-5].concat(ge[we]);break;case 53:this.$=ge[we-4].concat(ge[we]);break;case 54:this.$=ge[we];break;case 55:this.$=ge[we-2],lt.setClass(ge[we-2],ge[we]);break;case 56:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"square");break;case 57:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"doublecircle");break;case 58:this.$=ge[we-5],lt.addVertex(ge[we-5],ge[we-2],"circle");break;case 59:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"ellipse");break;case 60:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"stadium");break;case 61:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"subroutine");break;case 62:this.$=ge[we-7],lt.addVertex(ge[we-7],ge[we-1],"rect",void 0,void 0,void 0,Object.fromEntries([[ge[we-5],ge[we-3]]]));break;case 63:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"cylinder");break;case 64:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"round");break;case 65:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"diamond");break;case 66:this.$=ge[we-5],lt.addVertex(ge[we-5],ge[we-2],"hexagon");break;case 67:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"odd");break;case 68:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"trapezoid");break;case 69:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"inv_trapezoid");break;case 70:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"lean_right");break;case 71:this.$=ge[we-3],lt.addVertex(ge[we-3],ge[we-1],"lean_left");break;case 72:this.$=ge[we],lt.addVertex(ge[we]);break;case 73:ge[we-1].text=ge[we],this.$=ge[we-1];break;case 74:case 75:ge[we-2].text=ge[we-1],this.$=ge[we-2];break;case 76:this.$=ge[we];break;case 77:var Ei=lt.destructLink(ge[we],ge[we-2]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,text:ge[we-1]};break;case 78:var Ei=lt.destructLink(ge[we],ge[we-2]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,text:ge[we-1],id:ge[we-3]};break;case 79:this.$={text:ge[we],type:"text"};break;case 80:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 81:this.$={text:ge[we],type:"string"};break;case 82:this.$={text:ge[we],type:"markdown"};break;case 83:var Ei=lt.destructLink(ge[we]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length};break;case 84:var Ei=lt.destructLink(ge[we]);this.$={type:Ei.type,stroke:Ei.stroke,length:Ei.length,id:ge[we-1]};break;case 85:this.$=ge[we-1];break;case 86:this.$={text:ge[we],type:"text"};break;case 87:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 88:this.$={text:ge[we],type:"string"};break;case 89:case 104:this.$={text:ge[we],type:"markdown"};break;case 101:this.$={text:ge[we],type:"text"};break;case 102:this.$={text:ge[we-1].text+""+ge[we],type:ge[we-1].type};break;case 103:this.$={text:ge[we],type:"text"};break;case 105:this.$=ge[we-4],lt.addClass(ge[we-2],ge[we]);break;case 106:this.$=ge[we-4],lt.setClass(ge[we-2],ge[we]);break;case 107:case 115:this.$=ge[we-1],lt.setClickEvent(ge[we-1],ge[we]);break;case 108:case 116:this.$=ge[we-3],lt.setClickEvent(ge[we-3],ge[we-2]),lt.setTooltip(ge[we-3],ge[we]);break;case 109:this.$=ge[we-2],lt.setClickEvent(ge[we-2],ge[we-1],ge[we]);break;case 110:this.$=ge[we-4],lt.setClickEvent(ge[we-4],ge[we-3],ge[we-2]),lt.setTooltip(ge[we-4],ge[we]);break;case 111:this.$=ge[we-2],lt.setLink(ge[we-2],ge[we]);break;case 112:this.$=ge[we-4],lt.setLink(ge[we-4],ge[we-2]),lt.setTooltip(ge[we-4],ge[we]);break;case 113:this.$=ge[we-4],lt.setLink(ge[we-4],ge[we-2],ge[we]);break;case 114:this.$=ge[we-6],lt.setLink(ge[we-6],ge[we-4],ge[we]),lt.setTooltip(ge[we-6],ge[we-2]);break;case 117:this.$=ge[we-1],lt.setLink(ge[we-1],ge[we]);break;case 118:this.$=ge[we-3],lt.setLink(ge[we-3],ge[we-2]),lt.setTooltip(ge[we-3],ge[we]);break;case 119:this.$=ge[we-3],lt.setLink(ge[we-3],ge[we-2],ge[we]);break;case 120:this.$=ge[we-5],lt.setLink(ge[we-5],ge[we-4],ge[we]),lt.setTooltip(ge[we-5],ge[we-2]);break;case 121:this.$=ge[we-4],lt.addVertex(ge[we-2],void 0,void 0,ge[we]);break;case 122:this.$=ge[we-4],lt.updateLink([ge[we-2]],ge[we]);break;case 123:this.$=ge[we-4],lt.updateLink(ge[we-2],ge[we]);break;case 124:this.$=ge[we-8],lt.updateLinkInterpolate([ge[we-6]],ge[we-2]),lt.updateLink([ge[we-6]],ge[we]);break;case 125:this.$=ge[we-8],lt.updateLinkInterpolate(ge[we-6],ge[we-2]),lt.updateLink(ge[we-6],ge[we]);break;case 126:this.$=ge[we-6],lt.updateLinkInterpolate([ge[we-4]],ge[we]);break;case 127:this.$=ge[we-6],lt.updateLinkInterpolate(ge[we-4],ge[we]);break;case 128:case 130:this.$=[ge[we]];break;case 129:case 131:ge[we-2].push(ge[we]),this.$=ge[we-2];break;case 133:this.$=ge[we-1]+ge[we];break;case 181:this.$=ge[we];break;case 182:this.$=ge[we-1]+""+ge[we];break;case 184:this.$=ge[we-1]+""+ge[we];break;case 185:this.$={stmt:"dir",value:"TB"};break;case 186:this.$={stmt:"dir",value:"BT"};break;case 187:this.$={stmt:"dir",value:"RL"};break;case 188:this.$={stmt:"dir",value:"LR"};break}},"anonymous"),table:[{3:1,4:2,9:e,10:r,12:n},{1:[3]},t(i,a,{5:6}),{4:7,9:e,10:r,12:n},{4:8,9:e,10:r,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:B,15:53,18:56},t(F,[2,3]),t(F,[2,4]),t(F,[2,5]),t(F,[2,6]),t(F,[2,7]),t(F,[2,8]),{8:z,9:$,11:U,21:58,41:59,72:63,75:[1,64],77:[1,66],78:[1,65]},{8:z,9:$,11:U,21:67},{8:z,9:$,11:U,21:68},{8:z,9:$,11:U,21:69},{8:z,9:$,11:U,21:70},{8:z,9:$,11:U,21:71},{8:z,9:$,10:[1,72],11:U,21:73},t(F,[2,36]),{35:[1,74]},{37:[1,75]},t(F,[2,39]),t(K,[2,50],{18:76,39:77,10:B,40:ee}),{10:[1,79]},{10:[1,80]},{10:[1,81]},{10:[1,82]},{14:Y,44:ce,60:Z,80:[1,86],89:ue,95:[1,83],97:[1,84],101:85,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},t(F,[2,185]),t(F,[2,186]),t(F,[2,187]),t(F,[2,188]),t(Se,[2,51]),t(Se,[2,54],{46:[1,99]}),t(se,[2,72],{113:112,29:[1,100],44:g,48:[1,101],50:[1,102],52:[1,103],54:[1,104],56:[1,105],58:[1,106],60:y,63:[1,107],65:[1,108],67:[1,109],68:[1,110],70:[1,111],89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),t(ae,[2,181]),t(ae,[2,142]),t(ae,[2,143]),t(ae,[2,144]),t(ae,[2,145]),t(ae,[2,146]),t(ae,[2,147]),t(ae,[2,148]),t(ae,[2,149]),t(ae,[2,150]),t(ae,[2,151]),t(ae,[2,152]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,113]},t(Oe,[2,26],{18:114,10:B}),t(F,[2,27]),{42:115,43:38,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(F,[2,40]),t(F,[2,41]),t(F,[2,42]),t(ye,[2,76],{73:116,62:[1,118],74:[1,117]}),{76:119,79:120,80:Be,81:He,116:ze,119:Le},{75:[1,125],77:[1,126]},t(Ie,[2,83]),t(F,[2,28]),t(F,[2,29]),t(F,[2,30]),t(F,[2,31]),t(F,[2,32]),{10:xe,12:q,14:de,27:ie,28:127,32:oe,44:V,60:Te,75:W,80:[1,129],81:[1,130],83:140,84:pe,85:ve,86:Pe,87:_e,88:be,89:Ve,90:De,91:128,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(We,a,{5:153}),t(F,[2,37]),t(F,[2,38]),t(K,[2,48],{44:ot}),t(K,[2,49],{18:155,10:B,40:Yt}),t(Se,[2,44]),{44:g,47:157,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{102:[1,158],103:159,105:[1,160]},{44:g,47:161,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{44:g,47:162,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,107],{10:[1,163],96:[1,164]}),{80:[1,165]},t(Tt,[2,115],{120:167,10:[1,166],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,117],{10:[1,168]}),t(Mt,[2,183]),t(Mt,[2,170]),t(Mt,[2,171]),t(Mt,[2,172]),t(Mt,[2,173]),t(Mt,[2,174]),t(Mt,[2,175]),t(Mt,[2,176]),t(Mt,[2,177]),t(Mt,[2,178]),t(Mt,[2,179]),t(Mt,[2,180]),{44:g,47:169,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{30:170,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:178,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:180,50:[1,179],67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:181,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:182,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:183,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{109:[1,184]},{30:185,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:186,65:[1,187],67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:188,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:189,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{30:190,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(ae,[2,182]),t(i,[2,20]),t(Oe,[2,25]),t(K,[2,46],{39:191,18:192,10:B,40:ee}),t(ye,[2,73],{10:[1,193]}),{10:[1,194]},{30:195,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{77:[1,196],79:197,116:ze,119:Le},t(pn,[2,79]),t(pn,[2,81]),t(pn,[2,82]),t(pn,[2,168]),t(pn,[2,169]),{76:198,79:120,80:Be,81:He,116:ze,119:Le},t(Ie,[2,84]),{8:z,9:$,10:xe,11:U,12:q,14:de,21:200,27:ie,29:[1,199],32:oe,44:V,60:Te,75:W,83:140,84:pe,85:ve,86:Pe,87:_e,88:be,89:Ve,90:De,91:201,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(kt,[2,101]),t(kt,[2,103]),t(kt,[2,104]),t(kt,[2,157]),t(kt,[2,158]),t(kt,[2,159]),t(kt,[2,160]),t(kt,[2,161]),t(kt,[2,162]),t(kt,[2,163]),t(kt,[2,164]),t(kt,[2,165]),t(kt,[2,166]),t(kt,[2,167]),t(kt,[2,90]),t(kt,[2,91]),t(kt,[2,92]),t(kt,[2,93]),t(kt,[2,94]),t(kt,[2,95]),t(kt,[2,96]),t(kt,[2,97]),t(kt,[2,98]),t(kt,[2,99]),t(kt,[2,100]),{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,202],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},{10:B,18:203},{44:[1,204]},t(Se,[2,43]),{10:[1,205],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{10:[1,206]},{10:[1,207],106:[1,208]},t(On,[2,128]),{10:[1,209],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{10:[1,210],44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:112,114:R,115:k,116:L},{80:[1,211]},t(Tt,[2,109],{10:[1,212]}),t(Tt,[2,111],{10:[1,213]}),{80:[1,214]},t(Mt,[2,184]),{80:[1,215],98:[1,216]},t(Se,[2,55],{113:112,44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),{31:[1,217],67:bt,82:218,116:ft,117:vt,118:nt},t(tn,[2,86]),t(tn,[2,88]),t(tn,[2,89]),t(tn,[2,153]),t(tn,[2,154]),t(tn,[2,155]),t(tn,[2,156]),{49:[1,219],67:bt,82:218,116:ft,117:vt,118:nt},{30:220,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{51:[1,221],67:bt,82:218,116:ft,117:vt,118:nt},{53:[1,222],67:bt,82:218,116:ft,117:vt,118:nt},{55:[1,223],67:bt,82:218,116:ft,117:vt,118:nt},{57:[1,224],67:bt,82:218,116:ft,117:vt,118:nt},{60:[1,225]},{64:[1,226],67:bt,82:218,116:ft,117:vt,118:nt},{66:[1,227],67:bt,82:218,116:ft,117:vt,118:nt},{30:228,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},{31:[1,229],67:bt,82:218,116:ft,117:vt,118:nt},{67:bt,69:[1,230],71:[1,231],82:218,116:ft,117:vt,118:nt},{67:bt,69:[1,233],71:[1,232],82:218,116:ft,117:vt,118:nt},t(K,[2,45],{18:155,10:B,40:Yt}),t(K,[2,47],{44:ot}),t(ye,[2,75]),t(ye,[2,74]),{62:[1,234],67:bt,82:218,116:ft,117:vt,118:nt},t(ye,[2,77]),t(pn,[2,80]),{77:[1,235],79:197,116:ze,119:Le},{30:236,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(We,a,{5:237}),t(kt,[2,102]),t(F,[2,35]),{43:238,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},{10:B,18:239},{10:Mr,60:Ir,84:Pn,92:240,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:251,104:[1,252],105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:253,104:[1,254],105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{105:[1,255]},{10:Mr,60:Ir,84:Pn,92:256,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{44:g,47:257,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,108]),{80:[1,258]},{80:[1,259],98:[1,260]},t(Tt,[2,116]),t(Tt,[2,118],{10:[1,261]}),t(Tt,[2,119]),t(se,[2,56]),t(tn,[2,87]),t(se,[2,57]),{51:[1,262],67:bt,82:218,116:ft,117:vt,118:nt},t(se,[2,64]),t(se,[2,59]),t(se,[2,60]),t(se,[2,61]),{109:[1,263]},t(se,[2,63]),t(se,[2,65]),{66:[1,264],67:bt,82:218,116:ft,117:vt,118:nt},t(se,[2,67]),t(se,[2,68]),t(se,[2,70]),t(se,[2,69]),t(se,[2,71]),t([10,44,60,89,102,105,106,109,111,114,115,116],[2,85]),t(ye,[2,78]),{31:[1,265],67:bt,82:218,116:ft,117:vt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,266],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},t(Se,[2,53]),{43:267,44:g,45:39,47:40,60:y,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L},t(Tt,[2,121],{106:rn}),t(yn,[2,130],{108:269,10:Mr,60:Ir,84:Pn,105:Dt,109:Ce,110:tt,111:Ct,112:gr}),t(Zr,[2,132]),t(Zr,[2,134]),t(Zr,[2,135]),t(Zr,[2,136]),t(Zr,[2,137]),t(Zr,[2,138]),t(Zr,[2,139]),t(Zr,[2,140]),t(Zr,[2,141]),t(Tt,[2,122],{106:rn}),{10:[1,270]},t(Tt,[2,123],{106:rn}),{10:[1,271]},t(On,[2,129]),t(Tt,[2,105],{106:rn}),t(Tt,[2,106],{113:112,44:g,60:y,89:w,102:E,105:_,106:C,109:D,111:O,114:R,115:k,116:L}),t(Tt,[2,110]),t(Tt,[2,112],{10:[1,272]}),t(Tt,[2,113]),{98:[1,273]},{51:[1,274]},{62:[1,275]},{66:[1,276]},{8:z,9:$,11:U,21:277},t(F,[2,34]),t(Se,[2,52]),{10:Mr,60:Ir,84:Pn,105:Dt,107:278,108:242,109:Ce,110:tt,111:Ct,112:gr},t(Zr,[2,133]),{14:Y,44:ce,60:Z,89:ue,101:279,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},{14:Y,44:ce,60:Z,89:ue,101:280,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J,120:87},{98:[1,281]},t(Tt,[2,120]),t(se,[2,58]),{30:282,67:bt,80:ut,81:St,82:171,116:ft,117:vt,118:nt},t(se,[2,66]),t(We,a,{5:283}),t(yn,[2,131],{108:269,10:Mr,60:Ir,84:Pn,105:Dt,109:Ce,110:tt,111:Ct,112:gr}),t(Tt,[2,126],{120:167,10:[1,284],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,127],{120:167,10:[1,285],14:Y,44:ce,60:Z,89:ue,105:Q,106:j,109:ne,111:te,114:he,115:le,116:J}),t(Tt,[2,114]),{31:[1,286],67:bt,82:218,116:ft,117:vt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,287],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:T,88:S,89:w,102:E,105:_,106:C,109:D,111:O,113:41,114:R,115:k,116:L,121:A,122:I,123:M,124:P},{10:Mr,60:Ir,84:Pn,92:288,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},{10:Mr,60:Ir,84:Pn,92:289,105:Dt,107:241,108:242,109:Ce,110:tt,111:Ct,112:gr},t(se,[2,62]),t(F,[2,33]),t(Tt,[2,124],{106:rn}),t(Tt,[2,125],{106:rn})],defaultActions:{},parseError:o(function(et,gt){if(gt.recoverable)this.trace(et);else{var Kt=new Error(et);throw Kt.hash=gt,Kt}},"parseError"),parse:o(function(et){var gt=this,Kt=[0],lt=[],Cn=[null],ge=[],Qf=this.table,we="",Ei=0,l$=0,c$=0,tbe=2,u$=1,rbe=ge.slice.call(arguments,1),ji=Object.create(this.lexer),Zf={yy:{}};for(var $C in this.yy)Object.prototype.hasOwnProperty.call(this.yy,$C)&&(Zf.yy[$C]=this.yy[$C]);ji.setInput(et,Zf.yy),Zf.yy.lexer=ji,Zf.yy.parser=this,typeof ji.yylloc>"u"&&(ji.yylloc={});var zC=ji.yylloc;ge.push(zC);var nbe=ji.options&&ji.options.ranges;typeof Zf.yy.parseError=="function"?this.parseError=Zf.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Qit(Xs){Kt.length=Kt.length-2*Xs,Cn.length=Cn.length-Xs,ge.length=ge.length-Xs}o(Qit,"popStack");function ibe(){var Xs;return Xs=lt.pop()||ji.lex()||u$,typeof Xs!="number"&&(Xs instanceof Array&&(lt=Xs,Xs=lt.pop()),Xs=gt.symbols_[Xs]||Xs),Xs}o(ibe,"lex");for(var Ka,GC,Jf,wo,Zit,VC,c0={},z4,nu,h$,G4;;){if(Jf=Kt[Kt.length-1],this.defaultActions[Jf]?wo=this.defaultActions[Jf]:((Ka===null||typeof Ka>"u")&&(Ka=ibe()),wo=Qf[Jf]&&Qf[Jf][Ka]),typeof wo>"u"||!wo.length||!wo[0]){var UC="";G4=[];for(z4 in Qf[Jf])this.terminals_[z4]&&z4>tbe&&G4.push("'"+this.terminals_[z4]+"'");ji.showPosition?UC="Parse error on line "+(Ei+1)+`: -`+ji.showPosition()+` -Expecting `+G4.join(", ")+", got '"+(this.terminals_[Ka]||Ka)+"'":UC="Parse error on line "+(Ei+1)+": Unexpected "+(Ka==u$?"end of input":"'"+(this.terminals_[Ka]||Ka)+"'"),this.parseError(UC,{text:ji.match,token:this.terminals_[Ka]||Ka,line:ji.yylineno,loc:zC,expected:G4})}if(wo[0]instanceof Array&&wo.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Jf+", token: "+Ka);switch(wo[0]){case 1:Kt.push(Ka),Cn.push(ji.yytext),ge.push(ji.yylloc),Kt.push(wo[1]),Ka=null,GC?(Ka=GC,GC=null):(l$=ji.yyleng,we=ji.yytext,Ei=ji.yylineno,zC=ji.yylloc,c$>0&&c$--);break;case 2:if(nu=this.productions_[wo[1]][1],c0.$=Cn[Cn.length-nu],c0._$={first_line:ge[ge.length-(nu||1)].first_line,last_line:ge[ge.length-1].last_line,first_column:ge[ge.length-(nu||1)].first_column,last_column:ge[ge.length-1].last_column},nbe&&(c0._$.range=[ge[ge.length-(nu||1)].range[0],ge[ge.length-1].range[1]]),VC=this.performAction.apply(c0,[we,l$,Ei,Zf.yy,wo[1],Cn,ge].concat(rbe)),typeof VC<"u")return VC;nu&&(Kt=Kt.slice(0,-1*nu*2),Cn=Cn.slice(0,-1*nu),ge=ge.slice(0,-1*nu)),Kt.push(this.productions_[wo[1]][0]),Cn.push(c0.$),ge.push(c0._$),h$=Qf[Kt[Kt.length-2]][Kt[Kt.length-1]],Kt.push(h$);break;case 3:return!0}}return!0},"parse")},ei=function(){var Hr={EOF:1,parseError:o(function(gt,Kt){if(this.yy.parser)this.yy.parser.parseError(gt,Kt);else throw new Error(gt)},"parseError"),setInput:o(function(et,gt){return this.yy=gt||this.yy||{},this._input=et,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var et=this._input[0];this.yytext+=et,this.yyleng++,this.offset++,this.match+=et,this.matched+=et;var gt=et.match(/(?:\r\n?|\n).*/g);return gt?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),et},"input"),unput:o(function(et){var gt=et.length,Kt=et.split(/(?:\r\n?|\n)/g);this._input=et+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-gt),this.offset-=gt;var lt=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Kt.length-1&&(this.yylineno-=Kt.length-1);var Cn=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Kt?(Kt.length===lt.length?this.yylloc.first_column:0)+lt[lt.length-Kt.length].length-Kt[0].length:this.yylloc.first_column-gt},this.options.ranges&&(this.yylloc.range=[Cn[0],Cn[0]+this.yyleng-gt]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(et){this.unput(this.match.slice(et))},"less"),pastInput:o(function(){var et=this.matched.substr(0,this.matched.length-this.match.length);return(et.length>20?"...":"")+et.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var et=this.match;return et.length<20&&(et+=this._input.substr(0,20-et.length)),(et.substr(0,20)+(et.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var et=this.pastInput(),gt=new Array(et.length+1).join("-");return et+this.upcomingInput()+` -`+gt+"^"},"showPosition"),test_match:o(function(et,gt){var Kt,lt,Cn;if(this.options.backtrack_lexer&&(Cn={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(Cn.yylloc.range=this.yylloc.range.slice(0))),lt=et[0].match(/(?:\r\n?|\n).*/g),lt&&(this.yylineno+=lt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:lt?lt[lt.length-1].length-lt[lt.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+et[0].length},this.yytext+=et[0],this.match+=et[0],this.matches=et,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(et[0].length),this.matched+=et[0],Kt=this.performAction.call(this,this.yy,this,gt,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Kt)return Kt;if(this._backtrack){for(var ge in Cn)this[ge]=Cn[ge];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var et,gt,Kt,lt;this._more||(this.yytext="",this.match="");for(var Cn=this._currentRules(),ge=0;gegt[0].length)){if(gt=Kt,lt=ge,this.options.backtrack_lexer){if(et=this.test_match(Kt,Cn[ge]),et!==!1)return et;if(this._backtrack){gt=!1;continue}else return!1}else if(!this.options.flex)break}return gt?(et=this.test_match(gt,Cn[lt]),et!==!1?et:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var gt=this.next();return gt||this.lex()},"lex"),begin:o(function(gt){this.conditionStack.push(gt)},"begin"),popState:o(function(){var gt=this.conditionStack.length-1;return gt>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(gt){return gt=this.conditionStack.length-1-Math.abs(gt||0),gt>=0?this.conditionStack[gt]:"INITIAL"},"topState"),pushState:o(function(gt){this.begin(gt)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(gt,Kt,lt,Cn){var ge=Cn;switch(lt){case 0:return this.begin("acc_title"),34;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),36;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.pushState("shapeData"),Kt.yytext="",40;break;case 8:return this.pushState("shapeDataStr"),40;break;case 9:return this.popState(),40;break;case 10:let Qf=/\n\s*/g;return Kt.yytext=Kt.yytext.replace(Qf,"
    "),40;break;case 11:return 40;case 12:this.popState();break;case 13:this.begin("callbackname");break;case 14:this.popState();break;case 15:this.popState(),this.begin("callbackargs");break;case 16:return 95;case 17:this.popState();break;case 18:return 96;case 19:return"MD_STR";case 20:this.popState();break;case 21:this.begin("md_string");break;case 22:return"STR";case 23:this.popState();break;case 24:this.pushState("string");break;case 25:return 84;case 26:return 102;case 27:return 85;case 28:return 104;case 29:return 86;case 30:return 87;case 31:return 97;case 32:this.begin("click");break;case 33:this.popState();break;case 34:return 88;case 35:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 36:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 37:return gt.lex.firstGraph()&&this.begin("dir"),12;break;case 38:return 27;case 39:return 32;case 40:return 98;case 41:return 98;case 42:return 98;case 43:return 98;case 44:return this.popState(),13;break;case 45:return this.popState(),14;break;case 46:return this.popState(),14;break;case 47:return this.popState(),14;break;case 48:return this.popState(),14;break;case 49:return this.popState(),14;break;case 50:return this.popState(),14;break;case 51:return this.popState(),14;break;case 52:return this.popState(),14;break;case 53:return this.popState(),14;break;case 54:return this.popState(),14;break;case 55:return 121;case 56:return 122;case 57:return 123;case 58:return 124;case 59:return 78;case 60:return 105;case 61:return 111;case 62:return 46;case 63:return 60;case 64:return 44;case 65:return 8;case 66:return 106;case 67:return 115;case 68:return this.popState(),77;break;case 69:return this.pushState("edgeText"),75;break;case 70:return 119;case 71:return this.popState(),77;break;case 72:return this.pushState("thickEdgeText"),75;break;case 73:return 119;case 74:return this.popState(),77;break;case 75:return this.pushState("dottedEdgeText"),75;break;case 76:return 119;case 77:return 77;case 78:return this.popState(),53;break;case 79:return"TEXT";case 80:return this.pushState("ellipseText"),52;break;case 81:return this.popState(),55;break;case 82:return this.pushState("text"),54;break;case 83:return this.popState(),57;break;case 84:return this.pushState("text"),56;break;case 85:return 58;case 86:return this.pushState("text"),67;break;case 87:return this.popState(),64;break;case 88:return this.pushState("text"),63;break;case 89:return this.popState(),49;break;case 90:return this.pushState("text"),48;break;case 91:return this.popState(),69;break;case 92:return this.popState(),71;break;case 93:return 117;case 94:return this.pushState("trapText"),68;break;case 95:return this.pushState("trapText"),70;break;case 96:return 118;case 97:return 67;case 98:return 90;case 99:return"SEP";case 100:return 89;case 101:return 115;case 102:return 111;case 103:return 44;case 104:return 109;case 105:return 114;case 106:return 116;case 107:return this.popState(),62;break;case 108:return this.pushState("text"),62;break;case 109:return this.popState(),51;break;case 110:return this.pushState("text"),50;break;case 111:return this.popState(),31;break;case 112:return this.pushState("text"),29;break;case 113:return this.popState(),66;break;case 114:return this.pushState("text"),65;break;case 115:return"TEXT";case 116:return"QUOTE";case 117:return 9;case 118:return 10;case 119:return 11}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:@\{)/,/^(?:["])/,/^(?:["])/,/^(?:[^\"]+)/,/^(?:[^}^"]+)/,/^(?:\})/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[^\s\"]+@(?=[^\{\"]))/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{shapeDataEndBracket:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeDataStr:{rules:[9,10,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeData:{rules:[8,11,12,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackargs:{rules:[17,18,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackname:{rules:[14,15,16,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},href:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},click:{rules:[21,24,33,34,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dottedEdgeText:{rules:[21,24,74,76,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},thickEdgeText:{rules:[21,24,71,73,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},edgeText:{rules:[21,24,68,70,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},trapText:{rules:[21,24,77,80,82,84,88,90,91,92,93,94,95,108,110,112,114],inclusive:!1},ellipseText:{rules:[21,24,77,78,79,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},text:{rules:[21,24,77,80,81,82,83,84,87,88,89,90,94,95,107,108,109,110,111,112,113,114,115],inclusive:!1},vertex:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dir:{rules:[21,24,44,45,46,47,48,49,50,51,52,53,54,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr_multiline:{rules:[5,6,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr:{rules:[3,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_title:{rules:[1,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},md_string:{rules:[19,20,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},string:{rules:[21,22,23,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},INITIAL:{rules:[0,2,4,7,13,21,24,25,26,27,28,29,30,31,32,35,36,37,38,39,40,41,42,43,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,71,72,74,75,77,80,82,84,85,86,88,90,94,95,96,97,98,99,100,101,102,103,104,105,106,108,110,112,114,116,117,118,119],inclusive:!0}}};return Hr}();Oi.lexer=ei;function Sn(){this.yy={}}return o(Sn,"Parser"),Sn.prototype=Oi,Oi.Parser=Sn,new Sn}();rN.parser=rN;nN=rN});var ase,sse,ose=N(()=>{"use strict";ise();ase=Object.assign({},nN);ase.parse=t=>{let e=t.replace(/}\s*\n/g,`} -`);return nN.parse(e)};sse=ase});var Nc,Xm=N(()=>{"use strict";Nc=o(()=>` - /* Font Awesome icon styling - consolidated */ - .label-icon { - display: inline-block; - height: 1em; - overflow: visible; - vertical-align: -0.125em; - } - - .node .label-icon path { - fill: currentColor; - stroke: revert; - stroke-width: revert; - } -`,"getIconStyles")});var UPe,HPe,lse,cse=N(()=>{"use strict";Ks();Xm();UPe=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),HPe=o(t=>`.label { - font-family: ${t.fontFamily}; - color: ${t.nodeTextColor||t.textColor}; - } - .cluster-label text { - fill: ${t.titleColor}; - } - .cluster-label span { - color: ${t.titleColor}; - } - .cluster-label span p { - background-color: transparent; - } - - .label text,span { - fill: ${t.nodeTextColor||t.textColor}; - color: ${t.nodeTextColor||t.textColor}; - } - - .node rect, - .node circle, - .node ellipse, - .node polygon, - .node path { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - stroke-width: 1px; - } - .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label { - text-anchor: middle; - } - // .flowchart-label .text-outer-tspan { - // text-anchor: middle; - // } - // .flowchart-label .text-inner-tspan { - // text-anchor: start; - // } - - .node .katex path { - fill: #000; - stroke: #000; - stroke-width: 1px; - } - - .rough-node .label,.node .label, .image-shape .label, .icon-shape .label { - text-align: center; - } - .node.clickable { - cursor: pointer; - } - - - .root .anchor path { - fill: ${t.lineColor} !important; - stroke-width: 0; - stroke: ${t.lineColor}; - } - - .arrowheadPath { - fill: ${t.arrowheadColor}; - } - - .edgePath .path { - stroke: ${t.lineColor}; - stroke-width: 2.0px; - } - - .flowchart-link { - stroke: ${t.lineColor}; - fill: none; - } - - .edgeLabel { - background-color: ${t.edgeLabelBackground}; - p { - background-color: ${t.edgeLabelBackground}; - } - rect { - opacity: 0.5; - background-color: ${t.edgeLabelBackground}; - fill: ${t.edgeLabelBackground}; - } - text-align: center; - } - - /* For html labels only */ - .labelBkg { - background-color: ${UPe(t.edgeLabelBackground,.5)}; - // background-color: - } - - .cluster rect { - fill: ${t.clusterBkg}; - stroke: ${t.clusterBorder}; - stroke-width: 1px; - } - - .cluster text { - fill: ${t.titleColor}; - } - - .cluster span { - color: ${t.titleColor}; - } - /* .cluster div { - color: ${t.titleColor}; - } */ - - div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: ${t.fontFamily}; - font-size: 12px; - background: ${t.tertiaryColor}; - border: 1px solid ${t.border2}; - border-radius: 2px; - pointer-events: none; - z-index: 100; - } - - .flowchartTitleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.textColor}; - } - - rect.text { - fill: none; - stroke-width: 0; - } - - .icon-shape, .image-shape { - background-color: ${t.edgeLabelBackground}; - p { - background-color: ${t.edgeLabelBackground}; - padding: 2px; - } - rect { - opacity: 0.5; - background-color: ${t.edgeLabelBackground}; - fill: ${t.edgeLabelBackground}; - } - text-align: center; - } - ${Nc()} -`,"getStyles"),lse=HPe});var xk={};ur(xk,{diagram:()=>WPe});var WPe,bk=N(()=>{"use strict";Gt();lee();nse();ose();cse();WPe={parser:sse,get db(){return new iw},renderer:rse,styles:lse,init:o(t=>{t.flowchart||(t.flowchart={}),t.layout&&nv({layout:t.layout}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,nv({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}})},"init")}});var iN,pse,mse=N(()=>{"use strict";iN=function(){var t=o(function(te,he,le,J){for(le=le||{},J=te.length;J--;le[te[J]]=he);return le},"o"),e=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,50],r=[1,10],n=[1,11],i=[1,12],a=[1,13],s=[1,20],l=[1,21],u=[1,22],h=[1,23],f=[1,24],d=[1,19],p=[1,25],m=[1,26],g=[1,18],y=[1,33],v=[1,34],x=[1,35],b=[1,36],T=[1,37],S=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,50,63,64,65,66,67],w=[1,42],E=[1,43],_=[1,52],C=[40,50,68,69],D=[1,63],O=[1,61],R=[1,58],k=[1,62],L=[1,64],A=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,63,64,65,66,67],I=[63,64,65,66,67],M=[1,81],P=[1,80],B=[1,78],F=[1,79],z=[6,10,42,47],$=[6,10,13,41,42,47,48,49],U=[1,89],K=[1,88],ee=[1,87],Y=[19,56],ce=[1,98],Z=[1,97],ue=[19,56,58,60],Q={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,attribute:51,attributeType:52,attributeName:53,attributeKeyTypeList:54,attributeComment:55,ATTRIBUTE_WORD:56,attributeKeyType:57,",":58,ATTRIBUTE_KEY:59,COMMENT:60,cardinality:61,relType:62,ZERO_OR_ONE:63,ZERO_OR_MORE:64,ONE_OR_MORE:65,ONLY_ONE:66,MD_PARENT:67,NON_IDENTIFYING:68,IDENTIFYING:69,WORD:70,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",56:"ATTRIBUTE_WORD",58:",",59:"ATTRIBUTE_KEY",60:"COMMENT",63:"ZERO_OR_ONE",64:"ZERO_OR_MORE",65:"ONE_OR_MORE",66:"ONLY_ONE",67:"MD_PARENT",68:"NON_IDENTIFYING",69:"IDENTIFYING",70:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[18,1],[18,2],[51,2],[51,3],[51,3],[51,4],[52,1],[53,1],[54,1],[54,3],[57,1],[55,1],[12,3],[61,1],[61,1],[61,1],[61,1],[61,1],[62,1],[62,1],[14,1],[14,1],[14,1]],performAction:o(function(he,le,J,Se,se,ae,Oe){var ye=ae.length-1;switch(se){case 1:break;case 2:this.$=[];break;case 3:ae[ye-1].push(ae[ye]),this.$=ae[ye-1];break;case 4:case 5:this.$=ae[ye];break;case 6:case 7:this.$=[];break;case 8:Se.addEntity(ae[ye-4]),Se.addEntity(ae[ye-2]),Se.addRelationship(ae[ye-4],ae[ye],ae[ye-2],ae[ye-3]);break;case 9:Se.addEntity(ae[ye-8]),Se.addEntity(ae[ye-4]),Se.addRelationship(ae[ye-8],ae[ye],ae[ye-4],ae[ye-5]),Se.setClass([ae[ye-8]],ae[ye-6]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 10:Se.addEntity(ae[ye-6]),Se.addEntity(ae[ye-2]),Se.addRelationship(ae[ye-6],ae[ye],ae[ye-2],ae[ye-3]),Se.setClass([ae[ye-6]],ae[ye-4]);break;case 11:Se.addEntity(ae[ye-6]),Se.addEntity(ae[ye-4]),Se.addRelationship(ae[ye-6],ae[ye],ae[ye-4],ae[ye-5]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 12:Se.addEntity(ae[ye-3]),Se.addAttributes(ae[ye-3],ae[ye-1]);break;case 13:Se.addEntity(ae[ye-5]),Se.addAttributes(ae[ye-5],ae[ye-1]),Se.setClass([ae[ye-5]],ae[ye-3]);break;case 14:Se.addEntity(ae[ye-2]);break;case 15:Se.addEntity(ae[ye-4]),Se.setClass([ae[ye-4]],ae[ye-2]);break;case 16:Se.addEntity(ae[ye]);break;case 17:Se.addEntity(ae[ye-2]),Se.setClass([ae[ye-2]],ae[ye]);break;case 18:Se.addEntity(ae[ye-6],ae[ye-4]),Se.addAttributes(ae[ye-6],ae[ye-1]);break;case 19:Se.addEntity(ae[ye-8],ae[ye-6]),Se.addAttributes(ae[ye-8],ae[ye-1]),Se.setClass([ae[ye-8]],ae[ye-3]);break;case 20:Se.addEntity(ae[ye-5],ae[ye-3]);break;case 21:Se.addEntity(ae[ye-7],ae[ye-5]),Se.setClass([ae[ye-7]],ae[ye-2]);break;case 22:Se.addEntity(ae[ye-3],ae[ye-1]);break;case 23:Se.addEntity(ae[ye-5],ae[ye-3]),Se.setClass([ae[ye-5]],ae[ye]);break;case 24:case 25:this.$=ae[ye].trim(),Se.setAccTitle(this.$);break;case 26:case 27:this.$=ae[ye].trim(),Se.setAccDescription(this.$);break;case 32:Se.setDirection("TB");break;case 33:Se.setDirection("BT");break;case 34:Se.setDirection("RL");break;case 35:Se.setDirection("LR");break;case 36:this.$=ae[ye-3],Se.addClass(ae[ye-2],ae[ye-1]);break;case 37:case 38:case 56:case 64:this.$=[ae[ye]];break;case 39:case 40:this.$=ae[ye-2].concat([ae[ye]]);break;case 41:this.$=ae[ye-2],Se.setClass(ae[ye-1],ae[ye]);break;case 42:this.$=ae[ye-3],Se.addCssStyles(ae[ye-2],ae[ye-1]);break;case 43:this.$=[ae[ye]];break;case 44:ae[ye-2].push(ae[ye]),this.$=ae[ye-2];break;case 46:this.$=ae[ye-1]+ae[ye];break;case 54:case 76:case 77:this.$=ae[ye].replace(/"/g,"");break;case 55:case 78:this.$=ae[ye];break;case 57:ae[ye].push(ae[ye-1]),this.$=ae[ye];break;case 58:this.$={type:ae[ye-1],name:ae[ye]};break;case 59:this.$={type:ae[ye-2],name:ae[ye-1],keys:ae[ye]};break;case 60:this.$={type:ae[ye-2],name:ae[ye-1],comment:ae[ye]};break;case 61:this.$={type:ae[ye-3],name:ae[ye-2],keys:ae[ye-1],comment:ae[ye]};break;case 62:case 63:case 66:this.$=ae[ye];break;case 65:ae[ye-2].push(ae[ye]),this.$=ae[ye-2];break;case 67:this.$=ae[ye].replace(/"/g,"");break;case 68:this.$={cardA:ae[ye],relType:ae[ye-1],cardB:ae[ye-2]};break;case 69:this.$=Se.Cardinality.ZERO_OR_ONE;break;case 70:this.$=Se.Cardinality.ZERO_OR_MORE;break;case 71:this.$=Se.Cardinality.ONE_OR_MORE;break;case 72:this.$=Se.Cardinality.ONLY_ONE;break;case 73:this.$=Se.Cardinality.MD_PARENT;break;case 74:this.$=Se.Identification.NON_IDENTIFYING;break;case 75:this.$=Se.Identification.IDENTIFYING;break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:27,11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,5]),t(e,[2,6]),t(e,[2,16],{12:28,61:32,15:[1,29],17:[1,30],20:[1,31],63:y,64:v,65:x,66:b,67:T}),{23:[1,38]},{25:[1,39]},{27:[1,40]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),t(e,[2,30]),t(e,[2,31]),t(S,[2,54]),t(S,[2,55]),t(e,[2,32]),t(e,[2,33]),t(e,[2,34]),t(e,[2,35]),{16:41,40:w,41:E},{16:44,40:w,41:E},{16:45,40:w,41:E},t(e,[2,4]),{11:46,40:d,50:g},{16:47,40:w,41:E},{18:48,19:[1,49],51:50,52:51,56:_},{11:53,40:d,50:g},{62:54,68:[1,55],69:[1,56]},t(C,[2,69]),t(C,[2,70]),t(C,[2,71]),t(C,[2,72]),t(C,[2,73]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),{13:D,38:57,41:O,42:R,45:59,46:60,48:k,49:L},t(A,[2,37]),t(A,[2,38]),{16:65,40:w,41:E,42:R},{13:D,38:66,41:O,42:R,45:59,46:60,48:k,49:L},{13:[1,67],15:[1,68]},t(e,[2,17],{61:32,12:69,17:[1,70],42:R,63:y,64:v,65:x,66:b,67:T}),{19:[1,71]},t(e,[2,14]),{18:72,19:[2,56],51:50,52:51,56:_},{53:73,56:[1,74]},{56:[2,62]},{21:[1,75]},{61:76,63:y,64:v,65:x,66:b,67:T},t(I,[2,74]),t(I,[2,75]),{6:M,10:P,39:77,42:B,47:F},{40:[1,82],41:[1,83]},t(z,[2,43],{46:84,13:D,41:O,48:k,49:L}),t($,[2,45]),t($,[2,50]),t($,[2,51]),t($,[2,52]),t($,[2,53]),t(e,[2,41],{42:R}),{6:M,10:P,39:85,42:B,47:F},{14:86,40:U,50:K,70:ee},{16:90,40:w,41:E},{11:91,40:d,50:g},{18:92,19:[1,93],51:50,52:51,56:_},t(e,[2,12]),{19:[2,57]},t(Y,[2,58],{54:94,55:95,57:96,59:ce,60:Z}),t([19,56,59,60],[2,63]),t(e,[2,22],{15:[1,100],17:[1,99]}),t([40,50],[2,68]),t(e,[2,36]),{13:D,41:O,45:101,46:60,48:k,49:L},t(e,[2,47]),t(e,[2,48]),t(e,[2,49]),t(A,[2,39]),t(A,[2,40]),t($,[2,46]),t(e,[2,42]),t(e,[2,8]),t(e,[2,76]),t(e,[2,77]),t(e,[2,78]),{13:[1,102],42:R},{13:[1,104],15:[1,103]},{19:[1,105]},t(e,[2,15]),t(Y,[2,59],{55:106,58:[1,107],60:Z}),t(Y,[2,60]),t(ue,[2,64]),t(Y,[2,67]),t(ue,[2,66]),{18:108,19:[1,109],51:50,52:51,56:_},{16:110,40:w,41:E},t(z,[2,44],{46:84,13:D,41:O,48:k,49:L}),{14:111,40:U,50:K,70:ee},{16:112,40:w,41:E},{14:113,40:U,50:K,70:ee},t(e,[2,13]),t(Y,[2,61]),{57:114,59:ce},{19:[1,115]},t(e,[2,20]),t(e,[2,23],{17:[1,116],42:R}),t(e,[2,11]),{13:[1,117],42:R},t(e,[2,10]),t(ue,[2,65]),t(e,[2,18]),{18:118,19:[1,119],51:50,52:51,56:_},{14:120,40:U,50:K,70:ee},{19:[1,121]},t(e,[2,21]),t(e,[2,9]),t(e,[2,19])],defaultActions:{52:[2,62],72:[2,57]},parseError:o(function(he,le){if(le.recoverable)this.trace(he);else{var J=new Error(he);throw J.hash=le,J}},"parseError"),parse:o(function(he){var le=this,J=[0],Se=[],se=[null],ae=[],Oe=this.table,ye="",Be=0,He=0,ze=0,Le=2,Ie=1,xe=ae.slice.call(arguments,1),q=Object.create(this.lexer),de={yy:{}};for(var ie in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ie)&&(de.yy[ie]=this.yy[ie]);q.setInput(he,de.yy),de.yy.lexer=q,de.yy.parser=this,typeof q.yylloc>"u"&&(q.yylloc={});var oe=q.yylloc;ae.push(oe);var V=q.options&&q.options.ranges;typeof de.yy.parseError=="function"?this.parseError=de.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Te(ct){J.length=J.length-2*ct,se.length=se.length-ct,ae.length=ae.length-ct}o(Te,"popStack");function W(){var ct;return ct=Se.pop()||q.lex()||Ie,typeof ct!="number"&&(ct instanceof Array&&(Se=ct,ct=Se.pop()),ct=le.symbols_[ct]||ct),ct}o(W,"lex");for(var pe,ve,Pe,_e,be,Ve,De={},qe,at,Rt,st;;){if(Pe=J[J.length-1],this.defaultActions[Pe]?_e=this.defaultActions[Pe]:((pe===null||typeof pe>"u")&&(pe=W()),_e=Oe[Pe]&&Oe[Pe][pe]),typeof _e>"u"||!_e.length||!_e[0]){var Ue="";st=[];for(qe in Oe[Pe])this.terminals_[qe]&&qe>Le&&st.push("'"+this.terminals_[qe]+"'");q.showPosition?Ue="Parse error on line "+(Be+1)+`: -`+q.showPosition()+` -Expecting `+st.join(", ")+", got '"+(this.terminals_[pe]||pe)+"'":Ue="Parse error on line "+(Be+1)+": Unexpected "+(pe==Ie?"end of input":"'"+(this.terminals_[pe]||pe)+"'"),this.parseError(Ue,{text:q.match,token:this.terminals_[pe]||pe,line:q.yylineno,loc:oe,expected:st})}if(_e[0]instanceof Array&&_e.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Pe+", token: "+pe);switch(_e[0]){case 1:J.push(pe),se.push(q.yytext),ae.push(q.yylloc),J.push(_e[1]),pe=null,ve?(pe=ve,ve=null):(He=q.yyleng,ye=q.yytext,Be=q.yylineno,oe=q.yylloc,ze>0&&ze--);break;case 2:if(at=this.productions_[_e[1]][1],De.$=se[se.length-at],De._$={first_line:ae[ae.length-(at||1)].first_line,last_line:ae[ae.length-1].last_line,first_column:ae[ae.length-(at||1)].first_column,last_column:ae[ae.length-1].last_column},V&&(De._$.range=[ae[ae.length-(at||1)].range[0],ae[ae.length-1].range[1]]),Ve=this.performAction.apply(De,[ye,He,Be,de.yy,_e[1],se,ae].concat(xe)),typeof Ve<"u")return Ve;at&&(J=J.slice(0,-1*at*2),se=se.slice(0,-1*at),ae=ae.slice(0,-1*at)),J.push(this.productions_[_e[1]][0]),se.push(De.$),ae.push(De._$),Rt=Oe[J[J.length-2]][J[J.length-1]],J.push(Rt);break;case 3:return!0}}return!0},"parse")},j=function(){var te={EOF:1,parseError:o(function(le,J){if(this.yy.parser)this.yy.parser.parseError(le,J);else throw new Error(le)},"parseError"),setInput:o(function(he,le){return this.yy=le||this.yy||{},this._input=he,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var he=this._input[0];this.yytext+=he,this.yyleng++,this.offset++,this.match+=he,this.matched+=he;var le=he.match(/(?:\r\n?|\n).*/g);return le?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),he},"input"),unput:o(function(he){var le=he.length,J=he.split(/(?:\r\n?|\n)/g);this._input=he+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-le),this.offset-=le;var Se=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),J.length-1&&(this.yylineno-=J.length-1);var se=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:J?(J.length===Se.length?this.yylloc.first_column:0)+Se[Se.length-J.length].length-J[0].length:this.yylloc.first_column-le},this.options.ranges&&(this.yylloc.range=[se[0],se[0]+this.yyleng-le]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(he){this.unput(this.match.slice(he))},"less"),pastInput:o(function(){var he=this.matched.substr(0,this.matched.length-this.match.length);return(he.length>20?"...":"")+he.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var he=this.match;return he.length<20&&(he+=this._input.substr(0,20-he.length)),(he.substr(0,20)+(he.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var he=this.pastInput(),le=new Array(he.length+1).join("-");return he+this.upcomingInput()+` -`+le+"^"},"showPosition"),test_match:o(function(he,le){var J,Se,se;if(this.options.backtrack_lexer&&(se={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(se.yylloc.range=this.yylloc.range.slice(0))),Se=he[0].match(/(?:\r\n?|\n).*/g),Se&&(this.yylineno+=Se.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Se?Se[Se.length-1].length-Se[Se.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+he[0].length},this.yytext+=he[0],this.match+=he[0],this.matches=he,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(he[0].length),this.matched+=he[0],J=this.performAction.call(this,this.yy,this,le,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),J)return J;if(this._backtrack){for(var ae in se)this[ae]=se[ae];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var he,le,J,Se;this._more||(this.yytext="",this.match="");for(var se=this._currentRules(),ae=0;aele[0].length)){if(le=J,Se=ae,this.options.backtrack_lexer){if(he=this.test_match(J,se[ae]),he!==!1)return he;if(this._backtrack){le=!1;continue}else return!1}else if(!this.options.flex)break}return le?(he=this.test_match(le,se[Se]),he!==!1?he:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var le=this.next();return le||this.lex()},"lex"),begin:o(function(le){this.conditionStack.push(le)},"begin"),popState:o(function(){var le=this.conditionStack.length-1;return le>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(le){return le=this.conditionStack.length-1-Math.abs(le||0),le>=0?this.conditionStack[le]:"INITIAL"},"topState"),pushState:o(function(le){this.begin(le)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(le,J,Se,se){var ae=se;switch(Se){case 0:return this.begin("acc_title"),24;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),26;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 33;case 8:return 34;case 9:return 35;case 10:return 36;case 11:return 10;case 12:break;case 13:return 8;case 14:return 50;case 15:return 70;case 16:return 4;case 17:return this.begin("block"),17;break;case 18:return 49;case 19:return 49;case 20:return 42;case 21:return 15;case 22:return 13;case 23:break;case 24:return 59;case 25:return 56;case 26:return 56;case 27:return 60;case 28:break;case 29:return this.popState(),19;break;case 30:return J.yytext[0];case 31:return 20;case 32:return 21;case 33:return this.begin("style"),44;break;case 34:return this.popState(),10;break;case 35:break;case 36:return 13;case 37:return 42;case 38:return 49;case 39:return this.begin("style"),37;break;case 40:return 43;case 41:return 63;case 42:return 65;case 43:return 65;case 44:return 65;case 45:return 63;case 46:return 63;case 47:return 64;case 48:return 64;case 49:return 64;case 50:return 64;case 51:return 64;case 52:return 65;case 53:return 64;case 54:return 65;case 55:return 66;case 56:return 66;case 57:return 66;case 58:return 66;case 59:return 63;case 60:return 64;case 61:return 65;case 62:return 67;case 63:return 68;case 64:return 69;case 65:return 69;case 66:return 68;case 67:return 68;case 68:return 68;case 69:return 41;case 70:return 47;case 71:return 40;case 72:return 48;case 73:return J.yytext[0];case 74:return 6}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:#)/i,/^(?:#)/i,/^(?:,)/i,/^(?::::)/i,/^(?::)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:([^\s]*)[~].*[~]([^\s]*))/i,/^(?:([\*A-Za-z_\u00C0-\uFFFF][A-Za-z0-9\-\_\[\]\(\)\u00C0-\uFFFF\*]*))/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:style\b)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?::)/i,/^(?:,)/i,/^(?:#)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:;)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:[0-9])/i,/^(?:.)/i,/^(?:$)/i],conditions:{style:{rules:[34,35,36,37,38,69,70],inclusive:!1},acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[23,24,25,26,27,28,29,30],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,31,32,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,71,72,73,74],inclusive:!0}}};return te}();Q.lexer=j;function ne(){this.yy={}}return o(ne,"Parser"),ne.prototype=Q,Q.Parser=ne,new ne}();iN.parser=iN;pse=iN});var Tk,gse=N(()=>{"use strict";yt();Gt();ci();er();Tk=class{constructor(){this.entities=new Map;this.relationships=[];this.classes=new Map;this.direction="TB";this.Cardinality={ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"};this.Identification={NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"};this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().er,"getConfig");this.clear(),this.addEntity=this.addEntity.bind(this),this.addAttributes=this.addAttributes.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setDirection=this.setDirection.bind(this),this.addCssStyles=this.addCssStyles.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"ErDB")}addEntity(e,r=""){return this.entities.has(e)?!this.entities.get(e)?.alias&&r&&(this.entities.get(e).alias=r,X.info(`Add alias '${r}' to entity '${e}'`)):(this.entities.set(e,{id:`entity-${e}-${this.entities.size}`,label:e,attributes:[],alias:r,shape:"erBox",look:me().look??"default",cssClasses:"default",cssStyles:[]}),X.info("Added new entity :",e)),this.entities.get(e)}getEntity(e){return this.entities.get(e)}getEntities(){return this.entities}getClasses(){return this.classes}addAttributes(e,r){let n=this.addEntity(e),i;for(i=r.length-1;i>=0;i--)r[i].keys||(r[i].keys=[]),r[i].comment||(r[i].comment=""),n.attributes.push(r[i]),X.debug("Added attribute ",r[i].name)}addRelationship(e,r,n,i){let a=this.entities.get(e),s=this.entities.get(n);if(!a||!s)return;let l={entityA:a.id,roleA:r,entityB:s.id,relSpec:i};this.relationships.push(l),X.debug("Added new relationship :",l)}getRelationships(){return this.relationships}getDirection(){return this.direction}setDirection(e){this.direction=e}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}addCssStyles(e,r){for(let n of e){let i=this.entities.get(n);if(!r||!i)return;for(let a of r)i.cssStyles.push(a)}}addClass(e,r){e.forEach(n=>{let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)})})}setClass(e,r){for(let n of e){let i=this.entities.get(n);if(i)for(let a of r)i.cssClasses+=" "+a}}clear(){this.entities=new Map,this.classes=new Map,this.relationships=[],kr()}getData(){let e=[],r=[],n=me();for(let a of this.entities.keys()){let s=this.entities.get(a);s&&(s.cssCompiledStyles=this.getCompiledStyles(s.cssClasses.split(" ")),e.push(s))}let i=0;for(let a of this.relationships){let s={id:Wh(a.entityA,a.entityB,{prefix:"id",counter:i++}),type:"normal",curve:"basis",start:a.entityA,end:a.entityB,label:a.roleA,labelpos:"c",thickness:"normal",classes:"relationshipLine",arrowTypeStart:a.relSpec.cardB.toLowerCase(),arrowTypeEnd:a.relSpec.cardA.toLowerCase(),pattern:a.relSpec.relType=="IDENTIFYING"?"solid":"dashed",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:"TB"}}}});var aN={};ur(aN,{draw:()=>ZPe});var ZPe,yse=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();fr();ZPe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing er diagram (unified)",e);let{securityLevel:i,er:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.config.flowchart.nodeSpacing=a?.nodeSpacing||140,l.config.flowchart.rankSpacing=a?.rankSpacing||80,l.direction=n.db.getDirection(),l.markers=["only_one","zero_or_one","one_or_more","zero_or_more"],l.diagramId=e,await Rc(l,u),l.layoutAlgorithm==="elk"&&u.select(".edges").lower();let h=u.selectAll('[id*="-background"]');Array.from(h).length>0&&h.each(function(){let d=Ge(this),m=d.attr("id").replace("-background",""),g=u.select(`#${CSS.escape(m)}`);if(!g.empty()){let y=g.attr("transform");d.attr("transform",y)}});let f=8;Vt.insertTitle(u,"erDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,f,"erDiagram",a?.useMaxWidth??!0)},"draw")});var JPe,eBe,vse,xse=N(()=>{"use strict";Ks();JPe=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),eBe=o(t=>` - .entityBox { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - } - - .relationshipLabelBox { - fill: ${t.tertiaryColor}; - opacity: 0.7; - background-color: ${t.tertiaryColor}; - rect { - opacity: 0.5; - } - } - - .labelBkg { - background-color: ${JPe(t.tertiaryColor,.5)}; - } - - .edgeLabel .label { - fill: ${t.nodeBorder}; - font-size: 14px; - } - - .label { - font-family: ${t.fontFamily}; - color: ${t.nodeTextColor||t.textColor}; - } - - .edge-pattern-dashed { - stroke-dasharray: 8,8; - } - - .node rect, - .node circle, - .node ellipse, - .node polygon - { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - stroke-width: 1px; - } - - .relationshipLine { - stroke: ${t.lineColor}; - stroke-width: 1; - fill: none; - } - - .marker { - fill: none !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; - } -`,"getStyles"),vse=eBe});var bse={};ur(bse,{diagram:()=>tBe});var tBe,Tse=N(()=>{"use strict";mse();gse();yse();xse();tBe={parser:pse,get db(){return new Tk},renderer:aN,styles:vse}});function si(t){return typeof t=="object"&&t!==null&&typeof t.$type=="string"}function ya(t){return typeof t=="object"&&t!==null&&typeof t.$refText=="string"}function sN(t){return typeof t=="object"&&t!==null&&typeof t.name=="string"&&typeof t.type=="string"&&typeof t.path=="string"}function ap(t){return typeof t=="object"&&t!==null&&si(t.container)&&ya(t.reference)&&typeof t.message=="string"}function Ml(t){return typeof t=="object"&&t!==null&&Array.isArray(t.content)}function hf(t){return typeof t=="object"&&t!==null&&typeof t.tokenType=="object"}function U2(t){return Ml(t)&&typeof t.fullText=="string"}var ip,Il=N(()=>{"use strict";o(si,"isAstNode");o(ya,"isReference");o(sN,"isAstNodeDescription");o(ap,"isLinkingError");ip=class{static{o(this,"AbstractAstReflection")}constructor(){this.subtypes={},this.allSubtypes={}}isInstance(e,r){return si(e)&&this.isSubtype(e.$type,r)}isSubtype(e,r){if(e===r)return!0;let n=this.subtypes[e];n||(n=this.subtypes[e]={});let i=n[r];if(i!==void 0)return i;{let a=this.computeIsSubtype(e,r);return n[r]=a,a}}getAllSubTypes(e){let r=this.allSubtypes[e];if(r)return r;{let n=this.getAllTypes(),i=[];for(let a of n)this.isSubtype(a,e)&&i.push(a);return this.allSubtypes[e]=i,i}}};o(Ml,"isCompositeCstNode");o(hf,"isLeafCstNode");o(U2,"isRootCstNode")});function aBe(t){return typeof t=="string"?t:typeof t>"u"?"undefined":typeof t.toString=="function"?t.toString():Object.prototype.toString.call(t)}function wk(t){return!!t&&typeof t[Symbol.iterator]=="function"}function en(...t){if(t.length===1){let e=t[0];if(e instanceof co)return e;if(wk(e))return new co(()=>e[Symbol.iterator](),r=>r.next());if(typeof e.length=="number")return new co(()=>({index:0}),r=>r.index1?new co(()=>({collIndex:0,arrIndex:0}),e=>{do{if(e.iterator){let r=e.iterator.next();if(!r.done)return r;e.iterator=void 0}if(e.array){if(e.arrIndex{"use strict";co=class t{static{o(this,"StreamImpl")}constructor(e,r){this.startFn=e,this.nextFn=r}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),[Symbol.iterator]:()=>e};return e}[Symbol.iterator](){return this.iterator()}isEmpty(){return!!this.iterator().next().done}count(){let e=this.iterator(),r=0,n=e.next();for(;!n.done;)r++,n=e.next();return r}toArray(){let e=[],r=this.iterator(),n;do n=r.next(),n.value!==void 0&&e.push(n.value);while(!n.done);return e}toSet(){return new Set(this)}toMap(e,r){let n=this.map(i=>[e?e(i):i,r?r(i):i]);return new Map(n)}toString(){return this.join()}concat(e){return new t(()=>({first:this.startFn(),firstDone:!1,iterator:e[Symbol.iterator]()}),r=>{let n;if(!r.firstDone){do if(n=this.nextFn(r.first),!n.done)return n;while(!n.done);r.firstDone=!0}do if(n=r.iterator.next(),!n.done)return n;while(!n.done);return Ba})}join(e=","){let r=this.iterator(),n="",i,a=!1;do i=r.next(),i.done||(a&&(n+=e),n+=aBe(i.value)),a=!0;while(!i.done);return n}indexOf(e,r=0){let n=this.iterator(),i=0,a=n.next();for(;!a.done;){if(i>=r&&a.value===e)return i;a=n.next(),i++}return-1}every(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(!e(n.value))return!1;n=r.next()}return!0}some(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return!0;n=r.next()}return!1}forEach(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;)e(i.value,n),i=r.next(),n++}map(e){return new t(this.startFn,r=>{let{done:n,value:i}=this.nextFn(r);return n?Ba:{done:!1,value:e(i)}})}filter(e){return new t(this.startFn,r=>{let n;do if(n=this.nextFn(r),!n.done&&e(n.value))return n;while(!n.done);return Ba})}nonNullable(){return this.filter(e=>e!=null)}reduce(e,r){let n=this.iterator(),i=r,a=n.next();for(;!a.done;)i===void 0?i=a.value:i=e(i,a.value),a=n.next();return i}reduceRight(e,r){return this.recursiveReduce(this.iterator(),e,r)}recursiveReduce(e,r,n){let i=e.next();if(i.done)return n;let a=this.recursiveReduce(e,r,n);return a===void 0?i.value:r(a,i.value)}find(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return n.value;n=r.next()}}findIndex(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;){if(e(i.value))return n;i=r.next(),n++}return-1}includes(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(n.value===e)return!0;n=r.next()}return!1}flatMap(e){return new t(()=>({this:this.startFn()}),r=>{do{if(r.iterator){let a=r.iterator.next();if(a.done)r.iterator=void 0;else return a}let{done:n,value:i}=this.nextFn(r.this);if(!n){let a=e(i);if(wk(a))r.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}}while(r.iterator);return Ba})}flat(e){if(e===void 0&&(e=1),e<=0)return this;let r=e>1?this.flat(e-1):this;return new t(()=>({this:r.startFn()}),n=>{do{if(n.iterator){let s=n.iterator.next();if(s.done)n.iterator=void 0;else return s}let{done:i,value:a}=r.nextFn(n.this);if(!i)if(wk(a))n.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}while(n.iterator);return Ba})}head(){let r=this.iterator().next();if(!r.done)return r.value}tail(e=1){return new t(()=>{let r=this.startFn();for(let n=0;n({size:0,state:this.startFn()}),r=>(r.size++,r.size>e?Ba:this.nextFn(r.state)))}distinct(e){return new t(()=>({set:new Set,internalState:this.startFn()}),r=>{let n;do if(n=this.nextFn(r.internalState),!n.done){let i=e?e(n.value):n.value;if(!r.set.has(i))return r.set.add(i),n}while(!n.done);return Ba})}exclude(e,r){let n=new Set;for(let i of e){let a=r?r(i):i;n.add(a)}return this.filter(i=>{let a=r?r(i):i;return!n.has(a)})}};o(aBe,"toString");o(wk,"isIterable");H2=new co(()=>{},()=>Ba),Ba=Object.freeze({done:!0,value:void 0});o(en,"stream");Mc=class extends co{static{o(this,"TreeStreamImpl")}constructor(e,r,n){super(()=>({iterators:n?.includeRoot?[[e][Symbol.iterator]()]:[r(e)[Symbol.iterator]()],pruned:!1}),i=>{for(i.pruned&&(i.iterators.pop(),i.pruned=!1);i.iterators.length>0;){let s=i.iterators[i.iterators.length-1].next();if(s.done)i.iterators.pop();else return i.iterators.push(r(s.value)[Symbol.iterator]()),s}return Ba})}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),prune:o(()=>{e.state.pruned=!0},"prune"),[Symbol.iterator]:()=>e};return e}};(function(t){function e(a){return a.reduce((s,l)=>s+l,0)}o(e,"sum"),t.sum=e;function r(a){return a.reduce((s,l)=>s*l,0)}o(r,"product"),t.product=r;function n(a){return a.reduce((s,l)=>Math.min(s,l))}o(n,"min"),t.min=n;function i(a){return a.reduce((s,l)=>Math.max(s,l))}o(i,"max"),t.max=i})(jm||(jm={}))});var Ek={};ur(Ek,{DefaultNameRegexp:()=>kk,RangeComparison:()=>Ic,compareRange:()=>Sse,findCommentNode:()=>uN,findDeclarationNodeAtOffset:()=>oBe,findLeafNodeAtOffset:()=>hN,findLeafNodeBeforeOffset:()=>Cse,flattenCst:()=>sBe,getInteriorNodes:()=>uBe,getNextNode:()=>lBe,getPreviousNode:()=>_se,getStartlineNode:()=>cBe,inRange:()=>cN,isChildNode:()=>lN,isCommentNode:()=>oN,streamCst:()=>sp,toDocumentSegment:()=>op,tokenToRange:()=>Km});function sp(t){return new Mc(t,e=>Ml(e)?e.content:[],{includeRoot:!0})}function sBe(t){return sp(t).filter(hf)}function lN(t,e){for(;t.container;)if(t=t.container,t===e)return!0;return!1}function Km(t){return{start:{character:t.startColumn-1,line:t.startLine-1},end:{character:t.endColumn,line:t.endLine-1}}}function op(t){if(!t)return;let{offset:e,end:r,range:n}=t;return{range:n,offset:e,end:r,length:r-e}}function Sse(t,e){if(t.end.linee.end.line||t.start.line===e.end.line&&t.start.character>=e.end.character)return Ic.After;let r=t.start.line>e.start.line||t.start.line===e.start.line&&t.start.character>=e.start.character,n=t.end.lineIc.After}function oBe(t,e,r=kk){if(t){if(e>0){let n=e-t.offset,i=t.text.charAt(n);r.test(i)||e--}return hN(t,e)}}function uN(t,e){if(t){let r=_se(t,!0);if(r&&oN(r,e))return r;if(U2(t)){let n=t.content.findIndex(i=>!i.hidden);for(let i=n-1;i>=0;i--){let a=t.content[i];if(oN(a,e))return a}}}}function oN(t,e){return hf(t)&&e.includes(t.tokenType.name)}function hN(t,e){if(hf(t))return t;if(Ml(t)){let r=Ase(t,e,!1);if(r)return hN(r,e)}}function Cse(t,e){if(hf(t))return t;if(Ml(t)){let r=Ase(t,e,!0);if(r)return Cse(r,e)}}function Ase(t,e,r){let n=0,i=t.content.length-1,a;for(;n<=i;){let s=Math.floor((n+i)/2),l=t.content[s];if(l.offset<=e&&l.end>e)return l;l.end<=e?(a=r?l:void 0,n=s+1):i=s-1}return a}function _se(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t);for(;n>0;){n--;let i=r.content[n];if(e||!i.hidden)return i}t=r}}function lBe(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t),i=r.content.length-1;for(;n{"use strict";Il();Gs();o(sp,"streamCst");o(sBe,"flattenCst");o(lN,"isChildNode");o(Km,"tokenToRange");o(op,"toDocumentSegment");(function(t){t[t.Before=0]="Before",t[t.After=1]="After",t[t.OverlapFront=2]="OverlapFront",t[t.OverlapBack=3]="OverlapBack",t[t.Inside=4]="Inside",t[t.Outside=5]="Outside"})(Ic||(Ic={}));o(Sse,"compareRange");o(cN,"inRange");kk=/^[\w\p{L}]$/u;o(oBe,"findDeclarationNodeAtOffset");o(uN,"findCommentNode");o(oN,"isCommentNode");o(hN,"findLeafNodeAtOffset");o(Cse,"findLeafNodeBeforeOffset");o(Ase,"binarySearch");o(_se,"getPreviousNode");o(lBe,"getNextNode");o(cBe,"getStartlineNode");o(uBe,"getInteriorNodes");o(hBe,"getCommonParent");o(Ese,"getParentChain")});function Oc(t){throw new Error("Error! The input value was not handled.")}var lp,Sk=N(()=>{"use strict";lp=class extends Error{static{o(this,"ErrorWithLocation")}constructor(e,r){super(e?`${r} at ${e.range.start.line}:${e.range.start.character}`:r)}};o(Oc,"assertUnreachable")});var J2={};ur(J2,{AbstractElement:()=>Jm,AbstractRule:()=>Qm,AbstractType:()=>Zm,Action:()=>vg,Alternatives:()=>xg,ArrayLiteral:()=>eg,ArrayType:()=>tg,Assignment:()=>bg,BooleanLiteral:()=>rg,CharacterRange:()=>Tg,Condition:()=>W2,Conjunction:()=>ng,CrossReference:()=>wg,Disjunction:()=>ig,EndOfFile:()=>kg,Grammar:()=>ag,GrammarImport:()=>Y2,Group:()=>Eg,InferredType:()=>sg,Interface:()=>og,Keyword:()=>Sg,LangiumGrammarAstReflection:()=>Og,LangiumGrammarTerminals:()=>fBe,NamedArgument:()=>X2,NegatedToken:()=>Cg,Negation:()=>lg,NumberLiteral:()=>cg,Parameter:()=>ug,ParameterReference:()=>hg,ParserRule:()=>fg,ReferenceType:()=>dg,RegexToken:()=>Ag,ReturnType:()=>j2,RuleCall:()=>_g,SimpleType:()=>pg,StringLiteral:()=>mg,TerminalAlternatives:()=>Dg,TerminalGroup:()=>Lg,TerminalRule:()=>cp,TerminalRuleCall:()=>Rg,Type:()=>gg,TypeAttribute:()=>K2,TypeDefinition:()=>Ck,UnionType:()=>yg,UnorderedGroup:()=>Ng,UntilToken:()=>Mg,ValueLiteral:()=>q2,Wildcard:()=>Ig,isAbstractElement:()=>Q2,isAbstractRule:()=>dBe,isAbstractType:()=>pBe,isAction:()=>$u,isAlternatives:()=>Lk,isArrayLiteral:()=>xBe,isArrayType:()=>fN,isAssignment:()=>Pl,isBooleanLiteral:()=>dN,isCharacterRange:()=>TN,isCondition:()=>mBe,isConjunction:()=>pN,isCrossReference:()=>up,isDisjunction:()=>mN,isEndOfFile:()=>wN,isFeatureName:()=>gBe,isGrammar:()=>bBe,isGrammarImport:()=>TBe,isGroup:()=>ff,isInferredType:()=>Ak,isInterface:()=>_k,isKeyword:()=>Xo,isNamedArgument:()=>wBe,isNegatedToken:()=>kN,isNegation:()=>gN,isNumberLiteral:()=>kBe,isParameter:()=>EBe,isParameterReference:()=>yN,isParserRule:()=>Fa,isPrimitiveType:()=>Dse,isReferenceType:()=>vN,isRegexToken:()=>EN,isReturnType:()=>xN,isRuleCall:()=>Bl,isSimpleType:()=>Dk,isStringLiteral:()=>SBe,isTerminalAlternatives:()=>SN,isTerminalGroup:()=>CN,isTerminalRule:()=>uo,isTerminalRuleCall:()=>Rk,isType:()=>Z2,isTypeAttribute:()=>CBe,isTypeDefinition:()=>yBe,isUnionType:()=>bN,isUnorderedGroup:()=>Nk,isUntilToken:()=>AN,isValueLiteral:()=>vBe,isWildcard:()=>_N,reflection:()=>cr});function dBe(t){return cr.isInstance(t,Qm)}function pBe(t){return cr.isInstance(t,Zm)}function mBe(t){return cr.isInstance(t,W2)}function gBe(t){return Dse(t)||t==="current"||t==="entry"||t==="extends"||t==="false"||t==="fragment"||t==="grammar"||t==="hidden"||t==="import"||t==="interface"||t==="returns"||t==="terminal"||t==="true"||t==="type"||t==="infer"||t==="infers"||t==="with"||typeof t=="string"&&/\^?[_a-zA-Z][\w_]*/.test(t)}function Dse(t){return t==="string"||t==="number"||t==="boolean"||t==="Date"||t==="bigint"}function yBe(t){return cr.isInstance(t,Ck)}function vBe(t){return cr.isInstance(t,q2)}function Q2(t){return cr.isInstance(t,Jm)}function xBe(t){return cr.isInstance(t,eg)}function fN(t){return cr.isInstance(t,tg)}function dN(t){return cr.isInstance(t,rg)}function pN(t){return cr.isInstance(t,ng)}function mN(t){return cr.isInstance(t,ig)}function bBe(t){return cr.isInstance(t,ag)}function TBe(t){return cr.isInstance(t,Y2)}function Ak(t){return cr.isInstance(t,sg)}function _k(t){return cr.isInstance(t,og)}function wBe(t){return cr.isInstance(t,X2)}function gN(t){return cr.isInstance(t,lg)}function kBe(t){return cr.isInstance(t,cg)}function EBe(t){return cr.isInstance(t,ug)}function yN(t){return cr.isInstance(t,hg)}function Fa(t){return cr.isInstance(t,fg)}function vN(t){return cr.isInstance(t,dg)}function xN(t){return cr.isInstance(t,j2)}function Dk(t){return cr.isInstance(t,pg)}function SBe(t){return cr.isInstance(t,mg)}function uo(t){return cr.isInstance(t,cp)}function Z2(t){return cr.isInstance(t,gg)}function CBe(t){return cr.isInstance(t,K2)}function bN(t){return cr.isInstance(t,yg)}function $u(t){return cr.isInstance(t,vg)}function Lk(t){return cr.isInstance(t,xg)}function Pl(t){return cr.isInstance(t,bg)}function TN(t){return cr.isInstance(t,Tg)}function up(t){return cr.isInstance(t,wg)}function wN(t){return cr.isInstance(t,kg)}function ff(t){return cr.isInstance(t,Eg)}function Xo(t){return cr.isInstance(t,Sg)}function kN(t){return cr.isInstance(t,Cg)}function EN(t){return cr.isInstance(t,Ag)}function Bl(t){return cr.isInstance(t,_g)}function SN(t){return cr.isInstance(t,Dg)}function CN(t){return cr.isInstance(t,Lg)}function Rk(t){return cr.isInstance(t,Rg)}function Nk(t){return cr.isInstance(t,Ng)}function AN(t){return cr.isInstance(t,Mg)}function _N(t){return cr.isInstance(t,Ig)}var fBe,Qm,Zm,W2,Ck,q2,Jm,eg,tg,rg,ng,ig,ag,Y2,sg,og,X2,lg,cg,ug,hg,fg,dg,j2,pg,mg,cp,gg,K2,yg,vg,xg,bg,Tg,wg,kg,Eg,Sg,Cg,Ag,_g,Dg,Lg,Rg,Ng,Mg,Ig,Og,cr,Pc=N(()=>{"use strict";Il();fBe={ID:/\^?[_a-zA-Z][\w_]*/,STRING:/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/,NUMBER:/NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)/,RegexLiteral:/\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/[a-z]*/,WS:/\s+/,ML_COMMENT:/\/\*[\s\S]*?\*\//,SL_COMMENT:/\/\/[^\n\r]*/},Qm="AbstractRule";o(dBe,"isAbstractRule");Zm="AbstractType";o(pBe,"isAbstractType");W2="Condition";o(mBe,"isCondition");o(gBe,"isFeatureName");o(Dse,"isPrimitiveType");Ck="TypeDefinition";o(yBe,"isTypeDefinition");q2="ValueLiteral";o(vBe,"isValueLiteral");Jm="AbstractElement";o(Q2,"isAbstractElement");eg="ArrayLiteral";o(xBe,"isArrayLiteral");tg="ArrayType";o(fN,"isArrayType");rg="BooleanLiteral";o(dN,"isBooleanLiteral");ng="Conjunction";o(pN,"isConjunction");ig="Disjunction";o(mN,"isDisjunction");ag="Grammar";o(bBe,"isGrammar");Y2="GrammarImport";o(TBe,"isGrammarImport");sg="InferredType";o(Ak,"isInferredType");og="Interface";o(_k,"isInterface");X2="NamedArgument";o(wBe,"isNamedArgument");lg="Negation";o(gN,"isNegation");cg="NumberLiteral";o(kBe,"isNumberLiteral");ug="Parameter";o(EBe,"isParameter");hg="ParameterReference";o(yN,"isParameterReference");fg="ParserRule";o(Fa,"isParserRule");dg="ReferenceType";o(vN,"isReferenceType");j2="ReturnType";o(xN,"isReturnType");pg="SimpleType";o(Dk,"isSimpleType");mg="StringLiteral";o(SBe,"isStringLiteral");cp="TerminalRule";o(uo,"isTerminalRule");gg="Type";o(Z2,"isType");K2="TypeAttribute";o(CBe,"isTypeAttribute");yg="UnionType";o(bN,"isUnionType");vg="Action";o($u,"isAction");xg="Alternatives";o(Lk,"isAlternatives");bg="Assignment";o(Pl,"isAssignment");Tg="CharacterRange";o(TN,"isCharacterRange");wg="CrossReference";o(up,"isCrossReference");kg="EndOfFile";o(wN,"isEndOfFile");Eg="Group";o(ff,"isGroup");Sg="Keyword";o(Xo,"isKeyword");Cg="NegatedToken";o(kN,"isNegatedToken");Ag="RegexToken";o(EN,"isRegexToken");_g="RuleCall";o(Bl,"isRuleCall");Dg="TerminalAlternatives";o(SN,"isTerminalAlternatives");Lg="TerminalGroup";o(CN,"isTerminalGroup");Rg="TerminalRuleCall";o(Rk,"isTerminalRuleCall");Ng="UnorderedGroup";o(Nk,"isUnorderedGroup");Mg="UntilToken";o(AN,"isUntilToken");Ig="Wildcard";o(_N,"isWildcard");Og=class extends ip{static{o(this,"LangiumGrammarAstReflection")}getAllTypes(){return[Jm,Qm,Zm,vg,xg,eg,tg,bg,rg,Tg,W2,ng,wg,ig,kg,ag,Y2,Eg,sg,og,Sg,X2,Cg,lg,cg,ug,hg,fg,dg,Ag,j2,_g,pg,mg,Dg,Lg,cp,Rg,gg,K2,Ck,yg,Ng,Mg,q2,Ig]}computeIsSubtype(e,r){switch(e){case vg:case xg:case bg:case Tg:case wg:case kg:case Eg:case Sg:case Cg:case Ag:case _g:case Dg:case Lg:case Rg:case Ng:case Mg:case Ig:return this.isSubtype(Jm,r);case eg:case cg:case mg:return this.isSubtype(q2,r);case tg:case dg:case pg:case yg:return this.isSubtype(Ck,r);case rg:return this.isSubtype(W2,r)||this.isSubtype(q2,r);case ng:case ig:case lg:case hg:return this.isSubtype(W2,r);case sg:case og:case gg:return this.isSubtype(Zm,r);case fg:return this.isSubtype(Qm,r)||this.isSubtype(Zm,r);case cp:return this.isSubtype(Qm,r);default:return!1}}getReferenceType(e){let r=`${e.container.$type}:${e.property}`;switch(r){case"Action:type":case"CrossReference:type":case"Interface:superTypes":case"ParserRule:returnType":case"SimpleType:typeRef":return Zm;case"Grammar:hiddenTokens":case"ParserRule:hiddenTokens":case"RuleCall:rule":return Qm;case"Grammar:usedGrammars":return ag;case"NamedArgument:parameter":case"ParameterReference:parameter":return ug;case"TerminalRuleCall:rule":return cp;default:throw new Error(`${r} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case Jm:return{name:Jm,properties:[{name:"cardinality"},{name:"lookahead"}]};case eg:return{name:eg,properties:[{name:"elements",defaultValue:[]}]};case tg:return{name:tg,properties:[{name:"elementType"}]};case rg:return{name:rg,properties:[{name:"true",defaultValue:!1}]};case ng:return{name:ng,properties:[{name:"left"},{name:"right"}]};case ig:return{name:ig,properties:[{name:"left"},{name:"right"}]};case ag:return{name:ag,properties:[{name:"definesHiddenTokens",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"imports",defaultValue:[]},{name:"interfaces",defaultValue:[]},{name:"isDeclared",defaultValue:!1},{name:"name"},{name:"rules",defaultValue:[]},{name:"types",defaultValue:[]},{name:"usedGrammars",defaultValue:[]}]};case Y2:return{name:Y2,properties:[{name:"path"}]};case sg:return{name:sg,properties:[{name:"name"}]};case og:return{name:og,properties:[{name:"attributes",defaultValue:[]},{name:"name"},{name:"superTypes",defaultValue:[]}]};case X2:return{name:X2,properties:[{name:"calledByName",defaultValue:!1},{name:"parameter"},{name:"value"}]};case lg:return{name:lg,properties:[{name:"value"}]};case cg:return{name:cg,properties:[{name:"value"}]};case ug:return{name:ug,properties:[{name:"name"}]};case hg:return{name:hg,properties:[{name:"parameter"}]};case fg:return{name:fg,properties:[{name:"dataType"},{name:"definesHiddenTokens",defaultValue:!1},{name:"definition"},{name:"entry",defaultValue:!1},{name:"fragment",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"inferredType"},{name:"name"},{name:"parameters",defaultValue:[]},{name:"returnType"},{name:"wildcard",defaultValue:!1}]};case dg:return{name:dg,properties:[{name:"referenceType"}]};case j2:return{name:j2,properties:[{name:"name"}]};case pg:return{name:pg,properties:[{name:"primitiveType"},{name:"stringType"},{name:"typeRef"}]};case mg:return{name:mg,properties:[{name:"value"}]};case cp:return{name:cp,properties:[{name:"definition"},{name:"fragment",defaultValue:!1},{name:"hidden",defaultValue:!1},{name:"name"},{name:"type"}]};case gg:return{name:gg,properties:[{name:"name"},{name:"type"}]};case K2:return{name:K2,properties:[{name:"defaultValue"},{name:"isOptional",defaultValue:!1},{name:"name"},{name:"type"}]};case yg:return{name:yg,properties:[{name:"types",defaultValue:[]}]};case vg:return{name:vg,properties:[{name:"cardinality"},{name:"feature"},{name:"inferredType"},{name:"lookahead"},{name:"operator"},{name:"type"}]};case xg:return{name:xg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case bg:return{name:bg,properties:[{name:"cardinality"},{name:"feature"},{name:"lookahead"},{name:"operator"},{name:"terminal"}]};case Tg:return{name:Tg,properties:[{name:"cardinality"},{name:"left"},{name:"lookahead"},{name:"right"}]};case wg:return{name:wg,properties:[{name:"cardinality"},{name:"deprecatedSyntax",defaultValue:!1},{name:"lookahead"},{name:"terminal"},{name:"type"}]};case kg:return{name:kg,properties:[{name:"cardinality"},{name:"lookahead"}]};case Eg:return{name:Eg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"guardCondition"},{name:"lookahead"}]};case Sg:return{name:Sg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"value"}]};case Cg:return{name:Cg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case Ag:return{name:Ag,properties:[{name:"cardinality"},{name:"lookahead"},{name:"regex"}]};case _g:return{name:_g,properties:[{name:"arguments",defaultValue:[]},{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case Dg:return{name:Dg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Lg:return{name:Lg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Rg:return{name:Rg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case Ng:return{name:Ng,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Mg:return{name:Mg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case Ig:return{name:Ig,properties:[{name:"cardinality"},{name:"lookahead"}]};default:return{name:e,properties:[]}}}},cr=new Og});var Ik={};ur(Ik,{assignMandatoryProperties:()=>RN,copyAstNode:()=>LN,findLocalReferences:()=>_Be,findRootNode:()=>ex,getContainerOfType:()=>hp,getDocument:()=>$a,hasContainerOfType:()=>ABe,linkContentToContainer:()=>Mk,streamAllContents:()=>Bc,streamAst:()=>jo,streamContents:()=>tx,streamReferences:()=>Pg});function Mk(t){for(let[e,r]of Object.entries(t))e.startsWith("$")||(Array.isArray(r)?r.forEach((n,i)=>{si(n)&&(n.$container=t,n.$containerProperty=e,n.$containerIndex=i)}):si(r)&&(r.$container=t,r.$containerProperty=e))}function hp(t,e){let r=t;for(;r;){if(e(r))return r;r=r.$container}}function ABe(t,e){let r=t;for(;r;){if(e(r))return!0;r=r.$container}return!1}function $a(t){let r=ex(t).$document;if(!r)throw new Error("AST node has no document.");return r}function ex(t){for(;t.$container;)t=t.$container;return t}function tx(t,e){if(!t)throw new Error("Node must be an AstNode.");let r=e?.range;return new co(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),n=>{for(;n.keyIndextx(r,e))}function jo(t,e){if(t){if(e?.range&&!DN(t,e.range))return new Mc(t,()=>[])}else throw new Error("Root node must be an AstNode.");return new Mc(t,r=>tx(r,e),{includeRoot:!0})}function DN(t,e){var r;if(!e)return!0;let n=(r=t.$cstNode)===null||r===void 0?void 0:r.range;return n?cN(n,e):!1}function Pg(t){return new co(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),e=>{for(;e.keyIndex{Pg(n).forEach(i=>{i.reference.ref===t&&r.push(i.reference)})}),en(r)}function RN(t,e){let r=t.getTypeMetaData(e.$type),n=e;for(let i of r.properties)i.defaultValue!==void 0&&n[i.name]===void 0&&(n[i.name]=Lse(i.defaultValue))}function Lse(t){return Array.isArray(t)?[...t.map(Lse)]:t}function LN(t,e){let r={$type:t.$type};for(let[n,i]of Object.entries(t))if(!n.startsWith("$"))if(si(i))r[n]=LN(i,e);else if(ya(i))r[n]=e(r,n,i.$refNode,i.$refText);else if(Array.isArray(i)){let a=[];for(let s of i)si(s)?a.push(LN(s,e)):ya(s)?a.push(e(r,n,s.$refNode,s.$refText)):a.push(s);r[n]=a}else r[n]=i;return Mk(r),r}var cs=N(()=>{"use strict";Il();Gs();Ol();o(Mk,"linkContentToContainer");o(hp,"getContainerOfType");o(ABe,"hasContainerOfType");o($a,"getDocument");o(ex,"findRootNode");o(tx,"streamContents");o(Bc,"streamAllContents");o(jo,"streamAst");o(DN,"isAstNodeInRange");o(Pg,"streamReferences");o(_Be,"findLocalReferences");o(RN,"assignMandatoryProperties");o(Lse,"copyDefaultValue");o(LN,"copyAstNode")});function sr(t){return t.charCodeAt(0)}function Ok(t,e){Array.isArray(t)?t.forEach(function(r){e.push(r)}):e.push(t)}function Bg(t,e){if(t[e]===!0)throw"duplicate flag "+e;let r=t[e];t[e]=!0}function fp(t){if(t===void 0)throw Error("Internal Error - Should never get here!");return!0}function rx(){throw Error("Internal Error - Should never get here!")}function NN(t){return t.type==="Character"}var MN=N(()=>{"use strict";o(sr,"cc");o(Ok,"insertToSet");o(Bg,"addFlag");o(fp,"ASSERT_EXISTS");o(rx,"ASSERT_NEVER_REACH_HERE");o(NN,"isCharacter")});var nx,ix,IN,Rse=N(()=>{"use strict";MN();nx=[];for(let t=sr("0");t<=sr("9");t++)nx.push(t);ix=[sr("_")].concat(nx);for(let t=sr("a");t<=sr("z");t++)ix.push(t);for(let t=sr("A");t<=sr("Z");t++)ix.push(t);IN=[sr(" "),sr("\f"),sr(` -`),sr("\r"),sr(" "),sr("\v"),sr(" "),sr("\xA0"),sr("\u1680"),sr("\u2000"),sr("\u2001"),sr("\u2002"),sr("\u2003"),sr("\u2004"),sr("\u2005"),sr("\u2006"),sr("\u2007"),sr("\u2008"),sr("\u2009"),sr("\u200A"),sr("\u2028"),sr("\u2029"),sr("\u202F"),sr("\u205F"),sr("\u3000"),sr("\uFEFF")]});var DBe,Pk,LBe,dp,Nse=N(()=>{"use strict";MN();Rse();DBe=/[0-9a-fA-F]/,Pk=/[0-9]/,LBe=/[1-9]/,dp=class{static{o(this,"RegExpParser")}constructor(){this.idx=0,this.input="",this.groupIdx=0}saveState(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}}restoreState(e){this.idx=e.idx,this.input=e.input,this.groupIdx=e.groupIdx}pattern(e){this.idx=0,this.input=e,this.groupIdx=0,this.consumeChar("/");let r=this.disjunction();this.consumeChar("/");let n={type:"Flags",loc:{begin:this.idx,end:e.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};for(;this.isRegExpFlag();)switch(this.popChar()){case"g":Bg(n,"global");break;case"i":Bg(n,"ignoreCase");break;case"m":Bg(n,"multiLine");break;case"u":Bg(n,"unicode");break;case"y":Bg(n,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:r,loc:this.loc(0)}}disjunction(){let e=[],r=this.idx;for(e.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),e.push(this.alternative());return{type:"Disjunction",value:e,loc:this.loc(r)}}alternative(){let e=[],r=this.idx;for(;this.isTerm();)e.push(this.term());return{type:"Alternative",value:e,loc:this.loc(r)}}term(){return this.isAssertion()?this.assertion():this.atom()}assertion(){let e=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(e)};case"$":return{type:"EndAnchor",loc:this.loc(e)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(e)};case"B":return{type:"NonWordBoundary",loc:this.loc(e)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");let r;switch(this.popChar()){case"=":r="Lookahead";break;case"!":r="NegativeLookahead";break}fp(r);let n=this.disjunction();return this.consumeChar(")"),{type:r,value:n,loc:this.loc(e)}}return rx()}quantifier(e=!1){let r,n=this.idx;switch(this.popChar()){case"*":r={atLeast:0,atMost:1/0};break;case"+":r={atLeast:1,atMost:1/0};break;case"?":r={atLeast:0,atMost:1};break;case"{":let i=this.integerIncludingZero();switch(this.popChar()){case"}":r={atLeast:i,atMost:i};break;case",":let a;this.isDigit()?(a=this.integerIncludingZero(),r={atLeast:i,atMost:a}):r={atLeast:i,atMost:1/0},this.consumeChar("}");break}if(e===!0&&r===void 0)return;fp(r);break}if(!(e===!0&&r===void 0)&&fp(r))return this.peekChar(0)==="?"?(this.consumeChar("?"),r.greedy=!1):r.greedy=!0,r.type="Quantifier",r.loc=this.loc(n),r}atom(){let e,r=this.idx;switch(this.peekChar()){case".":e=this.dotAll();break;case"\\":e=this.atomEscape();break;case"[":e=this.characterClass();break;case"(":e=this.group();break}return e===void 0&&this.isPatternCharacter()&&(e=this.patternCharacter()),fp(e)?(e.loc=this.loc(r),this.isQuantifier()&&(e.quantifier=this.quantifier()),e):rx()}dotAll(){return this.consumeChar("."),{type:"Set",complement:!0,value:[sr(` -`),sr("\r"),sr("\u2028"),sr("\u2029")]}}atomEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}decimalEscapeAtom(){return{type:"GroupBackReference",value:this.positiveInteger()}}characterClassEscape(){let e,r=!1;switch(this.popChar()){case"d":e=nx;break;case"D":e=nx,r=!0;break;case"s":e=IN;break;case"S":e=IN,r=!0;break;case"w":e=ix;break;case"W":e=ix,r=!0;break}return fp(e)?{type:"Set",value:e,complement:r}:rx()}controlEscapeAtom(){let e;switch(this.popChar()){case"f":e=sr("\f");break;case"n":e=sr(` -`);break;case"r":e=sr("\r");break;case"t":e=sr(" ");break;case"v":e=sr("\v");break}return fp(e)?{type:"Character",value:e}:rx()}controlLetterEscapeAtom(){this.consumeChar("c");let e=this.popChar();if(/[a-zA-Z]/.test(e)===!1)throw Error("Invalid ");return{type:"Character",value:e.toUpperCase().charCodeAt(0)-64}}nulCharacterAtom(){return this.consumeChar("0"),{type:"Character",value:sr("\0")}}hexEscapeSequenceAtom(){return this.consumeChar("x"),this.parseHexDigits(2)}regExpUnicodeEscapeSequenceAtom(){return this.consumeChar("u"),this.parseHexDigits(4)}identityEscapeAtom(){let e=this.popChar();return{type:"Character",value:sr(e)}}classPatternCharacterAtom(){switch(this.peekChar()){case` -`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:let e=this.popChar();return{type:"Character",value:sr(e)}}}characterClass(){let e=[],r=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),r=!0);this.isClassAtom();){let n=this.classAtom(),i=n.type==="Character";if(NN(n)&&this.isRangeDash()){this.consumeChar("-");let a=this.classAtom(),s=a.type==="Character";if(NN(a)){if(a.value=this.input.length)throw Error("Unexpected end of input");this.idx++}loc(e){return{begin:e,end:this.idx}}}});var Fc,Mse=N(()=>{"use strict";Fc=class{static{o(this,"BaseRegExpVisitor")}visitChildren(e){for(let r in e){let n=e[r];e.hasOwnProperty(r)&&(n.type!==void 0?this.visit(n):Array.isArray(n)&&n.forEach(i=>{this.visit(i)},this))}}visit(e){switch(e.type){case"Pattern":this.visitPattern(e);break;case"Flags":this.visitFlags(e);break;case"Disjunction":this.visitDisjunction(e);break;case"Alternative":this.visitAlternative(e);break;case"StartAnchor":this.visitStartAnchor(e);break;case"EndAnchor":this.visitEndAnchor(e);break;case"WordBoundary":this.visitWordBoundary(e);break;case"NonWordBoundary":this.visitNonWordBoundary(e);break;case"Lookahead":this.visitLookahead(e);break;case"NegativeLookahead":this.visitNegativeLookahead(e);break;case"Character":this.visitCharacter(e);break;case"Set":this.visitSet(e);break;case"Group":this.visitGroup(e);break;case"GroupBackReference":this.visitGroupBackReference(e);break;case"Quantifier":this.visitQuantifier(e);break}this.visitChildren(e)}visitPattern(e){}visitFlags(e){}visitDisjunction(e){}visitAlternative(e){}visitStartAnchor(e){}visitEndAnchor(e){}visitWordBoundary(e){}visitNonWordBoundary(e){}visitLookahead(e){}visitNegativeLookahead(e){}visitCharacter(e){}visitSet(e){}visitGroup(e){}visitGroupBackReference(e){}visitQuantifier(e){}}});var ax=N(()=>{"use strict";Nse();Mse()});var Bk={};ur(Bk,{NEWLINE_REGEXP:()=>PN,escapeRegExp:()=>mp,getCaseInsensitivePattern:()=>FN,getTerminalParts:()=>RBe,isMultilineComment:()=>BN,isWhitespace:()=>Fg,partialMatches:()=>$N,partialRegExp:()=>Pse,whitespaceCharacters:()=>Ose});function RBe(t){try{typeof t!="string"&&(t=t.source),t=`/${t}/`;let e=Ise.pattern(t),r=[];for(let n of e.value.value)pp.reset(t),pp.visit(n),r.push({start:pp.startRegexp,end:pp.endRegex});return r}catch{return[]}}function BN(t){try{return typeof t=="string"&&(t=new RegExp(t)),t=t.toString(),pp.reset(t),pp.visit(Ise.pattern(t)),pp.multiline}catch{return!1}}function Fg(t){let e=typeof t=="string"?new RegExp(t):t;return Ose.some(r=>e.test(r))}function mp(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function FN(t){return Array.prototype.map.call(t,e=>/\w/.test(e)?`[${e.toLowerCase()}${e.toUpperCase()}]`:mp(e)).join("")}function $N(t,e){let r=Pse(t),n=e.match(r);return!!n&&n[0].length>0}function Pse(t){typeof t=="string"&&(t=new RegExp(t));let e=t,r=t.source,n=0;function i(){let a="",s;function l(h){a+=r.substr(n,h),n+=h}o(l,"appendRaw");function u(h){a+="(?:"+r.substr(n,h)+"|$)",n+=h}for(o(u,"appendOptional");n",n)-n+1);break;default:u(2);break}break;case"[":s=/\[(?:\\.|.)*?\]/g,s.lastIndex=n,s=s.exec(r)||[],u(s[0].length);break;case"|":case"^":case"$":case"*":case"+":case"?":l(1);break;case"{":s=/\{\d+,?\d*\}/g,s.lastIndex=n,s=s.exec(r),s?l(s[0].length):u(1);break;case"(":if(r[n+1]==="?")switch(r[n+2]){case":":a+="(?:",n+=3,a+=i()+"|$)";break;case"=":a+="(?=",n+=3,a+=i()+")";break;case"!":s=n,n+=3,i(),a+=r.substr(s,n-s);break;case"<":switch(r[n+3]){case"=":case"!":s=n,n+=4,i(),a+=r.substr(s,n-s);break;default:l(r.indexOf(">",n)-n+1),a+=i()+"|$)";break}break}else l(1),a+=i()+"|$)";break;case")":return++n,a;default:u(1);break}return a}return o(i,"process"),new RegExp(i(),t.flags)}var PN,Ise,ON,pp,Ose,$g=N(()=>{"use strict";ax();PN=/\r?\n/gm,Ise=new dp,ON=class extends Fc{static{o(this,"TerminalRegExpVisitor")}constructor(){super(...arguments),this.isStarting=!0,this.endRegexpStack=[],this.multiline=!1}get endRegex(){return this.endRegexpStack.join("")}reset(e){this.multiline=!1,this.regex=e,this.startRegexp="",this.isStarting=!0,this.endRegexpStack=[]}visitGroup(e){e.quantifier&&(this.isStarting=!1,this.endRegexpStack=[])}visitCharacter(e){let r=String.fromCharCode(e.value);if(!this.multiline&&r===` -`&&(this.multiline=!0),e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let n=mp(r);this.endRegexpStack.push(n),this.isStarting&&(this.startRegexp+=n)}}visitSet(e){if(!this.multiline){let r=this.regex.substring(e.loc.begin,e.loc.end),n=new RegExp(r);this.multiline=!!` -`.match(n)}if(e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let r=this.regex.substring(e.loc.begin,e.loc.end);this.endRegexpStack.push(r),this.isStarting&&(this.startRegexp+=r)}}visitChildren(e){e.type==="Group"&&e.quantifier||super.visitChildren(e)}},pp=new ON;o(RBe,"getTerminalParts");o(BN,"isMultilineComment");Ose=`\f -\r \v \xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF`.split("");o(Fg,"isWhitespace");o(mp,"escapeRegExp");o(FN,"getCaseInsensitivePattern");o($N,"partialMatches");o(Pse,"partialRegExp")});var $k={};ur($k,{findAssignment:()=>XN,findNameAssignment:()=>Fk,findNodeForKeyword:()=>qN,findNodeForProperty:()=>ox,findNodesForKeyword:()=>NBe,findNodesForKeywordInternal:()=>YN,findNodesForProperty:()=>HN,getActionAtElement:()=>Gse,getActionType:()=>Use,getAllReachableRules:()=>sx,getCrossReferenceTerminal:()=>VN,getEntryRule:()=>Bse,getExplicitRuleType:()=>zg,getHiddenRules:()=>Fse,getRuleType:()=>jN,getRuleTypeName:()=>BBe,getTypeName:()=>cx,isArrayCardinality:()=>IBe,isArrayOperator:()=>OBe,isCommentTerminal:()=>UN,isDataType:()=>PBe,isDataTypeRule:()=>lx,isOptionalCardinality:()=>MBe,terminalRegex:()=>Gg});function Bse(t){return t.rules.find(e=>Fa(e)&&e.entry)}function Fse(t){return t.rules.filter(e=>uo(e)&&e.hidden)}function sx(t,e){let r=new Set,n=Bse(t);if(!n)return new Set(t.rules);let i=[n].concat(Fse(t));for(let s of i)$se(s,r,e);let a=new Set;for(let s of t.rules)(r.has(s.name)||uo(s)&&s.hidden)&&a.add(s);return a}function $se(t,e,r){e.add(t.name),Bc(t).forEach(n=>{if(Bl(n)||r&&Rk(n)){let i=n.rule.ref;i&&!e.has(i.name)&&$se(i,e,r)}})}function VN(t){if(t.terminal)return t.terminal;if(t.type.ref){let e=Fk(t.type.ref);return e?.terminal}}function UN(t){return t.hidden&&!Fg(Gg(t))}function HN(t,e){return!t||!e?[]:WN(t,e,t.astNode,!0)}function ox(t,e,r){if(!t||!e)return;let n=WN(t,e,t.astNode,!0);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function WN(t,e,r,n){if(!n){let i=hp(t.grammarSource,Pl);if(i&&i.feature===e)return[t]}return Ml(t)&&t.astNode===r?t.content.flatMap(i=>WN(i,e,r,!1)):[]}function NBe(t,e){return t?YN(t,e,t?.astNode):[]}function qN(t,e,r){if(!t)return;let n=YN(t,e,t?.astNode);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function YN(t,e,r){if(t.astNode!==r)return[];if(Xo(t.grammarSource)&&t.grammarSource.value===e)return[t];let n=sp(t).iterator(),i,a=[];do if(i=n.next(),!i.done){let s=i.value;s.astNode===r?Xo(s.grammarSource)&&s.grammarSource.value===e&&a.push(s):n.prune()}while(!i.done);return a}function XN(t){var e;let r=t.astNode;for(;r===((e=t.container)===null||e===void 0?void 0:e.astNode);){let n=hp(t.grammarSource,Pl);if(n)return n;t=t.container}}function Fk(t){let e=t;return Ak(e)&&($u(e.$container)?e=e.$container.$container:Fa(e.$container)?e=e.$container:Oc(e.$container)),zse(t,e,new Map)}function zse(t,e,r){var n;function i(a,s){let l;return hp(a,Pl)||(l=zse(s,s,r)),r.set(t,l),l}if(o(i,"go"),r.has(t))return r.get(t);r.set(t,void 0);for(let a of Bc(e)){if(Pl(a)&&a.feature.toLowerCase()==="name")return r.set(t,a),a;if(Bl(a)&&Fa(a.rule.ref))return i(a,a.rule.ref);if(Dk(a)&&(!((n=a.typeRef)===null||n===void 0)&&n.ref))return i(a,a.typeRef.ref)}}function Gse(t){let e=t.$container;if(ff(e)){let r=e.elements,n=r.indexOf(t);for(let i=n-1;i>=0;i--){let a=r[i];if($u(a))return a;{let s=Bc(r[i]).find($u);if(s)return s}}}if(Q2(e))return Gse(e)}function MBe(t,e){return t==="?"||t==="*"||ff(e)&&!!e.guardCondition}function IBe(t){return t==="*"||t==="+"}function OBe(t){return t==="+="}function lx(t){return Vse(t,new Set)}function Vse(t,e){if(e.has(t))return!0;e.add(t);for(let r of Bc(t))if(Bl(r)){if(!r.rule.ref||Fa(r.rule.ref)&&!Vse(r.rule.ref,e))return!1}else{if(Pl(r))return!1;if($u(r))return!1}return!!t.definition}function PBe(t){return GN(t.type,new Set)}function GN(t,e){if(e.has(t))return!0;if(e.add(t),fN(t))return!1;if(vN(t))return!1;if(bN(t))return t.types.every(r=>GN(r,e));if(Dk(t)){if(t.primitiveType!==void 0)return!0;if(t.stringType!==void 0)return!0;if(t.typeRef!==void 0){let r=t.typeRef.ref;return Z2(r)?GN(r.type,e):!1}else return!1}else return!1}function zg(t){if(t.inferredType)return t.inferredType.name;if(t.dataType)return t.dataType;if(t.returnType){let e=t.returnType.ref;if(e){if(Fa(e))return e.name;if(_k(e)||Z2(e))return e.name}}}function cx(t){var e;if(Fa(t))return lx(t)?t.name:(e=zg(t))!==null&&e!==void 0?e:t.name;if(_k(t)||Z2(t)||xN(t))return t.name;if($u(t)){let r=Use(t);if(r)return r}else if(Ak(t))return t.name;throw new Error("Cannot get name of Unknown Type")}function Use(t){var e;if(t.inferredType)return t.inferredType.name;if(!((e=t.type)===null||e===void 0)&&e.ref)return cx(t.type.ref)}function BBe(t){var e,r,n;return uo(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":lx(t)?t.name:(n=zg(t))!==null&&n!==void 0?n:t.name}function jN(t){var e,r,n;return uo(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":(n=zg(t))!==null&&n!==void 0?n:t.name}function Gg(t){let e={s:!1,i:!1,u:!1},r=Vg(t.definition,e),n=Object.entries(e).filter(([,i])=>i).map(([i])=>i).join("");return new RegExp(r,n)}function Vg(t,e){if(SN(t))return FBe(t);if(CN(t))return $Be(t);if(TN(t))return VBe(t);if(Rk(t)){let r=t.rule.ref;if(!r)throw new Error("Missing rule reference.");return zu(Vg(r.definition),{cardinality:t.cardinality,lookahead:t.lookahead})}else{if(kN(t))return GBe(t);if(AN(t))return zBe(t);if(EN(t)){let r=t.regex.lastIndexOf("/"),n=t.regex.substring(1,r),i=t.regex.substring(r+1);return e&&(e.i=i.includes("i"),e.s=i.includes("s"),e.u=i.includes("u")),zu(n,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}else{if(_N(t))return zu(KN,{cardinality:t.cardinality,lookahead:t.lookahead});throw new Error(`Invalid terminal element: ${t?.$type}`)}}}function FBe(t){return zu(t.elements.map(e=>Vg(e)).join("|"),{cardinality:t.cardinality,lookahead:t.lookahead})}function $Be(t){return zu(t.elements.map(e=>Vg(e)).join(""),{cardinality:t.cardinality,lookahead:t.lookahead})}function zBe(t){return zu(`${KN}*?${Vg(t.terminal)}`,{cardinality:t.cardinality,lookahead:t.lookahead})}function GBe(t){return zu(`(?!${Vg(t.terminal)})${KN}*?`,{cardinality:t.cardinality,lookahead:t.lookahead})}function VBe(t){return t.right?zu(`[${zN(t.left)}-${zN(t.right)}]`,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1}):zu(zN(t.left),{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}function zN(t){return mp(t.value)}function zu(t,e){var r;return(e.wrap!==!1||e.lookahead)&&(t=`(${(r=e.lookahead)!==null&&r!==void 0?r:""}${t})`),e.cardinality?`${t}${e.cardinality}`:t}var KN,Fl=N(()=>{"use strict";Sk();Pc();Il();cs();Ol();$g();o(Bse,"getEntryRule");o(Fse,"getHiddenRules");o(sx,"getAllReachableRules");o($se,"ruleDfs");o(VN,"getCrossReferenceTerminal");o(UN,"isCommentTerminal");o(HN,"findNodesForProperty");o(ox,"findNodeForProperty");o(WN,"findNodesForPropertyInternal");o(NBe,"findNodesForKeyword");o(qN,"findNodeForKeyword");o(YN,"findNodesForKeywordInternal");o(XN,"findAssignment");o(Fk,"findNameAssignment");o(zse,"findNameAssignmentInternal");o(Gse,"getActionAtElement");o(MBe,"isOptionalCardinality");o(IBe,"isArrayCardinality");o(OBe,"isArrayOperator");o(lx,"isDataTypeRule");o(Vse,"isDataTypeRuleInternal");o(PBe,"isDataType");o(GN,"isDataTypeInternal");o(zg,"getExplicitRuleType");o(cx,"getTypeName");o(Use,"getActionType");o(BBe,"getRuleTypeName");o(jN,"getRuleType");o(Gg,"terminalRegex");KN=/[\s\S]/.source;o(Vg,"abstractElementToRegex");o(FBe,"terminalAlternativesToRegex");o($Be,"terminalGroupToRegex");o(zBe,"untilTokenToRegex");o(GBe,"negateTokenToRegex");o(VBe,"characterRangeToRegex");o(zN,"keywordToRegex");o(zu,"withCardinality")});function QN(t){let e=[],r=t.Grammar;for(let n of r.rules)uo(n)&&UN(n)&&BN(Gg(n))&&e.push(n.name);return{multilineCommentRules:e,nameRegexp:kk}}var ZN=N(()=>{"use strict";Ol();Fl();$g();Pc();o(QN,"createGrammarConfig")});var JN=N(()=>{"use strict"});function Ug(t){console&&console.error&&console.error(`Error: ${t}`)}function ux(t){console&&console.warn&&console.warn(`Warning: ${t}`)}var Hse=N(()=>{"use strict";o(Ug,"PRINT_ERROR");o(ux,"PRINT_WARNING")});function hx(t){let e=new Date().getTime(),r=t();return{time:new Date().getTime()-e,value:r}}var Wse=N(()=>{"use strict";o(hx,"timer")});function fx(t){function e(){}o(e,"FakeConstructor"),e.prototype=t;let r=new e;function n(){return typeof r.bar}return o(n,"fakeAccess"),n(),n(),t;(0,eval)(t)}var qse=N(()=>{"use strict";o(fx,"toFastProperties")});var Hg=N(()=>{"use strict";Hse();Wse();qse()});function UBe(t){return HBe(t)?t.LABEL:t.name}function HBe(t){return Ti(t.LABEL)&&t.LABEL!==""}function zk(t){return Je(t,Wg)}function Wg(t){function e(r){return Je(r,Wg)}if(o(e,"convertDefinition"),t instanceof on){let r={type:"NonTerminal",name:t.nonTerminalName,idx:t.idx};return Ti(t.label)&&(r.label=t.label),r}else{if(t instanceof Dn)return{type:"Alternative",definition:e(t.definition)};if(t instanceof ln)return{type:"Option",idx:t.idx,definition:e(t.definition)};if(t instanceof Ln)return{type:"RepetitionMandatory",idx:t.idx,definition:e(t.definition)};if(t instanceof Rn)return{type:"RepetitionMandatoryWithSeparator",idx:t.idx,separator:Wg(new Er({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof Tn)return{type:"RepetitionWithSeparator",idx:t.idx,separator:Wg(new Er({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof Pr)return{type:"Repetition",idx:t.idx,definition:e(t.definition)};if(t instanceof wn)return{type:"Alternation",idx:t.idx,definition:e(t.definition)};if(t instanceof Er){let r={type:"Terminal",name:t.terminalType.name,label:UBe(t.terminalType),idx:t.idx};Ti(t.label)&&(r.terminalLabel=t.label);let n=t.terminalType.PATTERN;return t.terminalType.PATTERN&&(r.pattern=Uo(n)?n.source:n),r}else{if(t instanceof us)return{type:"Rule",name:t.name,orgText:t.orgText,definition:e(t.definition)};throw Error("non exhaustive match")}}}var ho,on,us,Dn,ln,Ln,Rn,Pr,Tn,wn,Er,Gk=N(()=>{"use strict";qt();o(UBe,"tokenLabel");o(HBe,"hasTokenLabel");ho=class{static{o(this,"AbstractProduction")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){this._definition=e}accept(e){e.visit(this),Ae(this.definition,r=>{r.accept(e)})}},on=class extends ho{static{o(this,"NonTerminal")}constructor(e){super([]),this.idx=1,pa(this,zs(e,r=>r!==void 0))}set definition(e){}get definition(){return this.referencedRule!==void 0?this.referencedRule.definition:[]}accept(e){e.visit(this)}},us=class extends ho{static{o(this,"Rule")}constructor(e){super(e.definition),this.orgText="",pa(this,zs(e,r=>r!==void 0))}},Dn=class extends ho{static{o(this,"Alternative")}constructor(e){super(e.definition),this.ignoreAmbiguities=!1,pa(this,zs(e,r=>r!==void 0))}},ln=class extends ho{static{o(this,"Option")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Ln=class extends ho{static{o(this,"RepetitionMandatory")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Rn=class extends ho{static{o(this,"RepetitionMandatoryWithSeparator")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Pr=class extends ho{static{o(this,"Repetition")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},Tn=class extends ho{static{o(this,"RepetitionWithSeparator")}constructor(e){super(e.definition),this.idx=1,pa(this,zs(e,r=>r!==void 0))}},wn=class extends ho{static{o(this,"Alternation")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){super(e.definition),this.idx=1,this.ignoreAmbiguities=!1,this.hasPredicates=!1,pa(this,zs(e,r=>r!==void 0))}},Er=class{static{o(this,"Terminal")}constructor(e){this.idx=1,pa(this,zs(e,r=>r!==void 0))}accept(e){e.visit(this)}};o(zk,"serializeGrammar");o(Wg,"serializeProduction")});var hs,Yse=N(()=>{"use strict";Gk();hs=class{static{o(this,"GAstVisitor")}visit(e){let r=e;switch(r.constructor){case on:return this.visitNonTerminal(r);case Dn:return this.visitAlternative(r);case ln:return this.visitOption(r);case Ln:return this.visitRepetitionMandatory(r);case Rn:return this.visitRepetitionMandatoryWithSeparator(r);case Tn:return this.visitRepetitionWithSeparator(r);case Pr:return this.visitRepetition(r);case wn:return this.visitAlternation(r);case Er:return this.visitTerminal(r);case us:return this.visitRule(r);default:throw Error("non exhaustive match")}}visitNonTerminal(e){}visitAlternative(e){}visitOption(e){}visitRepetition(e){}visitRepetitionMandatory(e){}visitRepetitionMandatoryWithSeparator(e){}visitRepetitionWithSeparator(e){}visitAlternation(e){}visitTerminal(e){}visitRule(e){}}});function eM(t){return t instanceof Dn||t instanceof ln||t instanceof Pr||t instanceof Ln||t instanceof Rn||t instanceof Tn||t instanceof Er||t instanceof us}function gp(t,e=[]){return t instanceof ln||t instanceof Pr||t instanceof Tn?!0:t instanceof wn?B2(t.definition,n=>gp(n,e)):t instanceof on&&Xn(e,t)?!1:t instanceof ho?(t instanceof on&&e.push(t),Pa(t.definition,n=>gp(n,e))):!1}function tM(t){return t instanceof wn}function Vs(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof wn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof Tn)return"MANY_SEP";if(t instanceof Pr)return"MANY";if(t instanceof Er)return"CONSUME";throw Error("non exhaustive match")}var Xse=N(()=>{"use strict";qt();Gk();o(eM,"isSequenceProd");o(gp,"isOptionalProd");o(tM,"isBranchingProd");o(Vs,"getProductionDslName")});var fs=N(()=>{"use strict";Gk();Yse();Xse()});function jse(t,e,r){return[new ln({definition:[new Er({terminalType:t.separator})].concat(t.definition)})].concat(e,r)}var Gu,Vk=N(()=>{"use strict";qt();fs();Gu=class{static{o(this,"RestWalker")}walk(e,r=[]){Ae(e.definition,(n,i)=>{let a=bi(e.definition,i+1);if(n instanceof on)this.walkProdRef(n,a,r);else if(n instanceof Er)this.walkTerminal(n,a,r);else if(n instanceof Dn)this.walkFlat(n,a,r);else if(n instanceof ln)this.walkOption(n,a,r);else if(n instanceof Ln)this.walkAtLeastOne(n,a,r);else if(n instanceof Rn)this.walkAtLeastOneSep(n,a,r);else if(n instanceof Tn)this.walkManySep(n,a,r);else if(n instanceof Pr)this.walkMany(n,a,r);else if(n instanceof wn)this.walkOr(n,a,r);else throw Error("non exhaustive match")})}walkTerminal(e,r,n){}walkProdRef(e,r,n){}walkFlat(e,r,n){let i=r.concat(n);this.walk(e,i)}walkOption(e,r,n){let i=r.concat(n);this.walk(e,i)}walkAtLeastOne(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkAtLeastOneSep(e,r,n){let i=jse(e,r,n);this.walk(e,i)}walkMany(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkManySep(e,r,n){let i=jse(e,r,n);this.walk(e,i)}walkOr(e,r,n){let i=r.concat(n);Ae(e.definition,a=>{let s=new Dn({definition:[a]});this.walk(s,i)})}};o(jse,"restForRepetitionWithSeparator")});function yp(t){if(t instanceof on)return yp(t.referencedRule);if(t instanceof Er)return YBe(t);if(eM(t))return WBe(t);if(tM(t))return qBe(t);throw Error("non exhaustive match")}function WBe(t){let e=[],r=t.definition,n=0,i=r.length>n,a,s=!0;for(;i&&s;)a=r[n],s=gp(a),e=e.concat(yp(a)),n=n+1,i=r.length>n;return qm(e)}function qBe(t){let e=Je(t.definition,r=>yp(r));return qm(qr(e))}function YBe(t){return[t.terminalType]}var rM=N(()=>{"use strict";qt();fs();o(yp,"first");o(WBe,"firstForSequence");o(qBe,"firstForBranching");o(YBe,"firstForTerminal")});var Uk,nM=N(()=>{"use strict";Uk="_~IN~_"});function Kse(t){let e={};return Ae(t,r=>{let n=new iM(r).startWalking();pa(e,n)}),e}function XBe(t,e){return t.name+e+Uk}var iM,Qse=N(()=>{"use strict";Vk();rM();qt();nM();fs();iM=class extends Gu{static{o(this,"ResyncFollowsWalker")}constructor(e){super(),this.topProd=e,this.follows={}}startWalking(){return this.walk(this.topProd),this.follows}walkTerminal(e,r,n){}walkProdRef(e,r,n){let i=XBe(e.referencedRule,e.idx)+this.topProd.name,a=r.concat(n),s=new Dn({definition:a}),l=yp(s);this.follows[i]=l}};o(Kse,"computeAllProdsFollows");o(XBe,"buildBetweenProdsFollowPrefix")});function qg(t){let e=t.toString();if(Hk.hasOwnProperty(e))return Hk[e];{let r=jBe.pattern(e);return Hk[e]=r,r}}function Zse(){Hk={}}var Hk,jBe,Wk=N(()=>{"use strict";ax();Hk={},jBe=new dp;o(qg,"getRegExpAst");o(Zse,"clearRegExpParserCache")});function toe(t,e=!1){try{let r=qg(t);return aM(r.value,{},r.flags.ignoreCase)}catch(r){if(r.message===eoe)e&&ux(`${dx} Unable to optimize: < ${t.toString()} > - Complement Sets cannot be automatically optimized. - This will disable the lexer's first char optimizations. - See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{let n="";e&&(n=` - This will disable the lexer's first char optimizations. - See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),Ug(`${dx} - Failed parsing: < ${t.toString()} > - Using the @chevrotain/regexp-to-ast library - Please open an issue at: https://github.com/chevrotain/chevrotain/issues`+n)}}return[]}function aM(t,e,r){switch(t.type){case"Disjunction":for(let i=0;i{if(typeof u=="number")qk(u,e,r);else{let h=u;if(r===!0)for(let f=h.from;f<=h.to;f++)qk(f,e,r);else{for(let f=h.from;f<=h.to&&f=Yg){let f=h.from>=Yg?h.from:Yg,d=h.to,p=$c(f),m=$c(d);for(let g=p;g<=m;g++)e[g]=g}}}});break;case"Group":aM(s.value,e,r);break;default:throw Error("Non Exhaustive Match")}let l=s.quantifier!==void 0&&s.quantifier.atLeast===0;if(s.type==="Group"&&sM(s)===!1||s.type!=="Group"&&l===!1)break}break;default:throw Error("non exhaustive match!")}return br(e)}function qk(t,e,r){let n=$c(t);e[n]=n,r===!0&&KBe(t,e)}function KBe(t,e){let r=String.fromCharCode(t),n=r.toUpperCase();if(n!==r){let i=$c(n.charCodeAt(0));e[i]=i}else{let i=r.toLowerCase();if(i!==r){let a=$c(i.charCodeAt(0));e[a]=a}}}function Jse(t,e){return ls(t.value,r=>{if(typeof r=="number")return Xn(e,r);{let n=r;return ls(e,i=>n.from<=i&&i<=n.to)!==void 0}})}function sM(t){let e=t.quantifier;return e&&e.atLeast===0?!0:t.value?Pt(t.value)?Pa(t.value,sM):sM(t.value):!1}function Yk(t,e){if(e instanceof RegExp){let r=qg(e),n=new oM(t);return n.visit(r),n.found}else return ls(e,r=>Xn(t,r.charCodeAt(0)))!==void 0}var eoe,dx,oM,roe=N(()=>{"use strict";ax();qt();Hg();Wk();lM();eoe="Complement Sets are not supported for first char optimization",dx=`Unable to use "first char" lexer optimizations: -`;o(toe,"getOptimizedStartCodesIndices");o(aM,"firstCharOptimizedIndices");o(qk,"addOptimizedIdxToResult");o(KBe,"handleIgnoreCase");o(Jse,"findCode");o(sM,"isWholeOptional");oM=class extends Fc{static{o(this,"CharCodeFinder")}constructor(e){super(),this.targetCharCodes=e,this.found=!1}visitChildren(e){if(this.found!==!0){switch(e.type){case"Lookahead":this.visitLookahead(e);return;case"NegativeLookahead":this.visitNegativeLookahead(e);return}super.visitChildren(e)}}visitCharacter(e){Xn(this.targetCharCodes,e.value)&&(this.found=!0)}visitSet(e){e.complement?Jse(e,this.targetCharCodes)===void 0&&(this.found=!0):Jse(e,this.targetCharCodes)!==void 0&&(this.found=!0)}};o(Yk,"canMatchCharCode")});function aoe(t,e){e=nf(e,{useSticky:uM,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` -`],tracer:o((b,T)=>T(),"tracer")});let r=e.tracer;r("initCharCodeToOptimizedIndexMap",()=>{pFe()});let n;r("Reject Lexer.NA",()=>{n=sf(t,b=>b[vp]===Kn.NA)});let i=!1,a;r("Transform Patterns",()=>{i=!1,a=Je(n,b=>{let T=b[vp];if(Uo(T)){let S=T.source;return S.length===1&&S!=="^"&&S!=="$"&&S!=="."&&!T.ignoreCase?S:S.length===2&&S[0]==="\\"&&!Xn(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],S[1])?S[1]:e.useSticky?ioe(T):noe(T)}else{if(Ai(T))return i=!0,{exec:T};if(typeof T=="object")return i=!0,T;if(typeof T=="string"){if(T.length===1)return T;{let S=T.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),w=new RegExp(S);return e.useSticky?ioe(w):noe(w)}}else throw Error("non exhaustive match")}})});let s,l,u,h,f;r("misc mapping",()=>{s=Je(n,b=>b.tokenTypeIdx),l=Je(n,b=>{let T=b.GROUP;if(T!==Kn.SKIPPED){if(Ti(T))return T;if(mr(T))return!1;throw Error("non exhaustive match")}}),u=Je(n,b=>{let T=b.LONGER_ALT;if(T)return Pt(T)?Je(T,w=>ik(n,w)):[ik(n,T)]}),h=Je(n,b=>b.PUSH_MODE),f=Je(n,b=>Bt(b,"POP_MODE"))});let d;r("Line Terminator Handling",()=>{let b=doe(e.lineTerminatorCharacters);d=Je(n,T=>!1),e.positionTracking!=="onlyOffset"&&(d=Je(n,T=>Bt(T,"LINE_BREAKS")?!!T.LINE_BREAKS:foe(T,b)===!1&&Yk(b,T.PATTERN)))});let p,m,g,y;r("Misc Mapping #2",()=>{p=Je(n,uoe),m=Je(a,fFe),g=Xr(n,(b,T)=>{let S=T.GROUP;return Ti(S)&&S!==Kn.SKIPPED&&(b[S]=[]),b},{}),y=Je(a,(b,T)=>({pattern:a[T],longerAlt:u[T],canLineTerminator:d[T],isCustom:p[T],short:m[T],group:l[T],push:h[T],pop:f[T],tokenTypeIdx:s[T],tokenType:n[T]}))});let v=!0,x=[];return e.safeMode||r("First Char Optimization",()=>{x=Xr(n,(b,T,S)=>{if(typeof T.PATTERN=="string"){let w=T.PATTERN.charCodeAt(0),E=$c(w);cM(b,E,y[S])}else if(Pt(T.START_CHARS_HINT)){let w;Ae(T.START_CHARS_HINT,E=>{let _=typeof E=="string"?E.charCodeAt(0):E,C=$c(_);w!==C&&(w=C,cM(b,C,y[S]))})}else if(Uo(T.PATTERN))if(T.PATTERN.unicode)v=!1,e.ensureOptimizations&&Ug(`${dx} Unable to analyze < ${T.PATTERN.toString()} > pattern. - The regexp unicode flag is not currently supported by the regexp-to-ast library. - This will disable the lexer's first char optimizations. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{let w=toe(T.PATTERN,e.ensureOptimizations);hr(w)&&(v=!1),Ae(w,E=>{cM(b,E,y[S])})}else e.ensureOptimizations&&Ug(`${dx} TokenType: <${T.name}> is using a custom token pattern without providing parameter. - This will disable the lexer's first char optimizations. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),v=!1;return b},[])}),{emptyGroups:g,patternIdxToConfig:y,charCodeToPatternIdxToConfig:x,hasCustom:i,canBeOptimized:v}}function soe(t,e){let r=[],n=ZBe(t);r=r.concat(n.errors);let i=JBe(n.valid),a=i.valid;return r=r.concat(i.errors),r=r.concat(QBe(a)),r=r.concat(oFe(a)),r=r.concat(lFe(a,e)),r=r.concat(cFe(a)),r}function QBe(t){let e=[],r=Yr(t,n=>Uo(n[vp]));return e=e.concat(tFe(r)),e=e.concat(iFe(r)),e=e.concat(aFe(r)),e=e.concat(sFe(r)),e=e.concat(rFe(r)),e}function ZBe(t){let e=Yr(t,i=>!Bt(i,vp)),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- missing static 'PATTERN' property",type:jn.MISSING_PATTERN,tokenTypes:[i]})),n=af(t,e);return{errors:r,valid:n}}function JBe(t){let e=Yr(t,i=>{let a=i[vp];return!Uo(a)&&!Ai(a)&&!Bt(a,"exec")&&!Ti(a)}),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:jn.INVALID_PATTERN,tokenTypes:[i]})),n=af(t,e);return{errors:r,valid:n}}function tFe(t){class e extends Fc{static{o(this,"EndAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitEndAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=qg(a),l=new e;return l.visit(s),l.found}catch{return eFe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error: - Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain end of input anchor '$' - See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:jn.EOI_ANCHOR_FOUND,tokenTypes:[i]}))}function rFe(t){let e=Yr(t,n=>n.PATTERN.test(""));return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' must not match an empty string",type:jn.EMPTY_MATCH_PATTERN,tokenTypes:[n]}))}function iFe(t){class e extends Fc{static{o(this,"StartAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitStartAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=qg(a),l=new e;return l.visit(s),l.found}catch{return nFe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error: - Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain start of input anchor '^' - See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:jn.SOI_ANCHOR_FOUND,tokenTypes:[i]}))}function aFe(t){let e=Yr(t,n=>{let i=n[vp];return i instanceof RegExp&&(i.multiline||i.global)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:jn.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[n]}))}function sFe(t){let e=[],r=Je(t,a=>Xr(t,(s,l)=>(a.PATTERN.source===l.PATTERN.source&&!Xn(e,l)&&l.PATTERN!==Kn.NA&&(e.push(l),s.push(l)),s),[]));r=Ac(r);let n=Yr(r,a=>a.length>1);return Je(n,a=>{let s=Je(a,u=>u.name);return{message:`The same RegExp pattern ->${ia(a).PATTERN}<-has been used in all of the following Token Types: ${s.join(", ")} <-`,type:jn.DUPLICATE_PATTERNS_FOUND,tokenTypes:a}})}function oFe(t){let e=Yr(t,n=>{if(!Bt(n,"GROUP"))return!1;let i=n.GROUP;return i!==Kn.SKIPPED&&i!==Kn.NA&&!Ti(i)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:jn.INVALID_GROUP_TYPE_FOUND,tokenTypes:[n]}))}function lFe(t,e){let r=Yr(t,i=>i.PUSH_MODE!==void 0&&!Xn(e,i.PUSH_MODE));return Je(r,i=>({message:`Token Type: ->${i.name}<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->${i.PUSH_MODE}<-which does not exist`,type:jn.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[i]}))}function cFe(t){let e=[],r=Xr(t,(n,i,a)=>{let s=i.PATTERN;return s===Kn.NA||(Ti(s)?n.push({str:s,idx:a,tokenType:i}):Uo(s)&&hFe(s)&&n.push({str:s.source,idx:a,tokenType:i})),n},[]);return Ae(t,(n,i)=>{Ae(r,({str:a,idx:s,tokenType:l})=>{if(i${l.name}<- can never be matched. -Because it appears AFTER the Token Type ->${n.name}<-in the lexer's definition. -See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:u,type:jn.UNREACHABLE_PATTERN,tokenTypes:[n,l]})}})}),e}function uFe(t,e){if(Uo(e)){let r=e.exec(t);return r!==null&&r.index===0}else{if(Ai(e))return e(t,0,[],{});if(Bt(e,"exec"))return e.exec(t,0,[],{});if(typeof e=="string")return e===t;throw Error("non exhaustive match")}}function hFe(t){return ls([".","\\","[","]","|","^","$","(",")","?","*","+","{"],r=>t.source.indexOf(r)!==-1)===void 0}function noe(t){let e=t.ignoreCase?"i":"";return new RegExp(`^(?:${t.source})`,e)}function ioe(t){let e=t.ignoreCase?"iy":"y";return new RegExp(`${t.source}`,e)}function ooe(t,e,r){let n=[];return Bt(t,Xg)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+Xg+`> property in its definition -`,type:jn.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),Bt(t,Xk)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+Xk+`> property in its definition -`,type:jn.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),Bt(t,Xk)&&Bt(t,Xg)&&!Bt(t.modes,t.defaultMode)&&n.push({message:`A MultiMode Lexer cannot be initialized with a ${Xg}: <${t.defaultMode}>which does not exist -`,type:jn.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),Bt(t,Xk)&&Ae(t.modes,(i,a)=>{Ae(i,(s,l)=>{if(mr(s))n.push({message:`A Lexer cannot be initialized using an undefined Token Type. Mode:<${a}> at index: <${l}> -`,type:jn.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED});else if(Bt(s,"LONGER_ALT")){let u=Pt(s.LONGER_ALT)?s.LONGER_ALT:[s.LONGER_ALT];Ae(u,h=>{!mr(h)&&!Xn(i,h)&&n.push({message:`A MultiMode Lexer cannot be initialized with a longer_alt <${h.name}> on token <${s.name}> outside of mode <${a}> -`,type:jn.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE})})}})}),n}function loe(t,e,r){let n=[],i=!1,a=Ac(qr(br(t.modes))),s=sf(a,u=>u[vp]===Kn.NA),l=doe(r);return e&&Ae(s,u=>{let h=foe(u,l);if(h!==!1){let d={message:dFe(u,h),type:h.issue,tokenType:u};n.push(d)}else Bt(u,"LINE_BREAKS")?u.LINE_BREAKS===!0&&(i=!0):Yk(l,u.PATTERN)&&(i=!0)}),e&&!i&&n.push({message:`Warning: No LINE_BREAKS Found. - This Lexer has been defined to track line and column information, - But none of the Token Types can be identified as matching a line terminator. - See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS - for details.`,type:jn.NO_LINE_BREAKS_FLAGS}),n}function coe(t){let e={},r=zr(t);return Ae(r,n=>{let i=t[n];if(Pt(i))e[n]=[];else throw Error("non exhaustive match")}),e}function uoe(t){let e=t.PATTERN;if(Uo(e))return!1;if(Ai(e))return!0;if(Bt(e,"exec"))return!0;if(Ti(e))return!1;throw Error("non exhaustive match")}function fFe(t){return Ti(t)&&t.length===1?t.charCodeAt(0):!1}function foe(t,e){if(Bt(t,"LINE_BREAKS"))return!1;if(Uo(t.PATTERN)){try{Yk(e,t.PATTERN)}catch(r){return{issue:jn.IDENTIFY_TERMINATOR,errMsg:r.message}}return!1}else{if(Ti(t.PATTERN))return!1;if(uoe(t))return{issue:jn.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}}function dFe(t,e){if(e.issue===jn.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern. - The problem is in the <${t.name}> Token Type - Root cause: ${e.errMsg}. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR`;if(e.issue===jn.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. - The problem is in the <${t.name}> Token Type - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK`;throw Error("non exhaustive match")}function doe(t){return Je(t,r=>Ti(r)?r.charCodeAt(0):r)}function cM(t,e,r){t[e]===void 0?t[e]=[r]:t[e].push(r)}function $c(t){return t255?255+~~(t/255):t}}var vp,Xg,Xk,uM,eFe,nFe,hoe,Yg,jk,lM=N(()=>{"use strict";ax();px();qt();Hg();roe();Wk();vp="PATTERN",Xg="defaultMode",Xk="modes",uM=typeof new RegExp("(?:)").sticky=="boolean";o(aoe,"analyzeTokenTypes");o(soe,"validatePatterns");o(QBe,"validateRegExpPattern");o(ZBe,"findMissingPatterns");o(JBe,"findInvalidPatterns");eFe=/[^\\][$]/;o(tFe,"findEndOfInputAnchor");o(rFe,"findEmptyMatchRegExps");nFe=/[^\\[][\^]|^\^/;o(iFe,"findStartOfInputAnchor");o(aFe,"findUnsupportedFlags");o(sFe,"findDuplicatePatterns");o(oFe,"findInvalidGroupType");o(lFe,"findModesThatDoNotExist");o(cFe,"findUnreachablePatterns");o(uFe,"testTokenType");o(hFe,"noMetaChar");o(noe,"addStartOfInput");o(ioe,"addStickyFlag");o(ooe,"performRuntimeChecks");o(loe,"performWarningRuntimeChecks");o(coe,"cloneEmptyGroups");o(uoe,"isCustomPattern");o(fFe,"isShortPattern");hoe={test:o(function(t){let e=t.length;for(let r=this.lastIndex;r{r.isParent=r.categoryMatches.length>0})}function mFe(t){let e=an(t),r=t,n=!0;for(;n;){r=Ac(qr(Je(r,a=>a.CATEGORIES)));let i=af(r,e);e=e.concat(i),hr(i)?n=!1:r=i}return e}function gFe(t){Ae(t,e=>{hM(e)||(goe[poe]=e,e.tokenTypeIdx=poe++),moe(e)&&!Pt(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),moe(e)||(e.CATEGORIES=[]),xFe(e)||(e.categoryMatches=[]),bFe(e)||(e.categoryMatchesMap={})})}function yFe(t){Ae(t,e=>{e.categoryMatches=[],Ae(e.categoryMatchesMap,(r,n)=>{e.categoryMatches.push(goe[n].tokenTypeIdx)})})}function vFe(t){Ae(t,e=>{yoe([],e)})}function yoe(t,e){Ae(t,r=>{e.categoryMatchesMap[r.tokenTypeIdx]=!0}),Ae(e.CATEGORIES,r=>{let n=t.concat(e);Xn(n,r)||yoe(n,r)})}function hM(t){return Bt(t,"tokenTypeIdx")}function moe(t){return Bt(t,"CATEGORIES")}function xFe(t){return Bt(t,"categoryMatches")}function bFe(t){return Bt(t,"categoryMatchesMap")}function voe(t){return Bt(t,"tokenTypeIdx")}var poe,goe,xp=N(()=>{"use strict";qt();o(Vu,"tokenStructuredMatcher");o(jg,"tokenStructuredMatcherNoCategories");poe=1,goe={};o(Uu,"augmentTokenTypes");o(mFe,"expandCategories");o(gFe,"assignTokenDefaultProps");o(yFe,"assignCategoriesTokensProp");o(vFe,"assignCategoriesMapProp");o(yoe,"singleAssignCategoriesToksMap");o(hM,"hasShortKeyProperty");o(moe,"hasCategoriesProperty");o(xFe,"hasExtendingTokensTypesProperty");o(bFe,"hasExtendingTokensTypesMapProperty");o(voe,"isTokenType")});var Kg,fM=N(()=>{"use strict";Kg={buildUnableToPopLexerModeMessage(t){return`Unable to pop Lexer Mode after encountering Token ->${t.image}<- The Mode Stack is empty`},buildUnexpectedCharactersMessage(t,e,r,n,i){return`unexpected character: ->${t.charAt(e)}<- at offset: ${e}, skipped ${r} characters.`}}});var jn,mx,Kn,px=N(()=>{"use strict";lM();qt();Hg();xp();fM();Wk();(function(t){t[t.MISSING_PATTERN=0]="MISSING_PATTERN",t[t.INVALID_PATTERN=1]="INVALID_PATTERN",t[t.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",t[t.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",t[t.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",t[t.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",t[t.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",t[t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",t[t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",t[t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",t[t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",t[t.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",t[t.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",t[t.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",t[t.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",t[t.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",t[t.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK",t[t.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE=17]="MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE"})(jn||(jn={}));mx={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` -`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:Kg,traceInitPerf:!1,skipValidations:!1,recoveryEnabled:!0};Object.freeze(mx);Kn=class{static{o(this,"Lexer")}constructor(e,r=mx){if(this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},this.TRACE_INIT=(i,a)=>{if(this.traceInitPerf===!0){this.traceInitIndent++;let s=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <${i}>`);let{time:l,value:u}=hx(a),h=l>10?console.warn:console.log;return this.traceInitIndent time: ${l}ms`),this.traceInitIndent--,u}else return a()},typeof r=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. -a boolean 2nd argument is no longer supported`);this.config=pa({},mx,r);let n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",()=>{let i,a=!0;this.TRACE_INIT("Lexer Config handling",()=>{if(this.config.lineTerminatorsPattern===mx.lineTerminatorsPattern)this.config.lineTerminatorsPattern=hoe;else if(this.config.lineTerminatorCharacters===mx.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(r.safeMode&&r.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking),Pt(e)?i={modes:{defaultMode:an(e)},defaultMode:Xg}:(a=!1,i=an(e))}),this.config.skipValidations===!1&&(this.TRACE_INIT("performRuntimeChecks",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(ooe(i,this.trackStartLines,this.config.lineTerminatorCharacters))}),this.TRACE_INIT("performWarningRuntimeChecks",()=>{this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(loe(i,this.trackStartLines,this.config.lineTerminatorCharacters))})),i.modes=i.modes?i.modes:{},Ae(i.modes,(l,u)=>{i.modes[u]=sf(l,h=>mr(h))});let s=zr(i.modes);if(Ae(i.modes,(l,u)=>{this.TRACE_INIT(`Mode: <${u}> processing`,()=>{if(this.modes.push(u),this.config.skipValidations===!1&&this.TRACE_INIT("validatePatterns",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(soe(l,s))}),hr(this.lexerDefinitionErrors)){Uu(l);let h;this.TRACE_INIT("analyzeTokenTypes",()=>{h=aoe(l,{lineTerminatorCharacters:this.config.lineTerminatorCharacters,positionTracking:r.positionTracking,ensureOptimizations:r.ensureOptimizations,safeMode:r.safeMode,tracer:this.TRACE_INIT})}),this.patternIdxToConfig[u]=h.patternIdxToConfig,this.charCodeToPatternIdxToConfig[u]=h.charCodeToPatternIdxToConfig,this.emptyGroups=pa({},this.emptyGroups,h.emptyGroups),this.hasCustom=h.hasCustom||this.hasCustom,this.canModeBeOptimized[u]=h.canBeOptimized}})}),this.defaultMode=i.defaultMode,!hr(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){let u=Je(this.lexerDefinitionErrors,h=>h.message).join(`----------------------- -`);throw new Error(`Errors detected in definition of Lexer: -`+u)}Ae(this.lexerDefinitionWarning,l=>{ux(l.message)}),this.TRACE_INIT("Choosing sub-methods implementations",()=>{if(uM?(this.chopInput=ta,this.match=this.matchWithTest):(this.updateLastIndex=ai,this.match=this.matchWithExec),a&&(this.handleModes=ai),this.trackStartLines===!1&&(this.computeNewColumn=ta),this.trackEndLines===!1&&(this.updateTokenEndLineColumnLocation=ai),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else if(/onlyOffset/i.test(this.config.positionTracking))this.createTokenInstance=this.createOffsetOnlyToken;else throw Error(`Invalid config option: "${this.config.positionTracking}"`);this.hasCustom?(this.addToken=this.addTokenUsingPush,this.handlePayload=this.handlePayloadWithCustom):(this.addToken=this.addTokenUsingMemberAccess,this.handlePayload=this.handlePayloadNoCustom)}),this.TRACE_INIT("Failed Optimization Warnings",()=>{let l=Xr(this.canModeBeOptimized,(u,h,f)=>(h===!1&&u.push(f),u),[]);if(r.ensureOptimizations&&!hr(l))throw Error(`Lexer Modes: < ${l.join(", ")} > cannot be optimized. - Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. - Or inspect the console log for details on how to resolve these issues.`)}),this.TRACE_INIT("clearRegExpParserCache",()=>{Zse()}),this.TRACE_INIT("toFastProperties",()=>{fx(this)})})}tokenize(e,r=this.defaultMode){if(!hr(this.lexerDefinitionErrors)){let i=Je(this.lexerDefinitionErrors,a=>a.message).join(`----------------------- -`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: -`+i)}return this.tokenizeInternal(e,r)}tokenizeInternal(e,r){let n,i,a,s,l,u,h,f,d,p,m,g,y,v,x,b,T=e,S=T.length,w=0,E=0,_=this.hasCustom?0:Math.floor(e.length/10),C=new Array(_),D=[],O=this.trackStartLines?1:void 0,R=this.trackStartLines?1:void 0,k=coe(this.emptyGroups),L=this.trackStartLines,A=this.config.lineTerminatorsPattern,I=0,M=[],P=[],B=[],F=[];Object.freeze(F);let z;function $(){return M}o($,"getPossiblePatternsSlow");function U(Z){let ue=$c(Z),Q=P[ue];return Q===void 0?F:Q}o(U,"getPossiblePatternsOptimized");let K=o(Z=>{if(B.length===1&&Z.tokenType.PUSH_MODE===void 0){let ue=this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(Z);D.push({offset:Z.startOffset,line:Z.startLine,column:Z.startColumn,length:Z.image.length,message:ue})}else{B.pop();let ue=ma(B);M=this.patternIdxToConfig[ue],P=this.charCodeToPatternIdxToConfig[ue],I=M.length;let Q=this.canModeBeOptimized[ue]&&this.config.safeMode===!1;P&&Q?z=U:z=$}},"pop_mode");function ee(Z){B.push(Z),P=this.charCodeToPatternIdxToConfig[Z],M=this.patternIdxToConfig[Z],I=M.length,I=M.length;let ue=this.canModeBeOptimized[Z]&&this.config.safeMode===!1;P&&ue?z=U:z=$}o(ee,"push_mode"),ee.call(this,r);let Y,ce=this.config.recoveryEnabled;for(;wu.length){u=s,h=f,Y=he;break}}}break}}if(u!==null){if(d=u.length,p=Y.group,p!==void 0&&(m=Y.tokenTypeIdx,g=this.createTokenInstance(u,w,m,Y.tokenType,O,R,d),this.handlePayload(g,h),p===!1?E=this.addToken(C,E,g):k[p].push(g)),e=this.chopInput(e,d),w=w+d,R=this.computeNewColumn(R,d),L===!0&&Y.canLineTerminator===!0){let j=0,ne,te;A.lastIndex=0;do ne=A.test(u),ne===!0&&(te=A.lastIndex-1,j++);while(ne===!0);j!==0&&(O=O+j,R=d-te,this.updateTokenEndLineColumnLocation(g,p,te,j,O,R,d))}this.handleModes(Y,K,ee,g)}else{let j=w,ne=O,te=R,he=ce===!1;for(;he===!1&&w{"use strict";qt();px();xp();o(Hu,"tokenLabel");o(dM,"hasTokenLabel");TFe="parent",xoe="categories",boe="label",Toe="group",woe="push_mode",koe="pop_mode",Eoe="longer_alt",Soe="line_breaks",Coe="start_chars_hint";o(df,"createToken");o(wFe,"createTokenInternal");fo=df({name:"EOF",pattern:Kn.NA});Uu([fo]);o(Wu,"createTokenInstance");o(gx,"tokenMatcher")});var qu,Aoe,$l,Qg=N(()=>{"use strict";bp();qt();fs();qu={buildMismatchTokenMessage({expected:t,actual:e,previous:r,ruleName:n}){return`Expecting ${dM(t)?`--> ${Hu(t)} <--`:`token of type --> ${t.name} <--`} but found --> '${e.image}' <--`},buildNotAllInputParsedMessage({firstRedundant:t,ruleName:e}){return"Redundant input, expecting EOF but found: "+t.image},buildNoViableAltMessage({expectedPathsPerAlt:t,actual:e,previous:r,customUserDescription:n,ruleName:i}){let a="Expecting: ",l=` -but found: '`+ia(e).image+"'";if(n)return a+n+l;{let u=Xr(t,(p,m)=>p.concat(m),[]),h=Je(u,p=>`[${Je(p,m=>Hu(m)).join(", ")}]`),d=`one of these possible Token sequences: -${Je(h,(p,m)=>` ${m+1}. ${p}`).join(` -`)}`;return a+d+l}},buildEarlyExitMessage({expectedIterationPaths:t,actual:e,customUserDescription:r,ruleName:n}){let i="Expecting: ",s=` -but found: '`+ia(e).image+"'";if(r)return i+r+s;{let u=`expecting at least one iteration which starts with one of these possible Token sequences:: - <${Je(t,h=>`[${Je(h,f=>Hu(f)).join(",")}]`).join(" ,")}>`;return i+u+s}}};Object.freeze(qu);Aoe={buildRuleNotFoundError(t,e){return"Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- -inside top level rule: ->`+t.name+"<-"}},$l={buildDuplicateFoundError(t,e){function r(f){return f instanceof Er?f.terminalType.name:f instanceof on?f.nonTerminalName:""}o(r,"getExtraProductionArgument");let n=t.name,i=ia(e),a=i.idx,s=Vs(i),l=r(i),u=a>0,h=`->${s}${u?a:""}<- ${l?`with argument: ->${l}<-`:""} - appears more than once (${e.length} times) in the top level rule: ->${n}<-. - For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES - `;return h=h.replace(/[ \t]+/g," "),h=h.replace(/\s\s+/g,` -`),h},buildNamespaceConflictError(t){return`Namespace conflict found in grammar. -The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${t.name}>. -To resolve this make sure each Terminal and Non-Terminal names are unique -This is easy to accomplish by using the convention that Terminal names start with an uppercase letter -and Non-Terminal names start with a lower case letter.`},buildAlternationPrefixAmbiguityError(t){let e=Je(t.prefixPath,i=>Hu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx;return`Ambiguous alternatives: <${t.ambiguityIndices.join(" ,")}> due to common lookahead prefix -in inside <${t.topLevelRule.name}> Rule, -<${e}> may appears as a prefix path in all these alternatives. -See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX -For Further details.`},buildAlternationAmbiguityError(t){let e=Je(t.prefixPath,i=>Hu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(" ,")}> in inside <${t.topLevelRule.name}> Rule, -<${e}> may appears as a prefix path in all these alternatives. -`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES -For Further details.`,n},buildEmptyRepetitionError(t){let e=Vs(t.repetition);return t.repetition.idx!==0&&(e+=t.repetition.idx),`The repetition <${e}> within Rule <${t.topLevelRule.name}> can never consume any tokens. -This could lead to an infinite loop.`},buildTokenNameError(t){return"deprecated"},buildEmptyAlternationError(t){return`Ambiguous empty alternative: <${t.emptyChoiceIdx+1}> in inside <${t.topLevelRule.name}> Rule. -Only the last alternative may be an empty alternative.`},buildTooManyAlternativesError(t){return`An Alternation cannot have more than 256 alternatives: - inside <${t.topLevelRule.name}> Rule. - has ${t.alternation.definition.length+1} alternatives.`},buildLeftRecursionError(t){let e=t.topLevelRule.name,r=Je(t.leftRecursionPath,a=>a.name),n=`${e} --> ${r.concat([e]).join(" --> ")}`;return`Left Recursion found in grammar. -rule: <${e}> can be invoked from itself (directly or indirectly) -without consuming any Tokens. The grammar path that causes this is: - ${n} - To fix this refactor your grammar to remove the left recursion. -see: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`},buildInvalidRuleNameError(t){return"deprecated"},buildDuplicateRuleNameError(t){let e;return t.topLevelRule instanceof us?e=t.topLevelRule.name:e=t.topLevelRule,`Duplicate definition, rule: ->${e}<- is already defined in the grammar: ->${t.grammarName}<-`}}});function _oe(t,e){let r=new pM(t,e);return r.resolveRefs(),r.errors}var pM,Doe=N(()=>{"use strict";Us();qt();fs();o(_oe,"resolveGrammar");pM=class extends hs{static{o(this,"GastRefResolverVisitor")}constructor(e,r){super(),this.nameToTopRule=e,this.errMsgProvider=r,this.errors=[]}resolveRefs(){Ae(br(this.nameToTopRule),e=>{this.currTopLevel=e,e.accept(this)})}visitNonTerminal(e){let r=this.nameToTopRule[e.nonTerminalName];if(r)e.referencedRule=r;else{let n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,e);this.errors.push({message:n,type:Vi.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:e.nonTerminalName})}}}});function Jk(t,e,r=[]){r=an(r);let n=[],i=0;function a(l){return l.concat(bi(t,i+1))}o(a,"remainingPathWith");function s(l){let u=Jk(a(l),e,r);return n.concat(u)}for(o(s,"getAlternativesForProd");r.length{hr(u.definition)===!1&&(n=s(u.definition))}),n;if(l instanceof Er)r.push(l.terminalType);else throw Error("non exhaustive match")}i++}return n.push({partialPath:r,suffixDef:bi(t,i)}),n}function eE(t,e,r,n){let i="EXIT_NONE_TERMINAL",a=[i],s="EXIT_ALTERNATIVE",l=!1,u=e.length,h=u-n-1,f=[],d=[];for(d.push({idx:-1,def:t,ruleStack:[],occurrenceStack:[]});!hr(d);){let p=d.pop();if(p===s){l&&ma(d).idx<=h&&d.pop();continue}let m=p.def,g=p.idx,y=p.ruleStack,v=p.occurrenceStack;if(hr(m))continue;let x=m[0];if(x===i){let b={idx:g,def:bi(m),ruleStack:Fu(y),occurrenceStack:Fu(v)};d.push(b)}else if(x instanceof Er)if(g=0;b--){let T=x.definition[b],S={idx:g,def:T.definition.concat(bi(m)),ruleStack:y,occurrenceStack:v};d.push(S),d.push(s)}else if(x instanceof Dn)d.push({idx:g,def:x.definition.concat(bi(m)),ruleStack:y,occurrenceStack:v});else if(x instanceof us)d.push(kFe(x,g,y,v));else throw Error("non exhaustive match")}return f}function kFe(t,e,r,n){let i=an(r);i.push(t.name);let a=an(n);return a.push(1),{idx:e,def:t.definition,ruleStack:i,occurrenceStack:a}}var mM,Kk,Zg,Qk,yx,Zk,vx,xx=N(()=>{"use strict";qt();rM();Vk();fs();mM=class extends Gu{static{o(this,"AbstractNextPossibleTokensWalker")}constructor(e,r){super(),this.topProd=e,this.path=r,this.possibleTokTypes=[],this.nextProductionName="",this.nextProductionOccurrence=0,this.found=!1,this.isAtEndOfPath=!1}startWalking(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=an(this.path.ruleStack).reverse(),this.occurrenceStack=an(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes}walk(e,r=[]){this.found||super.walk(e,r)}walkProdRef(e,r,n){if(e.referencedRule.name===this.nextProductionName&&e.idx===this.nextProductionOccurrence){let i=r.concat(n);this.updateExpectedNext(),this.walk(e.referencedRule,i)}}updateExpectedNext(){hr(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())}},Kk=class extends mM{static{o(this,"NextAfterTokenWalker")}constructor(e,r){super(e,r),this.path=r,this.nextTerminalName="",this.nextTerminalOccurrence=0,this.nextTerminalName=this.path.lastTok.name,this.nextTerminalOccurrence=this.path.lastTokOccurrence}walkTerminal(e,r,n){if(this.isAtEndOfPath&&e.terminalType.name===this.nextTerminalName&&e.idx===this.nextTerminalOccurrence&&!this.found){let i=r.concat(n),a=new Dn({definition:i});this.possibleTokTypes=yp(a),this.found=!0}}},Zg=class extends Gu{static{o(this,"AbstractNextTerminalAfterProductionWalker")}constructor(e,r){super(),this.topRule=e,this.occurrence=r,this.result={token:void 0,occurrence:void 0,isEndOfRule:void 0}}startWalking(){return this.walk(this.topRule),this.result}},Qk=class extends Zg{static{o(this,"NextTerminalAfterManyWalker")}walkMany(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkMany(e,r,n)}},yx=class extends Zg{static{o(this,"NextTerminalAfterManySepWalker")}walkManySep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkManySep(e,r,n)}},Zk=class extends Zg{static{o(this,"NextTerminalAfterAtLeastOneWalker")}walkAtLeastOne(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOne(e,r,n)}},vx=class extends Zg{static{o(this,"NextTerminalAfterAtLeastOneSepWalker")}walkAtLeastOneSep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof Er&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOneSep(e,r,n)}};o(Jk,"possiblePathsFrom");o(eE,"nextPossibleTokensAfter");o(kFe,"expandTopLevelRule")});function bx(t){if(t instanceof ln||t==="Option")return Qn.OPTION;if(t instanceof Pr||t==="Repetition")return Qn.REPETITION;if(t instanceof Ln||t==="RepetitionMandatory")return Qn.REPETITION_MANDATORY;if(t instanceof Rn||t==="RepetitionMandatoryWithSeparator")return Qn.REPETITION_MANDATORY_WITH_SEPARATOR;if(t instanceof Tn||t==="RepetitionWithSeparator")return Qn.REPETITION_WITH_SEPARATOR;if(t instanceof wn||t==="Alternation")return Qn.ALTERNATION;throw Error("non exhaustive match")}function rE(t){let{occurrence:e,rule:r,prodType:n,maxLookahead:i}=t,a=bx(n);return a===Qn.ALTERNATION?Jg(e,r,i):e1(e,r,a,i)}function Roe(t,e,r,n,i,a){let s=Jg(t,e,r),l=Boe(s)?jg:Vu;return a(s,n,l,i)}function Noe(t,e,r,n,i,a){let s=e1(t,e,i,r),l=Boe(s)?jg:Vu;return a(s[0],l,n)}function Moe(t,e,r,n){let i=t.length,a=Pa(t,s=>Pa(s,l=>l.length===1));if(e)return function(s){let l=Je(s,u=>u.GATE);for(let u=0;uqr(u)),l=Xr(s,(u,h,f)=>(Ae(h,d=>{Bt(u,d.tokenTypeIdx)||(u[d.tokenTypeIdx]=f),Ae(d.categoryMatches,p=>{Bt(u,p)||(u[p]=f)})}),u),{});return function(){let u=this.LA(1);return l[u.tokenTypeIdx]}}else return function(){for(let s=0;sa.length===1),i=t.length;if(n&&!r){let a=qr(t);if(a.length===1&&hr(a[0].categoryMatches)){let l=a[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===l}}else{let s=Xr(a,(l,u,h)=>(l[u.tokenTypeIdx]=!0,Ae(u.categoryMatches,f=>{l[f]=!0}),l),[]);return function(){let l=this.LA(1);return s[l.tokenTypeIdx]===!0}}}else return function(){e:for(let a=0;aJk([s],1)),n=Loe(r.length),i=Je(r,s=>{let l={};return Ae(s,u=>{let h=gM(u.partialPath);Ae(h,f=>{l[f]=!0})}),l}),a=r;for(let s=1;s<=e;s++){let l=a;a=Loe(l.length);for(let u=0;u{let x=gM(v.partialPath);Ae(x,b=>{i[u][b]=!0})})}}}}return n}function Jg(t,e,r,n){let i=new tE(t,Qn.ALTERNATION,n);return e.accept(i),Ooe(i.result,r)}function e1(t,e,r,n){let i=new tE(t,r);e.accept(i);let a=i.result,l=new yM(e,t,r).startWalking(),u=new Dn({definition:a}),h=new Dn({definition:l});return Ooe([u,h],n)}function nE(t,e){e:for(let r=0;r{let i=e[n];return r===i||i.categoryMatchesMap[r.tokenTypeIdx]})}function Boe(t){return Pa(t,e=>Pa(e,r=>Pa(r,n=>hr(n.categoryMatches))))}var Qn,yM,tE,t1=N(()=>{"use strict";qt();xx();Vk();xp();fs();(function(t){t[t.OPTION=0]="OPTION",t[t.REPETITION=1]="REPETITION",t[t.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",t[t.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",t[t.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",t[t.ALTERNATION=5]="ALTERNATION"})(Qn||(Qn={}));o(bx,"getProdType");o(rE,"getLookaheadPaths");o(Roe,"buildLookaheadFuncForOr");o(Noe,"buildLookaheadFuncForOptionalProd");o(Moe,"buildAlternativesLookAheadFunc");o(Ioe,"buildSingleAlternativeLookaheadFunction");yM=class extends Gu{static{o(this,"RestDefinitionFinderWalker")}constructor(e,r,n){super(),this.topProd=e,this.targetOccurrence=r,this.targetProdType=n}startWalking(){return this.walk(this.topProd),this.restDef}checkIsTarget(e,r,n,i){return e.idx===this.targetOccurrence&&this.targetProdType===r?(this.restDef=n.concat(i),!0):!1}walkOption(e,r,n){this.checkIsTarget(e,Qn.OPTION,r,n)||super.walkOption(e,r,n)}walkAtLeastOne(e,r,n){this.checkIsTarget(e,Qn.REPETITION_MANDATORY,r,n)||super.walkOption(e,r,n)}walkAtLeastOneSep(e,r,n){this.checkIsTarget(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}walkMany(e,r,n){this.checkIsTarget(e,Qn.REPETITION,r,n)||super.walkOption(e,r,n)}walkManySep(e,r,n){this.checkIsTarget(e,Qn.REPETITION_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}},tE=class extends hs{static{o(this,"InsideDefinitionFinderVisitor")}constructor(e,r,n){super(),this.targetOccurrence=e,this.targetProdType=r,this.targetRef=n,this.result=[]}checkIsTarget(e,r){e.idx===this.targetOccurrence&&this.targetProdType===r&&(this.targetRef===void 0||e===this.targetRef)&&(this.result=e.definition)}visitOption(e){this.checkIsTarget(e,Qn.OPTION)}visitRepetition(e){this.checkIsTarget(e,Qn.REPETITION)}visitRepetitionMandatory(e){this.checkIsTarget(e,Qn.REPETITION_MANDATORY)}visitRepetitionMandatoryWithSeparator(e){this.checkIsTarget(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR)}visitRepetitionWithSeparator(e){this.checkIsTarget(e,Qn.REPETITION_WITH_SEPARATOR)}visitAlternation(e){this.checkIsTarget(e,Qn.ALTERNATION)}};o(Loe,"initializeArrayOfArrays");o(gM,"pathToHashKeys");o(EFe,"isUniquePrefixHash");o(Ooe,"lookAheadSequenceFromAlternatives");o(Jg,"getLookaheadPathsForOr");o(e1,"getLookaheadPathsForOptionalProd");o(nE,"containsPath");o(Poe,"isStrictPrefixOfPath");o(Boe,"areTokenCategoriesNotUsed")});function Foe(t){let e=t.lookaheadStrategy.validate({rules:t.rules,tokenTypes:t.tokenTypes,grammarName:t.grammarName});return Je(e,r=>Object.assign({type:Vi.CUSTOM_LOOKAHEAD_VALIDATION},r))}function $oe(t,e,r,n){let i=ga(t,u=>SFe(u,r)),a=RFe(t,e,r),s=ga(t,u=>_Fe(u,r)),l=ga(t,u=>AFe(u,t,n,r));return i.concat(a,s,l)}function SFe(t,e){let r=new vM;t.accept(r);let n=r.allProductions,i=yR(n,CFe),a=zs(i,l=>l.length>1);return Je(br(a),l=>{let u=ia(l),h=e.buildDuplicateFoundError(t,l),f=Vs(u),d={message:h,type:Vi.DUPLICATE_PRODUCTIONS,ruleName:t.name,dslName:f,occurrence:u.idx},p=zoe(u);return p&&(d.parameter=p),d})}function CFe(t){return`${Vs(t)}_#_${t.idx}_#_${zoe(t)}`}function zoe(t){return t instanceof Er?t.terminalType.name:t instanceof on?t.nonTerminalName:""}function AFe(t,e,r,n){let i=[];if(Xr(e,(s,l)=>l.name===t.name?s+1:s,0)>1){let s=n.buildDuplicateRuleNameError({topLevelRule:t,grammarName:r});i.push({message:s,type:Vi.DUPLICATE_RULE_NAME,ruleName:t.name})}return i}function Goe(t,e,r){let n=[],i;return Xn(e,t)||(i=`Invalid rule override, rule: ->${t}<- cannot be overridden in the grammar: ->${r}<-as it is not defined in any of the super grammars `,n.push({message:i,type:Vi.INVALID_RULE_OVERRIDE,ruleName:t})),n}function bM(t,e,r,n=[]){let i=[],a=iE(e.definition);if(hr(a))return[];{let s=t.name;Xn(a,t)&&i.push({message:r.buildLeftRecursionError({topLevelRule:t,leftRecursionPath:n}),type:Vi.LEFT_RECURSION,ruleName:s});let u=af(a,n.concat([t])),h=ga(u,f=>{let d=an(n);return d.push(f),bM(t,f,r,d)});return i.concat(h)}}function iE(t){let e=[];if(hr(t))return e;let r=ia(t);if(r instanceof on)e.push(r.referencedRule);else if(r instanceof Dn||r instanceof ln||r instanceof Ln||r instanceof Rn||r instanceof Tn||r instanceof Pr)e=e.concat(iE(r.definition));else if(r instanceof wn)e=qr(Je(r.definition,a=>iE(a.definition)));else if(!(r instanceof Er))throw Error("non exhaustive match");let n=gp(r),i=t.length>1;if(n&&i){let a=bi(t);return e.concat(iE(a))}else return e}function Voe(t,e){let r=new Tx;t.accept(r);let n=r.alternations;return ga(n,a=>{let s=Fu(a.definition);return ga(s,(l,u)=>{let h=eE([l],[],Vu,1);return hr(h)?[{message:e.buildEmptyAlternationError({topLevelRule:t,alternation:a,emptyChoiceIdx:u}),type:Vi.NONE_LAST_EMPTY_ALT,ruleName:t.name,occurrence:a.idx,alternative:u+1}]:[]})})}function Uoe(t,e,r){let n=new Tx;t.accept(n);let i=n.alternations;return i=sf(i,s=>s.ignoreAmbiguities===!0),ga(i,s=>{let l=s.idx,u=s.maxLookahead||e,h=Jg(l,t,u,s),f=DFe(h,s,t,r),d=LFe(h,s,t,r);return f.concat(d)})}function _Fe(t,e){let r=new Tx;t.accept(r);let n=r.alternations;return ga(n,a=>a.definition.length>255?[{message:e.buildTooManyAlternativesError({topLevelRule:t,alternation:a}),type:Vi.TOO_MANY_ALTS,ruleName:t.name,occurrence:a.idx}]:[])}function Hoe(t,e,r){let n=[];return Ae(t,i=>{let a=new xM;i.accept(a);let s=a.allProductions;Ae(s,l=>{let u=bx(l),h=l.maxLookahead||e,f=l.idx,p=e1(f,i,u,h)[0];if(hr(qr(p))){let m=r.buildEmptyRepetitionError({topLevelRule:i,repetition:l});n.push({message:m,type:Vi.NO_NON_EMPTY_LOOKAHEAD,ruleName:i.name})}})}),n}function DFe(t,e,r,n){let i=[],a=Xr(t,(l,u,h)=>(e.definition[h].ignoreAmbiguities===!0||Ae(u,f=>{let d=[h];Ae(t,(p,m)=>{h!==m&&nE(p,f)&&e.definition[m].ignoreAmbiguities!==!0&&d.push(m)}),d.length>1&&!nE(i,f)&&(i.push(f),l.push({alts:d,path:f}))}),l),[]);return Je(a,l=>{let u=Je(l.alts,f=>f+1);return{message:n.buildAlternationAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:u,prefixPath:l.path}),type:Vi.AMBIGUOUS_ALTS,ruleName:r.name,occurrence:e.idx,alternatives:l.alts}})}function LFe(t,e,r,n){let i=Xr(t,(s,l,u)=>{let h=Je(l,f=>({idx:u,path:f}));return s.concat(h)},[]);return Ac(ga(i,s=>{if(e.definition[s.idx].ignoreAmbiguities===!0)return[];let u=s.idx,h=s.path,f=Yr(i,p=>e.definition[p.idx].ignoreAmbiguities!==!0&&p.idx{let m=[p.idx+1,u+1],g=e.idx===0?"":e.idx;return{message:n.buildAlternationPrefixAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:m,prefixPath:p.path}),type:Vi.AMBIGUOUS_PREFIX_ALTS,ruleName:r.name,occurrence:g,alternatives:m}})}))}function RFe(t,e,r){let n=[],i=Je(e,a=>a.name);return Ae(t,a=>{let s=a.name;if(Xn(i,s)){let l=r.buildNamespaceConflictError(a);n.push({message:l,type:Vi.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:s})}}),n}var vM,Tx,xM,wx=N(()=>{"use strict";qt();Us();fs();t1();xx();xp();o(Foe,"validateLookahead");o($oe,"validateGrammar");o(SFe,"validateDuplicateProductions");o(CFe,"identifyProductionForDuplicates");o(zoe,"getExtraProductionArgument");vM=class extends hs{static{o(this,"OccurrenceValidationCollector")}constructor(){super(...arguments),this.allProductions=[]}visitNonTerminal(e){this.allProductions.push(e)}visitOption(e){this.allProductions.push(e)}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}visitAlternation(e){this.allProductions.push(e)}visitTerminal(e){this.allProductions.push(e)}};o(AFe,"validateRuleDoesNotAlreadyExist");o(Goe,"validateRuleIsOverridden");o(bM,"validateNoLeftRecursion");o(iE,"getFirstNoneTerminal");Tx=class extends hs{static{o(this,"OrCollector")}constructor(){super(...arguments),this.alternations=[]}visitAlternation(e){this.alternations.push(e)}};o(Voe,"validateEmptyOrAlternative");o(Uoe,"validateAmbiguousAlternationAlternatives");xM=class extends hs{static{o(this,"RepetitionCollector")}constructor(){super(...arguments),this.allProductions=[]}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}};o(_Fe,"validateTooManyAlts");o(Hoe,"validateSomeNonEmptyLookaheadPath");o(DFe,"checkAlternativesAmbiguities");o(LFe,"checkPrefixAlternativesAmbiguities");o(RFe,"checkTerminalAndNoneTerminalsNameSpace")});function Woe(t){let e=nf(t,{errMsgProvider:Aoe}),r={};return Ae(t.rules,n=>{r[n.name]=n}),_oe(r,e.errMsgProvider)}function qoe(t){return t=nf(t,{errMsgProvider:$l}),$oe(t.rules,t.tokenTypes,t.errMsgProvider,t.grammarName)}var Yoe=N(()=>{"use strict";qt();Doe();wx();Qg();o(Woe,"resolveGrammar");o(qoe,"validateGrammar")});function pf(t){return Xn(Zoe,t.name)}var Xoe,joe,Koe,Qoe,Zoe,r1,Tp,kx,Ex,Sx,n1=N(()=>{"use strict";qt();Xoe="MismatchedTokenException",joe="NoViableAltException",Koe="EarlyExitException",Qoe="NotAllInputParsedException",Zoe=[Xoe,joe,Koe,Qoe];Object.freeze(Zoe);o(pf,"isRecognitionException");r1=class extends Error{static{o(this,"RecognitionException")}constructor(e,r){super(e),this.token=r,this.resyncedTokens=[],Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},Tp=class extends r1{static{o(this,"MismatchedTokenException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Xoe}},kx=class extends r1{static{o(this,"NoViableAltException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=joe}},Ex=class extends r1{static{o(this,"NotAllInputParsedException")}constructor(e,r){super(e,r),this.name=Qoe}},Sx=class extends r1{static{o(this,"EarlyExitException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Koe}}});function NFe(t,e,r,n,i,a,s){let l=this.getKeyForAutomaticLookahead(n,i),u=this.firstAfterRepMap[l];if(u===void 0){let p=this.getCurrRuleFullName(),m=this.getGAstProductions()[p];u=new a(m,i).startWalking(),this.firstAfterRepMap[l]=u}let h=u.token,f=u.occurrence,d=u.isEndOfRule;this.RULE_STACK.length===1&&d&&h===void 0&&(h=fo,f=1),!(h===void 0||f===void 0)&&this.shouldInRepetitionRecoveryBeTried(h,f,s)&&this.tryInRepetitionRecovery(t,e,r,h)}var TM,kM,wM,aE,EM=N(()=>{"use strict";bp();qt();n1();nM();Us();TM={},kM="InRuleRecoveryException",wM=class extends Error{static{o(this,"InRuleRecoveryException")}constructor(e){super(e),this.name=kM}},aE=class{static{o(this,"Recoverable")}initRecoverable(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=Bt(e,"recoveryEnabled")?e.recoveryEnabled:ds.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=NFe)}getTokenToInsert(e){let r=Wu(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return r.isInsertedInRecovery=!0,r}canTokenTypeBeInsertedInRecovery(e){return!0}canTokenTypeBeDeletedInRecovery(e){return!0}tryInRepetitionRecovery(e,r,n,i){let a=this.findReSyncTokenType(),s=this.exportLexerState(),l=[],u=!1,h=this.LA(1),f=this.LA(1),d=o(()=>{let p=this.LA(0),m=this.errorMessageProvider.buildMismatchTokenMessage({expected:i,actual:h,previous:p,ruleName:this.getCurrRuleFullName()}),g=new Tp(m,h,this.LA(0));g.resyncedTokens=Fu(l),this.SAVE_ERROR(g)},"generateErrorMessage");for(;!u;)if(this.tokenMatcher(f,i)){d();return}else if(n.call(this)){d(),e.apply(this,r);return}else this.tokenMatcher(f,a)?u=!0:(f=this.SKIP_TOKEN(),this.addToResyncTokens(f,l));this.importLexerState(s)}shouldInRepetitionRecoveryBeTried(e,r,n){return!(n===!1||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,r)))}getFollowsForInRuleRecovery(e,r){let n=this.getCurrentGrammarPath(e,r);return this.getNextPossibleTokenTypes(n)}tryInRuleRecovery(e,r){if(this.canRecoverWithSingleTokenInsertion(e,r))return this.getTokenToInsert(e);if(this.canRecoverWithSingleTokenDeletion(e)){let n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new wM("sad sad panda")}canPerformInRuleRecovery(e,r){return this.canRecoverWithSingleTokenInsertion(e,r)||this.canRecoverWithSingleTokenDeletion(e)}canRecoverWithSingleTokenInsertion(e,r){if(!this.canTokenTypeBeInsertedInRecovery(e)||hr(r))return!1;let n=this.LA(1);return ls(r,a=>this.tokenMatcher(n,a))!==void 0}canRecoverWithSingleTokenDeletion(e){return this.canTokenTypeBeDeletedInRecovery(e)?this.tokenMatcher(this.LA(2),e):!1}isInCurrentRuleReSyncSet(e){let r=this.getCurrFollowKey(),n=this.getFollowSetFromFollowKey(r);return Xn(n,e)}findReSyncTokenType(){let e=this.flattenFollowSet(),r=this.LA(1),n=2;for(;;){let i=ls(e,a=>gx(r,a));if(i!==void 0)return i;r=this.LA(n),n++}}getCurrFollowKey(){if(this.RULE_STACK.length===1)return TM;let e=this.getLastExplicitRuleShortName(),r=this.getLastExplicitRuleOccurrenceIndex(),n=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:r,inRule:this.shortRuleNameToFullName(n)}}buildFullFollowKeyStack(){let e=this.RULE_STACK,r=this.RULE_OCCURRENCE_STACK;return Je(e,(n,i)=>i===0?TM:{ruleName:this.shortRuleNameToFullName(n),idxInCallingRule:r[i],inRule:this.shortRuleNameToFullName(e[i-1])})}flattenFollowSet(){let e=Je(this.buildFullFollowKeyStack(),r=>this.getFollowSetFromFollowKey(r));return qr(e)}getFollowSetFromFollowKey(e){if(e===TM)return[fo];let r=e.ruleName+e.idxInCallingRule+Uk+e.inRule;return this.resyncFollows[r]}addToResyncTokens(e,r){return this.tokenMatcher(e,fo)||r.push(e),r}reSyncTo(e){let r=[],n=this.LA(1);for(;this.tokenMatcher(n,e)===!1;)n=this.SKIP_TOKEN(),this.addToResyncTokens(n,r);return Fu(r)}attemptInRepetitionRecovery(e,r,n,i,a,s,l){}getCurrentGrammarPath(e,r){let n=this.getHumanReadableRuleStack(),i=an(this.RULE_OCCURRENCE_STACK);return{ruleStack:n,occurrenceStack:i,lastTok:e,lastTokOccurrence:r}}getHumanReadableRuleStack(){return Je(this.RULE_STACK,e=>this.shortRuleNameToFullName(e))}};o(NFe,"attemptInRepetitionRecovery")});function sE(t,e,r){return r|e|t}var oE=N(()=>{"use strict";o(sE,"getKeyForAutomaticLookahead")});var Yu,SM=N(()=>{"use strict";qt();Qg();Us();wx();t1();Yu=class{static{o(this,"LLkLookaheadStrategy")}constructor(e){var r;this.maxLookahead=(r=e?.maxLookahead)!==null&&r!==void 0?r:ds.maxLookahead}validate(e){let r=this.validateNoLeftRecursion(e.rules);if(hr(r)){let n=this.validateEmptyOrAlternatives(e.rules),i=this.validateAmbiguousAlternationAlternatives(e.rules,this.maxLookahead),a=this.validateSomeNonEmptyLookaheadPath(e.rules,this.maxLookahead);return[...r,...n,...i,...a]}return r}validateNoLeftRecursion(e){return ga(e,r=>bM(r,r,$l))}validateEmptyOrAlternatives(e){return ga(e,r=>Voe(r,$l))}validateAmbiguousAlternationAlternatives(e,r){return ga(e,n=>Uoe(n,r,$l))}validateSomeNonEmptyLookaheadPath(e,r){return Hoe(e,r,$l)}buildLookaheadForAlternation(e){return Roe(e.prodOccurrence,e.rule,e.maxLookahead,e.hasPredicates,e.dynamicTokensEnabled,Moe)}buildLookaheadForOptional(e){return Noe(e.prodOccurrence,e.rule,e.maxLookahead,e.dynamicTokensEnabled,bx(e.prodType),Ioe)}}});function MFe(t){lE.reset(),t.accept(lE);let e=lE.dslMethods;return lE.reset(),e}var cE,CM,lE,Joe=N(()=>{"use strict";qt();Us();oE();fs();SM();cE=class{static{o(this,"LooksAhead")}initLooksAhead(e){this.dynamicTokensEnabled=Bt(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:ds.dynamicTokensEnabled,this.maxLookahead=Bt(e,"maxLookahead")?e.maxLookahead:ds.maxLookahead,this.lookaheadStrategy=Bt(e,"lookaheadStrategy")?e.lookaheadStrategy:new Yu({maxLookahead:this.maxLookahead}),this.lookAheadFuncsCache=new Map}preComputeLookaheadFunctions(e){Ae(e,r=>{this.TRACE_INIT(`${r.name} Rule Lookahead`,()=>{let{alternation:n,repetition:i,option:a,repetitionMandatory:s,repetitionMandatoryWithSeparator:l,repetitionWithSeparator:u}=MFe(r);Ae(n,h=>{let f=h.idx===0?"":h.idx;this.TRACE_INIT(`${Vs(h)}${f}`,()=>{let d=this.lookaheadStrategy.buildLookaheadForAlternation({prodOccurrence:h.idx,rule:r,maxLookahead:h.maxLookahead||this.maxLookahead,hasPredicates:h.hasPredicates,dynamicTokensEnabled:this.dynamicTokensEnabled}),p=sE(this.fullRuleNameToShort[r.name],256,h.idx);this.setLaFuncCache(p,d)})}),Ae(i,h=>{this.computeLookaheadFunc(r,h.idx,768,"Repetition",h.maxLookahead,Vs(h))}),Ae(a,h=>{this.computeLookaheadFunc(r,h.idx,512,"Option",h.maxLookahead,Vs(h))}),Ae(s,h=>{this.computeLookaheadFunc(r,h.idx,1024,"RepetitionMandatory",h.maxLookahead,Vs(h))}),Ae(l,h=>{this.computeLookaheadFunc(r,h.idx,1536,"RepetitionMandatoryWithSeparator",h.maxLookahead,Vs(h))}),Ae(u,h=>{this.computeLookaheadFunc(r,h.idx,1280,"RepetitionWithSeparator",h.maxLookahead,Vs(h))})})})}computeLookaheadFunc(e,r,n,i,a,s){this.TRACE_INIT(`${s}${r===0?"":r}`,()=>{let l=this.lookaheadStrategy.buildLookaheadForOptional({prodOccurrence:r,rule:e,maxLookahead:a||this.maxLookahead,dynamicTokensEnabled:this.dynamicTokensEnabled,prodType:i}),u=sE(this.fullRuleNameToShort[e.name],n,r);this.setLaFuncCache(u,l)})}getKeyForAutomaticLookahead(e,r){let n=this.getLastExplicitRuleShortName();return sE(n,e,r)}getLaFuncFromCache(e){return this.lookAheadFuncsCache.get(e)}setLaFuncCache(e,r){this.lookAheadFuncsCache.set(e,r)}},CM=class extends hs{static{o(this,"DslMethodsCollectorVisitor")}constructor(){super(...arguments),this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}reset(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}visitOption(e){this.dslMethods.option.push(e)}visitRepetitionWithSeparator(e){this.dslMethods.repetitionWithSeparator.push(e)}visitRepetitionMandatory(e){this.dslMethods.repetitionMandatory.push(e)}visitRepetitionMandatoryWithSeparator(e){this.dslMethods.repetitionMandatoryWithSeparator.push(e)}visitRepetition(e){this.dslMethods.repetition.push(e)}visitAlternation(e){this.dslMethods.alternation.push(e)}},lE=new CM;o(MFe,"collectMethods")});function DM(t,e){isNaN(t.startOffset)===!0?(t.startOffset=e.startOffset,t.endOffset=e.endOffset):t.endOffset{"use strict";o(DM,"setNodeLocationOnlyOffset");o(LM,"setNodeLocationFull");o(ele,"addTerminalToCst");o(tle,"addNoneTerminalToCst")});function RM(t,e){Object.defineProperty(t,IFe,{enumerable:!1,configurable:!0,writable:!1,value:e})}var IFe,nle=N(()=>{"use strict";IFe="name";o(RM,"defineNameProp")});function OFe(t,e){let r=zr(t),n=r.length;for(let i=0;is.msg);throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>: - ${a.join(` - -`).replace(/\n/g,` - `)}`)}},"validateVisitor")};return r.prototype=n,r.prototype.constructor=r,r._RULE_NAMES=e,r}function ale(t,e,r){let n=o(function(){},"derivedConstructor");RM(n,t+"BaseSemanticsWithDefaults");let i=Object.create(r.prototype);return Ae(e,a=>{i[a]=OFe}),n.prototype=i,n.prototype.constructor=n,n}function PFe(t,e){return BFe(t,e)}function BFe(t,e){let r=Yr(e,i=>Ai(t[i])===!1),n=Je(r,i=>({msg:`Missing visitor method: <${i}> on ${t.constructor.name} CST Visitor.`,type:NM.MISSING_METHOD,methodName:i}));return Ac(n)}var NM,sle=N(()=>{"use strict";qt();nle();o(OFe,"defaultVisit");o(ile,"createBaseSemanticVisitorConstructor");o(ale,"createBaseVisitorConstructorWithDefaults");(function(t){t[t.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",t[t.MISSING_METHOD=1]="MISSING_METHOD"})(NM||(NM={}));o(PFe,"validateVisitor");o(BFe,"validateMissingCstMethods")});var dE,ole=N(()=>{"use strict";rle();qt();sle();Us();dE=class{static{o(this,"TreeBuilder")}initTreeBuilder(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=Bt(e,"nodeLocationTracking")?e.nodeLocationTracking:ds.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=ai,this.cstFinallyStateUpdate=ai,this.cstPostTerminal=ai,this.cstPostNonTerminal=ai,this.cstPostRule=ai;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=LM,this.setNodeLocationFromNode=LM,this.cstPostRule=ai,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=DM,this.setNodeLocationFromNode=DM,this.cstPostRule=ai,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=ai,this.setNodeLocationFromNode=ai,this.cstPostRule=ai,this.setInitialNodeLocation=ai;else throw Error(`Invalid config option: "${e.nodeLocationTracking}"`)}setInitialNodeLocationOnlyOffsetRecovery(e){e.location={startOffset:NaN,endOffset:NaN}}setInitialNodeLocationOnlyOffsetRegular(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}}setInitialNodeLocationFullRecovery(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}}setInitialNodeLocationFullRegular(e){let r=this.LA(1);e.location={startOffset:r.startOffset,startLine:r.startLine,startColumn:r.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}}cstInvocationStateUpdate(e){let r={name:e,children:Object.create(null)};this.setInitialNodeLocation(r),this.CST_STACK.push(r)}cstFinallyStateUpdate(){this.CST_STACK.pop()}cstPostRuleFull(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?(n.endOffset=r.endOffset,n.endLine=r.endLine,n.endColumn=r.endColumn):(n.startOffset=NaN,n.startLine=NaN,n.startColumn=NaN)}cstPostRuleOnlyOffset(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?n.endOffset=r.endOffset:n.startOffset=NaN}cstPostTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];ele(n,r,e),this.setNodeLocationFromToken(n.location,r)}cstPostNonTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];tle(n,r,e),this.setNodeLocationFromNode(n.location,e.location)}getBaseCstVisitorConstructor(){if(mr(this.baseCstVisitorConstructor)){let e=ile(this.className,zr(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor}getBaseCstVisitorConstructorWithDefaults(){if(mr(this.baseCstVisitorWithDefaultsConstructor)){let e=ale(this.className,zr(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor}getLastExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-1]}getPreviousExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-2]}getLastExplicitRuleOccurrenceIndex(){let e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]}}});var pE,lle=N(()=>{"use strict";Us();pE=class{static{o(this,"LexerAdapter")}initLexerAdapter(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1}set input(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length}get input(){return this.tokVector}SKIP_TOKEN(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):i1}LA(e){let r=this.currIdx+e;return r<0||this.tokVectorLength<=r?i1:this.tokVector[r]}consumeToken(){this.currIdx++}exportLexerState(){return this.currIdx}importLexerState(e){this.currIdx=e}resetLexerState(){this.currIdx=-1}moveToTerminatedState(){this.currIdx=this.tokVector.length-1}getLexerPosition(){return this.exportLexerState()}}});var mE,cle=N(()=>{"use strict";qt();n1();Us();Qg();wx();fs();mE=class{static{o(this,"RecognizerApi")}ACTION(e){return e.call(this)}consume(e,r,n){return this.consumeInternal(r,e,n)}subrule(e,r,n){return this.subruleInternal(r,e,n)}option(e,r){return this.optionInternal(r,e)}or(e,r){return this.orInternal(r,e)}many(e,r){return this.manyInternal(e,r)}atLeastOne(e,r){return this.atLeastOneInternal(e,r)}CONSUME(e,r){return this.consumeInternal(e,0,r)}CONSUME1(e,r){return this.consumeInternal(e,1,r)}CONSUME2(e,r){return this.consumeInternal(e,2,r)}CONSUME3(e,r){return this.consumeInternal(e,3,r)}CONSUME4(e,r){return this.consumeInternal(e,4,r)}CONSUME5(e,r){return this.consumeInternal(e,5,r)}CONSUME6(e,r){return this.consumeInternal(e,6,r)}CONSUME7(e,r){return this.consumeInternal(e,7,r)}CONSUME8(e,r){return this.consumeInternal(e,8,r)}CONSUME9(e,r){return this.consumeInternal(e,9,r)}SUBRULE(e,r){return this.subruleInternal(e,0,r)}SUBRULE1(e,r){return this.subruleInternal(e,1,r)}SUBRULE2(e,r){return this.subruleInternal(e,2,r)}SUBRULE3(e,r){return this.subruleInternal(e,3,r)}SUBRULE4(e,r){return this.subruleInternal(e,4,r)}SUBRULE5(e,r){return this.subruleInternal(e,5,r)}SUBRULE6(e,r){return this.subruleInternal(e,6,r)}SUBRULE7(e,r){return this.subruleInternal(e,7,r)}SUBRULE8(e,r){return this.subruleInternal(e,8,r)}SUBRULE9(e,r){return this.subruleInternal(e,9,r)}OPTION(e){return this.optionInternal(e,0)}OPTION1(e){return this.optionInternal(e,1)}OPTION2(e){return this.optionInternal(e,2)}OPTION3(e){return this.optionInternal(e,3)}OPTION4(e){return this.optionInternal(e,4)}OPTION5(e){return this.optionInternal(e,5)}OPTION6(e){return this.optionInternal(e,6)}OPTION7(e){return this.optionInternal(e,7)}OPTION8(e){return this.optionInternal(e,8)}OPTION9(e){return this.optionInternal(e,9)}OR(e){return this.orInternal(e,0)}OR1(e){return this.orInternal(e,1)}OR2(e){return this.orInternal(e,2)}OR3(e){return this.orInternal(e,3)}OR4(e){return this.orInternal(e,4)}OR5(e){return this.orInternal(e,5)}OR6(e){return this.orInternal(e,6)}OR7(e){return this.orInternal(e,7)}OR8(e){return this.orInternal(e,8)}OR9(e){return this.orInternal(e,9)}MANY(e){this.manyInternal(0,e)}MANY1(e){this.manyInternal(1,e)}MANY2(e){this.manyInternal(2,e)}MANY3(e){this.manyInternal(3,e)}MANY4(e){this.manyInternal(4,e)}MANY5(e){this.manyInternal(5,e)}MANY6(e){this.manyInternal(6,e)}MANY7(e){this.manyInternal(7,e)}MANY8(e){this.manyInternal(8,e)}MANY9(e){this.manyInternal(9,e)}MANY_SEP(e){this.manySepFirstInternal(0,e)}MANY_SEP1(e){this.manySepFirstInternal(1,e)}MANY_SEP2(e){this.manySepFirstInternal(2,e)}MANY_SEP3(e){this.manySepFirstInternal(3,e)}MANY_SEP4(e){this.manySepFirstInternal(4,e)}MANY_SEP5(e){this.manySepFirstInternal(5,e)}MANY_SEP6(e){this.manySepFirstInternal(6,e)}MANY_SEP7(e){this.manySepFirstInternal(7,e)}MANY_SEP8(e){this.manySepFirstInternal(8,e)}MANY_SEP9(e){this.manySepFirstInternal(9,e)}AT_LEAST_ONE(e){this.atLeastOneInternal(0,e)}AT_LEAST_ONE1(e){return this.atLeastOneInternal(1,e)}AT_LEAST_ONE2(e){this.atLeastOneInternal(2,e)}AT_LEAST_ONE3(e){this.atLeastOneInternal(3,e)}AT_LEAST_ONE4(e){this.atLeastOneInternal(4,e)}AT_LEAST_ONE5(e){this.atLeastOneInternal(5,e)}AT_LEAST_ONE6(e){this.atLeastOneInternal(6,e)}AT_LEAST_ONE7(e){this.atLeastOneInternal(7,e)}AT_LEAST_ONE8(e){this.atLeastOneInternal(8,e)}AT_LEAST_ONE9(e){this.atLeastOneInternal(9,e)}AT_LEAST_ONE_SEP(e){this.atLeastOneSepFirstInternal(0,e)}AT_LEAST_ONE_SEP1(e){this.atLeastOneSepFirstInternal(1,e)}AT_LEAST_ONE_SEP2(e){this.atLeastOneSepFirstInternal(2,e)}AT_LEAST_ONE_SEP3(e){this.atLeastOneSepFirstInternal(3,e)}AT_LEAST_ONE_SEP4(e){this.atLeastOneSepFirstInternal(4,e)}AT_LEAST_ONE_SEP5(e){this.atLeastOneSepFirstInternal(5,e)}AT_LEAST_ONE_SEP6(e){this.atLeastOneSepFirstInternal(6,e)}AT_LEAST_ONE_SEP7(e){this.atLeastOneSepFirstInternal(7,e)}AT_LEAST_ONE_SEP8(e){this.atLeastOneSepFirstInternal(8,e)}AT_LEAST_ONE_SEP9(e){this.atLeastOneSepFirstInternal(9,e)}RULE(e,r,n=a1){if(Xn(this.definedRulesNames,e)){let s={message:$l.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),type:Vi.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);let i=this.defineRule(e,r,n);return this[e]=i,i}OVERRIDE_RULE(e,r,n=a1){let i=Goe(e,this.definedRulesNames,this.className);this.definitionErrors=this.definitionErrors.concat(i);let a=this.defineRule(e,r,n);return this[e]=a,a}BACKTRACK(e,r){return function(){this.isBackTrackingStack.push(1);let n=this.saveRecogState();try{return e.apply(this,r),!0}catch(i){if(pf(i))return!1;throw i}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}}getGAstProductions(){return this.gastProductionsCache}getSerializedGastProductions(){return zk(br(this.gastProductionsCache))}}});var gE,ule=N(()=>{"use strict";qt();oE();n1();t1();xx();Us();EM();bp();xp();gE=class{static{o(this,"RecognizerEngine")}initRecognizerEngine(e,r){if(this.className=this.constructor.name,this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=jg,this.subruleIdx=0,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},Bt(r,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. - See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 - For Further details.`);if(Pt(e)){if(hr(e))throw Error(`A Token Vocabulary cannot be empty. - Note that the first argument for the parser constructor - is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. - See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 - For Further details.`)}if(Pt(e))this.tokensMap=Xr(e,(a,s)=>(a[s.name]=s,a),{});else if(Bt(e,"modes")&&Pa(qr(br(e.modes)),voe)){let a=qr(br(e.modes)),s=qm(a);this.tokensMap=Xr(s,(l,u)=>(l[u.name]=u,l),{})}else if(bn(e))this.tokensMap=an(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=fo;let n=Bt(e,"modes")?qr(br(e.modes)):br(e),i=Pa(n,a=>hr(a.categoryMatches));this.tokenMatcher=i?jg:Vu,Uu(br(this.tokensMap))}defineRule(e,r,n){if(this.selfAnalysisDone)throw Error(`Grammar rule <${e}> may not be defined after the 'performSelfAnalysis' method has been called' -Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);let i=Bt(n,"resyncEnabled")?n.resyncEnabled:a1.resyncEnabled,a=Bt(n,"recoveryValueFunc")?n.recoveryValueFunc:a1.recoveryValueFunc,s=this.ruleShortNameIdx<<12;this.ruleShortNameIdx++,this.shortRuleNameToFull[s]=e,this.fullRuleNameToShort[e]=s;let l;return this.outputCst===!0?l=o(function(...f){try{this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f);let d=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(d),d}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTry"):l=o(function(...f){try{return this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f)}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTryCst"),Object.assign(l,{ruleName:e,originalGrammarAction:r})}invokeRuleCatch(e,r,n){let i=this.RULE_STACK.length===1,a=r&&!this.isBackTracking()&&this.recoveryEnabled;if(pf(e)){let s=e;if(a){let l=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(l))if(s.resyncedTokens=this.reSyncTo(l),this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];return u.recoveredNode=!0,u}else return n(e);else{if(this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];u.recoveredNode=!0,s.partialCstResult=u}throw s}}else{if(i)return this.moveToTerminatedState(),n(e);throw s}}else throw e}optionInternal(e,r){let n=this.getKeyForAutomaticLookahead(512,r);return this.optionInternalLogic(e,r,n)}optionInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof e!="function"){a=e.DEF;let s=e.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=e;if(i.call(this)===!0)return a.call(this)}atLeastOneInternal(e,r){let n=this.getKeyForAutomaticLookahead(1024,e);return this.atLeastOneInternalLogic(e,r,n)}atLeastOneInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let s=r.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=r;if(i.call(this)===!0){let s=this.doSingleRepetition(a);for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a)}else throw this.raiseEarlyExitException(e,Qn.REPETITION_MANDATORY,r.ERR_MSG);this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,r],i,1024,e,Zk)}atLeastOneSepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1536,e);this.atLeastOneSepFirstInternalLogic(e,r,n)}atLeastOneSepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,vx],l,1536,e,vx)}else throw this.raiseEarlyExitException(e,Qn.REPETITION_MANDATORY_WITH_SEPARATOR,r.ERR_MSG)}manyInternal(e,r){let n=this.getKeyForAutomaticLookahead(768,e);return this.manyInternalLogic(e,r,n)}manyInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let l=r.GATE;if(l!==void 0){let u=i;i=o(()=>l.call(this)&&u.call(this),"lookaheadFunction")}}else a=r;let s=!0;for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a);this.attemptInRepetitionRecovery(this.manyInternal,[e,r],i,768,e,Qk,s)}manySepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1280,e);this.manySepFirstInternalLogic(e,r,n)}manySepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,yx],l,1280,e,yx)}}repetitionSepSecondInternal(e,r,n,i,a){for(;n();)this.CONSUME(r),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,r,n,i,a],n,1536,e,a)}doSingleRepetition(e){let r=this.getLexerPosition();return e.call(this),this.getLexerPosition()>r}orInternal(e,r){let n=this.getKeyForAutomaticLookahead(256,r),i=Pt(e)?e:e.DEF,s=this.getLaFuncFromCache(n).call(this,i);if(s!==void 0)return i[s].ALT.call(this);this.raiseNoAltException(r,e.ERR_MSG)}ruleFinallyStateUpdate(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){let e=this.LA(1),r=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new Ex(r,e))}}subruleInternal(e,r,n){let i;try{let a=n!==void 0?n.ARGS:void 0;return this.subruleIdx=r,i=e.apply(this,a),this.cstPostNonTerminal(i,n!==void 0&&n.LABEL!==void 0?n.LABEL:e.ruleName),i}catch(a){throw this.subruleInternalError(a,n,e.ruleName)}}subruleInternalError(e,r,n){throw pf(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,r!==void 0&&r.LABEL!==void 0?r.LABEL:n),delete e.partialCstResult),e}consumeInternal(e,r,n){let i;try{let a=this.LA(1);this.tokenMatcher(a,e)===!0?(this.consumeToken(),i=a):this.consumeInternalError(e,a,n)}catch(a){i=this.consumeInternalRecovery(e,r,a)}return this.cstPostTerminal(n!==void 0&&n.LABEL!==void 0?n.LABEL:e.name,i),i}consumeInternalError(e,r,n){let i,a=this.LA(0);throw n!==void 0&&n.ERR_MSG?i=n.ERR_MSG:i=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:r,previous:a,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new Tp(i,r,a))}consumeInternalRecovery(e,r,n){if(this.recoveryEnabled&&n.name==="MismatchedTokenException"&&!this.isBackTracking()){let i=this.getFollowsForInRuleRecovery(e,r);try{return this.tryInRuleRecovery(e,i)}catch(a){throw a.name===kM?n:a}}else throw n}saveRecogState(){let e=this.errors,r=an(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:r,CST_STACK:this.CST_STACK}}reloadRecogState(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK}ruleInvocationStateUpdate(e,r,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(r)}isBackTracking(){return this.isBackTrackingStack.length!==0}getCurrRuleFullName(){let e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]}shortRuleNameToFullName(e){return this.shortRuleNameToFull[e]}isAtEndOfInput(){return this.tokenMatcher(this.LA(1),fo)}reset(){this.resetLexerState(),this.subruleIdx=0,this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]}}});var yE,hle=N(()=>{"use strict";n1();qt();t1();Us();yE=class{static{o(this,"ErrorHandler")}initErrorHandler(e){this._errors=[],this.errorMessageProvider=Bt(e,"errorMessageProvider")?e.errorMessageProvider:ds.errorMessageProvider}SAVE_ERROR(e){if(pf(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:an(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")}get errors(){return an(this._errors)}set errors(e){this._errors=e}raiseEarlyExitException(e,r,n){let i=this.getCurrRuleFullName(),a=this.getGAstProductions()[i],l=e1(e,a,r,this.maxLookahead)[0],u=[];for(let f=1;f<=this.maxLookahead;f++)u.push(this.LA(f));let h=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:l,actual:u,previous:this.LA(0),customUserDescription:n,ruleName:i});throw this.SAVE_ERROR(new Sx(h,this.LA(1),this.LA(0)))}raiseNoAltException(e,r){let n=this.getCurrRuleFullName(),i=this.getGAstProductions()[n],a=Jg(e,i,this.maxLookahead),s=[];for(let h=1;h<=this.maxLookahead;h++)s.push(this.LA(h));let l=this.LA(0),u=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:a,actual:s,previous:l,customUserDescription:r,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new kx(u,this.LA(1),l))}}});var vE,fle=N(()=>{"use strict";xx();qt();vE=class{static{o(this,"ContentAssist")}initContentAssist(){}computeContentAssist(e,r){let n=this.gastProductionsCache[e];if(mr(n))throw Error(`Rule ->${e}<- does not exist in this grammar.`);return eE([n],r,this.tokenMatcher,this.maxLookahead)}getNextPossibleTokenTypes(e){let r=ia(e.ruleStack),i=this.getGAstProductions()[r];return new Kk(i,e).startWalking()}}});function Ax(t,e,r,n=!1){bE(r);let i=ma(this.recordingProdStack),a=Ai(e)?e:e.DEF,s=new t({definition:[],idx:r});return n&&(s.separator=e.SEP),Bt(e,"MAX_LOOKAHEAD")&&(s.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(s),a.call(this),i.definition.push(s),this.recordingProdStack.pop(),TE}function zFe(t,e){bE(e);let r=ma(this.recordingProdStack),n=Pt(t)===!1,i=n===!1?t:t.DEF,a=new wn({definition:[],idx:e,ignoreAmbiguities:n&&t.IGNORE_AMBIGUITIES===!0});Bt(t,"MAX_LOOKAHEAD")&&(a.maxLookahead=t.MAX_LOOKAHEAD);let s=B2(i,l=>Ai(l.GATE));return a.hasPredicates=s,r.definition.push(a),Ae(i,l=>{let u=new Dn({definition:[]});a.definition.push(u),Bt(l,"IGNORE_AMBIGUITIES")?u.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:Bt(l,"GATE")&&(u.ignoreAmbiguities=!0),this.recordingProdStack.push(u),l.ALT.call(this),this.recordingProdStack.pop()}),TE}function mle(t){return t===0?"":`${t}`}function bE(t){if(t<0||t>ple){let e=new Error(`Invalid DSL Method idx value: <${t}> - Idx value must be a none negative value smaller than ${ple+1}`);throw e.KNOWN_RECORDER_ERROR=!0,e}}var TE,dle,ple,gle,yle,$Fe,xE,vle=N(()=>{"use strict";qt();fs();px();xp();bp();Us();oE();TE={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(TE);dle=!0,ple=Math.pow(2,8)-1,gle=df({name:"RECORDING_PHASE_TOKEN",pattern:Kn.NA});Uu([gle]);yle=Wu(gle,`This IToken indicates the Parser is in Recording Phase - See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(yle);$Fe={name:`This CSTNode indicates the Parser is in Recording Phase - See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},xE=class{static{o(this,"GastRecorder")}initGastRecorder(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1}enableRecording(){this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",()=>{for(let e=0;e<10;e++){let r=e>0?e:"";this[`CONSUME${r}`]=function(n,i){return this.consumeInternalRecord(n,e,i)},this[`SUBRULE${r}`]=function(n,i){return this.subruleInternalRecord(n,e,i)},this[`OPTION${r}`]=function(n){return this.optionInternalRecord(n,e)},this[`OR${r}`]=function(n){return this.orInternalRecord(n,e)},this[`MANY${r}`]=function(n){this.manyInternalRecord(e,n)},this[`MANY_SEP${r}`]=function(n){this.manySepFirstInternalRecord(e,n)},this[`AT_LEAST_ONE${r}`]=function(n){this.atLeastOneInternalRecord(e,n)},this[`AT_LEAST_ONE_SEP${r}`]=function(n){this.atLeastOneSepFirstInternalRecord(e,n)}}this.consume=function(e,r,n){return this.consumeInternalRecord(r,e,n)},this.subrule=function(e,r,n){return this.subruleInternalRecord(r,e,n)},this.option=function(e,r){return this.optionInternalRecord(r,e)},this.or=function(e,r){return this.orInternalRecord(r,e)},this.many=function(e,r){this.manyInternalRecord(e,r)},this.atLeastOne=function(e,r){this.atLeastOneInternalRecord(e,r)},this.ACTION=this.ACTION_RECORD,this.BACKTRACK=this.BACKTRACK_RECORD,this.LA=this.LA_RECORD})}disableRecording(){this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",()=>{let e=this;for(let r=0;r<10;r++){let n=r>0?r:"";delete e[`CONSUME${n}`],delete e[`SUBRULE${n}`],delete e[`OPTION${n}`],delete e[`OR${n}`],delete e[`MANY${n}`],delete e[`MANY_SEP${n}`],delete e[`AT_LEAST_ONE${n}`],delete e[`AT_LEAST_ONE_SEP${n}`]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})}ACTION_RECORD(e){}BACKTRACK_RECORD(e,r){return()=>!0}LA_RECORD(e){return i1}topLevelRuleRecord(e,r){try{let n=new us({definition:[],name:e});return n.name=e,this.recordingProdStack.push(n),r.call(this),this.recordingProdStack.pop(),n}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` - This error was thrown during the "grammar recording phase" For more info see: - https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}}optionInternalRecord(e,r){return Ax.call(this,ln,e,r)}atLeastOneInternalRecord(e,r){Ax.call(this,Ln,r,e)}atLeastOneSepFirstInternalRecord(e,r){Ax.call(this,Rn,r,e,dle)}manyInternalRecord(e,r){Ax.call(this,Pr,r,e)}manySepFirstInternalRecord(e,r){Ax.call(this,Tn,r,e,dle)}orInternalRecord(e,r){return zFe.call(this,e,r)}subruleInternalRecord(e,r,n){if(bE(r),!e||Bt(e,"ruleName")===!1){let l=new Error(` argument is invalid expecting a Parser method reference but got: <${JSON.stringify(e)}> - inside top level rule: <${this.recordingProdStack[0].name}>`);throw l.KNOWN_RECORDER_ERROR=!0,l}let i=ma(this.recordingProdStack),a=e.ruleName,s=new on({idx:r,nonTerminalName:a,label:n?.LABEL,referencedRule:void 0});return i.definition.push(s),this.outputCst?$Fe:TE}consumeInternalRecord(e,r,n){if(bE(r),!hM(e)){let s=new Error(` argument is invalid expecting a TokenType reference but got: <${JSON.stringify(e)}> - inside top level rule: <${this.recordingProdStack[0].name}>`);throw s.KNOWN_RECORDER_ERROR=!0,s}let i=ma(this.recordingProdStack),a=new Er({idx:r,terminalType:e,label:n?.LABEL});return i.definition.push(a),yle}};o(Ax,"recordProd");o(zFe,"recordOrProd");o(mle,"getIdxSuffix");o(bE,"assertMethodIdxIsValid")});var wE,xle=N(()=>{"use strict";qt();Hg();Us();wE=class{static{o(this,"PerformanceTracer")}initPerformanceTracer(e){if(Bt(e,"traceInitPerf")){let r=e.traceInitPerf,n=typeof r=="number";this.traceInitMaxIdent=n?r:1/0,this.traceInitPerf=n?r>0:r}else this.traceInitMaxIdent=0,this.traceInitPerf=ds.traceInitPerf;this.traceInitIndent=-1}TRACE_INIT(e,r){if(this.traceInitPerf===!0){this.traceInitIndent++;let n=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <${e}>`);let{time:i,value:a}=hx(r),s=i>10?console.warn:console.log;return this.traceInitIndent time: ${i}ms`),this.traceInitIndent--,a}else return r()}}});function ble(t,e){e.forEach(r=>{let n=r.prototype;Object.getOwnPropertyNames(n).forEach(i=>{if(i==="constructor")return;let a=Object.getOwnPropertyDescriptor(n,i);a&&(a.get||a.set)?Object.defineProperty(t.prototype,i,a):t.prototype[i]=r.prototype[i]})})}var Tle=N(()=>{"use strict";o(ble,"applyMixins")});function kE(t=void 0){return function(){return t}}var i1,ds,a1,Vi,_x,Dx,Us=N(()=>{"use strict";qt();Hg();Qse();bp();Qg();Yoe();EM();Joe();ole();lle();cle();ule();hle();fle();vle();xle();Tle();wx();i1=Wu(fo,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(i1);ds=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:qu,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1}),a1=Object.freeze({recoveryValueFunc:o(()=>{},"recoveryValueFunc"),resyncEnabled:!0});(function(t){t[t.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",t[t.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",t[t.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",t[t.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",t[t.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",t[t.LEFT_RECURSION=5]="LEFT_RECURSION",t[t.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",t[t.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",t[t.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",t[t.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",t[t.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",t[t.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",t[t.TOO_MANY_ALTS=12]="TOO_MANY_ALTS",t[t.CUSTOM_LOOKAHEAD_VALIDATION=13]="CUSTOM_LOOKAHEAD_VALIDATION"})(Vi||(Vi={}));o(kE,"EMPTY_ALT");_x=class t{static{o(this,"Parser")}static performSelfAnalysis(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")}performSelfAnalysis(){this.TRACE_INIT("performSelfAnalysis",()=>{let e;this.selfAnalysisDone=!0;let r=this.className;this.TRACE_INIT("toFastProps",()=>{fx(this)}),this.TRACE_INIT("Grammar Recording",()=>{try{this.enableRecording(),Ae(this.definedRulesNames,i=>{let s=this[i].originalGrammarAction,l;this.TRACE_INIT(`${i} Rule`,()=>{l=this.topLevelRuleRecord(i,s)}),this.gastProductionsCache[i]=l})}finally{this.disableRecording()}});let n=[];if(this.TRACE_INIT("Grammar Resolving",()=>{n=Woe({rules:br(this.gastProductionsCache)}),this.definitionErrors=this.definitionErrors.concat(n)}),this.TRACE_INIT("Grammar Validations",()=>{if(hr(n)&&this.skipValidations===!1){let i=qoe({rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),errMsgProvider:$l,grammarName:r}),a=Foe({lookaheadStrategy:this.lookaheadStrategy,rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),grammarName:r});this.definitionErrors=this.definitionErrors.concat(i,a)}}),hr(this.definitionErrors)&&(this.recoveryEnabled&&this.TRACE_INIT("computeAllProdsFollows",()=>{let i=Kse(br(this.gastProductionsCache));this.resyncFollows=i}),this.TRACE_INIT("ComputeLookaheadFunctions",()=>{var i,a;(a=(i=this.lookaheadStrategy).initialize)===null||a===void 0||a.call(i,{rules:br(this.gastProductionsCache)}),this.preComputeLookaheadFunctions(br(this.gastProductionsCache))})),!t.DEFER_DEFINITION_ERRORS_HANDLING&&!hr(this.definitionErrors))throw e=Je(this.definitionErrors,i=>i.message),new Error(`Parser Definition Errors detected: - ${e.join(` -------------------------------- -`)}`)})}constructor(e,r){this.definitionErrors=[],this.selfAnalysisDone=!1;let n=this;if(n.initErrorHandler(r),n.initLexerAdapter(),n.initLooksAhead(r),n.initRecognizerEngine(e,r),n.initRecoverable(r),n.initTreeBuilder(r),n.initContentAssist(),n.initGastRecorder(r),n.initPerformanceTracer(r),Bt(r,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. - Please use the flag on the relevant DSL method instead. - See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES - For further details.`);this.skipValidations=Bt(r,"skipValidations")?r.skipValidations:ds.skipValidations}};_x.DEFER_DEFINITION_ERRORS_HANDLING=!1;ble(_x,[aE,cE,dE,pE,gE,mE,yE,vE,xE,wE]);Dx=class extends _x{static{o(this,"EmbeddedActionsParser")}constructor(e,r=ds){let n=an(r);n.outputCst=!1,super(e,n)}}});var wle=N(()=>{"use strict";fs()});var kle=N(()=>{"use strict"});var Ele=N(()=>{"use strict";wle();kle()});var Sle=N(()=>{"use strict";JN()});var mf=N(()=>{"use strict";JN();Us();px();bp();t1();SM();Qg();n1();fM();fs();fs();Ele();Sle()});function wp(t,e,r){return`${t.name}_${e}_${r}`}function Dle(t){let e={decisionMap:{},decisionStates:[],ruleToStartState:new Map,ruleToStopState:new Map,states:[]};YFe(e,t);let r=t.length;for(let n=0;nLle(t,e,s));return c1(t,e,n,r,...i)}function JFe(t,e,r){let n=aa(t,e,r,{type:gf});yf(t,n);let i=c1(t,e,n,r,kp(t,e,r));return e$e(t,e,r,i)}function kp(t,e,r){let n=Yr(Je(r.definition,i=>Lle(t,e,i)),i=>i!==void 0);return n.length===1?n[0]:n.length===0?void 0:r$e(t,n)}function Rle(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:qFe});yf(t,l);let u=aa(t,e,r,{type:_le});return a.loopback=l,u.loopback=l,t.decisionMap[wp(e,i?"RepetitionMandatoryWithSeparator":"RepetitionMandatory",r.idx)]=l,Di(s,l),i===void 0?(Di(l,a),Di(l,u)):(Di(l,u),Di(l,i.left),Di(i.right,a)),{left:a,right:u}}function Nle(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:WFe});yf(t,l);let u=aa(t,e,r,{type:_le}),h=aa(t,e,r,{type:HFe});return l.loopback=h,u.loopback=h,Di(l,a),Di(l,u),Di(s,h),i!==void 0?(Di(h,u),Di(h,i.left),Di(i.right,a)):Di(h,l),t.decisionMap[wp(e,i?"RepetitionWithSeparator":"Repetition",r.idx)]=l,{left:l,right:u}}function e$e(t,e,r,n){let i=n.left,a=n.right;return Di(i,a),t.decisionMap[wp(e,"Option",r.idx)]=i,n}function yf(t,e){return t.decisionStates.push(e),e.decision=t.decisionStates.length-1,e.decision}function c1(t,e,r,n,...i){let a=aa(t,e,n,{type:UFe,start:r});r.end=a;for(let l of i)l!==void 0?(Di(r,l.left),Di(l.right,a)):Di(r,a);let s={left:r,right:a};return t.decisionMap[wp(e,t$e(n),n.idx)]=r,s}function t$e(t){if(t instanceof wn)return"Alternation";if(t instanceof ln)return"Option";if(t instanceof Pr)return"Repetition";if(t instanceof Tn)return"RepetitionWithSeparator";if(t instanceof Ln)return"RepetitionMandatory";if(t instanceof Rn)return"RepetitionMandatoryWithSeparator";throw new Error("Invalid production type encountered")}function r$e(t,e){let r=e.length;for(let a=0;a{"use strict";Um();fR();mf();o(wp,"buildATNKey");gf=1,VFe=2,Cle=4,Ale=5,l1=7,UFe=8,HFe=9,WFe=10,qFe=11,_le=12,Lx=class{static{o(this,"AbstractTransition")}constructor(e){this.target=e}isEpsilon(){return!1}},s1=class extends Lx{static{o(this,"AtomTransition")}constructor(e,r){super(e),this.tokenType=r}},Rx=class extends Lx{static{o(this,"EpsilonTransition")}constructor(e){super(e)}isEpsilon(){return!0}},o1=class extends Lx{static{o(this,"RuleTransition")}constructor(e,r,n){super(e),this.rule=r,this.followState=n}isEpsilon(){return!0}};o(Dle,"createATN");o(YFe,"createRuleStartAndStopATNStates");o(Lle,"atom");o(XFe,"repetition");o(jFe,"repetitionSep");o(KFe,"repetitionMandatory");o(QFe,"repetitionMandatorySep");o(ZFe,"alternation");o(JFe,"option");o(kp,"block");o(Rle,"plus");o(Nle,"star");o(e$e,"optional");o(yf,"defineDecisionState");o(c1,"makeAlts");o(t$e,"getProdType");o(r$e,"makeBlock");o(IM,"tokenRef");o(n$e,"ruleRef");o(i$e,"buildRuleHandle");o(Di,"epsilon");o(aa,"newState");o(OM,"addTransition");o(a$e,"removeState")});function PM(t,e=!0){return`${e?`a${t.alt}`:""}s${t.state.stateNumber}:${t.stack.map(r=>r.stateNumber.toString()).join("_")}`}var Nx,u1,Ile=N(()=>{"use strict";Um();Nx={},u1=class{static{o(this,"ATNConfigSet")}constructor(){this.map={},this.configs=[]}get size(){return this.configs.length}finalize(){this.map={}}add(e){let r=PM(e);r in this.map||(this.map[r]=this.configs.length,this.configs.push(e))}get elements(){return this.configs}get alts(){return Je(this.configs,e=>e.alt)}get key(){let e="";for(let r in this.map)e+=r+":";return e}};o(PM,"getATNConfigKey")});function s$e(t,e){let r={};return n=>{let i=n.toString(),a=r[i];return a!==void 0||(a={atnStartState:t,decision:e,states:{}},r[i]=a),a}}function Ple(t,e=!0){let r=new Set;for(let n of t){let i=new Set;for(let a of n){if(a===void 0){if(e)break;return!1}let s=[a.tokenTypeIdx].concat(a.categoryMatches);for(let l of s)if(r.has(l)){if(!i.has(l))return!1}else r.add(l),i.add(l)}}return!0}function o$e(t){let e=t.decisionStates.length,r=Array(e);for(let n=0;nHu(i)).join(", "),r=t.production.idx===0?"":t.production.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(", ")}> in <${f$e(t.production)}${r}> inside <${t.topLevelRule.name}> Rule, -<${e}> may appears as a prefix path in all these alternatives. -`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES -For Further details.`,n}function f$e(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof wn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof Tn)return"MANY_SEP";if(t instanceof Pr)return"MANY";if(t instanceof Er)return"CONSUME";throw Error("non exhaustive match")}function d$e(t,e,r){let n=ga(e.configs.elements,a=>a.state.transitions),i=die(n.filter(a=>a instanceof s1).map(a=>a.tokenType),a=>a.tokenTypeIdx);return{actualToken:r,possibleTokenTypes:i,tokenPath:t}}function p$e(t,e){return t.edges[e.tokenTypeIdx]}function m$e(t,e,r){let n=new u1,i=[];for(let s of t.elements){if(r.is(s.alt)===!1)continue;if(s.state.type===l1){i.push(s);continue}let l=s.state.transitions.length;for(let u=0;u0&&!b$e(a))for(let s of i)a.add(s);return a}function g$e(t,e){if(t instanceof s1&&gx(e,t.tokenType))return t.target}function y$e(t,e){let r;for(let n of t.elements)if(e.is(n.alt)===!0){if(r===void 0)r=n.alt;else if(r!==n.alt)return}return r}function Fle(t){return{configs:t,edges:{},isAcceptState:!1,prediction:-1}}function Ble(t,e,r,n){return n=$le(t,n),e.edges[r.tokenTypeIdx]=n,n}function $le(t,e){if(e===Nx)return e;let r=e.configs.key,n=t.states[r];return n!==void 0?n:(e.configs.finalize(),t.states[r]=e,e)}function v$e(t){let e=new u1,r=t.transitions.length;for(let n=0;n0){let i=[...t.stack],s={state:i.pop(),alt:t.alt,stack:i};SE(s,e)}else e.add(t);return}r.epsilonOnlyTransitions||e.add(t);let n=r.transitions.length;for(let i=0;i1)return!0;return!1}function S$e(t){for(let e of Array.from(t.values()))if(Object.keys(e).length===1)return!0;return!1}var EE,Ole,Mx,zle=N(()=>{"use strict";mf();Mle();Ile();bR();pR();pie();Um();Sw();ek();ak();ER();o(s$e,"createDFACache");EE=class{static{o(this,"PredicateSet")}constructor(){this.predicates=[]}is(e){return e>=this.predicates.length||this.predicates[e]}set(e,r){this.predicates[e]=r}toString(){let e="",r=this.predicates.length;for(let n=0;nconsole.log(n)}initialize(e){this.atn=Dle(e.rules),this.dfas=o$e(this.atn)}validateAmbiguousAlternationAlternatives(){return[]}validateEmptyOrAlternatives(){return[]}buildLookaheadForAlternation(e){let{prodOccurrence:r,rule:n,hasPredicates:i,dynamicTokensEnabled:a}=e,s=this.dfas,l=this.logging,u=wp(n,"Alternation",r),f=this.atn.decisionMap[u].decision,d=Je(rE({maxLookahead:1,occurrence:r,prodType:"Alternation",rule:n}),p=>Je(p,m=>m[0]));if(Ple(d,!1)&&!a){let p=Xr(d,(m,g,y)=>(Ae(g,v=>{v&&(m[v.tokenTypeIdx]=y,Ae(v.categoryMatches,x=>{m[x]=y}))}),m),{});return i?function(m){var g;let y=this.LA(1),v=p[y.tokenTypeIdx];if(m!==void 0&&v!==void 0){let x=(g=m[v])===null||g===void 0?void 0:g.GATE;if(x!==void 0&&x.call(this)===!1)return}return v}:function(){let m=this.LA(1);return p[m.tokenTypeIdx]}}else return i?function(p){let m=new EE,g=p===void 0?0:p.length;for(let v=0;vJe(p,m=>m[0]));if(Ple(d)&&d[0][0]&&!a){let p=d[0],m=qr(p);if(m.length===1&&hr(m[0].categoryMatches)){let y=m[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===y}}else{let g=Xr(m,(y,v)=>(v!==void 0&&(y[v.tokenTypeIdx]=!0,Ae(v.categoryMatches,x=>{y[x]=!0})),y),{});return function(){let y=this.LA(1);return g[y.tokenTypeIdx]===!0}}}return function(){let p=BM.call(this,s,f,Ole,l);return typeof p=="object"?!1:p===0}}};o(Ple,"isLL1Sequence");o(o$e,"initATNSimulator");o(BM,"adaptivePredict");o(l$e,"performLookahead");o(c$e,"computeLookaheadTarget");o(u$e,"reportLookaheadAmbiguity");o(h$e,"buildAmbiguityError");o(f$e,"getProductionDslName");o(d$e,"buildAdaptivePredictError");o(p$e,"getExistingTargetState");o(m$e,"computeReachSet");o(g$e,"getReachableTarget");o(y$e,"getUniqueAlt");o(Fle,"newDFAState");o(Ble,"addDFAEdge");o($le,"addDFAState");o(v$e,"computeStartState");o(SE,"closure");o(x$e,"getEpsilonTarget");o(b$e,"hasConfigInRuleStopState");o(T$e,"allConfigsInRuleStopStates");o(w$e,"hasConflictTerminatingPrediction");o(k$e,"getConflictingAltSets");o(E$e,"hasConflictingAltSet");o(S$e,"hasStateAssociatedWithOneAlt")});var Gle=N(()=>{"use strict";zle()});var Vle,FM,Ule,CE,jr,Br,AE,Hle,$M,Wle,qle,Yle,Xle,zM,jle,Kle,Qle,_E,h1,f1,GM,d1,Zle,VM,UM,HM,WM,qM,Jle,ece,YM,tce,XM,Ix,rce,nce,ice,ace,sce,oce,lce,cce,DE,uce,hce,fce,dce,pce,mce,gce,yce,vce,xce,bce,LE,Tce,wce,kce,Ece,Sce,Cce,Ace,_ce,Dce,Lce,Rce,Nce,Mce,jM,KM,Ice,Oce,Pce,Bce,Fce,$ce,zce,Gce,Vce,QM,$e,ZM=N(()=>{"use strict";(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(Vle||(Vle={}));(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(FM||(FM={}));(function(t){t.MIN_VALUE=-2147483648,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(Ule||(Ule={}));(function(t){t.MIN_VALUE=0,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(CE||(CE={}));(function(t){function e(n,i){return n===Number.MAX_VALUE&&(n=CE.MAX_VALUE),i===Number.MAX_VALUE&&(i=CE.MAX_VALUE),{line:n,character:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.uinteger(i.line)&&$e.uinteger(i.character)}o(r,"is"),t.is=r})(jr||(jr={}));(function(t){function e(n,i,a,s){if($e.uinteger(n)&&$e.uinteger(i)&&$e.uinteger(a)&&$e.uinteger(s))return{start:jr.create(n,i),end:jr.create(a,s)};if(jr.is(n)&&jr.is(i))return{start:n,end:i};throw new Error(`Range#create called with invalid arguments[${n}, ${i}, ${a}, ${s}]`)}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&jr.is(i.start)&&jr.is(i.end)}o(r,"is"),t.is=r})(Br||(Br={}));(function(t){function e(n,i){return{uri:n,range:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&($e.string(i.uri)||$e.undefined(i.uri))}o(r,"is"),t.is=r})(AE||(AE={}));(function(t){function e(n,i,a,s){return{targetUri:n,targetRange:i,targetSelectionRange:a,originSelectionRange:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.targetRange)&&$e.string(i.targetUri)&&Br.is(i.targetSelectionRange)&&(Br.is(i.originSelectionRange)||$e.undefined(i.originSelectionRange))}o(r,"is"),t.is=r})(Hle||(Hle={}));(function(t){function e(n,i,a,s){return{red:n,green:i,blue:a,alpha:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.numberRange(i.red,0,1)&&$e.numberRange(i.green,0,1)&&$e.numberRange(i.blue,0,1)&&$e.numberRange(i.alpha,0,1)}o(r,"is"),t.is=r})($M||($M={}));(function(t){function e(n,i){return{range:n,color:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&$M.is(i.color)}o(r,"is"),t.is=r})(Wle||(Wle={}));(function(t){function e(n,i,a){return{label:n,textEdit:i,additionalTextEdits:a}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.string(i.label)&&($e.undefined(i.textEdit)||f1.is(i))&&($e.undefined(i.additionalTextEdits)||$e.typedArray(i.additionalTextEdits,f1.is))}o(r,"is"),t.is=r})(qle||(qle={}));(function(t){t.Comment="comment",t.Imports="imports",t.Region="region"})(Yle||(Yle={}));(function(t){function e(n,i,a,s,l,u){let h={startLine:n,endLine:i};return $e.defined(a)&&(h.startCharacter=a),$e.defined(s)&&(h.endCharacter=s),$e.defined(l)&&(h.kind=l),$e.defined(u)&&(h.collapsedText=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.uinteger(i.startLine)&&$e.uinteger(i.startLine)&&($e.undefined(i.startCharacter)||$e.uinteger(i.startCharacter))&&($e.undefined(i.endCharacter)||$e.uinteger(i.endCharacter))&&($e.undefined(i.kind)||$e.string(i.kind))}o(r,"is"),t.is=r})(Xle||(Xle={}));(function(t){function e(n,i){return{location:n,message:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&AE.is(i.location)&&$e.string(i.message)}o(r,"is"),t.is=r})(zM||(zM={}));(function(t){t.Error=1,t.Warning=2,t.Information=3,t.Hint=4})(jle||(jle={}));(function(t){t.Unnecessary=1,t.Deprecated=2})(Kle||(Kle={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&$e.string(n.href)}o(e,"is"),t.is=e})(Qle||(Qle={}));(function(t){function e(n,i,a,s,l,u){let h={range:n,message:i};return $e.defined(a)&&(h.severity=a),$e.defined(s)&&(h.code=s),$e.defined(l)&&(h.source=l),$e.defined(u)&&(h.relatedInformation=u),h}o(e,"create"),t.create=e;function r(n){var i;let a=n;return $e.defined(a)&&Br.is(a.range)&&$e.string(a.message)&&($e.number(a.severity)||$e.undefined(a.severity))&&($e.integer(a.code)||$e.string(a.code)||$e.undefined(a.code))&&($e.undefined(a.codeDescription)||$e.string((i=a.codeDescription)===null||i===void 0?void 0:i.href))&&($e.string(a.source)||$e.undefined(a.source))&&($e.undefined(a.relatedInformation)||$e.typedArray(a.relatedInformation,zM.is))}o(r,"is"),t.is=r})(_E||(_E={}));(function(t){function e(n,i,...a){let s={title:n,command:i};return $e.defined(a)&&a.length>0&&(s.arguments=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.title)&&$e.string(i.command)}o(r,"is"),t.is=r})(h1||(h1={}));(function(t){function e(a,s){return{range:a,newText:s}}o(e,"replace"),t.replace=e;function r(a,s){return{range:{start:a,end:a},newText:s}}o(r,"insert"),t.insert=r;function n(a){return{range:a,newText:""}}o(n,"del"),t.del=n;function i(a){let s=a;return $e.objectLiteral(s)&&$e.string(s.newText)&&Br.is(s.range)}o(i,"is"),t.is=i})(f1||(f1={}));(function(t){function e(n,i,a){let s={label:n};return i!==void 0&&(s.needsConfirmation=i),a!==void 0&&(s.description=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&$e.string(i.label)&&($e.boolean(i.needsConfirmation)||i.needsConfirmation===void 0)&&($e.string(i.description)||i.description===void 0)}o(r,"is"),t.is=r})(GM||(GM={}));(function(t){function e(r){let n=r;return $e.string(n)}o(e,"is"),t.is=e})(d1||(d1={}));(function(t){function e(a,s,l){return{range:a,newText:s,annotationId:l}}o(e,"replace"),t.replace=e;function r(a,s,l){return{range:{start:a,end:a},newText:s,annotationId:l}}o(r,"insert"),t.insert=r;function n(a,s){return{range:a,newText:"",annotationId:s}}o(n,"del"),t.del=n;function i(a){let s=a;return f1.is(s)&&(GM.is(s.annotationId)||d1.is(s.annotationId))}o(i,"is"),t.is=i})(Zle||(Zle={}));(function(t){function e(n,i){return{textDocument:n,edits:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&YM.is(i.textDocument)&&Array.isArray(i.edits)}o(r,"is"),t.is=r})(VM||(VM={}));(function(t){function e(n,i,a){let s={kind:"create",uri:n};return i!==void 0&&(i.overwrite!==void 0||i.ignoreIfExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="create"&&$e.string(i.uri)&&(i.options===void 0||(i.options.overwrite===void 0||$e.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||$e.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(UM||(UM={}));(function(t){function e(n,i,a,s){let l={kind:"rename",oldUri:n,newUri:i};return a!==void 0&&(a.overwrite!==void 0||a.ignoreIfExists!==void 0)&&(l.options=a),s!==void 0&&(l.annotationId=s),l}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="rename"&&$e.string(i.oldUri)&&$e.string(i.newUri)&&(i.options===void 0||(i.options.overwrite===void 0||$e.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||$e.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(HM||(HM={}));(function(t){function e(n,i,a){let s={kind:"delete",uri:n};return i!==void 0&&(i.recursive!==void 0||i.ignoreIfNotExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="delete"&&$e.string(i.uri)&&(i.options===void 0||(i.options.recursive===void 0||$e.boolean(i.options.recursive))&&(i.options.ignoreIfNotExists===void 0||$e.boolean(i.options.ignoreIfNotExists)))&&(i.annotationId===void 0||d1.is(i.annotationId))}o(r,"is"),t.is=r})(WM||(WM={}));(function(t){function e(r){let n=r;return n&&(n.changes!==void 0||n.documentChanges!==void 0)&&(n.documentChanges===void 0||n.documentChanges.every(i=>$e.string(i.kind)?UM.is(i)||HM.is(i)||WM.is(i):VM.is(i)))}o(e,"is"),t.is=e})(qM||(qM={}));(function(t){function e(n){return{uri:n}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)}o(r,"is"),t.is=r})(Jle||(Jle={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&$e.integer(i.version)}o(r,"is"),t.is=r})(ece||(ece={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&(i.version===null||$e.integer(i.version))}o(r,"is"),t.is=r})(YM||(YM={}));(function(t){function e(n,i,a,s){return{uri:n,languageId:i,version:a,text:s}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.string(i.uri)&&$e.string(i.languageId)&&$e.integer(i.version)&&$e.string(i.text)}o(r,"is"),t.is=r})(tce||(tce={}));(function(t){t.PlainText="plaintext",t.Markdown="markdown";function e(r){let n=r;return n===t.PlainText||n===t.Markdown}o(e,"is"),t.is=e})(XM||(XM={}));(function(t){function e(r){let n=r;return $e.objectLiteral(r)&&XM.is(n.kind)&&$e.string(n.value)}o(e,"is"),t.is=e})(Ix||(Ix={}));(function(t){t.Text=1,t.Method=2,t.Function=3,t.Constructor=4,t.Field=5,t.Variable=6,t.Class=7,t.Interface=8,t.Module=9,t.Property=10,t.Unit=11,t.Value=12,t.Enum=13,t.Keyword=14,t.Snippet=15,t.Color=16,t.File=17,t.Reference=18,t.Folder=19,t.EnumMember=20,t.Constant=21,t.Struct=22,t.Event=23,t.Operator=24,t.TypeParameter=25})(rce||(rce={}));(function(t){t.PlainText=1,t.Snippet=2})(nce||(nce={}));(function(t){t.Deprecated=1})(ice||(ice={}));(function(t){function e(n,i,a){return{newText:n,insert:i,replace:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.newText)&&Br.is(i.insert)&&Br.is(i.replace)}o(r,"is"),t.is=r})(ace||(ace={}));(function(t){t.asIs=1,t.adjustIndentation=2})(sce||(sce={}));(function(t){function e(r){let n=r;return n&&($e.string(n.detail)||n.detail===void 0)&&($e.string(n.description)||n.description===void 0)}o(e,"is"),t.is=e})(oce||(oce={}));(function(t){function e(r){return{label:r}}o(e,"create"),t.create=e})(lce||(lce={}));(function(t){function e(r,n){return{items:r||[],isIncomplete:!!n}}o(e,"create"),t.create=e})(cce||(cce={}));(function(t){function e(n){return n.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}o(e,"fromPlainText"),t.fromPlainText=e;function r(n){let i=n;return $e.string(i)||$e.objectLiteral(i)&&$e.string(i.language)&&$e.string(i.value)}o(r,"is"),t.is=r})(DE||(DE={}));(function(t){function e(r){let n=r;return!!n&&$e.objectLiteral(n)&&(Ix.is(n.contents)||DE.is(n.contents)||$e.typedArray(n.contents,DE.is))&&(r.range===void 0||Br.is(r.range))}o(e,"is"),t.is=e})(uce||(uce={}));(function(t){function e(r,n){return n?{label:r,documentation:n}:{label:r}}o(e,"create"),t.create=e})(hce||(hce={}));(function(t){function e(r,n,...i){let a={label:r};return $e.defined(n)&&(a.documentation=n),$e.defined(i)?a.parameters=i:a.parameters=[],a}o(e,"create"),t.create=e})(fce||(fce={}));(function(t){t.Text=1,t.Read=2,t.Write=3})(dce||(dce={}));(function(t){function e(r,n){let i={range:r};return $e.number(n)&&(i.kind=n),i}o(e,"create"),t.create=e})(pce||(pce={}));(function(t){t.File=1,t.Module=2,t.Namespace=3,t.Package=4,t.Class=5,t.Method=6,t.Property=7,t.Field=8,t.Constructor=9,t.Enum=10,t.Interface=11,t.Function=12,t.Variable=13,t.Constant=14,t.String=15,t.Number=16,t.Boolean=17,t.Array=18,t.Object=19,t.Key=20,t.Null=21,t.EnumMember=22,t.Struct=23,t.Event=24,t.Operator=25,t.TypeParameter=26})(mce||(mce={}));(function(t){t.Deprecated=1})(gce||(gce={}));(function(t){function e(r,n,i,a,s){let l={name:r,kind:n,location:{uri:a,range:i}};return s&&(l.containerName=s),l}o(e,"create"),t.create=e})(yce||(yce={}));(function(t){function e(r,n,i,a){return a!==void 0?{name:r,kind:n,location:{uri:i,range:a}}:{name:r,kind:n,location:{uri:i}}}o(e,"create"),t.create=e})(vce||(vce={}));(function(t){function e(n,i,a,s,l,u){let h={name:n,detail:i,kind:a,range:s,selectionRange:l};return u!==void 0&&(h.children=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.name)&&$e.number(i.kind)&&Br.is(i.range)&&Br.is(i.selectionRange)&&(i.detail===void 0||$e.string(i.detail))&&(i.deprecated===void 0||$e.boolean(i.deprecated))&&(i.children===void 0||Array.isArray(i.children))&&(i.tags===void 0||Array.isArray(i.tags))}o(r,"is"),t.is=r})(xce||(xce={}));(function(t){t.Empty="",t.QuickFix="quickfix",t.Refactor="refactor",t.RefactorExtract="refactor.extract",t.RefactorInline="refactor.inline",t.RefactorRewrite="refactor.rewrite",t.Source="source",t.SourceOrganizeImports="source.organizeImports",t.SourceFixAll="source.fixAll"})(bce||(bce={}));(function(t){t.Invoked=1,t.Automatic=2})(LE||(LE={}));(function(t){function e(n,i,a){let s={diagnostics:n};return i!=null&&(s.only=i),a!=null&&(s.triggerKind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.typedArray(i.diagnostics,_E.is)&&(i.only===void 0||$e.typedArray(i.only,$e.string))&&(i.triggerKind===void 0||i.triggerKind===LE.Invoked||i.triggerKind===LE.Automatic)}o(r,"is"),t.is=r})(Tce||(Tce={}));(function(t){function e(n,i,a){let s={title:n},l=!0;return typeof i=="string"?(l=!1,s.kind=i):h1.is(i)?s.command=i:s.edit=i,l&&a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&$e.string(i.title)&&(i.diagnostics===void 0||$e.typedArray(i.diagnostics,_E.is))&&(i.kind===void 0||$e.string(i.kind))&&(i.edit!==void 0||i.command!==void 0)&&(i.command===void 0||h1.is(i.command))&&(i.isPreferred===void 0||$e.boolean(i.isPreferred))&&(i.edit===void 0||qM.is(i.edit))}o(r,"is"),t.is=r})(wce||(wce={}));(function(t){function e(n,i){let a={range:n};return $e.defined(i)&&(a.data=i),a}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(i.range)&&($e.undefined(i.command)||h1.is(i.command))}o(r,"is"),t.is=r})(kce||(kce={}));(function(t){function e(n,i){return{tabSize:n,insertSpaces:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&$e.uinteger(i.tabSize)&&$e.boolean(i.insertSpaces)}o(r,"is"),t.is=r})(Ece||(Ece={}));(function(t){function e(n,i,a){return{range:n,target:i,data:a}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(i.range)&&($e.undefined(i.target)||$e.string(i.target))}o(r,"is"),t.is=r})(Sce||(Sce={}));(function(t){function e(n,i){return{range:n,parent:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&Br.is(i.range)&&(i.parent===void 0||t.is(i.parent))}o(r,"is"),t.is=r})(Cce||(Cce={}));(function(t){t.namespace="namespace",t.type="type",t.class="class",t.enum="enum",t.interface="interface",t.struct="struct",t.typeParameter="typeParameter",t.parameter="parameter",t.variable="variable",t.property="property",t.enumMember="enumMember",t.event="event",t.function="function",t.method="method",t.macro="macro",t.keyword="keyword",t.modifier="modifier",t.comment="comment",t.string="string",t.number="number",t.regexp="regexp",t.operator="operator",t.decorator="decorator"})(Ace||(Ace={}));(function(t){t.declaration="declaration",t.definition="definition",t.readonly="readonly",t.static="static",t.deprecated="deprecated",t.abstract="abstract",t.async="async",t.modification="modification",t.documentation="documentation",t.defaultLibrary="defaultLibrary"})(_ce||(_ce={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&(n.resultId===void 0||typeof n.resultId=="string")&&Array.isArray(n.data)&&(n.data.length===0||typeof n.data[0]=="number")}o(e,"is"),t.is=e})(Dce||(Dce={}));(function(t){function e(n,i){return{range:n,text:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&$e.string(i.text)}o(r,"is"),t.is=r})(Lce||(Lce={}));(function(t){function e(n,i,a){return{range:n,variableName:i,caseSensitiveLookup:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&$e.boolean(i.caseSensitiveLookup)&&($e.string(i.variableName)||i.variableName===void 0)}o(r,"is"),t.is=r})(Rce||(Rce={}));(function(t){function e(n,i){return{range:n,expression:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Br.is(i.range)&&($e.string(i.expression)||i.expression===void 0)}o(r,"is"),t.is=r})(Nce||(Nce={}));(function(t){function e(n,i){return{frameId:n,stoppedLocation:i}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.defined(i)&&Br.is(n.stoppedLocation)}o(r,"is"),t.is=r})(Mce||(Mce={}));(function(t){t.Type=1,t.Parameter=2;function e(r){return r===1||r===2}o(e,"is"),t.is=e})(jM||(jM={}));(function(t){function e(n){return{value:n}}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&(i.tooltip===void 0||$e.string(i.tooltip)||Ix.is(i.tooltip))&&(i.location===void 0||AE.is(i.location))&&(i.command===void 0||h1.is(i.command))}o(r,"is"),t.is=r})(KM||(KM={}));(function(t){function e(n,i,a){let s={position:n,label:i};return a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return $e.objectLiteral(i)&&jr.is(i.position)&&($e.string(i.label)||$e.typedArray(i.label,KM.is))&&(i.kind===void 0||jM.is(i.kind))&&i.textEdits===void 0||$e.typedArray(i.textEdits,f1.is)&&(i.tooltip===void 0||$e.string(i.tooltip)||Ix.is(i.tooltip))&&(i.paddingLeft===void 0||$e.boolean(i.paddingLeft))&&(i.paddingRight===void 0||$e.boolean(i.paddingRight))}o(r,"is"),t.is=r})(Ice||(Ice={}));(function(t){function e(r){return{kind:"snippet",value:r}}o(e,"createSnippet"),t.createSnippet=e})(Oce||(Oce={}));(function(t){function e(r,n,i,a){return{insertText:r,filterText:n,range:i,command:a}}o(e,"create"),t.create=e})(Pce||(Pce={}));(function(t){function e(r){return{items:r}}o(e,"create"),t.create=e})(Bce||(Bce={}));(function(t){t.Invoked=0,t.Automatic=1})(Fce||(Fce={}));(function(t){function e(r,n){return{range:r,text:n}}o(e,"create"),t.create=e})($ce||($ce={}));(function(t){function e(r,n){return{triggerKind:r,selectedCompletionInfo:n}}o(e,"create"),t.create=e})(zce||(zce={}));(function(t){function e(r){let n=r;return $e.objectLiteral(n)&&FM.is(n.uri)&&$e.string(n.name)}o(e,"is"),t.is=e})(Gce||(Gce={}));(function(t){function e(a,s,l,u){return new QM(a,s,l,u)}o(e,"create"),t.create=e;function r(a){let s=a;return!!($e.defined(s)&&$e.string(s.uri)&&($e.undefined(s.languageId)||$e.string(s.languageId))&&$e.uinteger(s.lineCount)&&$e.func(s.getText)&&$e.func(s.positionAt)&&$e.func(s.offsetAt))}o(r,"is"),t.is=r;function n(a,s){let l=a.getText(),u=i(s,(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),h=l.length;for(let f=u.length-1;f>=0;f--){let d=u[f],p=a.offsetAt(d.range.start),m=a.offsetAt(d.range.end);if(m<=h)l=l.substring(0,p)+d.newText+l.substring(m,l.length);else throw new Error("Overlapping edit");h=p}return l}o(n,"applyEdits"),t.applyEdits=n;function i(a,s){if(a.length<=1)return a;let l=a.length/2|0,u=a.slice(0,l),h=a.slice(l);i(u,s),i(h,s);let f=0,d=0,p=0;for(;f0&&e.push(r.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let r=this.getLineOffsets(),n=0,i=r.length;if(i===0)return jr.create(0,e);for(;ne?i=s:n=s+1}let a=n-1;return jr.create(a,e-r[a])}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line],i=e.line+1"u"}o(n,"undefined"),t.undefined=n;function i(m){return m===!0||m===!1}o(i,"boolean"),t.boolean=i;function a(m){return e.call(m)==="[object String]"}o(a,"string"),t.string=a;function s(m){return e.call(m)==="[object Number]"}o(s,"number"),t.number=s;function l(m,g,y){return e.call(m)==="[object Number]"&&g<=m&&m<=y}o(l,"numberRange"),t.numberRange=l;function u(m){return e.call(m)==="[object Number]"&&-2147483648<=m&&m<=2147483647}o(u,"integer"),t.integer=u;function h(m){return e.call(m)==="[object Number]"&&0<=m&&m<=2147483647}o(h,"uinteger"),t.uinteger=h;function f(m){return e.call(m)==="[object Function]"}o(f,"func"),t.func=f;function d(m){return m!==null&&typeof m=="object"}o(d,"objectLiteral"),t.objectLiteral=d;function p(m,g){return Array.isArray(m)&&m.every(g)}o(p,"typedArray"),t.typedArray=p})($e||($e={}))});var Ox,Px,Ep,Sp,JM,p1,RE=N(()=>{"use strict";ZM();Ol();Ox=class{static{o(this,"CstNodeBuilder")}constructor(){this.nodeStack=[]}get current(){var e;return(e=this.nodeStack[this.nodeStack.length-1])!==null&&e!==void 0?e:this.rootNode}buildRootNode(e){return this.rootNode=new p1(e),this.rootNode.root=this.rootNode,this.nodeStack=[this.rootNode],this.rootNode}buildCompositeNode(e){let r=new Sp;return r.grammarSource=e,r.root=this.rootNode,this.current.content.push(r),this.nodeStack.push(r),r}buildLeafNode(e,r){let n=new Ep(e.startOffset,e.image.length,Km(e),e.tokenType,!r);return n.grammarSource=r,n.root=this.rootNode,this.current.content.push(n),n}removeNode(e){let r=e.container;if(r){let n=r.content.indexOf(e);n>=0&&r.content.splice(n,1)}}addHiddenNodes(e){let r=[];for(let a of e){let s=new Ep(a.startOffset,a.image.length,Km(a),a.tokenType,!0);s.root=this.rootNode,r.push(s)}let n=this.current,i=!1;if(n.content.length>0){n.content.push(...r);return}for(;n.container;){let a=n.container.content.indexOf(n);if(a>0){n.container.content.splice(a,0,...r),i=!0;break}n=n.container}i||this.rootNode.content.unshift(...r)}construct(e){let r=this.current;typeof e.$type=="string"&&(this.current.astNode=e),e.$cstNode=r;let n=this.nodeStack.pop();n?.content.length===0&&this.removeNode(n)}},Px=class{static{o(this,"AbstractCstNode")}get parent(){return this.container}get feature(){return this.grammarSource}get hidden(){return!1}get astNode(){var e,r;let n=typeof((e=this._astNode)===null||e===void 0?void 0:e.$type)=="string"?this._astNode:(r=this.container)===null||r===void 0?void 0:r.astNode;if(!n)throw new Error("This node has no associated AST element");return n}set astNode(e){this._astNode=e}get element(){return this.astNode}get text(){return this.root.fullText.substring(this.offset,this.end)}},Ep=class extends Px{static{o(this,"LeafCstNodeImpl")}get offset(){return this._offset}get length(){return this._length}get end(){return this._offset+this._length}get hidden(){return this._hidden}get tokenType(){return this._tokenType}get range(){return this._range}constructor(e,r,n,i,a=!1){super(),this._hidden=a,this._offset=e,this._tokenType=i,this._length=r,this._range=n}},Sp=class extends Px{static{o(this,"CompositeCstNodeImpl")}constructor(){super(...arguments),this.content=new JM(this)}get children(){return this.content}get offset(){var e,r;return(r=(e=this.firstNonHiddenNode)===null||e===void 0?void 0:e.offset)!==null&&r!==void 0?r:0}get length(){return this.end-this.offset}get end(){var e,r;return(r=(e=this.lastNonHiddenNode)===null||e===void 0?void 0:e.end)!==null&&r!==void 0?r:0}get range(){let e=this.firstNonHiddenNode,r=this.lastNonHiddenNode;if(e&&r){if(this._rangeCache===void 0){let{range:n}=e,{range:i}=r;this._rangeCache={start:n.start,end:i.end.line=0;e--){let r=this.content[e];if(!r.hidden)return r}return this.content[this.content.length-1]}},JM=class t extends Array{static{o(this,"CstNodeContainer")}constructor(e){super(),this.parent=e,Object.setPrototypeOf(this,t.prototype)}push(...e){return this.addParents(e),super.push(...e)}unshift(...e){return this.addParents(e),super.unshift(...e)}splice(e,r,...n){return this.addParents(n),super.splice(e,r,...n)}addParents(e){for(let r of e)r.container=this.parent}},p1=class extends Sp{static{o(this,"RootCstNodeImpl")}get text(){return this._text.substring(this.offset,this.end)}get fullText(){return this._text}constructor(e){super(),this._text="",this._text=e??""}}});function eI(t){return t.$type===NE}var NE,Uce,Hce,Bx,Fx,ME,m1,$x,C$e,tI,zx=N(()=>{"use strict";mf();Gle();Pc();Fl();cs();RE();NE=Symbol("Datatype");o(eI,"isDataTypeNode");Uce="\u200B",Hce=o(t=>t.endsWith(Uce)?t:t+Uce,"withRuleSuffix"),Bx=class{static{o(this,"AbstractLangiumParser")}constructor(e){this._unorderedGroups=new Map,this.allRules=new Map,this.lexer=e.parser.Lexer;let r=this.lexer.definition,n=e.LanguageMetaData.mode==="production";this.wrapper=new tI(r,Object.assign(Object.assign({},e.parser.ParserConfig),{skipValidations:n,errorMessageProvider:e.parser.ParserErrorMessageProvider}))}alternatives(e,r){this.wrapper.wrapOr(e,r)}optional(e,r){this.wrapper.wrapOption(e,r)}many(e,r){this.wrapper.wrapMany(e,r)}atLeastOne(e,r){this.wrapper.wrapAtLeastOne(e,r)}getRule(e){return this.allRules.get(e)}isRecording(){return this.wrapper.IS_RECORDING}get unorderedGroups(){return this._unorderedGroups}getRuleStack(){return this.wrapper.RULE_STACK}finalize(){this.wrapper.wrapSelfAnalysis()}},Fx=class extends Bx{static{o(this,"LangiumParser")}get current(){return this.stack[this.stack.length-1]}constructor(e){super(e),this.nodeBuilder=new Ox,this.stack=[],this.assignmentMap=new Map,this.linker=e.references.Linker,this.converter=e.parser.ValueConverter,this.astReflection=e.shared.AstReflection}rule(e,r){let n=this.computeRuleType(e),i=this.wrapper.DEFINE_RULE(Hce(e.name),this.startImplementation(n,r).bind(this));return this.allRules.set(e.name,i),e.entry&&(this.mainRule=i),i}computeRuleType(e){if(!e.fragment){if(lx(e))return NE;{let r=zg(e);return r??e.name}}}parse(e,r={}){this.nodeBuilder.buildRootNode(e);let n=this.lexerResult=this.lexer.tokenize(e);this.wrapper.input=n.tokens;let i=r.rule?this.allRules.get(r.rule):this.mainRule;if(!i)throw new Error(r.rule?`No rule found with name '${r.rule}'`:"No main rule available.");let a=i.call(this.wrapper,{});return this.nodeBuilder.addHiddenNodes(n.hidden),this.unorderedGroups.clear(),this.lexerResult=void 0,{value:a,lexerErrors:n.errors,lexerReport:n.report,parserErrors:this.wrapper.errors}}startImplementation(e,r){return n=>{let i=!this.isRecording()&&e!==void 0;if(i){let s={$type:e};this.stack.push(s),e===NE&&(s.value="")}let a;try{a=r(n)}catch{a=void 0}return a===void 0&&i&&(a=this.construct()),a}}extractHiddenTokens(e){let r=this.lexerResult.hidden;if(!r.length)return[];let n=e.startOffset;for(let i=0;in)return r.splice(0,i);return r.splice(0,r.length)}consume(e,r,n){let i=this.wrapper.wrapConsume(e,r);if(!this.isRecording()&&this.isValidToken(i)){let a=this.extractHiddenTokens(i);this.nodeBuilder.addHiddenNodes(a);let s=this.nodeBuilder.buildLeafNode(i,n),{assignment:l,isCrossRef:u}=this.getAssignment(n),h=this.current;if(l){let f=Xo(n)?i.image:this.converter.convert(i.image,s);this.assign(l.operator,l.feature,f,s,u)}else if(eI(h)){let f=i.image;Xo(n)||(f=this.converter.convert(f,s).toString()),h.value+=f}}}isValidToken(e){return!e.isInsertedInRecovery&&!isNaN(e.startOffset)&&typeof e.endOffset=="number"&&!isNaN(e.endOffset)}subrule(e,r,n,i,a){let s;!this.isRecording()&&!n&&(s=this.nodeBuilder.buildCompositeNode(i));let l=this.wrapper.wrapSubrule(e,r,a);!this.isRecording()&&s&&s.length>0&&this.performSubruleAssignment(l,i,s)}performSubruleAssignment(e,r,n){let{assignment:i,isCrossRef:a}=this.getAssignment(r);if(i)this.assign(i.operator,i.feature,e,n,a);else if(!i){let s=this.current;if(eI(s))s.value+=e.toString();else if(typeof e=="object"&&e){let u=this.assignWithoutOverride(e,s);this.stack.pop(),this.stack.push(u)}}}action(e,r){if(!this.isRecording()){let n=this.current;if(r.feature&&r.operator){n=this.construct(),this.nodeBuilder.removeNode(n.$cstNode),this.nodeBuilder.buildCompositeNode(r).content.push(n.$cstNode);let a={$type:e};this.stack.push(a),this.assign(r.operator,r.feature,n,n.$cstNode,!1)}else n.$type=e}}construct(){if(this.isRecording())return;let e=this.current;return Mk(e),this.nodeBuilder.construct(e),this.stack.pop(),eI(e)?this.converter.convert(e.value,e.$cstNode):(RN(this.astReflection,e),e)}getAssignment(e){if(!this.assignmentMap.has(e)){let r=hp(e,Pl);this.assignmentMap.set(e,{assignment:r,isCrossRef:r?up(r.terminal):!1})}return this.assignmentMap.get(e)}assign(e,r,n,i,a){let s=this.current,l;switch(a&&typeof n=="string"?l=this.linker.buildReference(s,r,i,n):l=n,e){case"=":{s[r]=l;break}case"?=":{s[r]=!0;break}case"+=":Array.isArray(s[r])||(s[r]=[]),s[r].push(l)}}assignWithoutOverride(e,r){for(let[i,a]of Object.entries(r)){let s=e[i];s===void 0?e[i]=a:Array.isArray(s)&&Array.isArray(a)&&(a.push(...s),e[i]=a)}let n=e.$cstNode;return n&&(n.astNode=void 0,e.$cstNode=void 0),e}get definitionErrors(){return this.wrapper.definitionErrors}},ME=class{static{o(this,"AbstractParserErrorMessageProvider")}buildMismatchTokenMessage(e){return qu.buildMismatchTokenMessage(e)}buildNotAllInputParsedMessage(e){return qu.buildNotAllInputParsedMessage(e)}buildNoViableAltMessage(e){return qu.buildNoViableAltMessage(e)}buildEarlyExitMessage(e){return qu.buildEarlyExitMessage(e)}},m1=class extends ME{static{o(this,"LangiumParserErrorMessageProvider")}buildMismatchTokenMessage({expected:e,actual:r}){return`Expecting ${e.LABEL?"`"+e.LABEL+"`":e.name.endsWith(":KW")?`keyword '${e.name.substring(0,e.name.length-3)}'`:`token of type '${e.name}'`} but found \`${r.image}\`.`}buildNotAllInputParsedMessage({firstRedundant:e}){return`Expecting end of file but found \`${e.image}\`.`}},$x=class extends Bx{static{o(this,"LangiumCompletionParser")}constructor(){super(...arguments),this.tokens=[],this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}action(){}construct(){}parse(e){this.resetState();let r=this.lexer.tokenize(e,{mode:"partial"});return this.tokens=r.tokens,this.wrapper.input=[...this.tokens],this.mainRule.call(this.wrapper,{}),this.unorderedGroups.clear(),{tokens:this.tokens,elementStack:[...this.lastElementStack],tokenIndex:this.nextTokenIndex}}rule(e,r){let n=this.wrapper.DEFINE_RULE(Hce(e.name),this.startImplementation(r).bind(this));return this.allRules.set(e.name,n),e.entry&&(this.mainRule=n),n}resetState(){this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}startImplementation(e){return r=>{let n=this.keepStackSize();try{e(r)}finally{this.resetStackSize(n)}}}removeUnexpectedElements(){this.elementStack.splice(this.stackSize)}keepStackSize(){let e=this.elementStack.length;return this.stackSize=e,e}resetStackSize(e){this.removeUnexpectedElements(),this.stackSize=e}consume(e,r,n){this.wrapper.wrapConsume(e,r),this.isRecording()||(this.lastElementStack=[...this.elementStack,n],this.nextTokenIndex=this.currIdx+1)}subrule(e,r,n,i,a){this.before(i),this.wrapper.wrapSubrule(e,r,a),this.after(i)}before(e){this.isRecording()||this.elementStack.push(e)}after(e){if(!this.isRecording()){let r=this.elementStack.lastIndexOf(e);r>=0&&this.elementStack.splice(r)}}get currIdx(){return this.wrapper.currIdx}},C$e={recoveryEnabled:!0,nodeLocationTracking:"full",skipValidations:!0,errorMessageProvider:new m1},tI=class extends Dx{static{o(this,"ChevrotainWrapper")}constructor(e,r){let n=r&&"maxLookahead"in r;super(e,Object.assign(Object.assign(Object.assign({},C$e),{lookaheadStrategy:n?new Yu({maxLookahead:r.maxLookahead}):new Mx({logging:r.skipValidations?()=>{}:void 0})}),r))}get IS_RECORDING(){return this.RECORDING_PHASE}DEFINE_RULE(e,r){return this.RULE(e,r)}wrapSelfAnalysis(){this.performSelfAnalysis()}wrapConsume(e,r){return this.consume(e,r)}wrapSubrule(e,r,n){return this.subrule(e,r,{ARGS:[n]})}wrapOr(e,r){this.or(e,r)}wrapOption(e,r){this.option(e,r)}wrapMany(e,r){this.many(e,r)}wrapAtLeastOne(e,r){this.atLeastOne(e,r)}}});function Gx(t,e,r){return A$e({parser:e,tokens:r,ruleNames:new Map},t),e}function A$e(t,e){let r=sx(e,!1),n=en(e.rules).filter(Fa).filter(i=>r.has(i));for(let i of n){let a=Object.assign(Object.assign({},t),{consume:1,optional:1,subrule:1,many:1,or:1});t.parser.rule(i,Cp(a,i.definition))}}function Cp(t,e,r=!1){let n;if(Xo(e))n=I$e(t,e);else if($u(e))n=_$e(t,e);else if(Pl(e))n=Cp(t,e.terminal);else if(up(e))n=Wce(t,e);else if(Bl(e))n=D$e(t,e);else if(Lk(e))n=R$e(t,e);else if(Nk(e))n=N$e(t,e);else if(ff(e))n=M$e(t,e);else if(wN(e)){let i=t.consume++;n=o(()=>t.parser.consume(i,fo,e),"method")}else throw new lp(e.$cstNode,`Unexpected element type: ${e.$type}`);return qce(t,r?void 0:IE(e),n,e.cardinality)}function _$e(t,e){let r=cx(e);return()=>t.parser.action(r,e)}function D$e(t,e){let r=e.rule.ref;if(Fa(r)){let n=t.subrule++,i=r.fragment,a=e.arguments.length>0?L$e(r,e.arguments):()=>({});return s=>t.parser.subrule(n,Yce(t,r),i,e,a(s))}else if(uo(r)){let n=t.consume++,i=rI(t,r.name);return()=>t.parser.consume(n,i,e)}else if(r)Oc(r);else throw new lp(e.$cstNode,`Undefined rule: ${e.rule.$refText}`)}function L$e(t,e){let r=e.map(n=>Xu(n.value));return n=>{let i={};for(let a=0;ae(n)||r(n)}else if(pN(t)){let e=Xu(t.left),r=Xu(t.right);return n=>e(n)&&r(n)}else if(gN(t)){let e=Xu(t.value);return r=>!e(r)}else if(yN(t)){let e=t.parameter.ref.name;return r=>r!==void 0&&r[e]===!0}else if(dN(t)){let e=!!t.true;return()=>e}Oc(t)}function R$e(t,e){if(e.elements.length===1)return Cp(t,e.elements[0]);{let r=[];for(let i of e.elements){let a={ALT:Cp(t,i,!0)},s=IE(i);s&&(a.GATE=Xu(s)),r.push(a)}let n=t.or++;return i=>t.parser.alternatives(n,r.map(a=>{let s={ALT:o(()=>a.ALT(i),"ALT")},l=a.GATE;return l&&(s.GATE=()=>l(i)),s}))}}function N$e(t,e){if(e.elements.length===1)return Cp(t,e.elements[0]);let r=[];for(let l of e.elements){let u={ALT:Cp(t,l,!0)},h=IE(l);h&&(u.GATE=Xu(h)),r.push(u)}let n=t.or++,i=o((l,u)=>{let h=u.getRuleStack().join("-");return`uGroup_${l}_${h}`},"idFunc"),a=o(l=>t.parser.alternatives(n,r.map((u,h)=>{let f={ALT:o(()=>!0,"ALT")},d=t.parser;f.ALT=()=>{if(u.ALT(l),!d.isRecording()){let m=i(n,d);d.unorderedGroups.get(m)||d.unorderedGroups.set(m,[]);let g=d.unorderedGroups.get(m);typeof g?.[h]>"u"&&(g[h]=!0)}};let p=u.GATE;return p?f.GATE=()=>p(l):f.GATE=()=>{let m=d.unorderedGroups.get(i(n,d));return!m?.[h]},f})),"alternatives"),s=qce(t,IE(e),a,"*");return l=>{s(l),t.parser.isRecording()||t.parser.unorderedGroups.delete(i(n,t.parser))}}function M$e(t,e){let r=e.elements.map(n=>Cp(t,n));return n=>r.forEach(i=>i(n))}function IE(t){if(ff(t))return t.guardCondition}function Wce(t,e,r=e.terminal){if(r)if(Bl(r)&&Fa(r.rule.ref)){let n=r.rule.ref,i=t.subrule++;return a=>t.parser.subrule(i,Yce(t,n),!1,e,a)}else if(Bl(r)&&uo(r.rule.ref)){let n=t.consume++,i=rI(t,r.rule.ref.name);return()=>t.parser.consume(n,i,e)}else if(Xo(r)){let n=t.consume++,i=rI(t,r.value);return()=>t.parser.consume(n,i,e)}else throw new Error("Could not build cross reference parser");else{if(!e.type.ref)throw new Error("Could not resolve reference to type: "+e.type.$refText);let n=Fk(e.type.ref),i=n?.terminal;if(!i)throw new Error("Could not find name assignment for type: "+cx(e.type.ref));return Wce(t,e,i)}}function I$e(t,e){let r=t.consume++,n=t.tokens[e.value];if(!n)throw new Error("Could not find token for keyword: "+e.value);return()=>t.parser.consume(r,n,e)}function qce(t,e,r,n){let i=e&&Xu(e);if(!n)if(i){let a=t.or++;return s=>t.parser.alternatives(a,[{ALT:o(()=>r(s),"ALT"),GATE:o(()=>i(s),"GATE")},{ALT:kE(),GATE:o(()=>!i(s),"GATE")}])}else return r;if(n==="*"){let a=t.many++;return s=>t.parser.many(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else if(n==="+"){let a=t.many++;if(i){let s=t.or++;return l=>t.parser.alternatives(s,[{ALT:o(()=>t.parser.atLeastOne(a,{DEF:o(()=>r(l),"DEF")}),"ALT"),GATE:o(()=>i(l),"GATE")},{ALT:kE(),GATE:o(()=>!i(l),"GATE")}])}else return s=>t.parser.atLeastOne(a,{DEF:o(()=>r(s),"DEF")})}else if(n==="?"){let a=t.optional++;return s=>t.parser.optional(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else Oc(n)}function Yce(t,e){let r=O$e(t,e),n=t.parser.getRule(r);if(!n)throw new Error(`Rule "${r}" not found."`);return n}function O$e(t,e){if(Fa(e))return e.name;if(t.ruleNames.has(e))return t.ruleNames.get(e);{let r=e,n=r.$container,i=e.$type;for(;!Fa(n);)(ff(n)||Lk(n)||Nk(n))&&(i=n.elements.indexOf(r).toString()+":"+i),r=n,n=n.$container;return i=n.name+":"+i,t.ruleNames.set(e,i),i}}function rI(t,e){let r=t.tokens[e];if(!r)throw new Error(`Token "${e}" not found."`);return r}var OE=N(()=>{"use strict";mf();Pc();Sk();Gs();Fl();o(Gx,"createParser");o(A$e,"buildRules");o(Cp,"buildElement");o(_$e,"buildAction");o(D$e,"buildRuleCall");o(L$e,"buildRuleCallPredicate");o(Xu,"buildPredicate");o(R$e,"buildAlternatives");o(N$e,"buildUnorderedGroup");o(M$e,"buildGroup");o(IE,"getGuardCondition");o(Wce,"buildCrossReference");o(I$e,"buildKeyword");o(qce,"wrap");o(Yce,"getRule");o(O$e,"getRuleName");o(rI,"getToken")});function nI(t){let e=t.Grammar,r=t.parser.Lexer,n=new $x(t);return Gx(e,n,r.definition),n.finalize(),n}var iI=N(()=>{"use strict";zx();OE();o(nI,"createCompletionParser")});function aI(t){let e=Xce(t);return e.finalize(),e}function Xce(t){let e=t.Grammar,r=t.parser.Lexer,n=new Fx(t);return Gx(e,n,r.definition)}var sI=N(()=>{"use strict";zx();OE();o(aI,"createLangiumParser");o(Xce,"prepareLangiumParser")});var ju,PE=N(()=>{"use strict";mf();Pc();cs();Fl();$g();Gs();ju=class{static{o(this,"DefaultTokenBuilder")}constructor(){this.diagnostics=[]}buildTokens(e,r){let n=en(sx(e,!1)),i=this.buildTerminalTokens(n),a=this.buildKeywordTokens(n,i,r);return i.forEach(s=>{let l=s.PATTERN;typeof l=="object"&&l&&"test"in l&&Fg(l)?a.unshift(s):a.push(s)}),a}flushLexingReport(e){return{diagnostics:this.popDiagnostics()}}popDiagnostics(){let e=[...this.diagnostics];return this.diagnostics=[],e}buildTerminalTokens(e){return e.filter(uo).filter(r=>!r.fragment).map(r=>this.buildTerminalToken(r)).toArray()}buildTerminalToken(e){let r=Gg(e),n=this.requiresCustomPattern(r)?this.regexPatternFunction(r):r,i={name:e.name,PATTERN:n};return typeof n=="function"&&(i.LINE_BREAKS=!0),e.hidden&&(i.GROUP=Fg(r)?Kn.SKIPPED:"hidden"),i}requiresCustomPattern(e){return e.flags.includes("u")||e.flags.includes("s")?!0:!!(e.source.includes("?<=")||e.source.includes("?(r.lastIndex=i,r.exec(n))}buildKeywordTokens(e,r,n){return e.filter(Fa).flatMap(i=>Bc(i).filter(Xo)).distinct(i=>i.value).toArray().sort((i,a)=>a.value.length-i.value.length).map(i=>this.buildKeywordToken(i,r,!!n?.caseInsensitive))}buildKeywordToken(e,r,n){let i=this.buildKeywordPattern(e,n),a={name:e.value,PATTERN:i,LONGER_ALT:this.findLongerAlt(e,r)};return typeof i=="function"&&(a.LINE_BREAKS=!0),a}buildKeywordPattern(e,r){return r?new RegExp(FN(e.value)):e.value}findLongerAlt(e,r){return r.reduce((n,i)=>{let a=i?.PATTERN;return a?.source&&$N("^"+a.source+"$",e.value)&&n.push(i),n},[])}}});var Ap,zc,oI=N(()=>{"use strict";Pc();Fl();Ap=class{static{o(this,"DefaultValueConverter")}convert(e,r){let n=r.grammarSource;if(up(n)&&(n=VN(n)),Bl(n)){let i=n.rule.ref;if(!i)throw new Error("This cst node was not parsed by a rule.");return this.runConverter(i,e,r)}return e}runConverter(e,r,n){var i;switch(e.name.toUpperCase()){case"INT":return zc.convertInt(r);case"STRING":return zc.convertString(r);case"ID":return zc.convertID(r)}switch((i=jN(e))===null||i===void 0?void 0:i.toLowerCase()){case"number":return zc.convertNumber(r);case"boolean":return zc.convertBoolean(r);case"bigint":return zc.convertBigint(r);case"date":return zc.convertDate(r);default:return r}}};(function(t){function e(h){let f="";for(let d=1;d{"use strict";Object.defineProperty(uI,"__esModule",{value:!0});var lI;function cI(){if(lI===void 0)throw new Error("No runtime abstraction layer installed");return lI}o(cI,"RAL");(function(t){function e(r){if(r===void 0)throw new Error("No runtime abstraction layer provided");lI=r}o(e,"install"),t.install=e})(cI||(cI={}));uI.default=cI});var Qce=Pi(za=>{"use strict";Object.defineProperty(za,"__esModule",{value:!0});za.stringArray=za.array=za.func=za.error=za.number=za.string=za.boolean=void 0;function P$e(t){return t===!0||t===!1}o(P$e,"boolean");za.boolean=P$e;function jce(t){return typeof t=="string"||t instanceof String}o(jce,"string");za.string=jce;function B$e(t){return typeof t=="number"||t instanceof Number}o(B$e,"number");za.number=B$e;function F$e(t){return t instanceof Error}o(F$e,"error");za.error=F$e;function $$e(t){return typeof t=="function"}o($$e,"func");za.func=$$e;function Kce(t){return Array.isArray(t)}o(Kce,"array");za.array=Kce;function z$e(t){return Kce(t)&&t.every(e=>jce(e))}o(z$e,"stringArray");za.stringArray=z$e});var dI=Pi(g1=>{"use strict";Object.defineProperty(g1,"__esModule",{value:!0});g1.Emitter=g1.Event=void 0;var G$e=hI(),Zce;(function(t){let e={dispose(){}};t.None=function(){return e}})(Zce||(g1.Event=Zce={}));var fI=class{static{o(this,"CallbackList")}add(e,r=null,n){this._callbacks||(this._callbacks=[],this._contexts=[]),this._callbacks.push(e),this._contexts.push(r),Array.isArray(n)&&n.push({dispose:o(()=>this.remove(e,r),"dispose")})}remove(e,r=null){if(!this._callbacks)return;let n=!1;for(let i=0,a=this._callbacks.length;i{this._callbacks||(this._callbacks=new fI),this._options&&this._options.onFirstListenerAdd&&this._callbacks.isEmpty()&&this._options.onFirstListenerAdd(this),this._callbacks.add(e,r);let i={dispose:o(()=>{this._callbacks&&(this._callbacks.remove(e,r),i.dispose=t._noop,this._options&&this._options.onLastListenerRemove&&this._callbacks.isEmpty()&&this._options.onLastListenerRemove(this))},"dispose")};return Array.isArray(n)&&n.push(i),i}),this._event}fire(e){this._callbacks&&this._callbacks.invoke.call(this._callbacks,e)}dispose(){this._callbacks&&(this._callbacks.dispose(),this._callbacks=void 0)}};g1.Emitter=BE;BE._noop=function(){}});var Jce=Pi(y1=>{"use strict";Object.defineProperty(y1,"__esModule",{value:!0});y1.CancellationTokenSource=y1.CancellationToken=void 0;var V$e=hI(),U$e=Qce(),pI=dI(),FE;(function(t){t.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:pI.Event.None}),t.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:pI.Event.None});function e(r){let n=r;return n&&(n===t.None||n===t.Cancelled||U$e.boolean(n.isCancellationRequested)&&!!n.onCancellationRequested)}o(e,"is"),t.is=e})(FE||(y1.CancellationToken=FE={}));var H$e=Object.freeze(function(t,e){let r=(0,V$e.default)().timer.setTimeout(t.bind(e),0);return{dispose(){r.dispose()}}}),$E=class{static{o(this,"MutableToken")}constructor(){this._isCancelled=!1}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?H$e:(this._emitter||(this._emitter=new pI.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=void 0)}},mI=class{static{o(this,"CancellationTokenSource")}get token(){return this._token||(this._token=new $E),this._token}cancel(){this._token?this._token.cancel():this._token=FE.Cancelled}dispose(){this._token?this._token instanceof $E&&this._token.dispose():this._token=FE.None}};y1.CancellationTokenSource=mI});var yr={};var Ko=N(()=>{"use strict";Cr(yr,Aa(Jce(),1))});function gI(){return new Promise(t=>{typeof setImmediate>"u"?setTimeout(t,0):setImmediate(t)})}function GE(){return zE=performance.now(),new yr.CancellationTokenSource}function tue(t){eue=t}function Vc(t){return t===Gc}async function wi(t){if(t===yr.CancellationToken.None)return;let e=performance.now();if(e-zE>=eue&&(zE=e,await gI(),zE=performance.now()),t.isCancellationRequested)throw Gc}var zE,eue,Gc,ps,Qo=N(()=>{"use strict";Ko();o(gI,"delayNextTick");zE=0,eue=10;o(GE,"startCancelableOperation");o(tue,"setInterruptionPeriod");Gc=Symbol("OperationCancelled");o(Vc,"isOperationCancelled");o(wi,"interruptAndCheck");ps=class{static{o(this,"Deferred")}constructor(){this.promise=new Promise((e,r)=>{this.resolve=n=>(e(n),this),this.reject=n=>(r(n),this)})}}});function yI(t,e){if(t.length<=1)return t;let r=t.length/2|0,n=t.slice(0,r),i=t.slice(r);yI(n,e),yI(i,e);let a=0,s=0,l=0;for(;ar.line||e.line===r.line&&e.character>r.character?{start:r,end:e}:t}function W$e(t){let e=iue(t.range);return e!==t.range?{newText:t.newText,range:e}:t}var VE,v1,aue=N(()=>{"use strict";VE=class t{static{o(this,"FullTextDocument")}constructor(e,r,n,i){this._uri=e,this._languageId=r,this._version=n,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let r=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(r,n)}return this._content}update(e,r){for(let n of e)if(t.isIncremental(n)){let i=iue(n.range),a=this.offsetAt(i.start),s=this.offsetAt(i.end);this._content=this._content.substring(0,a)+n.text+this._content.substring(s,this._content.length);let l=Math.max(i.start.line,0),u=Math.max(i.end.line,0),h=this._lineOffsets,f=rue(n.text,!1,a);if(u-l===f.length)for(let p=0,m=f.length;pe?i=s:n=s+1}let a=n-1;return e=this.ensureBeforeEOL(e,r[a]),{line:a,character:e-r[a]}}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line];if(e.character<=0)return n;let i=e.line+1r&&nue(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range!==void 0&&(r.rangeLength===void 0||typeof r.rangeLength=="number")}static isFull(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range===void 0&&r.rangeLength===void 0}};(function(t){function e(i,a,s,l){return new VE(i,a,s,l)}o(e,"create"),t.create=e;function r(i,a,s){if(i instanceof VE)return i.update(a,s),i;throw new Error("TextDocument.update: document must be created by TextDocument.create")}o(r,"update"),t.update=r;function n(i,a){let s=i.getText(),l=yI(a.map(W$e),(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),u=0,h=[];for(let f of l){let d=i.offsetAt(f.range.start);if(du&&h.push(s.substring(u,d)),f.newText.length&&h.push(f.newText),u=i.offsetAt(f.range.end)}return h.push(s.substr(u)),h.join("")}o(n,"applyEdits"),t.applyEdits=n})(v1||(v1={}));o(yI,"mergeSort");o(rue,"computeLineOffsets");o(nue,"isEOL");o(iue,"getWellformedRange");o(W$e,"getWellformedEdit")});var sue,ms,x1,vI=N(()=>{"use strict";(()=>{"use strict";var t={470:i=>{function a(u){if(typeof u!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(u))}o(a,"e");function s(u,h){for(var f,d="",p=0,m=-1,g=0,y=0;y<=u.length;++y){if(y2){var v=d.lastIndexOf("/");if(v!==d.length-1){v===-1?(d="",p=0):p=(d=d.slice(0,v)).length-1-d.lastIndexOf("/"),m=y,g=0;continue}}else if(d.length===2||d.length===1){d="",p=0,m=y,g=0;continue}}h&&(d.length>0?d+="/..":d="..",p=2)}else d.length>0?d+="/"+u.slice(m+1,y):d=u.slice(m+1,y),p=y-m-1;m=y,g=0}else f===46&&g!==-1?++g:g=-1}return d}o(s,"r");var l={resolve:o(function(){for(var u,h="",f=!1,d=arguments.length-1;d>=-1&&!f;d--){var p;d>=0?p=arguments[d]:(u===void 0&&(u=process.cwd()),p=u),a(p),p.length!==0&&(h=p+"/"+h,f=p.charCodeAt(0)===47)}return h=s(h,!f),f?h.length>0?"/"+h:"/":h.length>0?h:"."},"resolve"),normalize:o(function(u){if(a(u),u.length===0)return".";var h=u.charCodeAt(0)===47,f=u.charCodeAt(u.length-1)===47;return(u=s(u,!h)).length!==0||h||(u="."),u.length>0&&f&&(u+="/"),h?"/"+u:u},"normalize"),isAbsolute:o(function(u){return a(u),u.length>0&&u.charCodeAt(0)===47},"isAbsolute"),join:o(function(){if(arguments.length===0)return".";for(var u,h=0;h0&&(u===void 0?u=f:u+="/"+f)}return u===void 0?".":l.normalize(u)},"join"),relative:o(function(u,h){if(a(u),a(h),u===h||(u=l.resolve(u))===(h=l.resolve(h)))return"";for(var f=1;fy){if(h.charCodeAt(m+x)===47)return h.slice(m+x+1);if(x===0)return h.slice(m+x)}else p>y&&(u.charCodeAt(f+x)===47?v=x:x===0&&(v=0));break}var b=u.charCodeAt(f+x);if(b!==h.charCodeAt(m+x))break;b===47&&(v=x)}var T="";for(x=f+v+1;x<=d;++x)x!==d&&u.charCodeAt(x)!==47||(T.length===0?T+="..":T+="/..");return T.length>0?T+h.slice(m+v):(m+=v,h.charCodeAt(m)===47&&++m,h.slice(m))},"relative"),_makeLong:o(function(u){return u},"_makeLong"),dirname:o(function(u){if(a(u),u.length===0)return".";for(var h=u.charCodeAt(0),f=h===47,d=-1,p=!0,m=u.length-1;m>=1;--m)if((h=u.charCodeAt(m))===47){if(!p){d=m;break}}else p=!1;return d===-1?f?"/":".":f&&d===1?"//":u.slice(0,d)},"dirname"),basename:o(function(u,h){if(h!==void 0&&typeof h!="string")throw new TypeError('"ext" argument must be a string');a(u);var f,d=0,p=-1,m=!0;if(h!==void 0&&h.length>0&&h.length<=u.length){if(h.length===u.length&&h===u)return"";var g=h.length-1,y=-1;for(f=u.length-1;f>=0;--f){var v=u.charCodeAt(f);if(v===47){if(!m){d=f+1;break}}else y===-1&&(m=!1,y=f+1),g>=0&&(v===h.charCodeAt(g)?--g==-1&&(p=f):(g=-1,p=y))}return d===p?p=y:p===-1&&(p=u.length),u.slice(d,p)}for(f=u.length-1;f>=0;--f)if(u.charCodeAt(f)===47){if(!m){d=f+1;break}}else p===-1&&(m=!1,p=f+1);return p===-1?"":u.slice(d,p)},"basename"),extname:o(function(u){a(u);for(var h=-1,f=0,d=-1,p=!0,m=0,g=u.length-1;g>=0;--g){var y=u.charCodeAt(g);if(y!==47)d===-1&&(p=!1,d=g+1),y===46?h===-1?h=g:m!==1&&(m=1):h!==-1&&(m=-1);else if(!p){f=g+1;break}}return h===-1||d===-1||m===0||m===1&&h===d-1&&h===f+1?"":u.slice(h,d)},"extname"),format:o(function(u){if(u===null||typeof u!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof u);return function(h,f){var d=f.dir||f.root,p=f.base||(f.name||"")+(f.ext||"");return d?d===f.root?d+p:d+"/"+p:p}(0,u)},"format"),parse:o(function(u){a(u);var h={root:"",dir:"",base:"",ext:"",name:""};if(u.length===0)return h;var f,d=u.charCodeAt(0),p=d===47;p?(h.root="/",f=1):f=0;for(var m=-1,g=0,y=-1,v=!0,x=u.length-1,b=0;x>=f;--x)if((d=u.charCodeAt(x))!==47)y===-1&&(v=!1,y=x+1),d===46?m===-1?m=x:b!==1&&(b=1):m!==-1&&(b=-1);else if(!v){g=x+1;break}return m===-1||y===-1||b===0||b===1&&m===y-1&&m===g+1?y!==-1&&(h.base=h.name=g===0&&p?u.slice(1,y):u.slice(g,y)):(g===0&&p?(h.name=u.slice(1,m),h.base=u.slice(1,y)):(h.name=u.slice(g,m),h.base=u.slice(g,y)),h.ext=u.slice(m,y)),g>0?h.dir=u.slice(0,g-1):p&&(h.dir="/"),h},"parse"),sep:"/",delimiter:":",win32:null,posix:null};l.posix=l,i.exports=l}},e={};function r(i){var a=e[i];if(a!==void 0)return a.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,r),s.exports}o(r,"r"),r.d=(i,a)=>{for(var s in a)r.o(a,s)&&!r.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:a[s]})},r.o=(i,a)=>Object.prototype.hasOwnProperty.call(i,a),r.r=i=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var n={};(()=>{let i;r.r(n),r.d(n,{URI:o(()=>p,"URI"),Utils:o(()=>O,"Utils")}),typeof process=="object"?i=process.platform==="win32":typeof navigator=="object"&&(i=navigator.userAgent.indexOf("Windows")>=0);let a=/^\w[\w\d+.-]*$/,s=/^\//,l=/^\/\//;function u(R,k){if(!R.scheme&&k)throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${R.authority}", path: "${R.path}", query: "${R.query}", fragment: "${R.fragment}"}`);if(R.scheme&&!a.test(R.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(R.path){if(R.authority){if(!s.test(R.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(l.test(R.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}}o(u,"s");let h="",f="/",d=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;class p{static{o(this,"f")}static isUri(k){return k instanceof p||!!k&&typeof k.authority=="string"&&typeof k.fragment=="string"&&typeof k.path=="string"&&typeof k.query=="string"&&typeof k.scheme=="string"&&typeof k.fsPath=="string"&&typeof k.with=="function"&&typeof k.toString=="function"}scheme;authority;path;query;fragment;constructor(k,L,A,I,M,P=!1){typeof k=="object"?(this.scheme=k.scheme||h,this.authority=k.authority||h,this.path=k.path||h,this.query=k.query||h,this.fragment=k.fragment||h):(this.scheme=function(B,F){return B||F?B:"file"}(k,P),this.authority=L||h,this.path=function(B,F){switch(B){case"https":case"http":case"file":F?F[0]!==f&&(F=f+F):F=f}return F}(this.scheme,A||h),this.query=I||h,this.fragment=M||h,u(this,P))}get fsPath(){return b(this,!1)}with(k){if(!k)return this;let{scheme:L,authority:A,path:I,query:M,fragment:P}=k;return L===void 0?L=this.scheme:L===null&&(L=h),A===void 0?A=this.authority:A===null&&(A=h),I===void 0?I=this.path:I===null&&(I=h),M===void 0?M=this.query:M===null&&(M=h),P===void 0?P=this.fragment:P===null&&(P=h),L===this.scheme&&A===this.authority&&I===this.path&&M===this.query&&P===this.fragment?this:new g(L,A,I,M,P)}static parse(k,L=!1){let A=d.exec(k);return A?new g(A[2]||h,E(A[4]||h),E(A[5]||h),E(A[7]||h),E(A[9]||h),L):new g(h,h,h,h,h)}static file(k){let L=h;if(i&&(k=k.replace(/\\/g,f)),k[0]===f&&k[1]===f){let A=k.indexOf(f,2);A===-1?(L=k.substring(2),k=f):(L=k.substring(2,A),k=k.substring(A)||f)}return new g("file",L,k,h,h)}static from(k){let L=new g(k.scheme,k.authority,k.path,k.query,k.fragment);return u(L,!0),L}toString(k=!1){return T(this,k)}toJSON(){return this}static revive(k){if(k){if(k instanceof p)return k;{let L=new g(k);return L._formatted=k.external,L._fsPath=k._sep===m?k.fsPath:null,L}}return k}}let m=i?1:void 0;class g extends p{static{o(this,"l")}_formatted=null;_fsPath=null;get fsPath(){return this._fsPath||(this._fsPath=b(this,!1)),this._fsPath}toString(k=!1){return k?T(this,!0):(this._formatted||(this._formatted=T(this,!1)),this._formatted)}toJSON(){let k={$mid:1};return this._fsPath&&(k.fsPath=this._fsPath,k._sep=m),this._formatted&&(k.external=this._formatted),this.path&&(k.path=this.path),this.scheme&&(k.scheme=this.scheme),this.authority&&(k.authority=this.authority),this.query&&(k.query=this.query),this.fragment&&(k.fragment=this.fragment),k}}let y={58:"%3A",47:"%2F",63:"%3F",35:"%23",91:"%5B",93:"%5D",64:"%40",33:"%21",36:"%24",38:"%26",39:"%27",40:"%28",41:"%29",42:"%2A",43:"%2B",44:"%2C",59:"%3B",61:"%3D",32:"%20"};function v(R,k,L){let A,I=-1;for(let M=0;M=97&&P<=122||P>=65&&P<=90||P>=48&&P<=57||P===45||P===46||P===95||P===126||k&&P===47||L&&P===91||L&&P===93||L&&P===58)I!==-1&&(A+=encodeURIComponent(R.substring(I,M)),I=-1),A!==void 0&&(A+=R.charAt(M));else{A===void 0&&(A=R.substr(0,M));let B=y[P];B!==void 0?(I!==-1&&(A+=encodeURIComponent(R.substring(I,M)),I=-1),A+=B):I===-1&&(I=M)}}return I!==-1&&(A+=encodeURIComponent(R.substring(I))),A!==void 0?A:R}o(v,"d");function x(R){let k;for(let L=0;L1&&R.scheme==="file"?`//${R.authority}${R.path}`:R.path.charCodeAt(0)===47&&(R.path.charCodeAt(1)>=65&&R.path.charCodeAt(1)<=90||R.path.charCodeAt(1)>=97&&R.path.charCodeAt(1)<=122)&&R.path.charCodeAt(2)===58?k?R.path.substr(1):R.path[1].toLowerCase()+R.path.substr(2):R.path,i&&(L=L.replace(/\//g,"\\")),L}o(b,"m");function T(R,k){let L=k?x:v,A="",{scheme:I,authority:M,path:P,query:B,fragment:F}=R;if(I&&(A+=I,A+=":"),(M||I==="file")&&(A+=f,A+=f),M){let z=M.indexOf("@");if(z!==-1){let $=M.substr(0,z);M=M.substr(z+1),z=$.lastIndexOf(":"),z===-1?A+=L($,!1,!1):(A+=L($.substr(0,z),!1,!1),A+=":",A+=L($.substr(z+1),!1,!0)),A+="@"}M=M.toLowerCase(),z=M.lastIndexOf(":"),z===-1?A+=L(M,!1,!0):(A+=L(M.substr(0,z),!1,!0),A+=M.substr(z))}if(P){if(P.length>=3&&P.charCodeAt(0)===47&&P.charCodeAt(2)===58){let z=P.charCodeAt(1);z>=65&&z<=90&&(P=`/${String.fromCharCode(z+32)}:${P.substr(3)}`)}else if(P.length>=2&&P.charCodeAt(1)===58){let z=P.charCodeAt(0);z>=65&&z<=90&&(P=`${String.fromCharCode(z+32)}:${P.substr(2)}`)}A+=L(P,!0,!1)}return B&&(A+="?",A+=L(B,!1,!1)),F&&(A+="#",A+=k?F:v(F,!1,!1)),A}o(T,"y");function S(R){try{return decodeURIComponent(R)}catch{return R.length>3?R.substr(0,3)+S(R.substr(3)):R}}o(S,"v");let w=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function E(R){return R.match(w)?R.replace(w,k=>S(k)):R}o(E,"C");var _=r(470);let C=_.posix||_,D="/";var O;(function(R){R.joinPath=function(k,...L){return k.with({path:C.join(k.path,...L)})},R.resolvePath=function(k,...L){let A=k.path,I=!1;A[0]!==D&&(A=D+A,I=!0);let M=C.resolve(A,...L);return I&&M[0]===D&&!k.authority&&(M=M.substring(1)),k.with({path:M})},R.dirname=function(k){if(k.path.length===0||k.path===D)return k;let L=C.dirname(k.path);return L.length===1&&L.charCodeAt(0)===46&&(L=""),k.with({path:L})},R.basename=function(k){return C.basename(k.path)},R.extname=function(k){return C.extname(k.path)}})(O||(O={}))})(),sue=n})();({URI:ms,Utils:x1}=sue)});var gs,Uc=N(()=>{"use strict";vI();(function(t){t.basename=x1.basename,t.dirname=x1.dirname,t.extname=x1.extname,t.joinPath=x1.joinPath,t.resolvePath=x1.resolvePath;function e(i,a){return i?.toString()===a?.toString()}o(e,"equals"),t.equals=e;function r(i,a){let s=typeof i=="string"?i:i.path,l=typeof a=="string"?a:a.path,u=s.split("/").filter(m=>m.length>0),h=l.split("/").filter(m=>m.length>0),f=0;for(;f{"use strict";aue();b1();Ko();Gs();Uc();(function(t){t[t.Changed=0]="Changed",t[t.Parsed=1]="Parsed",t[t.IndexedContent=2]="IndexedContent",t[t.ComputedScopes=3]="ComputedScopes",t[t.Linked=4]="Linked",t[t.IndexedReferences=5]="IndexedReferences",t[t.Validated=6]="Validated"})(kn||(kn={}));Vx=class{static{o(this,"DefaultLangiumDocumentFactory")}constructor(e){this.serviceRegistry=e.ServiceRegistry,this.textDocuments=e.workspace.TextDocuments,this.fileSystemProvider=e.workspace.FileSystemProvider}async fromUri(e,r=yr.CancellationToken.None){let n=await this.fileSystemProvider.readFile(e);return this.createAsync(e,n,r)}fromTextDocument(e,r,n){return r=r??ms.parse(e.uri),yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromString(e,r,n){return yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromModel(e,r){return this.create(r,{$model:e})}create(e,r,n){if(typeof r=="string"){let i=this.parse(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else if("$model"in r){let i={value:r.$model,parserErrors:[],lexerErrors:[]};return this.createLangiumDocument(i,e)}else{let i=this.parse(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}async createAsync(e,r,n){if(typeof r=="string"){let i=await this.parseAsync(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else{let i=await this.parseAsync(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}createLangiumDocument(e,r,n,i){let a;if(n)a={parseResult:e,uri:r,state:kn.Parsed,references:[],textDocument:n};else{let s=this.createTextDocumentGetter(r,i);a={parseResult:e,uri:r,state:kn.Parsed,references:[],get textDocument(){return s()}}}return e.value.$document=a,a}async update(e,r){var n,i;let a=(n=e.parseResult.value.$cstNode)===null||n===void 0?void 0:n.root.fullText,s=(i=this.textDocuments)===null||i===void 0?void 0:i.get(e.uri.toString()),l=s?s.getText():await this.fileSystemProvider.readFile(e.uri);if(s)Object.defineProperty(e,"textDocument",{value:s});else{let u=this.createTextDocumentGetter(e.uri,l);Object.defineProperty(e,"textDocument",{get:u})}return a!==l&&(e.parseResult=await this.parseAsync(e.uri,l,r),e.parseResult.value.$document=e),e.state=kn.Parsed,e}parse(e,r,n){return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(r,n)}parseAsync(e,r,n){return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(r,n)}createTextDocumentGetter(e,r){let n=this.serviceRegistry,i;return()=>i??(i=v1.create(e.toString(),n.getServices(e).LanguageMetaData.languageId,0,r??""))}},Ux=class{static{o(this,"DefaultLangiumDocuments")}constructor(e){this.documentMap=new Map,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.serviceRegistry=e.ServiceRegistry}get all(){return en(this.documentMap.values())}addDocument(e){let r=e.uri.toString();if(this.documentMap.has(r))throw new Error(`A document with the URI '${r}' is already present.`);this.documentMap.set(r,e)}getDocument(e){let r=e.toString();return this.documentMap.get(r)}async getOrCreateDocument(e,r){let n=this.getDocument(e);return n||(n=await this.langiumDocumentFactory.fromUri(e,r),this.addDocument(n),n)}createDocument(e,r,n){if(n)return this.langiumDocumentFactory.fromString(r,e,n).then(i=>(this.addDocument(i),i));{let i=this.langiumDocumentFactory.fromString(r,e);return this.addDocument(i),i}}hasDocument(e){return this.documentMap.has(e.toString())}invalidateDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(this.serviceRegistry.getServices(e).references.Linker.unlink(n),n.state=kn.Changed,n.precomputedScopes=void 0,n.diagnostics=void 0),n}deleteDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(n.state=kn.Changed,this.documentMap.delete(r)),n}}});var xI,Hx,bI=N(()=>{"use strict";Ko();Il();cs();Qo();b1();xI=Symbol("ref_resolving"),Hx=class{static{o(this,"DefaultLinker")}constructor(e){this.reflection=e.shared.AstReflection,this.langiumDocuments=()=>e.shared.workspace.LangiumDocuments,this.scopeProvider=e.references.ScopeProvider,this.astNodeLocator=e.workspace.AstNodeLocator}async link(e,r=yr.CancellationToken.None){for(let n of jo(e.parseResult.value))await wi(r),Pg(n).forEach(i=>this.doLink(i,e))}doLink(e,r){var n;let i=e.reference;if(i._ref===void 0){i._ref=xI;try{let a=this.getCandidate(e);if(ap(a))i._ref=a;else if(i._nodeDescription=a,this.langiumDocuments().hasDocument(a.documentUri)){let s=this.loadAstNode(a);i._ref=s??this.createLinkingError(e,a)}else i._ref=void 0}catch(a){console.error(`An error occurred while resolving reference to '${i.$refText}':`,a);let s=(n=a.message)!==null&&n!==void 0?n:String(a);i._ref=Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${i.$refText}': ${s}`})}r.references.push(i)}}unlink(e){for(let r of e.references)delete r._ref,delete r._nodeDescription;e.references=[]}getCandidate(e){let n=this.scopeProvider.getScope(e).getElement(e.reference.$refText);return n??this.createLinkingError(e)}buildReference(e,r,n,i){let a=this,s={$refNode:n,$refText:i,get ref(){var l;if(si(this._ref))return this._ref;if(sN(this._nodeDescription)){let u=a.loadAstNode(this._nodeDescription);this._ref=u??a.createLinkingError({reference:s,container:e,property:r},this._nodeDescription)}else if(this._ref===void 0){this._ref=xI;let u=ex(e).$document,h=a.getLinkedNode({reference:s,container:e,property:r});if(h.error&&u&&u.state{"use strict";Fl();o(oue,"isNamed");Wx=class{static{o(this,"DefaultNameProvider")}getName(e){if(oue(e))return e.name}getNameNode(e){return ox(e.$cstNode,"name")}}});var qx,wI=N(()=>{"use strict";Fl();Il();cs();Ol();Gs();Uc();qx=class{static{o(this,"DefaultReferences")}constructor(e){this.nameProvider=e.references.NameProvider,this.index=e.shared.workspace.IndexManager,this.nodeLocator=e.workspace.AstNodeLocator}findDeclaration(e){if(e){let r=XN(e),n=e.astNode;if(r&&n){let i=n[r.feature];if(ya(i))return i.ref;if(Array.isArray(i)){for(let a of i)if(ya(a)&&a.$refNode&&a.$refNode.offset<=e.offset&&a.$refNode.end>=e.end)return a.ref}}if(n){let i=this.nameProvider.getNameNode(n);if(i&&(i===e||lN(e,i)))return n}}}findDeclarationNode(e){let r=this.findDeclaration(e);if(r?.$cstNode){let n=this.nameProvider.getNameNode(r);return n??r.$cstNode}}findReferences(e,r){let n=[];if(r.includeDeclaration){let a=this.getReferenceToSelf(e);a&&n.push(a)}let i=this.index.findAllReferences(e,this.nodeLocator.getAstNodePath(e));return r.documentUri&&(i=i.filter(a=>gs.equals(a.sourceUri,r.documentUri))),n.push(...i),en(n)}getReferenceToSelf(e){let r=this.nameProvider.getNameNode(e);if(r){let n=$a(e),i=this.nodeLocator.getAstNodePath(e);return{sourceUri:n.uri,sourcePath:i,targetUri:n.uri,targetPath:i,segment:op(r),local:!0}}}}});var zl,_p,T1=N(()=>{"use strict";Gs();zl=class{static{o(this,"MultiMap")}constructor(e){if(this.map=new Map,e)for(let[r,n]of e)this.add(r,n)}get size(){return jm.sum(en(this.map.values()).map(e=>e.length))}clear(){this.map.clear()}delete(e,r){if(r===void 0)return this.map.delete(e);{let n=this.map.get(e);if(n){let i=n.indexOf(r);if(i>=0)return n.length===1?this.map.delete(e):n.splice(i,1),!0}return!1}}get(e){var r;return(r=this.map.get(e))!==null&&r!==void 0?r:[]}has(e,r){if(r===void 0)return this.map.has(e);{let n=this.map.get(e);return n?n.indexOf(r)>=0:!1}}add(e,r){return this.map.has(e)?this.map.get(e).push(r):this.map.set(e,[r]),this}addAll(e,r){return this.map.has(e)?this.map.get(e).push(...r):this.map.set(e,Array.from(r)),this}forEach(e){this.map.forEach((r,n)=>r.forEach(i=>e(i,n,this)))}[Symbol.iterator](){return this.entries().iterator()}entries(){return en(this.map.entries()).flatMap(([e,r])=>r.map(n=>[e,n]))}keys(){return en(this.map.keys())}values(){return en(this.map.values()).flat()}entriesGroupedByKey(){return en(this.map.entries())}},_p=class{static{o(this,"BiMap")}get size(){return this.map.size}constructor(e){if(this.map=new Map,this.inverse=new Map,e)for(let[r,n]of e)this.set(r,n)}clear(){this.map.clear(),this.inverse.clear()}set(e,r){return this.map.set(e,r),this.inverse.set(r,e),this}get(e){return this.map.get(e)}getKey(e){return this.inverse.get(e)}delete(e){let r=this.map.get(e);return r!==void 0?(this.map.delete(e),this.inverse.delete(r),!0):!1}}});var Yx,kI=N(()=>{"use strict";Ko();cs();T1();Qo();Yx=class{static{o(this,"DefaultScopeComputation")}constructor(e){this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider}async computeExports(e,r=yr.CancellationToken.None){return this.computeExportsForNode(e.parseResult.value,e,void 0,r)}async computeExportsForNode(e,r,n=tx,i=yr.CancellationToken.None){let a=[];this.exportNode(e,a,r);for(let s of n(e))await wi(i),this.exportNode(s,a,r);return a}exportNode(e,r,n){let i=this.nameProvider.getName(e);i&&r.push(this.descriptions.createDescription(e,i,n))}async computeLocalScopes(e,r=yr.CancellationToken.None){let n=e.parseResult.value,i=new zl;for(let a of Bc(n))await wi(r),this.processNode(a,e,i);return i}processNode(e,r,n){let i=e.$container;if(i){let a=this.nameProvider.getName(e);a&&n.add(i,this.descriptions.createDescription(e,a,r))}}}});var w1,Xx,q$e,EI=N(()=>{"use strict";Gs();w1=class{static{o(this,"StreamScope")}constructor(e,r,n){var i;this.elements=e,this.outerScope=r,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1}getAllElements(){return this.outerScope?this.elements.concat(this.outerScope.getAllElements()):this.elements}getElement(e){let r=this.caseInsensitive?this.elements.find(n=>n.name.toLowerCase()===e.toLowerCase()):this.elements.find(n=>n.name===e);if(r)return r;if(this.outerScope)return this.outerScope.getElement(e)}},Xx=class{static{o(this,"MapScope")}constructor(e,r,n){var i;this.elements=new Map,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1;for(let a of e){let s=this.caseInsensitive?a.name.toLowerCase():a.name;this.elements.set(s,a)}this.outerScope=r}getElement(e){let r=this.caseInsensitive?e.toLowerCase():e,n=this.elements.get(r);if(n)return n;if(this.outerScope)return this.outerScope.getElement(e)}getAllElements(){let e=en(this.elements.values());return this.outerScope&&(e=e.concat(this.outerScope.getAllElements())),e}},q$e={getElement(){},getAllElements(){return H2}}});var k1,jx,Dp,UE,E1,HE=N(()=>{"use strict";k1=class{static{o(this,"DisposableCache")}constructor(){this.toDispose=[],this.isDisposed=!1}onDispose(e){this.toDispose.push(e)}dispose(){this.throwIfDisposed(),this.clear(),this.isDisposed=!0,this.toDispose.forEach(e=>e.dispose())}throwIfDisposed(){if(this.isDisposed)throw new Error("This cache has already been disposed")}},jx=class extends k1{static{o(this,"SimpleCache")}constructor(){super(...arguments),this.cache=new Map}has(e){return this.throwIfDisposed(),this.cache.has(e)}set(e,r){this.throwIfDisposed(),this.cache.set(e,r)}get(e,r){if(this.throwIfDisposed(),this.cache.has(e))return this.cache.get(e);if(r){let n=r();return this.cache.set(e,n),n}else return}delete(e){return this.throwIfDisposed(),this.cache.delete(e)}clear(){this.throwIfDisposed(),this.cache.clear()}},Dp=class extends k1{static{o(this,"ContextCache")}constructor(e){super(),this.cache=new Map,this.converter=e??(r=>r)}has(e,r){return this.throwIfDisposed(),this.cacheForContext(e).has(r)}set(e,r,n){this.throwIfDisposed(),this.cacheForContext(e).set(r,n)}get(e,r,n){this.throwIfDisposed();let i=this.cacheForContext(e);if(i.has(r))return i.get(r);if(n){let a=n();return i.set(r,a),a}else return}delete(e,r){return this.throwIfDisposed(),this.cacheForContext(e).delete(r)}clear(e){if(this.throwIfDisposed(),e){let r=this.converter(e);this.cache.delete(r)}else this.cache.clear()}cacheForContext(e){let r=this.converter(e),n=this.cache.get(r);return n||(n=new Map,this.cache.set(r,n)),n}},UE=class extends Dp{static{o(this,"DocumentCache")}constructor(e,r){super(n=>n.toString()),r?(this.toDispose.push(e.workspace.DocumentBuilder.onDocumentPhase(r,n=>{this.clear(n.uri.toString())})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{for(let a of i)this.clear(a)}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{let a=n.concat(i);for(let s of a)this.clear(s)}))}},E1=class extends jx{static{o(this,"WorkspaceCache")}constructor(e,r){super(),r?(this.toDispose.push(e.workspace.DocumentBuilder.onBuildPhase(r,()=>{this.clear()})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{i.length>0&&this.clear()}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate(()=>{this.clear()}))}}});var Kx,SI=N(()=>{"use strict";EI();cs();Gs();HE();Kx=class{static{o(this,"DefaultScopeProvider")}constructor(e){this.reflection=e.shared.AstReflection,this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider,this.indexManager=e.shared.workspace.IndexManager,this.globalScopeCache=new E1(e.shared)}getScope(e){let r=[],n=this.reflection.getReferenceType(e),i=$a(e.container).precomputedScopes;if(i){let s=e.container;do{let l=i.get(s);l.length>0&&r.push(en(l).filter(u=>this.reflection.isSubtype(u.type,n))),s=s.$container}while(s)}let a=this.getGlobalScope(n,e);for(let s=r.length-1;s>=0;s--)a=this.createScope(r[s],a);return a}createScope(e,r,n){return new w1(en(e),r,n)}createScopeForNodes(e,r,n){let i=en(e).map(a=>{let s=this.nameProvider.getName(a);if(s)return this.descriptions.createDescription(a,s)}).nonNullable();return new w1(i,r,n)}getGlobalScope(e,r){return this.globalScopeCache.get(e,()=>new Xx(this.indexManager.allElements(e)))}}});function CI(t){return typeof t.$comment=="string"}function lue(t){return typeof t=="object"&&!!t&&("$ref"in t||"$error"in t)}var Qx,WE=N(()=>{"use strict";vI();Il();cs();Fl();o(CI,"isAstNodeWithComment");o(lue,"isIntermediateReference");Qx=class{static{o(this,"DefaultJsonSerializer")}constructor(e){this.ignoreProperties=new Set(["$container","$containerProperty","$containerIndex","$document","$cstNode"]),this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider,this.commentProvider=e.documentation.CommentProvider}serialize(e,r){let n=r??{},i=r?.replacer,a=o((l,u)=>this.replacer(l,u,n),"defaultReplacer"),s=i?(l,u)=>i(l,u,a):a;try{return this.currentDocument=$a(e),JSON.stringify(e,s,r?.space)}finally{this.currentDocument=void 0}}deserialize(e,r){let n=r??{},i=JSON.parse(e);return this.linkNode(i,i,n),i}replacer(e,r,{refText:n,sourceText:i,textRegions:a,comments:s,uriConverter:l}){var u,h,f,d;if(!this.ignoreProperties.has(e))if(ya(r)){let p=r.ref,m=n?r.$refText:void 0;if(p){let g=$a(p),y="";this.currentDocument&&this.currentDocument!==g&&(l?y=l(g.uri,r):y=g.uri.toString());let v=this.astNodeLocator.getAstNodePath(p);return{$ref:`${y}#${v}`,$refText:m}}else return{$error:(h=(u=r.error)===null||u===void 0?void 0:u.message)!==null&&h!==void 0?h:"Could not resolve reference",$refText:m}}else if(si(r)){let p;if(a&&(p=this.addAstNodeRegionWithAssignmentsTo(Object.assign({},r)),(!e||r.$document)&&p?.$textRegion&&(p.$textRegion.documentURI=(f=this.currentDocument)===null||f===void 0?void 0:f.uri.toString())),i&&!e&&(p??(p=Object.assign({},r)),p.$sourceText=(d=r.$cstNode)===null||d===void 0?void 0:d.text),s){p??(p=Object.assign({},r));let m=this.commentProvider.getComment(r);m&&(p.$comment=m.replace(/\r/g,""))}return p??r}else return r}addAstNodeRegionWithAssignmentsTo(e){let r=o(n=>({offset:n.offset,end:n.end,length:n.length,range:n.range}),"createDocumentSegment");if(e.$cstNode){let n=e.$textRegion=r(e.$cstNode),i=n.assignments={};return Object.keys(e).filter(a=>!a.startsWith("$")).forEach(a=>{let s=HN(e.$cstNode,a).map(r);s.length!==0&&(i[a]=s)}),e}}linkNode(e,r,n,i,a,s){for(let[u,h]of Object.entries(e))if(Array.isArray(h))for(let f=0;f{"use strict";Uc();Zx=class{static{o(this,"DefaultServiceRegistry")}get map(){return this.fileExtensionMap}constructor(e){this.languageIdMap=new Map,this.fileExtensionMap=new Map,this.textDocuments=e?.workspace.TextDocuments}register(e){let r=e.LanguageMetaData;for(let n of r.fileExtensions)this.fileExtensionMap.has(n)&&console.warn(`The file extension ${n} is used by multiple languages. It is now assigned to '${r.languageId}'.`),this.fileExtensionMap.set(n,e);this.languageIdMap.set(r.languageId,e),this.languageIdMap.size===1?this.singleton=e:this.singleton=void 0}getServices(e){var r,n;if(this.singleton!==void 0)return this.singleton;if(this.languageIdMap.size===0)throw new Error("The service registry is empty. Use `register` to register the services of a language.");let i=(n=(r=this.textDocuments)===null||r===void 0?void 0:r.get(e))===null||n===void 0?void 0:n.languageId;if(i!==void 0){let l=this.languageIdMap.get(i);if(l)return l}let a=gs.extname(e),s=this.fileExtensionMap.get(a);if(!s)throw i?new Error(`The service registry contains no services for the extension '${a}' for language '${i}'.`):new Error(`The service registry contains no services for the extension '${a}'.`);return s}hasServices(e){try{return this.getServices(e),!0}catch{return!1}}get all(){return Array.from(this.languageIdMap.values())}}});function Lp(t){return{code:t}}var S1,Jx,eb=N(()=>{"use strict";po();T1();Qo();Gs();o(Lp,"diagnosticData");(function(t){t.all=["fast","slow","built-in"]})(S1||(S1={}));Jx=class{static{o(this,"ValidationRegistry")}constructor(e){this.entries=new zl,this.entriesBefore=[],this.entriesAfter=[],this.reflection=e.shared.AstReflection}register(e,r=this,n="fast"){if(n==="built-in")throw new Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");for(let[i,a]of Object.entries(e)){let s=a;if(Array.isArray(s))for(let l of s){let u={check:this.wrapValidationException(l,r),category:n};this.addEntry(i,u)}else if(typeof s=="function"){let l={check:this.wrapValidationException(s,r),category:n};this.addEntry(i,l)}else Oc(s)}}wrapValidationException(e,r){return async(n,i,a)=>{await this.handleException(()=>e.call(r,n,i,a),"An error occurred during validation",i,n)}}async handleException(e,r,n,i){try{await e()}catch(a){if(Vc(a))throw a;console.error(`${r}:`,a),a instanceof Error&&a.stack&&console.error(a.stack);let s=a instanceof Error?a.message:String(a);n("error",`${r}: ${s}`,{node:i})}}addEntry(e,r){if(e==="AstNode"){this.entries.add("AstNode",r);return}for(let n of this.reflection.getAllSubTypes(e))this.entries.add(n,r)}getChecks(e,r){let n=en(this.entries.get(e)).concat(this.entries.get("AstNode"));return r&&(n=n.filter(i=>r.includes(i.category))),n.map(i=>i.check)}registerBeforeDocument(e,r=this){this.entriesBefore.push(this.wrapPreparationException(e,"An error occurred during set-up of the validation",r))}registerAfterDocument(e,r=this){this.entriesAfter.push(this.wrapPreparationException(e,"An error occurred during tear-down of the validation",r))}wrapPreparationException(e,r,n){return async(i,a,s,l)=>{await this.handleException(()=>e.call(n,i,a,s,l),r,a,i)}}get checksBefore(){return this.entriesBefore}get checksAfter(){return this.entriesAfter}}});function cue(t){if(t.range)return t.range;let e;return typeof t.property=="string"?e=ox(t.node.$cstNode,t.property,t.index):typeof t.keyword=="string"&&(e=qN(t.node.$cstNode,t.keyword,t.index)),e??(e=t.node.$cstNode),e?e.range:{start:{line:0,character:0},end:{line:0,character:0}}}function qE(t){switch(t){case"error":return 1;case"warning":return 2;case"info":return 3;case"hint":return 4;default:throw new Error("Invalid diagnostic severity: "+t)}}function uue(t){switch(t){case"error":return Lp(Zo.LexingError);case"warning":return Lp(Zo.LexingWarning);case"info":return Lp(Zo.LexingInfo);case"hint":return Lp(Zo.LexingHint);default:throw new Error("Invalid diagnostic severity: "+t)}}var tb,Zo,_I=N(()=>{"use strict";Ko();Fl();cs();Ol();Qo();eb();tb=class{static{o(this,"DefaultDocumentValidator")}constructor(e){this.validationRegistry=e.validation.ValidationRegistry,this.metadata=e.LanguageMetaData}async validateDocument(e,r={},n=yr.CancellationToken.None){let i=e.parseResult,a=[];if(await wi(n),(!r.categories||r.categories.includes("built-in"))&&(this.processLexingErrors(i,a,r),r.stopAfterLexingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.LexingError})||(this.processParsingErrors(i,a,r),r.stopAfterParsingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.ParsingError}))||(this.processLinkingErrors(e,a,r),r.stopAfterLinkingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===Zo.LinkingError}))))return a;try{a.push(...await this.validateAst(i.value,r,n))}catch(s){if(Vc(s))throw s;console.error("An error occurred during validation:",s)}return await wi(n),a}processLexingErrors(e,r,n){var i,a,s;let l=[...e.lexerErrors,...(a=(i=e.lexerReport)===null||i===void 0?void 0:i.diagnostics)!==null&&a!==void 0?a:[]];for(let u of l){let h=(s=u.severity)!==null&&s!==void 0?s:"error",f={severity:qE(h),range:{start:{line:u.line-1,character:u.column-1},end:{line:u.line-1,character:u.column+u.length-1}},message:u.message,data:uue(h),source:this.getSource()};r.push(f)}}processParsingErrors(e,r,n){for(let i of e.parserErrors){let a;if(isNaN(i.token.startOffset)){if("previousToken"in i){let s=i.previousToken;if(isNaN(s.startOffset)){let l={line:0,character:0};a={start:l,end:l}}else{let l={line:s.endLine-1,character:s.endColumn};a={start:l,end:l}}}}else a=Km(i.token);if(a){let s={severity:qE("error"),range:a,message:i.message,data:Lp(Zo.ParsingError),source:this.getSource()};r.push(s)}}}processLinkingErrors(e,r,n){for(let i of e.references){let a=i.error;if(a){let s={node:a.container,property:a.property,index:a.index,data:{code:Zo.LinkingError,containerType:a.container.$type,property:a.property,refText:a.reference.$refText}};r.push(this.toDiagnostic("error",a.message,s))}}}async validateAst(e,r,n=yr.CancellationToken.None){let i=[],a=o((s,l,u)=>{i.push(this.toDiagnostic(s,l,u))},"acceptor");return await this.validateAstBefore(e,r,a,n),await this.validateAstNodes(e,r,a,n),await this.validateAstAfter(e,r,a,n),i}async validateAstBefore(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksBefore;for(let l of s)await wi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}async validateAstNodes(e,r,n,i=yr.CancellationToken.None){await Promise.all(jo(e).map(async a=>{await wi(i);let s=this.validationRegistry.getChecks(a.$type,r.categories);for(let l of s)await l(a,n,i)}))}async validateAstAfter(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksAfter;for(let l of s)await wi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}toDiagnostic(e,r,n){return{message:r,range:cue(n),severity:qE(e),code:n.code,codeDescription:n.codeDescription,tags:n.tags,relatedInformation:n.relatedInformation,data:n.data,source:this.getSource()}}getSource(){return this.metadata.languageId}};o(cue,"getDiagnosticRange");o(qE,"toDiagnosticSeverity");o(uue,"toDiagnosticData");(function(t){t.LexingError="lexing-error",t.LexingWarning="lexing-warning",t.LexingInfo="lexing-info",t.LexingHint="lexing-hint",t.ParsingError="parsing-error",t.LinkingError="linking-error"})(Zo||(Zo={}))});var rb,nb,DI=N(()=>{"use strict";Ko();Il();cs();Ol();Qo();Uc();rb=class{static{o(this,"DefaultAstNodeDescriptionProvider")}constructor(e){this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider}createDescription(e,r,n){let i=n??$a(e);r??(r=this.nameProvider.getName(e));let a=this.astNodeLocator.getAstNodePath(e);if(!r)throw new Error(`Node at path ${a} has no name.`);let s,l=o(()=>{var u;return s??(s=op((u=this.nameProvider.getNameNode(e))!==null&&u!==void 0?u:e.$cstNode))},"nameSegmentGetter");return{node:e,name:r,get nameSegment(){return l()},selectionSegment:op(e.$cstNode),type:e.$type,documentUri:i.uri,path:a}}},nb=class{static{o(this,"DefaultReferenceDescriptionProvider")}constructor(e){this.nodeLocator=e.workspace.AstNodeLocator}async createDescriptions(e,r=yr.CancellationToken.None){let n=[],i=e.parseResult.value;for(let a of jo(i))await wi(r),Pg(a).filter(s=>!ap(s)).forEach(s=>{let l=this.createDescription(s);l&&n.push(l)});return n}createDescription(e){let r=e.reference.$nodeDescription,n=e.reference.$refNode;if(!r||!n)return;let i=$a(e.container).uri;return{sourceUri:i,sourcePath:this.nodeLocator.getAstNodePath(e.container),targetUri:r.documentUri,targetPath:r.path,segment:op(n),local:gs.equals(r.documentUri,i)}}}});var ib,LI=N(()=>{"use strict";ib=class{static{o(this,"DefaultAstNodeLocator")}constructor(){this.segmentSeparator="/",this.indexSeparator="@"}getAstNodePath(e){if(e.$container){let r=this.getAstNodePath(e.$container),n=this.getPathSegment(e);return r+this.segmentSeparator+n}return""}getPathSegment({$containerProperty:e,$containerIndex:r}){if(!e)throw new Error("Missing '$containerProperty' in AST node.");return r!==void 0?e+this.indexSeparator+r:e}getAstNode(e,r){return r.split(this.segmentSeparator).reduce((i,a)=>{if(!i||a.length===0)return i;let s=a.indexOf(this.indexSeparator);if(s>0){let l=a.substring(0,s),u=parseInt(a.substring(s+1)),h=i[l];return h?.[u]}return i[a]},e)}}});var Zn={};var YE=N(()=>{"use strict";Cr(Zn,Aa(dI(),1))});var ab,RI=N(()=>{"use strict";YE();Qo();ab=class{static{o(this,"DefaultConfigurationProvider")}constructor(e){this._ready=new ps,this.settings={},this.workspaceConfig=!1,this.onConfigurationSectionUpdateEmitter=new Zn.Emitter,this.serviceRegistry=e.ServiceRegistry}get ready(){return this._ready.promise}initialize(e){var r,n;this.workspaceConfig=(n=(r=e.capabilities.workspace)===null||r===void 0?void 0:r.configuration)!==null&&n!==void 0?n:!1}async initialized(e){if(this.workspaceConfig){if(e.register){let r=this.serviceRegistry.all;e.register({section:r.map(n=>this.toSectionName(n.LanguageMetaData.languageId))})}if(e.fetchConfiguration){let r=this.serviceRegistry.all.map(i=>({section:this.toSectionName(i.LanguageMetaData.languageId)})),n=await e.fetchConfiguration(r);r.forEach((i,a)=>{this.updateSectionConfiguration(i.section,n[a])})}}this._ready.resolve()}updateConfiguration(e){e.settings&&Object.keys(e.settings).forEach(r=>{let n=e.settings[r];this.updateSectionConfiguration(r,n),this.onConfigurationSectionUpdateEmitter.fire({section:r,configuration:n})})}updateSectionConfiguration(e,r){this.settings[e]=r}async getConfiguration(e,r){await this.ready;let n=this.toSectionName(e);if(this.settings[n])return this.settings[n][r]}toSectionName(e){return`${e}`}get onConfigurationSectionUpdate(){return this.onConfigurationSectionUpdateEmitter.event}}});var vf,NI=N(()=>{"use strict";(function(t){function e(r){return{dispose:o(async()=>await r(),"dispose")}}o(e,"create"),t.create=e})(vf||(vf={}))});var sb,MI=N(()=>{"use strict";Ko();NI();T1();Qo();Gs();eb();b1();sb=class{static{o(this,"DefaultDocumentBuilder")}constructor(e){this.updateBuildOptions={validation:{categories:["built-in","fast"]}},this.updateListeners=[],this.buildPhaseListeners=new zl,this.documentPhaseListeners=new zl,this.buildState=new Map,this.documentBuildWaiters=new Map,this.currentState=kn.Changed,this.langiumDocuments=e.workspace.LangiumDocuments,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.textDocuments=e.workspace.TextDocuments,this.indexManager=e.workspace.IndexManager,this.serviceRegistry=e.ServiceRegistry}async build(e,r={},n=yr.CancellationToken.None){var i,a;for(let s of e){let l=s.uri.toString();if(s.state===kn.Validated){if(typeof r.validation=="boolean"&&r.validation)s.state=kn.IndexedReferences,s.diagnostics=void 0,this.buildState.delete(l);else if(typeof r.validation=="object"){let u=this.buildState.get(l),h=(i=u?.result)===null||i===void 0?void 0:i.validationChecks;if(h){let d=((a=r.validation.categories)!==null&&a!==void 0?a:S1.all).filter(p=>!h.includes(p));d.length>0&&(this.buildState.set(l,{completed:!1,options:{validation:Object.assign(Object.assign({},r.validation),{categories:d})},result:u.result}),s.state=kn.IndexedReferences)}}}else this.buildState.delete(l)}this.currentState=kn.Changed,await this.emitUpdate(e.map(s=>s.uri),[]),await this.buildDocuments(e,r,n)}async update(e,r,n=yr.CancellationToken.None){this.currentState=kn.Changed;for(let s of r)this.langiumDocuments.deleteDocument(s),this.buildState.delete(s.toString()),this.indexManager.remove(s);for(let s of e){if(!this.langiumDocuments.invalidateDocument(s)){let u=this.langiumDocumentFactory.fromModel({$type:"INVALID"},s);u.state=kn.Changed,this.langiumDocuments.addDocument(u)}this.buildState.delete(s.toString())}let i=en(e).concat(r).map(s=>s.toString()).toSet();this.langiumDocuments.all.filter(s=>!i.has(s.uri.toString())&&this.shouldRelink(s,i)).forEach(s=>{this.serviceRegistry.getServices(s.uri).references.Linker.unlink(s),s.state=Math.min(s.state,kn.ComputedScopes),s.diagnostics=void 0}),await this.emitUpdate(e,r),await wi(n);let a=this.sortDocuments(this.langiumDocuments.all.filter(s=>{var l;return s.staten(e,r)))}sortDocuments(e){let r=0,n=e.length-1;for(;r=0&&!this.hasTextDocument(e[n]);)n--;rn.error!==void 0)?!0:this.indexManager.isAffected(e,r)}onUpdate(e){return this.updateListeners.push(e),vf.create(()=>{let r=this.updateListeners.indexOf(e);r>=0&&this.updateListeners.splice(r,1)})}async buildDocuments(e,r,n){this.prepareBuild(e,r),await this.runCancelable(e,kn.Parsed,n,a=>this.langiumDocumentFactory.update(a,n)),await this.runCancelable(e,kn.IndexedContent,n,a=>this.indexManager.updateContent(a,n)),await this.runCancelable(e,kn.ComputedScopes,n,async a=>{let s=this.serviceRegistry.getServices(a.uri).references.ScopeComputation;a.precomputedScopes=await s.computeLocalScopes(a,n)}),await this.runCancelable(e,kn.Linked,n,a=>this.serviceRegistry.getServices(a.uri).references.Linker.link(a,n)),await this.runCancelable(e,kn.IndexedReferences,n,a=>this.indexManager.updateReferences(a,n));let i=e.filter(a=>this.shouldValidate(a));await this.runCancelable(i,kn.Validated,n,a=>this.validate(a,n));for(let a of e){let s=this.buildState.get(a.uri.toString());s&&(s.completed=!0)}}prepareBuild(e,r){for(let n of e){let i=n.uri.toString(),a=this.buildState.get(i);(!a||a.completed)&&this.buildState.set(i,{completed:!1,options:r,result:a?.result})}}async runCancelable(e,r,n,i){let a=e.filter(l=>l.statel.state===r);await this.notifyBuildPhase(s,r,n),this.currentState=r}onBuildPhase(e,r){return this.buildPhaseListeners.add(e,r),vf.create(()=>{this.buildPhaseListeners.delete(e,r)})}onDocumentPhase(e,r){return this.documentPhaseListeners.add(e,r),vf.create(()=>{this.documentPhaseListeners.delete(e,r)})}waitUntil(e,r,n){let i;if(r&&"path"in r?i=r:n=r,n??(n=yr.CancellationToken.None),i){let a=this.langiumDocuments.getDocument(i);if(a&&a.state>e)return Promise.resolve(i)}return this.currentState>=e?Promise.resolve(void 0):n.isCancellationRequested?Promise.reject(Gc):new Promise((a,s)=>{let l=this.onBuildPhase(e,()=>{if(l.dispose(),u.dispose(),i){let h=this.langiumDocuments.getDocument(i);a(h?.uri)}else a(void 0)}),u=n.onCancellationRequested(()=>{l.dispose(),u.dispose(),s(Gc)})})}async notifyDocumentPhase(e,r,n){let a=this.documentPhaseListeners.get(r).slice();for(let s of a)try{await s(e,n)}catch(l){if(!Vc(l))throw l}}async notifyBuildPhase(e,r,n){if(e.length===0)return;let a=this.buildPhaseListeners.get(r).slice();for(let s of a)await wi(n),await s(e,n)}shouldValidate(e){return!!this.getBuildOptions(e).validation}async validate(e,r){var n,i;let a=this.serviceRegistry.getServices(e.uri).validation.DocumentValidator,s=this.getBuildOptions(e).validation,l=typeof s=="object"?s:void 0,u=await a.validateDocument(e,l,r);e.diagnostics?e.diagnostics.push(...u):e.diagnostics=u;let h=this.buildState.get(e.uri.toString());if(h){(n=h.result)!==null&&n!==void 0||(h.result={});let f=(i=l?.categories)!==null&&i!==void 0?i:S1.all;h.result.validationChecks?h.result.validationChecks.push(...f):h.result.validationChecks=[...f]}}getBuildOptions(e){var r,n;return(n=(r=this.buildState.get(e.uri.toString()))===null||r===void 0?void 0:r.options)!==null&&n!==void 0?n:{}}}});var ob,II=N(()=>{"use strict";cs();HE();Ko();Gs();Uc();ob=class{static{o(this,"DefaultIndexManager")}constructor(e){this.symbolIndex=new Map,this.symbolByTypeIndex=new Dp,this.referenceIndex=new Map,this.documents=e.workspace.LangiumDocuments,this.serviceRegistry=e.ServiceRegistry,this.astReflection=e.AstReflection}findAllReferences(e,r){let n=$a(e).uri,i=[];return this.referenceIndex.forEach(a=>{a.forEach(s=>{gs.equals(s.targetUri,n)&&s.targetPath===r&&i.push(s)})}),en(i)}allElements(e,r){let n=en(this.symbolIndex.keys());return r&&(n=n.filter(i=>!r||r.has(i))),n.map(i=>this.getFileDescriptions(i,e)).flat()}getFileDescriptions(e,r){var n;return r?this.symbolByTypeIndex.get(e,r,()=>{var a;return((a=this.symbolIndex.get(e))!==null&&a!==void 0?a:[]).filter(l=>this.astReflection.isSubtype(l.type,r))}):(n=this.symbolIndex.get(e))!==null&&n!==void 0?n:[]}remove(e){let r=e.toString();this.symbolIndex.delete(r),this.symbolByTypeIndex.clear(r),this.referenceIndex.delete(r)}async updateContent(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).references.ScopeComputation.computeExports(e,r),a=e.uri.toString();this.symbolIndex.set(a,i),this.symbolByTypeIndex.clear(a)}async updateReferences(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).workspace.ReferenceDescriptionProvider.createDescriptions(e,r);this.referenceIndex.set(e.uri.toString(),i)}isAffected(e,r){let n=this.referenceIndex.get(e.uri.toString());return n?n.some(i=>!i.local&&r.has(i.targetUri.toString())):!1}}});var lb,OI=N(()=>{"use strict";Ko();Qo();Uc();lb=class{static{o(this,"DefaultWorkspaceManager")}constructor(e){this.initialBuildOptions={},this._ready=new ps,this.serviceRegistry=e.ServiceRegistry,this.langiumDocuments=e.workspace.LangiumDocuments,this.documentBuilder=e.workspace.DocumentBuilder,this.fileSystemProvider=e.workspace.FileSystemProvider,this.mutex=e.workspace.WorkspaceLock}get ready(){return this._ready.promise}get workspaceFolders(){return this.folders}initialize(e){var r;this.folders=(r=e.workspaceFolders)!==null&&r!==void 0?r:void 0}initialized(e){return this.mutex.write(r=>{var n;return this.initializeWorkspace((n=this.folders)!==null&&n!==void 0?n:[],r)})}async initializeWorkspace(e,r=yr.CancellationToken.None){let n=await this.performStartup(e);await wi(r),await this.documentBuilder.build(n,this.initialBuildOptions,r)}async performStartup(e){let r=this.serviceRegistry.all.flatMap(a=>a.LanguageMetaData.fileExtensions),n=[],i=o(a=>{n.push(a),this.langiumDocuments.hasDocument(a.uri)||this.langiumDocuments.addDocument(a)},"collector");return await this.loadAdditionalDocuments(e,i),await Promise.all(e.map(a=>[a,this.getRootFolder(a)]).map(async a=>this.traverseFolder(...a,r,i))),this._ready.resolve(),n}loadAdditionalDocuments(e,r){return Promise.resolve()}getRootFolder(e){return ms.parse(e.uri)}async traverseFolder(e,r,n,i){let a=await this.fileSystemProvider.readDirectory(r);await Promise.all(a.map(async s=>{if(this.includeEntry(e,s,n)){if(s.isDirectory)await this.traverseFolder(e,s.uri,n,i);else if(s.isFile){let l=await this.langiumDocuments.getOrCreateDocument(s.uri);i(l)}}}))}includeEntry(e,r,n){let i=gs.basename(r.uri);if(i.startsWith("."))return!1;if(r.isDirectory)return i!=="node_modules"&&i!=="out";if(r.isFile){let a=gs.extname(r.uri);return n.includes(a)}return!1}}});function jE(t){return Array.isArray(t)&&(t.length===0||"name"in t[0])}function BI(t){return t&&"modes"in t&&"defaultMode"in t}function PI(t){return!jE(t)&&!BI(t)}var cb,XE,Rp,KE=N(()=>{"use strict";mf();cb=class{static{o(this,"DefaultLexerErrorMessageProvider")}buildUnexpectedCharactersMessage(e,r,n,i,a){return Kg.buildUnexpectedCharactersMessage(e,r,n,i,a)}buildUnableToPopLexerModeMessage(e){return Kg.buildUnableToPopLexerModeMessage(e)}},XE={mode:"full"},Rp=class{static{o(this,"DefaultLexer")}constructor(e){this.errorMessageProvider=e.parser.LexerErrorMessageProvider,this.tokenBuilder=e.parser.TokenBuilder;let r=this.tokenBuilder.buildTokens(e.Grammar,{caseInsensitive:e.LanguageMetaData.caseInsensitive});this.tokenTypes=this.toTokenTypeDictionary(r);let n=PI(r)?Object.values(r):r,i=e.LanguageMetaData.mode==="production";this.chevrotainLexer=new Kn(n,{positionTracking:"full",skipValidations:i,errorMessageProvider:this.errorMessageProvider})}get definition(){return this.tokenTypes}tokenize(e,r=XE){var n,i,a;let s=this.chevrotainLexer.tokenize(e);return{tokens:s.tokens,errors:s.errors,hidden:(n=s.groups.hidden)!==null&&n!==void 0?n:[],report:(a=(i=this.tokenBuilder).flushLexingReport)===null||a===void 0?void 0:a.call(i,e)}}toTokenTypeDictionary(e){if(PI(e))return e;let r=BI(e)?Object.values(e.modes).flat():e,n={};return r.forEach(i=>n[i.name]=i),n}};o(jE,"isTokenTypeArray");o(BI,"isIMultiModeLexerDefinition");o(PI,"isTokenTypeDictionary")});function zI(t,e,r){let n,i;typeof t=="string"?(i=e,n=r):(i=t.range.start,n=e),i||(i=jr.create(0,0));let a=due(t),s=VI(n),l=X$e({lines:a,position:i,options:s});return J$e({index:0,tokens:l,position:i})}function GI(t,e){let r=VI(e),n=due(t);if(n.length===0)return!1;let i=n[0],a=n[n.length-1],s=r.start,l=r.end;return!!s?.exec(i)&&!!l?.exec(a)}function due(t){let e="";return typeof t=="string"?e=t:e=t.text,e.split(PN)}function X$e(t){var e,r,n;let i=[],a=t.position.line,s=t.position.character;for(let l=0;l=f.length){if(i.length>0){let m=jr.create(a,s);i.push({type:"break",content:"",range:Br.create(m,m)})}}else{hue.lastIndex=d;let m=hue.exec(f);if(m){let g=m[0],y=m[1],v=jr.create(a,s+d),x=jr.create(a,s+d+g.length);i.push({type:"tag",content:y,range:Br.create(v,x)}),d+=g.length,d=$I(f,d)}if(d0&&i[i.length-1].type==="break"?i.slice(0,-1):i}function j$e(t,e,r,n){let i=[];if(t.length===0){let a=jr.create(r,n),s=jr.create(r,n+e.length);i.push({type:"text",content:e,range:Br.create(a,s)})}else{let a=0;for(let l of t){let u=l.index,h=e.substring(a,u);h.length>0&&i.push({type:"text",content:e.substring(a,u),range:Br.create(jr.create(r,a+n),jr.create(r,u+n))});let f=h.length+1,d=l[1];if(i.push({type:"inline-tag",content:d,range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+d.length+n))}),f+=d.length,l.length===4){f+=l[2].length;let p=l[3];i.push({type:"text",content:p,range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+p.length+n))})}else i.push({type:"text",content:"",range:Br.create(jr.create(r,a+f+n),jr.create(r,a+f+n))});a=u+l[0].length}let s=e.substring(a);s.length>0&&i.push({type:"text",content:s,range:Br.create(jr.create(r,a+n),jr.create(r,a+n+s.length))})}return i}function $I(t,e){let r=t.substring(e).match(K$e);return r?e+r.index:t.length}function Z$e(t){let e=t.match(Q$e);if(e&&typeof e.index=="number")return e.index}function J$e(t){var e,r,n,i;let a=jr.create(t.position.line,t.position.character);if(t.tokens.length===0)return new QE([],Br.create(a,a));let s=[];for(;t.index0){let u=$I(e,a);s=e.substring(u),e=e.substring(0,a)}return(t==="linkcode"||t==="link"&&r.link==="code")&&(s=`\`${s}\``),(i=(n=r.renderLink)===null||n===void 0?void 0:n.call(r,e,s))!==null&&i!==void 0?i:ize(e,s)}}function ize(t,e){try{return ms.parse(t,!0),`[${e}](${t})`}catch{return t}}function fue(t){return t.endsWith(` -`)?` -`:` - -`}var hue,Y$e,K$e,Q$e,QE,ub,hb,ZE,UI=N(()=>{"use strict";ZM();$g();Uc();o(zI,"parseJSDoc");o(GI,"isJSDoc");o(due,"getLines");hue=/\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy,Y$e=/\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;o(X$e,"tokenize");o(j$e,"buildInlineTokens");K$e=/\S/,Q$e=/\s*$/;o($I,"skipWhitespace");o(Z$e,"lastCharacter");o(J$e,"parseJSDocComment");o(eze,"parseJSDocElement");o(tze,"appendEmptyLine");o(pue,"parseJSDocText");o(rze,"parseJSDocInline");o(mue,"parseJSDocTag");o(gue,"parseJSDocLine");o(VI,"normalizeOptions");o(FI,"normalizeOption");QE=class{static{o(this,"JSDocCommentImpl")}constructor(e,r){this.elements=e,this.range=r}getTag(e){return this.getAllTags().find(r=>r.name===e)}getTags(e){return this.getAllTags().filter(r=>r.name===e)}getAllTags(){return this.elements.filter(e=>"name"in e)}toString(){let e="";for(let r of this.elements)if(e.length===0)e=r.toString();else{let n=r.toString();e+=fue(e)+n}return e.trim()}toMarkdown(e){let r="";for(let n of this.elements)if(r.length===0)r=n.toMarkdown(e);else{let i=n.toMarkdown(e);r+=fue(r)+i}return r.trim()}},ub=class{static{o(this,"JSDocTagImpl")}constructor(e,r,n,i){this.name=e,this.content=r,this.inline=n,this.range=i}toString(){let e=`@${this.name}`,r=this.content.toString();return this.content.inlines.length===1?e=`${e} ${r}`:this.content.inlines.length>1&&(e=`${e} -${r}`),this.inline?`{${e}}`:e}toMarkdown(e){var r,n;return(n=(r=e?.renderTag)===null||r===void 0?void 0:r.call(e,this))!==null&&n!==void 0?n:this.toMarkdownDefault(e)}toMarkdownDefault(e){let r=this.content.toMarkdown(e);if(this.inline){let a=nze(this.name,r,e??{});if(typeof a=="string")return a}let n="";e?.tag==="italic"||e?.tag===void 0?n="*":e?.tag==="bold"?n="**":e?.tag==="bold-italic"&&(n="***");let i=`${n}@${this.name}${n}`;return this.content.inlines.length===1?i=`${i} \u2014 ${r}`:this.content.inlines.length>1&&(i=`${i} -${r}`),this.inline?`{${i}}`:i}};o(nze,"renderInlineTag");o(ize,"renderLinkDefault");hb=class{static{o(this,"JSDocTextImpl")}constructor(e,r){this.inlines=e,this.range=r}toString(){let e="";for(let r=0;rn.range.start.line&&(e+=` -`)}return e}toMarkdown(e){let r="";for(let n=0;ni.range.start.line&&(r+=` -`)}return r}},ZE=class{static{o(this,"JSDocLineImpl")}constructor(e,r){this.text=e,this.range=r}toString(){return this.text}toMarkdown(){return this.text}};o(fue,"fillNewlines")});var fb,HI=N(()=>{"use strict";cs();UI();fb=class{static{o(this,"JSDocDocumentationProvider")}constructor(e){this.indexManager=e.shared.workspace.IndexManager,this.commentProvider=e.documentation.CommentProvider}getDocumentation(e){let r=this.commentProvider.getComment(e);if(r&&GI(r))return zI(r).toMarkdown({renderLink:o((i,a)=>this.documentationLinkRenderer(e,i,a),"renderLink"),renderTag:o(i=>this.documentationTagRenderer(e,i),"renderTag")})}documentationLinkRenderer(e,r,n){var i;let a=(i=this.findNameInPrecomputedScopes(e,r))!==null&&i!==void 0?i:this.findNameInGlobalScope(e,r);if(a&&a.nameSegment){let s=a.nameSegment.range.start.line+1,l=a.nameSegment.range.start.character+1,u=a.documentUri.with({fragment:`L${s},${l}`});return`[${n}](${u.toString()})`}else return}documentationTagRenderer(e,r){}findNameInPrecomputedScopes(e,r){let i=$a(e).precomputedScopes;if(!i)return;let a=e;do{let l=i.get(a).find(u=>u.name===r);if(l)return l;a=a.$container}while(a)}findNameInGlobalScope(e,r){return this.indexManager.allElements().find(i=>i.name===r)}}});var db,WI=N(()=>{"use strict";WE();Ol();db=class{static{o(this,"DefaultCommentProvider")}constructor(e){this.grammarConfig=()=>e.parser.GrammarConfig}getComment(e){var r;return CI(e)?e.$comment:(r=uN(e.$cstNode,this.grammarConfig().multilineCommentRules))===null||r===void 0?void 0:r.text}}});var pb,qI,YI,XI=N(()=>{"use strict";Qo();YE();pb=class{static{o(this,"DefaultAsyncParser")}constructor(e){this.syncParser=e.parser.LangiumParser}parse(e,r){return Promise.resolve(this.syncParser.parse(e))}},qI=class{static{o(this,"AbstractThreadedAsyncParser")}constructor(e){this.threadCount=8,this.terminationDelay=200,this.workerPool=[],this.queue=[],this.hydrator=e.serializer.Hydrator}initializeWorkers(){for(;this.workerPool.length{if(this.queue.length>0){let r=this.queue.shift();r&&(e.lock(),r.resolve(e))}}),this.workerPool.push(e)}}async parse(e,r){let n=await this.acquireParserWorker(r),i=new ps,a,s=r.onCancellationRequested(()=>{a=setTimeout(()=>{this.terminateWorker(n)},this.terminationDelay)});return n.parse(e).then(l=>{let u=this.hydrator.hydrate(l);i.resolve(u)}).catch(l=>{i.reject(l)}).finally(()=>{s.dispose(),clearTimeout(a)}),i.promise}terminateWorker(e){e.terminate();let r=this.workerPool.indexOf(e);r>=0&&this.workerPool.splice(r,1)}async acquireParserWorker(e){this.initializeWorkers();for(let n of this.workerPool)if(n.ready)return n.lock(),n;let r=new ps;return e.onCancellationRequested(()=>{let n=this.queue.indexOf(r);n>=0&&this.queue.splice(n,1),r.reject(Gc)}),this.queue.push(r),r.promise}},YI=class{static{o(this,"ParserWorker")}get ready(){return this._ready}get onReady(){return this.onReadyEmitter.event}constructor(e,r,n,i){this.onReadyEmitter=new Zn.Emitter,this.deferred=new ps,this._ready=!0,this._parsing=!1,this.sendMessage=e,this._terminate=i,r(a=>{let s=a;this.deferred.resolve(s),this.unlock()}),n(a=>{this.deferred.reject(a),this.unlock()})}terminate(){this.deferred.reject(Gc),this._terminate()}lock(){this._ready=!1}unlock(){this._parsing=!1,this._ready=!0,this.onReadyEmitter.fire()}parse(e){if(this._parsing)throw new Error("Parser worker is busy");return this._parsing=!0,this.deferred=new ps,this.sendMessage(e),this.deferred.promise}}});var mb,jI=N(()=>{"use strict";Ko();Qo();mb=class{static{o(this,"DefaultWorkspaceLock")}constructor(){this.previousTokenSource=new yr.CancellationTokenSource,this.writeQueue=[],this.readQueue=[],this.done=!0}write(e){this.cancelWrite();let r=GE();return this.previousTokenSource=r,this.enqueue(this.writeQueue,e,r.token)}read(e){return this.enqueue(this.readQueue,e)}enqueue(e,r,n=yr.CancellationToken.None){let i=new ps,a={action:r,deferred:i,cancellationToken:n};return e.push(a),this.performNextOperation(),i.promise}async performNextOperation(){if(!this.done)return;let e=[];if(this.writeQueue.length>0)e.push(this.writeQueue.shift());else if(this.readQueue.length>0)e.push(...this.readQueue.splice(0,this.readQueue.length));else return;this.done=!1,await Promise.all(e.map(async({action:r,deferred:n,cancellationToken:i})=>{try{let a=await Promise.resolve().then(()=>r(i));n.resolve(a)}catch(a){Vc(a)?n.resolve(void 0):n.reject(a)}})),this.done=!0,this.performNextOperation()}cancelWrite(){this.previousTokenSource.cancel()}}});var gb,KI=N(()=>{"use strict";RE();Pc();Il();cs();T1();Ol();gb=class{static{o(this,"DefaultHydrator")}constructor(e){this.grammarElementIdMap=new _p,this.tokenTypeIdMap=new _p,this.grammar=e.Grammar,this.lexer=e.parser.Lexer,this.linker=e.references.Linker}dehydrate(e){return{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport?this.dehydrateLexerReport(e.lexerReport):void 0,parserErrors:e.parserErrors.map(r=>Object.assign(Object.assign({},r),{message:r.message})),value:this.dehydrateAstNode(e.value,this.createDehyrationContext(e.value))}}dehydrateLexerReport(e){return e}createDehyrationContext(e){let r=new Map,n=new Map;for(let i of jo(e))r.set(i,{});if(e.$cstNode)for(let i of sp(e.$cstNode))n.set(i,{});return{astNodes:r,cstNodes:n}}dehydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode!==void 0&&(n.$cstNode=this.dehydrateCstNode(e.$cstNode,r));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)si(l)?s.push(this.dehydrateAstNode(l,r)):ya(l)?s.push(this.dehydrateReference(l,r)):s.push(l)}else si(a)?n[i]=this.dehydrateAstNode(a,r):ya(a)?n[i]=this.dehydrateReference(a,r):a!==void 0&&(n[i]=a);return n}dehydrateReference(e,r){let n={};return n.$refText=e.$refText,e.$refNode&&(n.$refNode=r.cstNodes.get(e.$refNode)),n}dehydrateCstNode(e,r){let n=r.cstNodes.get(e);return U2(e)?n.fullText=e.fullText:n.grammarSource=this.getGrammarElementId(e.grammarSource),n.hidden=e.hidden,n.astNode=r.astNodes.get(e.astNode),Ml(e)?n.content=e.content.map(i=>this.dehydrateCstNode(i,r)):hf(e)&&(n.tokenType=e.tokenType.name,n.offset=e.offset,n.length=e.length,n.startLine=e.range.start.line,n.startColumn=e.range.start.character,n.endLine=e.range.end.line,n.endColumn=e.range.end.character),n}hydrate(e){let r=e.value,n=this.createHydrationContext(r);return"$cstNode"in r&&this.hydrateCstNode(r.$cstNode,n),{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport,parserErrors:e.parserErrors,value:this.hydrateAstNode(r,n)}}createHydrationContext(e){let r=new Map,n=new Map;for(let a of jo(e))r.set(a,{});let i;if(e.$cstNode)for(let a of sp(e.$cstNode)){let s;"fullText"in a?(s=new p1(a.fullText),i=s):"content"in a?s=new Sp:"tokenType"in a&&(s=this.hydrateCstLeafNode(a)),s&&(n.set(a,s),s.root=i)}return{astNodes:r,cstNodes:n}}hydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode&&(n.$cstNode=r.cstNodes.get(e.$cstNode));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)si(l)?s.push(this.setParent(this.hydrateAstNode(l,r),n)):ya(l)?s.push(this.hydrateReference(l,n,i,r)):s.push(l)}else si(a)?n[i]=this.setParent(this.hydrateAstNode(a,r),n):ya(a)?n[i]=this.hydrateReference(a,n,i,r):a!==void 0&&(n[i]=a);return n}setParent(e,r){return e.$container=r,e}hydrateReference(e,r,n,i){return this.linker.buildReference(r,n,i.cstNodes.get(e.$refNode),e.$refText)}hydrateCstNode(e,r,n=0){let i=r.cstNodes.get(e);if(typeof e.grammarSource=="number"&&(i.grammarSource=this.getGrammarElement(e.grammarSource)),i.astNode=r.astNodes.get(e.astNode),Ml(i))for(let a of e.content){let s=this.hydrateCstNode(a,r,n++);i.content.push(s)}return i}hydrateCstLeafNode(e){let r=this.getTokenType(e.tokenType),n=e.offset,i=e.length,a=e.startLine,s=e.startColumn,l=e.endLine,u=e.endColumn,h=e.hidden;return new Ep(n,i,{start:{line:a,character:s},end:{line:l,character:u}},r,h)}getTokenType(e){return this.lexer.definition[e]}getGrammarElementId(e){if(e)return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.get(e)}getGrammarElement(e){return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.getKey(e)}createGrammarElementIdMap(){let e=0;for(let r of jo(this.grammar))Q2(r)&&this.grammarElementIdMap.set(r,e++)}}});function va(t){return{documentation:{CommentProvider:o(e=>new db(e),"CommentProvider"),DocumentationProvider:o(e=>new fb(e),"DocumentationProvider")},parser:{AsyncParser:o(e=>new pb(e),"AsyncParser"),GrammarConfig:o(e=>QN(e),"GrammarConfig"),LangiumParser:o(e=>aI(e),"LangiumParser"),CompletionParser:o(e=>nI(e),"CompletionParser"),ValueConverter:o(()=>new Ap,"ValueConverter"),TokenBuilder:o(()=>new ju,"TokenBuilder"),Lexer:o(e=>new Rp(e),"Lexer"),ParserErrorMessageProvider:o(()=>new m1,"ParserErrorMessageProvider"),LexerErrorMessageProvider:o(()=>new cb,"LexerErrorMessageProvider")},workspace:{AstNodeLocator:o(()=>new ib,"AstNodeLocator"),AstNodeDescriptionProvider:o(e=>new rb(e),"AstNodeDescriptionProvider"),ReferenceDescriptionProvider:o(e=>new nb(e),"ReferenceDescriptionProvider")},references:{Linker:o(e=>new Hx(e),"Linker"),NameProvider:o(()=>new Wx,"NameProvider"),ScopeProvider:o(e=>new Kx(e),"ScopeProvider"),ScopeComputation:o(e=>new Yx(e),"ScopeComputation"),References:o(e=>new qx(e),"References")},serializer:{Hydrator:o(e=>new gb(e),"Hydrator"),JsonSerializer:o(e=>new Qx(e),"JsonSerializer")},validation:{DocumentValidator:o(e=>new tb(e),"DocumentValidator"),ValidationRegistry:o(e=>new Jx(e),"ValidationRegistry")},shared:o(()=>t.shared,"shared")}}function xa(t){return{ServiceRegistry:o(e=>new Zx(e),"ServiceRegistry"),workspace:{LangiumDocuments:o(e=>new Ux(e),"LangiumDocuments"),LangiumDocumentFactory:o(e=>new Vx(e),"LangiumDocumentFactory"),DocumentBuilder:o(e=>new sb(e),"DocumentBuilder"),IndexManager:o(e=>new ob(e),"IndexManager"),WorkspaceManager:o(e=>new lb(e),"WorkspaceManager"),FileSystemProvider:o(e=>t.fileSystemProvider(e),"FileSystemProvider"),WorkspaceLock:o(()=>new mb,"WorkspaceLock"),ConfigurationProvider:o(e=>new ab(e),"ConfigurationProvider")}}}var QI=N(()=>{"use strict";ZN();iI();sI();PE();oI();bI();TI();wI();kI();SI();WE();AI();_I();eb();DI();LI();RI();MI();b1();II();OI();KE();HI();WI();zx();XI();jI();KI();o(va,"createDefaultCoreModule");o(xa,"createDefaultSharedCoreModule")});function Gn(t,e,r,n,i,a,s,l,u){let h=[t,e,r,n,i,a,s,l,u].reduce(JE,{});return Tue(h)}function bue(t){if(t&&t[xue])for(let e of Object.values(t))bue(e);return t}function Tue(t,e){let r=new Proxy({},{deleteProperty:o(()=>!1,"deleteProperty"),set:o(()=>{throw new Error("Cannot set property on injected service container")},"set"),get:o((n,i)=>i===xue?!0:vue(n,i,t,e||r),"get"),getOwnPropertyDescriptor:o((n,i)=>(vue(n,i,t,e||r),Object.getOwnPropertyDescriptor(n,i)),"getOwnPropertyDescriptor"),has:o((n,i)=>i in t,"has"),ownKeys:o(()=>[...Object.getOwnPropertyNames(t)],"ownKeys")});return r}function vue(t,e,r,n){if(e in t){if(t[e]instanceof Error)throw new Error("Construction failure. Please make sure that your dependencies are constructable.",{cause:t[e]});if(t[e]===yue)throw new Error('Cycle detected. Please make "'+String(e)+'" lazy. Visit https://langium.org/docs/reference/configuration-services/#resolving-cyclic-dependencies');return t[e]}else if(e in r){let i=r[e];t[e]=yue;try{t[e]=typeof i=="function"?i(n):Tue(i,n)}catch(a){throw t[e]=a instanceof Error?a:void 0,a}return t[e]}else return}function JE(t,e){if(e){for(let[r,n]of Object.entries(e))if(n!==void 0){let i=t[r];i!==null&&n!==null&&typeof i=="object"&&typeof n=="object"?t[r]=JE(i,n):t[r]=n}}return t}var ZI,xue,yue,JI=N(()=>{"use strict";(function(t){t.merge=(e,r)=>JE(JE({},e),r)})(ZI||(ZI={}));o(Gn,"inject");xue=Symbol("isProxy");o(bue,"eagerLoad");o(Tue,"_inject");yue=Symbol();o(vue,"_resolve");o(JE,"_merge")});var wue=N(()=>{"use strict"});var kue=N(()=>{"use strict";WI();HI();UI()});var Eue=N(()=>{"use strict"});var Sue=N(()=>{"use strict";ZN();Eue()});var eO,Np,eS,tO,Cue=N(()=>{"use strict";mf();PE();KE();eO={indentTokenName:"INDENT",dedentTokenName:"DEDENT",whitespaceTokenName:"WS",ignoreIndentationDelimiters:[]};(function(t){t.REGULAR="indentation-sensitive",t.IGNORE_INDENTATION="ignore-indentation"})(Np||(Np={}));eS=class extends ju{static{o(this,"IndentationAwareTokenBuilder")}constructor(e=eO){super(),this.indentationStack=[0],this.whitespaceRegExp=/[ \t]+/y,this.options=Object.assign(Object.assign({},eO),e),this.indentTokenType=df({name:this.options.indentTokenName,pattern:this.indentMatcher.bind(this),line_breaks:!1}),this.dedentTokenType=df({name:this.options.dedentTokenName,pattern:this.dedentMatcher.bind(this),line_breaks:!1})}buildTokens(e,r){let n=super.buildTokens(e,r);if(!jE(n))throw new Error("Invalid tokens built by default builder");let{indentTokenName:i,dedentTokenName:a,whitespaceTokenName:s,ignoreIndentationDelimiters:l}=this.options,u,h,f,d=[];for(let p of n){for(let[m,g]of l)p.name===m?p.PUSH_MODE=Np.IGNORE_INDENTATION:p.name===g&&(p.POP_MODE=!0);p.name===a?u=p:p.name===i?h=p:p.name===s?f=p:d.push(p)}if(!u||!h||!f)throw new Error("Some indentation/whitespace tokens not found!");return l.length>0?{modes:{[Np.REGULAR]:[u,h,...d,f],[Np.IGNORE_INDENTATION]:[...d,f]},defaultMode:Np.REGULAR}:[u,h,f,...d]}flushLexingReport(e){let r=super.flushLexingReport(e);return Object.assign(Object.assign({},r),{remainingDedents:this.flushRemainingDedents(e)})}isStartOfLine(e,r){return r===0||`\r -`.includes(e[r-1])}matchWhitespace(e,r,n,i){var a;this.whitespaceRegExp.lastIndex=r;let s=this.whitespaceRegExp.exec(e);return{currIndentLevel:(a=s?.[0].length)!==null&&a!==void 0?a:0,prevIndentLevel:this.indentationStack.at(-1),match:s}}createIndentationTokenInstance(e,r,n,i){let a=this.getLineNumber(r,i);return Wu(e,n,i,i+n.length,a,a,1,n.length)}getLineNumber(e,r){return e.substring(0,r).split(/\r\n|\r|\n/).length}indentMatcher(e,r,n,i){if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:a,prevIndentLevel:s,match:l}=this.matchWhitespace(e,r,n,i);return a<=s?null:(this.indentationStack.push(a),l)}dedentMatcher(e,r,n,i){var a,s,l,u;if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:h,prevIndentLevel:f,match:d}=this.matchWhitespace(e,r,n,i);if(h>=f)return null;let p=this.indentationStack.lastIndexOf(h);if(p===-1)return this.diagnostics.push({severity:"error",message:`Invalid dedent level ${h} at offset: ${r}. Current indentation stack: ${this.indentationStack}`,offset:r,length:(s=(a=d?.[0])===null||a===void 0?void 0:a.length)!==null&&s!==void 0?s:0,line:this.getLineNumber(e,r),column:1}),null;let m=this.indentationStack.length-p-1,g=(u=(l=e.substring(0,r).match(/[\r\n]+$/))===null||l===void 0?void 0:l[0].length)!==null&&u!==void 0?u:1;for(let y=0;y1;)r.push(this.createIndentationTokenInstance(this.dedentTokenType,e,"",e.length)),this.indentationStack.pop();return this.indentationStack=[0],r}},tO=class extends Rp{static{o(this,"IndentationAwareLexer")}constructor(e){if(super(e),e.parser.TokenBuilder instanceof eS)this.indentationTokenBuilder=e.parser.TokenBuilder;else throw new Error("IndentationAwareLexer requires an accompanying IndentationAwareTokenBuilder")}tokenize(e,r=XE){let n=super.tokenize(e),i=n.report;r?.mode==="full"&&n.tokens.push(...i.remainingDedents),i.remainingDedents=[];let{indentTokenType:a,dedentTokenType:s}=this.indentationTokenBuilder,l=a.tokenTypeIdx,u=s.tokenTypeIdx,h=[],f=n.tokens.length-1;for(let d=0;d=0&&h.push(n.tokens[f]),n.tokens=h,n}}});var Aue=N(()=>{"use strict"});var _ue=N(()=>{"use strict";XI();iI();RE();Cue();sI();zx();KE();OE();Aue();PE();oI()});var Due=N(()=>{"use strict";bI();TI();wI();EI();kI();SI()});var Lue=N(()=>{"use strict";KI();WE()});var tS,ba,rO=N(()=>{"use strict";tS=class{static{o(this,"EmptyFileSystemProvider")}readFile(){throw new Error("No file system is available.")}async readDirectory(){return[]}},ba={fileSystemProvider:o(()=>new tS,"fileSystemProvider")}});function oze(){let t=Gn(xa(ba),sze),e=Gn(va({shared:t}),aze);return t.ServiceRegistry.register(e),e}function Hc(t){var e;let r=oze(),n=r.serializer.JsonSerializer.deserialize(t);return r.shared.workspace.LangiumDocumentFactory.fromModel(n,ms.parse(`memory://${(e=n.name)!==null&&e!==void 0?e:"grammar"}.langium`)),n}var aze,sze,Rue=N(()=>{"use strict";QI();JI();Pc();rO();Uc();aze={Grammar:o(()=>{},"Grammar"),LanguageMetaData:o(()=>({caseInsensitive:!1,fileExtensions:[".langium"],languageId:"langium"}),"LanguageMetaData")},sze={AstReflection:o(()=>new Og,"AstReflection")};o(oze,"createMinimalGrammarServices");o(Hc,"loadGrammarFromJson")});var Gr={};ur(Gr,{AstUtils:()=>Ik,BiMap:()=>_p,Cancellation:()=>yr,ContextCache:()=>Dp,CstUtils:()=>Ek,DONE_RESULT:()=>Ba,Deferred:()=>ps,Disposable:()=>vf,DisposableCache:()=>k1,DocumentCache:()=>UE,EMPTY_STREAM:()=>H2,ErrorWithLocation:()=>lp,GrammarUtils:()=>$k,MultiMap:()=>zl,OperationCancelled:()=>Gc,Reduction:()=>jm,RegExpUtils:()=>Bk,SimpleCache:()=>jx,StreamImpl:()=>co,TreeStreamImpl:()=>Mc,URI:()=>ms,UriUtils:()=>gs,WorkspaceCache:()=>E1,assertUnreachable:()=>Oc,delayNextTick:()=>gI,interruptAndCheck:()=>wi,isOperationCancelled:()=>Vc,loadGrammarFromJson:()=>Hc,setInterruptionPeriod:()=>tue,startCancelableOperation:()=>GE,stream:()=>en});var Nue=N(()=>{"use strict";HE();YE();Cr(Gr,Zn);T1();NI();Sk();Rue();Qo();Gs();Uc();cs();Ko();Ol();Fl();$g()});var Mue=N(()=>{"use strict";_I();eb()});var Iue=N(()=>{"use strict";DI();LI();RI();MI();b1();rO();II();jI();OI()});var Ta={};ur(Ta,{AbstractAstReflection:()=>ip,AbstractCstNode:()=>Px,AbstractLangiumParser:()=>Bx,AbstractParserErrorMessageProvider:()=>ME,AbstractThreadedAsyncParser:()=>qI,AstUtils:()=>Ik,BiMap:()=>_p,Cancellation:()=>yr,CompositeCstNodeImpl:()=>Sp,ContextCache:()=>Dp,CstNodeBuilder:()=>Ox,CstUtils:()=>Ek,DEFAULT_TOKENIZE_OPTIONS:()=>XE,DONE_RESULT:()=>Ba,DatatypeSymbol:()=>NE,DefaultAstNodeDescriptionProvider:()=>rb,DefaultAstNodeLocator:()=>ib,DefaultAsyncParser:()=>pb,DefaultCommentProvider:()=>db,DefaultConfigurationProvider:()=>ab,DefaultDocumentBuilder:()=>sb,DefaultDocumentValidator:()=>tb,DefaultHydrator:()=>gb,DefaultIndexManager:()=>ob,DefaultJsonSerializer:()=>Qx,DefaultLangiumDocumentFactory:()=>Vx,DefaultLangiumDocuments:()=>Ux,DefaultLexer:()=>Rp,DefaultLexerErrorMessageProvider:()=>cb,DefaultLinker:()=>Hx,DefaultNameProvider:()=>Wx,DefaultReferenceDescriptionProvider:()=>nb,DefaultReferences:()=>qx,DefaultScopeComputation:()=>Yx,DefaultScopeProvider:()=>Kx,DefaultServiceRegistry:()=>Zx,DefaultTokenBuilder:()=>ju,DefaultValueConverter:()=>Ap,DefaultWorkspaceLock:()=>mb,DefaultWorkspaceManager:()=>lb,Deferred:()=>ps,Disposable:()=>vf,DisposableCache:()=>k1,DocumentCache:()=>UE,DocumentState:()=>kn,DocumentValidator:()=>Zo,EMPTY_SCOPE:()=>q$e,EMPTY_STREAM:()=>H2,EmptyFileSystem:()=>ba,EmptyFileSystemProvider:()=>tS,ErrorWithLocation:()=>lp,GrammarAST:()=>J2,GrammarUtils:()=>$k,IndentationAwareLexer:()=>tO,IndentationAwareTokenBuilder:()=>eS,JSDocDocumentationProvider:()=>fb,LangiumCompletionParser:()=>$x,LangiumParser:()=>Fx,LangiumParserErrorMessageProvider:()=>m1,LeafCstNodeImpl:()=>Ep,LexingMode:()=>Np,MapScope:()=>Xx,Module:()=>ZI,MultiMap:()=>zl,OperationCancelled:()=>Gc,ParserWorker:()=>YI,Reduction:()=>jm,RegExpUtils:()=>Bk,RootCstNodeImpl:()=>p1,SimpleCache:()=>jx,StreamImpl:()=>co,StreamScope:()=>w1,TextDocument:()=>v1,TreeStreamImpl:()=>Mc,URI:()=>ms,UriUtils:()=>gs,ValidationCategory:()=>S1,ValidationRegistry:()=>Jx,ValueConverter:()=>zc,WorkspaceCache:()=>E1,assertUnreachable:()=>Oc,createCompletionParser:()=>nI,createDefaultCoreModule:()=>va,createDefaultSharedCoreModule:()=>xa,createGrammarConfig:()=>QN,createLangiumParser:()=>aI,createParser:()=>Gx,delayNextTick:()=>gI,diagnosticData:()=>Lp,eagerLoad:()=>bue,getDiagnosticRange:()=>cue,indentationBuilderDefaultOptions:()=>eO,inject:()=>Gn,interruptAndCheck:()=>wi,isAstNode:()=>si,isAstNodeDescription:()=>sN,isAstNodeWithComment:()=>CI,isCompositeCstNode:()=>Ml,isIMultiModeLexerDefinition:()=>BI,isJSDoc:()=>GI,isLeafCstNode:()=>hf,isLinkingError:()=>ap,isNamed:()=>oue,isOperationCancelled:()=>Vc,isReference:()=>ya,isRootCstNode:()=>U2,isTokenTypeArray:()=>jE,isTokenTypeDictionary:()=>PI,loadGrammarFromJson:()=>Hc,parseJSDoc:()=>zI,prepareLangiumParser:()=>Xce,setInterruptionPeriod:()=>tue,startCancelableOperation:()=>GE,stream:()=>en,toDiagnosticData:()=>uue,toDiagnosticSeverity:()=>qE});var po=N(()=>{"use strict";QI();JI();AI();wue();Il();kue();Sue();_ue();Due();Lue();Nue();Cr(Ta,Gr);Mue();Iue();Pc()});function Vue(t){return Gl.isInstance(t,yb)}function Uue(t){return Gl.isInstance(t,C1)}function Hue(t){return Gl.isInstance(t,A1)}function Wue(t){return Gl.isInstance(t,_1)}function que(t){return Gl.isInstance(t,vb)}function Yue(t){return Gl.isInstance(t,D1)}function Xue(t){return Gl.isInstance(t,xb)}function jue(t){return Gl.isInstance(t,bb)}function Kue(t){return Gl.isInstance(t,Tb)}function Que(t){return Gl.isInstance(t,wb)}function Zue(t){return Gl.isInstance(t,kb)}var lze,xt,fO,yb,rS,C1,nS,iS,nO,A1,iO,aO,sO,_1,oO,vb,aS,lO,D1,cO,xb,bb,Tb,wb,cS,uO,kb,hO,sS,oS,lS,Jue,Gl,Oue,cze,Pue,uze,Bue,hze,Fue,fze,$ue,dze,zue,pze,Gue,mze,gze,yze,vze,xze,bze,Tze,wze,ys,dO,pO,mO,gO,yO,vO,xO,kze,Eze,Sze,Cze,xf,Ku,Ga,Aze,Va=N(()=>{"use strict";po();po();po();po();lze=Object.defineProperty,xt=o((t,e)=>lze(t,"name",{value:e,configurable:!0}),"__name"),fO="Statement",yb="Architecture";o(Vue,"isArchitecture");xt(Vue,"isArchitecture");rS="Axis",C1="Branch";o(Uue,"isBranch");xt(Uue,"isBranch");nS="Checkout",iS="CherryPicking",nO="ClassDefStatement",A1="Commit";o(Hue,"isCommit");xt(Hue,"isCommit");iO="Curve",aO="Edge",sO="Entry",_1="GitGraph";o(Wue,"isGitGraph");xt(Wue,"isGitGraph");oO="Group",vb="Info";o(que,"isInfo");xt(que,"isInfo");aS="Item",lO="Junction",D1="Merge";o(Yue,"isMerge");xt(Yue,"isMerge");cO="Option",xb="Packet";o(Xue,"isPacket");xt(Xue,"isPacket");bb="PacketBlock";o(jue,"isPacketBlock");xt(jue,"isPacketBlock");Tb="Pie";o(Kue,"isPie");xt(Kue,"isPie");wb="PieSection";o(Que,"isPieSection");xt(Que,"isPieSection");cS="Radar",uO="Service",kb="Treemap";o(Zue,"isTreemap");xt(Zue,"isTreemap");hO="TreemapRow",sS="Direction",oS="Leaf",lS="Section",Jue=class extends ip{static{o(this,"MermaidAstReflection")}static{xt(this,"MermaidAstReflection")}getAllTypes(){return[yb,rS,C1,nS,iS,nO,A1,iO,sS,aO,sO,_1,oO,vb,aS,lO,oS,D1,cO,xb,bb,Tb,wb,cS,lS,uO,fO,kb,hO]}computeIsSubtype(t,e){switch(t){case C1:case nS:case iS:case A1:case D1:return this.isSubtype(fO,e);case sS:return this.isSubtype(_1,e);case oS:case lS:return this.isSubtype(aS,e);default:return!1}}getReferenceType(t){let e=`${t.container.$type}:${t.property}`;switch(e){case"Entry:axis":return rS;default:throw new Error(`${e} is not a valid reference id.`)}}getTypeMetaData(t){switch(t){case yb:return{name:yb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"edges",defaultValue:[]},{name:"groups",defaultValue:[]},{name:"junctions",defaultValue:[]},{name:"services",defaultValue:[]},{name:"title"}]};case rS:return{name:rS,properties:[{name:"label"},{name:"name"}]};case C1:return{name:C1,properties:[{name:"name"},{name:"order"}]};case nS:return{name:nS,properties:[{name:"branch"}]};case iS:return{name:iS,properties:[{name:"id"},{name:"parent"},{name:"tags",defaultValue:[]}]};case nO:return{name:nO,properties:[{name:"className"},{name:"styleText"}]};case A1:return{name:A1,properties:[{name:"id"},{name:"message"},{name:"tags",defaultValue:[]},{name:"type"}]};case iO:return{name:iO,properties:[{name:"entries",defaultValue:[]},{name:"label"},{name:"name"}]};case aO:return{name:aO,properties:[{name:"lhsDir"},{name:"lhsGroup",defaultValue:!1},{name:"lhsId"},{name:"lhsInto",defaultValue:!1},{name:"rhsDir"},{name:"rhsGroup",defaultValue:!1},{name:"rhsId"},{name:"rhsInto",defaultValue:!1},{name:"title"}]};case sO:return{name:sO,properties:[{name:"axis"},{name:"value"}]};case _1:return{name:_1,properties:[{name:"accDescr"},{name:"accTitle"},{name:"statements",defaultValue:[]},{name:"title"}]};case oO:return{name:oO,properties:[{name:"icon"},{name:"id"},{name:"in"},{name:"title"}]};case vb:return{name:vb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case aS:return{name:aS,properties:[{name:"classSelector"},{name:"name"}]};case lO:return{name:lO,properties:[{name:"id"},{name:"in"}]};case D1:return{name:D1,properties:[{name:"branch"},{name:"id"},{name:"tags",defaultValue:[]},{name:"type"}]};case cO:return{name:cO,properties:[{name:"name"},{name:"value",defaultValue:!1}]};case xb:return{name:xb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"blocks",defaultValue:[]},{name:"title"}]};case bb:return{name:bb,properties:[{name:"bits"},{name:"end"},{name:"label"},{name:"start"}]};case Tb:return{name:Tb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"sections",defaultValue:[]},{name:"showData",defaultValue:!1},{name:"title"}]};case wb:return{name:wb,properties:[{name:"label"},{name:"value"}]};case cS:return{name:cS,properties:[{name:"accDescr"},{name:"accTitle"},{name:"axes",defaultValue:[]},{name:"curves",defaultValue:[]},{name:"options",defaultValue:[]},{name:"title"}]};case uO:return{name:uO,properties:[{name:"icon"},{name:"iconText"},{name:"id"},{name:"in"},{name:"title"}]};case kb:return{name:kb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"},{name:"TreemapRows",defaultValue:[]}]};case hO:return{name:hO,properties:[{name:"indent"},{name:"item"}]};case sS:return{name:sS,properties:[{name:"accDescr"},{name:"accTitle"},{name:"dir"},{name:"statements",defaultValue:[]},{name:"title"}]};case oS:return{name:oS,properties:[{name:"classSelector"},{name:"name"},{name:"value"}]};case lS:return{name:lS,properties:[{name:"classSelector"},{name:"name"}]};default:return{name:t,properties:[]}}}},Gl=new Jue,cze=xt(()=>Oue??(Oue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Info","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Info","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"info"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"Keyword","value":"showInfo"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@7"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"InfoGrammar"),uze=xt(()=>Pue??(Pue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Packet","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Packet","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"packet"},{"$type":"Keyword","value":"packet-beta"}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PacketBlock","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"start","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"end","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}],"cardinality":"?"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"+"},{"$type":"Assignment","feature":"bits","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]}]},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@9"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"PacketGrammar"),hze=xt(()=>Bue??(Bue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Pie","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Pie","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"pie"},{"$type":"Assignment","feature":"showData","operator":"?=","terminal":{"$type":"Keyword","value":"showData"},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PieSection","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@9"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"PieGrammar"),fze=xt(()=>Fue??(Fue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Architecture","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Architecture","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"architecture-beta"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"groups","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"services","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"junctions","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"edges","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"LeftPort","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"lhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"RightPort","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"rhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Keyword","value":":"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Arrow","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Assignment","feature":"lhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"--"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]}},{"$type":"Keyword","value":"-"}]}]},{"$type":"Assignment","feature":"rhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Group","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Service","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"service"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"iconText","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]}}],"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Junction","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"junction"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Edge","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"lhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"lhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"rhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"rhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"ARROW_DIRECTION","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"L"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"R"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"T"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"B"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_GROUP","definition":{"$type":"RegexToken","regex":"/\\\\{group\\\\}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_INTO","definition":{"$type":"RegexToken","regex":"/<|>/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@18"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@19"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"ARCH_ICON","definition":{"$type":"RegexToken","regex":"/\\\\([\\\\w-:]+\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TITLE","definition":{"$type":"RegexToken","regex":"/\\\\[[\\\\w ]+\\\\]/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"ArchitectureGrammar"),dze=xt(()=>$ue??($ue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"GitGraph","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"GitGraph","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Keyword","value":":"}]},{"$type":"Keyword","value":"gitGraph:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Keyword","value":":"}]}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"Assignment","feature":"statements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Direction","definition":{"$type":"Assignment","feature":"dir","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"LR"},{"$type":"Keyword","value":"TB"},{"$type":"Keyword","value":"BT"}]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Commit","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"commit"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"msg:","cardinality":"?"},{"$type":"Assignment","feature":"message","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Branch","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"branch"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"order:"},{"$type":"Assignment","feature":"order","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Merge","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"merge"},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Checkout","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"checkout"},{"$type":"Keyword","value":"switch"}]},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CherryPicking","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"cherry-pick"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"parent:"},{"$type":"Assignment","feature":"parent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@14"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"REFERENCE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\\\w([-\\\\./\\\\w]*[-\\\\w])?/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}`)),"GitGraphGrammar"),pze=xt(()=>zue??(zue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Radar","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Radar","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":"radar-beta:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Keyword","value":"axis"},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"curve"},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Label","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"["},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}},{"$type":"Keyword","value":"]"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Axis","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Curve","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Entries","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DetailedEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"axis","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@2"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NumberEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Option","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"showLegend"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"ticks"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"max"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"min"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"graticule"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"GRATICULE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"circle"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"polygon"}}]},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@16"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'([^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"interfaces":[{"$type":"Interface","name":"Entry","attributes":[{"$type":"TypeAttribute","name":"axis","isOptional":true,"type":{"$type":"ReferenceType","referenceType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@2"}}}},{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"types":[],"usedGrammars":[]}`)),"RadarGrammar"),mze=xt(()=>Gue??(Gue=Hc(`{"$type":"Grammar","isDeclared":true,"name":"Treemap","rules":[{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"ParserRule","entry":true,"name":"Treemap","returnType":{"$ref":"#/interfaces@4"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Assignment","feature":"TreemapRows","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"TREEMAP_KEYWORD","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap-beta"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"CLASS_DEF","definition":{"$type":"RegexToken","regex":"/classDef\\\\s+([a-zA-Z_][a-zA-Z0-9_]+)(?:\\\\s+([^;\\\\r\\\\n]*))?(?:;)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STYLE_SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":::"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"COMMA","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":","}},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WS","definition":{"$type":"RegexToken","regex":"/[ \\\\t]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"ML_COMMENT","definition":{"$type":"RegexToken","regex":"/\\\\%\\\\%[^\\\\n]*/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"NL","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false},{"$type":"ParserRule","name":"TreemapRow","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"indent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"item","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ClassDef","dataType":"string","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Item","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Section","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Leaf","returnType":{"$ref":"#/interfaces@2"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INDENTATION","definition":{"$type":"RegexToken","regex":"/[ \\\\t]{1,}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID2","definition":{"$type":"RegexToken","regex":"/[a-zA-Z_][a-zA-Z0-9_]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER2","definition":{"$type":"RegexToken","regex":"/[0-9_\\\\.\\\\,]+/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"MyNumber","dataType":"number","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"STRING2","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|'[^']*'/"},"fragment":false,"hidden":false}],"interfaces":[{"$type":"Interface","name":"Item","attributes":[{"$type":"TypeAttribute","name":"name","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"classSelector","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]},{"$type":"Interface","name":"Section","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[]},{"$type":"Interface","name":"Leaf","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}]},{"$type":"Interface","name":"ClassDefStatement","attributes":[{"$type":"TypeAttribute","name":"className","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"styleText","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false}],"superTypes":[]},{"$type":"Interface","name":"Treemap","attributes":[{"$type":"TypeAttribute","name":"TreemapRows","type":{"$type":"ArrayType","elementType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@14"}}},"isOptional":false},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[],"$comment":"/**\\n * Treemap grammar for Langium\\n * Converted from mindmap grammar\\n *\\n * The ML_COMMENT and NL hidden terminals handle whitespace, comments, and newlines\\n * before the treemap keyword, allowing for empty lines and comments before the\\n * treemap declaration.\\n */"}`)),"TreemapGrammar"),gze={languageId:"info",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},yze={languageId:"packet",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},vze={languageId:"pie",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},xze={languageId:"architecture",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},bze={languageId:"gitGraph",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},Tze={languageId:"radar",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},wze={languageId:"treemap",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},ys={AstReflection:xt(()=>new Jue,"AstReflection")},dO={Grammar:xt(()=>cze(),"Grammar"),LanguageMetaData:xt(()=>gze,"LanguageMetaData"),parser:{}},pO={Grammar:xt(()=>uze(),"Grammar"),LanguageMetaData:xt(()=>yze,"LanguageMetaData"),parser:{}},mO={Grammar:xt(()=>hze(),"Grammar"),LanguageMetaData:xt(()=>vze,"LanguageMetaData"),parser:{}},gO={Grammar:xt(()=>fze(),"Grammar"),LanguageMetaData:xt(()=>xze,"LanguageMetaData"),parser:{}},yO={Grammar:xt(()=>dze(),"Grammar"),LanguageMetaData:xt(()=>bze,"LanguageMetaData"),parser:{}},vO={Grammar:xt(()=>pze(),"Grammar"),LanguageMetaData:xt(()=>Tze,"LanguageMetaData"),parser:{}},xO={Grammar:xt(()=>mze(),"Grammar"),LanguageMetaData:xt(()=>wze,"LanguageMetaData"),parser:{}},kze=/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,Eze=/accTitle[\t ]*:([^\n\r]*)/,Sze=/title([\t ][^\n\r]*|)/,Cze={ACC_DESCR:kze,ACC_TITLE:Eze,TITLE:Sze},xf=class extends Ap{static{o(this,"AbstractMermaidValueConverter")}static{xt(this,"AbstractMermaidValueConverter")}runConverter(t,e,r){let n=this.runCommonConverter(t,e,r);return n===void 0&&(n=this.runCustomConverter(t,e,r)),n===void 0?super.runConverter(t,e,r):n}runCommonConverter(t,e,r){let n=Cze[t.name];if(n===void 0)return;let i=n.exec(e);if(i!==null){if(i[1]!==void 0)return i[1].trim().replace(/[\t ]{2,}/gm," ");if(i[2]!==void 0)return i[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,` -`)}}},Ku=class extends xf{static{o(this,"CommonValueConverter")}static{xt(this,"CommonValueConverter")}runCustomConverter(t,e,r){}},Ga=class extends ju{static{o(this,"AbstractMermaidTokenBuilder")}static{xt(this,"AbstractMermaidTokenBuilder")}constructor(t){super(),this.keywords=new Set(t)}buildKeywordTokens(t,e,r){let n=super.buildKeywordTokens(t,e,r);return n.forEach(i=>{this.keywords.has(i.name)&&i.PATTERN!==void 0&&(i.PATTERN=new RegExp(i.PATTERN.toString()+"(?:(?=%%)|(?!\\S))"))}),n}},Aze=class extends Ga{static{o(this,"CommonTokenBuilder")}static{xt(this,"CommonTokenBuilder")}}});function hS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),yO,uS);return e.ServiceRegistry.register(r),{shared:e,GitGraph:r}}var _ze,uS,bO=N(()=>{"use strict";Va();po();_ze=class extends Ga{static{o(this,"GitGraphTokenBuilder")}static{xt(this,"GitGraphTokenBuilder")}constructor(){super(["gitGraph"])}},uS={parser:{TokenBuilder:xt(()=>new _ze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(hS,"createGitGraphServices");xt(hS,"createGitGraphServices")});function dS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),dO,fS);return e.ServiceRegistry.register(r),{shared:e,Info:r}}var Dze,fS,TO=N(()=>{"use strict";Va();po();Dze=class extends Ga{static{o(this,"InfoTokenBuilder")}static{xt(this,"InfoTokenBuilder")}constructor(){super(["info","showInfo"])}},fS={parser:{TokenBuilder:xt(()=>new Dze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(dS,"createInfoServices");xt(dS,"createInfoServices")});function mS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),pO,pS);return e.ServiceRegistry.register(r),{shared:e,Packet:r}}var Lze,pS,wO=N(()=>{"use strict";Va();po();Lze=class extends Ga{static{o(this,"PacketTokenBuilder")}static{xt(this,"PacketTokenBuilder")}constructor(){super(["packet"])}},pS={parser:{TokenBuilder:xt(()=>new Lze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(mS,"createPacketServices");xt(mS,"createPacketServices")});function yS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),mO,gS);return e.ServiceRegistry.register(r),{shared:e,Pie:r}}var Rze,Nze,gS,kO=N(()=>{"use strict";Va();po();Rze=class extends Ga{static{o(this,"PieTokenBuilder")}static{xt(this,"PieTokenBuilder")}constructor(){super(["pie","showData"])}},Nze=class extends xf{static{o(this,"PieValueConverter")}static{xt(this,"PieValueConverter")}runCustomConverter(t,e,r){if(t.name==="PIE_SECTION_LABEL")return e.replace(/"/g,"").trim()}},gS={parser:{TokenBuilder:xt(()=>new Rze,"TokenBuilder"),ValueConverter:xt(()=>new Nze,"ValueConverter")}};o(yS,"createPieServices");xt(yS,"createPieServices")});function xS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),gO,vS);return e.ServiceRegistry.register(r),{shared:e,Architecture:r}}var Mze,Ize,vS,EO=N(()=>{"use strict";Va();po();Mze=class extends Ga{static{o(this,"ArchitectureTokenBuilder")}static{xt(this,"ArchitectureTokenBuilder")}constructor(){super(["architecture"])}},Ize=class extends xf{static{o(this,"ArchitectureValueConverter")}static{xt(this,"ArchitectureValueConverter")}runCustomConverter(t,e,r){if(t.name==="ARCH_ICON")return e.replace(/[()]/g,"").trim();if(t.name==="ARCH_TEXT_ICON")return e.replace(/["()]/g,"");if(t.name==="ARCH_TITLE")return e.replace(/[[\]]/g,"").trim()}},vS={parser:{TokenBuilder:xt(()=>new Mze,"TokenBuilder"),ValueConverter:xt(()=>new Ize,"ValueConverter")}};o(xS,"createArchitectureServices");xt(xS,"createArchitectureServices")});function TS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),vO,bS);return e.ServiceRegistry.register(r),{shared:e,Radar:r}}var Oze,bS,SO=N(()=>{"use strict";Va();po();Oze=class extends Ga{static{o(this,"RadarTokenBuilder")}static{xt(this,"RadarTokenBuilder")}constructor(){super(["radar-beta"])}},bS={parser:{TokenBuilder:xt(()=>new Oze,"TokenBuilder"),ValueConverter:xt(()=>new Ku,"ValueConverter")}};o(TS,"createRadarServices");xt(TS,"createRadarServices")});function ehe(t){let e=t.validation.TreemapValidator,r=t.validation.ValidationRegistry;if(r){let n={Treemap:e.checkSingleRoot.bind(e)};r.register(n,e)}}function kS(t=ba){let e=Gn(xa(t),ys),r=Gn(va({shared:e}),xO,wS);return e.ServiceRegistry.register(r),ehe(r),{shared:e,Treemap:r}}var Pze,Bze,Fze,$ze,wS,CO=N(()=>{"use strict";Va();po();Pze=class extends Ga{static{o(this,"TreemapTokenBuilder")}static{xt(this,"TreemapTokenBuilder")}constructor(){super(["treemap"])}},Bze=/classDef\s+([A-Z_a-z]\w+)(?:\s+([^\n\r;]*))?;?/,Fze=class extends xf{static{o(this,"TreemapValueConverter")}static{xt(this,"TreemapValueConverter")}runCustomConverter(t,e,r){if(t.name==="NUMBER2")return parseFloat(e.replace(/,/g,""));if(t.name==="SEPARATOR")return e.substring(1,e.length-1);if(t.name==="STRING2")return e.substring(1,e.length-1);if(t.name==="INDENTATION")return e.length;if(t.name==="ClassDef"){if(typeof e!="string")return e;let n=Bze.exec(e);if(n)return{$type:"ClassDefStatement",className:n[1],styleText:n[2]||void 0}}}};o(ehe,"registerValidationChecks");xt(ehe,"registerValidationChecks");$ze=class{static{o(this,"TreemapValidator")}static{xt(this,"TreemapValidator")}checkSingleRoot(t,e){let r;for(let n of t.TreemapRows)n.item&&(r===void 0&&n.indent===void 0?r=0:n.indent===void 0?e("error","Multiple root nodes are not allowed in a treemap.",{node:n,property:"item"}):r!==void 0&&r>=parseInt(n.indent,10)&&e("error","Multiple root nodes are not allowed in a treemap.",{node:n,property:"item"}))}},wS={parser:{TokenBuilder:xt(()=>new Pze,"TokenBuilder"),ValueConverter:xt(()=>new Fze,"ValueConverter")},validation:{TreemapValidator:xt(()=>new $ze,"TreemapValidator")}};o(kS,"createTreemapServices");xt(kS,"createTreemapServices")});var the={};ur(the,{InfoModule:()=>fS,createInfoServices:()=>dS});var rhe=N(()=>{"use strict";TO();Va()});var nhe={};ur(nhe,{PacketModule:()=>pS,createPacketServices:()=>mS});var ihe=N(()=>{"use strict";wO();Va()});var ahe={};ur(ahe,{PieModule:()=>gS,createPieServices:()=>yS});var she=N(()=>{"use strict";kO();Va()});var ohe={};ur(ohe,{ArchitectureModule:()=>vS,createArchitectureServices:()=>xS});var lhe=N(()=>{"use strict";EO();Va()});var che={};ur(che,{GitGraphModule:()=>uS,createGitGraphServices:()=>hS});var uhe=N(()=>{"use strict";bO();Va()});var hhe={};ur(hhe,{RadarModule:()=>bS,createRadarServices:()=>TS});var fhe=N(()=>{"use strict";SO();Va()});var dhe={};ur(dhe,{TreemapModule:()=>wS,createTreemapServices:()=>kS});var phe=N(()=>{"use strict";CO();Va()});async function vs(t,e){let r=zze[t];if(!r)throw new Error(`Unknown diagram type: ${t}`);Qu[t]||await r();let i=Qu[t].parse(e);if(i.lexerErrors.length>0||i.parserErrors.length>0)throw new Gze(i);return i.value}var Qu,zze,Gze,bf=N(()=>{"use strict";bO();TO();wO();kO();EO();SO();CO();Va();Qu={},zze={info:xt(async()=>{let{createInfoServices:t}=await Promise.resolve().then(()=>(rhe(),the)),e=t().Info.parser.LangiumParser;Qu.info=e},"info"),packet:xt(async()=>{let{createPacketServices:t}=await Promise.resolve().then(()=>(ihe(),nhe)),e=t().Packet.parser.LangiumParser;Qu.packet=e},"packet"),pie:xt(async()=>{let{createPieServices:t}=await Promise.resolve().then(()=>(she(),ahe)),e=t().Pie.parser.LangiumParser;Qu.pie=e},"pie"),architecture:xt(async()=>{let{createArchitectureServices:t}=await Promise.resolve().then(()=>(lhe(),ohe)),e=t().Architecture.parser.LangiumParser;Qu.architecture=e},"architecture"),gitGraph:xt(async()=>{let{createGitGraphServices:t}=await Promise.resolve().then(()=>(uhe(),che)),e=t().GitGraph.parser.LangiumParser;Qu.gitGraph=e},"gitGraph"),radar:xt(async()=>{let{createRadarServices:t}=await Promise.resolve().then(()=>(fhe(),hhe)),e=t().Radar.parser.LangiumParser;Qu.radar=e},"radar"),treemap:xt(async()=>{let{createTreemapServices:t}=await Promise.resolve().then(()=>(phe(),dhe)),e=t().Treemap.parser.LangiumParser;Qu.treemap=e},"treemap")};o(vs,"parse");xt(vs,"parse");Gze=class extends Error{static{o(this,"MermaidParseError")}constructor(t){let e=t.lexerErrors.map(n=>n.message).join(` -`),r=t.parserErrors.map(n=>n.message).join(` -`);super(`Parsing failed: ${e} ${r}`),this.result=t}static{xt(this,"MermaidParseError")}}});function Jo(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}var Mp=N(()=>{"use strict";o(Jo,"populateCommonDb")});var Kr,ES=N(()=>{"use strict";Kr={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4}});var Tf,SS=N(()=>{"use strict";Tf=class{constructor(e){this.init=e;this.records=this.init()}static{o(this,"ImperativeState")}reset(){this.records=this.init()}}});function AO(){return R9({length:7})}function Uze(t,e){let r=Object.create(null);return t.reduce((n,i)=>{let a=e(i);return r[a]||(r[a]=!0,n.push(i)),n},[])}function mhe(t,e,r){let n=t.indexOf(e);n===-1?t.push(r):t.splice(n,1,r)}function yhe(t){let e=t.reduce((i,a)=>i.seq>a.seq?i:a,t[0]),r="";t.forEach(function(i){i===e?r+=" *":r+=" |"});let n=[r,e.id,e.seq];for(let i in At.records.branches)At.records.branches.get(i)===e.id&&n.push(i);if(X.debug(n.join(" ")),e.parents&&e.parents.length==2&&e.parents[0]&&e.parents[1]){let i=At.records.commits.get(e.parents[0]);mhe(t,e,i),e.parents[1]&&t.push(At.records.commits.get(e.parents[1]))}else{if(e.parents.length==0)return;if(e.parents[0]){let i=At.records.commits.get(e.parents[0]);mhe(t,e,i)}}t=Uze(t,i=>i.id),yhe(t)}var Vze,Ip,At,Hze,Wze,qze,Yze,Xze,jze,Kze,ghe,Qze,Zze,Jze,eGe,tGe,vhe,rGe,nGe,iGe,CS,_O=N(()=>{"use strict";yt();er();mi();pr();ci();ES();SS();_a();Vze=or.gitGraph,Ip=o(()=>$n({...Vze,...tr().gitGraph}),"getConfig"),At=new Tf(()=>{let t=Ip(),e=t.mainBranchName,r=t.mainBranchOrder;return{mainBranchName:e,commits:new Map,head:null,branchConfig:new Map([[e,{name:e,order:r}]]),branches:new Map([[e,null]]),currBranch:e,direction:"LR",seq:0,options:{}}});o(AO,"getID");o(Uze,"uniqBy");Hze=o(function(t){At.records.direction=t},"setDirection"),Wze=o(function(t){X.debug("options str",t),t=t?.trim(),t=t||"{}";try{At.records.options=JSON.parse(t)}catch(e){X.error("error while parsing gitGraph options",e.message)}},"setOptions"),qze=o(function(){return At.records.options},"getOptions"),Yze=o(function(t){let e=t.msg,r=t.id,n=t.type,i=t.tags;X.info("commit",e,r,n,i),X.debug("Entering commit:",e,r,n,i);let a=Ip();r=Ze.sanitizeText(r,a),e=Ze.sanitizeText(e,a),i=i?.map(l=>Ze.sanitizeText(l,a));let s={id:r||At.records.seq+"-"+AO(),message:e,seq:At.records.seq++,type:n??Kr.NORMAL,tags:i??[],parents:At.records.head==null?[]:[At.records.head.id],branch:At.records.currBranch};At.records.head=s,X.info("main branch",a.mainBranchName),At.records.commits.has(s.id)&&X.warn(`Commit ID ${s.id} already exists`),At.records.commits.set(s.id,s),At.records.branches.set(At.records.currBranch,s.id),X.debug("in pushCommit "+s.id)},"commit"),Xze=o(function(t){let e=t.name,r=t.order;if(e=Ze.sanitizeText(e,Ip()),At.records.branches.has(e))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${e}")`);At.records.branches.set(e,At.records.head!=null?At.records.head.id:null),At.records.branchConfig.set(e,{name:e,order:r}),ghe(e),X.debug("in createBranch")},"branch"),jze=o(t=>{let e=t.branch,r=t.id,n=t.type,i=t.tags,a=Ip();e=Ze.sanitizeText(e,a),r&&(r=Ze.sanitizeText(r,a));let s=At.records.branches.get(At.records.currBranch),l=At.records.branches.get(e),u=s?At.records.commits.get(s):void 0,h=l?At.records.commits.get(l):void 0;if(u&&h&&u.branch===e)throw new Error(`Cannot merge branch '${e}' into itself.`);if(At.records.currBranch===e){let p=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(u===void 0||!u){let p=new Error(`Incorrect usage of "merge". Current branch (${At.records.currBranch})has no commits`);throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["commit"]},p}if(!At.records.branches.has(e)){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") does not exist");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:[`branch ${e}`]},p}if(h===void 0||!h){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") has no commits");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:['"commit"']},p}if(u===h){let p=new Error('Incorrect usage of "merge". Both branches have same head');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(r&&At.records.commits.has(r)){let p=new Error('Incorrect usage of "merge". Commit with id:'+r+" already exists, use different custom id");throw p.hash={text:`merge ${e} ${r} ${n} ${i?.join(" ")}`,token:`merge ${e} ${r} ${n} ${i?.join(" ")}`,expected:[`merge ${e} ${r}_UNIQUE ${n} ${i?.join(" ")}`]},p}let f=l||"",d={id:r||`${At.records.seq}-${AO()}`,message:`merged branch ${e} into ${At.records.currBranch}`,seq:At.records.seq++,parents:At.records.head==null?[]:[At.records.head.id,f],branch:At.records.currBranch,type:Kr.MERGE,customType:n,customId:!!r,tags:i??[]};At.records.head=d,At.records.commits.set(d.id,d),At.records.branches.set(At.records.currBranch,d.id),X.debug(At.records.branches),X.debug("in mergeBranch")},"merge"),Kze=o(function(t){let e=t.id,r=t.targetId,n=t.tags,i=t.parent;X.debug("Entering cherryPick:",e,r,n);let a=Ip();if(e=Ze.sanitizeText(e,a),r=Ze.sanitizeText(r,a),n=n?.map(u=>Ze.sanitizeText(u,a)),i=Ze.sanitizeText(i,a),!e||!At.records.commits.has(e)){let u=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw u.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},u}let s=At.records.commits.get(e);if(s===void 0||!s)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(i&&!(Array.isArray(s.parents)&&s.parents.includes(i)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");let l=s.branch;if(s.type===Kr.MERGE&&!i)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!r||!At.records.commits.has(r)){if(l===At.records.currBranch){let d=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let u=At.records.branches.get(At.records.currBranch);if(u===void 0||!u){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${At.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let h=At.records.commits.get(u);if(h===void 0||!h){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${At.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let f={id:At.records.seq+"-"+AO(),message:`cherry-picked ${s?.message} into ${At.records.currBranch}`,seq:At.records.seq++,parents:At.records.head==null?[]:[At.records.head.id,s.id],branch:At.records.currBranch,type:Kr.CHERRY_PICK,tags:n?n.filter(Boolean):[`cherry-pick:${s.id}${s.type===Kr.MERGE?`|parent:${i}`:""}`]};At.records.head=f,At.records.commits.set(f.id,f),At.records.branches.set(At.records.currBranch,f.id),X.debug(At.records.branches),X.debug("in cherryPick")}},"cherryPick"),ghe=o(function(t){if(t=Ze.sanitizeText(t,Ip()),At.records.branches.has(t)){At.records.currBranch=t;let e=At.records.branches.get(At.records.currBranch);e===void 0||!e?At.records.head=null:At.records.head=At.records.commits.get(e)??null}else{let e=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${t}")`);throw e.hash={text:`checkout ${t}`,token:`checkout ${t}`,expected:[`branch ${t}`]},e}},"checkout");o(mhe,"upsert");o(yhe,"prettyPrintCommitHistory");Qze=o(function(){X.debug(At.records.commits);let t=vhe()[0];yhe([t])},"prettyPrint"),Zze=o(function(){At.reset(),kr()},"clear"),Jze=o(function(){return[...At.records.branchConfig.values()].map((e,r)=>e.order!==null&&e.order!==void 0?e:{...e,order:parseFloat(`0.${r}`)}).sort((e,r)=>(e.order??0)-(r.order??0)).map(({name:e})=>({name:e}))},"getBranchesAsObjArray"),eGe=o(function(){return At.records.branches},"getBranches"),tGe=o(function(){return At.records.commits},"getCommits"),vhe=o(function(){let t=[...At.records.commits.values()];return t.forEach(function(e){X.debug(e.id)}),t.sort((e,r)=>e.seq-r.seq),t},"getCommitsArray"),rGe=o(function(){return At.records.currBranch},"getCurrentBranch"),nGe=o(function(){return At.records.direction},"getDirection"),iGe=o(function(){return At.records.head},"getHead"),CS={commitType:Kr,getConfig:Ip,setDirection:Hze,setOptions:Wze,getOptions:qze,commit:Yze,branch:Xze,merge:jze,cherryPick:Kze,checkout:ghe,prettyPrint:Qze,clear:Zze,getBranchesAsObjArray:Jze,getBranches:eGe,getCommits:tGe,getCommitsArray:vhe,getCurrentBranch:rGe,getDirection:nGe,getHead:iGe,setAccTitle:Ar,getAccTitle:Dr,getAccDescription:Rr,setAccDescription:Lr,setDiagramTitle:Or,getDiagramTitle:Nr}});var aGe,sGe,oGe,lGe,cGe,uGe,hGe,xhe,bhe=N(()=>{"use strict";bf();yt();Mp();_O();ES();aGe=o((t,e)=>{Jo(t,e),t.dir&&e.setDirection(t.dir);for(let r of t.statements)sGe(r,e)},"populate"),sGe=o((t,e)=>{let n={Commit:o(i=>e.commit(oGe(i)),"Commit"),Branch:o(i=>e.branch(lGe(i)),"Branch"),Merge:o(i=>e.merge(cGe(i)),"Merge"),Checkout:o(i=>e.checkout(uGe(i)),"Checkout"),CherryPicking:o(i=>e.cherryPick(hGe(i)),"CherryPicking")}[t.$type];n?n(t):X.error(`Unknown statement type: ${t.$type}`)},"parseStatement"),oGe=o(t=>({id:t.id,msg:t.message??"",type:t.type!==void 0?Kr[t.type]:Kr.NORMAL,tags:t.tags??void 0}),"parseCommit"),lGe=o(t=>({name:t.name,order:t.order??0}),"parseBranch"),cGe=o(t=>({branch:t.branch,id:t.id??"",type:t.type!==void 0?Kr[t.type]:void 0,tags:t.tags??void 0}),"parseMerge"),uGe=o(t=>t.branch,"parseCheckout"),hGe=o(t=>({id:t.id,targetId:"",tags:t.tags?.length===0?void 0:t.tags,parent:t.parent}),"parseCherryPicking"),xhe={parse:o(async t=>{let e=await vs("gitGraph",t);X.debug(e),aGe(e,CS)},"parse")}});var fGe,el,kf,Ef,Wc,Zu,Op,Hs,Ws,AS,Eb,_S,wf,Fr,dGe,whe,khe,pGe,mGe,gGe,yGe,vGe,xGe,bGe,TGe,wGe,kGe,EGe,SGe,The,CGe,Sb,AGe,_Ge,DGe,LGe,RGe,Ehe,She=N(()=>{"use strict";fr();Gt();yt();er();ES();fGe=me(),el=fGe?.gitGraph,kf=10,Ef=40,Wc=4,Zu=2,Op=8,Hs=new Map,Ws=new Map,AS=30,Eb=new Map,_S=[],wf=0,Fr="LR",dGe=o(()=>{Hs.clear(),Ws.clear(),Eb.clear(),wf=0,_S=[],Fr="LR"},"clear"),whe=o(t=>{let e=document.createElementNS("http://www.w3.org/2000/svg","text");return(typeof t=="string"?t.split(/\\n|\n|/gi):t).forEach(n=>{let i=document.createElementNS("http://www.w3.org/2000/svg","tspan");i.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),i.setAttribute("dy","1em"),i.setAttribute("x","0"),i.setAttribute("class","row"),i.textContent=n.trim(),e.appendChild(i)}),e},"drawText"),khe=o(t=>{let e,r,n;return Fr==="BT"?(r=o((i,a)=>i<=a,"comparisonFunc"),n=1/0):(r=o((i,a)=>i>=a,"comparisonFunc"),n=0),t.forEach(i=>{let a=Fr==="TB"||Fr=="BT"?Ws.get(i)?.y:Ws.get(i)?.x;a!==void 0&&r(a,n)&&(e=i,n=a)}),e},"findClosestParent"),pGe=o(t=>{let e="",r=1/0;return t.forEach(n=>{let i=Ws.get(n).y;i<=r&&(e=n,r=i)}),e||void 0},"findClosestParentBT"),mGe=o((t,e,r)=>{let n=r,i=r,a=[];t.forEach(s=>{let l=e.get(s);if(!l)throw new Error(`Commit not found for key ${s}`);l.parents.length?(n=yGe(l),i=Math.max(n,i)):a.push(l),vGe(l,n)}),n=i,a.forEach(s=>{xGe(s,n,r)}),t.forEach(s=>{let l=e.get(s);if(l?.parents.length){let u=pGe(l.parents);n=Ws.get(u).y-Ef,n<=i&&(i=n);let h=Hs.get(l.branch).pos,f=n-kf;Ws.set(l.id,{x:h,y:f})}})},"setParallelBTPos"),gGe=o(t=>{let e=khe(t.parents.filter(n=>n!==null));if(!e)throw new Error(`Closest parent not found for commit ${t.id}`);let r=Ws.get(e)?.y;if(r===void 0)throw new Error(`Closest parent position not found for commit ${t.id}`);return r},"findClosestParentPos"),yGe=o(t=>gGe(t)+Ef,"calculateCommitPosition"),vGe=o((t,e)=>{let r=Hs.get(t.branch);if(!r)throw new Error(`Branch not found for commit ${t.id}`);let n=r.pos,i=e+kf;return Ws.set(t.id,{x:n,y:i}),{x:n,y:i}},"setCommitPosition"),xGe=o((t,e,r)=>{let n=Hs.get(t.branch);if(!n)throw new Error(`Branch not found for commit ${t.id}`);let i=e+r,a=n.pos;Ws.set(t.id,{x:a,y:i})},"setRootPosition"),bGe=o((t,e,r,n,i,a)=>{if(a===Kr.HIGHLIGHT)t.append("rect").attr("x",r.x-10).attr("y",r.y-10).attr("width",20).attr("height",20).attr("class",`commit ${e.id} commit-highlight${i%Op} ${n}-outer`),t.append("rect").attr("x",r.x-6).attr("y",r.y-6).attr("width",12).attr("height",12).attr("class",`commit ${e.id} commit${i%Op} ${n}-inner`);else if(a===Kr.CHERRY_PICK)t.append("circle").attr("cx",r.x).attr("cy",r.y).attr("r",10).attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x-3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x+3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x+3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x-3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`);else{let s=t.append("circle");if(s.attr("cx",r.x),s.attr("cy",r.y),s.attr("r",e.type===Kr.MERGE?9:10),s.attr("class",`commit ${e.id} commit${i%Op}`),a===Kr.MERGE){let l=t.append("circle");l.attr("cx",r.x),l.attr("cy",r.y),l.attr("r",6),l.attr("class",`commit ${n} ${e.id} commit${i%Op}`)}a===Kr.REVERSE&&t.append("path").attr("d",`M ${r.x-5},${r.y-5}L${r.x+5},${r.y+5}M${r.x-5},${r.y+5}L${r.x+5},${r.y-5}`).attr("class",`commit ${n} ${e.id} commit${i%Op}`)}},"drawCommitBullet"),TGe=o((t,e,r,n)=>{if(e.type!==Kr.CHERRY_PICK&&(e.customId&&e.type===Kr.MERGE||e.type!==Kr.MERGE)&&el?.showCommitLabel){let i=t.append("g"),a=i.insert("rect").attr("class","commit-label-bkg"),s=i.append("text").attr("x",n).attr("y",r.y+25).attr("class","commit-label").text(e.id),l=s.node()?.getBBox();if(l&&(a.attr("x",r.posWithOffset-l.width/2-Zu).attr("y",r.y+13.5).attr("width",l.width+2*Zu).attr("height",l.height+2*Zu),Fr==="TB"||Fr==="BT"?(a.attr("x",r.x-(l.width+4*Wc+5)).attr("y",r.y-12),s.attr("x",r.x-(l.width+4*Wc)).attr("y",r.y+l.height-12)):s.attr("x",r.posWithOffset-l.width/2),el.rotateCommitLabel))if(Fr==="TB"||Fr==="BT")s.attr("transform","rotate(-45, "+r.x+", "+r.y+")"),a.attr("transform","rotate(-45, "+r.x+", "+r.y+")");else{let u=-7.5-(l.width+10)/25*9.5,h=10+l.width/25*8.5;i.attr("transform","translate("+u+", "+h+") rotate(-45, "+n+", "+r.y+")")}}},"drawCommitLabel"),wGe=o((t,e,r,n)=>{if(e.tags.length>0){let i=0,a=0,s=0,l=[];for(let u of e.tags.reverse()){let h=t.insert("polygon"),f=t.append("circle"),d=t.append("text").attr("y",r.y-16-i).attr("class","tag-label").text(u),p=d.node()?.getBBox();if(!p)throw new Error("Tag bbox not found");a=Math.max(a,p.width),s=Math.max(s,p.height),d.attr("x",r.posWithOffset-p.width/2),l.push({tag:d,hole:f,rect:h,yOffset:i}),i+=20}for(let{tag:u,hole:h,rect:f,yOffset:d}of l){let p=s/2,m=r.y-19.2-d;if(f.attr("class","tag-label-bkg").attr("points",` - ${n-a/2-Wc/2},${m+Zu} - ${n-a/2-Wc/2},${m-Zu} - ${r.posWithOffset-a/2-Wc},${m-p-Zu} - ${r.posWithOffset+a/2+Wc},${m-p-Zu} - ${r.posWithOffset+a/2+Wc},${m+p+Zu} - ${r.posWithOffset-a/2-Wc},${m+p+Zu}`),h.attr("cy",m).attr("cx",n-a/2+Wc/2).attr("r",1.5).attr("class","tag-hole"),Fr==="TB"||Fr==="BT"){let g=n+d;f.attr("class","tag-label-bkg").attr("points",` - ${r.x},${g+2} - ${r.x},${g-2} - ${r.x+kf},${g-p-2} - ${r.x+kf+a+4},${g-p-2} - ${r.x+kf+a+4},${g+p+2} - ${r.x+kf},${g+p+2}`).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),h.attr("cx",r.x+Wc/2).attr("cy",g).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),u.attr("x",r.x+5).attr("y",g+3).attr("transform","translate(14,14) rotate(45, "+r.x+","+n+")")}}}},"drawCommitTags"),kGe=o(t=>{switch(t.customType??t.type){case Kr.NORMAL:return"commit-normal";case Kr.REVERSE:return"commit-reverse";case Kr.HIGHLIGHT:return"commit-highlight";case Kr.MERGE:return"commit-merge";case Kr.CHERRY_PICK:return"commit-cherry-pick";default:return"commit-normal"}},"getCommitClassType"),EGe=o((t,e,r,n)=>{let i={x:0,y:0};if(t.parents.length>0){let a=khe(t.parents);if(a){let s=n.get(a)??i;return e==="TB"?s.y+Ef:e==="BT"?(n.get(t.id)??i).y-Ef:s.x+Ef}}else return e==="TB"?AS:e==="BT"?(n.get(t.id)??i).y-Ef:0;return 0},"calculatePosition"),SGe=o((t,e,r)=>{let n=Fr==="BT"&&r?e:e+kf,i=Fr==="TB"||Fr==="BT"?n:Hs.get(t.branch)?.pos,a=Fr==="TB"||Fr==="BT"?Hs.get(t.branch)?.pos:n;if(a===void 0||i===void 0)throw new Error(`Position were undefined for commit ${t.id}`);return{x:a,y:i,posWithOffset:n}},"getCommitPosition"),The=o((t,e,r)=>{if(!el)throw new Error("GitGraph config not found");let n=t.append("g").attr("class","commit-bullets"),i=t.append("g").attr("class","commit-labels"),a=Fr==="TB"||Fr==="BT"?AS:0,s=[...e.keys()],l=el?.parallelCommits??!1,u=o((f,d)=>{let p=e.get(f)?.seq,m=e.get(d)?.seq;return p!==void 0&&m!==void 0?p-m:0},"sortKeys"),h=s.sort(u);Fr==="BT"&&(l&&mGe(h,e,a),h=h.reverse()),h.forEach(f=>{let d=e.get(f);if(!d)throw new Error(`Commit not found for key ${f}`);l&&(a=EGe(d,Fr,a,Ws));let p=SGe(d,a,l);if(r){let m=kGe(d),g=d.customType??d.type,y=Hs.get(d.branch)?.index??0;bGe(n,d,p,m,y,g),TGe(i,d,p,a),wGe(i,d,p,a)}Fr==="TB"||Fr==="BT"?Ws.set(d.id,{x:p.x,y:p.posWithOffset}):Ws.set(d.id,{x:p.posWithOffset,y:p.y}),a=Fr==="BT"&&l?a+Ef:a+Ef+kf,a>wf&&(wf=a)})},"drawCommits"),CGe=o((t,e,r,n,i)=>{let s=(Fr==="TB"||Fr==="BT"?r.xh.branch===s,"isOnBranchToGetCurve"),u=o(h=>h.seq>t.seq&&h.sequ(h)&&l(h))},"shouldRerouteArrow"),Sb=o((t,e,r=0)=>{let n=t+Math.abs(t-e)/2;if(r>5)return n;if(_S.every(s=>Math.abs(s-n)>=10))return _S.push(n),n;let a=Math.abs(t-e);return Sb(t,e-a/5,r+1)},"findLane"),AGe=o((t,e,r,n)=>{let i=Ws.get(e.id),a=Ws.get(r.id);if(i===void 0||a===void 0)throw new Error(`Commit positions not found for commits ${e.id} and ${r.id}`);let s=CGe(e,r,i,a,n),l="",u="",h=0,f=0,d=Hs.get(r.branch)?.index;r.type===Kr.MERGE&&e.id!==r.parents[0]&&(d=Hs.get(e.branch)?.index);let p;if(s){l="A 10 10, 0, 0, 0,",u="A 10 10, 0, 0, 1,",h=10,f=10;let m=i.ya.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y-h} ${u} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x+h} ${i.y} ${l} ${a.x} ${i.y+f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):Fr==="BT"?(i.xa.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${l} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):(i.ya.y&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${u} ${i.x+f} ${a.y} L ${a.x} ${a.y}`),i.y===a.y&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`));if(p===void 0)throw new Error("Line definition not found");t.append("path").attr("d",p).attr("class","arrow arrow"+d%Op)},"drawArrow"),_Ge=o((t,e)=>{let r=t.append("g").attr("class","commit-arrows");[...e.keys()].forEach(n=>{let i=e.get(n);i.parents&&i.parents.length>0&&i.parents.forEach(a=>{AGe(r,e.get(a),i,e)})})},"drawArrows"),DGe=o((t,e)=>{let r=t.append("g");e.forEach((n,i)=>{let a=i%Op,s=Hs.get(n.name)?.pos;if(s===void 0)throw new Error(`Position not found for branch ${n.name}`);let l=r.append("line");l.attr("x1",0),l.attr("y1",s),l.attr("x2",wf),l.attr("y2",s),l.attr("class","branch branch"+a),Fr==="TB"?(l.attr("y1",AS),l.attr("x1",s),l.attr("y2",wf),l.attr("x2",s)):Fr==="BT"&&(l.attr("y1",wf),l.attr("x1",s),l.attr("y2",AS),l.attr("x2",s)),_S.push(s);let u=n.name,h=whe(u),f=r.insert("rect"),p=r.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+a);p.node().appendChild(h);let m=h.getBBox();f.attr("class","branchLabelBkg label"+a).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(el?.rotateCommitLabel===!0?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),p.attr("transform","translate("+(-m.width-14-(el?.rotateCommitLabel===!0?30:0))+", "+(s-m.height/2-1)+")"),Fr==="TB"?(f.attr("x",s-m.width/2-10).attr("y",0),p.attr("transform","translate("+(s-m.width/2-5)+", 0)")):Fr==="BT"?(f.attr("x",s-m.width/2-10).attr("y",wf),p.attr("transform","translate("+(s-m.width/2-5)+", "+wf+")")):f.attr("transform","translate(-19, "+(s-m.height/2)+")")})},"drawBranches"),LGe=o(function(t,e,r,n,i){return Hs.set(t,{pos:e,index:r}),e+=50+(i?40:0)+(Fr==="TB"||Fr==="BT"?n.width/2:0),e},"setBranchPosition"),RGe=o(function(t,e,r,n){if(dGe(),X.debug("in gitgraph renderer",t+` -`,"id:",e,r),!el)throw new Error("GitGraph config not found");let i=el.rotateCommitLabel??!1,a=n.db;Eb=a.getCommits();let s=a.getBranchesAsObjArray();Fr=a.getDirection();let l=Ge(`[id="${e}"]`),u=0;s.forEach((h,f)=>{let d=whe(h.name),p=l.append("g"),m=p.insert("g").attr("class","branchLabel"),g=m.insert("g").attr("class","label branch-label");g.node()?.appendChild(d);let y=d.getBBox();u=LGe(h.name,u,f,y,i),g.remove(),m.remove(),p.remove()}),The(l,Eb,!1),el.showBranches&&DGe(l,s),_Ge(l,Eb),The(l,Eb,!0),Vt.insertTitle(l,"gitTitleText",el.titleTopMargin??0,a.getDiagramTitle()),AA(void 0,l,el.diagramPadding,el.useMaxWidth)},"draw"),Ehe={draw:RGe}});var NGe,Che,Ahe=N(()=>{"use strict";NGe=o(t=>` - .commit-id, - .commit-msg, - .branch-label { - fill: lightgrey; - color: lightgrey; - font-family: 'trebuchet ms', verdana, arial, sans-serif; - font-family: var(--mermaid-font-family); - } - ${[0,1,2,3,4,5,6,7].map(e=>` - .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; } - .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; } - .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; } - .label${e} { fill: ${t["git"+e]}; } - .arrow${e} { stroke: ${t["git"+e]}; } - `).join(` -`)} - - .branch { - stroke-width: 1; - stroke: ${t.lineColor}; - stroke-dasharray: 2; - } - .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};} - .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; } - .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};} - .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; } - .tag-hole { fill: ${t.textColor}; } - - .commit-merge { - stroke: ${t.primaryColor}; - fill: ${t.primaryColor}; - } - .commit-reverse { - stroke: ${t.primaryColor}; - fill: ${t.primaryColor}; - stroke-width: 3; - } - .commit-highlight-outer { - } - .commit-highlight-inner { - stroke: ${t.primaryColor}; - fill: ${t.primaryColor}; - } - - .arrow { stroke-width: 8; stroke-linecap: round; fill: none} - .gitTitleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.textColor}; - } -`,"getStyles"),Che=NGe});var _he={};ur(_he,{diagram:()=>MGe});var MGe,Dhe=N(()=>{"use strict";bhe();_O();She();Ahe();MGe={parser:xhe,db:CS,renderer:Ehe,styles:Che}});var DO,Nhe,Mhe=N(()=>{"use strict";DO=function(){var t=o(function(L,A,I,M){for(I=I||{},M=L.length;M--;I[L[M]]=A);return I},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],r=[1,26],n=[1,27],i=[1,28],a=[1,29],s=[1,30],l=[1,31],u=[1,32],h=[1,33],f=[1,34],d=[1,9],p=[1,10],m=[1,11],g=[1,12],y=[1,13],v=[1,14],x=[1,15],b=[1,16],T=[1,19],S=[1,20],w=[1,21],E=[1,22],_=[1,23],C=[1,25],D=[1,35],O={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:o(function(A,I,M,P,B,F,z){var $=F.length-1;switch(B){case 1:return F[$-1];case 2:this.$=[];break;case 3:F[$-1].push(F[$]),this.$=F[$-1];break;case 4:case 5:this.$=F[$];break;case 6:case 7:this.$=[];break;case 8:P.setWeekday("monday");break;case 9:P.setWeekday("tuesday");break;case 10:P.setWeekday("wednesday");break;case 11:P.setWeekday("thursday");break;case 12:P.setWeekday("friday");break;case 13:P.setWeekday("saturday");break;case 14:P.setWeekday("sunday");break;case 15:P.setWeekend("friday");break;case 16:P.setWeekend("saturday");break;case 17:P.setDateFormat(F[$].substr(11)),this.$=F[$].substr(11);break;case 18:P.enableInclusiveEndDates(),this.$=F[$].substr(18);break;case 19:P.TopAxis(),this.$=F[$].substr(8);break;case 20:P.setAxisFormat(F[$].substr(11)),this.$=F[$].substr(11);break;case 21:P.setTickInterval(F[$].substr(13)),this.$=F[$].substr(13);break;case 22:P.setExcludes(F[$].substr(9)),this.$=F[$].substr(9);break;case 23:P.setIncludes(F[$].substr(9)),this.$=F[$].substr(9);break;case 24:P.setTodayMarker(F[$].substr(12)),this.$=F[$].substr(12);break;case 27:P.setDiagramTitle(F[$].substr(6)),this.$=F[$].substr(6);break;case 28:this.$=F[$].trim(),P.setAccTitle(this.$);break;case 29:case 30:this.$=F[$].trim(),P.setAccDescription(this.$);break;case 31:P.addSection(F[$].substr(8)),this.$=F[$].substr(8);break;case 33:P.addTask(F[$-1],F[$]),this.$="task";break;case 34:this.$=F[$-1],P.setClickEvent(F[$-1],F[$],null);break;case 35:this.$=F[$-2],P.setClickEvent(F[$-2],F[$-1],F[$]);break;case 36:this.$=F[$-2],P.setClickEvent(F[$-2],F[$-1],null),P.setLink(F[$-2],F[$]);break;case 37:this.$=F[$-3],P.setClickEvent(F[$-3],F[$-2],F[$-1]),P.setLink(F[$-3],F[$]);break;case 38:this.$=F[$-2],P.setClickEvent(F[$-2],F[$],null),P.setLink(F[$-2],F[$-1]);break;case 39:this.$=F[$-3],P.setClickEvent(F[$-3],F[$-1],F[$]),P.setLink(F[$-3],F[$-2]);break;case 40:this.$=F[$-1],P.setLink(F[$-1],F[$]);break;case 41:case 47:this.$=F[$-1]+" "+F[$];break;case 42:case 43:case 45:this.$=F[$-2]+" "+F[$-1]+" "+F[$];break;case 44:case 46:this.$=F[$-3]+" "+F[$-2]+" "+F[$-1]+" "+F[$];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:T,31:S,33:w,35:E,36:_,37:24,38:C,40:D},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:T,31:S,33:w,35:E,36:_,37:24,38:C,40:D},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:o(function(A,I){if(I.recoverable)this.trace(A);else{var M=new Error(A);throw M.hash=I,M}},"parseError"),parse:o(function(A){var I=this,M=[0],P=[],B=[null],F=[],z=this.table,$="",U=0,K=0,ee=0,Y=2,ce=1,Z=F.slice.call(arguments,1),ue=Object.create(this.lexer),Q={yy:{}};for(var j in this.yy)Object.prototype.hasOwnProperty.call(this.yy,j)&&(Q.yy[j]=this.yy[j]);ue.setInput(A,Q.yy),Q.yy.lexer=ue,Q.yy.parser=this,typeof ue.yylloc>"u"&&(ue.yylloc={});var ne=ue.yylloc;F.push(ne);var te=ue.options&&ue.options.ranges;typeof Q.yy.parseError=="function"?this.parseError=Q.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function he(q){M.length=M.length-2*q,B.length=B.length-q,F.length=F.length-q}o(he,"popStack");function le(){var q;return q=P.pop()||ue.lex()||ce,typeof q!="number"&&(q instanceof Array&&(P=q,q=P.pop()),q=I.symbols_[q]||q),q}o(le,"lex");for(var J,Se,se,ae,Oe,ye,Be={},He,ze,Le,Ie;;){if(se=M[M.length-1],this.defaultActions[se]?ae=this.defaultActions[se]:((J===null||typeof J>"u")&&(J=le()),ae=z[se]&&z[se][J]),typeof ae>"u"||!ae.length||!ae[0]){var xe="";Ie=[];for(He in z[se])this.terminals_[He]&&He>Y&&Ie.push("'"+this.terminals_[He]+"'");ue.showPosition?xe="Parse error on line "+(U+1)+`: -`+ue.showPosition()+` -Expecting `+Ie.join(", ")+", got '"+(this.terminals_[J]||J)+"'":xe="Parse error on line "+(U+1)+": Unexpected "+(J==ce?"end of input":"'"+(this.terminals_[J]||J)+"'"),this.parseError(xe,{text:ue.match,token:this.terminals_[J]||J,line:ue.yylineno,loc:ne,expected:Ie})}if(ae[0]instanceof Array&&ae.length>1)throw new Error("Parse Error: multiple actions possible at state: "+se+", token: "+J);switch(ae[0]){case 1:M.push(J),B.push(ue.yytext),F.push(ue.yylloc),M.push(ae[1]),J=null,Se?(J=Se,Se=null):(K=ue.yyleng,$=ue.yytext,U=ue.yylineno,ne=ue.yylloc,ee>0&&ee--);break;case 2:if(ze=this.productions_[ae[1]][1],Be.$=B[B.length-ze],Be._$={first_line:F[F.length-(ze||1)].first_line,last_line:F[F.length-1].last_line,first_column:F[F.length-(ze||1)].first_column,last_column:F[F.length-1].last_column},te&&(Be._$.range=[F[F.length-(ze||1)].range[0],F[F.length-1].range[1]]),ye=this.performAction.apply(Be,[$,K,U,Q.yy,ae[1],B,F].concat(Z)),typeof ye<"u")return ye;ze&&(M=M.slice(0,-1*ze*2),B=B.slice(0,-1*ze),F=F.slice(0,-1*ze)),M.push(this.productions_[ae[1]][0]),B.push(Be.$),F.push(Be._$),Le=z[M[M.length-2]][M[M.length-1]],M.push(Le);break;case 3:return!0}}return!0},"parse")},R=function(){var L={EOF:1,parseError:o(function(I,M){if(this.yy.parser)this.yy.parser.parseError(I,M);else throw new Error(I)},"parseError"),setInput:o(function(A,I){return this.yy=I||this.yy||{},this._input=A,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var A=this._input[0];this.yytext+=A,this.yyleng++,this.offset++,this.match+=A,this.matched+=A;var I=A.match(/(?:\r\n?|\n).*/g);return I?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),A},"input"),unput:o(function(A){var I=A.length,M=A.split(/(?:\r\n?|\n)/g);this._input=A+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-I),this.offset-=I;var P=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),M.length-1&&(this.yylineno-=M.length-1);var B=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:M?(M.length===P.length?this.yylloc.first_column:0)+P[P.length-M.length].length-M[0].length:this.yylloc.first_column-I},this.options.ranges&&(this.yylloc.range=[B[0],B[0]+this.yyleng-I]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(A){this.unput(this.match.slice(A))},"less"),pastInput:o(function(){var A=this.matched.substr(0,this.matched.length-this.match.length);return(A.length>20?"...":"")+A.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var A=this.match;return A.length<20&&(A+=this._input.substr(0,20-A.length)),(A.substr(0,20)+(A.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var A=this.pastInput(),I=new Array(A.length+1).join("-");return A+this.upcomingInput()+` -`+I+"^"},"showPosition"),test_match:o(function(A,I){var M,P,B;if(this.options.backtrack_lexer&&(B={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(B.yylloc.range=this.yylloc.range.slice(0))),P=A[0].match(/(?:\r\n?|\n).*/g),P&&(this.yylineno+=P.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:P?P[P.length-1].length-P[P.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+A[0].length},this.yytext+=A[0],this.match+=A[0],this.matches=A,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(A[0].length),this.matched+=A[0],M=this.performAction.call(this,this.yy,this,I,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),M)return M;if(this._backtrack){for(var F in B)this[F]=B[F];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var A,I,M,P;this._more||(this.yytext="",this.match="");for(var B=this._currentRules(),F=0;FI[0].length)){if(I=M,P=F,this.options.backtrack_lexer){if(A=this.test_match(M,B[F]),A!==!1)return A;if(this._backtrack){I=!1;continue}else return!1}else if(!this.options.flex)break}return I?(A=this.test_match(I,B[P]),A!==!1?A:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var I=this.next();return I||this.lex()},"lex"),begin:o(function(I){this.conditionStack.push(I)},"begin"),popState:o(function(){var I=this.conditionStack.length-1;return I>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(I){return I=this.conditionStack.length-1-Math.abs(I||0),I>=0?this.conditionStack[I]:"INITIAL"},"topState"),pushState:o(function(I){this.begin(I)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(I,M,P,B){var F=B;switch(P){case 0:return this.begin("open_directive"),"open_directive";break;case 1:return this.begin("acc_title"),31;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),33;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:break;case 9:break;case 10:break;case 11:return 10;case 12:break;case 13:break;case 14:this.begin("href");break;case 15:this.popState();break;case 16:return 43;case 17:this.begin("callbackname");break;case 18:this.popState();break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 41;case 21:this.popState();break;case 22:return 42;case 23:this.begin("click");break;case 24:this.popState();break;case 25:return 40;case 26:return 4;case 27:return 22;case 28:return 23;case 29:return 24;case 30:return 25;case 31:return 26;case 32:return 28;case 33:return 27;case 34:return 29;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return 20;case 43:return 21;case 44:return"date";case 45:return 30;case 46:return"accDescription";case 47:return 36;case 48:return 38;case 49:return 39;case 50:return":";case 51:return 6;case 52:return"INVALID"}},"anonymous"),rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:weekend\s+friday\b)/i,/^(?:weekend\s+saturday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],inclusive:!0}}};return L}();O.lexer=R;function k(){this.yy={}}return o(k,"Parser"),k.prototype=O,O.Parser=k,new k}();DO.parser=DO;Nhe=DO});var Ihe=Pi((LO,RO)=>{"use strict";(function(t,e){typeof LO=="object"&&typeof RO<"u"?RO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_isoWeek=e()})(LO,function(){"use strict";var t="day";return function(e,r,n){var i=o(function(l){return l.add(4-l.isoWeekday(),t)},"a"),a=r.prototype;a.isoWeekYear=function(){return i(this).year()},a.isoWeek=function(l){if(!this.$utils().u(l))return this.add(7*(l-this.isoWeek()),t);var u,h,f,d,p=i(this),m=(u=this.isoWeekYear(),h=this.$u,f=(h?n.utc:n)().year(u).startOf("year"),d=4-f.isoWeekday(),f.isoWeekday()>4&&(d+=7),f.add(d,t));return p.diff(m,"week")+1},a.isoWeekday=function(l){return this.$utils().u(l)?this.day()||7:this.day(this.day()%7?l:l-7)};var s=a.startOf;a.startOf=function(l,u){var h=this.$utils(),f=!!h.u(u)||u;return h.p(l)==="isoweek"?f?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(l,u)}}})});var Ohe=Pi((NO,MO)=>{"use strict";(function(t,e){typeof NO=="object"&&typeof MO<"u"?MO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_customParseFormat=e()})(NO,function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,r=/\d/,n=/\d\d/,i=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,s={},l=o(function(g){return(g=+g)+(g>68?1900:2e3)},"a"),u=o(function(g){return function(y){this[g]=+y}},"f"),h=[/[+-]\d\d:?(\d\d)?|Z/,function(g){(this.zone||(this.zone={})).offset=function(y){if(!y||y==="Z")return 0;var v=y.match(/([+-]|\d\d)/g),x=60*v[1]+(+v[2]||0);return x===0?0:v[0]==="+"?-x:x}(g)}],f=o(function(g){var y=s[g];return y&&(y.indexOf?y:y.s.concat(y.f))},"u"),d=o(function(g,y){var v,x=s.meridiem;if(x){for(var b=1;b<=24;b+=1)if(g.indexOf(x(b,0,y))>-1){v=b>12;break}}else v=g===(y?"pm":"PM");return v},"d"),p={A:[a,function(g){this.afternoon=d(g,!1)}],a:[a,function(g){this.afternoon=d(g,!0)}],Q:[r,function(g){this.month=3*(g-1)+1}],S:[r,function(g){this.milliseconds=100*+g}],SS:[n,function(g){this.milliseconds=10*+g}],SSS:[/\d{3}/,function(g){this.milliseconds=+g}],s:[i,u("seconds")],ss:[i,u("seconds")],m:[i,u("minutes")],mm:[i,u("minutes")],H:[i,u("hours")],h:[i,u("hours")],HH:[i,u("hours")],hh:[i,u("hours")],D:[i,u("day")],DD:[n,u("day")],Do:[a,function(g){var y=s.ordinal,v=g.match(/\d+/);if(this.day=v[0],y)for(var x=1;x<=31;x+=1)y(x).replace(/\[|\]/g,"")===g&&(this.day=x)}],w:[i,u("week")],ww:[n,u("week")],M:[i,u("month")],MM:[n,u("month")],MMM:[a,function(g){var y=f("months"),v=(f("monthsShort")||y.map(function(x){return x.slice(0,3)})).indexOf(g)+1;if(v<1)throw new Error;this.month=v%12||v}],MMMM:[a,function(g){var y=f("months").indexOf(g)+1;if(y<1)throw new Error;this.month=y%12||y}],Y:[/[+-]?\d+/,u("year")],YY:[n,function(g){this.year=l(g)}],YYYY:[/\d{4}/,u("year")],Z:h,ZZ:h};function m(g){var y,v;y=g,v=s&&s.formats;for(var x=(g=y.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(C,D,O){var R=O&&O.toUpperCase();return D||v[O]||t[O]||v[R].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(k,L,A){return L||A.slice(1)})})).match(e),b=x.length,T=0;T-1)return new Date((M==="X"?1e3:1)*I);var F=m(M)(I),z=F.year,$=F.month,U=F.day,K=F.hours,ee=F.minutes,Y=F.seconds,ce=F.milliseconds,Z=F.zone,ue=F.week,Q=new Date,j=U||(z||$?1:Q.getDate()),ne=z||Q.getFullYear(),te=0;z&&!$||(te=$>0?$-1:Q.getMonth());var he,le=K||0,J=ee||0,Se=Y||0,se=ce||0;return Z?new Date(Date.UTC(ne,te,j,le,J,Se,se+60*Z.offset*1e3)):P?new Date(Date.UTC(ne,te,j,le,J,Se,se)):(he=new Date(ne,te,j,le,J,Se,se),ue&&(he=B(he).week(ue).toDate()),he)}catch{return new Date("")}}(S,_,w,v),this.init(),R&&R!==!0&&(this.$L=this.locale(R).$L),O&&S!=this.format(_)&&(this.$d=new Date("")),s={}}else if(_ instanceof Array)for(var k=_.length,L=1;L<=k;L+=1){E[1]=_[L-1];var A=v.apply(this,E);if(A.isValid()){this.$d=A.$d,this.$L=A.$L,this.init();break}L===k&&(this.$d=new Date(""))}else b.call(this,T)}}})});var Phe=Pi((IO,OO)=>{"use strict";(function(t,e){typeof IO=="object"&&typeof OO<"u"?OO.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_advancedFormat=e()})(IO,function(){"use strict";return function(t,e){var r=e.prototype,n=r.format;r.format=function(i){var a=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var l=this.$utils(),u=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(h){switch(h){case"Q":return Math.ceil((a.$M+1)/3);case"Do":return s.ordinal(a.$D);case"gggg":return a.weekYear();case"GGGG":return a.isoWeekYear();case"wo":return s.ordinal(a.week(),"W");case"w":case"ww":return l.s(a.week(),h==="w"?1:2,"0");case"W":case"WW":return l.s(a.isoWeek(),h==="W"?1:2,"0");case"k":case"kk":return l.s(String(a.$H===0?24:a.$H),h==="k"?1:2,"0");case"X":return Math.floor(a.$d.getTime()/1e3);case"x":return a.$d.getTime();case"z":return"["+a.offsetName()+"]";case"zzz":return"["+a.offsetName("long")+"]";default:return h}});return n.bind(this)(u)}}})});function Zhe(t,e,r){let n=!0;for(;n;)n=!1,r.forEach(function(i){let a="^\\s*"+i+"\\s*$",s=new RegExp(a);t[0].match(s)&&(e[i]=!0,t.shift(1),n=!0)})}var $he,mo,zhe,Ghe,Vhe,Bhe,qc,$O,zO,GO,Cb,Ab,VO,UO,RS,R1,HO,Uhe,WO,_b,qO,YO,NS,PO,BGe,FGe,$Ge,zGe,GGe,VGe,UGe,HGe,WGe,qGe,YGe,XGe,jGe,KGe,QGe,ZGe,JGe,eVe,tVe,rVe,nVe,iVe,aVe,Hhe,sVe,oVe,lVe,Whe,cVe,BO,qhe,Yhe,DS,L1,uVe,hVe,FO,LS,Ui,Xhe,fVe,Pp,dVe,Fhe,pVe,jhe,mVe,Khe,gVe,yVe,Qhe,Jhe=N(()=>{"use strict";$he=Aa(Z0(),1),mo=Aa(U4(),1),zhe=Aa(Ihe(),1),Ghe=Aa(Ohe(),1),Vhe=Aa(Phe(),1);yt();Gt();er();ci();mo.default.extend(zhe.default);mo.default.extend(Ghe.default);mo.default.extend(Vhe.default);Bhe={friday:5,saturday:6},qc="",$O="",GO="",Cb=[],Ab=[],VO=new Map,UO=[],RS=[],R1="",HO="",Uhe=["active","done","crit","milestone","vert"],WO=[],_b=!1,qO=!1,YO="sunday",NS="saturday",PO=0,BGe=o(function(){UO=[],RS=[],R1="",WO=[],DS=0,FO=void 0,LS=void 0,Ui=[],qc="",$O="",HO="",zO=void 0,GO="",Cb=[],Ab=[],_b=!1,qO=!1,PO=0,VO=new Map,kr(),YO="sunday",NS="saturday"},"clear"),FGe=o(function(t){$O=t},"setAxisFormat"),$Ge=o(function(){return $O},"getAxisFormat"),zGe=o(function(t){zO=t},"setTickInterval"),GGe=o(function(){return zO},"getTickInterval"),VGe=o(function(t){GO=t},"setTodayMarker"),UGe=o(function(){return GO},"getTodayMarker"),HGe=o(function(t){qc=t},"setDateFormat"),WGe=o(function(){_b=!0},"enableInclusiveEndDates"),qGe=o(function(){return _b},"endDatesAreInclusive"),YGe=o(function(){qO=!0},"enableTopAxis"),XGe=o(function(){return qO},"topAxisEnabled"),jGe=o(function(t){HO=t},"setDisplayMode"),KGe=o(function(){return HO},"getDisplayMode"),QGe=o(function(){return qc},"getDateFormat"),ZGe=o(function(t){Cb=t.toLowerCase().split(/[\s,]+/)},"setIncludes"),JGe=o(function(){return Cb},"getIncludes"),eVe=o(function(t){Ab=t.toLowerCase().split(/[\s,]+/)},"setExcludes"),tVe=o(function(){return Ab},"getExcludes"),rVe=o(function(){return VO},"getLinks"),nVe=o(function(t){R1=t,UO.push(t)},"addSection"),iVe=o(function(){return UO},"getSections"),aVe=o(function(){let t=Fhe(),e=10,r=0;for(;!t&&r[\d\w- ]+)/.exec(r);if(i!==null){let s=null;for(let u of i.groups.ids.split(" ")){let h=Pp(u);h!==void 0&&(!s||h.endTime>s.endTime)&&(s=h)}if(s)return s.endTime;let l=new Date;return l.setHours(0,0,0,0),l}let a=(0,mo.default)(r,e.trim(),!0);if(a.isValid())return a.toDate();{X.debug("Invalid date:"+r),X.debug("With date format:"+e.trim());let s=new Date(r);if(s===void 0||isNaN(s.getTime())||s.getFullYear()<-1e4||s.getFullYear()>1e4)throw new Error("Invalid date:"+r);return s}},"getStartDate"),qhe=o(function(t){let e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return e!==null?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},"parseDuration"),Yhe=o(function(t,e,r,n=!1){r=r.trim();let a=/^until\s+(?[\d\w- ]+)/.exec(r);if(a!==null){let f=null;for(let p of a.groups.ids.split(" ")){let m=Pp(p);m!==void 0&&(!f||m.startTime{window.open(r,"_self")}),VO.set(n,r))}),jhe(t,"clickable")},"setLink"),jhe=o(function(t,e){t.split(",").forEach(function(r){let n=Pp(r);n!==void 0&&n.classes.push(e)})},"setClass"),mVe=o(function(t,e,r){if(me().securityLevel!=="loose"||e===void 0)return;let n=[];if(typeof r=="string"){n=r.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let a=0;a{Vt.runFunc(e,...n)})},"setClickFun"),Khe=o(function(t,e){WO.push(function(){let r=document.querySelector(`[id="${t}"]`);r!==null&&r.addEventListener("click",function(){e()})},function(){let r=document.querySelector(`[id="${t}-text"]`);r!==null&&r.addEventListener("click",function(){e()})})},"pushFun"),gVe=o(function(t,e,r){t.split(",").forEach(function(n){mVe(n,e,r)}),jhe(t,"clickable")},"setClickEvent"),yVe=o(function(t){WO.forEach(function(e){e(t)})},"bindFunctions"),Qhe={getConfig:o(()=>me().gantt,"getConfig"),clear:BGe,setDateFormat:HGe,getDateFormat:QGe,enableInclusiveEndDates:WGe,endDatesAreInclusive:qGe,enableTopAxis:YGe,topAxisEnabled:XGe,setAxisFormat:FGe,getAxisFormat:$Ge,setTickInterval:zGe,getTickInterval:GGe,setTodayMarker:VGe,getTodayMarker:UGe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,setDisplayMode:jGe,getDisplayMode:KGe,setAccDescription:Lr,getAccDescription:Rr,addSection:nVe,getSections:iVe,getTasks:aVe,addTask:fVe,findTaskById:Pp,addTaskOrg:dVe,setIncludes:ZGe,getIncludes:JGe,setExcludes:eVe,getExcludes:tVe,setClickEvent:gVe,setLink:pVe,getLinks:rVe,bindFunctions:yVe,parseDuration:qhe,isInvalidDate:Hhe,setWeekday:sVe,getWeekday:oVe,setWeekend:lVe};o(Zhe,"getTaskTags")});var MS,vVe,efe,xVe,Ju,bVe,tfe,rfe=N(()=>{"use strict";MS=Aa(U4(),1);yt();fr();pr();Gt();xi();vVe=o(function(){X.debug("Something is calling, setConf, remove the call")},"setConf"),efe={monday:Nh,tuesday:I5,wednesday:O5,thursday:fc,friday:P5,saturday:B5,sunday:wl},xVe=o((t,e)=>{let r=[...t].map(()=>-1/0),n=[...t].sort((a,s)=>a.startTime-s.startTime||a.order-s.order),i=0;for(let a of n)for(let s=0;s=r[s]){r[s]=a.endTime,a.order=s+e,s>i&&(i=s);break}return i},"getMaxIntersections"),bVe=o(function(t,e,r,n){let i=me().gantt,a=me().securityLevel,s;a==="sandbox"&&(s=Ge("#i"+e));let l=a==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=a==="sandbox"?s.nodes()[0].contentDocument:document,h=u.getElementById(e);Ju=h.parentElement.offsetWidth,Ju===void 0&&(Ju=1200),i.useWidth!==void 0&&(Ju=i.useWidth);let f=n.db.getTasks(),d=[];for(let C of f)d.push(C.type);d=_(d);let p={},m=2*i.topPadding;if(n.db.getDisplayMode()==="compact"||i.displayMode==="compact"){let C={};for(let O of f)C[O.section]===void 0?C[O.section]=[O]:C[O.section].push(O);let D=0;for(let O of Object.keys(C)){let R=xVe(C[O],D)+1;D+=R,m+=R*(i.barHeight+i.barGap),p[O]=R}}else{m+=f.length*(i.barHeight+i.barGap);for(let C of d)p[C]=f.filter(D=>D.type===C).length}h.setAttribute("viewBox","0 0 "+Ju+" "+m);let g=l.select(`[id="${e}"]`),y=z5().domain([W3(f,function(C){return C.startTime}),H3(f,function(C){return C.endTime})]).rangeRound([0,Ju-i.leftPadding-i.rightPadding]);function v(C,D){let O=C.startTime,R=D.startTime,k=0;return O>R?k=1:Oz.vert===$.vert?0:z.vert?1:-1);let M=[...new Set(C.map(z=>z.order))].map(z=>C.find($=>$.order===z));g.append("g").selectAll("rect").data(M).enter().append("rect").attr("x",0).attr("y",function(z,$){return $=z.order,$*D+O-2}).attr("width",function(){return A-i.rightPadding/2}).attr("height",D).attr("class",function(z){for(let[$,U]of d.entries())if(z.type===U)return"section section"+$%i.numberSectionStyles;return"section section0"}).enter();let P=g.append("g").selectAll("rect").data(C).enter(),B=n.db.getLinks();if(P.append("rect").attr("id",function(z){return z.id}).attr("rx",3).attr("ry",3).attr("x",function(z){return z.milestone?y(z.startTime)+R+.5*(y(z.endTime)-y(z.startTime))-.5*k:y(z.startTime)+R}).attr("y",function(z,$){return $=z.order,z.vert?i.gridLineStartPadding:$*D+O}).attr("width",function(z){return z.milestone?k:z.vert?.08*k:y(z.renderEndTime||z.endTime)-y(z.startTime)}).attr("height",function(z){return z.vert?f.length*(i.barHeight+i.barGap)+i.barHeight*2:k}).attr("transform-origin",function(z,$){return $=z.order,(y(z.startTime)+R+.5*(y(z.endTime)-y(z.startTime))).toString()+"px "+($*D+O+.5*k).toString()+"px"}).attr("class",function(z){let $="task",U="";z.classes.length>0&&(U=z.classes.join(" "));let K=0;for(let[Y,ce]of d.entries())z.type===ce&&(K=Y%i.numberSectionStyles);let ee="";return z.active?z.crit?ee+=" activeCrit":ee=" active":z.done?z.crit?ee=" doneCrit":ee=" done":z.crit&&(ee+=" crit"),ee.length===0&&(ee=" task"),z.milestone&&(ee=" milestone "+ee),z.vert&&(ee=" vert "+ee),ee+=K,ee+=" "+U,$+ee}),P.append("text").attr("id",function(z){return z.id+"-text"}).text(function(z){return z.task}).attr("font-size",i.fontSize).attr("x",function(z){let $=y(z.startTime),U=y(z.renderEndTime||z.endTime);if(z.milestone&&($+=.5*(y(z.endTime)-y(z.startTime))-.5*k,U=$+k),z.vert)return y(z.startTime)+R;let K=this.getBBox().width;return K>U-$?U+K+1.5*i.leftPadding>A?$+R-5:U+R+5:(U-$)/2+$+R}).attr("y",function(z,$){return z.vert?i.gridLineStartPadding+f.length*(i.barHeight+i.barGap)+60:($=z.order,$*D+i.barHeight/2+(i.fontSize/2-2)+O)}).attr("text-height",k).attr("class",function(z){let $=y(z.startTime),U=y(z.endTime);z.milestone&&(U=$+k);let K=this.getBBox().width,ee="";z.classes.length>0&&(ee=z.classes.join(" "));let Y=0;for(let[Z,ue]of d.entries())z.type===ue&&(Y=Z%i.numberSectionStyles);let ce="";return z.active&&(z.crit?ce="activeCritText"+Y:ce="activeText"+Y),z.done?z.crit?ce=ce+" doneCritText"+Y:ce=ce+" doneText"+Y:z.crit&&(ce=ce+" critText"+Y),z.milestone&&(ce+=" milestoneText"),z.vert&&(ce+=" vertText"),K>U-$?U+K+1.5*i.leftPadding>A?ee+" taskTextOutsideLeft taskTextOutside"+Y+" "+ce:ee+" taskTextOutsideRight taskTextOutside"+Y+" "+ce+" width-"+K:ee+" taskText taskText"+Y+" "+ce+" width-"+K}),me().securityLevel==="sandbox"){let z;z=Ge("#i"+e);let $=z.nodes()[0].contentDocument;P.filter(function(U){return B.has(U.id)}).each(function(U){var K=$.querySelector("#"+U.id),ee=$.querySelector("#"+U.id+"-text");let Y=K.parentNode;var ce=$.createElement("a");ce.setAttribute("xlink:href",B.get(U.id)),ce.setAttribute("target","_top"),Y.appendChild(ce),ce.appendChild(K),ce.appendChild(ee)})}}o(b,"drawRects");function T(C,D,O,R,k,L,A,I){if(A.length===0&&I.length===0)return;let M,P;for(let{startTime:K,endTime:ee}of L)(M===void 0||KP)&&(P=ee);if(!M||!P)return;if((0,MS.default)(P).diff((0,MS.default)(M),"year")>5){X.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");return}let B=n.db.getDateFormat(),F=[],z=null,$=(0,MS.default)(M);for(;$.valueOf()<=P;)n.db.isInvalidDate($,B,A,I)?z?z.end=$:z={start:$,end:$}:z&&(F.push(z),z=null),$=$.add(1,"d");g.append("g").selectAll("rect").data(F).enter().append("rect").attr("id",function(K){return"exclude-"+K.start.format("YYYY-MM-DD")}).attr("x",function(K){return y(K.start)+O}).attr("y",i.gridLineStartPadding).attr("width",function(K){let ee=K.end.add(1,"day");return y(ee)-y(K.start)}).attr("height",k-D-i.gridLineStartPadding).attr("transform-origin",function(K,ee){return(y(K.start)+O+.5*(y(K.end)-y(K.start))).toString()+"px "+(ee*C+.5*k).toString()+"px"}).attr("class","exclude-range")}o(T,"drawExcludeDays");function S(C,D,O,R){let k=zA(y).tickSize(-R+D+i.gridLineStartPadding).tickFormat(Ld(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d")),A=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(n.db.getTickInterval()||i.tickInterval);if(A!==null){let I=A[1],M=A[2],P=n.db.getWeekday()||i.weekday;switch(M){case"millisecond":k.ticks(uc.every(I));break;case"second":k.ticks(eo.every(I));break;case"minute":k.ticks(wu.every(I));break;case"hour":k.ticks(ku.every(I));break;case"day":k.ticks(Ro.every(I));break;case"week":k.ticks(efe[P].every(I));break;case"month":k.ticks(Eu.every(I));break}}if(g.append("g").attr("class","grid").attr("transform","translate("+C+", "+(R-50)+")").call(k).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),n.db.topAxisEnabled()||i.topAxis){let I=$A(y).tickSize(-R+D+i.gridLineStartPadding).tickFormat(Ld(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));if(A!==null){let M=A[1],P=A[2],B=n.db.getWeekday()||i.weekday;switch(P){case"millisecond":I.ticks(uc.every(M));break;case"second":I.ticks(eo.every(M));break;case"minute":I.ticks(wu.every(M));break;case"hour":I.ticks(ku.every(M));break;case"day":I.ticks(Ro.every(M));break;case"week":I.ticks(efe[B].every(M));break;case"month":I.ticks(Eu.every(M));break}}g.append("g").attr("class","grid").attr("transform","translate("+C+", "+D+")").call(I).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}o(S,"makeGrid");function w(C,D){let O=0,R=Object.keys(p).map(k=>[k,p[k]]);g.append("g").selectAll("text").data(R).enter().append(function(k){let L=k[0].split(Ze.lineBreakRegex),A=-(L.length-1)/2,I=u.createElementNS("http://www.w3.org/2000/svg","text");I.setAttribute("dy",A+"em");for(let[M,P]of L.entries()){let B=u.createElementNS("http://www.w3.org/2000/svg","tspan");B.setAttribute("alignment-baseline","central"),B.setAttribute("x","10"),M>0&&B.setAttribute("dy","1em"),B.textContent=P,I.appendChild(B)}return I}).attr("x",10).attr("y",function(k,L){if(L>0)for(let A=0;A{"use strict";TVe=o(t=>` - .mermaid-main-font { - font-family: ${t.fontFamily}; - } - - .exclude-range { - fill: ${t.excludeBkgColor}; - } - - .section { - stroke: none; - opacity: 0.2; - } - - .section0 { - fill: ${t.sectionBkgColor}; - } - - .section2 { - fill: ${t.sectionBkgColor2}; - } - - .section1, - .section3 { - fill: ${t.altSectionBkgColor}; - opacity: 0.2; - } - - .sectionTitle0 { - fill: ${t.titleColor}; - } - - .sectionTitle1 { - fill: ${t.titleColor}; - } - - .sectionTitle2 { - fill: ${t.titleColor}; - } - - .sectionTitle3 { - fill: ${t.titleColor}; - } - - .sectionTitle { - text-anchor: start; - font-family: ${t.fontFamily}; - } - - - /* Grid and axis */ - - .grid .tick { - stroke: ${t.gridColor}; - opacity: 0.8; - shape-rendering: crispEdges; - } - - .grid .tick text { - font-family: ${t.fontFamily}; - fill: ${t.textColor}; - } - - .grid path { - stroke-width: 0; - } - - - /* Today line */ - - .today { - fill: none; - stroke: ${t.todayLineColor}; - stroke-width: 2px; - } - - - /* Task styling */ - - /* Default task */ - - .task { - stroke-width: 2; - } - - .taskText { - text-anchor: middle; - font-family: ${t.fontFamily}; - } - - .taskTextOutsideRight { - fill: ${t.taskTextDarkColor}; - text-anchor: start; - font-family: ${t.fontFamily}; - } - - .taskTextOutsideLeft { - fill: ${t.taskTextDarkColor}; - text-anchor: end; - } - - - /* Special case clickable */ - - .task.clickable { - cursor: pointer; - } - - .taskText.clickable { - cursor: pointer; - fill: ${t.taskTextClickableColor} !important; - font-weight: bold; - } - - .taskTextOutsideLeft.clickable { - cursor: pointer; - fill: ${t.taskTextClickableColor} !important; - font-weight: bold; - } - - .taskTextOutsideRight.clickable { - cursor: pointer; - fill: ${t.taskTextClickableColor} !important; - font-weight: bold; - } - - - /* Specific task settings for the sections*/ - - .taskText0, - .taskText1, - .taskText2, - .taskText3 { - fill: ${t.taskTextColor}; - } - - .task0, - .task1, - .task2, - .task3 { - fill: ${t.taskBkgColor}; - stroke: ${t.taskBorderColor}; - } - - .taskTextOutside0, - .taskTextOutside2 - { - fill: ${t.taskTextOutsideColor}; - } - - .taskTextOutside1, - .taskTextOutside3 { - fill: ${t.taskTextOutsideColor}; - } - - - /* Active task */ - - .active0, - .active1, - .active2, - .active3 { - fill: ${t.activeTaskBkgColor}; - stroke: ${t.activeTaskBorderColor}; - } - - .activeText0, - .activeText1, - .activeText2, - .activeText3 { - fill: ${t.taskTextDarkColor} !important; - } - - - /* Completed task */ - - .done0, - .done1, - .done2, - .done3 { - stroke: ${t.doneTaskBorderColor}; - fill: ${t.doneTaskBkgColor}; - stroke-width: 2; - } - - .doneText0, - .doneText1, - .doneText2, - .doneText3 { - fill: ${t.taskTextDarkColor} !important; - } - - - /* Tasks on the critical line */ - - .crit0, - .crit1, - .crit2, - .crit3 { - stroke: ${t.critBorderColor}; - fill: ${t.critBkgColor}; - stroke-width: 2; - } - - .activeCrit0, - .activeCrit1, - .activeCrit2, - .activeCrit3 { - stroke: ${t.critBorderColor}; - fill: ${t.activeTaskBkgColor}; - stroke-width: 2; - } - - .doneCrit0, - .doneCrit1, - .doneCrit2, - .doneCrit3 { - stroke: ${t.critBorderColor}; - fill: ${t.doneTaskBkgColor}; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; - } - - .milestone { - transform: rotate(45deg) scale(0.8,0.8); - } - - .milestoneText { - font-style: italic; - } - .doneCritText0, - .doneCritText1, - .doneCritText2, - .doneCritText3 { - fill: ${t.taskTextDarkColor} !important; - } - - .vert { - stroke: ${t.vertLineColor}; - } - - .vertText { - font-size: 15px; - text-anchor: middle; - fill: ${t.vertLineColor} !important; - } - - .activeCritText0, - .activeCritText1, - .activeCritText2, - .activeCritText3 { - fill: ${t.taskTextDarkColor} !important; - } - - .titleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.titleColor||t.textColor}; - font-family: ${t.fontFamily}; - } -`,"getStyles"),nfe=TVe});var afe={};ur(afe,{diagram:()=>wVe});var wVe,sfe=N(()=>{"use strict";Mhe();Jhe();rfe();ife();wVe={parser:Nhe,db:Qhe,renderer:tfe,styles:nfe}});var cfe,ufe=N(()=>{"use strict";bf();yt();cfe={parse:o(async t=>{let e=await vs("info",t);X.debug(e)},"parse")}});var Db,XO=N(()=>{Db={name:"mermaid",version:"11.9.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",type:"module",module:"./dist/mermaid.core.mjs",types:"./dist/mermaid.d.ts",exports:{".":{types:"./dist/mermaid.d.ts",import:"./dist/mermaid.core.mjs",default:"./dist/mermaid.core.mjs"},"./*":"./*"},keywords:["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph","mindmap","packet diagram","c4 diagram","er diagram","pie chart","pie diagram","quadrant chart","requirement diagram","graph"],scripts:{clean:"rimraf dist",dev:"pnpm -w dev","docs:code":"typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup","docs:build":"rimraf ../../docs && pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts","docs:verify":"pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts --verify","docs:pre:vitepress":"pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts","docs:build:vitepress":"pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing","docs:dev":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:dev:docker":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev:docker" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:serve":"pnpm docs:build:vitepress && vitepress serve src/vitepress","docs:spellcheck":'cspell "src/docs/**/*.md"',"docs:release-version":"tsx scripts/update-release-version.mts","docs:verify-version":"tsx scripts/update-release-version.mts --verify","types:build-config":"tsx scripts/create-types-from-json-schema.mts","types:verify-config":"tsx scripts/create-types-from-json-schema.mts --verify",checkCircle:"npx madge --circular ./src",prepublishOnly:"pnpm docs:verify-version"},repository:{type:"git",url:"https://github.com/mermaid-js/mermaid"},author:"Knut Sveidqvist",license:"MIT",standard:{ignore:["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],globals:["page"]},dependencies:{"@braintree/sanitize-url":"^7.0.4","@iconify/utils":"^2.1.33","@mermaid-js/parser":"workspace:^","@types/d3":"^7.4.3",cytoscape:"^3.29.3","cytoscape-cose-bilkent":"^4.1.0","cytoscape-fcose":"^2.2.0",d3:"^7.9.0","d3-sankey":"^0.12.3","dagre-d3-es":"7.0.11",dayjs:"^1.11.13",dompurify:"^3.2.5",katex:"^0.16.22",khroma:"^2.1.0","lodash-es":"^4.17.21",marked:"^16.0.0",roughjs:"^4.6.6",stylis:"^4.3.6","ts-dedent":"^2.2.0",uuid:"^11.1.0"},devDependencies:{"@adobe/jsonschema2md":"^8.0.2","@iconify/types":"^2.0.0","@types/cytoscape":"^3.21.9","@types/cytoscape-fcose":"^2.2.4","@types/d3-sankey":"^0.12.4","@types/d3-scale":"^4.0.9","@types/d3-scale-chromatic":"^3.1.0","@types/d3-selection":"^3.0.11","@types/d3-shape":"^3.1.7","@types/jsdom":"^21.1.7","@types/katex":"^0.16.7","@types/lodash-es":"^4.17.12","@types/micromatch":"^4.0.9","@types/stylis":"^4.2.7","@types/uuid":"^10.0.0",ajv:"^8.17.1",canvas:"^3.1.0",chokidar:"3.6.0",concurrently:"^9.1.2","csstree-validator":"^4.0.1",globby:"^14.0.2",jison:"^0.4.18","js-base64":"^3.7.7",jsdom:"^26.1.0","json-schema-to-typescript":"^15.0.4",micromatch:"^4.0.8","path-browserify":"^1.0.1",prettier:"^3.5.2",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-gfm":"^4.0.1",rimraf:"^6.0.1","start-server-and-test":"^2.0.10","type-fest":"^4.35.0",typedoc:"^0.27.8","typedoc-plugin-markdown":"^4.4.2",typescript:"~5.7.3","unist-util-flatmap":"^1.0.0","unist-util-visit":"^5.0.0",vitepress:"^1.0.2","vitepress-plugin-search":"1.0.4-alpha.22"},files:["dist/","README.md"],publishConfig:{access:"public"}}});var AVe,_Ve,hfe,ffe=N(()=>{"use strict";XO();AVe={version:Db.version+""},_Ve=o(()=>AVe.version,"getVersion"),hfe={getVersion:_Ve}});var Li,Vl=N(()=>{"use strict";fr();Gt();Li=o(t=>{let{securityLevel:e}=me(),r=Ge("body");if(e==="sandbox"){let a=Ge(`#i${t}`).node()?.contentDocument??document;r=Ge(a.body)}return r.select(`#${t}`)},"selectSvgElement")});var DVe,dfe,pfe=N(()=>{"use strict";yt();Vl();xi();DVe=o((t,e,r)=>{X.debug(`rendering info diagram -`+t);let n=Li(e);fn(n,100,400,!0),n.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${r}`)},"draw"),dfe={draw:DVe}});var mfe={};ur(mfe,{diagram:()=>LVe});var LVe,gfe=N(()=>{"use strict";ufe();ffe();pfe();LVe={parser:cfe,db:hfe,renderer:dfe}});var xfe,jO,IS,KO,MVe,IVe,OVe,PVe,BVe,FVe,$Ve,OS,QO=N(()=>{"use strict";yt();ci();_a();xfe=or.pie,jO={sections:new Map,showData:!1,config:xfe},IS=jO.sections,KO=jO.showData,MVe=structuredClone(xfe),IVe=o(()=>structuredClone(MVe),"getConfig"),OVe=o(()=>{IS=new Map,KO=jO.showData,kr()},"clear"),PVe=o(({label:t,value:e})=>{IS.has(t)||(IS.set(t,e),X.debug(`added new section: ${t}, with value: ${e}`))},"addSection"),BVe=o(()=>IS,"getSections"),FVe=o(t=>{KO=t},"setShowData"),$Ve=o(()=>KO,"getShowData"),OS={getConfig:IVe,clear:OVe,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,addSection:PVe,getSections:BVe,setShowData:FVe,getShowData:$Ve}});var zVe,bfe,Tfe=N(()=>{"use strict";bf();yt();Mp();QO();zVe=o((t,e)=>{Jo(t,e),e.setShowData(t.showData),t.sections.map(e.addSection)},"populateDb"),bfe={parse:o(async t=>{let e=await vs("pie",t);X.debug(e),zVe(e,OS)},"parse")}});var GVe,wfe,kfe=N(()=>{"use strict";GVe=o(t=>` - .pieCircle{ - stroke: ${t.pieStrokeColor}; - stroke-width : ${t.pieStrokeWidth}; - opacity : ${t.pieOpacity}; - } - .pieOuterCircle{ - stroke: ${t.pieOuterStrokeColor}; - stroke-width: ${t.pieOuterStrokeWidth}; - fill: none; - } - .pieTitleText { - text-anchor: middle; - font-size: ${t.pieTitleTextSize}; - fill: ${t.pieTitleTextColor}; - font-family: ${t.fontFamily}; - } - .slice { - font-family: ${t.fontFamily}; - fill: ${t.pieSectionTextColor}; - font-size:${t.pieSectionTextSize}; - // fill: white; - } - .legend text { - fill: ${t.pieLegendTextColor}; - font-family: ${t.fontFamily}; - font-size: ${t.pieLegendTextSize}; - } -`,"getStyles"),wfe=GVe});var VVe,UVe,Efe,Sfe=N(()=>{"use strict";fr();Gt();yt();Vl();xi();er();VVe=o(t=>{let e=[...t.entries()].map(n=>({label:n[0],value:n[1]})).sort((n,i)=>i.value-n.value);return q5().value(n=>n.value)(e)},"createPieArcs"),UVe=o((t,e,r,n)=>{X.debug(`rendering pie chart -`+t);let i=n.db,a=me(),s=$n(i.getConfig(),a.pie),l=40,u=18,h=4,f=450,d=f,p=Li(e),m=p.append("g");m.attr("transform","translate("+d/2+","+f/2+")");let{themeVariables:g}=a,[y]=zo(g.pieOuterStrokeWidth);y??=2;let v=s.textPosition,x=Math.min(d,f)/2-l,b=Sl().innerRadius(0).outerRadius(x),T=Sl().innerRadius(x*v).outerRadius(x*v);m.append("circle").attr("cx",0).attr("cy",0).attr("r",x+y/2).attr("class","pieOuterCircle");let S=i.getSections(),w=VVe(S),E=[g.pie1,g.pie2,g.pie3,g.pie4,g.pie5,g.pie6,g.pie7,g.pie8,g.pie9,g.pie10,g.pie11,g.pie12],_=Js(E);m.selectAll("mySlices").data(w).enter().append("path").attr("d",b).attr("fill",k=>_(k.data.label)).attr("class","pieCircle");let C=0;S.forEach(k=>{C+=k}),m.selectAll("mySlices").data(w).enter().append("text").text(k=>(k.data.value/C*100).toFixed(0)+"%").attr("transform",k=>"translate("+T.centroid(k)+")").style("text-anchor","middle").attr("class","slice"),m.append("text").text(i.getDiagramTitle()).attr("x",0).attr("y",-(f-50)/2).attr("class","pieTitleText");let D=m.selectAll(".legend").data(_.domain()).enter().append("g").attr("class","legend").attr("transform",(k,L)=>{let A=u+h,I=A*_.domain().length/2,M=12*u,P=L*A-I;return"translate("+M+","+P+")"});D.append("rect").attr("width",u).attr("height",u).style("fill",_).style("stroke",_),D.data(w).append("text").attr("x",u+h).attr("y",u-h).text(k=>{let{label:L,value:A}=k.data;return i.getShowData()?`${L} [${A}]`:L});let O=Math.max(...D.selectAll("text").nodes().map(k=>k?.getBoundingClientRect().width??0)),R=d+l+u+h+O;p.attr("viewBox",`0 0 ${R} ${f}`),fn(p,f,R,s.useMaxWidth)},"draw"),Efe={draw:UVe}});var Cfe={};ur(Cfe,{diagram:()=>HVe});var HVe,Afe=N(()=>{"use strict";Tfe();QO();kfe();Sfe();HVe={parser:bfe,db:OS,renderer:Efe,styles:wfe}});var ZO,Lfe,Rfe=N(()=>{"use strict";ZO=function(){var t=o(function(Te,W,pe,ve){for(pe=pe||{},ve=Te.length;ve--;pe[Te[ve]]=W);return pe},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[1,7],s=[1,4,5,10,12,13,14,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],l=[1,4,5,10,12,13,14,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],u=[55,56,57],h=[2,36],f=[1,37],d=[1,36],p=[1,38],m=[1,35],g=[1,43],y=[1,41],v=[1,14],x=[1,23],b=[1,18],T=[1,19],S=[1,20],w=[1,21],E=[1,22],_=[1,24],C=[1,25],D=[1,26],O=[1,27],R=[1,28],k=[1,29],L=[1,32],A=[1,33],I=[1,34],M=[1,39],P=[1,40],B=[1,42],F=[1,44],z=[1,62],$=[1,61],U=[4,5,8,10,12,13,14,18,44,47,49,55,56,57,63,64,65,66,67],K=[1,65],ee=[1,66],Y=[1,67],ce=[1,68],Z=[1,69],ue=[1,70],Q=[1,71],j=[1,72],ne=[1,73],te=[1,74],he=[1,75],le=[1,76],J=[4,5,6,7,8,9,10,11,12,13,14,15,18],Se=[1,90],se=[1,91],ae=[1,92],Oe=[1,99],ye=[1,93],Be=[1,96],He=[1,94],ze=[1,95],Le=[1,97],Ie=[1,98],xe=[1,102],q=[10,55,56,57],de=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],ie={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:o(function(W,pe,ve,Pe,_e,be,Ve){var De=be.length-1;switch(_e){case 23:this.$=be[De];break;case 24:this.$=be[De-1]+""+be[De];break;case 26:this.$=be[De-1]+be[De];break;case 27:this.$=[be[De].trim()];break;case 28:be[De-2].push(be[De].trim()),this.$=be[De-2];break;case 29:this.$=be[De-4],Pe.addClass(be[De-2],be[De]);break;case 37:this.$=[];break;case 42:this.$=be[De].trim(),Pe.setDiagramTitle(this.$);break;case 43:this.$=be[De].trim(),Pe.setAccTitle(this.$);break;case 44:case 45:this.$=be[De].trim(),Pe.setAccDescription(this.$);break;case 46:Pe.addSection(be[De].substr(8)),this.$=be[De].substr(8);break;case 47:Pe.addPoint(be[De-3],"",be[De-1],be[De],[]);break;case 48:Pe.addPoint(be[De-4],be[De-3],be[De-1],be[De],[]);break;case 49:Pe.addPoint(be[De-4],"",be[De-2],be[De-1],be[De]);break;case 50:Pe.addPoint(be[De-5],be[De-4],be[De-2],be[De-1],be[De]);break;case 51:Pe.setXAxisLeftText(be[De-2]),Pe.setXAxisRightText(be[De]);break;case 52:be[De-1].text+=" \u27F6 ",Pe.setXAxisLeftText(be[De-1]);break;case 53:Pe.setXAxisLeftText(be[De]);break;case 54:Pe.setYAxisBottomText(be[De-2]),Pe.setYAxisTopText(be[De]);break;case 55:be[De-1].text+=" \u27F6 ",Pe.setYAxisBottomText(be[De-1]);break;case 56:Pe.setYAxisBottomText(be[De]);break;case 57:Pe.setQuadrant1Text(be[De]);break;case 58:Pe.setQuadrant2Text(be[De]);break;case 59:Pe.setQuadrant3Text(be[De]);break;case 60:Pe.setQuadrant4Text(be[De]);break;case 64:this.$={text:be[De],type:"text"};break;case 65:this.$={text:be[De-1].text+""+be[De],type:be[De-1].type};break;case 66:this.$={text:be[De],type:"text"};break;case 67:this.$={text:be[De],type:"markdown"};break;case 68:this.$=be[De];break;case 69:this.$=be[De-1]+""+be[De];break}},"anonymous"),table:[{18:e,26:1,27:2,28:r,55:n,56:i,57:a},{1:[3]},{18:e,26:8,27:2,28:r,55:n,56:i,57:a},{18:e,26:9,27:2,28:r,55:n,56:i,57:a},t(s,[2,33],{29:10}),t(l,[2,61]),t(l,[2,62]),t(l,[2,63]),{1:[2,30]},{1:[2,31]},t(u,h,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:T,39:S,41:w,42:E,48:_,50:C,51:D,52:O,53:R,54:k,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(s,[2,34]),{27:45,55:n,56:i,57:a},t(u,[2,37]),t(u,h,{24:13,32:15,33:16,34:17,43:30,58:31,31:46,4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:T,39:S,41:w,42:E,48:_,50:C,51:D,52:O,53:R,54:k,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(u,[2,39]),t(u,[2,40]),t(u,[2,41]),{36:[1,47]},{38:[1,48]},{40:[1,49]},t(u,[2,45]),t(u,[2,46]),{18:[1,50]},{4:f,5:d,10:p,12:m,13:g,14:y,43:51,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:52,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:53,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:54,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:55,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,10:p,12:m,13:g,14:y,43:56,58:31,60:L,61:A,63:I,64:M,65:P,66:B,67:F},{4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,44:[1,57],47:[1,58],58:60,59:59,63:I,64:M,65:P,66:B,67:F},t(U,[2,64]),t(U,[2,66]),t(U,[2,67]),t(U,[2,70]),t(U,[2,71]),t(U,[2,72]),t(U,[2,73]),t(U,[2,74]),t(U,[2,75]),t(U,[2,76]),t(U,[2,77]),t(U,[2,78]),t(U,[2,79]),t(U,[2,80]),t(s,[2,35]),t(u,[2,38]),t(u,[2,42]),t(u,[2,43]),t(u,[2,44]),{3:64,4:K,5:ee,6:Y,7:ce,8:Z,9:ue,10:Q,11:j,12:ne,13:te,14:he,15:le,21:63},t(u,[2,53],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,77],63:I,64:M,65:P,66:B,67:F}),t(u,[2,56],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,78],63:I,64:M,65:P,66:B,67:F}),t(u,[2,57],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,58],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,59],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,60],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),{45:[1,79]},{44:[1,80]},t(U,[2,65]),t(U,[2,81]),t(U,[2,82]),t(U,[2,83]),{3:82,4:K,5:ee,6:Y,7:ce,8:Z,9:ue,10:Q,11:j,12:ne,13:te,14:he,15:le,18:[1,81]},t(J,[2,23]),t(J,[2,1]),t(J,[2,2]),t(J,[2,3]),t(J,[2,4]),t(J,[2,5]),t(J,[2,6]),t(J,[2,7]),t(J,[2,8]),t(J,[2,9]),t(J,[2,10]),t(J,[2,11]),t(J,[2,12]),t(u,[2,52],{58:31,43:83,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),t(u,[2,55],{58:31,43:84,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:A,63:I,64:M,65:P,66:B,67:F}),{46:[1,85]},{45:[1,86]},{4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,16:89,17:He,18:ze,19:Le,20:Ie,22:88,23:87},t(J,[2,24]),t(u,[2,51],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,54],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:I,64:M,65:P,66:B,67:F}),t(u,[2,47],{22:88,16:89,23:100,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),{46:[1,101]},t(u,[2,29],{10:xe}),t(q,[2,27],{16:103,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),t(de,[2,25]),t(de,[2,13]),t(de,[2,14]),t(de,[2,15]),t(de,[2,16]),t(de,[2,17]),t(de,[2,18]),t(de,[2,19]),t(de,[2,20]),t(de,[2,21]),t(de,[2,22]),t(u,[2,49],{10:xe}),t(u,[2,48],{22:88,16:89,23:104,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie}),{4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,16:89,17:He,18:ze,19:Le,20:Ie,22:105},t(de,[2,26]),t(u,[2,50],{10:xe}),t(q,[2,28],{16:103,4:Se,5:se,6:ae,8:Oe,11:ye,13:Be,17:He,18:ze,19:Le,20:Ie})],defaultActions:{8:[2,30],9:[2,31]},parseError:o(function(W,pe){if(pe.recoverable)this.trace(W);else{var ve=new Error(W);throw ve.hash=pe,ve}},"parseError"),parse:o(function(W){var pe=this,ve=[0],Pe=[],_e=[null],be=[],Ve=this.table,De="",qe=0,at=0,Rt=0,st=2,Ue=1,ct=be.slice.call(arguments,1),We=Object.create(this.lexer),ot={yy:{}};for(var Yt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Yt)&&(ot.yy[Yt]=this.yy[Yt]);We.setInput(W,ot.yy),ot.yy.lexer=We,ot.yy.parser=this,typeof We.yylloc>"u"&&(We.yylloc={});var Tt=We.yylloc;be.push(Tt);var Mt=We.options&&We.options.ranges;typeof ot.yy.parseError=="function"?this.parseError=ot.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function bt(Ce){ve.length=ve.length-2*Ce,_e.length=_e.length-Ce,be.length=be.length-Ce}o(bt,"popStack");function ut(){var Ce;return Ce=Pe.pop()||We.lex()||Ue,typeof Ce!="number"&&(Ce instanceof Array&&(Pe=Ce,Ce=Pe.pop()),Ce=pe.symbols_[Ce]||Ce),Ce}o(ut,"lex");for(var St,ft,vt,nt,pn,kt,On={},tn,Mr,Ir,Pn;;){if(vt=ve[ve.length-1],this.defaultActions[vt]?nt=this.defaultActions[vt]:((St===null||typeof St>"u")&&(St=ut()),nt=Ve[vt]&&Ve[vt][St]),typeof nt>"u"||!nt.length||!nt[0]){var Dt="";Pn=[];for(tn in Ve[vt])this.terminals_[tn]&&tn>st&&Pn.push("'"+this.terminals_[tn]+"'");We.showPosition?Dt="Parse error on line "+(qe+1)+`: -`+We.showPosition()+` -Expecting `+Pn.join(", ")+", got '"+(this.terminals_[St]||St)+"'":Dt="Parse error on line "+(qe+1)+": Unexpected "+(St==Ue?"end of input":"'"+(this.terminals_[St]||St)+"'"),this.parseError(Dt,{text:We.match,token:this.terminals_[St]||St,line:We.yylineno,loc:Tt,expected:Pn})}if(nt[0]instanceof Array&&nt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+vt+", token: "+St);switch(nt[0]){case 1:ve.push(St),_e.push(We.yytext),be.push(We.yylloc),ve.push(nt[1]),St=null,ft?(St=ft,ft=null):(at=We.yyleng,De=We.yytext,qe=We.yylineno,Tt=We.yylloc,Rt>0&&Rt--);break;case 2:if(Mr=this.productions_[nt[1]][1],On.$=_e[_e.length-Mr],On._$={first_line:be[be.length-(Mr||1)].first_line,last_line:be[be.length-1].last_line,first_column:be[be.length-(Mr||1)].first_column,last_column:be[be.length-1].last_column},Mt&&(On._$.range=[be[be.length-(Mr||1)].range[0],be[be.length-1].range[1]]),kt=this.performAction.apply(On,[De,at,qe,ot.yy,nt[1],_e,be].concat(ct)),typeof kt<"u")return kt;Mr&&(ve=ve.slice(0,-1*Mr*2),_e=_e.slice(0,-1*Mr),be=be.slice(0,-1*Mr)),ve.push(this.productions_[nt[1]][0]),_e.push(On.$),be.push(On._$),Ir=Ve[ve[ve.length-2]][ve[ve.length-1]],ve.push(Ir);break;case 3:return!0}}return!0},"parse")},oe=function(){var Te={EOF:1,parseError:o(function(pe,ve){if(this.yy.parser)this.yy.parser.parseError(pe,ve);else throw new Error(pe)},"parseError"),setInput:o(function(W,pe){return this.yy=pe||this.yy||{},this._input=W,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var W=this._input[0];this.yytext+=W,this.yyleng++,this.offset++,this.match+=W,this.matched+=W;var pe=W.match(/(?:\r\n?|\n).*/g);return pe?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),W},"input"),unput:o(function(W){var pe=W.length,ve=W.split(/(?:\r\n?|\n)/g);this._input=W+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-pe),this.offset-=pe;var Pe=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),ve.length-1&&(this.yylineno-=ve.length-1);var _e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:ve?(ve.length===Pe.length?this.yylloc.first_column:0)+Pe[Pe.length-ve.length].length-ve[0].length:this.yylloc.first_column-pe},this.options.ranges&&(this.yylloc.range=[_e[0],_e[0]+this.yyleng-pe]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(W){this.unput(this.match.slice(W))},"less"),pastInput:o(function(){var W=this.matched.substr(0,this.matched.length-this.match.length);return(W.length>20?"...":"")+W.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var W=this.match;return W.length<20&&(W+=this._input.substr(0,20-W.length)),(W.substr(0,20)+(W.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var W=this.pastInput(),pe=new Array(W.length+1).join("-");return W+this.upcomingInput()+` -`+pe+"^"},"showPosition"),test_match:o(function(W,pe){var ve,Pe,_e;if(this.options.backtrack_lexer&&(_e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(_e.yylloc.range=this.yylloc.range.slice(0))),Pe=W[0].match(/(?:\r\n?|\n).*/g),Pe&&(this.yylineno+=Pe.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Pe?Pe[Pe.length-1].length-Pe[Pe.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+W[0].length},this.yytext+=W[0],this.match+=W[0],this.matches=W,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(W[0].length),this.matched+=W[0],ve=this.performAction.call(this,this.yy,this,pe,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ve)return ve;if(this._backtrack){for(var be in _e)this[be]=_e[be];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var W,pe,ve,Pe;this._more||(this.yytext="",this.match="");for(var _e=this._currentRules(),be=0;be<_e.length;be++)if(ve=this._input.match(this.rules[_e[be]]),ve&&(!pe||ve[0].length>pe[0].length)){if(pe=ve,Pe=be,this.options.backtrack_lexer){if(W=this.test_match(ve,_e[be]),W!==!1)return W;if(this._backtrack){pe=!1;continue}else return!1}else if(!this.options.flex)break}return pe?(W=this.test_match(pe,_e[Pe]),W!==!1?W:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var pe=this.next();return pe||this.lex()},"lex"),begin:o(function(pe){this.conditionStack.push(pe)},"begin"),popState:o(function(){var pe=this.conditionStack.length-1;return pe>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(pe){return pe=this.conditionStack.length-1-Math.abs(pe||0),pe>=0?this.conditionStack[pe]:"INITIAL"},"topState"),pushState:o(function(pe){this.begin(pe)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(pe,ve,Pe,_e){var be=_e;switch(Pe){case 0:break;case 1:break;case 2:return 55;case 3:break;case 4:return this.begin("title"),35;break;case 5:return this.popState(),"title_value";break;case 6:return this.begin("acc_title"),37;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),39;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 48;case 14:return 50;case 15:return 49;case 16:return 51;case 17:return 52;case 18:return 53;case 19:return 54;case 20:return 25;case 21:this.begin("md_string");break;case 22:return"MD_STR";case 23:this.popState();break;case 24:this.begin("string");break;case 25:this.popState();break;case 26:return"STR";case 27:this.begin("class_name");break;case 28:return this.popState(),47;break;case 29:return this.begin("point_start"),44;break;case 30:return this.begin("point_x"),45;break;case 31:this.popState();break;case 32:this.popState(),this.begin("point_y");break;case 33:return this.popState(),46;break;case 34:return 28;case 35:return 4;case 36:return 11;case 37:return 64;case 38:return 10;case 39:return 65;case 40:return 65;case 41:return 14;case 42:return 13;case 43:return 67;case 44:return 66;case 45:return 12;case 46:return 8;case 47:return 5;case 48:return 18;case 49:return 56;case 50:return 63;case 51:return 57}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:classDef\b)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::::)/i,/^(?:^\w+)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{class_name:{rules:[28],inclusive:!1},point_y:{rules:[33],inclusive:!1},point_x:{rules:[32],inclusive:!1},point_start:{rules:[30,31],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[22,23],inclusive:!1},string:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,21,24,27,29,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}};return Te}();ie.lexer=oe;function V(){this.yy={}}return o(V,"Parser"),V.prototype=ie,ie.Parser=V,new V}();ZO.parser=ZO;Lfe=ZO});var xs,PS,Nfe=N(()=>{"use strict";fr();_a();yt();By();xs=dh(),PS=class{constructor(){this.classes=new Map;this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}static{o(this,"QuadrantBuilder")}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:or.quadrantChart?.chartWidth||500,chartWidth:or.quadrantChart?.chartHeight||500,titlePadding:or.quadrantChart?.titlePadding||10,titleFontSize:or.quadrantChart?.titleFontSize||20,quadrantPadding:or.quadrantChart?.quadrantPadding||5,xAxisLabelPadding:or.quadrantChart?.xAxisLabelPadding||5,yAxisLabelPadding:or.quadrantChart?.yAxisLabelPadding||5,xAxisLabelFontSize:or.quadrantChart?.xAxisLabelFontSize||16,yAxisLabelFontSize:or.quadrantChart?.yAxisLabelFontSize||16,quadrantLabelFontSize:or.quadrantChart?.quadrantLabelFontSize||16,quadrantTextTopPadding:or.quadrantChart?.quadrantTextTopPadding||5,pointTextPadding:or.quadrantChart?.pointTextPadding||5,pointLabelFontSize:or.quadrantChart?.pointLabelFontSize||12,pointRadius:or.quadrantChart?.pointRadius||5,xAxisPosition:or.quadrantChart?.xAxisPosition||"top",yAxisPosition:or.quadrantChart?.yAxisPosition||"left",quadrantInternalBorderStrokeWidth:or.quadrantChart?.quadrantInternalBorderStrokeWidth||1,quadrantExternalBorderStrokeWidth:or.quadrantChart?.quadrantExternalBorderStrokeWidth||2}}getDefaultThemeConfig(){return{quadrant1Fill:xs.quadrant1Fill,quadrant2Fill:xs.quadrant2Fill,quadrant3Fill:xs.quadrant3Fill,quadrant4Fill:xs.quadrant4Fill,quadrant1TextFill:xs.quadrant1TextFill,quadrant2TextFill:xs.quadrant2TextFill,quadrant3TextFill:xs.quadrant3TextFill,quadrant4TextFill:xs.quadrant4TextFill,quadrantPointFill:xs.quadrantPointFill,quadrantPointTextFill:xs.quadrantPointTextFill,quadrantXAxisTextFill:xs.quadrantXAxisTextFill,quadrantYAxisTextFill:xs.quadrantYAxisTextFill,quadrantTitleFill:xs.quadrantTitleFill,quadrantInternalBorderStrokeFill:xs.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:xs.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),this.classes=new Map,X.info("clear called")}setData(e){this.data={...this.data,...e}}addPoints(e){this.data.points=[...e,...this.data.points]}addClass(e,r){this.classes.set(e,r)}setConfig(e){X.trace("setConfig called with: ",e),this.config={...this.config,...e}}setThemeConfig(e){X.trace("setThemeConfig called with: ",e),this.themeConfig={...this.themeConfig,...e}}calculateSpace(e,r,n,i){let a=this.config.xAxisLabelPadding*2+this.config.xAxisLabelFontSize,s={top:e==="top"&&r?a:0,bottom:e==="bottom"&&r?a:0},l=this.config.yAxisLabelPadding*2+this.config.yAxisLabelFontSize,u={left:this.config.yAxisPosition==="left"&&n?l:0,right:this.config.yAxisPosition==="right"&&n?l:0},h=this.config.titleFontSize+this.config.titlePadding*2,f={top:i?h:0},d=this.config.quadrantPadding+u.left,p=this.config.quadrantPadding+s.top+f.top,m=this.config.chartWidth-this.config.quadrantPadding*2-u.left-u.right,g=this.config.chartHeight-this.config.quadrantPadding*2-s.top-s.bottom-f.top,y=m/2,v=g/2;return{xAxisSpace:s,yAxisSpace:u,titleSpace:f,quadrantSpace:{quadrantLeft:d,quadrantTop:p,quadrantWidth:m,quadrantHalfWidth:y,quadrantHeight:g,quadrantHalfHeight:v}}}getAxisLabels(e,r,n,i){let{quadrantSpace:a,titleSpace:s}=i,{quadrantHalfHeight:l,quadrantHeight:u,quadrantLeft:h,quadrantHalfWidth:f,quadrantTop:d,quadrantWidth:p}=a,m=!!this.data.xAxisRightText,g=!!this.data.yAxisTopText,y=[];return this.data.xAxisLeftText&&r&&y.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&r&&y.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+f+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&n&&y.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+u-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&n&&y.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+l-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),y}getQuadrants(e){let{quadrantSpace:r}=e,{quadrantHalfHeight:n,quadrantLeft:i,quadrantHalfWidth:a,quadrantTop:s}=r,l=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s,width:a,height:n,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s,width:a,height:n,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant4Fill}];for(let u of l)u.text.x=u.x+u.width/2,this.data.points.length===0?(u.text.y=u.y+u.height/2,u.text.horizontalPos="middle"):(u.text.y=u.y+this.config.quadrantTextTopPadding,u.text.horizontalPos="top");return l}getQuadrantPoints(e){let{quadrantSpace:r}=e,{quadrantHeight:n,quadrantLeft:i,quadrantTop:a,quadrantWidth:s}=r,l=Tl().domain([0,1]).range([i,s+i]),u=Tl().domain([0,1]).range([n+a,a]);return this.data.points.map(f=>{let d=this.classes.get(f.className);return d&&(f={...d,...f}),{x:l(f.x),y:u(f.y),fill:f.color??this.themeConfig.quadrantPointFill,radius:f.radius??this.config.pointRadius,text:{text:f.text,fill:this.themeConfig.quadrantPointTextFill,x:l(f.x),y:u(f.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0},strokeColor:f.strokeColor??this.themeConfig.quadrantPointFill,strokeWidth:f.strokeWidth??"0px"}})}getBorders(e){let r=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:n}=e,{quadrantHalfHeight:i,quadrantHeight:a,quadrantLeft:s,quadrantHalfWidth:l,quadrantTop:u,quadrantWidth:h}=n;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u,x2:s+h+r,y2:u},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s+h,y1:u+r,x2:s+h,y2:u+a-r},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u+a,x2:s+h+r,y2:u+a},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s,y1:u+r,x2:s,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+l,y1:u+r,x2:s+l,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+r,y1:u+i,x2:s+h-r,y2:u+i}]}getTitle(e){if(e)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){let e=this.config.showXAxis&&!!(this.data.xAxisLeftText||this.data.xAxisRightText),r=this.config.showYAxis&&!!(this.data.yAxisTopText||this.data.yAxisBottomText),n=this.config.showTitle&&!!this.data.titleText,i=this.data.points.length>0?"bottom":this.config.xAxisPosition,a=this.calculateSpace(i,e,r,n);return{points:this.getQuadrantPoints(a),quadrants:this.getQuadrants(a),axisLabels:this.getAxisLabels(i,e,r,a),borderLines:this.getBorders(a),title:this.getTitle(n)}}}});function JO(t){return!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(t)}function Mfe(t){return!/^\d+$/.test(t)}function Ife(t){return!/^\d+px$/.test(t)}var Bp,Ofe=N(()=>{"use strict";Bp=class extends Error{static{o(this,"InvalidStyleError")}constructor(e,r,n){super(`value for ${e} ${r} is invalid, please use a valid ${n}`),this.name="InvalidStyleError"}};o(JO,"validateHexCode");o(Mfe,"validateNumber");o(Ife,"validateSizeInPixels")});function eh(t){return wr(t.trim(),YVe)}function XVe(t){wa.setData({quadrant1Text:eh(t.text)})}function jVe(t){wa.setData({quadrant2Text:eh(t.text)})}function KVe(t){wa.setData({quadrant3Text:eh(t.text)})}function QVe(t){wa.setData({quadrant4Text:eh(t.text)})}function ZVe(t){wa.setData({xAxisLeftText:eh(t.text)})}function JVe(t){wa.setData({xAxisRightText:eh(t.text)})}function eUe(t){wa.setData({yAxisTopText:eh(t.text)})}function tUe(t){wa.setData({yAxisBottomText:eh(t.text)})}function eP(t){let e={};for(let r of t){let[n,i]=r.trim().split(/\s*:\s*/);if(n==="radius"){if(Mfe(i))throw new Bp(n,i,"number");e.radius=parseInt(i)}else if(n==="color"){if(JO(i))throw new Bp(n,i,"hex code");e.color=i}else if(n==="stroke-color"){if(JO(i))throw new Bp(n,i,"hex code");e.strokeColor=i}else if(n==="stroke-width"){if(Ife(i))throw new Bp(n,i,"number of pixels (eg. 10px)");e.strokeWidth=i}else throw new Error(`style named ${n} is not supported.`)}return e}function rUe(t,e,r,n,i){let a=eP(i);wa.addPoints([{x:r,y:n,text:eh(t.text),className:e,...a}])}function nUe(t,e){wa.addClass(t,eP(e))}function iUe(t){wa.setConfig({chartWidth:t})}function aUe(t){wa.setConfig({chartHeight:t})}function sUe(){let t=me(),{themeVariables:e,quadrantChart:r}=t;return r&&wa.setConfig(r),wa.setThemeConfig({quadrant1Fill:e.quadrant1Fill,quadrant2Fill:e.quadrant2Fill,quadrant3Fill:e.quadrant3Fill,quadrant4Fill:e.quadrant4Fill,quadrant1TextFill:e.quadrant1TextFill,quadrant2TextFill:e.quadrant2TextFill,quadrant3TextFill:e.quadrant3TextFill,quadrant4TextFill:e.quadrant4TextFill,quadrantPointFill:e.quadrantPointFill,quadrantPointTextFill:e.quadrantPointTextFill,quadrantXAxisTextFill:e.quadrantXAxisTextFill,quadrantYAxisTextFill:e.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:e.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:e.quadrantInternalBorderStrokeFill,quadrantTitleFill:e.quadrantTitleFill}),wa.setData({titleText:Nr()}),wa.build()}var YVe,wa,oUe,Pfe,Bfe=N(()=>{"use strict";Gt();pr();ci();Nfe();Ofe();YVe=me();o(eh,"textSanitizer");wa=new PS;o(XVe,"setQuadrant1Text");o(jVe,"setQuadrant2Text");o(KVe,"setQuadrant3Text");o(QVe,"setQuadrant4Text");o(ZVe,"setXAxisLeftText");o(JVe,"setXAxisRightText");o(eUe,"setYAxisTopText");o(tUe,"setYAxisBottomText");o(eP,"parseStyles");o(rUe,"addPoint");o(nUe,"addClass");o(iUe,"setWidth");o(aUe,"setHeight");o(sUe,"getQuadrantData");oUe=o(function(){wa.clear(),kr()},"clear"),Pfe={setWidth:iUe,setHeight:aUe,setQuadrant1Text:XVe,setQuadrant2Text:jVe,setQuadrant3Text:KVe,setQuadrant4Text:QVe,setXAxisLeftText:ZVe,setXAxisRightText:JVe,setYAxisTopText:eUe,setYAxisBottomText:tUe,parseStyles:eP,addPoint:rUe,addClass:nUe,getQuadrantData:sUe,clear:oUe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var lUe,Ffe,$fe=N(()=>{"use strict";fr();Gt();yt();xi();lUe=o((t,e,r,n)=>{function i(C){return C==="top"?"hanging":"middle"}o(i,"getDominantBaseLine");function a(C){return C==="left"?"start":"middle"}o(a,"getTextAnchor");function s(C){return`translate(${C.x}, ${C.y}) rotate(${C.rotation||0})`}o(s,"getTransformation");let l=me();X.debug(`Rendering quadrant chart -`+t);let u=l.securityLevel,h;u==="sandbox"&&(h=Ge("#i"+e));let d=(u==="sandbox"?Ge(h.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${e}"]`),p=d.append("g").attr("class","main"),m=l.quadrantChart?.chartWidth??500,g=l.quadrantChart?.chartHeight??500;fn(d,g,m,l.quadrantChart?.useMaxWidth??!0),d.attr("viewBox","0 0 "+m+" "+g),n.db.setHeight(g),n.db.setWidth(m);let y=n.db.getQuadrantData(),v=p.append("g").attr("class","quadrants"),x=p.append("g").attr("class","border"),b=p.append("g").attr("class","data-points"),T=p.append("g").attr("class","labels"),S=p.append("g").attr("class","title");y.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",y.title.fill).attr("font-size",y.title.fontSize).attr("dominant-baseline",i(y.title.horizontalPos)).attr("text-anchor",a(y.title.verticalPos)).attr("transform",s(y.title)).text(y.title.text),y.borderLines&&x.selectAll("line").data(y.borderLines).enter().append("line").attr("x1",C=>C.x1).attr("y1",C=>C.y1).attr("x2",C=>C.x2).attr("y2",C=>C.y2).style("stroke",C=>C.strokeFill).style("stroke-width",C=>C.strokeWidth);let w=v.selectAll("g.quadrant").data(y.quadrants).enter().append("g").attr("class","quadrant");w.append("rect").attr("x",C=>C.x).attr("y",C=>C.y).attr("width",C=>C.width).attr("height",C=>C.height).attr("fill",C=>C.fill),w.append("text").attr("x",0).attr("y",0).attr("fill",C=>C.text.fill).attr("font-size",C=>C.text.fontSize).attr("dominant-baseline",C=>i(C.text.horizontalPos)).attr("text-anchor",C=>a(C.text.verticalPos)).attr("transform",C=>s(C.text)).text(C=>C.text.text),T.selectAll("g.label").data(y.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text(C=>C.text).attr("fill",C=>C.fill).attr("font-size",C=>C.fontSize).attr("dominant-baseline",C=>i(C.horizontalPos)).attr("text-anchor",C=>a(C.verticalPos)).attr("transform",C=>s(C));let _=b.selectAll("g.data-point").data(y.points).enter().append("g").attr("class","data-point");_.append("circle").attr("cx",C=>C.x).attr("cy",C=>C.y).attr("r",C=>C.radius).attr("fill",C=>C.fill).attr("stroke",C=>C.strokeColor).attr("stroke-width",C=>C.strokeWidth),_.append("text").attr("x",0).attr("y",0).text(C=>C.text.text).attr("fill",C=>C.text.fill).attr("font-size",C=>C.text.fontSize).attr("dominant-baseline",C=>i(C.text.horizontalPos)).attr("text-anchor",C=>a(C.text.verticalPos)).attr("transform",C=>s(C.text))},"draw"),Ffe={draw:lUe}});var zfe={};ur(zfe,{diagram:()=>cUe});var cUe,Gfe=N(()=>{"use strict";Rfe();Bfe();$fe();cUe={parser:Lfe,db:Pfe,renderer:Ffe,styles:o(()=>"","styles")}});var tP,Hfe,Wfe=N(()=>{"use strict";tP=function(){var t=o(function(I,M,P,B){for(P=P||{},B=I.length;B--;P[I[B]]=M);return P},"o"),e=[1,10,12,14,16,18,19,21,23],r=[2,6],n=[1,3],i=[1,5],a=[1,6],s=[1,7],l=[1,5,10,12,14,16,18,19,21,23,34,35,36],u=[1,25],h=[1,26],f=[1,28],d=[1,29],p=[1,30],m=[1,31],g=[1,32],y=[1,33],v=[1,34],x=[1,35],b=[1,36],T=[1,37],S=[1,43],w=[1,42],E=[1,47],_=[1,50],C=[1,10,12,14,16,18,19,21,23,34,35,36],D=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],O=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],R=[1,64],k={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:o(function(M,P,B,F,z,$,U){var K=$.length-1;switch(z){case 5:F.setOrientation($[K]);break;case 9:F.setDiagramTitle($[K].text.trim());break;case 12:F.setLineData({text:"",type:"text"},$[K]);break;case 13:F.setLineData($[K-1],$[K]);break;case 14:F.setBarData({text:"",type:"text"},$[K]);break;case 15:F.setBarData($[K-1],$[K]);break;case 16:this.$=$[K].trim(),F.setAccTitle(this.$);break;case 17:case 18:this.$=$[K].trim(),F.setAccDescription(this.$);break;case 19:this.$=$[K-1];break;case 20:this.$=[Number($[K-2]),...$[K]];break;case 21:this.$=[Number($[K])];break;case 22:F.setXAxisTitle($[K]);break;case 23:F.setXAxisTitle($[K-1]);break;case 24:F.setXAxisTitle({type:"text",text:""});break;case 25:F.setXAxisBand($[K]);break;case 26:F.setXAxisRangeData(Number($[K-2]),Number($[K]));break;case 27:this.$=$[K-1];break;case 28:this.$=[$[K-2],...$[K]];break;case 29:this.$=[$[K]];break;case 30:F.setYAxisTitle($[K]);break;case 31:F.setYAxisTitle($[K-1]);break;case 32:F.setYAxisTitle({type:"text",text:""});break;case 33:F.setYAxisRangeData(Number($[K-2]),Number($[K]));break;case 37:this.$={text:$[K],type:"text"};break;case 38:this.$={text:$[K],type:"text"};break;case 39:this.$={text:$[K],type:"markdown"};break;case 40:this.$=$[K];break;case 41:this.$=$[K-1]+""+$[K];break}},"anonymous"),table:[t(e,r,{3:1,4:2,7:4,5:n,34:i,35:a,36:s}),{1:[3]},t(e,r,{4:2,7:4,3:8,5:n,34:i,35:a,36:s}),t(e,r,{4:2,7:4,6:9,3:10,5:n,8:[1,11],34:i,35:a,36:s}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(l,[2,34]),t(l,[2,35]),t(l,[2,36]),{1:[2,1]},t(e,r,{4:2,7:4,3:21,5:n,34:i,35:a,36:s}),{1:[2,3]},t(l,[2,5]),t(e,[2,7],{4:22,34:i,35:a,36:s}),{11:23,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:39,13:38,24:S,27:w,29:40,30:41,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:45,15:44,27:E,33:46,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:49,17:48,24:_,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{11:52,17:51,24:_,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},{20:[1,53]},{22:[1,54]},t(C,[2,18]),{1:[2,2]},t(C,[2,8]),t(C,[2,9]),t(D,[2,37],{40:55,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T}),t(D,[2,38]),t(D,[2,39]),t(O,[2,40]),t(O,[2,42]),t(O,[2,43]),t(O,[2,44]),t(O,[2,45]),t(O,[2,46]),t(O,[2,47]),t(O,[2,48]),t(O,[2,49]),t(O,[2,50]),t(O,[2,51]),t(C,[2,10]),t(C,[2,22],{30:41,29:56,24:S,27:w}),t(C,[2,24]),t(C,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},t(C,[2,11]),t(C,[2,30],{33:60,27:E}),t(C,[2,32]),{31:[1,61]},t(C,[2,12]),{17:62,24:_},{25:63,27:R},t(C,[2,14]),{17:65,24:_},t(C,[2,16]),t(C,[2,17]),t(O,[2,41]),t(C,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(C,[2,31]),{27:[1,69]},t(C,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(C,[2,15]),t(C,[2,26]),t(C,[2,27]),{11:59,32:72,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:T},t(C,[2,33]),t(C,[2,19]),{25:73,27:R},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:o(function(M,P){if(P.recoverable)this.trace(M);else{var B=new Error(M);throw B.hash=P,B}},"parseError"),parse:o(function(M){var P=this,B=[0],F=[],z=[null],$=[],U=this.table,K="",ee=0,Y=0,ce=0,Z=2,ue=1,Q=$.slice.call(arguments,1),j=Object.create(this.lexer),ne={yy:{}};for(var te in this.yy)Object.prototype.hasOwnProperty.call(this.yy,te)&&(ne.yy[te]=this.yy[te]);j.setInput(M,ne.yy),ne.yy.lexer=j,ne.yy.parser=this,typeof j.yylloc>"u"&&(j.yylloc={});var he=j.yylloc;$.push(he);var le=j.options&&j.options.ranges;typeof ne.yy.parseError=="function"?this.parseError=ne.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function J(ie){B.length=B.length-2*ie,z.length=z.length-ie,$.length=$.length-ie}o(J,"popStack");function Se(){var ie;return ie=F.pop()||j.lex()||ue,typeof ie!="number"&&(ie instanceof Array&&(F=ie,ie=F.pop()),ie=P.symbols_[ie]||ie),ie}o(Se,"lex");for(var se,ae,Oe,ye,Be,He,ze={},Le,Ie,xe,q;;){if(Oe=B[B.length-1],this.defaultActions[Oe]?ye=this.defaultActions[Oe]:((se===null||typeof se>"u")&&(se=Se()),ye=U[Oe]&&U[Oe][se]),typeof ye>"u"||!ye.length||!ye[0]){var de="";q=[];for(Le in U[Oe])this.terminals_[Le]&&Le>Z&&q.push("'"+this.terminals_[Le]+"'");j.showPosition?de="Parse error on line "+(ee+1)+`: -`+j.showPosition()+` -Expecting `+q.join(", ")+", got '"+(this.terminals_[se]||se)+"'":de="Parse error on line "+(ee+1)+": Unexpected "+(se==ue?"end of input":"'"+(this.terminals_[se]||se)+"'"),this.parseError(de,{text:j.match,token:this.terminals_[se]||se,line:j.yylineno,loc:he,expected:q})}if(ye[0]instanceof Array&&ye.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Oe+", token: "+se);switch(ye[0]){case 1:B.push(se),z.push(j.yytext),$.push(j.yylloc),B.push(ye[1]),se=null,ae?(se=ae,ae=null):(Y=j.yyleng,K=j.yytext,ee=j.yylineno,he=j.yylloc,ce>0&&ce--);break;case 2:if(Ie=this.productions_[ye[1]][1],ze.$=z[z.length-Ie],ze._$={first_line:$[$.length-(Ie||1)].first_line,last_line:$[$.length-1].last_line,first_column:$[$.length-(Ie||1)].first_column,last_column:$[$.length-1].last_column},le&&(ze._$.range=[$[$.length-(Ie||1)].range[0],$[$.length-1].range[1]]),He=this.performAction.apply(ze,[K,Y,ee,ne.yy,ye[1],z,$].concat(Q)),typeof He<"u")return He;Ie&&(B=B.slice(0,-1*Ie*2),z=z.slice(0,-1*Ie),$=$.slice(0,-1*Ie)),B.push(this.productions_[ye[1]][0]),z.push(ze.$),$.push(ze._$),xe=U[B[B.length-2]][B[B.length-1]],B.push(xe);break;case 3:return!0}}return!0},"parse")},L=function(){var I={EOF:1,parseError:o(function(P,B){if(this.yy.parser)this.yy.parser.parseError(P,B);else throw new Error(P)},"parseError"),setInput:o(function(M,P){return this.yy=P||this.yy||{},this._input=M,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var M=this._input[0];this.yytext+=M,this.yyleng++,this.offset++,this.match+=M,this.matched+=M;var P=M.match(/(?:\r\n?|\n).*/g);return P?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),M},"input"),unput:o(function(M){var P=M.length,B=M.split(/(?:\r\n?|\n)/g);this._input=M+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-P),this.offset-=P;var F=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),B.length-1&&(this.yylineno-=B.length-1);var z=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:B?(B.length===F.length?this.yylloc.first_column:0)+F[F.length-B.length].length-B[0].length:this.yylloc.first_column-P},this.options.ranges&&(this.yylloc.range=[z[0],z[0]+this.yyleng-P]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(M){this.unput(this.match.slice(M))},"less"),pastInput:o(function(){var M=this.matched.substr(0,this.matched.length-this.match.length);return(M.length>20?"...":"")+M.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var M=this.match;return M.length<20&&(M+=this._input.substr(0,20-M.length)),(M.substr(0,20)+(M.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var M=this.pastInput(),P=new Array(M.length+1).join("-");return M+this.upcomingInput()+` -`+P+"^"},"showPosition"),test_match:o(function(M,P){var B,F,z;if(this.options.backtrack_lexer&&(z={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(z.yylloc.range=this.yylloc.range.slice(0))),F=M[0].match(/(?:\r\n?|\n).*/g),F&&(this.yylineno+=F.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:F?F[F.length-1].length-F[F.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+M[0].length},this.yytext+=M[0],this.match+=M[0],this.matches=M,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(M[0].length),this.matched+=M[0],B=this.performAction.call(this,this.yy,this,P,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),B)return B;if(this._backtrack){for(var $ in z)this[$]=z[$];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var M,P,B,F;this._more||(this.yytext="",this.match="");for(var z=this._currentRules(),$=0;$P[0].length)){if(P=B,F=$,this.options.backtrack_lexer){if(M=this.test_match(B,z[$]),M!==!1)return M;if(this._backtrack){P=!1;continue}else return!1}else if(!this.options.flex)break}return P?(M=this.test_match(P,z[F]),M!==!1?M:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var P=this.next();return P||this.lex()},"lex"),begin:o(function(P){this.conditionStack.push(P)},"begin"),popState:o(function(){var P=this.conditionStack.length-1;return P>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(P){return P=this.conditionStack.length-1-Math.abs(P||0),P>=0?this.conditionStack[P]:"INITIAL"},"topState"),pushState:o(function(P){this.begin(P)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(P,B,F,z){var $=z;switch(F){case 0:break;case 1:break;case 2:return this.popState(),34;break;case 3:return this.popState(),34;break;case 4:return 34;case 5:break;case 6:return 10;case 7:return this.pushState("acc_title"),19;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.pushState("acc_descr"),21;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.pushState("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";break;case 17:return this.pushState("axis_data"),"Y_AXIS";break;case 18:return this.pushState("axis_band_data"),24;break;case 19:return 31;case 20:return this.pushState("data"),16;break;case 21:return this.pushState("data"),18;break;case 22:return this.pushState("data_inner"),24;break;case 23:return 27;case 24:return this.popState(),26;break;case 25:this.popState();break;case 26:this.pushState("string");break;case 27:this.popState();break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 43:break;case 44:return 35;case 45:return 36}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};return I}();k.lexer=L;function A(){this.yy={}}return o(A,"Parser"),A.prototype=k,k.Parser=A,new A}();tP.parser=tP;Hfe=tP});function rP(t){return t.type==="bar"}function BS(t){return t.type==="band"}function N1(t){return t.type==="linear"}var FS=N(()=>{"use strict";o(rP,"isBarPlot");o(BS,"isBandAxisData");o(N1,"isLinearAxisData")});var M1,nP=N(()=>{"use strict";ao();M1=class{constructor(e){this.parentGroup=e}static{o(this,"TextDimensionCalculatorWithFont")}getMaxDimension(e,r){if(!this.parentGroup)return{width:e.reduce((a,s)=>Math.max(s.length,a),0)*r,height:r};let n={width:0,height:0},i=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",r);for(let a of e){let s=wQ(i,1,a),l=s?s.width:a.length*r,u=s?s.height:r;n.width=Math.max(n.width,l),n.height=Math.max(n.height,u)}return i.remove(),n}}});var I1,iP=N(()=>{"use strict";I1=class{constructor(e,r,n,i){this.axisConfig=e;this.title=r;this.textDimensionCalculator=n;this.axisThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0};this.axisPosition="left";this.showTitle=!1;this.showLabel=!1;this.showTick=!1;this.showAxisLine=!1;this.outerPadding=0;this.titleTextHeight=0;this.labelTextHeight=0;this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}static{o(this,"BaseAxis")}setRange(e){this.range=e,this.axisPosition==="left"||this.axisPosition==="right"?this.boundingRect.height=e[1]-e[0]:this.boundingRect.width=e[1]-e[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(e){this.axisPosition=e,this.setRange(this.range)}getTickDistance(){let e=this.getRange();return Math.abs(e[0]-e[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(e=>e.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>this.outerPadding*2&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(e){let r=e.height;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.width;this.outerPadding=Math.min(n.width/2,i);let a=n.height+this.axisConfig.labelPadding*2;this.labelTextHeight=n.height,a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width,this.boundingRect.height=e.height-r}calculateSpaceIfDrawnVertical(e){let r=e.width;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.height;this.outerPadding=Math.min(n.height/2,i);let a=n.width+this.axisConfig.labelPadding*2;a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width-r,this.boundingRect.height=e.height}calculateSpace(e){return this.axisPosition==="left"||this.axisPosition==="right"?this.calculateSpaceIfDrawnVertical(e):this.calculateSpaceIfDrawnHorizontally(e),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}getDrawableElementsForLeftAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${r},${this.boundingRect.y} L ${r},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(r),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){let r=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${r},${this.getScaleValue(n)} L ${r-this.axisConfig.tickLength},${this.getScaleValue(n)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForBottomAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r} L ${this.getScaleValue(n)},${r+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForTopAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+this.axisConfig.titlePadding*2:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y;e.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(n)},${r+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElements(){if(this.axisPosition==="left")return this.getDrawableElementsForLeftAxis();if(this.axisPosition==="right")throw Error("Drawing of right axis is not implemented");return this.axisPosition==="bottom"?this.getDrawableElementsForBottomAxis():this.axisPosition==="top"?this.getDrawableElementsForTopAxis():[]}}});var $S,qfe=N(()=>{"use strict";fr();yt();iP();$S=class extends I1{static{o(this,"BandAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.categories=n,this.scale=V0().domain(this.categories).range(this.getRange())}setRange(e){super.setRange(e)}recalculateScale(){this.scale=V0().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),X.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(e){return this.scale(e)??this.getRange()[0]}}});var zS,Yfe=N(()=>{"use strict";fr();iP();zS=class extends I1{static{o(this,"LinearAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.domain=n,this.scale=Tl().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){let e=[...this.domain];this.axisPosition==="left"&&e.reverse(),this.scale=Tl().domain(e).range(this.getRange())}getScaleValue(e){return this.scale(e)}}});function aP(t,e,r,n){let i=new M1(n);return BS(t)?new $S(e,r,t.categories,t.title,i):new zS(e,r,[t.min,t.max],t.title,i)}var Xfe=N(()=>{"use strict";FS();nP();qfe();Yfe();o(aP,"getAxis")});function jfe(t,e,r,n){let i=new M1(n);return new sP(i,t,e,r)}var sP,Kfe=N(()=>{"use strict";nP();sP=class{constructor(e,r,n,i){this.textDimensionCalculator=e;this.chartConfig=r;this.chartData=n;this.chartThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}static{o(this,"ChartTitle")}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){let r=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),n=Math.max(r.width,e.width),i=r.height+2*this.chartConfig.titlePadding;return r.width<=n&&r.height<=i&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=n,this.boundingRect.height=i,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){let e=[];return this.showChartTitle&&e.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),e}};o(jfe,"getChartTitleComponent")});var GS,Qfe=N(()=>{"use strict";fr();GS=class{constructor(e,r,n,i,a){this.plotData=e;this.xAxis=r;this.yAxis=n;this.orientation=i;this.plotIndex=a}static{o(this,"LinePlot")}getDrawableElement(){let e=this.plotData.data.map(n=>[this.xAxis.getScaleValue(n[0]),this.yAxis.getScaleValue(n[1])]),r;return this.orientation==="horizontal"?r=Cl().y(n=>n[0]).x(n=>n[1])(e):r=Cl().x(n=>n[0]).y(n=>n[1])(e),r?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:r,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}});var VS,Zfe=N(()=>{"use strict";VS=class{constructor(e,r,n,i,a,s){this.barData=e;this.boundingRect=r;this.xAxis=n;this.yAxis=i;this.orientation=a;this.plotIndex=s}static{o(this,"BarPlot")}getDrawableElement(){let e=this.barData.data.map(a=>[this.xAxis.getScaleValue(a[0]),this.yAxis.getScaleValue(a[1])]),n=Math.min(this.xAxis.getAxisOuterPadding()*2,this.xAxis.getTickDistance())*(1-.05),i=n/2;return this.orientation==="horizontal"?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:this.boundingRect.x,y:a[0]-i,height:n,width:a[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:a[0]-i,y:a[1],width:n,height:this.boundingRect.y+this.boundingRect.height-a[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}}});function Jfe(t,e,r){return new oP(t,e,r)}var oP,ede=N(()=>{"use strict";Qfe();Zfe();oP=class{constructor(e,r,n){this.chartConfig=e;this.chartData=r;this.chartThemeConfig=n;this.boundingRect={x:0,y:0,width:0,height:0}}static{o(this,"BasePlot")}setAxes(e,r){this.xAxis=e,this.yAxis=r}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){return this.boundingRect.width=e.width,this.boundingRect.height=e.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!(this.xAxis&&this.yAxis))throw Error("Axes must be passed to render Plots");let e=[];for(let[r,n]of this.chartData.plots.entries())switch(n.type){case"line":{let i=new GS(n,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break;case"bar":{let i=new VS(n,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break}return e}};o(Jfe,"getPlotComponent")});var US,tde=N(()=>{"use strict";Xfe();Kfe();ede();FS();US=class{constructor(e,r,n,i){this.chartConfig=e;this.chartData=r;this.componentStore={title:jfe(e,r,n,i),plot:Jfe(e,r,n),xAxis:aP(r.xAxis,e.xAxis,{titleColor:n.xAxisTitleColor,labelColor:n.xAxisLabelColor,tickColor:n.xAxisTickColor,axisLineColor:n.xAxisLineColor},i),yAxis:aP(r.yAxis,e.yAxis,{titleColor:n.yAxisTitleColor,labelColor:n.yAxisLabelColor,tickColor:n.yAxisTickColor,axisLineColor:n.yAxisLineColor},i)}}static{o(this,"Orchestrator")}calculateVerticalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),s=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),l=this.componentStore.plot.calculateSpace({width:a,height:s});e-=l.width,r-=l.height,l=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),i=l.height,r-=l.height,this.componentStore.xAxis.setAxisPosition("bottom"),l=this.componentStore.xAxis.calculateSpace({width:e,height:r}),r-=l.height,this.componentStore.yAxis.setAxisPosition("left"),l=this.componentStore.yAxis.calculateSpace({width:e,height:r}),n=l.width,e-=l.width,e>0&&(a+=e,e=0),r>0&&(s+=r,r=0),this.componentStore.plot.calculateSpace({width:a,height:s}),this.componentStore.plot.setBoundingBoxXY({x:n,y:i}),this.componentStore.xAxis.setRange([n,n+a]),this.componentStore.xAxis.setBoundingBoxXY({x:n,y:i+s}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:i}),this.chartData.plots.some(u=>rP(u))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=0,s=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),l=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),u=this.componentStore.plot.calculateSpace({width:s,height:l});e-=u.width,r-=u.height,u=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),n=u.height,r-=u.height,this.componentStore.xAxis.setAxisPosition("left"),u=this.componentStore.xAxis.calculateSpace({width:e,height:r}),e-=u.width,i=u.width,this.componentStore.yAxis.setAxisPosition("top"),u=this.componentStore.yAxis.calculateSpace({width:e,height:r}),r-=u.height,a=n+u.height,e>0&&(s+=e,e=0),r>0&&(l+=r,r=0),this.componentStore.plot.calculateSpace({width:s,height:l}),this.componentStore.plot.setBoundingBoxXY({x:i,y:a}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:i,y:n}),this.componentStore.xAxis.setRange([a,a+l]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:a}),this.chartData.plots.some(h=>rP(h))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){this.chartConfig.chartOrientation==="horizontal"?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();let e=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(let r of Object.values(this.componentStore))e.push(...r.getDrawableElements());return e}}});var HS,rde=N(()=>{"use strict";tde();HS=class{static{o(this,"XYChartBuilder")}static build(e,r,n,i){return new US(e,r,n,i).getDrawableElement()}}});function ide(){let t=dh(),e=tr();return $n(t.xyChart,e.themeVariables.xyChart)}function ade(){let t=tr();return $n(or.xyChart,t.xyChart)}function sde(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function uP(t){let e=tr();return wr(t.trim(),e)}function dUe(t){nde=t}function pUe(t){t==="horizontal"?Rb.chartOrientation="horizontal":Rb.chartOrientation="vertical"}function mUe(t){cn.xAxis.title=uP(t.text)}function ode(t,e){cn.xAxis={type:"linear",title:cn.xAxis.title,min:t,max:e},WS=!0}function gUe(t){cn.xAxis={type:"band",title:cn.xAxis.title,categories:t.map(e=>uP(e.text))},WS=!0}function yUe(t){cn.yAxis.title=uP(t.text)}function vUe(t,e){cn.yAxis={type:"linear",title:cn.yAxis.title,min:t,max:e},cP=!0}function xUe(t){let e=Math.min(...t),r=Math.max(...t),n=N1(cn.yAxis)?cn.yAxis.min:1/0,i=N1(cn.yAxis)?cn.yAxis.max:-1/0;cn.yAxis={type:"linear",title:cn.yAxis.title,min:Math.min(n,e),max:Math.max(i,r)}}function lde(t){let e=[];if(t.length===0)return e;if(!WS){let r=N1(cn.xAxis)?cn.xAxis.min:1/0,n=N1(cn.xAxis)?cn.xAxis.max:-1/0;ode(Math.min(r,1),Math.max(n,t.length))}if(cP||xUe(t),BS(cn.xAxis)&&(e=cn.xAxis.categories.map((r,n)=>[r,t[n]])),N1(cn.xAxis)){let r=cn.xAxis.min,n=cn.xAxis.max,i=(n-r)/(t.length-1),a=[];for(let s=r;s<=n;s+=i)a.push(`${s}`);e=a.map((s,l)=>[s,t[l]])}return e}function cde(t){return lP[t===0?0:t%lP.length]}function bUe(t,e){let r=lde(e);cn.plots.push({type:"line",strokeFill:cde(Lb),strokeWidth:2,data:r}),Lb++}function TUe(t,e){let r=lde(e);cn.plots.push({type:"bar",fill:cde(Lb),data:r}),Lb++}function wUe(){if(cn.plots.length===0)throw Error("No Plot to render, please provide a plot with some data");return cn.title=Nr(),HS.build(Rb,cn,Nb,nde)}function kUe(){return Nb}function EUe(){return Rb}function SUe(){return cn}var Lb,nde,Rb,Nb,cn,lP,WS,cP,CUe,ude,hde=N(()=>{"use strict";mi();_a();By();er();pr();ci();rde();FS();Lb=0,Rb=ade(),Nb=ide(),cn=sde(),lP=Nb.plotColorPalette.split(",").map(t=>t.trim()),WS=!1,cP=!1;o(ide,"getChartDefaultThemeConfig");o(ade,"getChartDefaultConfig");o(sde,"getChartDefaultData");o(uP,"textSanitizer");o(dUe,"setTmpSVGG");o(pUe,"setOrientation");o(mUe,"setXAxisTitle");o(ode,"setXAxisRangeData");o(gUe,"setXAxisBand");o(yUe,"setYAxisTitle");o(vUe,"setYAxisRangeData");o(xUe,"setYAxisRangeFromPlotData");o(lde,"transformDataWithoutCategory");o(cde,"getPlotColorFromPalette");o(bUe,"setLineData");o(TUe,"setBarData");o(wUe,"getDrawableElem");o(kUe,"getChartThemeConfig");o(EUe,"getChartConfig");o(SUe,"getXYChartData");CUe=o(function(){kr(),Lb=0,Rb=ade(),cn=sde(),Nb=ide(),lP=Nb.plotColorPalette.split(",").map(t=>t.trim()),WS=!1,cP=!1},"clear"),ude={getDrawableElem:wUe,clear:CUe,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr,setOrientation:pUe,setXAxisTitle:mUe,setXAxisRangeData:ode,setXAxisBand:gUe,setYAxisTitle:yUe,setYAxisRangeData:vUe,setLineData:bUe,setBarData:TUe,setTmpSVGG:dUe,getChartThemeConfig:kUe,getChartConfig:EUe,getXYChartData:SUe}});var AUe,fde,dde=N(()=>{"use strict";yt();Vl();xi();AUe=o((t,e,r,n)=>{let i=n.db,a=i.getChartThemeConfig(),s=i.getChartConfig(),l=i.getXYChartData().plots[0].data.map(T=>T[1]);function u(T){return T==="top"?"text-before-edge":"middle"}o(u,"getDominantBaseLine");function h(T){return T==="left"?"start":T==="right"?"end":"middle"}o(h,"getTextAnchor");function f(T){return`translate(${T.x}, ${T.y}) rotate(${T.rotation||0})`}o(f,"getTextTransformation"),X.debug(`Rendering xychart chart -`+t);let d=Li(e),p=d.append("g").attr("class","main"),m=p.append("rect").attr("width",s.width).attr("height",s.height).attr("class","background");fn(d,s.height,s.width,!0),d.attr("viewBox",`0 0 ${s.width} ${s.height}`),m.attr("fill",a.backgroundColor),i.setTmpSVGG(d.append("g").attr("class","mermaid-tmp-group"));let g=i.getDrawableElem(),y={};function v(T){let S=p,w="";for(let[E]of T.entries()){let _=p;E>0&&y[w]&&(_=y[w]),w+=T[E],S=y[w],S||(S=y[w]=_.append("g").attr("class",T[E]))}return S}o(v,"getGroup");for(let T of g){if(T.data.length===0)continue;let S=v(T.groupTexts);switch(T.type){case"rect":if(S.selectAll("rect").data(T.data).enter().append("rect").attr("x",w=>w.x).attr("y",w=>w.y).attr("width",w=>w.width).attr("height",w=>w.height).attr("fill",w=>w.fill).attr("stroke",w=>w.strokeFill).attr("stroke-width",w=>w.strokeWidth),s.showDataLabel)if(s.chartOrientation==="horizontal"){let _=function(O,R){let{data:k,label:L}=O;return R*L.length*.7<=k.width-10};var x=_;o(_,"fitsHorizontally");let w=.7,E=T.data.map((O,R)=>({data:O,label:l[R].toString()})).filter(O=>O.data.width>0&&O.data.height>0),C=E.map(O=>{let{data:R}=O,k=R.height*.7;for(;!_(O,k)&&k>0;)k-=1;return k}),D=Math.floor(Math.min(...C));S.selectAll("text").data(E).enter().append("text").attr("x",O=>O.data.x+O.data.width-10).attr("y",O=>O.data.y+O.data.height/2).attr("text-anchor","end").attr("dominant-baseline","middle").attr("fill","black").attr("font-size",`${D}px`).text(O=>O.label)}else{let _=function(O,R,k){let{data:L,label:A}=O,M=R*A.length*.7,P=L.x+L.width/2,B=P-M/2,F=P+M/2,z=B>=L.x&&F<=L.x+L.width,$=L.y+k+R<=L.y+L.height;return z&&$};var b=_;o(_,"fitsInBar");let w=10,E=T.data.map((O,R)=>({data:O,label:l[R].toString()})).filter(O=>O.data.width>0&&O.data.height>0),C=E.map(O=>{let{data:R,label:k}=O,L=R.width/(k.length*.7);for(;!_(O,L,10)&&L>0;)L-=1;return L}),D=Math.floor(Math.min(...C));S.selectAll("text").data(E).enter().append("text").attr("x",O=>O.data.x+O.data.width/2).attr("y",O=>O.data.y+10).attr("text-anchor","middle").attr("dominant-baseline","hanging").attr("fill","black").attr("font-size",`${D}px`).text(O=>O.label)}break;case"text":S.selectAll("text").data(T.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",w=>w.fill).attr("font-size",w=>w.fontSize).attr("dominant-baseline",w=>u(w.verticalPos)).attr("text-anchor",w=>h(w.horizontalPos)).attr("transform",w=>f(w)).text(w=>w.text);break;case"path":S.selectAll("path").data(T.data).enter().append("path").attr("d",w=>w.path).attr("fill",w=>w.fill?w.fill:"none").attr("stroke",w=>w.strokeFill).attr("stroke-width",w=>w.strokeWidth);break}}},"draw"),fde={draw:AUe}});var pde={};ur(pde,{diagram:()=>_Ue});var _Ue,mde=N(()=>{"use strict";Wfe();hde();dde();_Ue={parser:Hfe,db:ude,renderer:fde}});var hP,vde,xde=N(()=>{"use strict";hP=function(){var t=o(function(ie,oe,V,Te){for(V=V||{},Te=ie.length;Te--;V[ie[Te]]=oe);return V},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],s=[1,22],l=[2,7],u=[1,26],h=[1,27],f=[1,28],d=[1,29],p=[1,33],m=[1,34],g=[1,35],y=[1,36],v=[1,37],x=[1,38],b=[1,24],T=[1,31],S=[1,32],w=[1,30],E=[1,39],_=[1,40],C=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],D=[1,61],O=[89,90],R=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],k=[27,29],L=[1,70],A=[1,71],I=[1,72],M=[1,73],P=[1,74],B=[1,75],F=[1,76],z=[1,83],$=[1,80],U=[1,84],K=[1,85],ee=[1,86],Y=[1,87],ce=[1,88],Z=[1,89],ue=[1,90],Q=[1,91],j=[1,92],ne=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],te=[63,64],he=[1,101],le=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],J=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Se=[1,110],se=[1,106],ae=[1,107],Oe=[1,108],ye=[1,109],Be=[1,111],He=[1,116],ze=[1,117],Le=[1,114],Ie=[1,115],xe={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:o(function(oe,V,Te,W,pe,ve,Pe){var _e=ve.length-1;switch(pe){case 4:this.$=ve[_e].trim(),W.setAccTitle(this.$);break;case 5:case 6:this.$=ve[_e].trim(),W.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:W.setDirection("TB");break;case 18:W.setDirection("BT");break;case 19:W.setDirection("RL");break;case 20:W.setDirection("LR");break;case 21:W.addRequirement(ve[_e-3],ve[_e-4]);break;case 22:W.addRequirement(ve[_e-5],ve[_e-6]),W.setClass([ve[_e-5]],ve[_e-3]);break;case 23:W.setNewReqId(ve[_e-2]);break;case 24:W.setNewReqText(ve[_e-2]);break;case 25:W.setNewReqRisk(ve[_e-2]);break;case 26:W.setNewReqVerifyMethod(ve[_e-2]);break;case 29:this.$=W.RequirementType.REQUIREMENT;break;case 30:this.$=W.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=W.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=W.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=W.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=W.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=W.RiskLevel.LOW_RISK;break;case 36:this.$=W.RiskLevel.MED_RISK;break;case 37:this.$=W.RiskLevel.HIGH_RISK;break;case 38:this.$=W.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=W.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=W.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=W.VerifyType.VERIFY_TEST;break;case 42:W.addElement(ve[_e-3]);break;case 43:W.addElement(ve[_e-5]),W.setClass([ve[_e-5]],ve[_e-3]);break;case 44:W.setNewElementType(ve[_e-2]);break;case 45:W.setNewElementDocRef(ve[_e-2]);break;case 48:W.addRelationship(ve[_e-2],ve[_e],ve[_e-4]);break;case 49:W.addRelationship(ve[_e-2],ve[_e-4],ve[_e]);break;case 50:this.$=W.Relationships.CONTAINS;break;case 51:this.$=W.Relationships.COPIES;break;case 52:this.$=W.Relationships.DERIVES;break;case 53:this.$=W.Relationships.SATISFIES;break;case 54:this.$=W.Relationships.VERIFIES;break;case 55:this.$=W.Relationships.REFINES;break;case 56:this.$=W.Relationships.TRACES;break;case 57:this.$=ve[_e-2],W.defineClass(ve[_e-1],ve[_e]);break;case 58:W.setClass(ve[_e-1],ve[_e]);break;case 59:W.setClass([ve[_e-2]],ve[_e]);break;case 60:case 62:this.$=[ve[_e]];break;case 61:case 63:this.$=ve[_e-2].concat([ve[_e]]);break;case 64:this.$=ve[_e-2],W.setCssStyle(ve[_e-1],ve[_e]);break;case 65:this.$=[ve[_e]];break;case 66:ve[_e-2].push(ve[_e]),this.$=ve[_e-2];break;case 68:this.$=ve[_e-1]+ve[_e];break}},"anonymous"),table:[{3:1,4:2,6:e,9:r,11:n,13:i},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:r,11:n,13:i},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(a,[2,6]),{3:12,4:2,6:e,9:r,11:n,13:i},{1:[2,2]},{4:17,5:s,7:13,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},t(a,[2,4]),t(a,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:s,7:42,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:43,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:44,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:45,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:46,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:47,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:48,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:49,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{4:17,5:s,7:50,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:T,74:S,77:w,89:E,90:_},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},t(C,[2,17]),t(C,[2,18]),t(C,[2,19]),t(C,[2,20]),{30:60,33:62,75:D,89:E,90:_},{30:63,33:62,75:D,89:E,90:_},{30:64,33:62,75:D,89:E,90:_},t(O,[2,29]),t(O,[2,30]),t(O,[2,31]),t(O,[2,32]),t(O,[2,33]),t(O,[2,34]),t(R,[2,81]),t(R,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},t(k,[2,79]),t(k,[2,80]),{27:[1,67],29:[1,68]},t(k,[2,85]),t(k,[2,86]),{62:69,65:L,66:A,67:I,68:M,69:P,70:B,71:F},{62:77,65:L,66:A,67:I,68:M,69:P,70:B,71:F},{30:78,33:62,75:D,89:E,90:_},{73:79,75:z,76:$,78:81,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},t(ne,[2,60]),t(ne,[2,62]),{73:93,75:z,76:$,78:81,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},{30:94,33:62,75:D,76:$,89:E,90:_},{5:[1,95]},{30:96,33:62,75:D,89:E,90:_},{5:[1,97]},{30:98,33:62,75:D,89:E,90:_},{63:[1,99]},t(te,[2,50]),t(te,[2,51]),t(te,[2,52]),t(te,[2,53]),t(te,[2,54]),t(te,[2,55]),t(te,[2,56]),{64:[1,100]},t(C,[2,59],{76:$}),t(C,[2,64],{76:he}),{33:103,75:[1,102],89:E,90:_},t(le,[2,65],{79:104,75:z,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j}),t(J,[2,67]),t(J,[2,69]),t(J,[2,70]),t(J,[2,71]),t(J,[2,72]),t(J,[2,73]),t(J,[2,74]),t(J,[2,75]),t(J,[2,76]),t(J,[2,77]),t(J,[2,78]),t(C,[2,57],{76:he}),t(C,[2,58],{76:$}),{5:Se,28:105,31:se,34:ae,36:Oe,38:ye,40:Be},{27:[1,112],76:$},{5:He,40:ze,56:113,57:Le,59:Ie},{27:[1,118],76:$},{33:119,89:E,90:_},{33:120,89:E,90:_},{75:z,78:121,79:82,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j},t(ne,[2,61]),t(ne,[2,63]),t(J,[2,68]),t(C,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:Se,28:126,31:se,34:ae,36:Oe,38:ye,40:Be},t(C,[2,28]),{5:[1,127]},t(C,[2,42]),{32:[1,128]},{32:[1,129]},{5:He,40:ze,56:130,57:Le,59:Ie},t(C,[2,47]),{5:[1,131]},t(C,[2,48]),t(C,[2,49]),t(le,[2,66],{79:104,75:z,80:U,81:K,82:ee,83:Y,84:ce,85:Z,86:ue,87:Q,88:j}),{33:132,89:E,90:_},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},t(C,[2,27]),{5:Se,28:145,31:se,34:ae,36:Oe,38:ye,40:Be},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},t(C,[2,46]),{5:He,40:ze,56:152,57:Le,59:Ie},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},t(C,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},t(C,[2,43]),{5:Se,28:159,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:160,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:161,31:se,34:ae,36:Oe,38:ye,40:Be},{5:Se,28:162,31:se,34:ae,36:Oe,38:ye,40:Be},{5:He,40:ze,56:163,57:Le,59:Ie},{5:He,40:ze,56:164,57:Le,59:Ie},t(C,[2,23]),t(C,[2,24]),t(C,[2,25]),t(C,[2,26]),t(C,[2,44]),t(C,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:o(function(oe,V){if(V.recoverable)this.trace(oe);else{var Te=new Error(oe);throw Te.hash=V,Te}},"parseError"),parse:o(function(oe){var V=this,Te=[0],W=[],pe=[null],ve=[],Pe=this.table,_e="",be=0,Ve=0,De=0,qe=2,at=1,Rt=ve.slice.call(arguments,1),st=Object.create(this.lexer),Ue={yy:{}};for(var ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ct)&&(Ue.yy[ct]=this.yy[ct]);st.setInput(oe,Ue.yy),Ue.yy.lexer=st,Ue.yy.parser=this,typeof st.yylloc>"u"&&(st.yylloc={});var We=st.yylloc;ve.push(We);var ot=st.options&&st.options.ranges;typeof Ue.yy.parseError=="function"?this.parseError=Ue.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Yt(Ir){Te.length=Te.length-2*Ir,pe.length=pe.length-Ir,ve.length=ve.length-Ir}o(Yt,"popStack");function Tt(){var Ir;return Ir=W.pop()||st.lex()||at,typeof Ir!="number"&&(Ir instanceof Array&&(W=Ir,Ir=W.pop()),Ir=V.symbols_[Ir]||Ir),Ir}o(Tt,"lex");for(var Mt,bt,ut,St,ft,vt,nt={},pn,kt,On,tn;;){if(ut=Te[Te.length-1],this.defaultActions[ut]?St=this.defaultActions[ut]:((Mt===null||typeof Mt>"u")&&(Mt=Tt()),St=Pe[ut]&&Pe[ut][Mt]),typeof St>"u"||!St.length||!St[0]){var Mr="";tn=[];for(pn in Pe[ut])this.terminals_[pn]&&pn>qe&&tn.push("'"+this.terminals_[pn]+"'");st.showPosition?Mr="Parse error on line "+(be+1)+`: -`+st.showPosition()+` -Expecting `+tn.join(", ")+", got '"+(this.terminals_[Mt]||Mt)+"'":Mr="Parse error on line "+(be+1)+": Unexpected "+(Mt==at?"end of input":"'"+(this.terminals_[Mt]||Mt)+"'"),this.parseError(Mr,{text:st.match,token:this.terminals_[Mt]||Mt,line:st.yylineno,loc:We,expected:tn})}if(St[0]instanceof Array&&St.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ut+", token: "+Mt);switch(St[0]){case 1:Te.push(Mt),pe.push(st.yytext),ve.push(st.yylloc),Te.push(St[1]),Mt=null,bt?(Mt=bt,bt=null):(Ve=st.yyleng,_e=st.yytext,be=st.yylineno,We=st.yylloc,De>0&&De--);break;case 2:if(kt=this.productions_[St[1]][1],nt.$=pe[pe.length-kt],nt._$={first_line:ve[ve.length-(kt||1)].first_line,last_line:ve[ve.length-1].last_line,first_column:ve[ve.length-(kt||1)].first_column,last_column:ve[ve.length-1].last_column},ot&&(nt._$.range=[ve[ve.length-(kt||1)].range[0],ve[ve.length-1].range[1]]),vt=this.performAction.apply(nt,[_e,Ve,be,Ue.yy,St[1],pe,ve].concat(Rt)),typeof vt<"u")return vt;kt&&(Te=Te.slice(0,-1*kt*2),pe=pe.slice(0,-1*kt),ve=ve.slice(0,-1*kt)),Te.push(this.productions_[St[1]][0]),pe.push(nt.$),ve.push(nt._$),On=Pe[Te[Te.length-2]][Te[Te.length-1]],Te.push(On);break;case 3:return!0}}return!0},"parse")},q=function(){var ie={EOF:1,parseError:o(function(V,Te){if(this.yy.parser)this.yy.parser.parseError(V,Te);else throw new Error(V)},"parseError"),setInput:o(function(oe,V){return this.yy=V||this.yy||{},this._input=oe,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var oe=this._input[0];this.yytext+=oe,this.yyleng++,this.offset++,this.match+=oe,this.matched+=oe;var V=oe.match(/(?:\r\n?|\n).*/g);return V?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),oe},"input"),unput:o(function(oe){var V=oe.length,Te=oe.split(/(?:\r\n?|\n)/g);this._input=oe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-V),this.offset-=V;var W=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Te.length-1&&(this.yylineno-=Te.length-1);var pe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Te?(Te.length===W.length?this.yylloc.first_column:0)+W[W.length-Te.length].length-Te[0].length:this.yylloc.first_column-V},this.options.ranges&&(this.yylloc.range=[pe[0],pe[0]+this.yyleng-V]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(oe){this.unput(this.match.slice(oe))},"less"),pastInput:o(function(){var oe=this.matched.substr(0,this.matched.length-this.match.length);return(oe.length>20?"...":"")+oe.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var oe=this.match;return oe.length<20&&(oe+=this._input.substr(0,20-oe.length)),(oe.substr(0,20)+(oe.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var oe=this.pastInput(),V=new Array(oe.length+1).join("-");return oe+this.upcomingInput()+` -`+V+"^"},"showPosition"),test_match:o(function(oe,V){var Te,W,pe;if(this.options.backtrack_lexer&&(pe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(pe.yylloc.range=this.yylloc.range.slice(0))),W=oe[0].match(/(?:\r\n?|\n).*/g),W&&(this.yylineno+=W.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:W?W[W.length-1].length-W[W.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+oe[0].length},this.yytext+=oe[0],this.match+=oe[0],this.matches=oe,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(oe[0].length),this.matched+=oe[0],Te=this.performAction.call(this,this.yy,this,V,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Te)return Te;if(this._backtrack){for(var ve in pe)this[ve]=pe[ve];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var oe,V,Te,W;this._more||(this.yytext="",this.match="");for(var pe=this._currentRules(),ve=0;veV[0].length)){if(V=Te,W=ve,this.options.backtrack_lexer){if(oe=this.test_match(Te,pe[ve]),oe!==!1)return oe;if(this._backtrack){V=!1;continue}else return!1}else if(!this.options.flex)break}return V?(oe=this.test_match(V,pe[W]),oe!==!1?oe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var V=this.next();return V||this.lex()},"lex"),begin:o(function(V){this.conditionStack.push(V)},"begin"),popState:o(function(){var V=this.conditionStack.length-1;return V>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(V){return V=this.conditionStack.length-1-Math.abs(V||0),V>=0?this.conditionStack[V]:"INITIAL"},"topState"),pushState:o(function(V){this.begin(V)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(V,Te,W,pe){var ve=pe;switch(W){case 0:return"title";case 1:return this.begin("acc_title"),9;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),11;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 21;case 9:return 22;case 10:return 23;case 11:return 24;case 12:return 5;case 13:break;case 14:break;case 15:break;case 16:return 8;case 17:return 6;case 18:return 27;case 19:return 40;case 20:return 29;case 21:return 32;case 22:return 31;case 23:return 34;case 24:return 36;case 25:return 38;case 26:return 41;case 27:return 42;case 28:return 43;case 29:return 44;case 30:return 45;case 31:return 46;case 32:return 47;case 33:return 48;case 34:return 49;case 35:return 50;case 36:return 51;case 37:return 52;case 38:return 53;case 39:return 54;case 40:return 65;case 41:return 66;case 42:return 67;case 43:return 68;case 44:return 69;case 45:return 70;case 46:return 71;case 47:return 57;case 48:return 59;case 49:return this.begin("style"),77;break;case 50:return 75;case 51:return 81;case 52:return 88;case 53:return"PERCENT";case 54:return 86;case 55:return 84;case 56:break;case 57:this.begin("string");break;case 58:this.popState();break;case 59:return this.begin("style"),72;break;case 60:return this.begin("style"),74;break;case 61:return 61;case 62:return 64;case 63:return 63;case 64:this.begin("string");break;case 65:this.popState();break;case 66:return"qString";case 67:return Te.yytext=Te.yytext.trim(),89;break;case 68:return 75;case 69:return 80;case 70:return 76}},"anonymous"),rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::{3})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:style\b)/i,/^(?:\w+)/i,/^(?::)/i,/^(?:;)/i,/^(?:%)/i,/^(?:-)/i,/^(?:#)/i,/^(?: )/i,/^(?:["])/i,/^(?:\n)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^:,\r\n\{\<\>\-\=]*)/i,/^(?:\w+)/i,/^(?:[0-9]+)/i,/^(?:,)/i],conditions:{acc_descr_multiline:{rules:[6,7,68,69,70],inclusive:!1},acc_descr:{rules:[4,68,69,70],inclusive:!1},acc_title:{rules:[2,68,69,70],inclusive:!1},style:{rules:[50,51,52,53,54,55,56,57,58,68,69,70],inclusive:!1},unqString:{rules:[68,69,70],inclusive:!1},token:{rules:[68,69,70],inclusive:!1},string:{rules:[65,66,68,69,70],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,59,60,61,62,63,64,67,68,69,70],inclusive:!0}}};return ie}();xe.lexer=q;function de(){this.yy={}}return o(de,"Parser"),de.prototype=xe,xe.Parser=de,new de}();hP.parser=hP;vde=hP});var qS,bde=N(()=>{"use strict";Gt();yt();ci();qS=class{constructor(){this.relations=[];this.latestRequirement=this.getInitialRequirement();this.requirements=new Map;this.latestElement=this.getInitialElement();this.elements=new Map;this.classes=new Map;this.direction="TB";this.RequirementType={REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"};this.RiskLevel={LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"};this.VerifyType={VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"};this.Relationships={CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"};this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().requirement,"getConfig");this.clear(),this.setDirection=this.setDirection.bind(this),this.addRequirement=this.addRequirement.bind(this),this.setNewReqId=this.setNewReqId.bind(this),this.setNewReqRisk=this.setNewReqRisk.bind(this),this.setNewReqText=this.setNewReqText.bind(this),this.setNewReqVerifyMethod=this.setNewReqVerifyMethod.bind(this),this.addElement=this.addElement.bind(this),this.setNewElementType=this.setNewElementType.bind(this),this.setNewElementDocRef=this.setNewElementDocRef.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setCssStyle=this.setCssStyle.bind(this),this.setClass=this.setClass.bind(this),this.defineClass=this.defineClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"RequirementDB")}getDirection(){return this.direction}setDirection(e){this.direction=e}resetLatestRequirement(){this.latestRequirement=this.getInitialRequirement()}resetLatestElement(){this.latestElement=this.getInitialElement()}getInitialRequirement(){return{requirementId:"",text:"",risk:"",verifyMethod:"",name:"",type:"",cssStyles:[],classes:["default"]}}getInitialElement(){return{name:"",type:"",docRef:"",cssStyles:[],classes:["default"]}}addRequirement(e,r){return this.requirements.has(e)||this.requirements.set(e,{name:e,type:r,requirementId:this.latestRequirement.requirementId,text:this.latestRequirement.text,risk:this.latestRequirement.risk,verifyMethod:this.latestRequirement.verifyMethod,cssStyles:[],classes:["default"]}),this.resetLatestRequirement(),this.requirements.get(e)}getRequirements(){return this.requirements}setNewReqId(e){this.latestRequirement!==void 0&&(this.latestRequirement.requirementId=e)}setNewReqText(e){this.latestRequirement!==void 0&&(this.latestRequirement.text=e)}setNewReqRisk(e){this.latestRequirement!==void 0&&(this.latestRequirement.risk=e)}setNewReqVerifyMethod(e){this.latestRequirement!==void 0&&(this.latestRequirement.verifyMethod=e)}addElement(e){return this.elements.has(e)||(this.elements.set(e,{name:e,type:this.latestElement.type,docRef:this.latestElement.docRef,cssStyles:[],classes:["default"]}),X.info("Added new element: ",e)),this.resetLatestElement(),this.elements.get(e)}getElements(){return this.elements}setNewElementType(e){this.latestElement!==void 0&&(this.latestElement.type=e)}setNewElementDocRef(e){this.latestElement!==void 0&&(this.latestElement.docRef=e)}addRelationship(e,r,n){this.relations.push({type:e,src:r,dst:n})}getRelationships(){return this.relations}clear(){this.relations=[],this.resetLatestRequirement(),this.requirements=new Map,this.resetLatestElement(),this.elements=new Map,this.classes=new Map,kr()}setCssStyle(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(!r||!i)return;for(let a of r)a.includes(",")?i.cssStyles.push(...a.split(",")):i.cssStyles.push(a)}}setClass(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(i)for(let a of r){i.classes.push(a);let s=this.classes.get(a)?.styles;s&&i.cssStyles.push(...s)}}}defineClass(e,r){for(let n of e){let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.requirements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))}),this.elements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))})}}getClasses(){return this.classes}getData(){let e=me(),r=[],n=[];for(let i of this.requirements.values()){let a=i;a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),a.shape="requirementBox",a.look=e.look,r.push(a)}for(let i of this.elements.values()){let a=i;a.shape="requirementBox",a.look=e.look,a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),r.push(a)}for(let i of this.relations){let a=0,s=i.type===this.Relationships.CONTAINS,l={id:`${i.src}-${i.dst}-${a}`,start:this.requirements.get(i.src)?.name??this.elements.get(i.src)?.name,end:this.requirements.get(i.dst)?.name??this.elements.get(i.dst)?.name,label:`<<${i.type}>>`,classes:"relationshipLine",style:["fill:none",s?"":"stroke-dasharray: 10,7"],labelpos:"c",thickness:"normal",type:"normal",pattern:s?"normal":"dashed",arrowTypeStart:s?"requirement_contains":"",arrowTypeEnd:s?"":"requirement_arrow",look:e.look};n.push(l),a++}return{nodes:r,edges:n,other:{},config:e,direction:this.getDirection()}}}});var NUe,Tde,wde=N(()=>{"use strict";NUe=o(t=>` - - marker { - fill: ${t.relationColor}; - stroke: ${t.relationColor}; - } - - marker.cross { - stroke: ${t.lineColor}; - } - - svg { - font-family: ${t.fontFamily}; - font-size: ${t.fontSize}; - } - - .reqBox { - fill: ${t.requirementBackground}; - fill-opacity: 1.0; - stroke: ${t.requirementBorderColor}; - stroke-width: ${t.requirementBorderSize}; - } - - .reqTitle, .reqLabel{ - fill: ${t.requirementTextColor}; - } - .reqLabelBox { - fill: ${t.relationLabelBackground}; - fill-opacity: 1.0; - } - - .req-title-line { - stroke: ${t.requirementBorderColor}; - stroke-width: ${t.requirementBorderSize}; - } - .relationshipLine { - stroke: ${t.relationColor}; - stroke-width: 1; - } - .relationshipLabel { - fill: ${t.relationLabelColor}; - } - .divider { - stroke: ${t.nodeBorder}; - stroke-width: 1; - } - .label { - font-family: ${t.fontFamily}; - color: ${t.nodeTextColor||t.textColor}; - } - .label text,span { - fill: ${t.nodeTextColor||t.textColor}; - color: ${t.nodeTextColor||t.textColor}; - } - .labelBkg { - background-color: ${t.edgeLabelBackground}; - } - -`,"getStyles"),Tde=NUe});var fP={};ur(fP,{draw:()=>MUe});var MUe,kde=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();MUe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing requirement diagram (unified)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.nodeSpacing=a?.nodeSpacing??50,l.rankSpacing=a?.rankSpacing??50,l.markers=["requirement_contains","requirement_arrow"],l.diagramId=e,await Rc(l,u);let h=8;Vt.insertTitle(u,"requirementDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,"requirementDiagram",a?.useMaxWidth??!0)},"draw")});var Ede={};ur(Ede,{diagram:()=>IUe});var IUe,Sde=N(()=>{"use strict";xde();bde();wde();kde();IUe={parser:vde,get db(){return new qS},renderer:fP,styles:Tde}});var dP,_de,Dde=N(()=>{"use strict";dP=function(){var t=o(function(Q,j,ne,te){for(ne=ne||{},te=Q.length;te--;ne[Q[te]]=j);return ne},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,13],u=[1,14],h=[1,16],f=[1,17],d=[1,18],p=[1,24],m=[1,25],g=[1,26],y=[1,27],v=[1,28],x=[1,29],b=[1,30],T=[1,31],S=[1,32],w=[1,33],E=[1,34],_=[1,35],C=[1,36],D=[1,37],O=[1,38],R=[1,39],k=[1,41],L=[1,42],A=[1,43],I=[1,44],M=[1,45],P=[1,46],B=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],F=[4,5,16,50,52,53],z=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],U=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],K=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],ee=[68,69,70],Y=[1,122],ce={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,BIDIRECTIONAL_SOLID_ARROW:74,DOTTED_ARROW:75,BIDIRECTIONAL_DOTTED_ARROW:76,SOLID_CROSS:77,DOTTED_CROSS:78,SOLID_POINT:79,DOTTED_POINT:80,TXT:81,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"BIDIRECTIONAL_SOLID_ARROW",75:"DOTTED_ARROW",76:"BIDIRECTIONAL_DOTTED_ARROW",77:"SOLID_CROSS",78:"DOTTED_CROSS",79:"SOLID_POINT",80:"DOTTED_POINT",81:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:o(function(j,ne,te,he,le,J,Se){var se=J.length-1;switch(le){case 3:return he.apply(J[se]),J[se];break;case 4:case 9:this.$=[];break;case 5:case 10:J[se-1].push(J[se]),this.$=J[se-1];break;case 6:case 7:case 11:case 12:this.$=J[se];break;case 8:case 13:this.$=[];break;case 15:J[se].type="createParticipant",this.$=J[se];break;case 16:J[se-1].unshift({type:"boxStart",boxData:he.parseBoxData(J[se-2])}),J[se-1].push({type:"boxEnd",boxText:J[se-2]}),this.$=J[se-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(J[se-2]),sequenceIndexStep:Number(J[se-1]),sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(J[se-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:he.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:he.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:he.LINETYPE.ACTIVE_START,actor:J[se-1].actor};break;case 23:this.$={type:"activeEnd",signalType:he.LINETYPE.ACTIVE_END,actor:J[se-1].actor};break;case 29:he.setDiagramTitle(J[se].substring(6)),this.$=J[se].substring(6);break;case 30:he.setDiagramTitle(J[se].substring(7)),this.$=J[se].substring(7);break;case 31:this.$=J[se].trim(),he.setAccTitle(this.$);break;case 32:case 33:this.$=J[se].trim(),he.setAccDescription(this.$);break;case 34:J[se-1].unshift({type:"loopStart",loopText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.LOOP_START}),J[se-1].push({type:"loopEnd",loopText:J[se-2],signalType:he.LINETYPE.LOOP_END}),this.$=J[se-1];break;case 35:J[se-1].unshift({type:"rectStart",color:he.parseMessage(J[se-2]),signalType:he.LINETYPE.RECT_START}),J[se-1].push({type:"rectEnd",color:he.parseMessage(J[se-2]),signalType:he.LINETYPE.RECT_END}),this.$=J[se-1];break;case 36:J[se-1].unshift({type:"optStart",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.OPT_START}),J[se-1].push({type:"optEnd",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.OPT_END}),this.$=J[se-1];break;case 37:J[se-1].unshift({type:"altStart",altText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.ALT_START}),J[se-1].push({type:"altEnd",signalType:he.LINETYPE.ALT_END}),this.$=J[se-1];break;case 38:J[se-1].unshift({type:"parStart",parText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.PAR_START}),J[se-1].push({type:"parEnd",signalType:he.LINETYPE.PAR_END}),this.$=J[se-1];break;case 39:J[se-1].unshift({type:"parStart",parText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.PAR_OVER_START}),J[se-1].push({type:"parEnd",signalType:he.LINETYPE.PAR_END}),this.$=J[se-1];break;case 40:J[se-1].unshift({type:"criticalStart",criticalText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.CRITICAL_START}),J[se-1].push({type:"criticalEnd",signalType:he.LINETYPE.CRITICAL_END}),this.$=J[se-1];break;case 41:J[se-1].unshift({type:"breakStart",breakText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.BREAK_START}),J[se-1].push({type:"breakEnd",optText:he.parseMessage(J[se-2]),signalType:he.LINETYPE.BREAK_END}),this.$=J[se-1];break;case 43:this.$=J[se-3].concat([{type:"option",optionText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.CRITICAL_OPTION},J[se]]);break;case 45:this.$=J[se-3].concat([{type:"and",parText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.PAR_AND},J[se]]);break;case 47:this.$=J[se-3].concat([{type:"else",altText:he.parseMessage(J[se-1]),signalType:he.LINETYPE.ALT_ELSE},J[se]]);break;case 48:J[se-3].draw="participant",J[se-3].type="addParticipant",J[se-3].description=he.parseMessage(J[se-1]),this.$=J[se-3];break;case 49:J[se-1].draw="participant",J[se-1].type="addParticipant",this.$=J[se-1];break;case 50:J[se-3].draw="actor",J[se-3].type="addParticipant",J[se-3].description=he.parseMessage(J[se-1]),this.$=J[se-3];break;case 51:J[se-1].draw="actor",J[se-1].type="addParticipant",this.$=J[se-1];break;case 52:J[se-1].type="destroyParticipant",this.$=J[se-1];break;case 53:this.$=[J[se-1],{type:"addNote",placement:J[se-2],actor:J[se-1].actor,text:J[se]}];break;case 54:J[se-2]=[].concat(J[se-1],J[se-1]).slice(0,2),J[se-2][0]=J[se-2][0].actor,J[se-2][1]=J[se-2][1].actor,this.$=[J[se-1],{type:"addNote",placement:he.PLACEMENT.OVER,actor:J[se-2].slice(0,2),text:J[se]}];break;case 55:this.$=[J[se-1],{type:"addLinks",actor:J[se-1].actor,text:J[se]}];break;case 56:this.$=[J[se-1],{type:"addALink",actor:J[se-1].actor,text:J[se]}];break;case 57:this.$=[J[se-1],{type:"addProperties",actor:J[se-1].actor,text:J[se]}];break;case 58:this.$=[J[se-1],{type:"addDetails",actor:J[se-1].actor,text:J[se]}];break;case 61:this.$=[J[se-2],J[se]];break;case 62:this.$=J[se];break;case 63:this.$=he.PLACEMENT.LEFTOF;break;case 64:this.$=he.PLACEMENT.RIGHTOF;break;case 65:this.$=[J[se-4],J[se-1],{type:"addMessage",from:J[se-4].actor,to:J[se-1].actor,signalType:J[se-3],msg:J[se],activate:!0},{type:"activeStart",signalType:he.LINETYPE.ACTIVE_START,actor:J[se-1].actor}];break;case 66:this.$=[J[se-4],J[se-1],{type:"addMessage",from:J[se-4].actor,to:J[se-1].actor,signalType:J[se-3],msg:J[se]},{type:"activeEnd",signalType:he.LINETYPE.ACTIVE_END,actor:J[se-4].actor}];break;case 67:this.$=[J[se-3],J[se-1],{type:"addMessage",from:J[se-3].actor,to:J[se-1].actor,signalType:J[se-2],msg:J[se]}];break;case 68:this.$={type:"addParticipant",actor:J[se]};break;case 69:this.$=he.LINETYPE.SOLID_OPEN;break;case 70:this.$=he.LINETYPE.DOTTED_OPEN;break;case 71:this.$=he.LINETYPE.SOLID;break;case 72:this.$=he.LINETYPE.BIDIRECTIONAL_SOLID;break;case 73:this.$=he.LINETYPE.DOTTED;break;case 74:this.$=he.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 75:this.$=he.LINETYPE.SOLID_CROSS;break;case 76:this.$=he.LINETYPE.DOTTED_CROSS;break;case 77:this.$=he.LINETYPE.SOLID_POINT;break;case 78:this.$=he.LINETYPE.DOTTED_POINT;break;case 79:this.$=he.parseMessage(J[se].trim().substring(1));break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},t(B,[2,5]),{9:47,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},t(B,[2,7]),t(B,[2,8]),t(B,[2,14]),{12:48,50:D,52:O,53:R},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:P},{22:55,70:P},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(B,[2,29]),t(B,[2,30]),{32:[1,61]},{34:[1,62]},t(B,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:P},{22:72,70:P},{22:73,70:P},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82],79:[1,83],80:[1,84]},{55:85,57:[1,86],65:[1,87],66:[1,88]},{22:89,70:P},{22:90,70:P},{22:91,70:P},{22:92,70:P},t([5,51,64,71,72,73,74,75,76,77,78,79,80,81],[2,68]),t(B,[2,6]),t(B,[2,15]),t(F,[2,9],{10:93}),t(B,[2,17]),{5:[1,95],19:[1,94]},{5:[1,96]},t(B,[2,21]),{5:[1,97]},{5:[1,98]},t(B,[2,24]),t(B,[2,25]),t(B,[2,26]),t(B,[2,27]),t(B,[2,28]),t(B,[2,31]),t(B,[2,32]),t(z,i,{7:99}),t(z,i,{7:100}),t(z,i,{7:101}),t($,i,{40:102,7:103}),t(U,i,{42:104,7:105}),t(U,i,{7:105,42:106}),t(K,i,{45:107,7:108}),t(z,i,{7:109}),{5:[1,111],51:[1,110]},{5:[1,113],51:[1,112]},{5:[1,114]},{22:117,68:[1,115],69:[1,116],70:P},t(ee,[2,69]),t(ee,[2,70]),t(ee,[2,71]),t(ee,[2,72]),t(ee,[2,73]),t(ee,[2,74]),t(ee,[2,75]),t(ee,[2,76]),t(ee,[2,77]),t(ee,[2,78]),{22:118,70:P},{22:120,58:119,70:P},{70:[2,63]},{70:[2,64]},{56:121,81:Y},{56:123,81:Y},{56:124,81:Y},{56:125,81:Y},{4:[1,128],5:[1,130],11:127,12:129,16:[1,126],50:D,52:O,53:R},{5:[1,131]},t(B,[2,19]),t(B,[2,20]),t(B,[2,22]),t(B,[2,23]),{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,132],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,133],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,134],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,135]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,46],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,49:[1,136],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,137]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,44],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,48:[1,138],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{16:[1,139]},{16:[1,140]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,42],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,47:[1,141],50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,142],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:T,39:S,41:w,43:E,44:_,46:C,50:D,52:O,53:R,54:k,59:L,60:A,61:I,62:M,70:P},{15:[1,143]},t(B,[2,49]),{15:[1,144]},t(B,[2,51]),t(B,[2,52]),{22:145,70:P},{22:146,70:P},{56:147,81:Y},{56:148,81:Y},{56:149,81:Y},{64:[1,150],81:[2,62]},{5:[2,55]},{5:[2,79]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(B,[2,16]),t(F,[2,10]),{12:151,50:D,52:O,53:R},t(F,[2,12]),t(F,[2,13]),t(B,[2,18]),t(B,[2,34]),t(B,[2,35]),t(B,[2,36]),t(B,[2,37]),{15:[1,152]},t(B,[2,38]),{15:[1,153]},t(B,[2,39]),t(B,[2,40]),{15:[1,154]},t(B,[2,41]),{5:[1,155]},{5:[1,156]},{56:157,81:Y},{56:158,81:Y},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:159,70:P},t(F,[2,11]),t($,i,{7:103,40:160}),t(U,i,{7:105,42:161}),t(K,i,{7:108,45:162}),t(B,[2,48]),t(B,[2,50]),{5:[2,65]},{5:[2,66]},{81:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],87:[2,63],88:[2,64],121:[2,55],122:[2,79],123:[2,56],124:[2,57],125:[2,58],147:[2,67],148:[2,53],149:[2,54],157:[2,65],158:[2,66],159:[2,61],160:[2,47],161:[2,45],162:[2,43]},parseError:o(function(j,ne){if(ne.recoverable)this.trace(j);else{var te=new Error(j);throw te.hash=ne,te}},"parseError"),parse:o(function(j){var ne=this,te=[0],he=[],le=[null],J=[],Se=this.table,se="",ae=0,Oe=0,ye=0,Be=2,He=1,ze=J.slice.call(arguments,1),Le=Object.create(this.lexer),Ie={yy:{}};for(var xe in this.yy)Object.prototype.hasOwnProperty.call(this.yy,xe)&&(Ie.yy[xe]=this.yy[xe]);Le.setInput(j,Ie.yy),Ie.yy.lexer=Le,Ie.yy.parser=this,typeof Le.yylloc>"u"&&(Le.yylloc={});var q=Le.yylloc;J.push(q);var de=Le.options&&Le.options.ranges;typeof Ie.yy.parseError=="function"?this.parseError=Ie.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ie(Rt){te.length=te.length-2*Rt,le.length=le.length-Rt,J.length=J.length-Rt}o(ie,"popStack");function oe(){var Rt;return Rt=he.pop()||Le.lex()||He,typeof Rt!="number"&&(Rt instanceof Array&&(he=Rt,Rt=he.pop()),Rt=ne.symbols_[Rt]||Rt),Rt}o(oe,"lex");for(var V,Te,W,pe,ve,Pe,_e={},be,Ve,De,qe;;){if(W=te[te.length-1],this.defaultActions[W]?pe=this.defaultActions[W]:((V===null||typeof V>"u")&&(V=oe()),pe=Se[W]&&Se[W][V]),typeof pe>"u"||!pe.length||!pe[0]){var at="";qe=[];for(be in Se[W])this.terminals_[be]&&be>Be&&qe.push("'"+this.terminals_[be]+"'");Le.showPosition?at="Parse error on line "+(ae+1)+`: -`+Le.showPosition()+` -Expecting `+qe.join(", ")+", got '"+(this.terminals_[V]||V)+"'":at="Parse error on line "+(ae+1)+": Unexpected "+(V==He?"end of input":"'"+(this.terminals_[V]||V)+"'"),this.parseError(at,{text:Le.match,token:this.terminals_[V]||V,line:Le.yylineno,loc:q,expected:qe})}if(pe[0]instanceof Array&&pe.length>1)throw new Error("Parse Error: multiple actions possible at state: "+W+", token: "+V);switch(pe[0]){case 1:te.push(V),le.push(Le.yytext),J.push(Le.yylloc),te.push(pe[1]),V=null,Te?(V=Te,Te=null):(Oe=Le.yyleng,se=Le.yytext,ae=Le.yylineno,q=Le.yylloc,ye>0&&ye--);break;case 2:if(Ve=this.productions_[pe[1]][1],_e.$=le[le.length-Ve],_e._$={first_line:J[J.length-(Ve||1)].first_line,last_line:J[J.length-1].last_line,first_column:J[J.length-(Ve||1)].first_column,last_column:J[J.length-1].last_column},de&&(_e._$.range=[J[J.length-(Ve||1)].range[0],J[J.length-1].range[1]]),Pe=this.performAction.apply(_e,[se,Oe,ae,Ie.yy,pe[1],le,J].concat(ze)),typeof Pe<"u")return Pe;Ve&&(te=te.slice(0,-1*Ve*2),le=le.slice(0,-1*Ve),J=J.slice(0,-1*Ve)),te.push(this.productions_[pe[1]][0]),le.push(_e.$),J.push(_e._$),De=Se[te[te.length-2]][te[te.length-1]],te.push(De);break;case 3:return!0}}return!0},"parse")},Z=function(){var Q={EOF:1,parseError:o(function(ne,te){if(this.yy.parser)this.yy.parser.parseError(ne,te);else throw new Error(ne)},"parseError"),setInput:o(function(j,ne){return this.yy=ne||this.yy||{},this._input=j,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var j=this._input[0];this.yytext+=j,this.yyleng++,this.offset++,this.match+=j,this.matched+=j;var ne=j.match(/(?:\r\n?|\n).*/g);return ne?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),j},"input"),unput:o(function(j){var ne=j.length,te=j.split(/(?:\r\n?|\n)/g);this._input=j+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ne),this.offset-=ne;var he=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),te.length-1&&(this.yylineno-=te.length-1);var le=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:te?(te.length===he.length?this.yylloc.first_column:0)+he[he.length-te.length].length-te[0].length:this.yylloc.first_column-ne},this.options.ranges&&(this.yylloc.range=[le[0],le[0]+this.yyleng-ne]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(j){this.unput(this.match.slice(j))},"less"),pastInput:o(function(){var j=this.matched.substr(0,this.matched.length-this.match.length);return(j.length>20?"...":"")+j.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var j=this.match;return j.length<20&&(j+=this._input.substr(0,20-j.length)),(j.substr(0,20)+(j.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var j=this.pastInput(),ne=new Array(j.length+1).join("-");return j+this.upcomingInput()+` -`+ne+"^"},"showPosition"),test_match:o(function(j,ne){var te,he,le;if(this.options.backtrack_lexer&&(le={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(le.yylloc.range=this.yylloc.range.slice(0))),he=j[0].match(/(?:\r\n?|\n).*/g),he&&(this.yylineno+=he.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:he?he[he.length-1].length-he[he.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+j[0].length},this.yytext+=j[0],this.match+=j[0],this.matches=j,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(j[0].length),this.matched+=j[0],te=this.performAction.call(this,this.yy,this,ne,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),te)return te;if(this._backtrack){for(var J in le)this[J]=le[J];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var j,ne,te,he;this._more||(this.yytext="",this.match="");for(var le=this._currentRules(),J=0;Jne[0].length)){if(ne=te,he=J,this.options.backtrack_lexer){if(j=this.test_match(te,le[J]),j!==!1)return j;if(this._backtrack){ne=!1;continue}else return!1}else if(!this.options.flex)break}return ne?(j=this.test_match(ne,le[he]),j!==!1?j:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var ne=this.next();return ne||this.lex()},"lex"),begin:o(function(ne){this.conditionStack.push(ne)},"begin"),popState:o(function(){var ne=this.conditionStack.length-1;return ne>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(ne){return ne=this.conditionStack.length-1-Math.abs(ne||0),ne>=0?this.conditionStack[ne]:"INITIAL"},"topState"),pushState:o(function(ne){this.begin(ne)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(ne,te,he,le){var J=le;switch(he){case 0:return 5;case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;break;case 8:return this.begin("ID"),50;break;case 9:return this.begin("ID"),52;break;case 10:return 13;case 11:return this.begin("ID"),53;break;case 12:return te.yytext=te.yytext.trim(),this.begin("ALIAS"),70;break;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;break;case 14:return this.popState(),this.popState(),5;break;case 15:return this.begin("LINE"),36;break;case 16:return this.begin("LINE"),37;break;case 17:return this.begin("LINE"),38;break;case 18:return this.begin("LINE"),39;break;case 19:return this.begin("LINE"),49;break;case 20:return this.begin("LINE"),41;break;case 21:return this.begin("LINE"),43;break;case 22:return this.begin("LINE"),48;break;case 23:return this.begin("LINE"),44;break;case 24:return this.begin("LINE"),47;break;case 25:return this.begin("LINE"),46;break;case 26:return this.popState(),15;break;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;break;case 37:return this.begin("ID"),23;break;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;break;case 41:return this.popState(),"acc_title_value";break;case 42:return this.begin("acc_descr"),33;break;case 43:return this.popState(),"acc_descr_value";break;case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 51:return 5;case 52:return te.yytext=te.yytext.trim(),70;break;case 53:return 73;case 54:return 74;case 55:return 75;case 56:return 76;case 57:return 71;case 58:return 72;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 80;case 63:return 81;case 64:return 81;case 65:return 68;case 66:return 69;case 67:return 5;case 68:return"INVALID"}},"anonymous"),rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\<->\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\<->\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:<<->>)/i,/^(?:-->>)/i,/^(?:<<-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]*)/i,/^(?::)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],inclusive:!0}}};return Q}();ce.lexer=Z;function ue(){this.yy={}}return o(ue,"Parser"),ue.prototype=ce,ce.Parser=ue,new ue}();dP.parser=dP;_de=dP});var FUe,$Ue,zUe,YS,Lde=N(()=>{"use strict";Gt();yt();SS();pr();ci();FUe={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32,BIDIRECTIONAL_SOLID:33,BIDIRECTIONAL_DOTTED:34},$Ue={FILLED:0,OPEN:1},zUe={LEFTOF:0,RIGHTOF:1,OVER:2},YS=class{constructor(){this.state=new Tf(()=>({prevActor:void 0,actors:new Map,createdActors:new Map,destroyedActors:new Map,boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}));this.setAccTitle=Ar;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getAccTitle=Dr;this.getAccDescription=Rr;this.getDiagramTitle=Nr;this.apply=this.apply.bind(this),this.parseBoxData=this.parseBoxData.bind(this),this.parseMessage=this.parseMessage.bind(this),this.clear(),this.setWrap(me().wrap),this.LINETYPE=FUe,this.ARROWTYPE=$Ue,this.PLACEMENT=zUe}static{o(this,"SequenceDB")}addBox(e){this.state.records.boxes.push({name:e.text,wrap:e.wrap??this.autoWrap(),fill:e.color,actorKeys:[]}),this.state.records.currentBox=this.state.records.boxes.slice(-1)[0]}addActor(e,r,n,i){let a=this.state.records.currentBox,s=this.state.records.actors.get(e);if(s){if(this.state.records.currentBox&&s.box&&this.state.records.currentBox!==s.box)throw new Error(`A same participant should only be defined in one Box: ${s.name} can't be in '${s.box.name}' and in '${this.state.records.currentBox.name}' at the same time.`);if(a=s.box?s.box:this.state.records.currentBox,s.box=a,s&&r===s.name&&n==null)return}if(n?.text==null&&(n={text:r,type:i}),(i==null||n.text==null)&&(n={text:r,type:i}),this.state.records.actors.set(e,{box:a,name:r,description:n.text,wrap:n.wrap??this.autoWrap(),prevActor:this.state.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:i??"participant"}),this.state.records.prevActor){let l=this.state.records.actors.get(this.state.records.prevActor);l&&(l.nextActor=e)}this.state.records.currentBox&&this.state.records.currentBox.actorKeys.push(e),this.state.records.prevActor=e}activationCount(e){let r,n=0;if(!e)return 0;for(r=0;r>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},l}return this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:e,to:r,message:n?.text??"",wrap:n?.wrap??this.autoWrap(),type:i,activate:a}),!0}hasAtLeastOneBox(){return this.state.records.boxes.length>0}hasAtLeastOneBoxWithTitle(){return this.state.records.boxes.some(e=>e.name)}getMessages(){return this.state.records.messages}getBoxes(){return this.state.records.boxes}getActors(){return this.state.records.actors}getCreatedActors(){return this.state.records.createdActors}getDestroyedActors(){return this.state.records.destroyedActors}getActor(e){return this.state.records.actors.get(e)}getActorKeys(){return[...this.state.records.actors.keys()]}enableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!0}disableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!1}showSequenceNumbers(){return this.state.records.sequenceNumbersEnabled}setWrap(e){this.state.records.wrapEnabled=e}extractWrap(e){if(e===void 0)return{};e=e.trim();let r=/^:?wrap:/.exec(e)!==null?!0:/^:?nowrap:/.exec(e)!==null?!1:void 0;return{cleanedText:(r===void 0?e:e.replace(/^:?(?:no)?wrap:/,"")).trim(),wrap:r}}autoWrap(){return this.state.records.wrapEnabled!==void 0?this.state.records.wrapEnabled:me().sequence?.wrap??!1}clear(){this.state.reset(),kr()}parseMessage(e){let r=e.trim(),{wrap:n,cleanedText:i}=this.extractWrap(r),a={text:i,wrap:n};return X.debug(`parseMessage: ${JSON.stringify(a)}`),a}parseBoxData(e){let r=/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(e),n=r?.[1]?r[1].trim():"transparent",i=r?.[2]?r[2].trim():void 0;if(window?.CSS)window.CSS.supports("color",n)||(n="transparent",i=e.trim());else{let l=new Option().style;l.color=n,l.color!==n&&(n="transparent",i=e.trim())}let{wrap:a,cleanedText:s}=this.extractWrap(i);return{text:s?wr(s,me()):void 0,color:n,wrap:a}}addNote(e,r,n){let i={actor:e,placement:r,message:n.text,wrap:n.wrap??this.autoWrap()},a=[].concat(e,e);this.state.records.notes.push(i),this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:a[0],to:a[1],message:n.text,wrap:n.wrap??this.autoWrap(),type:this.LINETYPE.NOTE,placement:r})}addLinks(e,r){let n=this.getActor(e);try{let i=wr(r.text,me());i=i.replace(/=/g,"="),i=i.replace(/&/g,"&");let a=JSON.parse(i);this.insertLinks(n,a)}catch(i){X.error("error while parsing actor link text",i)}}addALink(e,r){let n=this.getActor(e);try{let i={},a=wr(r.text,me()),s=a.indexOf("@");a=a.replace(/=/g,"="),a=a.replace(/&/g,"&");let l=a.slice(0,s-1).trim(),u=a.slice(s+1).trim();i[l]=u,this.insertLinks(n,i)}catch(i){X.error("error while parsing actor link text",i)}}insertLinks(e,r){if(e.links==null)e.links=r;else for(let n in r)e.links[n]=r[n]}addProperties(e,r){let n=this.getActor(e);try{let i=wr(r.text,me()),a=JSON.parse(i);this.insertProperties(n,a)}catch(i){X.error("error while parsing actor properties text",i)}}insertProperties(e,r){if(e.properties==null)e.properties=r;else for(let n in r)e.properties[n]=r[n]}boxEnd(){this.state.records.currentBox=void 0}addDetails(e,r){let n=this.getActor(e),i=document.getElementById(r.text);try{let a=i.innerHTML,s=JSON.parse(a);s.properties&&this.insertProperties(n,s.properties),s.links&&this.insertLinks(n,s.links)}catch(a){X.error("error while parsing actor details text",a)}}getActorProperty(e,r){if(e?.properties!==void 0)return e.properties[r]}apply(e){if(Array.isArray(e))e.forEach(r=>{this.apply(r)});else switch(e.type){case"sequenceIndex":this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:void 0,to:void 0,message:{start:e.sequenceIndex,step:e.sequenceIndexStep,visible:e.sequenceVisible},wrap:!1,type:e.signalType});break;case"addParticipant":this.addActor(e.actor,e.actor,e.description,e.draw);break;case"createParticipant":if(this.state.records.actors.has(e.actor))throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");this.state.records.lastCreated=e.actor,this.addActor(e.actor,e.actor,e.description,e.draw),this.state.records.createdActors.set(e.actor,this.state.records.messages.length);break;case"destroyParticipant":this.state.records.lastDestroyed=e.actor,this.state.records.destroyedActors.set(e.actor,this.state.records.messages.length);break;case"activeStart":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"activeEnd":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"addNote":this.addNote(e.actor,e.placement,e.text);break;case"addLinks":this.addLinks(e.actor,e.text);break;case"addALink":this.addALink(e.actor,e.text);break;case"addProperties":this.addProperties(e.actor,e.text);break;case"addDetails":this.addDetails(e.actor,e.text);break;case"addMessage":if(this.state.records.lastCreated){if(e.to!==this.state.records.lastCreated)throw new Error("The created participant "+this.state.records.lastCreated.name+" does not have an associated creating message after its declaration. Please check the sequence diagram.");this.state.records.lastCreated=void 0}else if(this.state.records.lastDestroyed){if(e.to!==this.state.records.lastDestroyed&&e.from!==this.state.records.lastDestroyed)throw new Error("The destroyed participant "+this.state.records.lastDestroyed.name+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");this.state.records.lastDestroyed=void 0}this.addSignal(e.from,e.to,e.msg,e.signalType,e.activate);break;case"boxStart":this.addBox(e.boxData);break;case"boxEnd":this.boxEnd();break;case"loopStart":this.addSignal(void 0,void 0,e.loopText,e.signalType);break;case"loopEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"rectStart":this.addSignal(void 0,void 0,e.color,e.signalType);break;case"rectEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"optStart":this.addSignal(void 0,void 0,e.optText,e.signalType);break;case"optEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"altStart":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"else":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"altEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"setAccTitle":Ar(e.text);break;case"parStart":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"and":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"parEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"criticalStart":this.addSignal(void 0,void 0,e.criticalText,e.signalType);break;case"option":this.addSignal(void 0,void 0,e.optionText,e.signalType);break;case"criticalEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"breakStart":this.addSignal(void 0,void 0,e.breakText,e.signalType);break;case"breakEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break}}getConfig(){return me().sequence}}});var GUe,Rde,Nde=N(()=>{"use strict";GUe=o(t=>`.actor { - stroke: ${t.actorBorder}; - fill: ${t.actorBkg}; - } - - text.actor > tspan { - fill: ${t.actorTextColor}; - stroke: none; - } - - .actor-line { - stroke: ${t.actorLineColor}; - } - - .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: none; - stroke: ${t.signalColor}; - } - - .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: 2, 2; - stroke: ${t.signalColor}; - } - - #arrowhead path { - fill: ${t.signalColor}; - stroke: ${t.signalColor}; - } - - .sequenceNumber { - fill: ${t.sequenceNumberColor}; - } - - #sequencenumber { - fill: ${t.signalColor}; - } - - #crosshead path { - fill: ${t.signalColor}; - stroke: ${t.signalColor}; - } - - .messageText { - fill: ${t.signalTextColor}; - stroke: none; - } - - .labelBox { - stroke: ${t.labelBoxBorderColor}; - fill: ${t.labelBoxBkgColor}; - } - - .labelText, .labelText > tspan { - fill: ${t.labelTextColor}; - stroke: none; - } - - .loopText, .loopText > tspan { - fill: ${t.loopTextColor}; - stroke: none; - } - - .loopLine { - stroke-width: 2px; - stroke-dasharray: 2, 2; - stroke: ${t.labelBoxBorderColor}; - fill: ${t.labelBoxBorderColor}; - } - - .note { - //stroke: #decc93; - stroke: ${t.noteBorderColor}; - fill: ${t.noteBkgColor}; - } - - .noteText, .noteText > tspan { - fill: ${t.noteTextColor}; - stroke: none; - } - - .activation0 { - fill: ${t.activationBkgColor}; - stroke: ${t.activationBorderColor}; - } - - .activation1 { - fill: ${t.activationBkgColor}; - stroke: ${t.activationBorderColor}; - } - - .activation2 { - fill: ${t.activationBkgColor}; - stroke: ${t.activationBorderColor}; - } - - .actorPopupMenu { - position: absolute; - } - - .actorPopupMenuPanel { - position: absolute; - fill: ${t.actorBkg}; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4)); -} - .actor-man line { - stroke: ${t.actorBorder}; - fill: ${t.actorBkg}; - } - .actor-man circle, line { - stroke: ${t.actorBorder}; - fill: ${t.actorBkg}; - stroke-width: 2px; - } -`,"getStyles"),Rde=GUe});var pP,Sf,Ide,Ode,VUe,Mde,mP,UUe,HUe,Mb,Fp,Pde,Yc,gP,WUe,qUe,YUe,XUe,jUe,KUe,QUe,Bde,ZUe,JUe,eHe,tHe,rHe,nHe,iHe,Fde,aHe,yP,sHe,di,$de=N(()=>{"use strict";pr();t2();er();pP=Aa(Z0(),1);mi();Sf=18*2,Ide="actor-top",Ode="actor-bottom",VUe="actor-box",Mde="actor-man",mP=o(function(t,e){return Nd(t,e)},"drawRect"),UUe=o(function(t,e,r,n,i){if(e.links===void 0||e.links===null||Object.keys(e.links).length===0)return{height:0,width:0};let a=e.links,s=e.actorCnt,l=e.rectData;var u="none";i&&(u="block !important");let h=t.append("g");h.attr("id","actor"+s+"_popup"),h.attr("class","actorPopupMenu"),h.attr("display",u);var f="";l.class!==void 0&&(f=" "+l.class);let d=l.width>r?l.width:r,p=h.append("rect");if(p.attr("class","actorPopupMenuPanel"+f),p.attr("x",l.x),p.attr("y",l.height),p.attr("fill",l.fill),p.attr("stroke",l.stroke),p.attr("width",d),p.attr("height",l.height),p.attr("rx",l.rx),p.attr("ry",l.ry),a!=null){var m=20;for(let v in a){var g=h.append("a"),y=(0,pP.sanitizeUrl)(a[v]);g.attr("xlink:href",y),g.attr("target","_blank"),sHe(n)(v,g,l.x+10,l.height+m,d,20,{class:"actor"},n),m+=30}}return p.attr("height",m),{height:l.height+m,width:d}},"drawPopup"),HUe=o(function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"},"popupMenuToggle"),Mb=o(async function(t,e,r=null){let n=t.append("foreignObject"),i=await Th(e.text,tr()),s=n.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(i).node().getBoundingClientRect();if(n.attr("height",Math.round(s.height)).attr("width",Math.round(s.width)),e.class==="noteText"){let l=t.node().firstChild;l.setAttribute("height",s.height+2*e.textMargin);let u=l.getBBox();n.attr("x",Math.round(u.x+u.width/2-s.width/2)).attr("y",Math.round(u.y+u.height/2-s.height/2))}else if(r){let{startx:l,stopx:u,starty:h}=r;if(l>u){let f=l;l=u,u=f}n.attr("x",Math.round(l+Math.abs(l-u)/2-s.width/2)),e.class==="loopText"?n.attr("y",Math.round(h)):n.attr("y",Math.round(h-s.height))}return[n]},"drawKatex"),Fp=o(function(t,e){let r=0,n=0,i=e.text.split(Ze.lineBreakRegex),[a,s]=zo(e.fontSize),l=[],u=0,h=o(()=>e.y,"yfunc");if(e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0)switch(e.valign){case"top":case"start":h=o(()=>Math.round(e.y+e.textMargin),"yfunc");break;case"middle":case"center":h=o(()=>Math.round(e.y+(r+n+e.textMargin)/2),"yfunc");break;case"bottom":case"end":h=o(()=>Math.round(e.y+(r+n+2*e.textMargin)-e.textMargin),"yfunc");break}if(e.anchor!==void 0&&e.textMargin!==void 0&&e.width!==void 0)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle";break}for(let[f,d]of i.entries()){e.textMargin!==void 0&&e.textMargin===0&&a!==void 0&&(u=f*a);let p=t.append("text");p.attr("x",e.x),p.attr("y",h()),e.anchor!==void 0&&p.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),e.fontFamily!==void 0&&p.style("font-family",e.fontFamily),s!==void 0&&p.style("font-size",s),e.fontWeight!==void 0&&p.style("font-weight",e.fontWeight),e.fill!==void 0&&p.attr("fill",e.fill),e.class!==void 0&&p.attr("class",e.class),e.dy!==void 0?p.attr("dy",e.dy):u!==0&&p.attr("dy",u);let m=d||C9;if(e.tspan){let g=p.append("tspan");g.attr("x",e.x),e.fill!==void 0&&g.attr("fill",e.fill),g.text(m)}else p.text(m);e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0&&(n+=(p._groups||p)[0][0].getBBox().height,r=n),l.push(p)}return l},"drawText"),Pde=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");return n.attr("points",r(e.x,e.y,e.width,e.height,7)),n.attr("class","labelBox"),e.y=e.y+e.height/2,Fp(t,e),n},"drawLabel"),Yc=-1,gP=o((t,e,r,n)=>{t.select&&r.forEach(i=>{let a=e.get(i),s=t.select("#actor"+a.actorCnt);!n.mirrorActors&&a.stopy?s.attr("y2",a.stopy+a.height/2):n.mirrorActors&&s.attr("y2",a.stopy)})},"fixLifeLineHeights"),WUe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+e.height,l=t.append("g").lower();var u=l;n||(Yc++,Object.keys(e.links||{}).length&&!r.forceMenus&&u.attr("onclick",HUe(`actor${Yc}_popup`)).attr("cursor","pointer"),u.append("line").attr("id","actor"+Yc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),u=l.append("g"),e.actorCnt=Yc,e.links!=null&&u.attr("id","root-"+Yc));let h=Al();var f="actor";e.properties?.class?f=e.properties.class:h.fill="#eaeaea",n?f+=` ${Ode}`:f+=` ${Ide}`,h.x=e.x,h.y=i,h.width=e.width,h.height=e.height,h.class=f,h.rx=3,h.ry=3,h.name=e.name;let d=mP(u,h);if(e.rectData=h,e.properties?.icon){let m=e.properties.icon.trim();m.charAt(0)==="@"?KY(u,h.x+h.width-20,h.y+10,m.substr(1)):jY(u,h.x+h.width-20,h.y+10,m)}yP(r,yi(e.description))(e.description,u,h.x,h.y,h.width,h.height,{class:`actor ${VUe}`},r);let p=e.height;if(d.node){let m=d.node().getBBox();e.height=m.height,p=m.height}return p},"drawActorTypeParticipant"),qUe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+80,l=t.append("g").lower();n||(Yc++,l.append("line").attr("id","actor"+Yc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=Yc);let u=t.append("g"),h=Mde;n?h+=` ${Ode}`:h+=` ${Ide}`,u.attr("class",h),u.attr("name",e.name);let f=Al();f.x=e.x,f.y=i,f.fill="#eaeaea",f.width=e.width,f.height=e.height,f.class="actor",f.rx=3,f.ry=3,u.append("line").attr("id","actor-man-torso"+Yc).attr("x1",a).attr("y1",i+25).attr("x2",a).attr("y2",i+45),u.append("line").attr("id","actor-man-arms"+Yc).attr("x1",a-Sf/2).attr("y1",i+33).attr("x2",a+Sf/2).attr("y2",i+33),u.append("line").attr("x1",a-Sf/2).attr("y1",i+60).attr("x2",a).attr("y2",i+45),u.append("line").attr("x1",a).attr("y1",i+45).attr("x2",a+Sf/2-2).attr("y2",i+60);let d=u.append("circle");d.attr("cx",e.x+e.width/2),d.attr("cy",i+10),d.attr("r",15),d.attr("width",e.width),d.attr("height",e.height);let p=u.node().getBBox();return e.height=p.height,yP(r,yi(e.description))(e.description,u,f.x,f.y+35,f.width,f.height,{class:`actor ${Mde}`},r),e.height},"drawActorTypeActor"),YUe=o(async function(t,e,r,n){switch(e.type){case"actor":return await qUe(t,e,r,n);case"participant":return await WUe(t,e,r,n)}},"drawActor"),XUe=o(function(t,e,r){let i=t.append("g");Bde(i,e),e.name&&yP(r)(e.name,i,e.x,e.y+r.boxTextMargin+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},r),i.lower()},"drawBox"),jUe=o(function(t){return t.append("g")},"anchorElement"),KUe=o(function(t,e,r,n,i){let a=Al(),s=e.anchored;a.x=e.startx,a.y=e.starty,a.class="activation"+i%3,a.width=e.stopx-e.startx,a.height=r-e.starty,mP(s,a)},"drawActivation"),QUe=o(async function(t,e,r,n){let{boxMargin:i,boxTextMargin:a,labelBoxHeight:s,labelBoxWidth:l,messageFontFamily:u,messageFontSize:h,messageFontWeight:f}=n,d=t.append("g"),p=o(function(y,v,x,b){return d.append("line").attr("x1",y).attr("y1",v).attr("x2",x).attr("y2",b).attr("class","loopLine")},"drawLoopLine");p(e.startx,e.starty,e.stopx,e.starty),p(e.stopx,e.starty,e.stopx,e.stopy),p(e.startx,e.stopy,e.stopx,e.stopy),p(e.startx,e.starty,e.startx,e.stopy),e.sections!==void 0&&e.sections.forEach(function(y){p(e.startx,y.y,e.stopx,y.y).style("stroke-dasharray","3, 3")});let m=e2();m.text=r,m.x=e.startx,m.y=e.starty,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.anchor="middle",m.valign="middle",m.tspan=!1,m.width=l||50,m.height=s||20,m.textMargin=a,m.class="labelText",Pde(d,m),m=Fde(),m.text=e.title,m.x=e.startx+l/2+(e.stopx-e.startx)/2,m.y=e.starty+i+a,m.anchor="middle",m.valign="middle",m.textMargin=a,m.class="loopText",m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=!0;let g=yi(m.text)?await Mb(d,m,e):Fp(d,m);if(e.sectionTitles!==void 0){for(let[y,v]of Object.entries(e.sectionTitles))if(v.message){m.text=v.message,m.x=e.startx+(e.stopx-e.startx)/2,m.y=e.sections[y].y+i+a,m.class="loopText",m.anchor="middle",m.valign="middle",m.tspan=!1,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=e.wrap,yi(m.text)?(e.starty=e.sections[y].y,await Mb(d,m,e)):Fp(d,m);let x=Math.round(g.map(b=>(b._groups||b)[0][0].getBBox().height).reduce((b,T)=>b+T));e.sections[y].height+=x-(i+a)}}return e.height=Math.round(e.stopy-e.starty),d},"drawLoop"),Bde=o(function(t,e){iT(t,e)},"drawBackgroundRect"),ZUe=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),JUe=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),eHe=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),tHe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto-start-reverse").append("path").attr("d","M -1 0 L 10 5 L 0 10 z")},"insertArrowHead"),rHe=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),nHe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertSequenceNumber"),iHe=o(function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},"insertArrowCrossHead"),Fde=o(function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},"getTextObj"),aHe=o(function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),yP=function(){function t(a,s,l,u,h,f,d){let p=s.append("text").attr("x",l+h/2).attr("y",u+f/2+5).style("text-anchor","middle").text(a);i(p,d)}o(t,"byText");function e(a,s,l,u,h,f,d,p){let{actorFontSize:m,actorFontFamily:g,actorFontWeight:y}=p,[v,x]=zo(m),b=a.split(Ze.lineBreakRegex);for(let T=0;T{let s=$p(Ne),l=a.actorKeys.reduce((f,d)=>f+=t.get(d).width+(t.get(d).margin||0),0);l-=2*Ne.boxTextMargin,a.wrap&&(a.name=Vt.wrapLabel(a.name,l-2*Ne.wrapPadding,s));let u=Vt.calculateTextDimensions(a.name,s);i=Ze.getMax(u.height,i);let h=Ze.getMax(l,u.width+2*Ne.wrapPadding);if(a.margin=Ne.boxTextMargin,la.textMaxHeight=i),Ze.getMax(n,Ne.height)}var Ne,rt,oHe,$p,O1,vP,cHe,uHe,xP,Gde,Vde,XS,zde,fHe,pHe,gHe,yHe,vHe,Ude,Hde=N(()=>{"use strict";fr();$de();yt();pr();pr();t2();Gt();g0();er();xi();Ne={},rt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:o(function(){return Math.max.apply(null,this.actors.length===0?[0]:this.actors.map(t=>t.height||0))+(this.loops.length===0?0:this.loops.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.messages.length===0?0:this.messages.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.notes.length===0?0:this.notes.map(t=>t.height||0).reduce((t,e)=>t+e))},"getHeight"),clear:o(function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},"clear"),addBox:o(function(t){this.boxes.push(t)},"addBox"),addActor:o(function(t){this.actors.push(t)},"addActor"),addLoop:o(function(t){this.loops.push(t)},"addLoop"),addMessage:o(function(t){this.messages.push(t)},"addMessage"),addNote:o(function(t){this.notes.push(t)},"addNote"),lastActor:o(function(){return this.actors[this.actors.length-1]},"lastActor"),lastLoop:o(function(){return this.loops[this.loops.length-1]},"lastLoop"),lastMessage:o(function(){return this.messages[this.messages.length-1]},"lastMessage"),lastNote:o(function(){return this.notes[this.notes.length-1]},"lastNote"),actors:[],boxes:[],loops:[],messages:[],notes:[]},init:o(function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,Vde(me())},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=this,a=0;function s(l){return o(function(h){a++;let f=i.sequenceItems.length-a+1;i.updateVal(h,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopy",n+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopx",r+f*Ne.boxMargin,Math.max),l!=="activation"&&(i.updateVal(h,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopx",r+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopy",n+f*Ne.boxMargin,Math.max))},"updateItemBounds")}o(s,"updateFn"),this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},"updateBounds"),insert:o(function(t,e,r,n){let i=Ze.getMin(t,r),a=Ze.getMax(t,r),s=Ze.getMin(e,n),l=Ze.getMax(e,n);this.updateVal(rt.data,"startx",i,Math.min),this.updateVal(rt.data,"starty",s,Math.min),this.updateVal(rt.data,"stopx",a,Math.max),this.updateVal(rt.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),newActivation:o(function(t,e,r){let n=r.get(t.from),i=XS(t.from).length||0,a=n.x+n.width/2+(i-1)*Ne.activationWidth/2;this.activations.push({startx:a,starty:this.verticalPos+2,stopx:a+Ne.activationWidth,stopy:void 0,actor:t.from,anchored:di.anchorElement(e)})},"newActivation"),endActivation:o(function(t){let e=this.activations.map(function(r){return r.actor}).lastIndexOf(t.from);return this.activations.splice(e,1)[0]},"endActivation"),createLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},"createLoop"),newLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},"newLoop"),endLoop:o(function(){return this.sequenceItems.pop()},"endLoop"),isLoopOverlap:o(function(){return this.sequenceItems.length?this.sequenceItems[this.sequenceItems.length-1].overlap:!1},"isLoopOverlap"),addSectionToLoop:o(function(t){let e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:rt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},"addSectionToLoop"),saveVerticalPos:o(function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},"saveVerticalPos"),resetVerticalPos:o(function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},"resetVerticalPos"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=Ze.getMax(this.data.stopy,this.verticalPos)},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return{bounds:this.data,models:this.models}},"getBounds")},oHe=o(async function(t,e){rt.bumpVerticalPos(Ne.boxMargin),e.height=Ne.boxMargin,e.starty=rt.getVerticalPos();let r=Al();r.x=e.startx,r.y=e.starty,r.width=e.width||Ne.width,r.class="note";let n=t.append("g"),i=di.drawRect(n,r),a=e2();a.x=e.startx,a.y=e.starty,a.width=r.width,a.dy="1em",a.text=e.message,a.class="noteText",a.fontFamily=Ne.noteFontFamily,a.fontSize=Ne.noteFontSize,a.fontWeight=Ne.noteFontWeight,a.anchor=Ne.noteAlign,a.textMargin=Ne.noteMargin,a.valign="center";let s=yi(a.text)?await Mb(n,a):Fp(n,a),l=Math.round(s.map(u=>(u._groups||u)[0][0].getBBox().height).reduce((u,h)=>u+h));i.attr("height",l+2*Ne.noteMargin),e.height+=l+2*Ne.noteMargin,rt.bumpVerticalPos(l+2*Ne.noteMargin),e.stopy=e.starty+l+2*Ne.noteMargin,e.stopx=e.startx+r.width,rt.insert(e.startx,e.starty,e.stopx,e.stopy),rt.models.addNote(e)},"drawNote"),$p=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont"),O1=o(t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),"noteFont"),vP=o(t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}),"actorFont");o(lHe,"boundMessage");cHe=o(async function(t,e,r,n){let{startx:i,stopx:a,starty:s,message:l,type:u,sequenceIndex:h,sequenceVisible:f}=e,d=Vt.calculateTextDimensions(l,$p(Ne)),p=e2();p.x=i,p.y=s+10,p.width=a-i,p.class="messageText",p.dy="1em",p.text=l,p.fontFamily=Ne.messageFontFamily,p.fontSize=Ne.messageFontSize,p.fontWeight=Ne.messageFontWeight,p.anchor=Ne.messageAlign,p.valign="center",p.textMargin=Ne.wrapPadding,p.tspan=!1,yi(p.text)?await Mb(t,p,{startx:i,stopx:a,starty:r}):Fp(t,p);let m=d.width,g;i===a?Ne.rightAngles?g=t.append("path").attr("d",`M ${i},${r} H ${i+Ze.getMax(Ne.width/2,m/2)} V ${r+25} H ${i}`):g=t.append("path").attr("d","M "+i+","+r+" C "+(i+60)+","+(r-10)+" "+(i+60)+","+(r+30)+" "+i+","+(r+20)):(g=t.append("line"),g.attr("x1",i),g.attr("y1",r),g.attr("x2",a),g.attr("y2",r)),u===n.db.LINETYPE.DOTTED||u===n.db.LINETYPE.DOTTED_CROSS||u===n.db.LINETYPE.DOTTED_POINT||u===n.db.LINETYPE.DOTTED_OPEN||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED?(g.style("stroke-dasharray","3, 3"),g.attr("class","messageLine1")):g.attr("class","messageLine0");let y="";Ne.arrowMarkerAbsolute&&(y=mu(!0)),g.attr("stroke-width",2),g.attr("stroke","none"),g.style("fill","none"),(u===n.db.LINETYPE.SOLID||u===n.db.LINETYPE.DOTTED)&&g.attr("marker-end","url("+y+"#arrowhead)"),(u===n.db.LINETYPE.BIDIRECTIONAL_SOLID||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED)&&(g.attr("marker-start","url("+y+"#arrowhead)"),g.attr("marker-end","url("+y+"#arrowhead)")),(u===n.db.LINETYPE.SOLID_POINT||u===n.db.LINETYPE.DOTTED_POINT)&&g.attr("marker-end","url("+y+"#filled-head)"),(u===n.db.LINETYPE.SOLID_CROSS||u===n.db.LINETYPE.DOTTED_CROSS)&&g.attr("marker-end","url("+y+"#crosshead)"),(f||Ne.showSequenceNumbers)&&(g.attr("marker-start","url("+y+"#sequencenumber)"),t.append("text").attr("x",i).attr("y",r+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(h))},"drawMessage"),uHe=o(function(t,e,r,n,i,a,s){let l=0,u=0,h,f=0;for(let d of n){let p=e.get(d),m=p.box;h&&h!=m&&(s||rt.models.addBox(h),u+=Ne.boxMargin+h.margin),m&&m!=h&&(s||(m.x=l+u,m.y=i),u+=m.margin),p.width=p.width||Ne.width,p.height=Ze.getMax(p.height||Ne.height,Ne.height),p.margin=p.margin||Ne.actorMargin,f=Ze.getMax(f,p.height),r.get(p.name)&&(u+=p.width/2),p.x=l+u,p.starty=rt.getVerticalPos(),rt.insert(p.x,i,p.x+p.width,p.height),l+=p.width+u,p.box&&(p.box.width=l+m.margin-p.box.x),u=p.margin,h=p.box,rt.models.addActor(p)}h&&!s&&rt.models.addBox(h),rt.bumpVerticalPos(f)},"addActorRenderingData"),xP=o(async function(t,e,r,n){if(n){let i=0;rt.bumpVerticalPos(Ne.boxMargin*2);for(let a of r){let s=e.get(a);s.stopy||(s.stopy=rt.getVerticalPos());let l=await di.drawActor(t,s,Ne,!0);i=Ze.getMax(i,l)}rt.bumpVerticalPos(i+Ne.boxMargin)}else for(let i of r){let a=e.get(i);await di.drawActor(t,a,Ne,!1)}},"drawActors"),Gde=o(function(t,e,r,n){let i=0,a=0;for(let s of r){let l=e.get(s),u=pHe(l),h=di.drawPopup(t,l,u,Ne,Ne.forceMenus,n);h.height>i&&(i=h.height),h.width+l.x>a&&(a=h.width+l.x)}return{maxHeight:i,maxWidth:a}},"drawActorsPopup"),Vde=o(function(t){Un(Ne,t),t.fontFamily&&(Ne.actorFontFamily=Ne.noteFontFamily=Ne.messageFontFamily=t.fontFamily),t.fontSize&&(Ne.actorFontSize=Ne.noteFontSize=Ne.messageFontSize=t.fontSize),t.fontWeight&&(Ne.actorFontWeight=Ne.noteFontWeight=Ne.messageFontWeight=t.fontWeight)},"setConf"),XS=o(function(t){return rt.activations.filter(function(e){return e.actor===t})},"actorActivations"),zde=o(function(t,e){let r=e.get(t),n=XS(t),i=n.reduce(function(s,l){return Ze.getMin(s,l.startx)},r.x+r.width/2-1),a=n.reduce(function(s,l){return Ze.getMax(s,l.stopx)},r.x+r.width/2+1);return[i,a]},"activationBounds");o(Xc,"adjustLoopHeightForWrap");o(hHe,"adjustCreatedDestroyedData");fHe=o(async function(t,e,r,n){let{securityLevel:i,sequence:a}=me();Ne=a;let s;i==="sandbox"&&(s=Ge("#i"+e));let l=i==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=i==="sandbox"?s.nodes()[0].contentDocument:document;rt.init(),X.debug(n.db);let h=i==="sandbox"?l.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=n.db.getActors(),d=n.db.getCreatedActors(),p=n.db.getDestroyedActors(),m=n.db.getBoxes(),g=n.db.getActorKeys(),y=n.db.getMessages(),v=n.db.getDiagramTitle(),x=n.db.hasAtLeastOneBox(),b=n.db.hasAtLeastOneBoxWithTitle(),T=await dHe(f,y,n);if(Ne.height=await mHe(f,T,m),di.insertComputerIcon(h),di.insertDatabaseIcon(h),di.insertClockIcon(h),x&&(rt.bumpVerticalPos(Ne.boxMargin),b&&rt.bumpVerticalPos(m[0].textMaxHeight)),Ne.hideUnusedParticipants===!0){let B=new Set;y.forEach(F=>{B.add(F.from),B.add(F.to)}),g=g.filter(F=>B.has(F))}uHe(h,f,d,g,0,y,!1);let S=await vHe(y,f,T,n);di.insertArrowHead(h),di.insertArrowCrossHead(h),di.insertArrowFilledHead(h),di.insertSequenceNumber(h);function w(B,F){let z=rt.endActivation(B);z.starty+18>F&&(z.starty=F-6,F+=12),di.drawActivation(h,z,F,Ne,XS(B.from).length),rt.insert(z.startx,F-10,z.stopx,F)}o(w,"activeEnd");let E=1,_=1,C=[],D=[],O=0;for(let B of y){let F,z,$;switch(B.type){case n.db.LINETYPE.NOTE:rt.resetVerticalPos(),z=B.noteModel,await oHe(h,z);break;case n.db.LINETYPE.ACTIVE_START:rt.newActivation(B,h,f);break;case n.db.LINETYPE.ACTIVE_END:w(B,rt.getVerticalPos());break;case n.db.LINETYPE.LOOP_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.LOOP_END:F=rt.endLoop(),await di.drawLoop(h,F,"loop",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.RECT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin,U=>rt.newLoop(void 0,U.message));break;case n.db.LINETYPE.RECT_END:F=rt.endLoop(),D.push(F),rt.models.addLoop(F),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos());break;case n.db.LINETYPE.OPT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.OPT_END:F=rt.endLoop(),await di.drawLoop(h,F,"opt",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.ALT_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.ALT_ELSE:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.ALT_END:F=rt.endLoop(),await di.drawLoop(h,F,"alt",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U)),rt.saveVerticalPos();break;case n.db.LINETYPE.PAR_AND:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.PAR_END:F=rt.endLoop(),await di.drawLoop(h,F,"par",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.AUTONUMBER:E=B.message.start||E,_=B.message.step||_,B.message.visible?n.db.enableSequenceNumbers():n.db.disableSequenceNumbers();break;case n.db.LINETYPE.CRITICAL_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.CRITICAL_OPTION:Xc(S,B,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,U=>rt.addSectionToLoop(U));break;case n.db.LINETYPE.CRITICAL_END:F=rt.endLoop(),await di.drawLoop(h,F,"critical",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;case n.db.LINETYPE.BREAK_START:Xc(S,B,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,U=>rt.newLoop(U));break;case n.db.LINETYPE.BREAK_END:F=rt.endLoop(),await di.drawLoop(h,F,"break",Ne),rt.bumpVerticalPos(F.stopy-rt.getVerticalPos()),rt.models.addLoop(F);break;default:try{$=B.msgModel,$.starty=rt.getVerticalPos(),$.sequenceIndex=E,$.sequenceVisible=n.db.showSequenceNumbers();let U=await lHe(h,$);hHe(B,$,U,O,f,d,p),C.push({messageModel:$,lineStartY:U}),rt.models.addMessage($)}catch(U){X.error("error while drawing message",U)}}[n.db.LINETYPE.SOLID_OPEN,n.db.LINETYPE.DOTTED_OPEN,n.db.LINETYPE.SOLID,n.db.LINETYPE.DOTTED,n.db.LINETYPE.SOLID_CROSS,n.db.LINETYPE.DOTTED_CROSS,n.db.LINETYPE.SOLID_POINT,n.db.LINETYPE.DOTTED_POINT,n.db.LINETYPE.BIDIRECTIONAL_SOLID,n.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(B.type)&&(E=E+_),O++}X.debug("createdActors",d),X.debug("destroyedActors",p),await xP(h,f,g,!1);for(let B of C)await cHe(h,B.messageModel,B.lineStartY,n);Ne.mirrorActors&&await xP(h,f,g,!0),D.forEach(B=>di.drawBackgroundRect(h,B)),gP(h,f,g,Ne);for(let B of rt.models.boxes)B.height=rt.getVerticalPos()-B.y,rt.insert(B.x,B.y,B.x+B.width,B.height),B.startx=B.x,B.starty=B.y,B.stopx=B.startx+B.width,B.stopy=B.starty+B.height,B.stroke="rgb(0,0,0, 0.5)",di.drawBox(h,B,Ne);x&&rt.bumpVerticalPos(Ne.boxMargin);let R=Gde(h,f,g,u),{bounds:k}=rt.getBounds();k.startx===void 0&&(k.startx=0),k.starty===void 0&&(k.starty=0),k.stopx===void 0&&(k.stopx=0),k.stopy===void 0&&(k.stopy=0);let L=k.stopy-k.starty;L2,d=o(y=>l?-y:y,"adjustValue");t.from===t.to?h=u:(t.activate&&!f&&(h+=d(Ne.activationWidth/2-1)),[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(h+=d(3)),[r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type)&&(u-=d(3)));let p=[n,i,a,s],m=Math.abs(u-h);t.wrap&&t.message&&(t.message=Vt.wrapLabel(t.message,Ze.getMax(m+2*Ne.wrapPadding,Ne.width),$p(Ne)));let g=Vt.calculateTextDimensions(t.message,$p(Ne));return{width:Ze.getMax(t.wrap?0:g.width+2*Ne.wrapPadding,m+2*Ne.wrapPadding,Ne.width),height:0,startx:u,stopx:h,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,p),toBounds:Math.max.apply(null,p)}},"buildMessageModel"),vHe=o(async function(t,e,r,n){let i={},a=[],s,l,u;for(let h of t){switch(h.type){case n.db.LINETYPE.LOOP_START:case n.db.LINETYPE.ALT_START:case n.db.LINETYPE.OPT_START:case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:case n.db.LINETYPE.CRITICAL_START:case n.db.LINETYPE.BREAK_START:a.push({id:h.id,msg:h.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case n.db.LINETYPE.ALT_ELSE:case n.db.LINETYPE.PAR_AND:case n.db.LINETYPE.CRITICAL_OPTION:h.message&&(s=a.pop(),i[s.id]=s,i[h.id]=s,a.push(s));break;case n.db.LINETYPE.LOOP_END:case n.db.LINETYPE.ALT_END:case n.db.LINETYPE.OPT_END:case n.db.LINETYPE.PAR_END:case n.db.LINETYPE.CRITICAL_END:case n.db.LINETYPE.BREAK_END:s=a.pop(),i[s.id]=s;break;case n.db.LINETYPE.ACTIVE_START:{let d=e.get(h.from?h.from:h.to.actor),p=XS(h.from?h.from:h.to.actor).length,m=d.x+d.width/2+(p-1)*Ne.activationWidth/2,g={startx:m,stopx:m+Ne.activationWidth,actor:h.from,enabled:!0};rt.activations.push(g)}break;case n.db.LINETYPE.ACTIVE_END:{let d=rt.activations.map(p=>p.actor).lastIndexOf(h.from);rt.activations.splice(d,1).splice(0,1)}break}h.placement!==void 0?(l=await gHe(h,e,n),h.noteModel=l,a.forEach(d=>{s=d,s.from=Ze.getMin(s.from,l.startx),s.to=Ze.getMax(s.to,l.startx+l.width),s.width=Ze.getMax(s.width,Math.abs(s.from-s.to))-Ne.labelBoxWidth})):(u=yHe(h,e,n),h.msgModel=u,u.startx&&u.stopx&&a.length>0&&a.forEach(d=>{if(s=d,u.startx===u.stopx){let p=e.get(h.from),m=e.get(h.to);s.from=Ze.getMin(p.x-u.width/2,p.x-p.width/2,s.from),s.to=Ze.getMax(m.x+u.width/2,m.x+p.width/2,s.to),s.width=Ze.getMax(s.width,Math.abs(s.to-s.from))-Ne.labelBoxWidth}else s.from=Ze.getMin(u.startx,s.from),s.to=Ze.getMax(u.stopx,s.to),s.width=Ze.getMax(s.width,u.width)-Ne.labelBoxWidth}))}return rt.activations=[],X.debug("Loop type widths:",i),i},"calculateLoopBounds"),Ude={bounds:rt,drawActors:xP,drawActorsPopup:Gde,setConf:Vde,draw:fHe}});var Wde={};ur(Wde,{diagram:()=>xHe});var xHe,qde=N(()=>{"use strict";Dde();Lde();Nde();Gt();Hde();xHe={parser:_de,get db(){return new YS},renderer:Ude,styles:Rde,init:o(t=>{t.sequence||(t.sequence={}),t.wrap&&(t.sequence.wrap=t.wrap,nv({sequence:{wrap:t.wrap}}))},"init")}});var bP,jS,TP=N(()=>{"use strict";bP=function(){var t=o(function(Ie,xe,q,de){for(q=q||{},de=Ie.length;de--;q[Ie[de]]=xe);return q},"o"),e=[1,18],r=[1,19],n=[1,20],i=[1,41],a=[1,42],s=[1,26],l=[1,24],u=[1,25],h=[1,32],f=[1,33],d=[1,34],p=[1,45],m=[1,35],g=[1,36],y=[1,37],v=[1,38],x=[1,27],b=[1,28],T=[1,29],S=[1,30],w=[1,31],E=[1,44],_=[1,46],C=[1,43],D=[1,47],O=[1,9],R=[1,8,9],k=[1,58],L=[1,59],A=[1,60],I=[1,61],M=[1,62],P=[1,63],B=[1,64],F=[1,8,9,41],z=[1,76],$=[1,8,9,12,13,22,39,41,44,66,67,68,69,70,71,72,77,79],U=[1,8,9,12,13,17,20,22,39,41,44,48,58,66,67,68,69,70,71,72,77,79,84,99,101,102],K=[13,58,84,99,101,102],ee=[13,58,71,72,84,99,101,102],Y=[13,58,66,67,68,69,70,84,99,101,102],ce=[1,98],Z=[1,115],ue=[1,107],Q=[1,113],j=[1,108],ne=[1,109],te=[1,110],he=[1,111],le=[1,112],J=[1,114],Se=[22,58,59,80,84,85,86,87,88,89],se=[1,8,9,39,41,44],ae=[1,8,9,22],Oe=[1,143],ye=[1,8,9,59],Be=[1,8,9,22,58,59,80,84,85,86,87,88,89],He={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,DOT:17,className:18,classLiteralName:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,CLASS:46,ANNOTATION_START:47,ANNOTATION_END:48,MEMBER:49,SEPARATOR:50,relation:51,NOTE_FOR:52,noteText:53,NOTE:54,CLASSDEF:55,classList:56,stylesOpt:57,ALPHA:58,COMMA:59,direction_tb:60,direction_bt:61,direction_rl:62,direction_lr:63,relationType:64,lineType:65,AGGREGATION:66,EXTENSION:67,COMPOSITION:68,DEPENDENCY:69,LOLLIPOP:70,LINE:71,DOTTED_LINE:72,CALLBACK:73,LINK:74,LINK_TARGET:75,CLICK:76,CALLBACK_NAME:77,CALLBACK_ARGS:78,HREF:79,STYLE:80,CSSCLASS:81,style:82,styleComponent:83,NUM:84,COLON:85,UNIT:86,SPACE:87,BRKT:88,PCT:89,commentToken:90,textToken:91,graphCodeTokens:92,textNoTagsToken:93,TAGSTART:94,TAGEND:95,"==":96,"--":97,DEFAULT:98,MINUS:99,keywords:100,UNICODE_TEXT:101,BQUOTE_STR:102,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",17:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"CLASS",47:"ANNOTATION_START",48:"ANNOTATION_END",49:"MEMBER",50:"SEPARATOR",52:"NOTE_FOR",54:"NOTE",55:"CLASSDEF",58:"ALPHA",59:"COMMA",60:"direction_tb",61:"direction_bt",62:"direction_rl",63:"direction_lr",66:"AGGREGATION",67:"EXTENSION",68:"COMPOSITION",69:"DEPENDENCY",70:"LOLLIPOP",71:"LINE",72:"DOTTED_LINE",73:"CALLBACK",74:"LINK",75:"LINK_TARGET",76:"CLICK",77:"CALLBACK_NAME",78:"CALLBACK_ARGS",79:"HREF",80:"STYLE",81:"CSSCLASS",84:"NUM",85:"COLON",86:"UNIT",87:"SPACE",88:"BRKT",89:"PCT",92:"graphCodeTokens",94:"TAGSTART",95:"TAGEND",96:"==",97:"--",98:"DEFAULT",99:"MINUS",100:"keywords",101:"UNICODE_TEXT",102:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,3],[15,2],[18,1],[18,3],[18,1],[18,2],[18,2],[18,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,6],[43,2],[43,3],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[56,1],[56,3],[32,1],[32,1],[32,1],[32,1],[51,3],[51,2],[51,2],[51,1],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[57,1],[57,3],[82,1],[82,2],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[90,1],[90,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[93,1],[93,1],[93,1],[93,1],[16,1],[16,1],[16,1],[16,1],[19,1],[53,1]],performAction:o(function(xe,q,de,ie,oe,V,Te){var W=V.length-1;switch(oe){case 8:this.$=V[W-1];break;case 9:case 12:case 14:this.$=V[W];break;case 10:case 13:this.$=V[W-2]+"."+V[W];break;case 11:case 15:this.$=V[W-1]+V[W];break;case 16:case 17:this.$=V[W-1]+"~"+V[W]+"~";break;case 18:ie.addRelation(V[W]);break;case 19:V[W-1].title=ie.cleanupLabel(V[W]),ie.addRelation(V[W-1]);break;case 30:this.$=V[W].trim(),ie.setAccTitle(this.$);break;case 31:case 32:this.$=V[W].trim(),ie.setAccDescription(this.$);break;case 33:ie.addClassesToNamespace(V[W-3],V[W-1]);break;case 34:ie.addClassesToNamespace(V[W-4],V[W-1]);break;case 35:this.$=V[W],ie.addNamespace(V[W]);break;case 36:this.$=[V[W]];break;case 37:this.$=[V[W-1]];break;case 38:V[W].unshift(V[W-2]),this.$=V[W];break;case 40:ie.setCssClass(V[W-2],V[W]);break;case 41:ie.addMembers(V[W-3],V[W-1]);break;case 42:ie.setCssClass(V[W-5],V[W-3]),ie.addMembers(V[W-5],V[W-1]);break;case 43:this.$=V[W],ie.addClass(V[W]);break;case 44:this.$=V[W-1],ie.addClass(V[W-1]),ie.setClassLabel(V[W-1],V[W]);break;case 45:ie.addAnnotation(V[W],V[W-2]);break;case 46:case 59:this.$=[V[W]];break;case 47:V[W].push(V[W-1]),this.$=V[W];break;case 48:break;case 49:ie.addMember(V[W-1],ie.cleanupLabel(V[W]));break;case 50:break;case 51:break;case 52:this.$={id1:V[W-2],id2:V[W],relation:V[W-1],relationTitle1:"none",relationTitle2:"none"};break;case 53:this.$={id1:V[W-3],id2:V[W],relation:V[W-1],relationTitle1:V[W-2],relationTitle2:"none"};break;case 54:this.$={id1:V[W-3],id2:V[W],relation:V[W-2],relationTitle1:"none",relationTitle2:V[W-1]};break;case 55:this.$={id1:V[W-4],id2:V[W],relation:V[W-2],relationTitle1:V[W-3],relationTitle2:V[W-1]};break;case 56:ie.addNote(V[W],V[W-1]);break;case 57:ie.addNote(V[W]);break;case 58:this.$=V[W-2],ie.defineClass(V[W-1],V[W]);break;case 60:this.$=V[W-2].concat([V[W]]);break;case 61:ie.setDirection("TB");break;case 62:ie.setDirection("BT");break;case 63:ie.setDirection("RL");break;case 64:ie.setDirection("LR");break;case 65:this.$={type1:V[W-2],type2:V[W],lineType:V[W-1]};break;case 66:this.$={type1:"none",type2:V[W],lineType:V[W-1]};break;case 67:this.$={type1:V[W-1],type2:"none",lineType:V[W]};break;case 68:this.$={type1:"none",type2:"none",lineType:V[W]};break;case 69:this.$=ie.relationType.AGGREGATION;break;case 70:this.$=ie.relationType.EXTENSION;break;case 71:this.$=ie.relationType.COMPOSITION;break;case 72:this.$=ie.relationType.DEPENDENCY;break;case 73:this.$=ie.relationType.LOLLIPOP;break;case 74:this.$=ie.lineType.LINE;break;case 75:this.$=ie.lineType.DOTTED_LINE;break;case 76:case 82:this.$=V[W-2],ie.setClickEvent(V[W-1],V[W]);break;case 77:case 83:this.$=V[W-3],ie.setClickEvent(V[W-2],V[W-1]),ie.setTooltip(V[W-2],V[W]);break;case 78:this.$=V[W-2],ie.setLink(V[W-1],V[W]);break;case 79:this.$=V[W-3],ie.setLink(V[W-2],V[W-1],V[W]);break;case 80:this.$=V[W-3],ie.setLink(V[W-2],V[W-1]),ie.setTooltip(V[W-2],V[W]);break;case 81:this.$=V[W-4],ie.setLink(V[W-3],V[W-2],V[W]),ie.setTooltip(V[W-3],V[W-1]);break;case 84:this.$=V[W-3],ie.setClickEvent(V[W-2],V[W-1],V[W]);break;case 85:this.$=V[W-4],ie.setClickEvent(V[W-3],V[W-2],V[W-1]),ie.setTooltip(V[W-3],V[W]);break;case 86:this.$=V[W-3],ie.setLink(V[W-2],V[W]);break;case 87:this.$=V[W-4],ie.setLink(V[W-3],V[W-1],V[W]);break;case 88:this.$=V[W-4],ie.setLink(V[W-3],V[W-1]),ie.setTooltip(V[W-3],V[W]);break;case 89:this.$=V[W-5],ie.setLink(V[W-4],V[W-2],V[W]),ie.setTooltip(V[W-4],V[W-1]);break;case 90:this.$=V[W-2],ie.setCssStyle(V[W-1],V[W]);break;case 91:ie.setCssClass(V[W-1],V[W]);break;case 92:this.$=[V[W]];break;case 93:V[W-2].push(V[W]),this.$=V[W-2];break;case 95:this.$=V[W-1]+V[W];break}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(O,[2,5],{8:[1,48]}),{8:[1,49]},t(R,[2,18],{22:[1,50]}),t(R,[2,20]),t(R,[2,21]),t(R,[2,22]),t(R,[2,23]),t(R,[2,24]),t(R,[2,25]),t(R,[2,26]),t(R,[2,27]),t(R,[2,28]),t(R,[2,29]),{34:[1,51]},{36:[1,52]},t(R,[2,32]),t(R,[2,48],{51:53,64:56,65:57,13:[1,54],22:[1,55],66:k,67:L,68:A,69:I,70:M,71:P,72:B}),{39:[1,65]},t(F,[2,39],{39:[1,67],44:[1,66]}),t(R,[2,50]),t(R,[2,51]),{16:68,58:p,84:E,99:_,101:C},{16:39,18:69,19:40,58:p,84:E,99:_,101:C,102:D},{16:39,18:70,19:40,58:p,84:E,99:_,101:C,102:D},{16:39,18:71,19:40,58:p,84:E,99:_,101:C,102:D},{58:[1,72]},{13:[1,73]},{16:39,18:74,19:40,58:p,84:E,99:_,101:C,102:D},{13:z,53:75},{56:77,58:[1,78]},t(R,[2,61]),t(R,[2,62]),t(R,[2,63]),t(R,[2,64]),t($,[2,12],{16:39,19:40,18:80,17:[1,79],20:[1,81],58:p,84:E,99:_,101:C,102:D}),t($,[2,14],{20:[1,82]}),{15:83,16:84,58:p,84:E,99:_,101:C},{16:39,18:85,19:40,58:p,84:E,99:_,101:C,102:D},t(U,[2,118]),t(U,[2,119]),t(U,[2,120]),t(U,[2,121]),t([1,8,9,12,13,20,22,39,41,44,66,67,68,69,70,71,72,77,79],[2,122]),t(O,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,18:21,38:22,43:23,16:39,19:40,5:86,33:e,35:r,37:n,42:i,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D}),{5:87,10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:T,80:S,81:w,84:E,99:_,101:C,102:D},t(R,[2,19]),t(R,[2,30]),t(R,[2,31]),{13:[1,89],16:39,18:88,19:40,58:p,84:E,99:_,101:C,102:D},{51:90,64:56,65:57,66:k,67:L,68:A,69:I,70:M,71:P,72:B},t(R,[2,49]),{65:91,71:P,72:B},t(K,[2,68],{64:92,66:k,67:L,68:A,69:I,70:M}),t(ee,[2,69]),t(ee,[2,70]),t(ee,[2,71]),t(ee,[2,72]),t(ee,[2,73]),t(Y,[2,74]),t(Y,[2,75]),{8:[1,94],24:95,40:93,43:23,46:a},{16:96,58:p,84:E,99:_,101:C},{45:97,49:ce},{48:[1,99]},{13:[1,100]},{13:[1,101]},{77:[1,102],79:[1,103]},{22:Z,57:104,58:ue,80:Q,82:105,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},{58:[1,116]},{13:z,53:117},t(R,[2,57]),t(R,[2,123]),{22:Z,57:118,58:ue,59:[1,119],80:Q,82:105,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},t(Se,[2,59]),{16:39,18:120,19:40,58:p,84:E,99:_,101:C,102:D},t($,[2,15]),t($,[2,16]),t($,[2,17]),{39:[2,35]},{15:122,16:84,17:[1,121],39:[2,9],58:p,84:E,99:_,101:C},t(se,[2,43],{11:123,12:[1,124]}),t(O,[2,7]),{9:[1,125]},t(ae,[2,52]),{16:39,18:126,19:40,58:p,84:E,99:_,101:C,102:D},{13:[1,128],16:39,18:127,19:40,58:p,84:E,99:_,101:C,102:D},t(K,[2,67],{64:129,66:k,67:L,68:A,69:I,70:M}),t(K,[2,66]),{41:[1,130]},{24:95,40:131,43:23,46:a},{8:[1,132],41:[2,36]},t(F,[2,40],{39:[1,133]}),{41:[1,134]},{41:[2,46],45:135,49:ce},{16:39,18:136,19:40,58:p,84:E,99:_,101:C,102:D},t(R,[2,76],{13:[1,137]}),t(R,[2,78],{13:[1,139],75:[1,138]}),t(R,[2,82],{13:[1,140],78:[1,141]}),{13:[1,142]},t(R,[2,90],{59:Oe}),t(ye,[2,92],{83:144,22:Z,58:ue,80:Q,84:j,85:ne,86:te,87:he,88:le,89:J}),t(Be,[2,94]),t(Be,[2,96]),t(Be,[2,97]),t(Be,[2,98]),t(Be,[2,99]),t(Be,[2,100]),t(Be,[2,101]),t(Be,[2,102]),t(Be,[2,103]),t(Be,[2,104]),t(R,[2,91]),t(R,[2,56]),t(R,[2,58],{59:Oe}),{58:[1,145]},t($,[2,13]),{15:146,16:84,58:p,84:E,99:_,101:C},{39:[2,11]},t(se,[2,44]),{13:[1,147]},{1:[2,4]},t(ae,[2,54]),t(ae,[2,53]),{16:39,18:148,19:40,58:p,84:E,99:_,101:C,102:D},t(K,[2,65]),t(R,[2,33]),{41:[1,149]},{24:95,40:150,41:[2,37],43:23,46:a},{45:151,49:ce},t(F,[2,41]),{41:[2,47]},t(R,[2,45]),t(R,[2,77]),t(R,[2,79]),t(R,[2,80],{75:[1,152]}),t(R,[2,83]),t(R,[2,84],{13:[1,153]}),t(R,[2,86],{13:[1,155],75:[1,154]}),{22:Z,58:ue,80:Q,82:156,83:106,84:j,85:ne,86:te,87:he,88:le,89:J},t(Be,[2,95]),t(Se,[2,60]),{39:[2,10]},{14:[1,157]},t(ae,[2,55]),t(R,[2,34]),{41:[2,38]},{41:[1,158]},t(R,[2,81]),t(R,[2,85]),t(R,[2,87]),t(R,[2,88],{75:[1,159]}),t(ye,[2,93],{83:144,22:Z,58:ue,80:Q,84:j,85:ne,86:te,87:he,88:le,89:J}),t(se,[2,8]),t(F,[2,42]),t(R,[2,89])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],83:[2,35],122:[2,11],125:[2,4],135:[2,47],146:[2,10],150:[2,38]},parseError:o(function(xe,q){if(q.recoverable)this.trace(xe);else{var de=new Error(xe);throw de.hash=q,de}},"parseError"),parse:o(function(xe){var q=this,de=[0],ie=[],oe=[null],V=[],Te=this.table,W="",pe=0,ve=0,Pe=0,_e=2,be=1,Ve=V.slice.call(arguments,1),De=Object.create(this.lexer),qe={yy:{}};for(var at in this.yy)Object.prototype.hasOwnProperty.call(this.yy,at)&&(qe.yy[at]=this.yy[at]);De.setInput(xe,qe.yy),qe.yy.lexer=De,qe.yy.parser=this,typeof De.yylloc>"u"&&(De.yylloc={});var Rt=De.yylloc;V.push(Rt);var st=De.options&&De.options.ranges;typeof qe.yy.parseError=="function"?this.parseError=qe.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ue(kt){de.length=de.length-2*kt,oe.length=oe.length-kt,V.length=V.length-kt}o(Ue,"popStack");function ct(){var kt;return kt=ie.pop()||De.lex()||be,typeof kt!="number"&&(kt instanceof Array&&(ie=kt,kt=ie.pop()),kt=q.symbols_[kt]||kt),kt}o(ct,"lex");for(var We,ot,Yt,Tt,Mt,bt,ut={},St,ft,vt,nt;;){if(Yt=de[de.length-1],this.defaultActions[Yt]?Tt=this.defaultActions[Yt]:((We===null||typeof We>"u")&&(We=ct()),Tt=Te[Yt]&&Te[Yt][We]),typeof Tt>"u"||!Tt.length||!Tt[0]){var pn="";nt=[];for(St in Te[Yt])this.terminals_[St]&&St>_e&&nt.push("'"+this.terminals_[St]+"'");De.showPosition?pn="Parse error on line "+(pe+1)+`: -`+De.showPosition()+` -Expecting `+nt.join(", ")+", got '"+(this.terminals_[We]||We)+"'":pn="Parse error on line "+(pe+1)+": Unexpected "+(We==be?"end of input":"'"+(this.terminals_[We]||We)+"'"),this.parseError(pn,{text:De.match,token:this.terminals_[We]||We,line:De.yylineno,loc:Rt,expected:nt})}if(Tt[0]instanceof Array&&Tt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Yt+", token: "+We);switch(Tt[0]){case 1:de.push(We),oe.push(De.yytext),V.push(De.yylloc),de.push(Tt[1]),We=null,ot?(We=ot,ot=null):(ve=De.yyleng,W=De.yytext,pe=De.yylineno,Rt=De.yylloc,Pe>0&&Pe--);break;case 2:if(ft=this.productions_[Tt[1]][1],ut.$=oe[oe.length-ft],ut._$={first_line:V[V.length-(ft||1)].first_line,last_line:V[V.length-1].last_line,first_column:V[V.length-(ft||1)].first_column,last_column:V[V.length-1].last_column},st&&(ut._$.range=[V[V.length-(ft||1)].range[0],V[V.length-1].range[1]]),bt=this.performAction.apply(ut,[W,ve,pe,qe.yy,Tt[1],oe,V].concat(Ve)),typeof bt<"u")return bt;ft&&(de=de.slice(0,-1*ft*2),oe=oe.slice(0,-1*ft),V=V.slice(0,-1*ft)),de.push(this.productions_[Tt[1]][0]),oe.push(ut.$),V.push(ut._$),vt=Te[de[de.length-2]][de[de.length-1]],de.push(vt);break;case 3:return!0}}return!0},"parse")},ze=function(){var Ie={EOF:1,parseError:o(function(q,de){if(this.yy.parser)this.yy.parser.parseError(q,de);else throw new Error(q)},"parseError"),setInput:o(function(xe,q){return this.yy=q||this.yy||{},this._input=xe,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var xe=this._input[0];this.yytext+=xe,this.yyleng++,this.offset++,this.match+=xe,this.matched+=xe;var q=xe.match(/(?:\r\n?|\n).*/g);return q?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),xe},"input"),unput:o(function(xe){var q=xe.length,de=xe.split(/(?:\r\n?|\n)/g);this._input=xe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-q),this.offset-=q;var ie=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),de.length-1&&(this.yylineno-=de.length-1);var oe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:de?(de.length===ie.length?this.yylloc.first_column:0)+ie[ie.length-de.length].length-de[0].length:this.yylloc.first_column-q},this.options.ranges&&(this.yylloc.range=[oe[0],oe[0]+this.yyleng-q]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(xe){this.unput(this.match.slice(xe))},"less"),pastInput:o(function(){var xe=this.matched.substr(0,this.matched.length-this.match.length);return(xe.length>20?"...":"")+xe.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var xe=this.match;return xe.length<20&&(xe+=this._input.substr(0,20-xe.length)),(xe.substr(0,20)+(xe.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var xe=this.pastInput(),q=new Array(xe.length+1).join("-");return xe+this.upcomingInput()+` -`+q+"^"},"showPosition"),test_match:o(function(xe,q){var de,ie,oe;if(this.options.backtrack_lexer&&(oe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(oe.yylloc.range=this.yylloc.range.slice(0))),ie=xe[0].match(/(?:\r\n?|\n).*/g),ie&&(this.yylineno+=ie.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:ie?ie[ie.length-1].length-ie[ie.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+xe[0].length},this.yytext+=xe[0],this.match+=xe[0],this.matches=xe,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(xe[0].length),this.matched+=xe[0],de=this.performAction.call(this,this.yy,this,q,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),de)return de;if(this._backtrack){for(var V in oe)this[V]=oe[V];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var xe,q,de,ie;this._more||(this.yytext="",this.match="");for(var oe=this._currentRules(),V=0;Vq[0].length)){if(q=de,ie=V,this.options.backtrack_lexer){if(xe=this.test_match(de,oe[V]),xe!==!1)return xe;if(this._backtrack){q=!1;continue}else return!1}else if(!this.options.flex)break}return q?(xe=this.test_match(q,oe[ie]),xe!==!1?xe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var q=this.next();return q||this.lex()},"lex"),begin:o(function(q){this.conditionStack.push(q)},"begin"),popState:o(function(){var q=this.conditionStack.length-1;return q>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(q){return q=this.conditionStack.length-1-Math.abs(q||0),q>=0?this.conditionStack[q]:"INITIAL"},"topState"),pushState:o(function(q){this.begin(q)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(q,de,ie,oe){var V=oe;switch(ie){case 0:return 60;case 1:return 61;case 2:return 62;case 3:return 63;case 4:break;case 5:break;case 6:return this.begin("acc_title"),33;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),35;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 8;case 14:break;case 15:return 7;case 16:return 7;case 17:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 19:this.popState();break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 77;case 22:this.popState();break;case 23:return 78;case 24:this.popState();break;case 25:return"STR";case 26:this.begin("string");break;case 27:return 80;case 28:return 55;case 29:return this.begin("namespace"),42;break;case 30:return this.popState(),8;break;case 31:break;case 32:return this.begin("namespace-body"),39;break;case 33:return this.popState(),41;break;case 34:return"EOF_IN_STRUCT";case 35:return 8;case 36:break;case 37:return"EDGE_STATE";case 38:return this.begin("class"),46;break;case 39:return this.popState(),8;break;case 40:break;case 41:return this.popState(),this.popState(),41;break;case 42:return this.begin("class-body"),39;break;case 43:return this.popState(),41;break;case 44:return"EOF_IN_STRUCT";case 45:return"EDGE_STATE";case 46:return"OPEN_IN_STRUCT";case 47:break;case 48:return"MEMBER";case 49:return 81;case 50:return 73;case 51:return 74;case 52:return 76;case 53:return 52;case 54:return 54;case 55:return 47;case 56:return 48;case 57:return 79;case 58:this.popState();break;case 59:return"GENERICTYPE";case 60:this.begin("generic");break;case 61:this.popState();break;case 62:return"BQUOTE_STR";case 63:this.begin("bqstring");break;case 64:return 75;case 65:return 75;case 66:return 75;case 67:return 75;case 68:return 67;case 69:return 67;case 70:return 69;case 71:return 69;case 72:return 68;case 73:return 66;case 74:return 70;case 75:return 71;case 76:return 72;case 77:return 22;case 78:return 44;case 79:return 99;case 80:return 17;case 81:return"PLUS";case 82:return 85;case 83:return 59;case 84:return 88;case 85:return 88;case 86:return 89;case 87:return"EQUALS";case 88:return"EQUALS";case 89:return 58;case 90:return 12;case 91:return 14;case 92:return"PUNCTUATION";case 93:return 84;case 94:return 101;case 95:return 87;case 96:return 87;case 97:return 9}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:classDef\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,33,34,35,36,37,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},namespace:{rules:[26,29,30,31,32,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},"class-body":{rules:[26,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},class:{rules:[26,39,40,41,42,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr:{rules:[9,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_title:{rules:[7,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_args:{rules:[22,23,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_name:{rules:[19,20,21,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},href:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},struct:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},generic:{rules:[26,49,50,51,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},bqstring:{rules:[26,49,50,51,52,53,54,55,56,57,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},string:{rules:[24,25,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,29,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}};return Ie}();He.lexer=ze;function Le(){this.yy={}}return o(Le,"Parser"),Le.prototype=He,He.Parser=Le,new Le}();bP.parser=bP;jS=bP});var jde,Ib,Kde=N(()=>{"use strict";Gt();pr();jde=["#","+","~","-",""],Ib=class{static{o(this,"ClassMember")}constructor(e,r){this.memberType=r,this.visibility="",this.classifier="",this.text="";let n=wr(e,me());this.parseMember(n)}getDisplayDetails(){let e=this.visibility+ic(this.id);this.memberType==="method"&&(e+=`(${ic(this.parameters.trim())})`,this.returnType&&(e+=" : "+ic(this.returnType))),e=e.trim();let r=this.parseClassifier();return{displayText:e,cssStyle:r}}parseMember(e){let r="";if(this.memberType==="method"){let a=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/.exec(e);if(a){let s=a[1]?a[1].trim():"";if(jde.includes(s)&&(this.visibility=s),this.id=a[2],this.parameters=a[3]?a[3].trim():"",r=a[4]?a[4].trim():"",this.returnType=a[5]?a[5].trim():"",r===""){let l=this.returnType.substring(this.returnType.length-1);/[$*]/.exec(l)&&(r=l,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{let i=e.length,a=e.substring(0,1),s=e.substring(i-1);jde.includes(a)&&(this.visibility=a),/[$*]/.exec(s)&&(r=s),this.id=e.substring(this.visibility===""?0:1,r===""?i:i-1)}this.classifier=r,this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim();let n=`${this.visibility?"\\"+this.visibility:""}${ic(this.id)}${this.memberType==="method"?`(${ic(this.parameters)})${this.returnType?" : "+ic(this.returnType):""}`:""}`;this.text=n.replaceAll("<","<").replaceAll(">",">"),this.text.startsWith("\\<")&&(this.text=this.text.replace("\\<","~"))}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}});var KS,Qde,zp,P1,wP=N(()=>{"use strict";fr();yt();Gt();pr();er();ci();Kde();KS="classId-",Qde=0,zp=o(t=>Ze.sanitizeText(t,me()),"sanitizeText"),P1=class{constructor(){this.relations=[];this.classes=new Map;this.styleClasses=new Map;this.notes=[];this.interfaces=[];this.namespaces=new Map;this.namespaceCounter=0;this.functions=[];this.lineType={LINE:0,DOTTED_LINE:1};this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4};this.setupToolTips=o(e=>{let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=this.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.top-14+document.body.scrollTop+"px"),r.html(r.html().replace(/<br\/>/g,"
    ")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})},"setupToolTips");this.direction="TB";this.setAccTitle=Ar;this.getAccTitle=Dr;this.setAccDescription=Lr;this.getAccDescription=Rr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getConfig=o(()=>me().class,"getConfig");this.functions.push(this.setupToolTips.bind(this)),this.clear(),this.addRelation=this.addRelation.bind(this),this.addClassesToNamespace=this.addClassesToNamespace.bind(this),this.addNamespace=this.addNamespace.bind(this),this.setCssClass=this.setCssClass.bind(this),this.addMembers=this.addMembers.bind(this),this.addClass=this.addClass.bind(this),this.setClassLabel=this.setClassLabel.bind(this),this.addAnnotation=this.addAnnotation.bind(this),this.addMember=this.addMember.bind(this),this.cleanupLabel=this.cleanupLabel.bind(this),this.addNote=this.addNote.bind(this),this.defineClass=this.defineClass.bind(this),this.setDirection=this.setDirection.bind(this),this.setLink=this.setLink.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.clear=this.clear.bind(this),this.setTooltip=this.setTooltip.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setCssStyle=this.setCssStyle.bind(this)}static{o(this,"ClassDB")}splitClassNameAndType(e){let r=Ze.sanitizeText(e,me()),n="",i=r;if(r.indexOf("~")>0){let a=r.split("~");i=zp(a[0]),n=zp(a[1])}return{className:i,type:n}}setClassLabel(e,r){let n=Ze.sanitizeText(e,me());r&&(r=zp(r));let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).label=r,this.classes.get(i).text=`${r}${this.classes.get(i).type?`<${this.classes.get(i).type}>`:""}`}addClass(e){let r=Ze.sanitizeText(e,me()),{className:n,type:i}=this.splitClassNameAndType(r);if(this.classes.has(n))return;let a=Ze.sanitizeText(n,me());this.classes.set(a,{id:a,type:i,label:a,text:`${a}${i?`<${i}>`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:KS+a+"-"+Qde}),Qde++}addInterface(e,r){let n={id:`interface${this.interfaces.length}`,label:e,classId:r};this.interfaces.push(n)}lookUpDomId(e){let r=Ze.sanitizeText(e,me());if(this.classes.has(r))return this.classes.get(r).domId;throw new Error("Class not found: "+r)}clear(){this.relations=[],this.classes=new Map,this.notes=[],this.interfaces=[],this.functions=[],this.functions.push(this.setupToolTips.bind(this)),this.namespaces=new Map,this.namespaceCounter=0,this.direction="TB",kr()}getClass(e){return this.classes.get(e)}getClasses(){return this.classes}getRelations(){return this.relations}getNotes(){return this.notes}addRelation(e){X.debug("Adding relation: "+JSON.stringify(e));let r=[this.relationType.LOLLIPOP,this.relationType.AGGREGATION,this.relationType.COMPOSITION,this.relationType.DEPENDENCY,this.relationType.EXTENSION];e.relation.type1===this.relationType.LOLLIPOP&&!r.includes(e.relation.type2)?(this.addClass(e.id2),this.addInterface(e.id1,e.id2),e.id1=`interface${this.interfaces.length-1}`):e.relation.type2===this.relationType.LOLLIPOP&&!r.includes(e.relation.type1)?(this.addClass(e.id1),this.addInterface(e.id2,e.id1),e.id2=`interface${this.interfaces.length-1}`):(this.addClass(e.id1),this.addClass(e.id2)),e.id1=this.splitClassNameAndType(e.id1).className,e.id2=this.splitClassNameAndType(e.id2).className,e.relationTitle1=Ze.sanitizeText(e.relationTitle1.trim(),me()),e.relationTitle2=Ze.sanitizeText(e.relationTitle2.trim(),me()),this.relations.push(e)}addAnnotation(e,r){let n=this.splitClassNameAndType(e).className;this.classes.get(n).annotations.push(r)}addMember(e,r){this.addClass(e);let n=this.splitClassNameAndType(e).className,i=this.classes.get(n);if(typeof r=="string"){let a=r.trim();a.startsWith("<<")&&a.endsWith(">>")?i.annotations.push(zp(a.substring(2,a.length-2))):a.indexOf(")")>0?i.methods.push(new Ib(a,"method")):a&&i.members.push(new Ib(a,"attribute"))}}addMembers(e,r){Array.isArray(r)&&(r.reverse(),r.forEach(n=>this.addMember(e,n)))}addNote(e,r){let n={id:`note${this.notes.length}`,class:r,text:e};this.notes.push(n)}cleanupLabel(e){return e.startsWith(":")&&(e=e.substring(1)),zp(e.trim())}setCssClass(e,r){e.split(",").forEach(n=>{let i=n;/\d/.exec(n[0])&&(i=KS+i);let a=this.classes.get(i);a&&(a.cssClasses+=" "+r)})}defineClass(e,r){for(let n of e){let i=this.styleClasses.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.styleClasses.set(n,i)),r&&r.forEach(a=>{if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.classes.forEach(a=>{a.cssClasses.includes(n)&&a.styles.push(...r.flatMap(s=>s.split(",")))})}}setTooltip(e,r){e.split(",").forEach(n=>{r!==void 0&&(this.classes.get(n).tooltip=zp(r))})}getTooltip(e,r){return r&&this.namespaces.has(r)?this.namespaces.get(r).classes.get(e).tooltip:this.classes.get(e).tooltip}setLink(e,r,n){let i=me();e.split(",").forEach(a=>{let s=a;/\d/.exec(a[0])&&(s=KS+s);let l=this.classes.get(s);l&&(l.link=Vt.formatUrl(r,i),i.securityLevel==="sandbox"?l.linkTarget="_top":typeof n=="string"?l.linkTarget=zp(n):l.linkTarget="_blank")}),this.setCssClass(e,"clickable")}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFunc(i,r,n),this.classes.get(i).haveCallback=!0}),this.setCssClass(e,"clickable")}setClickFunc(e,r,n){let i=Ze.sanitizeText(e,me());if(me().securityLevel!=="loose"||r===void 0)return;let s=i;if(this.classes.has(s)){let l=this.lookUpDomId(s),u=[];if(typeof n=="string"){u=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let h=0;h{let h=document.querySelector(`[id="${l}"]`);h!==null&&h.addEventListener("click",()=>{Vt.runFunc(r,...u)},!1)})}}bindFunctions(e){this.functions.forEach(r=>{r(e)})}getDirection(){return this.direction}setDirection(e){this.direction=e}addNamespace(e){this.namespaces.has(e)||(this.namespaces.set(e,{id:e,classes:new Map,children:{},domId:KS+e+"-"+this.namespaceCounter}),this.namespaceCounter++)}getNamespace(e){return this.namespaces.get(e)}getNamespaces(){return this.namespaces}addClassesToNamespace(e,r){if(this.namespaces.has(e))for(let n of r){let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).parent=e,this.namespaces.get(e).classes.set(i,this.classes.get(i))}}setCssStyle(e,r){let n=this.classes.get(e);if(!(!r||!n))for(let i of r)i.includes(",")?n.styles.push(...i.split(",")):n.styles.push(i)}getArrowMarker(e){let r;switch(e){case 0:r="aggregation";break;case 1:r="extension";break;case 2:r="composition";break;case 3:r="dependency";break;case 4:r="lollipop";break;default:r="none"}return r}getData(){let e=[],r=[],n=me();for(let a of this.namespaces.keys()){let s=this.namespaces.get(a);if(s){let l={id:s.id,label:s.id,isGroup:!0,padding:n.class.padding??16,shape:"rect",cssStyles:["fill: none","stroke: black"],look:n.look};e.push(l)}}for(let a of this.classes.keys()){let s=this.classes.get(a);if(s){let l=s;l.parentId=s.parent,l.look=n.look,e.push(l)}}let i=0;for(let a of this.notes){i++;let s={id:a.id,label:a.text,isGroup:!1,shape:"note",padding:n.class.padding??6,cssStyles:["text-align: left","white-space: nowrap",`fill: ${n.themeVariables.noteBkgColor}`,`stroke: ${n.themeVariables.noteBorderColor}`],look:n.look};e.push(s);let l=this.classes.get(a.class)?.id??"";if(l){let u={id:`edgeNote${i}`,start:a.id,end:l,type:"normal",thickness:"normal",classes:"relation",arrowTypeStart:"none",arrowTypeEnd:"none",arrowheadStyle:"",labelStyle:[""],style:["fill: none"],pattern:"dotted",look:n.look};r.push(u)}}for(let a of this.interfaces){let s={id:a.id,label:a.label,isGroup:!1,shape:"rect",cssStyles:["opacity: 0;"],look:n.look};e.push(s)}i=0;for(let a of this.relations){i++;let s={id:Wh(a.id1,a.id2,{prefix:"id",counter:i}),start:a.id1,end:a.id2,type:"normal",label:a.title,labelpos:"c",thickness:"normal",classes:"relation",arrowTypeStart:this.getArrowMarker(a.relation.type1),arrowTypeEnd:this.getArrowMarker(a.relation.type2),startLabelRight:a.relationTitle1==="none"?"":a.relationTitle1,endLabelLeft:a.relationTitle2==="none"?"":a.relationTitle2,arrowheadStyle:"",labelStyle:["display: inline-block"],style:a.style||"",pattern:a.relation.lineType==1?"dashed":"solid",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:this.getDirection()}}}});var kHe,QS,kP=N(()=>{"use strict";Xm();kHe=o(t=>`g.classGroup text { - fill: ${t.nodeBorder||t.classText}; - stroke: none; - font-family: ${t.fontFamily}; - font-size: 10px; - - .title { - font-weight: bolder; - } - -} - -.nodeLabel, .edgeLabel { - color: ${t.classText}; -} -.edgeLabel .label rect { - fill: ${t.mainBkg}; -} -.label text { - fill: ${t.classText}; -} - -.labelBkg { - background: ${t.mainBkg}; -} -.edgeLabel .label span { - background: ${t.mainBkg}; -} - -.classTitle { - font-weight: bolder; -} -.node rect, - .node circle, - .node ellipse, - .node polygon, - .node path { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - stroke-width: 1px; - } - - -.divider { - stroke: ${t.nodeBorder}; - stroke-width: 1; -} - -g.clickable { - cursor: pointer; -} - -g.classGroup rect { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; -} - -g.classGroup line { - stroke: ${t.nodeBorder}; - stroke-width: 1; -} - -.classLabel .box { - stroke: none; - stroke-width: 0; - fill: ${t.mainBkg}; - opacity: 0.5; -} - -.classLabel .label { - fill: ${t.nodeBorder}; - font-size: 10px; -} - -.relation { - stroke: ${t.lineColor}; - stroke-width: 1; - fill: none; -} - -.dashed-line{ - stroke-dasharray: 3; -} - -.dotted-line{ - stroke-dasharray: 1 2; -} - -#compositionStart, .composition { - fill: ${t.lineColor} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#compositionEnd, .composition { - fill: ${t.lineColor} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#dependencyStart, .dependency { - fill: ${t.lineColor} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#dependencyStart, .dependency { - fill: ${t.lineColor} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#extensionStart, .extension { - fill: transparent !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#extensionEnd, .extension { - fill: transparent !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#aggregationStart, .aggregation { - fill: transparent !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#aggregationEnd, .aggregation { - fill: transparent !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#lollipopStart, .lollipop { - fill: ${t.mainBkg} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -#lollipopEnd, .lollipop { - fill: ${t.mainBkg} !important; - stroke: ${t.lineColor} !important; - stroke-width: 1; -} - -.edgeTerminals { - font-size: 11px; - line-height: initial; -} - -.classTitleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.textColor}; -} - ${Nc()} -`,"getStyles"),QS=kHe});var EHe,SHe,CHe,ZS,EP=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();EHe=o((t,e="TB")=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),SHe=o(function(t,e){return e.db.getClasses()},"getClasses"),CHe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing class diagram (v3)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=uf(s),l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["aggregation","extension","composition","dependency","lollipop"],l.diagramId=e,await Rc(l,u);let h=8;Vt.insertTitle(u,"classDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,"classDiagram",a?.useMaxWidth??!0)},"draw"),ZS={getClasses:SHe,draw:CHe,getDir:EHe}});var Zde={};ur(Zde,{diagram:()=>AHe});var AHe,Jde=N(()=>{"use strict";TP();wP();kP();EP();AHe={parser:jS,get db(){return new P1},renderer:ZS,styles:QS,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var rpe={};ur(rpe,{diagram:()=>RHe});var RHe,npe=N(()=>{"use strict";TP();wP();kP();EP();RHe={parser:jS,get db(){return new P1},renderer:ZS,styles:QS,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var SP,JS,CP=N(()=>{"use strict";SP=function(){var t=o(function(F,z,$,U){for($=$||{},U=F.length;U--;$[F[U]]=z);return $},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,16],u=[1,17],h=[1,18],f=[1,19],d=[1,33],p=[1,20],m=[1,21],g=[1,22],y=[1,23],v=[1,24],x=[1,26],b=[1,27],T=[1,28],S=[1,29],w=[1,30],E=[1,31],_=[1,32],C=[1,35],D=[1,36],O=[1,37],R=[1,38],k=[1,34],L=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],A=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,39,40,41,45,48,51,52,53,54,57],I=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],M={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"-->":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,CLICK:38,STRING:39,HREF:40,classDef:41,CLASSDEF_ID:42,CLASSDEF_STYLEOPTS:43,DEFAULT:44,style:45,STYLE_IDS:46,STYLEDEF_STYLEOPTS:47,class:48,CLASSENTITY_IDS:49,STYLECLASS:50,direction_tb:51,direction_bt:52,direction_rl:53,direction_lr:54,eol:55,";":56,EDGE_STATE:57,STYLE_SEPARATOR:58,left_of:59,right_of:60,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"-->",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"CLICK",39:"STRING",40:"HREF",41:"classDef",42:"CLASSDEF_ID",43:"CLASSDEF_STYLEOPTS",44:"DEFAULT",45:"style",46:"STYLE_IDS",47:"STYLEDEF_STYLEOPTS",48:"class",49:"CLASSENTITY_IDS",50:"STYLECLASS",51:"direction_tb",52:"direction_bt",53:"direction_rl",54:"direction_lr",56:";",57:"EDGE_STATE",58:"STYLE_SEPARATOR",59:"left_of",60:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[9,5],[9,5],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[55,1],[55,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:o(function(z,$,U,K,ee,Y,ce){var Z=Y.length-1;switch(ee){case 3:return K.setRootDoc(Y[Z]),Y[Z];break;case 4:this.$=[];break;case 5:Y[Z]!="nl"&&(Y[Z-1].push(Y[Z]),this.$=Y[Z-1]);break;case 6:case 7:this.$=Y[Z];break;case 8:this.$="nl";break;case 12:this.$=Y[Z];break;case 13:let ne=Y[Z-1];ne.description=K.trimColon(Y[Z]),this.$=ne;break;case 14:this.$={stmt:"relation",state1:Y[Z-2],state2:Y[Z]};break;case 15:let te=K.trimColon(Y[Z]);this.$={stmt:"relation",state1:Y[Z-3],state2:Y[Z-1],description:te};break;case 19:this.$={stmt:"state",id:Y[Z-3],type:"default",description:"",doc:Y[Z-1]};break;case 20:var ue=Y[Z],Q=Y[Z-2].trim();if(Y[Z].match(":")){var j=Y[Z].split(":");ue=j[0],Q=[Q,j[1]]}this.$={stmt:"state",id:ue,type:"default",description:Q};break;case 21:this.$={stmt:"state",id:Y[Z-3],type:"default",description:Y[Z-5],doc:Y[Z-1]};break;case 22:this.$={stmt:"state",id:Y[Z],type:"fork"};break;case 23:this.$={stmt:"state",id:Y[Z],type:"join"};break;case 24:this.$={stmt:"state",id:Y[Z],type:"choice"};break;case 25:this.$={stmt:"state",id:K.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:Y[Z-1].trim(),note:{position:Y[Z-2].trim(),text:Y[Z].trim()}};break;case 29:this.$=Y[Z].trim(),K.setAccTitle(this.$);break;case 30:case 31:this.$=Y[Z].trim(),K.setAccDescription(this.$);break;case 32:this.$={stmt:"click",id:Y[Z-3],url:Y[Z-2],tooltip:Y[Z-1]};break;case 33:this.$={stmt:"click",id:Y[Z-3],url:Y[Z-1],tooltip:""};break;case 34:case 35:this.$={stmt:"classDef",id:Y[Z-1].trim(),classes:Y[Z].trim()};break;case 36:this.$={stmt:"style",id:Y[Z-1].trim(),styleClass:Y[Z].trim()};break;case 37:this.$={stmt:"applyClass",id:Y[Z-1].trim(),styleClass:Y[Z].trim()};break;case 38:K.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:K.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:K.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:K.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:Y[Z].trim(),type:"default",description:""};break;case 46:this.$={stmt:"state",id:Y[Z-2].trim(),classes:[Y[Z].trim()],type:"default",description:""};break;case 47:this.$={stmt:"state",id:Y[Z-2].trim(),classes:[Y[Z].trim()],type:"default",description:""};break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,5]),{9:39,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,7]),t(L,[2,8]),t(L,[2,9]),t(L,[2,10]),t(L,[2,11]),t(L,[2,12],{14:[1,40],15:[1,41]}),t(L,[2,16]),{18:[1,42]},t(L,[2,18],{20:[1,43]}),{23:[1,44]},t(L,[2,22]),t(L,[2,23]),t(L,[2,24]),t(L,[2,25]),{30:45,31:[1,46],59:[1,47],60:[1,48]},t(L,[2,28]),{34:[1,49]},{36:[1,50]},t(L,[2,31]),{13:51,24:d,57:k},{42:[1,52],44:[1,53]},{46:[1,54]},{49:[1,55]},t(A,[2,44],{58:[1,56]}),t(A,[2,45],{58:[1,57]}),t(L,[2,38]),t(L,[2,39]),t(L,[2,40]),t(L,[2,41]),t(L,[2,6]),t(L,[2,13]),{13:58,24:d,57:k},t(L,[2,17]),t(I,i,{7:59}),{24:[1,60]},{24:[1,61]},{23:[1,62]},{24:[2,48]},{24:[2,49]},t(L,[2,29]),t(L,[2,30]),{39:[1,63],40:[1,64]},{43:[1,65]},{43:[1,66]},{47:[1,67]},{50:[1,68]},{24:[1,69]},{24:[1,70]},t(L,[2,14],{14:[1,71]}),{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,72],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,20],{20:[1,73]}),{31:[1,74]},{24:[1,75]},{39:[1,76]},{39:[1,77]},t(L,[2,34]),t(L,[2,35]),t(L,[2,36]),t(L,[2,37]),t(A,[2,46]),t(A,[2,47]),t(L,[2,15]),t(L,[2,19]),t(I,i,{7:78}),t(L,[2,26]),t(L,[2,27]),{5:[1,79]},{5:[1,80]},{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,81],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:T,38:S,41:w,45:E,48:_,51:C,52:D,53:O,54:R,57:k},t(L,[2,32]),t(L,[2,33]),t(L,[2,21])],defaultActions:{5:[2,1],6:[2,2],47:[2,48],48:[2,49]},parseError:o(function(z,$){if($.recoverable)this.trace(z);else{var U=new Error(z);throw U.hash=$,U}},"parseError"),parse:o(function(z){var $=this,U=[0],K=[],ee=[null],Y=[],ce=this.table,Z="",ue=0,Q=0,j=0,ne=2,te=1,he=Y.slice.call(arguments,1),le=Object.create(this.lexer),J={yy:{}};for(var Se in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Se)&&(J.yy[Se]=this.yy[Se]);le.setInput(z,J.yy),J.yy.lexer=le,J.yy.parser=this,typeof le.yylloc>"u"&&(le.yylloc={});var se=le.yylloc;Y.push(se);var ae=le.options&&le.options.ranges;typeof J.yy.parseError=="function"?this.parseError=J.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Oe(W){U.length=U.length-2*W,ee.length=ee.length-W,Y.length=Y.length-W}o(Oe,"popStack");function ye(){var W;return W=K.pop()||le.lex()||te,typeof W!="number"&&(W instanceof Array&&(K=W,W=K.pop()),W=$.symbols_[W]||W),W}o(ye,"lex");for(var Be,He,ze,Le,Ie,xe,q={},de,ie,oe,V;;){if(ze=U[U.length-1],this.defaultActions[ze]?Le=this.defaultActions[ze]:((Be===null||typeof Be>"u")&&(Be=ye()),Le=ce[ze]&&ce[ze][Be]),typeof Le>"u"||!Le.length||!Le[0]){var Te="";V=[];for(de in ce[ze])this.terminals_[de]&&de>ne&&V.push("'"+this.terminals_[de]+"'");le.showPosition?Te="Parse error on line "+(ue+1)+`: -`+le.showPosition()+` -Expecting `+V.join(", ")+", got '"+(this.terminals_[Be]||Be)+"'":Te="Parse error on line "+(ue+1)+": Unexpected "+(Be==te?"end of input":"'"+(this.terminals_[Be]||Be)+"'"),this.parseError(Te,{text:le.match,token:this.terminals_[Be]||Be,line:le.yylineno,loc:se,expected:V})}if(Le[0]instanceof Array&&Le.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ze+", token: "+Be);switch(Le[0]){case 1:U.push(Be),ee.push(le.yytext),Y.push(le.yylloc),U.push(Le[1]),Be=null,He?(Be=He,He=null):(Q=le.yyleng,Z=le.yytext,ue=le.yylineno,se=le.yylloc,j>0&&j--);break;case 2:if(ie=this.productions_[Le[1]][1],q.$=ee[ee.length-ie],q._$={first_line:Y[Y.length-(ie||1)].first_line,last_line:Y[Y.length-1].last_line,first_column:Y[Y.length-(ie||1)].first_column,last_column:Y[Y.length-1].last_column},ae&&(q._$.range=[Y[Y.length-(ie||1)].range[0],Y[Y.length-1].range[1]]),xe=this.performAction.apply(q,[Z,Q,ue,J.yy,Le[1],ee,Y].concat(he)),typeof xe<"u")return xe;ie&&(U=U.slice(0,-1*ie*2),ee=ee.slice(0,-1*ie),Y=Y.slice(0,-1*ie)),U.push(this.productions_[Le[1]][0]),ee.push(q.$),Y.push(q._$),oe=ce[U[U.length-2]][U[U.length-1]],U.push(oe);break;case 3:return!0}}return!0},"parse")},P=function(){var F={EOF:1,parseError:o(function($,U){if(this.yy.parser)this.yy.parser.parseError($,U);else throw new Error($)},"parseError"),setInput:o(function(z,$){return this.yy=$||this.yy||{},this._input=z,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var z=this._input[0];this.yytext+=z,this.yyleng++,this.offset++,this.match+=z,this.matched+=z;var $=z.match(/(?:\r\n?|\n).*/g);return $?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),z},"input"),unput:o(function(z){var $=z.length,U=z.split(/(?:\r\n?|\n)/g);this._input=z+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-$),this.offset-=$;var K=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),U.length-1&&(this.yylineno-=U.length-1);var ee=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:U?(U.length===K.length?this.yylloc.first_column:0)+K[K.length-U.length].length-U[0].length:this.yylloc.first_column-$},this.options.ranges&&(this.yylloc.range=[ee[0],ee[0]+this.yyleng-$]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(z){this.unput(this.match.slice(z))},"less"),pastInput:o(function(){var z=this.matched.substr(0,this.matched.length-this.match.length);return(z.length>20?"...":"")+z.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var z=this.match;return z.length<20&&(z+=this._input.substr(0,20-z.length)),(z.substr(0,20)+(z.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var z=this.pastInput(),$=new Array(z.length+1).join("-");return z+this.upcomingInput()+` -`+$+"^"},"showPosition"),test_match:o(function(z,$){var U,K,ee;if(this.options.backtrack_lexer&&(ee={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(ee.yylloc.range=this.yylloc.range.slice(0))),K=z[0].match(/(?:\r\n?|\n).*/g),K&&(this.yylineno+=K.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:K?K[K.length-1].length-K[K.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+z[0].length},this.yytext+=z[0],this.match+=z[0],this.matches=z,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(z[0].length),this.matched+=z[0],U=this.performAction.call(this,this.yy,this,$,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),U)return U;if(this._backtrack){for(var Y in ee)this[Y]=ee[Y];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var z,$,U,K;this._more||(this.yytext="",this.match="");for(var ee=this._currentRules(),Y=0;Y$[0].length)){if($=U,K=Y,this.options.backtrack_lexer){if(z=this.test_match(U,ee[Y]),z!==!1)return z;if(this._backtrack){$=!1;continue}else return!1}else if(!this.options.flex)break}return $?(z=this.test_match($,ee[K]),z!==!1?z:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var $=this.next();return $||this.lex()},"lex"),begin:o(function($){this.conditionStack.push($)},"begin"),popState:o(function(){var $=this.conditionStack.length-1;return $>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function($){return $=this.conditionStack.length-1-Math.abs($||0),$>=0?this.conditionStack[$]:"INITIAL"},"topState"),pushState:o(function($){this.begin($)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function($,U,K,ee){var Y=ee;switch(K){case 0:return 38;case 1:return 40;case 2:return 39;case 3:return 44;case 4:return 51;case 5:return 52;case 6:return 53;case 7:return 54;case 8:break;case 9:break;case 10:return 5;case 11:break;case 12:break;case 13:break;case 14:break;case 15:return this.pushState("SCALE"),17;break;case 16:return 18;case 17:this.popState();break;case 18:return this.begin("acc_title"),33;break;case 19:return this.popState(),"acc_title_value";break;case 20:return this.begin("acc_descr"),35;break;case 21:return this.popState(),"acc_descr_value";break;case 22:this.begin("acc_descr_multiline");break;case 23:this.popState();break;case 24:return"acc_descr_multiline_value";case 25:return this.pushState("CLASSDEF"),41;break;case 26:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 27:return this.popState(),this.pushState("CLASSDEFID"),42;break;case 28:return this.popState(),43;break;case 29:return this.pushState("CLASS"),48;break;case 30:return this.popState(),this.pushState("CLASS_STYLE"),49;break;case 31:return this.popState(),50;break;case 32:return this.pushState("STYLE"),45;break;case 33:return this.popState(),this.pushState("STYLEDEF_STYLES"),46;break;case 34:return this.popState(),47;break;case 35:return this.pushState("SCALE"),17;break;case 36:return 18;case 37:this.popState();break;case 38:this.pushState("STATE");break;case 39:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),25;break;case 40:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),26;break;case 41:return this.popState(),U.yytext=U.yytext.slice(0,-10).trim(),27;break;case 42:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),25;break;case 43:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),26;break;case 44:return this.popState(),U.yytext=U.yytext.slice(0,-10).trim(),27;break;case 45:return 51;case 46:return 52;case 47:return 53;case 48:return 54;case 49:this.pushState("STATE_STRING");break;case 50:return this.pushState("STATE_ID"),"AS";break;case 51:return this.popState(),"ID";break;case 52:this.popState();break;case 53:return"STATE_DESCR";case 54:return 19;case 55:this.popState();break;case 56:return this.popState(),this.pushState("struct"),20;break;case 57:break;case 58:return this.popState(),21;break;case 59:break;case 60:return this.begin("NOTE"),29;break;case 61:return this.popState(),this.pushState("NOTE_ID"),59;break;case 62:return this.popState(),this.pushState("NOTE_ID"),60;break;case 63:this.popState(),this.pushState("FLOATING_NOTE");break;case 64:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";break;case 65:break;case 66:return"NOTE_TEXT";case 67:return this.popState(),"ID";break;case 68:return this.popState(),this.pushState("NOTE_TEXT"),24;break;case 69:return this.popState(),U.yytext=U.yytext.substr(2).trim(),31;break;case 70:return this.popState(),U.yytext=U.yytext.slice(0,-8).trim(),31;break;case 71:return 6;case 72:return 6;case 73:return 16;case 74:return 57;case 75:return 24;case 76:return U.yytext=U.yytext.trim(),14;break;case 77:return 15;case 78:return 28;case 79:return 58;case 80:return 5;case 81:return"INVALID"}},"anonymous"),rules:[/^(?:click\b)/i,/^(?:href\b)/i,/^(?:"[^"]*")/i,/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:style\s+)/i,/^(?:[\w,]+\s+)/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[12,13],inclusive:!1},struct:{rules:[12,13,25,29,32,38,45,46,47,48,57,58,59,60,74,75,76,77,78],inclusive:!1},FLOATING_NOTE_ID:{rules:[67],inclusive:!1},FLOATING_NOTE:{rules:[64,65,66],inclusive:!1},NOTE_TEXT:{rules:[69,70],inclusive:!1},NOTE_ID:{rules:[68],inclusive:!1},NOTE:{rules:[61,62,63],inclusive:!1},STYLEDEF_STYLEOPTS:{rules:[],inclusive:!1},STYLEDEF_STYLES:{rules:[34],inclusive:!1},STYLE_IDS:{rules:[],inclusive:!1},STYLE:{rules:[33],inclusive:!1},CLASS_STYLE:{rules:[31],inclusive:!1},CLASS:{rules:[30],inclusive:!1},CLASSDEFID:{rules:[28],inclusive:!1},CLASSDEF:{rules:[26,27],inclusive:!1},acc_descr_multiline:{rules:[23,24],inclusive:!1},acc_descr:{rules:[21],inclusive:!1},acc_title:{rules:[19],inclusive:!1},SCALE:{rules:[16,17,36,37],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[51],inclusive:!1},STATE_STRING:{rules:[52,53],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[12,13,39,40,41,42,43,44,49,50,54,55,56],inclusive:!1},ID:{rules:[12,13],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,18,20,22,25,29,32,35,38,56,60,71,72,73,74,75,76,77,79,80,81],inclusive:!0}}};return F}();M.lexer=P;function B(){this.yy={}}return o(B,"Parser"),B.prototype=M,M.Parser=B,new B}();SP.parser=SP;JS=SP});var spe,e6,AP,Cf,Gp,Ob,ope,lpe,cpe,Vp,t6,_P,DP,LP,RP,NP,r6,n6,upe,hpe,MP,IP,fpe,dpe,B1,OHe,ppe,OP,PHe,BHe,mpe,gpe,FHe,ype,$He,vpe,PP,BP,xpe,i6,bpe,FP,a6=N(()=>{"use strict";spe="TB",e6="TB",AP="dir",Cf="state",Gp="root",Ob="relation",ope="classDef",lpe="style",cpe="applyClass",Vp="default",t6="divider",_P="fill:none",DP="fill: #333",LP="c",RP="text",NP="normal",r6="rect",n6="rectWithTitle",upe="stateStart",hpe="stateEnd",MP="divider",IP="roundedWithTitle",fpe="note",dpe="noteGroup",B1="statediagram",OHe="state",ppe=`${B1}-${OHe}`,OP="transition",PHe="note",BHe="note-edge",mpe=`${OP} ${BHe}`,gpe=`${B1}-${PHe}`,FHe="cluster",ype=`${B1}-${FHe}`,$He="cluster-alt",vpe=`${B1}-${$He}`,PP="parent",BP="note",xpe="state",i6="----",bpe=`${i6}${BP}`,FP=`${i6}${PP}`});function $P(t="",e=0,r="",n=i6){let i=r!==null&&r.length>0?`${n}${r}`:"";return`${xpe}-${t}${i}-${e}`}function s6(t,e,r){if(!e.id||e.id===""||e.id==="")return;e.cssClasses&&(Array.isArray(e.cssCompiledStyles)||(e.cssCompiledStyles=[]),e.cssClasses.split(" ").forEach(i=>{let a=r.get(i);a&&(e.cssCompiledStyles=[...e.cssCompiledStyles??[],...a.styles])}));let n=t.find(i=>i.id===e.id);n?Object.assign(n,e):t.push(e)}function GHe(t){return t?.classes?.join(" ")??""}function VHe(t){return t?.styles??[]}var o6,Af,zHe,Tpe,F1,wpe,kpe=N(()=>{"use strict";Gt();yt();pr();a6();o6=new Map,Af=0;o($P,"stateDomId");zHe=o((t,e,r,n,i,a,s,l)=>{X.trace("items",e),e.forEach(u=>{switch(u.stmt){case Cf:F1(t,u,r,n,i,a,s,l);break;case Vp:F1(t,u,r,n,i,a,s,l);break;case Ob:{F1(t,u.state1,r,n,i,a,s,l),F1(t,u.state2,r,n,i,a,s,l);let h={id:"edge"+Af,start:u.state1.id,end:u.state2.id,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:_P,labelStyle:"",label:Ze.sanitizeText(u.description??"",me()),arrowheadStyle:DP,labelpos:LP,labelType:RP,thickness:NP,classes:OP,look:s};i.push(h),Af++}break}})},"setupDoc"),Tpe=o((t,e=e6)=>{let r=e;if(t.doc)for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir");o(s6,"insertOrUpdateNode");o(GHe,"getClassesFromDbInfo");o(VHe,"getStylesFromDbInfo");F1=o((t,e,r,n,i,a,s,l)=>{let u=e.id,h=r.get(u),f=GHe(h),d=VHe(h),p=me();if(X.info("dataFetcher parsedItem",e,h,d),u!=="root"){let m=r6;e.start===!0?m=upe:e.start===!1&&(m=hpe),e.type!==Vp&&(m=e.type),o6.get(u)||o6.set(u,{id:u,shape:m,description:Ze.sanitizeText(u,p),cssClasses:`${f} ${ppe}`,cssStyles:d});let g=o6.get(u);e.description&&(Array.isArray(g.description)?(g.shape=n6,g.description.push(e.description)):g.description?.length&&g.description.length>0?(g.shape=n6,g.description===u?g.description=[e.description]:g.description=[g.description,e.description]):(g.shape=r6,g.description=e.description),g.description=Ze.sanitizeTextOrArray(g.description,p)),g.description?.length===1&&g.shape===n6&&(g.type==="group"?g.shape=IP:g.shape=r6),!g.type&&e.doc&&(X.info("Setting cluster for XCX",u,Tpe(e)),g.type="group",g.isGroup=!0,g.dir=Tpe(e),g.shape=e.type===t6?MP:IP,g.cssClasses=`${g.cssClasses} ${ype} ${a?vpe:""}`);let y={labelStyle:"",shape:g.shape,label:g.description,cssClasses:g.cssClasses,cssCompiledStyles:[],cssStyles:g.cssStyles,id:u,dir:g.dir,domId:$P(u,Af),type:g.type,isGroup:g.type==="group",padding:8,rx:10,ry:10,look:s};if(y.shape===MP&&(y.label=""),t&&t.id!=="root"&&(X.trace("Setting node ",u," to be child of its parent ",t.id),y.parentId=t.id),y.centerLabel=!0,e.note){let v={labelStyle:"",shape:fpe,label:e.note.text,cssClasses:gpe,cssStyles:[],cssCompiledStyles:[],id:u+bpe+"-"+Af,domId:$P(u,Af,BP),type:g.type,isGroup:g.type==="group",padding:p.flowchart?.padding,look:s,position:e.note.position},x=u+FP,b={labelStyle:"",shape:dpe,label:e.note.text,cssClasses:g.cssClasses,cssStyles:[],id:u+FP,domId:$P(u,Af,PP),type:"group",isGroup:!0,padding:16,look:s,position:e.note.position};Af++,b.id=x,v.parentId=x,s6(n,b,l),s6(n,v,l),s6(n,y,l);let T=u,S=v.id;e.note.position==="left of"&&(T=v.id,S=u),i.push({id:T+"-"+S,start:T,end:S,arrowhead:"none",arrowTypeEnd:"",style:_P,labelStyle:"",classes:mpe,arrowheadStyle:DP,labelpos:LP,labelType:RP,thickness:NP,look:s})}else s6(n,y,l)}e.doc&&(X.trace("Adding nodes children "),zHe(e,e.doc,r,n,i,!a,s,l))},"dataFetcher"),wpe=o(()=>{o6.clear(),Af=0},"reset")});var zP,UHe,HHe,Epe,GP=N(()=>{"use strict";Gt();yt();Sm();rp();np();er();a6();zP=o((t,e=e6)=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),UHe=o(function(t,e){return e.db.getClasses()},"getClasses"),HHe=o(async function(t,e,r,n){X.info("REF0:"),X.info("Drawing state diagram (v2)",e);let{securityLevel:i,state:a,layout:s}=me();n.db.extract(n.db.getRootDocV2());let l=n.db.getData(),u=wc(e,i);l.type=n.type,l.layoutAlgorithm=s,l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["barb"],l.diagramId=e,await Rc(l,u);let h=8;try{(typeof n.db.getLinks=="function"?n.db.getLinks():new Map).forEach((d,p)=>{let m=typeof p=="string"?p:typeof p?.id=="string"?p.id:"";if(!m){X.warn("\u26A0\uFE0F Invalid or missing stateId from key:",JSON.stringify(p));return}let g=u.node()?.querySelectorAll("g"),y;if(g?.forEach(T=>{T.textContent?.trim()===m&&(y=T)}),!y){X.warn("\u26A0\uFE0F Could not find node matching text:",m);return}let v=y.parentNode;if(!v){X.warn("\u26A0\uFE0F Node has no parent, cannot wrap:",m);return}let x=document.createElementNS("http://www.w3.org/2000/svg","a"),b=d.url.replace(/^"+|"+$/g,"");if(x.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",b),x.setAttribute("target","_blank"),d.tooltip){let T=d.tooltip.replace(/^"+|"+$/g,"");x.setAttribute("title",T)}v.replaceChild(x,y),x.appendChild(y),X.info("\u{1F517} Wrapped node in
    tag for:",m,d.url)})}catch(f){X.error("\u274C Error injecting clickable links:",f)}Vt.insertTitle(u,"statediagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Yo(u,h,B1,a?.useMaxWidth??!0)},"draw"),Epe={getClasses:UHe,draw:HHe,getDir:zP}});var bs,Spe,Cpe,l6,tl,c6=N(()=>{"use strict";Gt();yt();er();pr();ci();kpe();GP();a6();bs={START_NODE:"[*]",START_TYPE:"start",END_NODE:"[*]",END_TYPE:"end",COLOR_KEYWORD:"color",FILL_KEYWORD:"fill",BG_FILL:"bgFill",STYLECLASS_SEP:","},Spe=o(()=>new Map,"newClassesList"),Cpe=o(()=>({relations:[],states:new Map,documents:{}}),"newDoc"),l6=o(t=>JSON.parse(JSON.stringify(t)),"clone"),tl=class{constructor(e){this.version=e;this.nodes=[];this.edges=[];this.rootDoc=[];this.classes=Spe();this.documents={root:Cpe()};this.currentDocument=this.documents.root;this.startEndCount=0;this.dividerCnt=0;this.links=new Map;this.getAccTitle=Dr;this.setAccTitle=Ar;this.getAccDescription=Rr;this.setAccDescription=Lr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.clear(),this.setRootDoc=this.setRootDoc.bind(this),this.getDividerId=this.getDividerId.bind(this),this.setDirection=this.setDirection.bind(this),this.trimColon=this.trimColon.bind(this)}static{o(this,"StateDB")}static{this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3}}extract(e){this.clear(!0);for(let i of Array.isArray(e)?e:e.doc)switch(i.stmt){case Cf:this.addState(i.id.trim(),i.type,i.doc,i.description,i.note);break;case Ob:this.addRelation(i.state1,i.state2,i.description);break;case ope:this.addStyleClass(i.id.trim(),i.classes);break;case lpe:this.handleStyleDef(i);break;case cpe:this.setCssClass(i.id.trim(),i.styleClass);break;case"click":this.addLink(i.id,i.url,i.tooltip);break}let r=this.getStates(),n=me();wpe(),F1(void 0,this.getRootDocV2(),r,this.nodes,this.edges,!0,n.look,this.classes);for(let i of this.nodes)if(Array.isArray(i.label)){if(i.description=i.label.slice(1),i.isGroup&&i.description.length>0)throw new Error(`Group nodes can only have label. Remove the additional description for node [${i.id}]`);i.label=i.label[0]}}handleStyleDef(e){let r=e.id.trim().split(","),n=e.styleClass.split(",");for(let i of r){let a=this.getState(i);if(!a){let s=i.trim();this.addState(s),a=this.getState(s)}a&&(a.styles=n.map(s=>s.replace(/;/g,"")?.trim()))}}setRootDoc(e){X.info("Setting root doc",e),this.rootDoc=e,this.version===1?this.extract(e):this.extract(this.getRootDocV2())}docTranslator(e,r,n){if(r.stmt===Ob){this.docTranslator(e,r.state1,!0),this.docTranslator(e,r.state2,!1);return}if(r.stmt===Cf&&(r.id===bs.START_NODE?(r.id=e.id+(n?"_start":"_end"),r.start=n):r.id=r.id.trim()),r.stmt!==Gp&&r.stmt!==Cf||!r.doc)return;let i=[],a=[];for(let s of r.doc)if(s.type===t6){let l=l6(s);l.doc=l6(a),i.push(l),a=[]}else a.push(s);if(i.length>0&&a.length>0){let s={stmt:Cf,id:L9(),type:"divider",doc:l6(a)};i.push(l6(s)),r.doc=i}r.doc.forEach(s=>this.docTranslator(r,s,!0))}getRootDocV2(){return this.docTranslator({id:Gp,stmt:Gp},{id:Gp,stmt:Gp,doc:this.rootDoc},!0),{id:Gp,doc:this.rootDoc}}addState(e,r=Vp,n=void 0,i=void 0,a=void 0,s=void 0,l=void 0,u=void 0){let h=e?.trim();if(!this.currentDocument.states.has(h))X.info("Adding state ",h,i),this.currentDocument.states.set(h,{stmt:Cf,id:h,descriptions:[],type:r,doc:n,note:a,classes:[],styles:[],textStyles:[]});else{let f=this.currentDocument.states.get(h);if(!f)throw new Error(`State not found: ${h}`);f.doc||(f.doc=n),f.type||(f.type=r)}if(i&&(X.info("Setting state description",h,i),(Array.isArray(i)?i:[i]).forEach(d=>this.addDescription(h,d.trim()))),a){let f=this.currentDocument.states.get(h);if(!f)throw new Error(`State not found: ${h}`);f.note=a,f.note.text=Ze.sanitizeText(f.note.text,me())}s&&(X.info("Setting state classes",h,s),(Array.isArray(s)?s:[s]).forEach(d=>this.setCssClass(h,d.trim()))),l&&(X.info("Setting state styles",h,l),(Array.isArray(l)?l:[l]).forEach(d=>this.setStyle(h,d.trim()))),u&&(X.info("Setting state styles",h,l),(Array.isArray(u)?u:[u]).forEach(d=>this.setTextStyle(h,d.trim())))}clear(e){this.nodes=[],this.edges=[],this.documents={root:Cpe()},this.currentDocument=this.documents.root,this.startEndCount=0,this.classes=Spe(),e||(this.links=new Map,kr())}getState(e){return this.currentDocument.states.get(e)}getStates(){return this.currentDocument.states}logDocuments(){X.info("Documents = ",this.documents)}getRelations(){return this.currentDocument.relations}addLink(e,r,n){this.links.set(e,{url:r,tooltip:n}),X.warn("Adding link",e,r,n)}getLinks(){return this.links}startIdIfNeeded(e=""){return e===bs.START_NODE?(this.startEndCount++,`${bs.START_TYPE}${this.startEndCount}`):e}startTypeIfNeeded(e="",r=Vp){return e===bs.START_NODE?bs.START_TYPE:r}endIdIfNeeded(e=""){return e===bs.END_NODE?(this.startEndCount++,`${bs.END_TYPE}${this.startEndCount}`):e}endTypeIfNeeded(e="",r=Vp){return e===bs.END_NODE?bs.END_TYPE:r}addRelationObjs(e,r,n=""){let i=this.startIdIfNeeded(e.id.trim()),a=this.startTypeIfNeeded(e.id.trim(),e.type),s=this.startIdIfNeeded(r.id.trim()),l=this.startTypeIfNeeded(r.id.trim(),r.type);this.addState(i,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),this.addState(s,l,r.doc,r.description,r.note,r.classes,r.styles,r.textStyles),this.currentDocument.relations.push({id1:i,id2:s,relationTitle:Ze.sanitizeText(n,me())})}addRelation(e,r,n){if(typeof e=="object"&&typeof r=="object")this.addRelationObjs(e,r,n);else if(typeof e=="string"&&typeof r=="string"){let i=this.startIdIfNeeded(e.trim()),a=this.startTypeIfNeeded(e),s=this.endIdIfNeeded(r.trim()),l=this.endTypeIfNeeded(r);this.addState(i,a),this.addState(s,l),this.currentDocument.relations.push({id1:i,id2:s,relationTitle:n?Ze.sanitizeText(n,me()):void 0})}}addDescription(e,r){let n=this.currentDocument.states.get(e),i=r.startsWith(":")?r.replace(":","").trim():r;n?.descriptions?.push(Ze.sanitizeText(i,me()))}cleanupLabel(e){return e.startsWith(":")?e.slice(2).trim():e.trim()}getDividerId(){return this.dividerCnt++,`divider-id-${this.dividerCnt}`}addStyleClass(e,r=""){this.classes.has(e)||this.classes.set(e,{id:e,styles:[],textStyles:[]});let n=this.classes.get(e);r&&n&&r.split(bs.STYLECLASS_SEP).forEach(i=>{let a=i.replace(/([^;]*);/,"$1").trim();if(RegExp(bs.COLOR_KEYWORD).exec(i)){let l=a.replace(bs.FILL_KEYWORD,bs.BG_FILL).replace(bs.COLOR_KEYWORD,bs.FILL_KEYWORD);n.textStyles.push(l)}n.styles.push(a)})}getClasses(){return this.classes}setCssClass(e,r){e.split(",").forEach(n=>{let i=this.getState(n);if(!i){let a=n.trim();this.addState(a),i=this.getState(a)}i?.classes?.push(r)})}setStyle(e,r){this.getState(e)?.styles?.push(r)}setTextStyle(e,r){this.getState(e)?.textStyles?.push(r)}getDirectionStatement(){return this.rootDoc.find(e=>e.stmt===AP)}getDirection(){return this.getDirectionStatement()?.value??spe}setDirection(e){let r=this.getDirectionStatement();r?r.value=e:this.rootDoc.unshift({stmt:AP,value:e})}trimColon(e){return e.startsWith(":")?e.slice(1).trim():e.trim()}getData(){let e=me();return{nodes:this.nodes,edges:this.edges,other:{},config:e,direction:zP(this.getRootDocV2())}}getConfig(){return me().state}}});var WHe,u6,VP=N(()=>{"use strict";WHe=o(t=>` -defs #statediagram-barbEnd { - fill: ${t.transitionColor}; - stroke: ${t.transitionColor}; - } -g.stateGroup text { - fill: ${t.nodeBorder}; - stroke: none; - font-size: 10px; -} -g.stateGroup text { - fill: ${t.textColor}; - stroke: none; - font-size: 10px; - -} -g.stateGroup .state-title { - font-weight: bolder; - fill: ${t.stateLabelColor}; -} - -g.stateGroup rect { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; -} - -g.stateGroup line { - stroke: ${t.lineColor}; - stroke-width: 1; -} - -.transition { - stroke: ${t.transitionColor}; - stroke-width: 1; - fill: none; -} - -.stateGroup .composit { - fill: ${t.background}; - border-bottom: 1px -} - -.stateGroup .alt-composit { - fill: #e0e0e0; - border-bottom: 1px -} - -.state-note { - stroke: ${t.noteBorderColor}; - fill: ${t.noteBkgColor}; - - text { - fill: ${t.noteTextColor}; - stroke: none; - font-size: 10px; - } -} - -.stateLabel .box { - stroke: none; - stroke-width: 0; - fill: ${t.mainBkg}; - opacity: 0.5; -} - -.edgeLabel .label rect { - fill: ${t.labelBackgroundColor}; - opacity: 0.5; -} -.edgeLabel { - background-color: ${t.edgeLabelBackground}; - p { - background-color: ${t.edgeLabelBackground}; - } - rect { - opacity: 0.5; - background-color: ${t.edgeLabelBackground}; - fill: ${t.edgeLabelBackground}; - } - text-align: center; -} -.edgeLabel .label text { - fill: ${t.transitionLabelColor||t.tertiaryTextColor}; -} -.label div .edgeLabel { - color: ${t.transitionLabelColor||t.tertiaryTextColor}; -} - -.stateLabel text { - fill: ${t.stateLabelColor}; - font-size: 10px; - font-weight: bold; -} - -.node circle.state-start { - fill: ${t.specialStateColor}; - stroke: ${t.specialStateColor}; -} - -.node .fork-join { - fill: ${t.specialStateColor}; - stroke: ${t.specialStateColor}; -} - -.node circle.state-end { - fill: ${t.innerEndBackground}; - stroke: ${t.background}; - stroke-width: 1.5 -} -.end-state-inner { - fill: ${t.compositeBackground||t.background}; - // stroke: ${t.background}; - stroke-width: 1.5 -} - -.node rect { - fill: ${t.stateBkg||t.mainBkg}; - stroke: ${t.stateBorder||t.nodeBorder}; - stroke-width: 1px; -} -.node polygon { - fill: ${t.mainBkg}; - stroke: ${t.stateBorder||t.nodeBorder};; - stroke-width: 1px; -} -#statediagram-barbEnd { - fill: ${t.lineColor}; -} - -.statediagram-cluster rect { - fill: ${t.compositeTitleBackground}; - stroke: ${t.stateBorder||t.nodeBorder}; - stroke-width: 1px; -} - -.cluster-label, .nodeLabel { - color: ${t.stateLabelColor}; - // line-height: 1; -} - -.statediagram-cluster rect.outer { - rx: 5px; - ry: 5px; -} -.statediagram-state .divider { - stroke: ${t.stateBorder||t.nodeBorder}; -} - -.statediagram-state .title-state { - rx: 5px; - ry: 5px; -} -.statediagram-cluster.statediagram-cluster .inner { - fill: ${t.compositeBackground||t.background}; -} -.statediagram-cluster.statediagram-cluster-alt .inner { - fill: ${t.altBackground?t.altBackground:"#efefef"}; -} - -.statediagram-cluster .inner { - rx:0; - ry:0; -} - -.statediagram-state rect.basic { - rx: 5px; - ry: 5px; -} -.statediagram-state rect.divider { - stroke-dasharray: 10,10; - fill: ${t.altBackground?t.altBackground:"#efefef"}; -} - -.note-edge { - stroke-dasharray: 5; -} - -.statediagram-note rect { - fill: ${t.noteBkgColor}; - stroke: ${t.noteBorderColor}; - stroke-width: 1px; - rx: 0; - ry: 0; -} -.statediagram-note rect { - fill: ${t.noteBkgColor}; - stroke: ${t.noteBorderColor}; - stroke-width: 1px; - rx: 0; - ry: 0; -} - -.statediagram-note text { - fill: ${t.noteTextColor}; -} - -.statediagram-note .nodeLabel { - color: ${t.noteTextColor}; -} -.statediagram .edgeLabel { - color: red; // ${t.noteTextColor}; -} - -#dependencyStart, #dependencyEnd { - fill: ${t.lineColor}; - stroke: ${t.lineColor}; - stroke-width: 1; -} - -.statediagramTitleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.textColor}; -} -`,"getStyles"),u6=WHe});var qHe,YHe,XHe,jHe,_pe,KHe,QHe,ZHe,JHe,UP,Ape,Dpe,Lpe=N(()=>{"use strict";fr();c6();er();pr();Gt();yt();qHe=o(t=>t.append("circle").attr("class","start-state").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit).attr("cy",me().state.padding+me().state.sizeUnit),"drawStartState"),YHe=o(t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",me().state.textHeight).attr("class","divider").attr("x2",me().state.textHeight*2).attr("y1",0).attr("y2",0),"drawDivider"),XHe=o((t,e)=>{let r=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+2*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),n=r.node().getBBox();return t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",n.width+2*me().state.padding).attr("height",n.height+2*me().state.padding).attr("rx",me().state.radius),r},"drawSimpleState"),jHe=o((t,e)=>{let r=o(function(p,m,g){let y=p.append("tspan").attr("x",2*me().state.padding).text(m);g||y.attr("dy",me().state.textHeight)},"addTspan"),i=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+1.3*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),a=i.height,s=t.append("text").attr("x",me().state.padding).attr("y",a+me().state.padding*.4+me().state.dividerMargin+me().state.textHeight).attr("class","state-description"),l=!0,u=!0;e.descriptions.forEach(function(p){l||(r(s,p,u),u=!1),l=!1});let h=t.append("line").attr("x1",me().state.padding).attr("y1",me().state.padding+a+me().state.dividerMargin/2).attr("y2",me().state.padding+a+me().state.dividerMargin/2).attr("class","descr-divider"),f=s.node().getBBox(),d=Math.max(f.width,i.width);return h.attr("x2",d+3*me().state.padding),t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",d+2*me().state.padding).attr("height",f.height+a+2*me().state.padding).attr("rx",me().state.radius),t},"drawDescrState"),_pe=o((t,e,r)=>{let n=me().state.padding,i=2*me().state.padding,a=t.node().getBBox(),s=a.width,l=a.x,u=t.append("text").attr("x",0).attr("y",me().state.titleShift).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),f=u.node().getBBox().width+i,d=Math.max(f,s);d===s&&(d=d+i);let p,m=t.node().getBBox();e.doc,p=l-n,f>s&&(p=(s-d)/2+n),Math.abs(l-m.x)s&&(p=l-(f-s)/2);let g=1-me().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",g).attr("class",r?"alt-composit":"composit").attr("width",d).attr("height",m.height+me().state.textHeight+me().state.titleShift+1).attr("rx","0"),u.attr("x",p+n),f<=s&&u.attr("x",l+(d-i)/2-f/2+n),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",me().state.textHeight*3).attr("rx",me().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",m.height+3+2*me().state.textHeight).attr("rx",me().state.radius),t},"addTitleAndBox"),KHe=o(t=>(t.append("circle").attr("class","end-state-outer").attr("r",me().state.sizeUnit+me().state.miniPadding).attr("cx",me().state.padding+me().state.sizeUnit+me().state.miniPadding).attr("cy",me().state.padding+me().state.sizeUnit+me().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit+2).attr("cy",me().state.padding+me().state.sizeUnit+2)),"drawEndState"),QHe=o((t,e)=>{let r=me().state.forkWidth,n=me().state.forkHeight;if(e.parentId){let i=r;r=n,n=i}return t.append("rect").style("stroke","black").style("fill","black").attr("width",r).attr("height",n).attr("x",me().state.padding).attr("y",me().state.padding)},"drawForkJoinState"),ZHe=o((t,e,r,n)=>{let i=0,a=n.append("text");a.style("text-anchor","start"),a.attr("class","noteText");let s=t.replace(/\r\n/g,"
    ");s=s.replace(/\n/g,"
    ");let l=s.split(Ze.lineBreakRegex),u=1.25*me().state.noteMargin;for(let h of l){let f=h.trim();if(f.length>0){let d=a.append("tspan");if(d.text(f),u===0){let p=d.node().getBBox();u+=p.height}i+=u,d.attr("x",e+me().state.noteMargin),d.attr("y",r+i+1.25*me().state.noteMargin)}}return{textWidth:a.node().getBBox().width,textHeight:i}},"_drawLongText"),JHe=o((t,e)=>{e.attr("class","state-note");let r=e.append("rect").attr("x",0).attr("y",me().state.padding),n=e.append("g"),{textWidth:i,textHeight:a}=ZHe(t,0,0,n);return r.attr("height",a+2*me().state.noteMargin),r.attr("width",i+me().state.noteMargin*2),r},"drawNote"),UP=o(function(t,e){let r=e.id,n={id:r,label:e.id,width:0,height:0},i=t.append("g").attr("id",r).attr("class","stateGroup");e.type==="start"&&qHe(i),e.type==="end"&&KHe(i),(e.type==="fork"||e.type==="join")&&QHe(i,e),e.type==="note"&&JHe(e.note.text,i),e.type==="divider"&&YHe(i),e.type==="default"&&e.descriptions.length===0&&XHe(i,e),e.type==="default"&&e.descriptions.length>0&&jHe(i,e);let a=i.node().getBBox();return n.width=a.width+2*me().state.padding,n.height=a.height+2*me().state.padding,n},"drawState"),Ape=0,Dpe=o(function(t,e,r){let n=o(function(u){switch(u){case tl.relationType.AGGREGATION:return"aggregation";case tl.relationType.EXTENSION:return"extension";case tl.relationType.COMPOSITION:return"composition";case tl.relationType.DEPENDENCY:return"dependency"}},"getRelationType");e.points=e.points.filter(u=>!Number.isNaN(u.y));let i=e.points,a=Cl().x(function(u){return u.x}).y(function(u){return u.y}).curve(No),s=t.append("path").attr("d",a(i)).attr("id","edge"+Ape).attr("class","transition"),l="";if(me().state.arrowMarkerAbsolute&&(l=mu(!0)),s.attr("marker-end","url("+l+"#"+n(tl.relationType.DEPENDENCY)+"End)"),r.title!==void 0){let u=t.append("g").attr("class","stateLabel"),{x:h,y:f}=Vt.calcLabelPosition(e.points),d=Ze.getRows(r.title),p=0,m=[],g=0,y=0;for(let b=0;b<=d.length;b++){let T=u.append("text").attr("text-anchor","middle").text(d[b]).attr("x",h).attr("y",f+p),S=T.node().getBBox();g=Math.max(g,S.width),y=Math.min(y,S.x),X.info(S.x,h,f+p),p===0&&(p=T.node().getBBox().height,X.info("Title height",p,f)),m.push(T)}let v=p*d.length;if(d.length>1){let b=(d.length-1)*p*.5;m.forEach((T,S)=>T.attr("y",f+S*p-b)),v=p*d.length}let x=u.node().getBBox();u.insert("rect",":first-child").attr("class","box").attr("x",h-g/2-me().state.padding/2).attr("y",f-v/2-me().state.padding/2-3.5).attr("width",g+me().state.padding).attr("height",v+me().state.padding),X.info(x)}Ape++},"drawEdge")});var go,HP,eWe,tWe,rWe,nWe,Rpe,Npe,Mpe=N(()=>{"use strict";fr();JR();Wo();yt();pr();Lpe();Gt();xi();HP={},eWe=o(function(){},"setConf"),tWe=o(function(t){t.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),rWe=o(function(t,e,r,n){go=me().state;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=i==="sandbox"?a.nodes()[0].contentDocument:document;X.debug("Rendering diagram "+t);let u=s.select(`[id='${e}']`);tWe(u);let h=n.db.getRootDoc();Rpe(h,u,void 0,!1,s,l,n);let f=go.padding,d=u.node().getBBox(),p=d.width+f*2,m=d.height+f*2,g=p*1.75;fn(u,m,g,go.useMaxWidth),u.attr("viewBox",`${d.x-go.padding} ${d.y-go.padding} `+p+" "+m)},"draw"),nWe=o(t=>t?t.length*go.fontSizeFactor:1,"getLabelWidth"),Rpe=o((t,e,r,n,i,a,s)=>{let l=new sn({compound:!0,multigraph:!0}),u,h=!0;for(u=0;u{let w=S.parentElement,E=0,_=0;w&&(w.parentElement&&(E=w.parentElement.getBBox().width),_=parseInt(w.getAttribute("data-x-shift"),10),Number.isNaN(_)&&(_=0)),S.setAttribute("x1",0-_+8),S.setAttribute("x2",E-_-8)})):X.debug("No Node "+b+": "+JSON.stringify(l.node(b)))});let v=y.getBBox();l.edges().forEach(function(b){b!==void 0&&l.edge(b)!==void 0&&(X.debug("Edge "+b.v+" -> "+b.w+": "+JSON.stringify(l.edge(b))),Dpe(e,l.edge(b),l.edge(b).relation))}),v=y.getBBox();let x={id:r||"root",label:r||"root",width:0,height:0};return x.width=v.width+2*go.padding,x.height=v.height+2*go.padding,X.debug("Doc rendered",x,l),x},"renderDoc"),Npe={setConf:eWe,draw:rWe}});var Ipe={};ur(Ipe,{diagram:()=>iWe});var iWe,Ope=N(()=>{"use strict";CP();c6();VP();Mpe();iWe={parser:JS,get db(){return new tl(1)},renderer:Npe,styles:u6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var Fpe={};ur(Fpe,{diagram:()=>lWe});var lWe,$pe=N(()=>{"use strict";CP();c6();VP();GP();lWe={parser:JS,get db(){return new tl(2)},renderer:Epe,styles:u6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var WP,Vpe,Upe=N(()=>{"use strict";WP=function(){var t=o(function(d,p,m,g){for(m=m||{},g=d.length;g--;m[d[g]]=p);return m},"o"),e=[6,8,10,11,12,14,16,17,18],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,14],u={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:o(function(p,m,g,y,v,x,b){var T=x.length-1;switch(v){case 1:return x[T-1];case 2:this.$=[];break;case 3:x[T-1].push(x[T]),this.$=x[T-1];break;case 4:case 5:this.$=x[T];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(x[T].substr(6)),this.$=x[T].substr(6);break;case 9:this.$=x[T].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=x[T].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(x[T].substr(8)),this.$=x[T].substr(8);break;case 13:y.addTask(x[T-1],x[T]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:o(function(p,m){if(m.recoverable)this.trace(p);else{var g=new Error(p);throw g.hash=m,g}},"parseError"),parse:o(function(p){var m=this,g=[0],y=[],v=[null],x=[],b=this.table,T="",S=0,w=0,E=0,_=2,C=1,D=x.slice.call(arguments,1),O=Object.create(this.lexer),R={yy:{}};for(var k in this.yy)Object.prototype.hasOwnProperty.call(this.yy,k)&&(R.yy[k]=this.yy[k]);O.setInput(p,R.yy),R.yy.lexer=O,R.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var L=O.yylloc;x.push(L);var A=O.options&&O.options.ranges;typeof R.yy.parseError=="function"?this.parseError=R.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function I(Q){g.length=g.length-2*Q,v.length=v.length-Q,x.length=x.length-Q}o(I,"popStack");function M(){var Q;return Q=y.pop()||O.lex()||C,typeof Q!="number"&&(Q instanceof Array&&(y=Q,Q=y.pop()),Q=m.symbols_[Q]||Q),Q}o(M,"lex");for(var P,B,F,z,$,U,K={},ee,Y,ce,Z;;){if(F=g[g.length-1],this.defaultActions[F]?z=this.defaultActions[F]:((P===null||typeof P>"u")&&(P=M()),z=b[F]&&b[F][P]),typeof z>"u"||!z.length||!z[0]){var ue="";Z=[];for(ee in b[F])this.terminals_[ee]&&ee>_&&Z.push("'"+this.terminals_[ee]+"'");O.showPosition?ue="Parse error on line "+(S+1)+`: -`+O.showPosition()+` -Expecting `+Z.join(", ")+", got '"+(this.terminals_[P]||P)+"'":ue="Parse error on line "+(S+1)+": Unexpected "+(P==C?"end of input":"'"+(this.terminals_[P]||P)+"'"),this.parseError(ue,{text:O.match,token:this.terminals_[P]||P,line:O.yylineno,loc:L,expected:Z})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+F+", token: "+P);switch(z[0]){case 1:g.push(P),v.push(O.yytext),x.push(O.yylloc),g.push(z[1]),P=null,B?(P=B,B=null):(w=O.yyleng,T=O.yytext,S=O.yylineno,L=O.yylloc,E>0&&E--);break;case 2:if(Y=this.productions_[z[1]][1],K.$=v[v.length-Y],K._$={first_line:x[x.length-(Y||1)].first_line,last_line:x[x.length-1].last_line,first_column:x[x.length-(Y||1)].first_column,last_column:x[x.length-1].last_column},A&&(K._$.range=[x[x.length-(Y||1)].range[0],x[x.length-1].range[1]]),U=this.performAction.apply(K,[T,w,S,R.yy,z[1],v,x].concat(D)),typeof U<"u")return U;Y&&(g=g.slice(0,-1*Y*2),v=v.slice(0,-1*Y),x=x.slice(0,-1*Y)),g.push(this.productions_[z[1]][0]),v.push(K.$),x.push(K._$),ce=b[g[g.length-2]][g[g.length-1]],g.push(ce);break;case 3:return!0}}return!0},"parse")},h=function(){var d={EOF:1,parseError:o(function(m,g){if(this.yy.parser)this.yy.parser.parseError(m,g);else throw new Error(m)},"parseError"),setInput:o(function(p,m){return this.yy=m||this.yy||{},this._input=p,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var p=this._input[0];this.yytext+=p,this.yyleng++,this.offset++,this.match+=p,this.matched+=p;var m=p.match(/(?:\r\n?|\n).*/g);return m?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),p},"input"),unput:o(function(p){var m=p.length,g=p.split(/(?:\r\n?|\n)/g);this._input=p+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-m),this.offset-=m;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var v=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===y.length?this.yylloc.first_column:0)+y[y.length-g.length].length-g[0].length:this.yylloc.first_column-m},this.options.ranges&&(this.yylloc.range=[v[0],v[0]+this.yyleng-m]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(p){this.unput(this.match.slice(p))},"less"),pastInput:o(function(){var p=this.matched.substr(0,this.matched.length-this.match.length);return(p.length>20?"...":"")+p.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var p=this.match;return p.length<20&&(p+=this._input.substr(0,20-p.length)),(p.substr(0,20)+(p.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var p=this.pastInput(),m=new Array(p.length+1).join("-");return p+this.upcomingInput()+` -`+m+"^"},"showPosition"),test_match:o(function(p,m){var g,y,v;if(this.options.backtrack_lexer&&(v={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(v.yylloc.range=this.yylloc.range.slice(0))),y=p[0].match(/(?:\r\n?|\n).*/g),y&&(this.yylineno+=y.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:y?y[y.length-1].length-y[y.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+p[0].length},this.yytext+=p[0],this.match+=p[0],this.matches=p,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(p[0].length),this.matched+=p[0],g=this.performAction.call(this,this.yy,this,m,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),g)return g;if(this._backtrack){for(var x in v)this[x]=v[x];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var p,m,g,y;this._more||(this.yytext="",this.match="");for(var v=this._currentRules(),x=0;xm[0].length)){if(m=g,y=x,this.options.backtrack_lexer){if(p=this.test_match(g,v[x]),p!==!1)return p;if(this._backtrack){m=!1;continue}else return!1}else if(!this.options.flex)break}return m?(p=this.test_match(m,v[y]),p!==!1?p:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var m=this.next();return m||this.lex()},"lex"),begin:o(function(m){this.conditionStack.push(m)},"begin"),popState:o(function(){var m=this.conditionStack.length-1;return m>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(m){return m=this.conditionStack.length-1-Math.abs(m||0),m>=0?this.conditionStack[m]:"INITIAL"},"topState"),pushState:o(function(m){this.begin(m)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(m,g,y,v){var x=v;switch(y){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};return d}();u.lexer=h;function f(){this.yy={}}return o(f,"Parser"),f.prototype=u,u.Parser=f,new f}();WP.parser=WP;Vpe=WP});var $1,qP,Pb,Bb,fWe,dWe,pWe,mWe,gWe,yWe,vWe,Hpe,xWe,YP,Wpe=N(()=>{"use strict";Gt();ci();$1="",qP=[],Pb=[],Bb=[],fWe=o(function(){qP.length=0,Pb.length=0,$1="",Bb.length=0,kr()},"clear"),dWe=o(function(t){$1=t,qP.push(t)},"addSection"),pWe=o(function(){return qP},"getSections"),mWe=o(function(){let t=Hpe(),e=100,r=0;for(;!t&&r{r.people&&t.push(...r.people)}),[...new Set(t)].sort()},"updateActors"),yWe=o(function(t,e){let r=e.substr(1).split(":"),n=0,i=[];r.length===1?(n=Number(r[0]),i=[]):(n=Number(r[0]),i=r[1].split(","));let a=i.map(l=>l.trim()),s={section:$1,type:$1,people:a,task:t,score:n};Bb.push(s)},"addTask"),vWe=o(function(t){let e={section:$1,type:$1,description:t,task:t,classes:[]};Pb.push(e)},"addTaskOrg"),Hpe=o(function(){let t=o(function(r){return Bb[r].processed},"compileTask"),e=!0;for(let[r,n]of Bb.entries())t(r),e=e&&n.processed;return e},"compileTasks"),xWe=o(function(){return gWe()},"getActors"),YP={getConfig:o(()=>me().journey,"getConfig"),clear:fWe,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,addSection:dWe,getSections:pWe,getTasks:mWe,addTask:yWe,addTaskOrg:vWe,getActors:xWe}});var bWe,qpe,Ype=N(()=>{"use strict";Xm();bWe=o(t=>`.label { - font-family: ${t.fontFamily}; - color: ${t.textColor}; - } - .mouth { - stroke: #666; - } - - line { - stroke: ${t.textColor} - } - - .legend { - fill: ${t.textColor}; - font-family: ${t.fontFamily}; - } - - .label text { - fill: #333; - } - .label { - color: ${t.textColor} - } - - .face { - ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"}; - stroke: #999; - } - - .node rect, - .node circle, - .node ellipse, - .node polygon, - .node path { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - stroke-width: 1px; - } - - .node .label { - text-align: center; - } - .node.clickable { - cursor: pointer; - } - - .arrowheadPath { - fill: ${t.arrowheadColor}; - } - - .edgePath .path { - stroke: ${t.lineColor}; - stroke-width: 1.5px; - } - - .flowchart-link { - stroke: ${t.lineColor}; - fill: none; - } - - .edgeLabel { - background-color: ${t.edgeLabelBackground}; - rect { - opacity: 0.5; - } - text-align: center; - } - - .cluster rect { - } - - .cluster text { - fill: ${t.titleColor}; - } - - div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: ${t.fontFamily}; - font-size: 12px; - background: ${t.tertiaryColor}; - border: 1px solid ${t.border2}; - border-radius: 2px; - pointer-events: none; - z-index: 100; - } - - .task-type-0, .section-type-0 { - ${t.fillType0?`fill: ${t.fillType0}`:""}; - } - .task-type-1, .section-type-1 { - ${t.fillType0?`fill: ${t.fillType1}`:""}; - } - .task-type-2, .section-type-2 { - ${t.fillType0?`fill: ${t.fillType2}`:""}; - } - .task-type-3, .section-type-3 { - ${t.fillType0?`fill: ${t.fillType3}`:""}; - } - .task-type-4, .section-type-4 { - ${t.fillType0?`fill: ${t.fillType4}`:""}; - } - .task-type-5, .section-type-5 { - ${t.fillType0?`fill: ${t.fillType5}`:""}; - } - .task-type-6, .section-type-6 { - ${t.fillType0?`fill: ${t.fillType6}`:""}; - } - .task-type-7, .section-type-7 { - ${t.fillType0?`fill: ${t.fillType7}`:""}; - } - - .actor-0 { - ${t.actor0?`fill: ${t.actor0}`:""}; - } - .actor-1 { - ${t.actor1?`fill: ${t.actor1}`:""}; - } - .actor-2 { - ${t.actor2?`fill: ${t.actor2}`:""}; - } - .actor-3 { - ${t.actor3?`fill: ${t.actor3}`:""}; - } - .actor-4 { - ${t.actor4?`fill: ${t.actor4}`:""}; - } - .actor-5 { - ${t.actor5?`fill: ${t.actor5}`:""}; - } - ${Nc()} -`,"getStyles"),qpe=bWe});var XP,TWe,jpe,Kpe,wWe,kWe,Xpe,EWe,SWe,Qpe,CWe,z1,Zpe=N(()=>{"use strict";fr();t2();XP=o(function(t,e){return Nd(t,e)},"drawRect"),TWe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=Sl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=Sl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),jpe=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),Kpe=o(function(t,e){return XY(t,e)},"drawText"),wWe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,Kpe(t,e)},"drawLabel"),kWe=o(function(t,e,r){let n=t.append("g"),i=Al();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width*e.taskCount+r.diagramMarginX*(e.taskCount-1),i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,XP(n,i),Qpe(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),Xpe=-1,EWe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");Xpe++;let a=300+5*30;i.append("line").attr("id","task"+Xpe).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),TWe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=Al();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,XP(i,s);let l=e.x+14;e.people.forEach(u=>{let h=e.actors[u].color,f={cx:l,cy:e.y,r:7,fill:h,stroke:"#000",title:u,pos:e.actors[u].position};jpe(i,f),l+=10}),Qpe(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),SWe=o(function(t,e){iT(t,e)},"drawBackgroundRect"),Qpe=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(//gi);for(let v=0;v{let a=th[i].color,s={cx:20,cy:n,r:7,fill:a,stroke:"#000",pos:th[i].position};z1.drawCircle(t,s);let l=t.append("text").attr("visibility","hidden").text(i),u=l.node().getBoundingClientRect().width;l.remove();let h=[];if(u<=r)h=[i];else{let f=i.split(" "),d="";l=t.append("text").attr("visibility","hidden"),f.forEach(p=>{let m=d?`${d} ${p}`:p;if(l.text(m),l.node().getBoundingClientRect().width>r){if(d&&h.push(d),d=p,l.text(p),l.node().getBoundingClientRect().width>r){let y="";for(let v of p)y+=v,l.text(y+"-"),l.node().getBoundingClientRect().width>r&&(h.push(y.slice(0,-1)+"-"),y=v);d=y}}else d=m}),d&&h.push(d),l.remove()}h.forEach((f,d)=>{let p={x:40,y:n+7+d*20,fill:"#666",text:f,textMargin:e.boxTextMargin??5},g=z1.drawText(t,p).node().getBoundingClientRect().width;g>h6&&g>e.leftMargin-g&&(h6=g)}),n+=Math.max(20,h.length*20)})}var AWe,th,h6,Ul,_f,DWe,rl,jP,Jpe,LWe,KP,e0e=N(()=>{"use strict";fr();Zpe();Gt();xi();AWe=o(function(t){Object.keys(t).forEach(function(r){Ul[r]=t[r]})},"setConf"),th={},h6=0;o(_We,"drawActorLegend");Ul=me().journey,_f=0,DWe=o(function(t,e,r,n){let i=me(),a=i.journey.titleColor,s=i.journey.titleFontSize,l=i.journey.titleFontFamily,u=i.securityLevel,h;u==="sandbox"&&(h=Ge("#i"+e));let f=u==="sandbox"?Ge(h.nodes()[0].contentDocument.body):Ge("body");rl.init();let d=f.select("#"+e);z1.initGraphics(d);let p=n.db.getTasks(),m=n.db.getDiagramTitle(),g=n.db.getActors();for(let S in th)delete th[S];let y=0;g.forEach(S=>{th[S]={color:Ul.actorColours[y%Ul.actorColours.length],position:y},y++}),_We(d),_f=Ul.leftMargin+h6,rl.insert(0,0,_f,Object.keys(th).length*50),LWe(d,p,0);let v=rl.getBounds();m&&d.append("text").text(m).attr("x",_f).attr("font-size",s).attr("font-weight","bold").attr("y",25).attr("fill",a).attr("font-family",l);let x=v.stopy-v.starty+2*Ul.diagramMarginY,b=_f+v.stopx+2*Ul.diagramMarginX;fn(d,x,b,Ul.useMaxWidth),d.append("line").attr("x1",_f).attr("y1",Ul.height*4).attr("x2",b-_f-4).attr("y2",Ul.height*4).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");let T=m?70:0;d.attr("viewBox",`${v.startx} -25 ${b} ${x+T}`),d.attr("preserveAspectRatio","xMinYMin meet"),d.attr("height",x+T+25)},"draw"),rl={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:o(function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=me().journey,a=this,s=0;function l(u){return o(function(f){s++;let d=a.sequenceItems.length-s+1;a.updateVal(f,"starty",e-d*i.boxMargin,Math.min),a.updateVal(f,"stopy",n+d*i.boxMargin,Math.max),a.updateVal(rl.data,"startx",t-d*i.boxMargin,Math.min),a.updateVal(rl.data,"stopx",r+d*i.boxMargin,Math.max),u!=="activation"&&(a.updateVal(f,"startx",t-d*i.boxMargin,Math.min),a.updateVal(f,"stopx",r+d*i.boxMargin,Math.max),a.updateVal(rl.data,"starty",e-d*i.boxMargin,Math.min),a.updateVal(rl.data,"stopy",n+d*i.boxMargin,Math.max))},"updateItemBounds")}o(l,"updateFn"),this.sequenceItems.forEach(l())},"updateBounds"),insert:o(function(t,e,r,n){let i=Math.min(t,r),a=Math.max(t,r),s=Math.min(e,n),l=Math.max(e,n);this.updateVal(rl.data,"startx",i,Math.min),this.updateVal(rl.data,"starty",s,Math.min),this.updateVal(rl.data,"stopx",a,Math.max),this.updateVal(rl.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return this.data},"getBounds")},jP=Ul.sectionFills,Jpe=Ul.sectionColours,LWe=o(function(t,e,r){let n=me().journey,i="",a=n.height*2+n.diagramMarginY,s=r+a,l=0,u="#CCC",h="black",f=0;for(let[d,p]of e.entries()){if(i!==p.section){u=jP[l%jP.length],f=l%jP.length,h=Jpe[l%Jpe.length];let g=0,y=p.section;for(let x=d;x(th[y]&&(g[y]=th[y]),g),{});p.x=d*n.taskMargin+d*n.width+_f,p.y=s,p.width=n.diagramMarginX,p.height=n.diagramMarginY,p.colour=h,p.fill=u,p.num=f,p.actors=m,z1.drawTask(t,p,n),rl.insert(p.x,p.y,p.x+p.width+n.taskMargin,300+5*30)}},"drawTasks"),KP={setConf:AWe,draw:DWe}});var t0e={};ur(t0e,{diagram:()=>RWe});var RWe,r0e=N(()=>{"use strict";Upe();Wpe();Ype();e0e();RWe={parser:Vpe,db:YP,renderer:KP,styles:qpe,init:o(t=>{KP.setConf(t.journey),YP.clear()},"init")}});var ZP,c0e,u0e=N(()=>{"use strict";ZP=function(){var t=o(function(p,m,g,y){for(g=g||{},y=p.length;y--;g[p[y]]=m);return g},"o"),e=[6,8,10,11,12,14,16,17,20,21],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,16],u=[1,17],h={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:o(function(m,g,y,v,x,b,T){var S=b.length-1;switch(x){case 1:return b[S-1];case 2:this.$=[];break;case 3:b[S-1].push(b[S]),this.$=b[S-1];break;case 4:case 5:this.$=b[S];break;case 6:case 7:this.$=[];break;case 8:v.getCommonDb().setDiagramTitle(b[S].substr(6)),this.$=b[S].substr(6);break;case 9:this.$=b[S].trim(),v.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=b[S].trim(),v.getCommonDb().setAccDescription(this.$);break;case 12:v.addSection(b[S].substr(8)),this.$=b[S].substr(8);break;case 15:v.addTask(b[S],0,""),this.$=b[S];break;case 16:v.addEvent(b[S].substr(2)),this.$=b[S];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:o(function(m,g){if(g.recoverable)this.trace(m);else{var y=new Error(m);throw y.hash=g,y}},"parseError"),parse:o(function(m){var g=this,y=[0],v=[],x=[null],b=[],T=this.table,S="",w=0,E=0,_=0,C=2,D=1,O=b.slice.call(arguments,1),R=Object.create(this.lexer),k={yy:{}};for(var L in this.yy)Object.prototype.hasOwnProperty.call(this.yy,L)&&(k.yy[L]=this.yy[L]);R.setInput(m,k.yy),k.yy.lexer=R,k.yy.parser=this,typeof R.yylloc>"u"&&(R.yylloc={});var A=R.yylloc;b.push(A);var I=R.options&&R.options.ranges;typeof k.yy.parseError=="function"?this.parseError=k.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function M(j){y.length=y.length-2*j,x.length=x.length-j,b.length=b.length-j}o(M,"popStack");function P(){var j;return j=v.pop()||R.lex()||D,typeof j!="number"&&(j instanceof Array&&(v=j,j=v.pop()),j=g.symbols_[j]||j),j}o(P,"lex");for(var B,F,z,$,U,K,ee={},Y,ce,Z,ue;;){if(z=y[y.length-1],this.defaultActions[z]?$=this.defaultActions[z]:((B===null||typeof B>"u")&&(B=P()),$=T[z]&&T[z][B]),typeof $>"u"||!$.length||!$[0]){var Q="";ue=[];for(Y in T[z])this.terminals_[Y]&&Y>C&&ue.push("'"+this.terminals_[Y]+"'");R.showPosition?Q="Parse error on line "+(w+1)+`: -`+R.showPosition()+` -Expecting `+ue.join(", ")+", got '"+(this.terminals_[B]||B)+"'":Q="Parse error on line "+(w+1)+": Unexpected "+(B==D?"end of input":"'"+(this.terminals_[B]||B)+"'"),this.parseError(Q,{text:R.match,token:this.terminals_[B]||B,line:R.yylineno,loc:A,expected:ue})}if($[0]instanceof Array&&$.length>1)throw new Error("Parse Error: multiple actions possible at state: "+z+", token: "+B);switch($[0]){case 1:y.push(B),x.push(R.yytext),b.push(R.yylloc),y.push($[1]),B=null,F?(B=F,F=null):(E=R.yyleng,S=R.yytext,w=R.yylineno,A=R.yylloc,_>0&&_--);break;case 2:if(ce=this.productions_[$[1]][1],ee.$=x[x.length-ce],ee._$={first_line:b[b.length-(ce||1)].first_line,last_line:b[b.length-1].last_line,first_column:b[b.length-(ce||1)].first_column,last_column:b[b.length-1].last_column},I&&(ee._$.range=[b[b.length-(ce||1)].range[0],b[b.length-1].range[1]]),K=this.performAction.apply(ee,[S,E,w,k.yy,$[1],x,b].concat(O)),typeof K<"u")return K;ce&&(y=y.slice(0,-1*ce*2),x=x.slice(0,-1*ce),b=b.slice(0,-1*ce)),y.push(this.productions_[$[1]][0]),x.push(ee.$),b.push(ee._$),Z=T[y[y.length-2]][y[y.length-1]],y.push(Z);break;case 3:return!0}}return!0},"parse")},f=function(){var p={EOF:1,parseError:o(function(g,y){if(this.yy.parser)this.yy.parser.parseError(g,y);else throw new Error(g)},"parseError"),setInput:o(function(m,g){return this.yy=g||this.yy||{},this._input=m,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var m=this._input[0];this.yytext+=m,this.yyleng++,this.offset++,this.match+=m,this.matched+=m;var g=m.match(/(?:\r\n?|\n).*/g);return g?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),m},"input"),unput:o(function(m){var g=m.length,y=m.split(/(?:\r\n?|\n)/g);this._input=m+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-g),this.offset-=g;var v=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),y.length-1&&(this.yylineno-=y.length-1);var x=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:y?(y.length===v.length?this.yylloc.first_column:0)+v[v.length-y.length].length-y[0].length:this.yylloc.first_column-g},this.options.ranges&&(this.yylloc.range=[x[0],x[0]+this.yyleng-g]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(m){this.unput(this.match.slice(m))},"less"),pastInput:o(function(){var m=this.matched.substr(0,this.matched.length-this.match.length);return(m.length>20?"...":"")+m.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var m=this.match;return m.length<20&&(m+=this._input.substr(0,20-m.length)),(m.substr(0,20)+(m.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var m=this.pastInput(),g=new Array(m.length+1).join("-");return m+this.upcomingInput()+` -`+g+"^"},"showPosition"),test_match:o(function(m,g){var y,v,x;if(this.options.backtrack_lexer&&(x={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(x.yylloc.range=this.yylloc.range.slice(0))),v=m[0].match(/(?:\r\n?|\n).*/g),v&&(this.yylineno+=v.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:v?v[v.length-1].length-v[v.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+m[0].length},this.yytext+=m[0],this.match+=m[0],this.matches=m,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(m[0].length),this.matched+=m[0],y=this.performAction.call(this,this.yy,this,g,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),y)return y;if(this._backtrack){for(var b in x)this[b]=x[b];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var m,g,y,v;this._more||(this.yytext="",this.match="");for(var x=this._currentRules(),b=0;bg[0].length)){if(g=y,v=b,this.options.backtrack_lexer){if(m=this.test_match(y,x[b]),m!==!1)return m;if(this._backtrack){g=!1;continue}else return!1}else if(!this.options.flex)break}return g?(m=this.test_match(g,x[v]),m!==!1?m:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var g=this.next();return g||this.lex()},"lex"),begin:o(function(g){this.conditionStack.push(g)},"begin"),popState:o(function(){var g=this.conditionStack.length-1;return g>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(g){return g=this.conditionStack.length-1-Math.abs(g||0),g>=0?this.conditionStack[g]:"INITIAL"},"topState"),pushState:o(function(g){this.begin(g)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(g,y,v,x){var b=x;switch(v){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^:\n]+)/i,/^(?::\s(?:[^:\n]|:(?!\s))+)/i,/^(?:[^#:\n]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};return p}();h.lexer=f;function d(){this.yy={}}return o(d,"Parser"),d.prototype=h,h.Parser=d,new d}();ZP.parser=ZP;c0e=ZP});var eB={};ur(eB,{addEvent:()=>x0e,addSection:()=>m0e,addTask:()=>v0e,addTaskOrg:()=>b0e,clear:()=>p0e,default:()=>zWe,getCommonDb:()=>d0e,getSections:()=>g0e,getTasks:()=>y0e});var G1,f0e,JP,f6,V1,d0e,p0e,m0e,g0e,y0e,v0e,x0e,b0e,h0e,zWe,T0e=N(()=>{"use strict";ci();G1="",f0e=0,JP=[],f6=[],V1=[],d0e=o(()=>rv,"getCommonDb"),p0e=o(function(){JP.length=0,f6.length=0,G1="",V1.length=0,kr()},"clear"),m0e=o(function(t){G1=t,JP.push(t)},"addSection"),g0e=o(function(){return JP},"getSections"),y0e=o(function(){let t=h0e(),e=100,r=0;for(;!t&&rr.id===f0e-1).events.push(t)},"addEvent"),b0e=o(function(t){let e={section:G1,type:G1,description:t,task:t,classes:[]};f6.push(e)},"addTaskOrg"),h0e=o(function(){let t=o(function(r){return V1[r].processed},"compileTask"),e=!0;for(let[r,n]of V1.entries())t(r),e=e&&n.processed;return e},"compileTasks"),zWe={clear:p0e,getCommonDb:d0e,addSection:m0e,getSections:g0e,getTasks:y0e,addTask:v0e,addTaskOrg:b0e,addEvent:x0e}});function S0e(t,e){t.each(function(){var r=Ge(this),n=r.text().split(/(\s+|
    )/).reverse(),i,a=[],s=1.1,l=r.attr("y"),u=parseFloat(r.attr("dy")),h=r.text(null).append("tspan").attr("x",0).attr("y",l).attr("dy",u+"em");for(let f=0;fe||i==="
    ")&&(a.pop(),h.text(a.join(" ").trim()),i==="
    "?a=[""]:a=[i],h=r.append("tspan").attr("x",0).attr("y",l).attr("dy",s+"em").text(i))})}var GWe,d6,VWe,UWe,k0e,HWe,WWe,w0e,qWe,YWe,XWe,tB,E0e,jWe,KWe,QWe,ZWe,Df,C0e=N(()=>{"use strict";fr();GWe=12,d6=o(function(t,e){let r=t.append("rect");return r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),r.attr("rx",e.rx),r.attr("ry",e.ry),e.class!==void 0&&r.attr("class",e.class),r},"drawRect"),VWe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=Sl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=Sl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),UWe=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),k0e=o(function(t,e){let r=e.text.replace(//gi," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class!==void 0&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),HWe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,k0e(t,e)},"drawLabel"),WWe=o(function(t,e,r){let n=t.append("g"),i=tB();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width,i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,d6(n,i),E0e(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),w0e=-1,qWe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");w0e++;let a=300+5*30;i.append("line").attr("id","task"+w0e).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),VWe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=tB();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,d6(i,s),E0e(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),YWe=o(function(t,e){d6(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()},"drawBackgroundRect"),XWe=o(function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}},"getTextObj"),tB=o(function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),E0e=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(//gi);for(let v=0;v{"use strict";fr();C0e();yt();Gt();xi();JWe=o(function(t,e,r,n){let i=me(),a=i.timeline?.leftMargin??50;X.debug("timeline",n.db);let s=i.securityLevel,l;s==="sandbox"&&(l=Ge("#i"+e));let h=(s==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body")).select("#"+e);h.append("g");let f=n.db.getTasks(),d=n.db.getCommonDb().getDiagramTitle();X.debug("task",f),Df.initGraphics(h);let p=n.db.getSections();X.debug("sections",p);let m=0,g=0,y=0,v=0,x=50+a,b=50;v=50;let T=0,S=!0;p.forEach(function(D){let O={number:T,descr:D,section:T,width:150,padding:20,maxHeight:m},R=Df.getVirtualNodeHeight(h,O,i);X.debug("sectionHeight before draw",R),m=Math.max(m,R+20)});let w=0,E=0;X.debug("tasks.length",f.length);for(let[D,O]of f.entries()){let R={number:D,descr:O,section:O.section,width:150,padding:20,maxHeight:g},k=Df.getVirtualNodeHeight(h,R,i);X.debug("taskHeight before draw",k),g=Math.max(g,k+20),w=Math.max(w,O.events.length);let L=0;for(let A of O.events){let I={descr:A,section:O.section,number:O.section,width:150,padding:20,maxHeight:50};L+=Df.getVirtualNodeHeight(h,I,i)}O.events.length>0&&(L+=(O.events.length-1)*10),E=Math.max(E,L)}X.debug("maxSectionHeight before draw",m),X.debug("maxTaskHeight before draw",g),p&&p.length>0?p.forEach(D=>{let O=f.filter(A=>A.section===D),R={number:T,descr:D,section:T,width:200*Math.max(O.length,1)-50,padding:20,maxHeight:m};X.debug("sectionNode",R);let k=h.append("g"),L=Df.drawNode(k,R,T,i);X.debug("sectionNode output",L),k.attr("transform",`translate(${x}, ${v})`),b+=m+50,O.length>0&&A0e(h,O,T,x,b,g,i,w,E,m,!1),x+=200*Math.max(O.length,1),b=v,T++}):(S=!1,A0e(h,f,T,x,b,g,i,w,E,m,!0));let _=h.node().getBBox();X.debug("bounds",_),d&&h.append("text").text(d).attr("x",_.width/2-a).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),y=S?m+g+150:g+100,h.append("g").attr("class","lineWrapper").append("line").attr("x1",a).attr("y1",y).attr("x2",_.width+3*a).attr("y2",y).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),Lo(void 0,h,i.timeline?.padding??50,i.timeline?.useMaxWidth??!1)},"draw"),A0e=o(function(t,e,r,n,i,a,s,l,u,h,f){for(let d of e){let p={descr:d.task,section:r,number:r,width:150,padding:20,maxHeight:a};X.debug("taskNode",p);let m=t.append("g").attr("class","taskWrapper"),y=Df.drawNode(m,p,r,s).height;if(X.debug("taskHeight after draw",y),m.attr("transform",`translate(${n}, ${i})`),a=Math.max(a,y),d.events){let v=t.append("g").attr("class","lineWrapper"),x=a;i+=100,x=x+eqe(t,d.events,r,n,i,s),i-=100,v.append("line").attr("x1",n+190/2).attr("y1",i+a).attr("x2",n+190/2).attr("y2",i+a+100+u+100).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}n=n+200,f&&!s.timeline?.disableMulticolor&&r++}i=i-10},"drawTasks"),eqe=o(function(t,e,r,n,i,a){let s=0,l=i;i=i+100;for(let u of e){let h={descr:u,section:r,number:r,width:150,padding:20,maxHeight:50};X.debug("eventNode",h);let f=t.append("g").attr("class","eventWrapper"),p=Df.drawNode(f,h,r,a).height;s=s+p,f.attr("transform",`translate(${n}, ${i})`),i=i+10+p}return i=l,s},"drawEvents"),_0e={setConf:o(()=>{},"setConf"),draw:JWe}});var tqe,rqe,L0e,R0e=N(()=>{"use strict";Ks();tqe=o(t=>{let e="";for(let r=0;r` - .edge { - stroke-width: 3; - } - ${tqe(t)} - .section-root rect, .section-root path, .section-root circle { - fill: ${t.git0}; - } - .section-root text { - fill: ${t.gitBranchLabel0}; - } - .icon-container { - height:100%; - display: flex; - justify-content: center; - align-items: center; - } - .edge { - fill: none; - } - .eventWrapper { - filter: brightness(120%); - } -`,"getStyles"),L0e=rqe});var N0e={};ur(N0e,{diagram:()=>nqe});var nqe,M0e=N(()=>{"use strict";u0e();T0e();D0e();R0e();nqe={db:eB,renderer:_0e,parser:c0e,styles:L0e}});var rB,P0e,B0e=N(()=>{"use strict";rB=function(){var t=o(function(S,w,E,_){for(E=E||{},_=S.length;_--;E[S[_]]=w);return E},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,6,13,15,16,19,22],g=[1,33],y=[1,34],v=[1,6,7,11,13,15,16,19,22],x={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:o(function(w,E,_,C,D,O,R){var k=O.length-1;switch(D){case 6:case 7:return C;case 8:C.getLogger().trace("Stop NL ");break;case 9:C.getLogger().trace("Stop EOF ");break;case 11:C.getLogger().trace("Stop NL2 ");break;case 12:C.getLogger().trace("Stop EOF2 ");break;case 15:C.getLogger().info("Node: ",O[k].id),C.addNode(O[k-1].length,O[k].id,O[k].descr,O[k].type);break;case 16:C.getLogger().trace("Icon: ",O[k]),C.decorateNode({icon:O[k]});break;case 17:case 21:C.decorateNode({class:O[k]});break;case 18:C.getLogger().trace("SPACELIST");break;case 19:C.getLogger().trace("Node: ",O[k].id),C.addNode(0,O[k].id,O[k].descr,O[k].type);break;case 20:C.decorateNode({icon:O[k]});break;case 25:C.getLogger().trace("node found ..",O[k-2]),this.$={id:O[k-1],descr:O[k-1],type:C.getType(O[k-2],O[k])};break;case 26:this.$={id:O[k],descr:O[k],type:C.nodeType.DEFAULT};break;case 27:C.getLogger().trace("node found ..",O[k-3]),this.$={id:O[k-3],descr:O[k-1],type:C.getType(O[k-2],O[k])};break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:r,9:22,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:h,7:f,10:23,11:d},t(p,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:s,22:l}),t(p,[2,18]),t(p,[2,19]),t(p,[2,20]),t(p,[2,21]),t(p,[2,23]),t(p,[2,24]),t(p,[2,26],{19:[1,30]}),{20:[1,31]},{6:h,7:f,10:32,11:d},{1:[2,7],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(m,[2,14],{7:g,11:y}),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(p,[2,15]),t(p,[2,16]),t(p,[2,17]),{20:[1,35]},{21:[1,36]},t(m,[2,13],{7:g,11:y}),t(v,[2,11]),t(v,[2,12]),{21:[1,37]},t(p,[2,25]),t(p,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(w,E){if(E.recoverable)this.trace(w);else{var _=new Error(w);throw _.hash=E,_}},"parseError"),parse:o(function(w){var E=this,_=[0],C=[],D=[null],O=[],R=this.table,k="",L=0,A=0,I=0,M=2,P=1,B=O.slice.call(arguments,1),F=Object.create(this.lexer),z={yy:{}};for(var $ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,$)&&(z.yy[$]=this.yy[$]);F.setInput(w,z.yy),z.yy.lexer=F,z.yy.parser=this,typeof F.yylloc>"u"&&(F.yylloc={});var U=F.yylloc;O.push(U);var K=F.options&&F.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ee(ae){_.length=_.length-2*ae,D.length=D.length-ae,O.length=O.length-ae}o(ee,"popStack");function Y(){var ae;return ae=C.pop()||F.lex()||P,typeof ae!="number"&&(ae instanceof Array&&(C=ae,ae=C.pop()),ae=E.symbols_[ae]||ae),ae}o(Y,"lex");for(var ce,Z,ue,Q,j,ne,te={},he,le,J,Se;;){if(ue=_[_.length-1],this.defaultActions[ue]?Q=this.defaultActions[ue]:((ce===null||typeof ce>"u")&&(ce=Y()),Q=R[ue]&&R[ue][ce]),typeof Q>"u"||!Q.length||!Q[0]){var se="";Se=[];for(he in R[ue])this.terminals_[he]&&he>M&&Se.push("'"+this.terminals_[he]+"'");F.showPosition?se="Parse error on line "+(L+1)+`: -`+F.showPosition()+` -Expecting `+Se.join(", ")+", got '"+(this.terminals_[ce]||ce)+"'":se="Parse error on line "+(L+1)+": Unexpected "+(ce==P?"end of input":"'"+(this.terminals_[ce]||ce)+"'"),this.parseError(se,{text:F.match,token:this.terminals_[ce]||ce,line:F.yylineno,loc:U,expected:Se})}if(Q[0]instanceof Array&&Q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ue+", token: "+ce);switch(Q[0]){case 1:_.push(ce),D.push(F.yytext),O.push(F.yylloc),_.push(Q[1]),ce=null,Z?(ce=Z,Z=null):(A=F.yyleng,k=F.yytext,L=F.yylineno,U=F.yylloc,I>0&&I--);break;case 2:if(le=this.productions_[Q[1]][1],te.$=D[D.length-le],te._$={first_line:O[O.length-(le||1)].first_line,last_line:O[O.length-1].last_line,first_column:O[O.length-(le||1)].first_column,last_column:O[O.length-1].last_column},K&&(te._$.range=[O[O.length-(le||1)].range[0],O[O.length-1].range[1]]),ne=this.performAction.apply(te,[k,A,L,z.yy,Q[1],D,O].concat(B)),typeof ne<"u")return ne;le&&(_=_.slice(0,-1*le*2),D=D.slice(0,-1*le),O=O.slice(0,-1*le)),_.push(this.productions_[Q[1]][0]),D.push(te.$),O.push(te._$),J=R[_[_.length-2]][_[_.length-1]],_.push(J);break;case 3:return!0}}return!0},"parse")},b=function(){var S={EOF:1,parseError:o(function(E,_){if(this.yy.parser)this.yy.parser.parseError(E,_);else throw new Error(E)},"parseError"),setInput:o(function(w,E){return this.yy=E||this.yy||{},this._input=w,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var w=this._input[0];this.yytext+=w,this.yyleng++,this.offset++,this.match+=w,this.matched+=w;var E=w.match(/(?:\r\n?|\n).*/g);return E?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),w},"input"),unput:o(function(w){var E=w.length,_=w.split(/(?:\r\n?|\n)/g);this._input=w+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-E),this.offset-=E;var C=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),_.length-1&&(this.yylineno-=_.length-1);var D=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:_?(_.length===C.length?this.yylloc.first_column:0)+C[C.length-_.length].length-_[0].length:this.yylloc.first_column-E},this.options.ranges&&(this.yylloc.range=[D[0],D[0]+this.yyleng-E]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(w){this.unput(this.match.slice(w))},"less"),pastInput:o(function(){var w=this.matched.substr(0,this.matched.length-this.match.length);return(w.length>20?"...":"")+w.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var w=this.match;return w.length<20&&(w+=this._input.substr(0,20-w.length)),(w.substr(0,20)+(w.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var w=this.pastInput(),E=new Array(w.length+1).join("-");return w+this.upcomingInput()+` -`+E+"^"},"showPosition"),test_match:o(function(w,E){var _,C,D;if(this.options.backtrack_lexer&&(D={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(D.yylloc.range=this.yylloc.range.slice(0))),C=w[0].match(/(?:\r\n?|\n).*/g),C&&(this.yylineno+=C.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:C?C[C.length-1].length-C[C.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+w[0].length},this.yytext+=w[0],this.match+=w[0],this.matches=w,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(w[0].length),this.matched+=w[0],_=this.performAction.call(this,this.yy,this,E,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),_)return _;if(this._backtrack){for(var O in D)this[O]=D[O];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var w,E,_,C;this._more||(this.yytext="",this.match="");for(var D=this._currentRules(),O=0;OE[0].length)){if(E=_,C=O,this.options.backtrack_lexer){if(w=this.test_match(_,D[O]),w!==!1)return w;if(this._backtrack){E=!1;continue}else return!1}else if(!this.options.flex)break}return E?(w=this.test_match(E,D[C]),w!==!1?w:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var E=this.next();return E||this.lex()},"lex"),begin:o(function(E){this.conditionStack.push(E)},"begin"),popState:o(function(){var E=this.conditionStack.length-1;return E>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(E){return E=this.conditionStack.length-1-Math.abs(E||0),E>=0?this.conditionStack[E]:"INITIAL"},"topState"),pushState:o(function(E){this.begin(E)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(E,_,C,D){var O=D;switch(C){case 0:return E.getLogger().trace("Found comment",_.yytext),6;break;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;break;case 4:this.popState();break;case 5:E.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return E.getLogger().trace("SPACELINE"),6;break;case 7:return 7;case 8:return 15;case 9:E.getLogger().trace("end icon"),this.popState();break;case 10:return E.getLogger().trace("Exploding node"),this.begin("NODE"),19;break;case 11:return E.getLogger().trace("Cloud"),this.begin("NODE"),19;break;case 12:return E.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;break;case 13:return E.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;break;case 14:return this.begin("NODE"),19;break;case 15:return this.begin("NODE"),19;break;case 16:return this.begin("NODE"),19;break;case 17:return this.begin("NODE"),19;break;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 23:this.popState();break;case 24:E.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return E.getLogger().trace("description:",_.yytext),"NODE_DESCR";break;case 26:this.popState();break;case 27:return this.popState(),E.getLogger().trace("node end ))"),"NODE_DEND";break;case 28:return this.popState(),E.getLogger().trace("node end )"),"NODE_DEND";break;case 29:return this.popState(),E.getLogger().trace("node end ...",_.yytext),"NODE_DEND";break;case 30:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 31:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 32:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 33:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 34:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 35:return E.getLogger().trace("Long description:",_.yytext),20;break;case 36:return E.getLogger().trace("Long description:",_.yytext),20;break}},"anonymous"),rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};return S}();x.lexer=b;function T(){this.yy={}}return o(T,"Parser"),T.prototype=x,x.Parser=T,new T}();rB.parser=rB;P0e=rB});var oqe,p6,F0e=N(()=>{"use strict";Gt();pr();yt();_a();oqe={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},p6=class{constructor(){this.nodes=[];this.count=0;this.elements={};this.getLogger=this.getLogger.bind(this),this.nodeType=oqe,this.clear(),this.getType=this.getType.bind(this),this.getMindmap=this.getMindmap.bind(this),this.getElementById=this.getElementById.bind(this),this.getParent=this.getParent.bind(this),this.getMindmap=this.getMindmap.bind(this),this.addNode=this.addNode.bind(this),this.decorateNode=this.decorateNode.bind(this)}static{o(this,"MindmapDB")}clear(){this.nodes=[],this.count=0,this.elements={}}getParent(e){for(let r=this.nodes.length-1;r>=0;r--)if(this.nodes[r].level0?this.nodes[0]:null}addNode(e,r,n,i){X.info("addNode",e,r,n,i);let a=me(),s=a.mindmap?.padding??or.mindmap.padding;switch(i){case this.nodeType.ROUNDED_RECT:case this.nodeType.RECT:case this.nodeType.HEXAGON:s*=2;break}let l={id:this.count++,nodeId:wr(r,a),level:e,descr:wr(n,a),type:i,children:[],width:a.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:s},u=this.getParent(e);if(u)u.children.push(l),this.nodes.push(l);else if(this.nodes.length===0)this.nodes.push(l);else throw new Error(`There can be only one root. No parent could be found for ("${l.descr}")`)}getType(e,r){switch(X.debug("In get type",e,r),e){case"[":return this.nodeType.RECT;case"(":return r===")"?this.nodeType.ROUNDED_RECT:this.nodeType.CLOUD;case"((":return this.nodeType.CIRCLE;case")":return this.nodeType.CLOUD;case"))":return this.nodeType.BANG;case"{{":return this.nodeType.HEXAGON;default:return this.nodeType.DEFAULT}}setElementForId(e,r){this.elements[e]=r}getElementById(e){return this.elements[e]}decorateNode(e){if(!e)return;let r=me(),n=this.nodes[this.nodes.length-1];e.icon&&(n.icon=wr(e.icon,r)),e.class&&(n.class=wr(e.class,r))}type2Str(e){switch(e){case this.nodeType.DEFAULT:return"no-border";case this.nodeType.RECT:return"rect";case this.nodeType.ROUNDED_RECT:return"rounded-rect";case this.nodeType.CIRCLE:return"circle";case this.nodeType.CLOUD:return"cloud";case this.nodeType.BANG:return"bang";case this.nodeType.HEXAGON:return"hexgon";default:return"no-border"}}getLogger(){return X}}});function qi(t){"@babel/helpers - typeof";return qi=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},qi(t)}function Vf(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function $0e(t,e){for(var r=0;rt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[n++]}},"n"),e:o(function(u){throw u},"e"),f:i}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var a=!0,s=!1,l;return{s:o(function(){r=r.call(t)},"s"),n:o(function(){var u=r.next();return a=u.done,u},"n"),e:o(function(u){s=!0,l=u},"e"),f:o(function(){try{!a&&r.return!=null&&r.return()}finally{if(s)throw l}},"f")}}function Pqe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}function Bqe(t,e){return e={exports:{}},t(e,e.exports),e.exports}function Hqe(t){for(var e=t.length;e--&&Uqe.test(t.charAt(e)););return e}function Yqe(t){return t&&t.slice(0,Wqe(t)+1).replace(qqe,"")}function Zqe(t){var e=Kqe.call(t,Fb),r=t[Fb];try{t[Fb]=void 0;var n=!0}catch{}var i=Qqe.call(t);return n&&(e?t[Fb]=r:delete t[Fb]),i}function rYe(t){return tYe.call(t)}function sYe(t){return t==null?t===void 0?aYe:iYe:V0e&&V0e in Object(t)?Jqe(t):nYe(t)}function oYe(t){return t!=null&&typeof t=="object"}function uYe(t){return typeof t=="symbol"||lYe(t)&&mge(t)==cYe}function mYe(t){if(typeof t=="number")return t;if(d4(t))return U0e;if(Kp(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=Kp(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=Xqe(t);var r=fYe.test(t);return r||dYe.test(t)?pYe(t.slice(2),r?2:8):hYe.test(t)?U0e:+t}function xYe(t,e,r){var n,i,a,s,l,u,h=0,f=!1,d=!1,p=!0;if(typeof t!="function")throw new TypeError(gYe);e=H0e(e)||0,Kp(r)&&(f=!!r.leading,d="maxWait"in r,a=d?yYe(H0e(r.maxWait)||0,e):a,p="trailing"in r?!!r.trailing:p);function m(E){var _=n,C=i;return n=i=void 0,h=E,s=t.apply(C,_),s}o(m,"invokeFunc");function g(E){return h=E,l=setTimeout(x,e),f?m(E):s}o(g,"leadingEdge");function y(E){var _=E-u,C=E-h,D=e-_;return d?vYe(D,a-C):D}o(y,"remainingWait");function v(E){var _=E-u,C=E-h;return u===void 0||_>=e||_<0||d&&C>=a}o(v,"shouldInvoke");function x(){var E=nB();if(v(E))return b(E);l=setTimeout(x,y(E))}o(x,"timerExpired");function b(E){return l=void 0,p&&n?m(E):(n=i=void 0,s)}o(b,"trailingEdge");function T(){l!==void 0&&clearTimeout(l),h=0,n=u=i=l=void 0}o(T,"cancel");function S(){return l===void 0?s:b(nB())}o(S,"flush");function w(){var E=nB(),_=v(E);if(n=arguments,i=this,u=E,_){if(l===void 0)return g(u);if(d)return clearTimeout(l),l=setTimeout(x,e),m(u)}return l===void 0&&(l=setTimeout(x,e)),s}return o(w,"debounced"),w.cancel=T,w.flush=S,w}function eC(t,e,r,n,i,a){var s;return li(t)?s=t:s=ny[t]||ny.euclidean,e===0&&li(t)?s(i,a):s(e,r,n,i,a)}function hje(t,e){if(tC(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||d4(t)?!0:uje.test(t)||!cje.test(t)||e!=null&&t in Object(e)}function yje(t){if(!Kp(t))return!1;var e=mge(t);return e==pje||e==mje||e==dje||e==gje}function bje(t){return!!ume&&ume in t}function Eje(t){if(t!=null){try{return kje.call(t)}catch{}try{return t+""}catch{}}return""}function Mje(t){if(!Kp(t)||Tje(t))return!1;var e=vje(t)?Nje:Aje;return e.test(Sje(t))}function Oje(t,e){return t?.[e]}function Bje(t,e){var r=Pje(t,e);return Ije(r)?r:void 0}function $je(){this.__data__=s4?s4(null):{},this.size=0}function Gje(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}function qje(t){var e=this.__data__;if(s4){var r=e[t];return r===Uje?void 0:r}return Wje.call(e,t)?e[t]:void 0}function Kje(t){var e=this.__data__;return s4?e[t]!==void 0:jje.call(e,t)}function Jje(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=s4&&e===void 0?Zje:e,this}function oy(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1}function dKe(t,e){var r=this.__data__,n=rC(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}function ly(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1&&t%1==0&&t0;){var f=i.shift();e(f),a.add(f.id()),l&&n(i,a,f)}return t}function Xge(t,e,r){if(r.isParent())for(var n=r._private.children,i=0;i0&&arguments[0]!==void 0?arguments[0]:QQe,e=arguments.length>1?arguments[1]:void 0,r=0;r0?k=A:R=A;while(Math.abs(L)>s&&++I=a?b(O,I):M===0?I:S(O,R,R+h)}o(w,"getTForX");var E=!1;function _(){E=!0,(t!==e||r!==n)&&T()}o(_,"precompute");var C=o(function(R){return E||_(),t===e&&r===n?R:R===0?0:R===1?1:v(w(R),e,n)},"f");C.getControlPoints=function(){return[{x:t,y:e},{x:r,y:n}]};var D="generateBezier("+[t,e,r,n]+")";return C.toString=function(){return D},C}function Dme(t,e,r,n,i){if(n===1||e===r)return r;var a=i(e,r,n);return t==null||((t.roundValue||t.color)&&(a=Math.round(a)),t.min!==void 0&&(a=Math.max(a,t.min)),t.max!==void 0&&(a=Math.min(a,t.max))),a}function Lme(t,e){return t.pfValue!=null||t.value!=null?t.pfValue!=null&&(e==null||e.type.units!=="%")?t.pfValue:t.value:t}function W1(t,e,r,n,i){var a=i!=null?i.type:null;r<0?r=0:r>1&&(r=1);var s=Lme(t,i),l=Lme(e,i);if(_t(s)&&_t(l))return Dme(a,s,l,r,n);if(En(s)&&En(l)){for(var u=[],h=0;h0?(m==="spring"&&g.push(s.duration),s.easingImpl=M6[m].apply(null,g)):s.easingImpl=M6[m]}var y=s.easingImpl,v;if(s.duration===0?v=1:v=(r-u)/s.duration,s.applying&&(v=s.progress),v<0?v=0:v>1&&(v=1),s.delay==null){var x=s.startPosition,b=s.position;if(b&&i&&!t.locked()){var T={};Vb(x.x,b.x)&&(T.x=W1(x.x,b.x,v,y)),Vb(x.y,b.y)&&(T.y=W1(x.y,b.y,v,y)),t.position(T)}var S=s.startPan,w=s.pan,E=a.pan,_=w!=null&&n;_&&(Vb(S.x,w.x)&&(E.x=W1(S.x,w.x,v,y)),Vb(S.y,w.y)&&(E.y=W1(S.y,w.y,v,y)),t.emit("pan"));var C=s.startZoom,D=s.zoom,O=D!=null&&n;O&&(Vb(C,D)&&(a.zoom=i4(a.minZoom,W1(C,D,v,y),a.maxZoom)),t.emit("zoom")),(_||O)&&t.emit("viewport");var R=s.style;if(R&&R.length>0&&i){for(var k=0;k=0;_--){var C=E[_];C()}E.splice(0,E.length)},"callbacks"),b=m.length-1;b>=0;b--){var T=m[b],S=T._private;if(S.stopped){m.splice(b,1),S.hooked=!1,S.playing=!1,S.started=!1,x(S.frames);continue}!S.playing&&!S.applying||(S.playing&&S.applying&&(S.applying=!1),S.started||hZe(f,T,t),uZe(f,T,t,d),S.applying&&(S.applying=!1),x(S.frames),S.step!=null&&S.step(t),T.completed()&&(m.splice(b,1),S.hooked=!1,S.playing=!1,S.started=!1,x(S.completes)),y=!0)}return!d&&m.length===0&&g.length===0&&n.push(f),y}o(i,"stepOne");for(var a=!1,s=0;s0?e.notify("draw",r):e.notify("draw")),r.unmerge(n),e.emit("step")}function h1e(t){this.options=ir({},xZe,bZe,t)}function f1e(t){this.options=ir({},TZe,t)}function d1e(t){this.options=ir({},wZe,t)}function uC(t){this.options=ir({},kZe,t),this.options.layout=this;var e=this.options.eles.nodes(),r=this.options.eles.edges(),n=r.filter(function(i){var a=i.source().data("id"),s=i.target().data("id"),l=e.some(function(h){return h.data("id")===a}),u=e.some(function(h){return h.data("id")===s});return!l||!u});this.options.eles=this.options.eles.not(n)}function m1e(t){this.options=ir({},zZe,t)}function eF(t){this.options=ir({},GZe,t)}function g1e(t){this.options=ir({},VZe,t)}function y1e(t){this.options=ir({},UZe,t)}function v1e(t){this.options=t,this.notifications=0}function T1e(t,e){e.radius===0?t.lineTo(e.cx,e.cy):t.arc(e.cx,e.cy,e.radius,e.startAngle,e.endAngle,e.counterClockwise)}function rF(t,e,r,n){var i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0;return n===0||e.radius===0?{cx:e.x,cy:e.y,radius:0,startX:e.x,startY:e.y,stopX:e.x,stopY:e.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(qZe(t,e,r,n,i),{cx:_B,cy:DB,radius:Yp,startX:x1e,startY:b1e,stopX:LB,stopY:RB,startAngle:Kc.ang+Math.PI/2*Xp,endAngle:nl.ang-Math.PI/2*Xp,counterClockwise:P6})}function w1e(t){var e=[];if(t!=null){for(var r=0;r5&&arguments[5]!==void 0?arguments[5]:5,s=arguments.length>6?arguments[6]:void 0;t.beginPath(),t.moveTo(e+a,r),t.lineTo(e+n-a,r),t.quadraticCurveTo(e+n,r,e+n,r+a),t.lineTo(e+n,r+i-a),t.quadraticCurveTo(e+n,r+i,e+n-a,r+i),t.lineTo(e+a,r+i),t.quadraticCurveTo(e,r+i,e,r+i-a),t.lineTo(e,r+a),t.quadraticCurveTo(e,r,e+a,r),t.closePath(),s?t.stroke():t.fill()}function Kme(t,e,r){var n=t.createShader(e);if(t.shaderSource(n,r),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(n));return n}function MJe(t,e,r){var n=Kme(t,t.VERTEX_SHADER,e),i=Kme(t,t.FRAGMENT_SHADER,r),a=t.createProgram();if(t.attachShader(a,n),t.attachShader(a,i),t.linkProgram(a),!t.getProgramParameter(a,t.LINK_STATUS))throw new Error("Could not initialize shaders");return a}function IJe(t,e,r){r===void 0&&(r=e);var n=t.makeOffscreenCanvas(e,r),i=n.context=n.getContext("2d");return n.clear=function(){return i.clearRect(0,0,n.width,n.height)},n.clear(),n}function aF(t){var e=t.pixelRatio,r=t.cy.zoom(),n=t.cy.pan();return{zoom:r*e,pan:{x:n.x*e,y:n.y*e}}}function gB(t,e,r,n,i){var a=n*r+e.x,s=i*r+e.y;return s=Math.round(t.canvasHeight-s),[a,s]}function A6(t,e,r){var n=t[0]/255,i=t[1]/255,a=t[2]/255,s=e,l=r||new Array(4);return l[0]=n*s,l[1]=i*s,l[2]=a*s,l[3]=s,l}function _6(t,e){var r=e||new Array(4);return r[0]=(t>>0&255)/255,r[1]=(t>>8&255)/255,r[2]=(t>>16&255)/255,r[3]=(t>>24&255)/255,r}function OJe(t){return t[0]+(t[1]<<8)+(t[2]<<16)+(t[3]<<24)}function PJe(t,e){var r=t.createTexture();return r.buffer=function(n){t.bindTexture(t.TEXTURE_2D,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR_MIPMAP_NEAREST),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n),t.generateMipmap(t.TEXTURE_2D),t.bindTexture(t.TEXTURE_2D,null)},r.deleteTexture=function(){t.deleteTexture(r)},r}function O1e(t,e){switch(e){case"float":return[1,t.FLOAT,4];case"vec2":return[2,t.FLOAT,4];case"vec3":return[3,t.FLOAT,4];case"vec4":return[4,t.FLOAT,4];case"int":return[1,t.INT,4];case"ivec2":return[2,t.INT,4]}}function P1e(t,e,r){switch(e){case t.FLOAT:return new Float32Array(r);case t.INT:return new Int32Array(r)}}function BJe(t,e,r,n,i,a){switch(e){case t.FLOAT:return new Float32Array(r.buffer,a*n,i);case t.INT:return new Int32Array(r.buffer,a*n,i)}}function FJe(t,e,r,n){var i=O1e(t,e),a=Ri(i,2),s=a[0],l=a[1],u=P1e(t,l,n),h=t.createBuffer();return t.bindBuffer(t.ARRAY_BUFFER,h),t.bufferData(t.ARRAY_BUFFER,u,t.STATIC_DRAW),l===t.FLOAT?t.vertexAttribPointer(r,s,l,!1,0,0):l===t.INT&&t.vertexAttribIPointer(r,s,l,0,0),t.enableVertexAttribArray(r),t.bindBuffer(t.ARRAY_BUFFER,null),h}function yo(t,e,r,n){var i=O1e(t,r),a=Ri(i,3),s=a[0],l=a[1],u=a[2],h=P1e(t,l,e*s),f=s*u,d=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,d),t.bufferData(t.ARRAY_BUFFER,e*f,t.DYNAMIC_DRAW),t.enableVertexAttribArray(n),l===t.FLOAT?t.vertexAttribPointer(n,s,l,!1,f,0):l===t.INT&&t.vertexAttribIPointer(n,s,l,f,0),t.vertexAttribDivisor(n,1),t.bindBuffer(t.ARRAY_BUFFER,null);for(var p=new Array(e),m=0;mL1e?(KJe(t),e.call(t,a)):(QJe(t),G1e(t,a,Jb.SCREEN)))}}{var r=t.matchCanvasSize;t.matchCanvasSize=function(a){r.call(t,a),t.pickingFrameBuffer.setFramebufferAttachmentSizes(t.canvasWidth,t.canvasHeight),t.pickingFrameBuffer.needsDraw=!0}}t.findNearestElements=function(a,s,l,u){return net(t,a,s)};{var n=t.invalidateCachedZSortedEles;t.invalidateCachedZSortedEles=function(){n.call(t),t.pickingFrameBuffer.needsDraw=!0}}{var i=t.notify;t.notify=function(a,s){i.call(t,a,s),a==="viewport"||a==="bounds"?t.pickingFrameBuffer.needsDraw=!0:a==="background"&&t.eleDrawing.invalidate(s,{type:"node-body"})}}}function KJe(t){var e=t.data.contexts[t.WEBGL];e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}function QJe(t){var e=o(function(n){n.save(),n.setTransform(1,0,0,1,0,0),n.clearRect(0,0,t.canvasWidth,t.canvasHeight),n.restore()},"clear");e(t.data.contexts[t.NODE]),e(t.data.contexts[t.DRAG])}function ZJe(t){var e=t.canvasWidth,r=t.canvasHeight,n=aF(t),i=n.pan,a=n.zoom,s=Zb();j6(s,s,[i.x,i.y]),sF(s,s,[a,a]);var l=Zb();GJe(l,e,r);var u=Zb();return zJe(u,l,s),u}function z1e(t,e){var r=t.canvasWidth,n=t.canvasHeight,i=aF(t),a=i.pan,s=i.zoom;e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,r,n),e.translate(a.x,a.y),e.scale(s,s)}function JJe(t,e){t.drawSelectionRectangle(e,function(r){return z1e(t,r)})}function eet(t){var e=t.data.contexts[t.NODE];e.save(),z1e(t,e),e.strokeStyle="rgba(0, 0, 0, 0.3)",e.beginPath(),e.moveTo(-1e3,0),e.lineTo(1e3,0),e.stroke(),e.beginPath(),e.moveTo(0,-1e3),e.lineTo(0,1e3),e.stroke(),e.restore()}function tet(t){var e=o(function(i,a,s){for(var l=i.atlasManager.getRenderTypeOpts(a),u=t.data.contexts[t.NODE],h=.125,f=l.atlasCollection.atlases,d=0;d=0&&k.add(I)}return k}function net(t,e,r){var n=ret(t,e,r),i=t.getCachedZSortedEles(),a,s,l=vo(n),u;try{for(l.s();!(u=l.n()).done;){var h=u.value,f=i[h];if(!a&&f.isNode()&&(a=f),!s&&f.isEdge()&&(s=f),a&&s)break}}catch(d){l.e(d)}finally{l.f()}return[a,s].filter(Boolean)}function G1e(t,e,r){var n,i;t.webglDebug&&(i=[],n=performance.now());var a=t.eleDrawing,s=0;if(r.screen&&t.data.canvasNeedsRedraw[t.SELECT_BOX]&&JJe(t,e),t.data.canvasNeedsRedraw[t.NODE]||r.picking){var l=o(function(k,L){L+=1,k.isNode()?(a.drawTexture(k,L,"node-underlay"),a.drawTexture(k,L,"node-body"),a.drawTexture(k,L,"node-label"),a.drawTexture(k,L,"node-overlay")):(a.drawEdgeLine(k,L),a.drawEdgeArrow(k,L,"source"),a.drawEdgeArrow(k,L,"target"),a.drawTexture(k,L,"edge-label"))},"draw"),u=t.data.contexts[t.WEBGL];r.screen?(u.clearColor(0,0,0,0),u.enable(u.BLEND),u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA)):u.disable(u.BLEND),u.clear(u.COLOR_BUFFER_BIT|u.DEPTH_BUFFER_BIT),u.viewport(0,0,u.canvas.width,u.canvas.height);var h=ZJe(t),f=t.getCachedZSortedEles();if(s=f.length,a.startFrame(h,i,r),r.screen){for(var d=0;d{"use strict";o(qi,"_typeof");o(Vf,"_classCallCheck");o($0e,"_defineProperties");o(Uf,"_createClass");o(ige,"_defineProperty$1");o(Ri,"_slicedToArray");o(age,"_toConsumableArray");o(lqe,"_arrayWithoutHoles");o(cqe,"_arrayWithHoles");o(uqe,"_iterableToArray");o(hqe,"_iterableToArrayLimit");o(PB,"_unsupportedIterableToArray");o(xB,"_arrayLikeToArray");o(fqe,"_nonIterableSpread");o(dqe,"_nonIterableRest");o(vo,"_createForOfIteratorHelper");Hi=typeof window>"u"?null:window,z0e=Hi?Hi.navigator:null;Hi&&Hi.document;pqe=qi(""),sge=qi({}),mqe=qi(function(){}),gqe=typeof HTMLElement>"u"?"undefined":qi(HTMLElement),h4=o(function(e){return e&&e.instanceString&&li(e.instanceString)?e.instanceString():null},"instanceStr"),Zt=o(function(e){return e!=null&&qi(e)==pqe},"string"),li=o(function(e){return e!=null&&qi(e)===mqe},"fn"),En=o(function(e){return!xo(e)&&(Array.isArray?Array.isArray(e):e!=null&&e instanceof Array)},"array"),Ur=o(function(e){return e!=null&&qi(e)===sge&&!En(e)&&e.constructor===Object},"plainObject"),yqe=o(function(e){return e!=null&&qi(e)===sge},"object"),_t=o(function(e){return e!=null&&qi(e)===qi(1)&&!isNaN(e)},"number"),vqe=o(function(e){return _t(e)&&Math.floor(e)===e},"integer"),F6=o(function(e){if(gqe!=="undefined")return e!=null&&e instanceof HTMLElement},"htmlElement"),xo=o(function(e){return f4(e)||oge(e)},"elementOrCollection"),f4=o(function(e){return h4(e)==="collection"&&e._private.single},"element"),oge=o(function(e){return h4(e)==="collection"&&!e._private.single},"collection"),BB=o(function(e){return h4(e)==="core"},"core"),lge=o(function(e){return h4(e)==="stylesheet"},"stylesheet"),xqe=o(function(e){return h4(e)==="event"},"event"),Pf=o(function(e){return e==null?!0:!!(e===""||e.match(/^\s+$/))},"emptyString"),bqe=o(function(e){return typeof HTMLElement>"u"?!1:e instanceof HTMLElement},"domElement"),Tqe=o(function(e){return Ur(e)&&_t(e.x1)&&_t(e.x2)&&_t(e.y1)&&_t(e.y2)},"boundingBox"),wqe=o(function(e){return yqe(e)&&li(e.then)},"promise"),kqe=o(function(){return z0e&&z0e.userAgent.match(/msie|trident|edge/i)},"ms"),e4=o(function(e,r){r||(r=o(function(){if(arguments.length===1)return arguments[0];if(arguments.length===0)return"undefined";for(var a=[],s=0;sr?1:0},"ascending"),Lqe=o(function(e,r){return-1*uge(e,r)},"descending"),ir=Object.assign!=null?Object.assign.bind(Object):function(t){for(var e=arguments,r=1;r1&&(v-=1),v<1/6?g+(y-g)*6*v:v<1/2?y:v<2/3?g+(y-g)*(2/3-v)*6:g}o(f,"hue2rgb");var d=new RegExp("^"+Cqe+"$").exec(e);if(d){if(n=parseInt(d[1]),n<0?n=(360- -1*n%360)%360:n>360&&(n=n%360),n/=360,i=parseFloat(d[2]),i<0||i>100||(i=i/100,a=parseFloat(d[3]),a<0||a>100)||(a=a/100,s=d[4],s!==void 0&&(s=parseFloat(s),s<0||s>1)))return;if(i===0)l=u=h=Math.round(a*255);else{var p=a<.5?a*(1+i):a+i-a*i,m=2*a-p;l=Math.round(255*f(m,p,n+1/3)),u=Math.round(255*f(m,p,n)),h=Math.round(255*f(m,p,n-1/3))}r=[l,u,h,s]}return r},"hsl2tuple"),Mqe=o(function(e){var r,n=new RegExp("^"+Eqe+"$").exec(e);if(n){r=[];for(var i=[],a=1;a<=3;a++){var s=n[a];if(s[s.length-1]==="%"&&(i[a]=!0),s=parseFloat(s),i[a]&&(s=s/100*255),s<0||s>255)return;r.push(Math.floor(s))}var l=i[1]||i[2]||i[3],u=i[1]&&i[2]&&i[3];if(l&&!u)return;var h=n[4];if(h!==void 0){if(h=parseFloat(h),h<0||h>1)return;r.push(h)}}return r},"rgb2tuple"),Iqe=o(function(e){return Oqe[e.toLowerCase()]},"colorname2tuple"),hge=o(function(e){return(En(e)?e:null)||Iqe(e)||Rqe(e)||Mqe(e)||Nqe(e)},"color2tuple"),Oqe={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},fge=o(function(e){for(var r=e.map,n=e.keys,i=n.length,a=0;a1&&arguments[1]!==void 0?arguments[1]:X1,n=r,i;i=e.next(),!i.done;)n=n*yge+i.value|0;return n},"hashIterableInts"),t4=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:X1;return r*yge+e|0},"hashInt"),r4=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:qb;return(r<<5)+r+e|0},"hashIntAlt"),TYe=o(function(e,r){return e*2097152+r},"combineHashes"),Lf=o(function(e){return e[0]*2097152+e[1]},"combineHashesArray"),m6=o(function(e,r){return[t4(e[0],r[0]),r4(e[1],r[1])]},"hashArrays"),wYe=o(function(e,r){var n={value:0,done:!1},i=0,a=e.length,s={next:o(function(){return i=0&&!(e[i]===r&&(e.splice(i,1),n));i--);},"removeFromArray"),GB=o(function(e){e.splice(0,e.length)},"clearArray"),DYe=o(function(e,r){for(var n=0;n"u"?"undefined":qi(Set))!==RYe?Set:NYe,Z6=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(e===void 0||r===void 0||!BB(e)){oi("An element must have a core reference and parameters set");return}var i=r.group;if(i==null&&(r.data&&r.data.source!=null&&r.data.target!=null?i="edges":i="nodes"),i!=="nodes"&&i!=="edges"){oi("An element must be of type `nodes` or `edges`; you specified `"+i+"`");return}this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:r.data||{},position:r.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:i,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!r.selected,selectable:r.selectable===void 0?!0:!!r.selectable,locked:!!r.locked,grabbed:!1,grabbable:r.grabbable===void 0?!0:!!r.grabbable,pannable:r.pannable===void 0?i==="edges":!!r.pannable,active:!1,classes:new ay,animation:{current:[],queue:[]},rscratch:{},scratch:r.scratch||{},edges:[],children:[],parent:r.parent&&r.parent.isNode()?r.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(a.position.x==null&&(a.position.x=0),a.position.y==null&&(a.position.y=0),r.renderedPosition){var s=r.renderedPosition,l=e.pan(),u=e.zoom();a.position={x:(s.x-l.x)/u,y:(s.y-l.y)/u}}var h=[];En(r.classes)?h=r.classes:Zt(r.classes)&&(h=r.classes.split(/\s+/));for(var f=0,d=h.length;fb?1:0},"defaultCmp"),f=o(function(x,b,T,S,w){var E;if(T==null&&(T=0),w==null&&(w=n),T<0)throw new Error("lo must be non-negative");for(S==null&&(S=x.length);TO;0<=O?D++:D--)C.push(D);return C}.apply(this).reverse(),_=[],S=0,w=E.length;SR;0<=R?++C:--C)k.push(s(x,T));return k},"nsmallest"),y=o(function(x,b,T,S){var w,E,_;for(S==null&&(S=n),w=x[T];T>b;){if(_=T-1>>1,E=x[_],S(w,E)<0){x[T]=E,T=_;continue}break}return x[T]=w},"_siftdown"),v=o(function(x,b,T){var S,w,E,_,C;for(T==null&&(T=n),w=x.length,C=b,E=x[b],S=2*b+1;S0;){var E=b.pop(),_=v(E),C=E.id();if(p[C]=_,_!==1/0)for(var D=E.neighborhood().intersect(g),O=0;O0)for(B.unshift(P);d[z];){var $=d[z];B.unshift($.edge),B.unshift($.node),F=$.node,z=F.id()}return l.spawn(B)},"pathTo")}},"dijkstra")},PYe={kruskal:o(function(e){e=e||function(T){return 1};for(var r=this.byGroup(),n=r.nodes,i=r.edges,a=n.length,s=new Array(a),l=n,u=o(function(S){for(var w=0;w0;){if(w(),_++,S===f){for(var C=[],D=a,O=f,R=x[O];C.unshift(D),R!=null&&C.unshift(R),D=v[O],D!=null;)O=D.id(),R=x[O];return{found:!0,distance:d[S],path:this.spawn(C),steps:_}}m[S]=!0;for(var k=T._private.edges,L=0;LR&&(g[O]=R,b[O]=D,T[O]=w),!a){var k=D*f+C;!a&&g[k]>R&&(g[k]=R,b[k]=C,T[k]=w)}}}for(var L=0;L1&&arguments[1]!==void 0?arguments[1]:s,ye=T(ae),Be=[],He=ye;;){if(He==null)return r.spawn();var ze=b(He),Le=ze.edge,Ie=ze.pred;if(Be.unshift(He[0]),He.same(Oe)&&Be.length>0)break;Le!=null&&Be.unshift(Le),He=Ie}return u.spawn(Be)},"pathTo"),E=0;E=0;f--){var d=h[f],p=d[1],m=d[2];(r[p]===l&&r[m]===u||r[p]===u&&r[m]===l)&&h.splice(f,1)}for(var g=0;gi;){var a=Math.floor(Math.random()*r.length);r=HYe(a,e,r),n--}return r},"contractUntil"),WYe={kargerStein:o(function(){var e=this,r=this.byGroup(),n=r.nodes,i=r.edges;i.unmergeBy(function(B){return B.isLoop()});var a=n.length,s=i.length,l=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),u=Math.floor(a/UYe);if(a<2){oi("At least 2 nodes are required for Karger-Stein algorithm");return}for(var h=[],f=0;f1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=1/0,a=r;a1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=-1/0,a=r;a1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=0,a=0,s=r;s1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,a=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;i?e=e.slice(r,n):(n0&&e.splice(0,r));for(var l=0,u=e.length-1;u>=0;u--){var h=e[u];s?isFinite(h)||(e[u]=-1/0,l++):e.splice(u,1)}a&&e.sort(function(p,m){return p-m});var f=e.length,d=Math.floor(f/2);return f%2!==0?e[d+1+l]:(e[d-1+l]+e[d+l])/2},"median"),QYe=o(function(e){return Math.PI*e/180},"deg2rad"),g6=o(function(e,r){return Math.atan2(r,e)-Math.PI/2},"getAngleFromDisp"),VB=Math.log2||function(t){return Math.log(t)/Math.log(2)},Sge=o(function(e){return e>0?1:e<0?-1:0},"signum"),Qp=o(function(e,r){return Math.sqrt(Wp(e,r))},"dist"),Wp=o(function(e,r){var n=r.x-e.x,i=r.y-e.y;return n*n+i*i},"sqdist"),ZYe=o(function(e){for(var r=e.length,n=0,i=0;i=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(e.w!=null&&e.h!=null&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},"makeBoundingBox"),eXe=o(function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},"copyBoundingBox"),tXe=o(function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},"clearBoundingBox"),rXe=o(function(e,r,n){return{x1:e.x1+r,x2:e.x2+r,y1:e.y1+n,y2:e.y2+n,w:e.w,h:e.h}},"shiftBoundingBox"),Cge=o(function(e,r){e.x1=Math.min(e.x1,r.x1),e.x2=Math.max(e.x2,r.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,r.y1),e.y2=Math.max(e.y2,r.y2),e.h=e.y2-e.y1},"updateBoundingBox"),nXe=o(function(e,r,n){e.x1=Math.min(e.x1,r),e.x2=Math.max(e.x2,r),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},"expandBoundingBoxByPoint"),D6=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return e.x1-=r,e.x2+=r,e.y1-=r,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBox"),L6=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[0],n,i,a,s;if(r.length===1)n=i=a=s=r[0];else if(r.length===2)n=a=r[0],s=i=r[1];else if(r.length===4){var l=Ri(r,4);n=l[0],i=l[1],a=l[2],s=l[3]}return e.x1-=s,e.x2+=i,e.y1-=n,e.y2+=a,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBoxSides"),X0e=o(function(e,r){e.x1=r.x1,e.y1=r.y1,e.x2=r.x2,e.y2=r.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},"assignBoundingBox"),UB=o(function(e,r){return!(e.x1>r.x2||r.x1>e.x2||e.x2r.y2||r.y1>e.y2)},"boundingBoxesIntersect"),ry=o(function(e,r,n){return e.x1<=r&&r<=e.x2&&e.y1<=n&&n<=e.y2},"inBoundingBox"),iXe=o(function(e,r){return ry(e,r.x,r.y)},"pointInBoundingBox"),Age=o(function(e,r){return ry(e,r.x1,r.y1)&&ry(e,r.x2,r.y2)},"boundingBoxInBoundingBox"),_ge=o(function(e,r,n,i,a,s,l){var u=arguments.length>7&&arguments[7]!==void 0?arguments[7]:"auto",h=u==="auto"?Zp(a,s):u,f=a/2,d=s/2;h=Math.min(h,f,d);var p=h!==f,m=h!==d,g;if(p){var y=n-f+h-l,v=i-d-l,x=n+f-h+l,b=v;if(g=Mf(e,r,n,i,y,v,x,b,!1),g.length>0)return g}if(m){var T=n+f+l,S=i-d+h-l,w=T,E=i+d-h+l;if(g=Mf(e,r,n,i,T,S,w,E,!1),g.length>0)return g}if(p){var _=n-f+h-l,C=i+d+l,D=n+f-h+l,O=C;if(g=Mf(e,r,n,i,_,C,D,O,!1),g.length>0)return g}if(m){var R=n-f-l,k=i-d+h-l,L=R,A=i+d-h+l;if(g=Mf(e,r,n,i,R,k,L,A,!1),g.length>0)return g}var I;{var M=n-f+h,P=i-d+h;if(I=Yb(e,r,n,i,M,P,h+l),I.length>0&&I[0]<=M&&I[1]<=P)return[I[0],I[1]]}{var B=n+f-h,F=i-d+h;if(I=Yb(e,r,n,i,B,F,h+l),I.length>0&&I[0]>=B&&I[1]<=F)return[I[0],I[1]]}{var z=n+f-h,$=i+d-h;if(I=Yb(e,r,n,i,z,$,h+l),I.length>0&&I[0]>=z&&I[1]>=$)return[I[0],I[1]]}{var U=n-f+h,K=i+d-h;if(I=Yb(e,r,n,i,U,K,h+l),I.length>0&&I[0]<=U&&I[1]>=K)return[I[0],I[1]]}return[]},"roundRectangleIntersectLine"),aXe=o(function(e,r,n,i,a,s,l){var u=l,h=Math.min(n,a),f=Math.max(n,a),d=Math.min(i,s),p=Math.max(i,s);return h-u<=e&&e<=f+u&&d-u<=r&&r<=p+u},"inLineVicinity"),sXe=o(function(e,r,n,i,a,s,l,u,h){var f={x1:Math.min(n,l,a)-h,x2:Math.max(n,l,a)+h,y1:Math.min(i,u,s)-h,y2:Math.max(i,u,s)+h};return!(ef.x2||rf.y2)},"inBezierVicinity"),oXe=o(function(e,r,n,i){n-=i;var a=r*r-4*e*n;if(a<0)return[];var s=Math.sqrt(a),l=2*e,u=(-r+s)/l,h=(-r-s)/l;return[u,h]},"solveQuadratic"),lXe=o(function(e,r,n,i,a){var s=1e-5;e===0&&(e=s),r/=e,n/=e,i/=e;var l,u,h,f,d,p,m,g;if(u=(3*n-r*r)/9,h=-(27*i)+r*(9*n-2*(r*r)),h/=54,l=u*u*u+h*h,a[1]=0,m=r/3,l>0){d=h+Math.sqrt(l),d=d<0?-Math.pow(-d,1/3):Math.pow(d,1/3),p=h-Math.sqrt(l),p=p<0?-Math.pow(-p,1/3):Math.pow(p,1/3),a[0]=-m+d+p,m+=(d+p)/2,a[4]=a[2]=-m,m=Math.sqrt(3)*(-p+d)/2,a[3]=m,a[5]=-m;return}if(a[5]=a[3]=0,l===0){g=h<0?-Math.pow(-h,1/3):Math.pow(h,1/3),a[0]=-m+2*g,a[4]=a[2]=-(g+m);return}u=-u,f=u*u*u,f=Math.acos(h/Math.sqrt(f)),g=2*Math.sqrt(u),a[0]=-m+g*Math.cos(f/3),a[2]=-m+g*Math.cos((f+2*Math.PI)/3),a[4]=-m+g*Math.cos((f+4*Math.PI)/3)},"solveCubic"),cXe=o(function(e,r,n,i,a,s,l,u){var h=1*n*n-4*n*a+2*n*l+4*a*a-4*a*l+l*l+i*i-4*i*s+2*i*u+4*s*s-4*s*u+u*u,f=1*9*n*a-3*n*n-3*n*l-6*a*a+3*a*l+9*i*s-3*i*i-3*i*u-6*s*s+3*s*u,d=1*3*n*n-6*n*a+n*l-n*e+2*a*a+2*a*e-l*e+3*i*i-6*i*s+i*u-i*r+2*s*s+2*s*r-u*r,p=1*n*a-n*n+n*e-a*e+i*s-i*i+i*r-s*r,m=[];lXe(h,f,d,p,m);for(var g=1e-7,y=[],v=0;v<6;v+=2)Math.abs(m[v+1])=0&&m[v]<=1&&y.push(m[v]);y.push(1),y.push(0);for(var x=-1,b,T,S,w=0;w=0?Sh?(e-a)*(e-a)+(r-s)*(r-s):f-p},"sqdistToFiniteLine"),qs=o(function(e,r,n){for(var i,a,s,l,u,h=0,f=0;f=e&&e>=s||i<=e&&e<=s)u=(e-i)/(s-i)*(l-a)+a,u>r&&h++;else continue;return h%2!==0},"pointInsidePolygonPoints"),ih=o(function(e,r,n,i,a,s,l,u,h){var f=new Array(n.length),d;u[0]!=null?(d=Math.atan(u[1]/u[0]),u[0]<0?d=d+Math.PI/2:d=-d-Math.PI/2):d=u;for(var p=Math.cos(-d),m=Math.sin(-d),g=0;g0){var v=V6(f,-h);y=G6(v)}else y=f;return qs(e,r,y)},"pointInsidePolygon"),hXe=o(function(e,r,n,i,a,s,l,u){for(var h=new Array(n.length*2),f=0;f=0&&v<=1&&b.push(v),x>=0&&x<=1&&b.push(x),b.length===0)return[];var T=b[0]*u[0]+e,S=b[0]*u[1]+r;if(b.length>1){if(b[0]==b[1])return[T,S];var w=b[1]*u[0]+e,E=b[1]*u[1]+r;return[T,S,w,E]}else return[T,S]},"intersectLineCircle"),sB=o(function(e,r,n){return r<=e&&e<=n||n<=e&&e<=r?e:e<=r&&r<=n||n<=r&&r<=e?r:n},"midOfThree"),Mf=o(function(e,r,n,i,a,s,l,u,h){var f=e-a,d=n-e,p=l-a,m=r-s,g=i-r,y=u-s,v=p*m-y*f,x=d*m-g*f,b=y*d-p*g;if(b!==0){var T=v/b,S=x/b,w=.001,E=0-w,_=1+w;return E<=T&&T<=_&&E<=S&&S<=_?[e+T*d,r+T*g]:h?[e+T*d,r+T*g]:[]}else return v===0||x===0?sB(e,n,l)===l?[l,u]:sB(e,n,a)===a?[a,s]:sB(a,l,n)===n?[n,i]:[]:[]},"finiteLinesIntersect"),a4=o(function(e,r,n,i,a,s,l,u){var h=[],f,d=new Array(n.length),p=!0;s==null&&(p=!1);var m;if(p){for(var g=0;g0){var y=V6(d,-u);m=G6(y)}else m=d}else m=n;for(var v,x,b,T,S=0;S2){for(var g=[f[0],f[1]],y=Math.pow(g[0]-e,2)+Math.pow(g[1]-r,2),v=1;vf&&(f=S)},"set"),get:o(function(T){return h[T]},"get")},p=0;p0?M=I.edgesTo(A)[0]:M=A.edgesTo(I)[0];var P=i(M);A=A.id(),C[A]>C[k]+P&&(C[A]=C[k]+P,D.nodes.indexOf(A)<0?D.push(A):D.updateItem(A),_[A]=0,E[A]=[]),C[A]==C[k]+P&&(_[A]=_[A]+_[k],E[A].push(k))}else for(var B=0;B0;){for(var U=w.pop(),K=0;K0&&l.push(n[u]);l.length!==0&&a.push(i.collection(l))}return a},"assign"),AXe=o(function(e,r){for(var n=0;n5&&arguments[5]!==void 0?arguments[5]:LXe,l=i,u,h,f=0;f=2?$b(e,r,n,0,J0e,RXe):$b(e,r,n,0,Z0e)},"euclidean"),squaredEuclidean:o(function(e,r,n){return $b(e,r,n,0,J0e)},"squaredEuclidean"),manhattan:o(function(e,r,n){return $b(e,r,n,0,Z0e)},"manhattan"),max:o(function(e,r,n){return $b(e,r,n,-1/0,NXe)},"max")};ny["squared-euclidean"]=ny.squaredEuclidean;ny.squaredeuclidean=ny.squaredEuclidean;o(eC,"clusteringDistance");MXe=oa({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),WB=o(function(e){return MXe(e)},"setOptions"),U6=o(function(e,r,n,i,a){var s=a!=="kMedoids",l=s?function(d){return n[d]}:function(d){return i[d](n)},u=o(function(p){return i[p](r)},"getQ"),h=n,f=r;return eC(e,i.length,l,u,h,f)},"getDist"),oB=o(function(e,r,n){for(var i=n.length,a=new Array(i),s=new Array(i),l=new Array(r),u=null,h=0;hn)return!1}return!0},"haveMatricesConverged"),PXe=o(function(e,r,n){for(var i=0;il&&(l=r[h][f],u=f);a[u].push(e[h])}for(var d=0;d=a.threshold||a.mode==="dendrogram"&&e.length===1)return!1;var g=r[s],y=r[i[s]],v;a.mode==="dendrogram"?v={left:g,right:y,key:g.key}:v={value:g.value.concat(y.value),key:g.key},e[g.index]=v,e.splice(y.index,1),r[g.key]=v;for(var x=0;xn[y.key][b.key]&&(u=n[y.key][b.key])):a.linkage==="max"?(u=n[g.key][b.key],n[g.key][b.key]0&&i.push(a);return i},"findExemplars"),ame=o(function(e,r,n){for(var i=[],a=0;al&&(s=h,l=r[a*e+h])}s>0&&i.push(s)}for(var f=0;fh&&(u=f,h=d)}n[a]=s[u]}return i=ame(e,r,n),i},"assign"),sme=o(function(e){for(var r=this.cy(),n=this.nodes(),i=KXe(e),a={},s=0;s=R?(k=R,R=A,L=I):A>k&&(k=A);for(var M=0;M0?1:0;_[D%i.minIterations*l+U]=K,$+=K}if($>0&&(D>=i.minIterations-1||D==i.maxIterations-1)){for(var ee=0,Y=0;Y1||E>1)&&(l=!0),d[T]=[],b.outgoers().forEach(function(C){C.isEdge()&&d[T].push(C.id())})}else p[T]=[void 0,b.target().id()]}):s.forEach(function(b){var T=b.id();if(b.isNode()){var S=b.degree(!0);S%2&&(u?h?l=!0:h=T:u=T),d[T]=[],b.connectedEdges().forEach(function(w){return d[T].push(w.id())})}else p[T]=[b.source().id(),b.target().id()]});var m={found:!1,trail:void 0};if(l)return m;if(h&&u)if(a){if(f&&h!=f)return m;f=h}else{if(f&&h!=f&&u!=f)return m;f||(f=h)}else f||(f=s[0].id());var g=o(function(T){for(var S=T,w=[T],E,_,C;d[S].length;)E=d[S].shift(),_=p[E][0],C=p[E][1],S!=C?(d[C]=d[C].filter(function(D){return D!=E}),S=C):!a&&S!=_&&(d[_]=d[_].filter(function(D){return D!=E}),S=_),w.unshift(E),w.unshift(S);return w},"walk"),y=[],v=[];for(v=g(f);v.length!=1;)d[v[0]].length==0?(y.unshift(s.getElementById(v.shift())),y.unshift(s.getElementById(v.shift()))):v=g(v.shift()).concat(v);y.unshift(s.getElementById(v.shift()));for(var x in d)if(d[x].length)return m;return m.found=!0,m.trail=this.spawn(y,!0),m},"hierholzer")},x6=o(function(){var e=this,r={},n=0,i=0,a=[],s=[],l={},u=o(function(p,m){for(var g=s.length-1,y=[],v=e.spawn();s[g].x!=p||s[g].y!=m;)y.push(s.pop().edge),g--;y.push(s.pop().edge),y.forEach(function(x){var b=x.connectedNodes().intersection(e);v.merge(x),b.forEach(function(T){var S=T.id(),w=T.connectedEdges().intersection(e);v.merge(T),r[S].cutVertex?v.merge(w.filter(function(E){return E.isLoop()})):v.merge(w)})}),a.push(v)},"buildComponent"),h=o(function d(p,m,g){p===g&&(i+=1),r[m]={id:n,low:n++,cutVertex:!1};var y=e.getElementById(m).connectedEdges().intersection(e);if(y.size()===0)a.push(e.spawn(e.getElementById(m)));else{var v,x,b,T;y.forEach(function(S){v=S.source().id(),x=S.target().id(),b=v===m?x:v,b!==g&&(T=S.id(),l[T]||(l[T]=!0,s.push({x:m,y:b,edge:S})),b in r?r[m].low=Math.min(r[m].low,r[b].id):(d(p,b,m),r[m].low=Math.min(r[m].low,r[b].low),r[m].id<=r[b].low&&(r[m].cutVertex=!0,u(m,b))))})}},"biconnectedSearch");e.forEach(function(d){if(d.isNode()){var p=d.id();p in r||(i=0,h(p,p),r[p].cutVertex=i>1)}});var f=Object.keys(r).filter(function(d){return r[d].cutVertex}).map(function(d){return e.getElementById(d)});return{cut:e.spawn(f),components:a}},"hopcroftTarjanBiconnected"),ije={hopcroftTarjanBiconnected:x6,htbc:x6,htb:x6,hopcroftTarjanBiconnectedComponents:x6},b6=o(function(){var e=this,r={},n=0,i=[],a=[],s=e.spawn(e),l=o(function u(h){a.push(h),r[h]={index:n,low:n++,explored:!1};var f=e.getElementById(h).connectedEdges().intersection(e);if(f.forEach(function(y){var v=y.target().id();v!==h&&(v in r||u(v),r[v].explored||(r[h].low=Math.min(r[h].low,r[v].low)))}),r[h].index===r[h].low){for(var d=e.spawn();;){var p=a.pop();if(d.merge(e.getElementById(p)),r[p].low=r[h].index,r[p].explored=!0,p===h)break}var m=d.edgesWith(d),g=d.merge(m);i.push(g),s=s.difference(g)}},"stronglyConnectedSearch");return e.forEach(function(u){if(u.isNode()){var h=u.id();h in r||l(h)}}),{cut:s,components:i}},"tarjanStronglyConnected"),aje={tarjanStronglyConnected:b6,tsc:b6,tscc:b6,tarjanStronglyConnectedComponents:b6},Oge={};[n4,OYe,PYe,FYe,zYe,VYe,WYe,gXe,Z1,J1,wB,DXe,VXe,XXe,tje,nje,ije,aje].forEach(function(t){ir(Oge,t)});Pge=0,Bge=1,Fge=2,ah=o(function t(e){if(!(this instanceof t))return new t(e);this.id="Thenable/1.0.7",this.state=Pge,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},typeof e=="function"&&e.call(this,this.fulfill.bind(this),this.reject.bind(this))},"api");ah.prototype={fulfill:o(function(e){return ome(this,Bge,"fulfillValue",e)},"fulfill"),reject:o(function(e){return ome(this,Fge,"rejectReason",e)},"reject"),then:o(function(e,r){var n=this,i=new ah;return n.onFulfilled.push(cme(e,i,"fulfill")),n.onRejected.push(cme(r,i,"reject")),$ge(n),i.proxy},"then")};ome=o(function(e,r,n,i){return e.state===Pge&&(e.state=r,e[n]=i,$ge(e)),e},"deliver"),$ge=o(function(e){e.state===Bge?lme(e,"onFulfilled",e.fulfillValue):e.state===Fge&&lme(e,"onRejected",e.rejectReason)},"execute"),lme=o(function(e,r,n){if(e[r].length!==0){var i=e[r];e[r]=[];var a=o(function(){for(var l=0;l0},"animatedImpl")},"animated"),clearQueue:o(function(){return o(function(){var r=this,n=r.length!==void 0,i=n?r:[r],a=this._private.cy||this;if(!a.styleEnabled())return this;for(var s=0;s0&&this.spawn(i).updateStyle().emit("class"),r},"classes"),addClass:o(function(e){return this.toggleClass(e,!0)},"addClass"),hasClass:o(function(e){var r=this[0];return r!=null&&r._private.classes.has(e)},"hasClass"),toggleClass:o(function(e,r){En(e)||(e=e.match(/\S+/g)||[]);for(var n=this,i=r===void 0,a=[],s=0,l=n.length;s0&&this.spawn(a).updateStyle().emit("class"),n},"toggleClass"),removeClass:o(function(e){return this.toggleClass(e,!1)},"removeClass"),flashClass:o(function(e,r){var n=this;if(r==null)r=250;else if(r===0)return n;return n.addClass(e),setTimeout(function(){n.removeClass(e)},r),n},"flashClass")};R6.className=R6.classNames=R6.classes;Vr={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:`"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'`,number:Wi,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Vr.variable="(?:[\\w-.]|(?:\\\\"+Vr.metaChar+"))+";Vr.className="(?:[\\w-]|(?:\\\\"+Vr.metaChar+"))+";Vr.value=Vr.string+"|"+Vr.number;Vr.id=Vr.variable;(function(){var t,e,r;for(t=Vr.comparatorOp.split("|"),r=0;r=0)&&e!=="="&&(Vr.comparatorOp+="|\\!"+e)})();gn=o(function(){return{checks:[]}},"newQuery"),$t={GROUP:0,COLLECTION:1,FILTER:2,DATA_COMPARE:3,DATA_EXIST:4,DATA_BOOL:5,META_COMPARE:6,STATE:7,ID:8,CLASS:9,UNDIRECTED_EDGE:10,DIRECTED_EDGE:11,NODE_SOURCE:12,NODE_TARGET:13,NODE_NEIGHBOR:14,CHILD:15,DESCENDANT:16,PARENT:17,ANCESTOR:18,COMPOUND_SPLIT:19,TRUE:20},EB=[{selector:":selected",matches:o(function(e){return e.selected()},"matches")},{selector:":unselected",matches:o(function(e){return!e.selected()},"matches")},{selector:":selectable",matches:o(function(e){return e.selectable()},"matches")},{selector:":unselectable",matches:o(function(e){return!e.selectable()},"matches")},{selector:":locked",matches:o(function(e){return e.locked()},"matches")},{selector:":unlocked",matches:o(function(e){return!e.locked()},"matches")},{selector:":visible",matches:o(function(e){return e.visible()},"matches")},{selector:":hidden",matches:o(function(e){return!e.visible()},"matches")},{selector:":transparent",matches:o(function(e){return e.transparent()},"matches")},{selector:":grabbed",matches:o(function(e){return e.grabbed()},"matches")},{selector:":free",matches:o(function(e){return!e.grabbed()},"matches")},{selector:":removed",matches:o(function(e){return e.removed()},"matches")},{selector:":inside",matches:o(function(e){return!e.removed()},"matches")},{selector:":grabbable",matches:o(function(e){return e.grabbable()},"matches")},{selector:":ungrabbable",matches:o(function(e){return!e.grabbable()},"matches")},{selector:":animated",matches:o(function(e){return e.animated()},"matches")},{selector:":unanimated",matches:o(function(e){return!e.animated()},"matches")},{selector:":parent",matches:o(function(e){return e.isParent()},"matches")},{selector:":childless",matches:o(function(e){return e.isChildless()},"matches")},{selector:":child",matches:o(function(e){return e.isChild()},"matches")},{selector:":orphan",matches:o(function(e){return e.isOrphan()},"matches")},{selector:":nonorphan",matches:o(function(e){return e.isChild()},"matches")},{selector:":compound",matches:o(function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()},"matches")},{selector:":loop",matches:o(function(e){return e.isLoop()},"matches")},{selector:":simple",matches:o(function(e){return e.isSimple()},"matches")},{selector:":active",matches:o(function(e){return e.active()},"matches")},{selector:":inactive",matches:o(function(e){return!e.active()},"matches")},{selector:":backgrounding",matches:o(function(e){return e.backgrounding()},"matches")},{selector:":nonbackgrounding",matches:o(function(e){return!e.backgrounding()},"matches")}].sort(function(t,e){return Lqe(t.selector,e.selector)}),vQe=function(){for(var t={},e,r=0;r0&&f.edgeCount>0)return hn("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(f.edgeCount>1)return hn("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;f.edgeCount===1&&hn("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},"parse"),EQe=o(function(){if(this.toStringCache!=null)return this.toStringCache;for(var e=o(function(f){return f??""},"clean"),r=o(function(f){return Zt(f)?'"'+f+'"':e(f)},"cleanVal"),n=o(function(f){return" "+f+" "},"space"),i=o(function(f,d){var p=f.type,m=f.value;switch(p){case $t.GROUP:{var g=e(m);return g.substring(0,g.length-1)}case $t.DATA_COMPARE:{var y=f.field,v=f.operator;return"["+y+n(e(v))+r(m)+"]"}case $t.DATA_BOOL:{var x=f.operator,b=f.field;return"["+e(x)+b+"]"}case $t.DATA_EXIST:{var T=f.field;return"["+T+"]"}case $t.META_COMPARE:{var S=f.operator,w=f.field;return"[["+w+n(e(S))+r(m)+"]]"}case $t.STATE:return m;case $t.ID:return"#"+m;case $t.CLASS:return"."+m;case $t.PARENT:case $t.CHILD:return a(f.parent,d)+n(">")+a(f.child,d);case $t.ANCESTOR:case $t.DESCENDANT:return a(f.ancestor,d)+" "+a(f.descendant,d);case $t.COMPOUND_SPLIT:{var E=a(f.left,d),_=a(f.subject,d),C=a(f.right,d);return E+(E.length>0?" ":"")+_+C}case $t.TRUE:return""}},"checkToString"),a=o(function(f,d){return f.checks.reduce(function(p,m,g){return p+(d===f&&g===0?"$":"")+i(m,d)},"")},"queryToString"),s="",l=0;l1&&l=0&&(r=r.replace("!",""),d=!0),r.indexOf("@")>=0&&(r=r.replace("@",""),f=!0),(a||l||f)&&(u=!a&&!s?"":""+e,h=""+n),f&&(e=u=u.toLowerCase(),n=h=h.toLowerCase()),r){case"*=":i=u.indexOf(h)>=0;break;case"$=":i=u.indexOf(h,u.length-h.length)>=0;break;case"^=":i=u.indexOf(h)===0;break;case"=":i=e===n;break;case">":p=!0,i=e>n;break;case">=":p=!0,i=e>=n;break;case"<":p=!0,i=e1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,Xge)};o(jge,"addParent");iy.forEachUp=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,jge)};o(NQe,"addParentAndChildren");iy.forEachUpAndDown=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return KB(this,t,e,NQe)};iy.ancestors=iy.parents;o4=Kge={data:un.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:un.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:un.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:un.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:un.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:un.removeData({field:"rscratch",triggerEvent:!1}),id:o(function(){var e=this[0];if(e)return e._private.data.id},"id")};o4.attr=o4.data;o4.removeAttr=o4.removeData;MQe=Kge,iC={};o(cB,"defineDegreeFunction");ir(iC,{degree:cB(function(t,e){return e.source().same(e.target())?2:1}),indegree:cB(function(t,e){return e.target().same(t)?1:0}),outdegree:cB(function(t,e){return e.source().same(t)?1:0})});o(H1,"defineDegreeBoundsFunction");ir(iC,{minDegree:H1("degree",function(t,e){return te}),minIndegree:H1("indegree",function(t,e){return te}),minOutdegree:H1("outdegree",function(t,e){return te})});ir(iC,{totalDegree:o(function(e){for(var r=0,n=this.nodes(),i=0;i0,p=d;d&&(f=f[0]);var m=p?f.position():{x:0,y:0};r!==void 0?h.position(e,r+m[e]):a!==void 0&&h.position({x:a.x+m.x,y:a.y+m.y})}else{var g=n.position(),y=l?n.parent():null,v=y&&y.length>0,x=v;v&&(y=y[0]);var b=x?y.position():{x:0,y:0};return a={x:g.x-b.x,y:g.y-b.y},e===void 0?a:a[e]}else if(!s)return;return this},"relativePosition")};ql.modelPosition=ql.point=ql.position;ql.modelPositions=ql.points=ql.positions;ql.renderedPoint=ql.renderedPosition;ql.relativePoint=ql.relativePosition;IQe=Qge;ey=Hf={};Hf.renderedBoundingBox=function(t){var e=this.boundingBox(t),r=this.cy(),n=r.zoom(),i=r.pan(),a=e.x1*n+i.x,s=e.x2*n+i.x,l=e.y1*n+i.y,u=e.y2*n+i.y;return{x1:a,x2:s,y1:l,y2:u,w:s-a,h:u-l}};Hf.dirtyCompoundBoundsCache=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();return!e.styleEnabled()||!e.hasCompoundNodes()?this:(this.forEachUp(function(r){if(r.isParent()){var n=r._private;n.compoundBoundsClean=!1,n.bbCache=null,t||r.emitAndNotify("bounds")}}),this)};Hf.updateCompoundBounds=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();if(!e.styleEnabled()||!e.hasCompoundNodes())return this;if(!t&&e.batching())return this;function r(s){if(!s.isParent())return;var l=s._private,u=s.children(),h=s.pstyle("compound-sizing-wrt-labels").value==="include",f={width:{val:s.pstyle("min-width").pfValue,left:s.pstyle("min-width-bias-left"),right:s.pstyle("min-width-bias-right")},height:{val:s.pstyle("min-height").pfValue,top:s.pstyle("min-height-bias-top"),bottom:s.pstyle("min-height-bias-bottom")}},d=u.boundingBox({includeLabels:h,includeOverlays:!1,useCache:!1}),p=l.position;(d.w===0||d.h===0)&&(d={w:s.pstyle("width").pfValue,h:s.pstyle("height").pfValue},d.x1=p.x-d.w/2,d.x2=p.x+d.w/2,d.y1=p.y-d.h/2,d.y2=p.y+d.h/2);function m(D,O,R){var k=0,L=0,A=O+R;return D>0&&A>0&&(k=O/A*D,L=R/A*D),{biasDiff:k,biasComplementDiff:L}}o(m,"computeBiasValues");function g(D,O,R,k){if(R.units==="%")switch(k){case"width":return D>0?R.pfValue*D:0;case"height":return O>0?R.pfValue*O:0;case"average":return D>0&&O>0?R.pfValue*(D+O)/2:0;case"min":return D>0&&O>0?D>O?R.pfValue*O:R.pfValue*D:0;case"max":return D>0&&O>0?D>O?R.pfValue*D:R.pfValue*O:0;default:return 0}else return R.units==="px"?R.pfValue:0}o(g,"computePaddingValues");var y=f.width.left.value;f.width.left.units==="px"&&f.width.val>0&&(y=y*100/f.width.val);var v=f.width.right.value;f.width.right.units==="px"&&f.width.val>0&&(v=v*100/f.width.val);var x=f.height.top.value;f.height.top.units==="px"&&f.height.val>0&&(x=x*100/f.height.val);var b=f.height.bottom.value;f.height.bottom.units==="px"&&f.height.val>0&&(b=b*100/f.height.val);var T=m(f.width.val-d.w,y,v),S=T.biasDiff,w=T.biasComplementDiff,E=m(f.height.val-d.h,x,b),_=E.biasDiff,C=E.biasComplementDiff;l.autoPadding=g(d.w,d.h,s.pstyle("padding"),s.pstyle("padding-relative-to").value),l.autoWidth=Math.max(d.w,f.width.val),p.x=(-S+d.x1+d.x2+w)/2,l.autoHeight=Math.max(d.h,f.height.val),p.y=(-_+d.y1+d.y2+C)/2}o(r,"update");for(var n=0;ne.x2?i:e.x2,e.y1=ne.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},"updateBounds"),qp=o(function(e,r){return r==null?e:Hl(e,r.x1,r.y1,r.x2,r.y2)},"updateBoundsFromBox"),zb=o(function(e,r,n){return Wl(e,r,n)},"prefixedProperty"),T6=o(function(e,r,n){if(!r.cy().headless()){var i=r._private,a=i.rstyle,s=a.arrowWidth/2,l=r.pstyle(n+"-arrow-shape").value,u,h;if(l!=="none"){n==="source"?(u=a.srcX,h=a.srcY):n==="target"?(u=a.tgtX,h=a.tgtY):(u=a.midX,h=a.midY);var f=i.arrowBounds=i.arrowBounds||{},d=f[n]=f[n]||{};d.x1=u-s,d.y1=h-s,d.x2=u+s,d.y2=h+s,d.w=d.x2-d.x1,d.h=d.y2-d.y1,D6(d,1),Hl(e,d.x1,d.y1,d.x2,d.y2)}}},"updateBoundsFromArrow"),uB=o(function(e,r,n){if(!r.cy().headless()){var i;n?i=n+"-":i="";var a=r._private,s=a.rstyle,l=r.pstyle(i+"label").strValue;if(l){var u=r.pstyle("text-halign"),h=r.pstyle("text-valign"),f=zb(s,"labelWidth",n),d=zb(s,"labelHeight",n),p=zb(s,"labelX",n),m=zb(s,"labelY",n),g=r.pstyle(i+"text-margin-x").pfValue,y=r.pstyle(i+"text-margin-y").pfValue,v=r.isEdge(),x=r.pstyle(i+"text-rotation"),b=r.pstyle("text-outline-width").pfValue,T=r.pstyle("text-border-width").pfValue,S=T/2,w=r.pstyle("text-background-padding").pfValue,E=2,_=d,C=f,D=C/2,O=_/2,R,k,L,A;if(v)R=p-D,k=p+D,L=m-O,A=m+O;else{switch(u.value){case"left":R=p-C,k=p;break;case"center":R=p-D,k=p+D;break;case"right":R=p,k=p+C;break}switch(h.value){case"top":L=m-_,A=m;break;case"center":L=m-O,A=m+O;break;case"bottom":L=m,A=m+_;break}}var I=g-Math.max(b,S)-w-E,M=g+Math.max(b,S)+w+E,P=y-Math.max(b,S)-w-E,B=y+Math.max(b,S)+w+E;R+=I,k+=M,L+=P,A+=B;var F=n||"main",z=a.labelBounds,$=z[F]=z[F]||{};$.x1=R,$.y1=L,$.x2=k,$.y2=A,$.w=k-R,$.h=A-L,$.leftPad=I,$.rightPad=M,$.topPad=P,$.botPad=B;var U=v&&x.strValue==="autorotate",K=x.pfValue!=null&&x.pfValue!==0;if(U||K){var ee=U?zb(a.rstyle,"labelAngle",n):x.pfValue,Y=Math.cos(ee),ce=Math.sin(ee),Z=(R+k)/2,ue=(L+A)/2;if(!v){switch(u.value){case"left":Z=k;break;case"right":Z=R;break}switch(h.value){case"top":ue=A;break;case"bottom":ue=L;break}}var Q=o(function(se,ae){return se=se-Z,ae=ae-ue,{x:se*Y-ae*ce+Z,y:se*ce+ae*Y+ue}},"rotate"),j=Q(R,L),ne=Q(R,A),te=Q(k,L),he=Q(k,A);R=Math.min(j.x,ne.x,te.x,he.x),k=Math.max(j.x,ne.x,te.x,he.x),L=Math.min(j.y,ne.y,te.y,he.y),A=Math.max(j.y,ne.y,te.y,he.y)}var le=F+"Rot",J=z[le]=z[le]||{};J.x1=R,J.y1=L,J.x2=k,J.y2=A,J.w=k-R,J.h=A-L,Hl(e,R,L,k,A),Hl(a.labelBounds.all,R,L,k,A)}return e}},"updateBoundsFromLabel"),OQe=o(function(e,r){if(!r.cy().headless()){var n=r.pstyle("outline-opacity").value,i=r.pstyle("outline-width").value;if(n>0&&i>0){var a=r.pstyle("outline-offset").value,s=r.pstyle("shape").value,l=i+a,u=(e.w+l*2)/e.w,h=(e.h+l*2)/e.h,f=0,d=0;["diamond","pentagon","round-triangle"].includes(s)?(u=(e.w+l*2.4)/e.w,d=-l/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(s)?u=(e.w+l*2.4)/e.w:s==="star"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.6)/e.h,d=-l/3.8):s==="triangle"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.4)/e.h,d=-l/1.4):s==="vee"&&(u=(e.w+l*4.4)/e.w,h=(e.h+l*3.8)/e.h,d=-l*.5);var p=e.h*h-e.h,m=e.w*u-e.w;if(L6(e,[Math.ceil(p/2),Math.ceil(m/2)]),f!=0||d!==0){var g=rXe(e,f,d);Cge(e,g)}}}},"updateBoundsFromOutline"),PQe=o(function(e,r){var n=e._private.cy,i=n.styleEnabled(),a=n.headless(),s=Ys(),l=e._private,u=e.isNode(),h=e.isEdge(),f,d,p,m,g,y,v=l.rstyle,x=u&&i?e.pstyle("bounds-expansion").pfValue:[0],b=o(function(Se){return Se.pstyle("display").value!=="none"},"isDisplayed"),T=!i||b(e)&&(!h||b(e.source())&&b(e.target()));if(T){var S=0,w=0;i&&r.includeOverlays&&(S=e.pstyle("overlay-opacity").value,S!==0&&(w=e.pstyle("overlay-padding").value));var E=0,_=0;i&&r.includeUnderlays&&(E=e.pstyle("underlay-opacity").value,E!==0&&(_=e.pstyle("underlay-padding").value));var C=Math.max(w,_),D=0,O=0;if(i&&(D=e.pstyle("width").pfValue,O=D/2),u&&r.includeNodes){var R=e.position();g=R.x,y=R.y;var k=e.outerWidth(),L=k/2,A=e.outerHeight(),I=A/2;f=g-L,d=g+L,p=y-I,m=y+I,Hl(s,f,p,d,m),i&&r.includeOutlines&&OQe(s,e)}else if(h&&r.includeEdges)if(i&&!a){var M=e.pstyle("curve-style").strValue;if(f=Math.min(v.srcX,v.midX,v.tgtX),d=Math.max(v.srcX,v.midX,v.tgtX),p=Math.min(v.srcY,v.midY,v.tgtY),m=Math.max(v.srcY,v.midY,v.tgtY),f-=O,d+=O,p-=O,m+=O,Hl(s,f,p,d,m),M==="haystack"){var P=v.haystackPts;if(P&&P.length===2){if(f=P[0].x,p=P[0].y,d=P[1].x,m=P[1].y,f>d){var B=f;f=d,d=B}if(p>m){var F=p;p=m,m=F}Hl(s,f-O,p-O,d+O,m+O)}}else if(M==="bezier"||M==="unbundled-bezier"||M.endsWith("segments")||M.endsWith("taxi")){var z;switch(M){case"bezier":case"unbundled-bezier":z=v.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":z=v.linePts;break}if(z!=null)for(var $=0;$d){var Z=f;f=d,d=Z}if(p>m){var ue=p;p=m,m=ue}f-=O,d+=O,p-=O,m+=O,Hl(s,f,p,d,m)}if(i&&r.includeEdges&&h&&(T6(s,e,"mid-source"),T6(s,e,"mid-target"),T6(s,e,"source"),T6(s,e,"target")),i){var Q=e.pstyle("ghost").value==="yes";if(Q){var j=e.pstyle("ghost-offset-x").pfValue,ne=e.pstyle("ghost-offset-y").pfValue;Hl(s,s.x1+j,s.y1+ne,s.x2+j,s.y2+ne)}}var te=l.bodyBounds=l.bodyBounds||{};X0e(te,s),L6(te,x),D6(te,1),i&&(f=s.x1,d=s.x2,p=s.y1,m=s.y2,Hl(s,f-C,p-C,d+C,m+C));var he=l.overlayBounds=l.overlayBounds||{};X0e(he,s),L6(he,x),D6(he,1);var le=l.labelBounds=l.labelBounds||{};le.all!=null?tXe(le.all):le.all=Ys(),i&&r.includeLabels&&(r.includeMainLabels&&uB(s,e,null),h&&(r.includeSourceLabels&&uB(s,e,"source"),r.includeTargetLabels&&uB(s,e,"target")))}return s.x1=il(s.x1),s.y1=il(s.y1),s.x2=il(s.x2),s.y2=il(s.y2),s.w=il(s.x2-s.x1),s.h=il(s.y2-s.y1),s.w>0&&s.h>0&&T&&(L6(s,x),D6(s,1)),s},"boundingBoxImpl"),Jge=o(function(e){var r=0,n=o(function(s){return(s?1:0)<=0;l--)s(l);return this};Gf.removeAllListeners=function(){return this.removeListener("*")};Gf.emit=Gf.trigger=function(t,e,r){var n=this.listeners,i=n.length;return this.emitting++,En(e)||(e=[e]),ZQe(this,function(a,s){r!=null&&(n=[{event:s.event,type:s.type,namespace:s.namespace,callback:r}],i=n.length);for(var l=o(function(f){var d=n[f];if(d.type===s.type&&(!d.namespace||d.namespace===s.namespace||d.namespace===KQe)&&a.eventMatches(a.context,d,s)){var p=[s];e!=null&&DYe(p,e),a.beforeEmit(a.context,d,s),d.conf&&d.conf.one&&(a.listeners=a.listeners.filter(function(y){return y!==d}));var m=a.callbackContext(a.context,d,s),g=d.callback.apply(m,p);a.afterEmit(a.context,d,s),g===!1&&(s.stopPropagation(),s.preventDefault())}},"_loop2"),u=0;u1&&!s){var l=this.length-1,u=this[l],h=u._private.data.id;this[l]=void 0,this[e]=u,a.set(h,{ele:u,index:e})}return this.length--,this},"unmergeAt"),unmergeOne:o(function(e){e=e[0];var r=this._private,n=e._private.data.id,i=r.map,a=i.get(n);if(!a)return this;var s=a.index;return this.unmergeAt(s),this},"unmergeOne"),unmerge:o(function(e){var r=this._private.cy;if(!e)return this;if(e&&Zt(e)){var n=e;e=r.mutableElements().filter(n)}for(var i=0;i=0;r--){var n=this[r];e(n)&&this.unmergeAt(r)}return this},"unmergeBy"),map:o(function(e,r){for(var n=[],i=this,a=0;an&&(n=u,i=l)}return{value:n,ele:i}},"max"),min:o(function(e,r){for(var n=1/0,i,a=this,s=0;s=0&&a"u"?"undefined":qi(Symbol))!=e&&qi(Symbol.iterator)!=e;r&&(H6[Symbol.iterator]=function(){var n=this,i={value:void 0,done:!1},a=0,s=this.length;return ige({next:o(function(){return a1&&arguments[1]!==void 0?arguments[1]:!0,n=this[0],i=n.cy();if(i.styleEnabled()&&n){n._private.styleDirty&&(n._private.styleDirty=!1,i.style().apply(n));var a=n._private.style[e];return a??(r?i.style().getDefaultProperty(e):null)}},"parsedStyle"),numericStyle:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r){var n=r.pstyle(e);return n.pfValue!==void 0?n.pfValue:n.value}},"numericStyle"),numericStyleUnits:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r)return r.pstyle(e).units},"numericStyleUnits"),renderedStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=this[0];if(n)return r.style().getRenderedStyle(n,e)},"renderedStyle"),style:o(function(e,r){var n=this.cy();if(!n.styleEnabled())return this;var i=!1,a=n.style();if(Ur(e)){var s=e;a.applyBypass(this,s,i),this.emitAndNotify("style")}else if(Zt(e))if(r===void 0){var l=this[0];return l?a.getStylePropertyValue(l,e):void 0}else a.applyBypass(this,e,r,i),this.emitAndNotify("style");else if(e===void 0){var u=this[0];return u?a.getRawStyle(u):void 0}return this},"style"),removeStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=!1,i=r.style(),a=this;if(e===void 0)for(var s=0;s0&&e.push(f[0]),e.push(l[0])}return this.spawn(e,!0).filter(t)},"neighborhood"),closedNeighborhood:o(function(e){return this.neighborhood().add(this).filter(e)},"closedNeighborhood"),openNeighborhood:o(function(e){return this.neighborhood(e)},"openNeighborhood")});Ha.neighbourhood=Ha.neighborhood;Ha.closedNeighbourhood=Ha.closedNeighborhood;Ha.openNeighbourhood=Ha.openNeighborhood;ir(Ha,{source:al(o(function(e){var r=this[0],n;return r&&(n=r._private.source||r.cy().collection()),n&&e?n.filter(e):n},"sourceImpl"),"source"),target:al(o(function(e){var r=this[0],n;return r&&(n=r._private.target||r.cy().collection()),n&&e?n.filter(e):n},"targetImpl"),"target"),sources:Cme({attr:"source"}),targets:Cme({attr:"target"})});o(Cme,"defineSourceFunction");ir(Ha,{edgesWith:al(Ame(),"edgesWith"),edgesTo:al(Ame({thisIsSrc:!0}),"edgesTo")});o(Ame,"defineEdgesWithFunction");ir(Ha,{connectedEdges:al(function(t){for(var e=[],r=this,n=0;n0);return s},"components"),component:o(function(){var e=this[0];return e.cy().mutableElements().components(e)[0]},"component")});Ha.componentsOf=Ha.components;Sa=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(e===void 0){oi("A collection must have a reference to the core");return}var a=new Zc,s=!1;if(!r)r=[];else if(r.length>0&&Ur(r[0])&&!f4(r[0])){s=!0;for(var l=[],u=new ay,h=0,f=r.length;h0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=r.cy(),i=n._private,a=[],s=[],l,u=0,h=r.length;u0){for(var F=l.length===r.length?r:new Sa(n,l),z=0;z0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=[],i={},a=r._private.cy;function s(A){for(var I=A._private.edges,M=0;M0&&(t?R.emitAndNotify("remove"):e&&R.emit("remove"));for(var k=0;kf&&Math.abs(g.v)>f;);return p?function(y){return u[y*(u.length-1)|0]}:h},"springRK4Factory")}(),Nn=o(function(e,r,n,i){var a=lZe(e,r,n,i);return function(s,l,u){return s+(l-s)*a(u)}},"cubicBezier"),M6={linear:o(function(e,r,n){return e+(r-e)*n},"linear"),ease:Nn(.25,.1,.25,1),"ease-in":Nn(.42,0,1,1),"ease-out":Nn(0,0,.58,1),"ease-in-out":Nn(.42,0,.58,1),"ease-in-sine":Nn(.47,0,.745,.715),"ease-out-sine":Nn(.39,.575,.565,1),"ease-in-out-sine":Nn(.445,.05,.55,.95),"ease-in-quad":Nn(.55,.085,.68,.53),"ease-out-quad":Nn(.25,.46,.45,.94),"ease-in-out-quad":Nn(.455,.03,.515,.955),"ease-in-cubic":Nn(.55,.055,.675,.19),"ease-out-cubic":Nn(.215,.61,.355,1),"ease-in-out-cubic":Nn(.645,.045,.355,1),"ease-in-quart":Nn(.895,.03,.685,.22),"ease-out-quart":Nn(.165,.84,.44,1),"ease-in-out-quart":Nn(.77,0,.175,1),"ease-in-quint":Nn(.755,.05,.855,.06),"ease-out-quint":Nn(.23,1,.32,1),"ease-in-out-quint":Nn(.86,0,.07,1),"ease-in-expo":Nn(.95,.05,.795,.035),"ease-out-expo":Nn(.19,1,.22,1),"ease-in-out-expo":Nn(1,0,0,1),"ease-in-circ":Nn(.6,.04,.98,.335),"ease-out-circ":Nn(.075,.82,.165,1),"ease-in-out-circ":Nn(.785,.135,.15,.86),spring:o(function(e,r,n){if(n===0)return M6.linear;var i=cZe(e,r,n);return function(a,s,l){return a+(s-a)*i(l)}},"spring"),"cubic-bezier":Nn};o(Dme,"getEasedValue");o(Lme,"getValue");o(W1,"ease");o(uZe,"step$1");o(Vb,"valid");o(hZe,"startAnimation");o(Rme,"stepAll");fZe={animate:un.animate(),animation:un.animation(),animated:un.animated(),clearQueue:un.clearQueue(),delay:un.delay(),delayAnimation:un.delayAnimation(),stop:un.stop(),addToAnimationPool:o(function(e){var r=this;r.styleEnabled()&&r._private.aniEles.merge(e)},"addToAnimationPool"),stopAnimationLoop:o(function(){this._private.animationsRunning=!1},"stopAnimationLoop"),startAnimationLoop:o(function(){var e=this;if(e._private.animationsRunning=!0,!e.styleEnabled())return;function r(){e._private.animationsRunning&&$6(o(function(a){Rme(a,e),r()},"animationStep"))}o(r,"headlessStep");var n=e.renderer();n&&n.beforeRender?n.beforeRender(o(function(a,s){Rme(s,e)},"rendererAnimationStep"),n.beforeRenderPriorities.animations):r()},"startAnimationLoop")},dZe={qualifierCompare:o(function(e,r){return e==null||r==null?e==null&&r==null:e.sameText(r)},"qualifierCompare"),eventMatches:o(function(e,r,n){var i=r.qualifier;return i!=null?e!==n.target&&f4(n.target)&&i.matches(n.target):!0},"eventMatches"),addEventFields:o(function(e,r){r.cy=e,r.target=e},"addEventFields"),callbackContext:o(function(e,r,n){return r.qualifier!=null?n.target:e},"callbackContext")},E6=o(function(e){return Zt(e)?new $f(e):e},"argSelector"),u1e={createEmitter:o(function(){var e=this._private;return e.emitter||(e.emitter=new aC(dZe,this)),this},"createEmitter"),emitter:o(function(){return this._private.emitter},"emitter"),on:o(function(e,r,n){return this.emitter().on(e,E6(r),n),this},"on"),removeListener:o(function(e,r,n){return this.emitter().removeListener(e,E6(r),n),this},"removeListener"),removeAllListeners:o(function(){return this.emitter().removeAllListeners(),this},"removeAllListeners"),one:o(function(e,r,n){return this.emitter().one(e,E6(r),n),this},"one"),once:o(function(e,r,n){return this.emitter().one(e,E6(r),n),this},"once"),emit:o(function(e,r){return this.emitter().emit(e,r),this},"emit"),emitAndNotify:o(function(e,r){return this.emit(e),this.notify(e,r),this},"emitAndNotify")};un.eventAliasesOn(u1e);CB={png:o(function(e){var r=this._private.renderer;return e=e||{},r.png(e)},"png"),jpg:o(function(e){var r=this._private.renderer;return e=e||{},e.bg=e.bg||"#fff",r.jpg(e)},"jpg")};CB.jpeg=CB.jpg;I6={layout:o(function(e){var r=this;if(e==null){oi("Layout options must be specified to make a layout");return}if(e.name==null){oi("A `name` must be specified to make a layout");return}var n=e.name,i=r.extension("layout",n);if(i==null){oi("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?");return}var a;Zt(e.eles)?a=r.$(e.eles):a=e.eles!=null?e.eles:r.$();var s=new i(ir({},e,{cy:r,eles:a}));return s},"layout")};I6.createLayout=I6.makeLayout=I6.layout;pZe={notify:o(function(e,r){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var i=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();r!=null&&i.merge(r);return}if(n.notificationsEnabled){var a=this.renderer();this.destroyed()||!a||a.notify(e,r)}},"notify"),notifications:o(function(e){var r=this._private;return e===void 0?r.notificationsEnabled:(r.notificationsEnabled=!!e,this)},"notifications"),noNotifications:o(function(e){this.notifications(!1),e(),this.notifications(!0)},"noNotifications"),batching:o(function(){return this._private.batchCount>0},"batching"),startBatch:o(function(){var e=this._private;return e.batchCount==null&&(e.batchCount=0),e.batchCount===0&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},"startBatch"),endBatch:o(function(){var e=this._private;if(e.batchCount===0)return this;if(e.batchCount--,e.batchCount===0){e.batchStyleEles.updateStyle();var r=this.renderer();Object.keys(e.batchNotifications).forEach(function(n){var i=e.batchNotifications[n];i.empty()?r.notify(n):r.notify(n,i)})}return this},"endBatch"),batch:o(function(e){return this.startBatch(),e(),this.endBatch(),this},"batch"),batchData:o(function(e){var r=this;return this.batch(function(){for(var n=Object.keys(e),i=0;i0;)r.removeChild(r.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach(function(n){var i=n._private;i.rscratch={},i.rstyle={},i.animation.current=[],i.animation.queue=[]})},"destroyRenderer"),onRender:o(function(e){return this.on("render",e)},"onRender"),offRender:o(function(e){return this.off("render",e)},"offRender")};AB.invalidateDimensions=AB.resize;O6={collection:o(function(e,r){return Zt(e)?this.$(e):xo(e)?e.collection():En(e)?(r||(r={}),new Sa(this,e,r.unique,r.removed)):new Sa(this)},"collection"),nodes:o(function(e){var r=this.$(function(n){return n.isNode()});return e?r.filter(e):r},"nodes"),edges:o(function(e){var r=this.$(function(n){return n.isEdge()});return e?r.filter(e):r},"edges"),$:o(function(e){var r=this._private.elements;return e?r.filter(e):r.spawnSelf()},"$"),mutableElements:o(function(){return this._private.elements},"mutableElements")};O6.elements=O6.filter=O6.$;qa={},Kb="t",gZe="f";qa.apply=function(t){for(var e=this,r=e._private,n=r.cy,i=n.collection(),a=0;a0;if(p||d&&m){var g=void 0;p&&m||p?g=h.properties:m&&(g=h.mappedProperties);for(var y=0;y1&&(S=1),l.color){var E=n.valueMin[0],_=n.valueMax[0],C=n.valueMin[1],D=n.valueMax[1],O=n.valueMin[2],R=n.valueMax[2],k=n.valueMin[3]==null?1:n.valueMin[3],L=n.valueMax[3]==null?1:n.valueMax[3],A=[Math.round(E+(_-E)*S),Math.round(C+(D-C)*S),Math.round(O+(R-O)*S),Math.round(k+(L-k)*S)];a={bypass:n.bypass,name:n.name,value:A,strValue:"rgb("+A[0]+", "+A[1]+", "+A[2]+")"}}else if(l.number){var I=n.valueMin+(n.valueMax-n.valueMin)*S;a=this.parse(n.name,I,n.bypass,p)}else return!1;if(!a)return y(),!1;a.mapping=n,n=a;break}case s.data:{for(var M=n.field.split("."),P=d.data,B=0;B0&&a>0){for(var l={},u=!1,h=0;h0?t.delayAnimation(s).play().promise().then(T):T()}).then(function(){return t.animation({style:l,duration:a,easing:t.pstyle("transition-timing-function").value,queue:!1}).play().promise()}).then(function(){r.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1})}else n.transitioning&&(this.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1)};qa.checkTrigger=function(t,e,r,n,i,a){var s=this.properties[e],l=i(s);l!=null&&l(r,n)&&a(s)};qa.checkZOrderTrigger=function(t,e,r,n){var i=this;this.checkTrigger(t,e,r,n,function(a){return a.triggersZOrder},function(){i._private.cy.notify("zorder",t)})};qa.checkBoundsTrigger=function(t,e,r,n){this.checkTrigger(t,e,r,n,function(i){return i.triggersBounds},function(i){t.dirtyCompoundBoundsCache(),t.dirtyBoundingBoxCache(),i.triggersBoundsOfParallelBeziers&&e==="curve-style"&&(r==="bezier"||n==="bezier")&&t.parallelEdges().forEach(function(a){a.dirtyBoundingBoxCache()}),i.triggersBoundsOfConnectedEdges&&e==="display"&&(r==="none"||n==="none")&&t.connectedEdges().forEach(function(a){a.dirtyBoundingBoxCache()})})};qa.checkTriggers=function(t,e,r,n){t.dirtyStyleCache(),this.checkZOrderTrigger(t,e,r,n),this.checkBoundsTrigger(t,e,r,n)};y4={};y4.applyBypass=function(t,e,r,n){var i=this,a=[],s=!0;if(e==="*"||e==="**"){if(r!==void 0)for(var l=0;li.length?n=n.substr(i.length):n=""}o(l,"removeSelAndBlockFromRemaining");function u(){a.length>s.length?a=a.substr(s.length):a=""}for(o(u,"removePropAndValFromRem");;){var h=n.match(/^\s*$/);if(h)break;var f=n.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!f){hn("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+n);break}i=f[0];var d=f[1];if(d!=="core"){var p=new $f(d);if(p.invalid){hn("Skipping parsing of block: Invalid selector found in string stylesheet: "+d),l();continue}}var m=f[2],g=!1;a=m;for(var y=[];;){var v=a.match(/^\s*$/);if(v)break;var x=a.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!x){hn("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+m),g=!0;break}s=x[0];var b=x[1],T=x[2],S=e.properties[b];if(!S){hn("Skipping property: Invalid property name in: "+s),u();continue}var w=r.parse(b,T);if(!w){hn("Skipping property: Invalid property definition in: "+s),u();continue}y.push({name:b,val:T}),u()}if(g){l();break}r.selector(d);for(var E=0;E=7&&e[0]==="d"&&(f=new RegExp(l.data.regex).exec(e))){if(r)return!1;var p=l.data;return{name:t,value:f,strValue:""+e,mapped:p,field:f[1],bypass:r}}else if(e.length>=10&&e[0]==="m"&&(d=new RegExp(l.mapData.regex).exec(e))){if(r||h.multiple)return!1;var m=l.mapData;if(!(h.color||h.number))return!1;var g=this.parse(t,d[4]);if(!g||g.mapped)return!1;var y=this.parse(t,d[5]);if(!y||y.mapped)return!1;if(g.pfValue===y.pfValue||g.strValue===y.strValue)return hn("`"+t+": "+e+"` is not a valid mapper because the output range is zero; converting to `"+t+": "+g.strValue+"`"),this.parse(t,g.strValue);if(h.color){var v=g.value,x=y.value,b=v[0]===x[0]&&v[1]===x[1]&&v[2]===x[2]&&(v[3]===x[3]||(v[3]==null||v[3]===1)&&(x[3]==null||x[3]===1));if(b)return!1}return{name:t,value:d,strValue:""+e,mapped:m,field:d[1],fieldMin:parseFloat(d[2]),fieldMax:parseFloat(d[3]),valueMin:g.value,valueMax:y.value,bypass:r}}}if(h.multiple&&n!=="multiple"){var T;if(u?T=e.split(/\s+/):En(e)?T=e:T=[e],h.evenMultiple&&T.length%2!==0)return null;for(var S=[],w=[],E=[],_="",C=!1,D=0;D0?" ":"")+O.strValue}return h.validate&&!h.validate(S,w)?null:h.singleEnum&&C?S.length===1&&Zt(S[0])?{name:t,value:S[0],strValue:S[0],bypass:r}:null:{name:t,value:S,pfValue:E,strValue:_,bypass:r,units:w}}var R=o(function(){for(var Q=0;Qh.max||h.strictMax&&e===h.max))return null;var M={name:t,value:e,strValue:""+e+(k||""),units:k,bypass:r};return h.unitless||k!=="px"&&k!=="em"?M.pfValue=e:M.pfValue=k==="px"||!k?e:this.getEmSizeInPixels()*e,(k==="ms"||k==="s")&&(M.pfValue=k==="ms"?e:1e3*e),(k==="deg"||k==="rad")&&(M.pfValue=k==="rad"?e:QYe(e)),k==="%"&&(M.pfValue=e/100),M}else if(h.propList){var P=[],B=""+e;if(B!=="none"){for(var F=B.split(/\s*,\s*|\s+/),z=0;z0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0){u=Math.min((s-2*r)/n.w,(l-2*r)/n.h),u=u>this._private.maxZoom?this._private.maxZoom:u,u=u=n.minZoom&&(n.maxZoom=r),this},"zoomRange"),minZoom:o(function(e){return e===void 0?this._private.minZoom:this.zoomRange({min:e})},"minZoom"),maxZoom:o(function(e){return e===void 0?this._private.maxZoom:this.zoomRange({max:e})},"maxZoom"),getZoomedViewport:o(function(e){var r=this._private,n=r.pan,i=r.zoom,a,s,l=!1;if(r.zoomingEnabled||(l=!0),_t(e)?s=e:Ur(e)&&(s=e.level,e.position!=null?a=J6(e.position,i,n):e.renderedPosition!=null&&(a=e.renderedPosition),a!=null&&!r.panningEnabled&&(l=!0)),s=s>r.maxZoom?r.maxZoom:s,s=sr.maxZoom||!r.zoomingEnabled?s=!0:(r.zoom=u,a.push("zoom"))}if(i&&(!s||!e.cancelOnFailedZoom)&&r.panningEnabled){var h=e.pan;_t(h.x)&&(r.pan.x=h.x,l=!1),_t(h.y)&&(r.pan.y=h.y,l=!1),l||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},"viewport"),center:o(function(e){var r=this.getCenterPan(e);return r&&(this._private.pan=r,this.emit("pan viewport"),this.notify("viewport")),this},"center"),getCenterPan:o(function(e,r){if(this._private.panningEnabled){if(Zt(e)){var n=e;e=this.mutableElements().filter(n)}else xo(e)||(e=this.mutableElements());if(e.length!==0){var i=e.boundingBox(),a=this.width(),s=this.height();r=r===void 0?this._private.zoom:r;var l={x:(a-r*(i.x1+i.x2))/2,y:(s-r*(i.y1+i.y2))/2};return l}}},"getCenterPan"),reset:o(function(){return!this._private.panningEnabled||!this._private.zoomingEnabled?this:(this.viewport({pan:{x:0,y:0},zoom:1}),this)},"reset"),invalidateSize:o(function(){this._private.sizeCache=null},"invalidateSize"),size:o(function(){var e=this._private,r=e.container,n=this;return e.sizeCache=e.sizeCache||(r?function(){var i=n.window().getComputedStyle(r),a=o(function(l){return parseFloat(i.getPropertyValue(l))},"val");return{width:r.clientWidth-a("padding-left")-a("padding-right"),height:r.clientHeight-a("padding-top")-a("padding-bottom")}}():{width:1,height:1})},"size"),width:o(function(){return this.size().width},"width"),height:o(function(){return this.size().height},"height"),extent:o(function(){var e=this._private.pan,r=this._private.zoom,n=this.renderedExtent(),i={x1:(n.x1-e.x)/r,x2:(n.x2-e.x)/r,y1:(n.y1-e.y)/r,y2:(n.y2-e.y)/r};return i.w=i.x2-i.x1,i.h=i.y2-i.y1,i},"extent"),renderedExtent:o(function(){var e=this.width(),r=this.height();return{x1:0,y1:0,x2:e,y2:r,w:e,h:r}},"renderedExtent"),multiClickDebounceTime:o(function(e){if(e)this._private.multiClickDebounceTime=e;else return this._private.multiClickDebounceTime;return this},"multiClickDebounceTime")};e0.centre=e0.center;e0.autolockNodes=e0.autolock;e0.autoungrabifyNodes=e0.autoungrabify;c4={data:un.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:un.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:un.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:un.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};c4.attr=c4.data;c4.removeAttr=c4.removeData;u4=o(function(e){var r=this;e=ir({},e);var n=e.container;n&&!F6(n)&&F6(n[0])&&(n=n[0]);var i=n?n._cyreg:null;i=i||{},i&&i.cy&&(i.cy.destroy(),i={});var a=i.readies=i.readies||[];n&&(n._cyreg=i),i.cy=r;var s=Hi!==void 0&&n!==void 0&&!e.headless,l=e;l.layout=ir({name:s?"grid":"null"},l.layout),l.renderer=ir({name:s?"canvas":"null"},l.renderer);var u=o(function(g,y,v){return y!==void 0?y:v!==void 0?v:g},"defVal"),h=this._private={container:n,ready:!1,options:l,elements:new Sa(this),listeners:[],aniEles:new Sa(this),data:l.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:u(!0,l.zoomingEnabled),userZoomingEnabled:u(!0,l.userZoomingEnabled),panningEnabled:u(!0,l.panningEnabled),userPanningEnabled:u(!0,l.userPanningEnabled),boxSelectionEnabled:u(!0,l.boxSelectionEnabled),autolock:u(!1,l.autolock,l.autolockNodes),autoungrabify:u(!1,l.autoungrabify,l.autoungrabifyNodes),autounselectify:u(!1,l.autounselectify),styleEnabled:l.styleEnabled===void 0?s:l.styleEnabled,zoom:_t(l.zoom)?l.zoom:1,pan:{x:Ur(l.pan)&&_t(l.pan.x)?l.pan.x:0,y:Ur(l.pan)&&_t(l.pan.y)?l.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:u(250,l.multiClickDebounceTime)};this.createEmitter(),this.selectionType(l.selectionType),this.zoomRange({min:l.minZoom,max:l.maxZoom});var f=o(function(g,y){var v=g.some(wqe);if(v)return sy.all(g).then(y);y(g)},"loadExtData");h.styleEnabled&&r.setStyle([]);var d=ir({},l,l.renderer);r.initRenderer(d);var p=o(function(g,y,v){r.notifications(!1);var x=r.mutableElements();x.length>0&&x.remove(),g!=null&&(Ur(g)||En(g))&&r.add(g),r.one("layoutready",function(T){r.notifications(!0),r.emit(T),r.one("load",y),r.emitAndNotify("load")}).one("layoutstop",function(){r.one("done",v),r.emit("done")});var b=ir({},r._private.options.layout);b.eles=r.elements(),r.layout(b).run()},"setElesAndLayout");f([l.style,l.elements],function(m){var g=m[0],y=m[1];h.styleEnabled&&r.style().append(g),p(y,function(){r.startAnimationLoop(),h.ready=!0,li(l.ready)&&r.on("ready",l.ready);for(var v=0;v0,l=!!t.boundingBox,u=e.extent(),h=Ys(l?t.boundingBox:{x1:u.x1,y1:u.y1,w:u.w,h:u.h}),f;if(xo(t.roots))f=t.roots;else if(En(t.roots)){for(var d=[],p=0;p0;){var I=A(),M=O(I,k);if(M)I.outgoers().filter(function(ae){return ae.isNode()&&r.has(ae)}).forEach(L);else if(M===null){hn("Detected double maximal shift for node `"+I.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}var P=0;if(t.avoidOverlap)for(var B=0;B0&&b[0].length<=3?ze/2:0),Ie=2*Math.PI/b[Be].length*He;return Be===0&&b[0].length===1&&(Le=1),{x:he.x+Le*Math.cos(Ie),y:he.y+Le*Math.sin(Ie)}}else{var xe=b[Be].length,q=Math.max(xe===1?0:l?(h.w-t.padding*2-le.w)/((t.grid?Se:xe)-1):(h.w-t.padding*2-le.w)/((t.grid?Se:xe)+1),P),de={x:he.x+(He+1-(xe+1)/2)*q,y:he.y+(Be+1-(ce+1)/2)*J};return de}},"getPosition");return r.nodes().layoutPositions(this,t,se),this};TZe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(f1e,"CircleLayout");f1e.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,a=n.nodes().not(":parent");e.sort&&(a=a.sort(e.sort));for(var s=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=e.sweep===void 0?2*Math.PI-2*Math.PI/a.length:e.sweep,h=u/Math.max(1,a.length-1),f,d=0,p=0;p1&&e.avoidOverlap){d*=1.75;var x=Math.cos(h)-Math.cos(0),b=Math.sin(h)-Math.sin(0),T=Math.sqrt(d*d/(x*x+b*b));f=Math.max(T,f)}var S=o(function(E,_){var C=e.startAngle+_*h*(i?1:-1),D=f*Math.cos(C),O=f*Math.sin(C),R={x:l.x+D,y:l.y+O};return R},"getPos");return n.nodes().layoutPositions(this,e,S),this};wZe={fit:!0,padding:30,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:o(function(e){return e.degree()},"concentric"),levelWidth:o(function(e){return e.maxDegree()/4},"levelWidth"),animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(d1e,"ConcentricLayout");d1e.prototype.run=function(){for(var t=this.options,e=t,r=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,n=t.cy,i=e.eles,a=i.nodes().not(":parent"),s=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=[],h=0,f=0;f0){var w=Math.abs(b[0].value-S.value);w>=v&&(b=[],x.push(b))}b.push(S)}var E=h+e.minNodeSpacing;if(!e.avoidOverlap){var _=x.length>0&&x[0].length>1,C=Math.min(s.w,s.h)/2-E,D=C/(x.length+_?1:0);E=Math.min(E,D)}for(var O=0,R=0;R1&&e.avoidOverlap){var I=Math.cos(A)-Math.cos(0),M=Math.sin(A)-Math.sin(0),P=Math.sqrt(E*E/(I*I+M*M));O=Math.max(P,O)}k.r=O,O+=E}if(e.equidistant){for(var B=0,F=0,z=0;z=t.numIter||(LZe(n,t),n.temperature=n.temperature*t.coolingFactor,n.temperature=t.animationThreshold&&a(),$6(d)}},"frame");f()}else{for(;h;)h=s(u),u++;Ime(n,t),l()}return this};uC.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this};uC.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};EZe=o(function(e,r,n){for(var i=n.eles.edges(),a=n.eles.nodes(),s=Ys(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),l={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:i.size(),temperature:n.initialTemp,clientWidth:s.w,clientHeight:s.h,boundingBox:s},u=n.eles.components(),h={},f=0;f0){l.graphSet.push(C);for(var f=0;fi.count?0:i.graph},"findLCA"),CZe=o(function t(e,r,n,i){var a=i.graphSet[n];if(-10)var d=i.nodeOverlap*f,p=Math.sqrt(l*l+u*u),m=d*l/p,g=d*u/p;else var y=q6(e,l,u),v=q6(r,-1*l,-1*u),x=v.x-y.x,b=v.y-y.y,T=x*x+b*b,p=Math.sqrt(T),d=(e.nodeRepulsion+r.nodeRepulsion)/T,m=d*x/p,g=d*b/p;e.isLocked||(e.offsetX-=m,e.offsetY-=g),r.isLocked||(r.offsetX+=m,r.offsetY+=g)}},"nodeRepulsion"),MZe=o(function(e,r,n,i){if(n>0)var a=e.maxX-r.minX;else var a=r.maxX-e.minX;if(i>0)var s=e.maxY-r.minY;else var s=r.maxY-e.minY;return a>=0&&s>=0?Math.sqrt(a*a+s*s):0},"nodesOverlap"),q6=o(function(e,r,n){var i=e.positionX,a=e.positionY,s=e.height||1,l=e.width||1,u=n/r,h=s/l,f={};return r===0&&0n?(f.x=i,f.y=a+s/2,f):0r&&-1*h<=u&&u<=h?(f.x=i-l/2,f.y=a-l*n/2/r,f):0=h)?(f.x=i+s*r/2/n,f.y=a+s/2,f):(0>n&&(u<=-1*h||u>=h)&&(f.x=i-s*r/2/n,f.y=a-s/2),f)},"findClippingPoint"),IZe=o(function(e,r){for(var n=0;nn){var v=r.gravity*m/y,x=r.gravity*g/y;p.offsetX+=v,p.offsetY+=x}}}}},"calculateGravityForces"),PZe=o(function(e,r){var n=[],i=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;i<=a;){var s=n[i++],l=e.idToIndex[s],u=e.layoutNodes[l],h=u.children;if(0n)var a={x:n*e/i,y:n*r/i};else var a={x:e,y:r};return a},"limitForce"),$Ze=o(function t(e,r){var n=e.parentId;if(n!=null){var i=r.layoutNodes[r.idToIndex[n]],a=!1;if((i.maxX==null||e.maxX+i.padRight>i.maxX)&&(i.maxX=e.maxX+i.padRight,a=!0),(i.minX==null||e.minX-i.padLefti.maxY)&&(i.maxY=e.maxY+i.padBottom,a=!0),(i.minY==null||e.minY-i.padTopx&&(g+=v+r.componentSpacing,m=0,y=0,v=0)}}},"separateComponents"),zZe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:o(function(e){},"position"),sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(m1e,"GridLayout");m1e.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=n.nodes().not(":parent");e.sort&&(i=i.sort(e.sort));var a=Ys(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(a.h===0||a.w===0)n.nodes().layoutPositions(this,e,function(K){return{x:a.x1,y:a.y1}});else{var s=i.size(),l=Math.sqrt(s*a.h/a.w),u=Math.round(l),h=Math.round(a.w/a.h*l),f=o(function(ee){if(ee==null)return Math.min(u,h);var Y=Math.min(u,h);Y==u?u=ee:h=ee},"small"),d=o(function(ee){if(ee==null)return Math.max(u,h);var Y=Math.max(u,h);Y==u?u=ee:h=ee},"large"),p=e.rows,m=e.cols!=null?e.cols:e.columns;if(p!=null&&m!=null)u=p,h=m;else if(p!=null&&m==null)u=p,h=Math.ceil(s/u);else if(p==null&&m!=null)h=m,u=Math.ceil(s/h);else if(h*u>s){var g=f(),y=d();(g-1)*y>=s?f(g-1):(y-1)*g>=s&&d(y-1)}else for(;h*u=s?d(x+1):f(v+1)}var b=a.w/h,T=a.h/u;if(e.condense&&(b=0,T=0),e.avoidOverlap)for(var S=0;S=h&&(I=0,A++)},"moveToNextCell"),P={},B=0;B(I=uXe(t,e,M[P],M[P+1],M[P+2],M[P+3])))return v(_,I),!0}else if(D.edgeType==="bezier"||D.edgeType==="multibezier"||D.edgeType==="self"||D.edgeType==="compound"){for(var M=D.allpts,P=0;P+5(I=cXe(t,e,M[P],M[P+1],M[P+2],M[P+3],M[P+4],M[P+5])))return v(_,I),!0}for(var B=B||C.source,F=F||C.target,z=i.getArrowWidth(O,R),$=[{name:"source",x:D.arrowStartX,y:D.arrowStartY,angle:D.srcArrowAngle},{name:"target",x:D.arrowEndX,y:D.arrowEndY,angle:D.tgtArrowAngle},{name:"mid-source",x:D.midX,y:D.midY,angle:D.midsrcArrowAngle},{name:"mid-target",x:D.midX,y:D.midY,angle:D.midtgtArrowAngle}],P=0;P<$.length;P++){var U=$[P],K=a.arrowShapes[_.pstyle(U.name+"-arrow-shape").value],ee=_.pstyle("width").pfValue;if(K.roughCollide(t,e,z,U.angle,{x:U.x,y:U.y},ee,f)&&K.collide(t,e,z,U.angle,{x:U.x,y:U.y},ee,f))return v(_),!0}h&&l.length>0&&(x(B),x(F))}o(b,"checkEdge");function T(_,C,D){return Wl(_,C,D)}o(T,"preprop");function S(_,C){var D=_._private,O=p,R;C?R=C+"-":R="",_.boundingBox();var k=D.labelBounds[C||"main"],L=_.pstyle(R+"label").value,A=_.pstyle("text-events").strValue==="yes";if(!(!A||!L)){var I=T(D.rscratch,"labelX",C),M=T(D.rscratch,"labelY",C),P=T(D.rscratch,"labelAngle",C),B=_.pstyle(R+"text-margin-x").pfValue,F=_.pstyle(R+"text-margin-y").pfValue,z=k.x1-O-B,$=k.x2+O-B,U=k.y1-O-F,K=k.y2+O-F;if(P){var ee=Math.cos(P),Y=Math.sin(P),ce=o(function(he,le){return he=he-I,le=le-M,{x:he*ee-le*Y+I,y:he*Y+le*ee+M}},"rotate"),Z=ce(z,U),ue=ce(z,K),Q=ce($,U),j=ce($,K),ne=[Z.x+B,Z.y+F,Q.x+B,Q.y+F,j.x+B,j.y+F,ue.x+B,ue.y+F];if(qs(t,e,ne))return v(_),!0}else if(ry(k,t,e))return v(_),!0}}o(S,"checkLabel");for(var w=s.length-1;w>=0;w--){var E=s[w];E.isNode()?x(E)||S(E):b(E)||S(E)||S(E,"source")||S(E,"target")}return l};r0.getAllInBox=function(t,e,r,n){var i=this.getCachedZSortedEles().interactive,a=[],s=Math.min(t,r),l=Math.max(t,r),u=Math.min(e,n),h=Math.max(e,n);t=s,r=l,e=u,n=h;for(var f=Ys({x1:t,y1:e,x2:r,y2:n}),d=0;d0?-(Math.PI-e.ang):Math.PI+e.ang},"invertVec"),qZe=o(function(e,r,n,i,a){if(e!==$me?zme(r,e,Kc):WZe(nl,Kc),zme(r,n,nl),Bme=Kc.nx*nl.ny-Kc.ny*nl.nx,Fme=Kc.nx*nl.nx-Kc.ny*-nl.ny,rh=Math.asin(Math.max(-1,Math.min(1,Bme))),Math.abs(rh)<1e-6){_B=r.x,DB=r.y,Yp=Y1=0;return}Xp=1,P6=!1,Fme<0?rh<0?rh=Math.PI+rh:(rh=Math.PI-rh,Xp=-1,P6=!0):rh>0&&(Xp=-1,P6=!0),r.radius!==void 0?Y1=r.radius:Y1=i,Up=rh/2,S6=Math.min(Kc.len/2,nl.len/2),a?(jc=Math.abs(Math.cos(Up)*Y1/Math.sin(Up)),jc>S6?(jc=S6,Yp=Math.abs(jc*Math.sin(Up)/Math.cos(Up))):Yp=Y1):(jc=Math.min(S6,Y1),Yp=Math.abs(jc*Math.sin(Up)/Math.cos(Up))),LB=r.x+nl.nx*jc,RB=r.y+nl.ny*jc,_B=LB-nl.ny*Yp*Xp,DB=RB+nl.nx*Yp*Xp,x1e=r.x+Kc.nx*jc,b1e=r.y+Kc.ny*jc,$me=r},"calcCornerArc");o(T1e,"drawPreparedRoundCorner");o(rF,"getRoundCorner");Ya={};Ya.findMidptPtsEtc=function(t,e){var r=e.posPts,n=e.intersectionPts,i=e.vectorNormInverse,a,s=t.pstyle("source-endpoint"),l=t.pstyle("target-endpoint"),u=s.units!=null&&l.units!=null,h=o(function(w,E,_,C){var D=C-E,O=_-w,R=Math.sqrt(O*O+D*D);return{x:-D/R,y:O/R}},"recalcVectorNormInverse"),f=t.pstyle("edge-distances").value;switch(f){case"node-position":a=r;break;case"intersection":a=n;break;case"endpoints":{if(u){var d=this.manualEndptToPx(t.source()[0],s),p=Ri(d,2),m=p[0],g=p[1],y=this.manualEndptToPx(t.target()[0],l),v=Ri(y,2),x=v[0],b=v[1],T={x1:m,y1:g,x2:x,y2:b};i=h(m,g,x,b),a=T}else hn("Edge ".concat(t.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),a=n;break}}return{midptPts:a,vectorNormInverse:i}};Ya.findHaystackPoints=function(t){for(var e=0;e0?Math.max(W-pe,0):Math.min(W+pe,0)},"subDWH"),L=k(O,C),A=k(R,D),I=!1;b===h?x=Math.abs(L)>Math.abs(A)?i:n:b===u||b===l?(x=n,I=!0):(b===a||b===s)&&(x=i,I=!0);var M=x===n,P=M?A:L,B=M?R:O,F=Sge(B),z=!1;!(I&&(S||E))&&(b===l&&B<0||b===u&&B>0||b===a&&B>0||b===s&&B<0)&&(F*=-1,P=F*Math.abs(P),z=!0);var $;if(S){var U=w<0?1+w:w;$=U*P}else{var K=w<0?P:0;$=K+w*F}var ee=o(function(W){return Math.abs(W)<_||Math.abs(W)>=Math.abs(P)},"getIsTooClose"),Y=ee($),ce=ee(Math.abs(P)-Math.abs($)),Z=Y||ce;if(Z&&!z)if(M){var ue=Math.abs(B)<=p/2,Q=Math.abs(O)<=m/2;if(ue){var j=(f.x1+f.x2)/2,ne=f.y1,te=f.y2;r.segpts=[j,ne,j,te]}else if(Q){var he=(f.y1+f.y2)/2,le=f.x1,J=f.x2;r.segpts=[le,he,J,he]}else r.segpts=[f.x1,f.y2]}else{var Se=Math.abs(B)<=d/2,se=Math.abs(R)<=g/2;if(Se){var ae=(f.y1+f.y2)/2,Oe=f.x1,ye=f.x2;r.segpts=[Oe,ae,ye,ae]}else if(se){var Be=(f.x1+f.x2)/2,He=f.y1,ze=f.y2;r.segpts=[Be,He,Be,ze]}else r.segpts=[f.x2,f.y1]}else if(M){var Le=f.y1+$+(v?p/2*F:0),Ie=f.x1,xe=f.x2;r.segpts=[Ie,Le,xe,Le]}else{var q=f.x1+$+(v?d/2*F:0),de=f.y1,ie=f.y2;r.segpts=[q,de,q,ie]}if(r.isRound){var oe=t.pstyle("taxi-radius").value,V=t.pstyle("radius-type").value[0]==="arc-radius";r.radii=new Array(r.segpts.length/2).fill(oe),r.isArcRadius=new Array(r.segpts.length/2).fill(V)}};Ya.tryToCorrectInvalidPoints=function(t,e){var r=t._private.rscratch;if(r.edgeType==="bezier"){var n=e.srcPos,i=e.tgtPos,a=e.srcW,s=e.srcH,l=e.tgtW,u=e.tgtH,h=e.srcShape,f=e.tgtShape,d=e.srcCornerRadius,p=e.tgtCornerRadius,m=e.srcRs,g=e.tgtRs,y=!_t(r.startX)||!_t(r.startY),v=!_t(r.arrowStartX)||!_t(r.arrowStartY),x=!_t(r.endX)||!_t(r.endY),b=!_t(r.arrowEndX)||!_t(r.arrowEndY),T=3,S=this.getArrowWidth(t.pstyle("width").pfValue,t.pstyle("arrow-scale").value)*this.arrowShapeWidth,w=T*S,E=Qp({x:r.ctrlpts[0],y:r.ctrlpts[1]},{x:r.startX,y:r.startY}),_=EA.poolIndex()){var I=L;L=A,A=I}var M=D.srcPos=L.position(),P=D.tgtPos=A.position(),B=D.srcW=L.outerWidth(),F=D.srcH=L.outerHeight(),z=D.tgtW=A.outerWidth(),$=D.tgtH=A.outerHeight(),U=D.srcShape=r.nodeShapes[e.getNodeShape(L)],K=D.tgtShape=r.nodeShapes[e.getNodeShape(A)],ee=D.srcCornerRadius=L.pstyle("corner-radius").value==="auto"?"auto":L.pstyle("corner-radius").pfValue,Y=D.tgtCornerRadius=A.pstyle("corner-radius").value==="auto"?"auto":A.pstyle("corner-radius").pfValue,ce=D.tgtRs=A._private.rscratch,Z=D.srcRs=L._private.rscratch;D.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var ue=0;ue0){var te=a,he=Wp(te,j1(r)),le=Wp(te,j1(ne)),J=he;if(le2){var Se=Wp(te,{x:ne[2],y:ne[3]});Se0){var ie=s,oe=Wp(ie,j1(r)),V=Wp(ie,j1(de)),Te=oe;if(V2){var W=Wp(ie,{x:de[2],y:de[3]});W=g||_){v={cp:S,segment:E};break}}if(v)break}var C=v.cp,D=v.segment,O=(g-x)/D.length,R=D.t1-D.t0,k=m?D.t0+R*O:D.t1-R*O;k=i4(0,k,1),e=Q1(C.p0,C.p1,C.p2,k),p=XZe(C.p0,C.p1,C.p2,k);break}case"straight":case"segments":case"haystack":{for(var L=0,A,I,M,P,B=n.allpts.length,F=0;F+3=g));F+=2);var z=g-I,$=z/A;$=i4(0,$,1),e=JYe(M,P,$),p=E1e(M,P);break}}s("labelX",d,e.x),s("labelY",d,e.y),s("labelAutoAngle",d,p)}},"calculateEndProjection");h("source"),h("target"),this.applyLabelDimensions(t)}};eu.applyLabelDimensions=function(t){this.applyPrefixedLabelDimensions(t),t.isEdge()&&(this.applyPrefixedLabelDimensions(t,"source"),this.applyPrefixedLabelDimensions(t,"target"))};eu.applyPrefixedLabelDimensions=function(t,e){var r=t._private,n=this.getLabelText(t,e),i=this.calculateLabelDimensions(t,n),a=t.pstyle("line-height").pfValue,s=t.pstyle("text-wrap").strValue,l=Wl(r.rscratch,"labelWrapCachedLines",e)||[],u=s!=="wrap"?1:Math.max(l.length,1),h=i.height/u,f=h*a,d=i.width,p=i.height+(u-1)*(a-1)*h;Nf(r.rstyle,"labelWidth",e,d),Nf(r.rscratch,"labelWidth",e,d),Nf(r.rstyle,"labelHeight",e,p),Nf(r.rscratch,"labelHeight",e,p),Nf(r.rscratch,"labelLineHeight",e,f)};eu.getLabelText=function(t,e){var r=t._private,n=e?e+"-":"",i=t.pstyle(n+"label").strValue,a=t.pstyle("text-transform").value,s=o(function(K,ee){return ee?(Nf(r.rscratch,K,e,ee),ee):Wl(r.rscratch,K,e)},"rscratch");if(!i)return"";a=="none"||(a=="uppercase"?i=i.toUpperCase():a=="lowercase"&&(i=i.toLowerCase()));var l=t.pstyle("text-wrap").value;if(l==="wrap"){var u=s("labelKey");if(u!=null&&s("labelWrapKey")===u)return s("labelWrapCachedText");for(var h="\u200B",f=i.split(` -`),d=t.pstyle("text-max-width").pfValue,p=t.pstyle("text-overflow-wrap").value,m=p==="anywhere",g=[],y=/[\s\u200b]+|$/g,v=0;vd){var w=x.matchAll(y),E="",_=0,C=vo(w),D;try{for(C.s();!(D=C.n()).done;){var O=D.value,R=O[0],k=x.substring(_,O.index);_=O.index+R.length;var L=E.length===0?k:E+k+R,A=this.calculateLabelDimensions(t,L),I=A.width;I<=d?E+=k+R:(E&&g.push(E),E=k+R)}}catch(U){C.e(U)}finally{C.f()}E.match(/^[\s\u200b]+$/)||g.push(E)}else g.push(x)}s("labelWrapCachedLines",g),i=s("labelWrapCachedText",g.join(` -`)),s("labelWrapKey",u)}else if(l==="ellipsis"){var M=t.pstyle("text-max-width").pfValue,P="",B="\u2026",F=!1;if(this.calculateLabelDimensions(t,i).widthM)break;P+=i[z],z===i.length-1&&(F=!0)}return F||(P+=B),P}return i};eu.getLabelJustification=function(t){var e=t.pstyle("text-justification").strValue,r=t.pstyle("text-halign").strValue;if(e==="auto")if(t.isNode())switch(r){case"left":return"right";case"right":return"left";default:return"center"}else return"center";else return e};eu.calculateLabelDimensions=function(t,e){var r=this,n=r.cy.window(),i=n.document,a=Bf(e,t._private.labelDimsKey),s=r.labelDimCache||(r.labelDimCache=[]),l=s[a];if(l!=null)return l;var u=0,h=t.pstyle("font-style").strValue,f=t.pstyle("font-size").pfValue,d=t.pstyle("font-family").strValue,p=t.pstyle("font-weight").strValue,m=this.labelCalcCanvas,g=this.labelCalcCanvasContext;if(!m){m=this.labelCalcCanvas=i.createElement("canvas"),g=this.labelCalcCanvasContext=m.getContext("2d");var y=m.style;y.position="absolute",y.left="-9999px",y.top="-9999px",y.zIndex="-1",y.visibility="hidden",y.pointerEvents="none"}g.font="".concat(h," ").concat(p," ").concat(f,"px ").concat(d);for(var v=0,x=0,b=e.split(` -`),T=0;T1&&arguments[1]!==void 0?arguments[1]:!0;if(e.merge(s),l)for(var u=0;u=t.desktopTapThreshold2}var ot=a(q);at&&(t.hoverData.tapholdCancelled=!0);var Yt=o(function(){var kt=t.hoverData.dragDelta=t.hoverData.dragDelta||[];kt.length===0?(kt.push(De[0]),kt.push(De[1])):(kt[0]+=De[0],kt[1]+=De[1])},"updateDragDelta");ie=!0,i(_e,["mousemove","vmousemove","tapdrag"],q,{x:W[0],y:W[1]});var Tt=o(function(){t.data.bgActivePosistion=void 0,t.hoverData.selecting||oe.emit({originalEvent:q,type:"boxstart",position:{x:W[0],y:W[1]}}),Pe[4]=1,t.hoverData.selecting=!0,t.redrawHint("select",!0),t.redraw()},"goIntoBoxMode");if(t.hoverData.which===3){if(at){var Mt={originalEvent:q,type:"cxtdrag",position:{x:W[0],y:W[1]}};Ve?Ve.emit(Mt):oe.emit(Mt),t.hoverData.cxtDragged=!0,(!t.hoverData.cxtOver||_e!==t.hoverData.cxtOver)&&(t.hoverData.cxtOver&&t.hoverData.cxtOver.emit({originalEvent:q,type:"cxtdragout",position:{x:W[0],y:W[1]}}),t.hoverData.cxtOver=_e,_e&&_e.emit({originalEvent:q,type:"cxtdragover",position:{x:W[0],y:W[1]}}))}}else if(t.hoverData.dragging){if(ie=!0,oe.panningEnabled()&&oe.userPanningEnabled()){var bt;if(t.hoverData.justStartedPan){var ut=t.hoverData.mdownPos;bt={x:(W[0]-ut[0])*V,y:(W[1]-ut[1])*V},t.hoverData.justStartedPan=!1}else bt={x:De[0]*V,y:De[1]*V};oe.panBy(bt),oe.emit("dragpan"),t.hoverData.dragged=!0}W=t.projectIntoViewport(q.clientX,q.clientY)}else if(Pe[4]==1&&(Ve==null||Ve.pannable())){if(at){if(!t.hoverData.dragging&&oe.boxSelectionEnabled()&&(ot||!oe.panningEnabled()||!oe.userPanningEnabled()))Tt();else if(!t.hoverData.selecting&&oe.panningEnabled()&&oe.userPanningEnabled()){var St=s(Ve,t.hoverData.downs);St&&(t.hoverData.dragging=!0,t.hoverData.justStartedPan=!0,Pe[4]=0,t.data.bgActivePosistion=j1(pe),t.redrawHint("select",!0),t.redraw())}Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate()}}else{if(Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate(),(!Ve||!Ve.grabbed())&&_e!=be&&(be&&i(be,["mouseout","tapdragout"],q,{x:W[0],y:W[1]}),_e&&i(_e,["mouseover","tapdragover"],q,{x:W[0],y:W[1]}),t.hoverData.last=_e),Ve)if(at){if(oe.boxSelectionEnabled()&&ot)Ve&&Ve.grabbed()&&(x(qe),Ve.emit("freeon"),qe.emit("free"),t.dragData.didDrag&&(Ve.emit("dragfreeon"),qe.emit("dragfree"))),Tt();else if(Ve&&Ve.grabbed()&&t.nodeIsDraggable(Ve)){var ft=!t.dragData.didDrag;ft&&t.redrawHint("eles",!0),t.dragData.didDrag=!0,t.hoverData.draggingEles||y(qe,{inDragLayer:!0});var vt={x:0,y:0};if(_t(De[0])&&_t(De[1])&&(vt.x+=De[0],vt.y+=De[1],ft)){var nt=t.hoverData.dragDelta;nt&&_t(nt[0])&&_t(nt[1])&&(vt.x+=nt[0],vt.y+=nt[1])}t.hoverData.draggingEles=!0,qe.silentShift(vt).emit("position drag"),t.redrawHint("drag",!0),t.redraw()}}else Yt();ie=!0}if(Pe[2]=W[0],Pe[3]=W[1],ie)return q.stopPropagation&&q.stopPropagation(),q.preventDefault&&q.preventDefault(),!1}},"mousemoveHandler"),!1);var k,L,A;t.registerBinding(e,"mouseup",o(function(q){if(!(t.hoverData.which===1&&q.which!==1&&t.hoverData.capture)){var de=t.hoverData.capture;if(de){t.hoverData.capture=!1;var ie=t.cy,oe=t.projectIntoViewport(q.clientX,q.clientY),V=t.selection,Te=t.findNearestElement(oe[0],oe[1],!0,!1),W=t.dragData.possibleDragElements,pe=t.hoverData.down,ve=a(q);if(t.data.bgActivePosistion&&(t.redrawHint("select",!0),t.redraw()),t.hoverData.tapholdCancelled=!0,t.data.bgActivePosistion=void 0,pe&&pe.unactivate(),t.hoverData.which===3){var Pe={originalEvent:q,type:"cxttapend",position:{x:oe[0],y:oe[1]}};if(pe?pe.emit(Pe):ie.emit(Pe),!t.hoverData.cxtDragged){var _e={originalEvent:q,type:"cxttap",position:{x:oe[0],y:oe[1]}};pe?pe.emit(_e):ie.emit(_e)}t.hoverData.cxtDragged=!1,t.hoverData.which=null}else if(t.hoverData.which===1){if(i(Te,["mouseup","tapend","vmouseup"],q,{x:oe[0],y:oe[1]}),!t.dragData.didDrag&&!t.hoverData.dragged&&!t.hoverData.selecting&&!t.hoverData.isOverThresholdDrag&&(i(pe,["click","tap","vclick"],q,{x:oe[0],y:oe[1]}),L=!1,q.timeStamp-A<=ie.multiClickDebounceTime()?(k&&clearTimeout(k),L=!0,A=null,i(pe,["dblclick","dbltap","vdblclick"],q,{x:oe[0],y:oe[1]})):(k=setTimeout(function(){L||i(pe,["oneclick","onetap","voneclick"],q,{x:oe[0],y:oe[1]})},ie.multiClickDebounceTime()),A=q.timeStamp)),pe==null&&!t.dragData.didDrag&&!t.hoverData.selecting&&!t.hoverData.dragged&&!a(q)&&(ie.$(r).unselect(["tapunselect"]),W.length>0&&t.redrawHint("eles",!0),t.dragData.possibleDragElements=W=ie.collection()),Te==pe&&!t.dragData.didDrag&&!t.hoverData.selecting&&Te!=null&&Te._private.selectable&&(t.hoverData.dragging||(ie.selectionType()==="additive"||ve?Te.selected()?Te.unselect(["tapunselect"]):Te.select(["tapselect"]):ve||(ie.$(r).unmerge(Te).unselect(["tapunselect"]),Te.select(["tapselect"]))),t.redrawHint("eles",!0)),t.hoverData.selecting){var be=ie.collection(t.getAllInBox(V[0],V[1],V[2],V[3]));t.redrawHint("select",!0),be.length>0&&t.redrawHint("eles",!0),ie.emit({type:"boxend",originalEvent:q,position:{x:oe[0],y:oe[1]}});var Ve=o(function(at){return at.selectable()&&!at.selected()},"eleWouldBeSelected");ie.selectionType()==="additive"||ve||ie.$(r).unmerge(be).unselect(),be.emit("box").stdFilter(Ve).select().emit("boxselect"),t.redraw()}if(t.hoverData.dragging&&(t.hoverData.dragging=!1,t.redrawHint("select",!0),t.redrawHint("eles",!0),t.redraw()),!V[4]){t.redrawHint("drag",!0),t.redrawHint("eles",!0);var De=pe&&pe.grabbed();x(W),De&&(pe.emit("freeon"),W.emit("free"),t.dragData.didDrag&&(pe.emit("dragfreeon"),W.emit("dragfree")))}}V[4]=0,t.hoverData.down=null,t.hoverData.cxtStarted=!1,t.hoverData.draggingEles=!1,t.hoverData.selecting=!1,t.hoverData.isOverThresholdDrag=!1,t.dragData.didDrag=!1,t.hoverData.dragged=!1,t.hoverData.dragDelta=[],t.hoverData.mdownPos=null,t.hoverData.mdownGPos=null,t.hoverData.which=null}}},"mouseupHandler"),!1);var I=o(function(q){if(!t.scrollingPage){var de=t.cy,ie=de.zoom(),oe=de.pan(),V=t.projectIntoViewport(q.clientX,q.clientY),Te=[V[0]*ie+oe.x,V[1]*ie+oe.y];if(t.hoverData.draggingEles||t.hoverData.dragging||t.hoverData.cxtStarted||D()){q.preventDefault();return}if(de.panningEnabled()&&de.userPanningEnabled()&&de.zoomingEnabled()&&de.userZoomingEnabled()){q.preventDefault(),t.data.wheelZooming=!0,clearTimeout(t.data.wheelTimeout),t.data.wheelTimeout=setTimeout(function(){t.data.wheelZooming=!1,t.redrawHint("eles",!0),t.redraw()},150);var W;q.deltaY!=null?W=q.deltaY/-250:q.wheelDeltaY!=null?W=q.wheelDeltaY/1e3:W=q.wheelDelta/1e3,W=W*t.wheelSensitivity;var pe=q.deltaMode===1;pe&&(W*=33);var ve=de.zoom()*Math.pow(10,W);q.type==="gesturechange"&&(ve=t.gestureStartZoom*q.scale),de.zoom({level:ve,renderedPosition:{x:Te[0],y:Te[1]}}),de.emit(q.type==="gesturechange"?"pinchzoom":"scrollzoom")}}},"wheelHandler");t.registerBinding(t.container,"wheel",I,!0),t.registerBinding(e,"scroll",o(function(q){t.scrollingPage=!0,clearTimeout(t.scrollingPageTimeout),t.scrollingPageTimeout=setTimeout(function(){t.scrollingPage=!1},250)},"scrollHandler"),!0),t.registerBinding(t.container,"gesturestart",o(function(q){t.gestureStartZoom=t.cy.zoom(),t.hasTouchStarted||q.preventDefault()},"gestureStartHandler"),!0),t.registerBinding(t.container,"gesturechange",function(xe){t.hasTouchStarted||I(xe)},!0),t.registerBinding(t.container,"mouseout",o(function(q){var de=t.projectIntoViewport(q.clientX,q.clientY);t.cy.emit({originalEvent:q,type:"mouseout",position:{x:de[0],y:de[1]}})},"mouseOutHandler"),!1),t.registerBinding(t.container,"mouseover",o(function(q){var de=t.projectIntoViewport(q.clientX,q.clientY);t.cy.emit({originalEvent:q,type:"mouseover",position:{x:de[0],y:de[1]}})},"mouseOverHandler"),!1);var M,P,B,F,z,$,U,K,ee,Y,ce,Z,ue,Q=o(function(q,de,ie,oe){return Math.sqrt((ie-q)*(ie-q)+(oe-de)*(oe-de))},"distance"),j=o(function(q,de,ie,oe){return(ie-q)*(ie-q)+(oe-de)*(oe-de)},"distanceSq"),ne;t.registerBinding(t.container,"touchstart",ne=o(function(q){if(t.hasTouchStarted=!0,!!O(q)){T(),t.touchData.capture=!0,t.data.bgActivePosistion=void 0;var de=t.cy,ie=t.touchData.now,oe=t.touchData.earlier;if(q.touches[0]){var V=t.projectIntoViewport(q.touches[0].clientX,q.touches[0].clientY);ie[0]=V[0],ie[1]=V[1]}if(q.touches[1]){var V=t.projectIntoViewport(q.touches[1].clientX,q.touches[1].clientY);ie[2]=V[0],ie[3]=V[1]}if(q.touches[2]){var V=t.projectIntoViewport(q.touches[2].clientX,q.touches[2].clientY);ie[4]=V[0],ie[5]=V[1]}if(q.touches[1]){t.touchData.singleTouchMoved=!0,x(t.dragData.touchDragEles);var Te=t.findContainerClientCoords();ee=Te[0],Y=Te[1],ce=Te[2],Z=Te[3],M=q.touches[0].clientX-ee,P=q.touches[0].clientY-Y,B=q.touches[1].clientX-ee,F=q.touches[1].clientY-Y,ue=0<=M&&M<=ce&&0<=B&&B<=ce&&0<=P&&P<=Z&&0<=F&&F<=Z;var W=de.pan(),pe=de.zoom();z=Q(M,P,B,F),$=j(M,P,B,F),U=[(M+B)/2,(P+F)/2],K=[(U[0]-W.x)/pe,(U[1]-W.y)/pe];var ve=200,Pe=ve*ve;if($=1){for(var st=t.touchData.startPosition=[null,null,null,null,null,null],Ue=0;Ue=t.touchTapThreshold2}if(de&&t.touchData.cxt){q.preventDefault();var st=q.touches[0].clientX-ee,Ue=q.touches[0].clientY-Y,ct=q.touches[1].clientX-ee,We=q.touches[1].clientY-Y,ot=j(st,Ue,ct,We),Yt=ot/$,Tt=150,Mt=Tt*Tt,bt=1.5,ut=bt*bt;if(Yt>=ut||ot>=Mt){t.touchData.cxt=!1,t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var St={originalEvent:q,type:"cxttapend",position:{x:V[0],y:V[1]}};t.touchData.start?(t.touchData.start.unactivate().emit(St),t.touchData.start=null):oe.emit(St)}}if(de&&t.touchData.cxt){var St={originalEvent:q,type:"cxtdrag",position:{x:V[0],y:V[1]}};t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.touchData.start?t.touchData.start.emit(St):oe.emit(St),t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxtDragged=!0;var ft=t.findNearestElement(V[0],V[1],!0,!0);(!t.touchData.cxtOver||ft!==t.touchData.cxtOver)&&(t.touchData.cxtOver&&t.touchData.cxtOver.emit({originalEvent:q,type:"cxtdragout",position:{x:V[0],y:V[1]}}),t.touchData.cxtOver=ft,ft&&ft.emit({originalEvent:q,type:"cxtdragover",position:{x:V[0],y:V[1]}}))}else if(de&&q.touches[2]&&oe.boxSelectionEnabled())q.preventDefault(),t.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,t.touchData.selecting||oe.emit({originalEvent:q,type:"boxstart",position:{x:V[0],y:V[1]}}),t.touchData.selecting=!0,t.touchData.didSelect=!0,ie[4]=1,!ie||ie.length===0||ie[0]===void 0?(ie[0]=(V[0]+V[2]+V[4])/3,ie[1]=(V[1]+V[3]+V[5])/3,ie[2]=(V[0]+V[2]+V[4])/3+1,ie[3]=(V[1]+V[3]+V[5])/3+1):(ie[2]=(V[0]+V[2]+V[4])/3,ie[3]=(V[1]+V[3]+V[5])/3),t.redrawHint("select",!0),t.redraw();else if(de&&q.touches[1]&&!t.touchData.didSelect&&oe.zoomingEnabled()&&oe.panningEnabled()&&oe.userZoomingEnabled()&&oe.userPanningEnabled()){q.preventDefault(),t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var vt=t.dragData.touchDragEles;if(vt){t.redrawHint("drag",!0);for(var nt=0;nt0&&!t.hoverData.draggingEles&&!t.swipePanning&&t.data.bgActivePosistion!=null&&(t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.redraw())}},"touchmoveHandler"),!1);var he;t.registerBinding(e,"touchcancel",he=o(function(q){var de=t.touchData.start;t.touchData.capture=!1,de&&de.unactivate()},"touchcancelHandler"));var le,J,Se,se;if(t.registerBinding(e,"touchend",le=o(function(q){var de=t.touchData.start,ie=t.touchData.capture;if(ie)q.touches.length===0&&(t.touchData.capture=!1),q.preventDefault();else return;var oe=t.selection;t.swipePanning=!1,t.hoverData.draggingEles=!1;var V=t.cy,Te=V.zoom(),W=t.touchData.now,pe=t.touchData.earlier;if(q.touches[0]){var ve=t.projectIntoViewport(q.touches[0].clientX,q.touches[0].clientY);W[0]=ve[0],W[1]=ve[1]}if(q.touches[1]){var ve=t.projectIntoViewport(q.touches[1].clientX,q.touches[1].clientY);W[2]=ve[0],W[3]=ve[1]}if(q.touches[2]){var ve=t.projectIntoViewport(q.touches[2].clientX,q.touches[2].clientY);W[4]=ve[0],W[5]=ve[1]}de&&de.unactivate();var Pe;if(t.touchData.cxt){if(Pe={originalEvent:q,type:"cxttapend",position:{x:W[0],y:W[1]}},de?de.emit(Pe):V.emit(Pe),!t.touchData.cxtDragged){var _e={originalEvent:q,type:"cxttap",position:{x:W[0],y:W[1]}};de?de.emit(_e):V.emit(_e)}t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxt=!1,t.touchData.start=null,t.redraw();return}if(!q.touches[2]&&V.boxSelectionEnabled()&&t.touchData.selecting){t.touchData.selecting=!1;var be=V.collection(t.getAllInBox(oe[0],oe[1],oe[2],oe[3]));oe[0]=void 0,oe[1]=void 0,oe[2]=void 0,oe[3]=void 0,oe[4]=0,t.redrawHint("select",!0),V.emit({type:"boxend",originalEvent:q,position:{x:W[0],y:W[1]}});var Ve=o(function(Mt){return Mt.selectable()&&!Mt.selected()},"eleWouldBeSelected");be.emit("box").stdFilter(Ve).select().emit("boxselect"),be.nonempty()&&t.redrawHint("eles",!0),t.redraw()}if(de?.unactivate(),q.touches[2])t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);else if(!q.touches[1]){if(!q.touches[0]){if(!q.touches[0]){t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var De=t.dragData.touchDragEles;if(de!=null){var qe=de._private.grabbed;x(De),t.redrawHint("drag",!0),t.redrawHint("eles",!0),qe&&(de.emit("freeon"),De.emit("free"),t.dragData.didDrag&&(de.emit("dragfreeon"),De.emit("dragfree"))),i(de,["touchend","tapend","vmouseup","tapdragout"],q,{x:W[0],y:W[1]}),de.unactivate(),t.touchData.start=null}else{var at=t.findNearestElement(W[0],W[1],!0,!0);i(at,["touchend","tapend","vmouseup","tapdragout"],q,{x:W[0],y:W[1]})}var Rt=t.touchData.startPosition[0]-W[0],st=Rt*Rt,Ue=t.touchData.startPosition[1]-W[1],ct=Ue*Ue,We=st+ct,ot=We*Te*Te;t.touchData.singleTouchMoved||(de||V.$(":selected").unselect(["tapunselect"]),i(de,["tap","vclick"],q,{x:W[0],y:W[1]}),J=!1,q.timeStamp-se<=V.multiClickDebounceTime()?(Se&&clearTimeout(Se),J=!0,se=null,i(de,["dbltap","vdblclick"],q,{x:W[0],y:W[1]})):(Se=setTimeout(function(){J||i(de,["onetap","voneclick"],q,{x:W[0],y:W[1]})},V.multiClickDebounceTime()),se=q.timeStamp)),de!=null&&!t.dragData.didDrag&&de._private.selectable&&ot"u"){var ae=[],Oe=o(function(q){return{clientX:q.clientX,clientY:q.clientY,force:1,identifier:q.pointerId,pageX:q.pageX,pageY:q.pageY,radiusX:q.width/2,radiusY:q.height/2,screenX:q.screenX,screenY:q.screenY,target:q.target}},"makeTouch"),ye=o(function(q){return{event:q,touch:Oe(q)}},"makePointer"),Be=o(function(q){ae.push(ye(q))},"addPointer"),He=o(function(q){for(var de=0;de0)return U[0]}return null},"getCurveT"),g=Object.keys(p),y=0;y0?m:_ge(a,s,e,r,n,i,l,u)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){u=u==="auto"?Zp(i,a):u;var h=2*u;if(ih(e,r,this.points,s,l,i,a-h,[0,-1],n)||ih(e,r,this.points,s,l,i-h,a,[0,-1],n))return!0;var f=i/2+2*n,d=a/2+2*n,p=[s-f,l-d,s-f,l,s+f,l,s+f,l-d];return!!(qs(e,r,p)||jp(e,r,h,h,s+i/2-u,l+a/2-u,n)||jp(e,r,h,h,s-i/2+u,l+a/2-u,n))},"checkPoint")}};sh.registerNodeShapes=function(){var t=this.nodeShapes={},e=this;this.generateEllipse(),this.generatePolygon("triangle",Ts(3,0)),this.generateRoundPolygon("round-triangle",Ts(3,0)),this.generatePolygon("rectangle",Ts(4,0)),t.square=t.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();{var r=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",r),this.generateRoundPolygon("round-diamond",r)}this.generatePolygon("pentagon",Ts(5,0)),this.generateRoundPolygon("round-pentagon",Ts(5,0)),this.generatePolygon("hexagon",Ts(6,0)),this.generateRoundPolygon("round-hexagon",Ts(6,0)),this.generatePolygon("heptagon",Ts(7,0)),this.generateRoundPolygon("round-heptagon",Ts(7,0)),this.generatePolygon("octagon",Ts(8,0)),this.generateRoundPolygon("round-octagon",Ts(8,0));var n=new Array(20);{var i=bB(5,0),a=bB(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;l=e.deqFastCost*S)break}else if(h){if(b>=e.deqCost*m||b>=e.deqAvgCost*p)break}else if(T>=e.deqNoDrawCost*dB)break;var w=e.deq(n,v,y);if(w.length>0)for(var E=0;E0&&(e.onDeqd(n,g),!h&&e.shouldRedraw(n,g,v,y)&&a())},"dequeue"),l=e.priority||zB;i.beforeRender(s,l(n))}},"setupDequeueingImpl")},"setupDequeueing")},KZe=function(){function t(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:z6;Vf(this,t),this.idsByKey=new Zc,this.keyForId=new Zc,this.cachesByLvl=new Zc,this.lvls=[],this.getKey=e,this.doesEleInvalidateKey=r}return o(t,"ElementTextureCacheLookup"),Uf(t,[{key:"getIdsFor",value:o(function(r){r==null&&oi("Can not get id list for null key");var n=this.idsByKey,i=this.idsByKey.get(r);return i||(i=new ay,n.set(r,i)),i},"getIdsFor")},{key:"addIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).add(n)},"addIdForKey")},{key:"deleteIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).delete(n)},"deleteIdForKey")},{key:"getNumberOfIdsForKey",value:o(function(r){return r==null?0:this.getIdsFor(r).size},"getNumberOfIdsForKey")},{key:"updateKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);this.deleteIdForKey(i,n),this.addIdForKey(a,n),this.keyForId.set(n,a)},"updateKeyMappingFor")},{key:"deleteKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteIdForKey(i,n),this.keyForId.delete(n)},"deleteKeyMappingFor")},{key:"keyHasChangedFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);return i!==a},"keyHasChangedFor")},{key:"isInvalid",value:o(function(r){return this.keyHasChangedFor(r)||this.doesEleInvalidateKey(r)},"isInvalid")},{key:"getCachesAt",value:o(function(r){var n=this.cachesByLvl,i=this.lvls,a=n.get(r);return a||(a=new Zc,n.set(r,a),i.push(r)),a},"getCachesAt")},{key:"getCache",value:o(function(r,n){return this.getCachesAt(n).get(r)},"getCache")},{key:"get",value:o(function(r,n){var i=this.getKey(r),a=this.getCache(i,n);return a!=null&&this.updateKeyMappingFor(r),a},"get")},{key:"getForCachedKey",value:o(function(r,n){var i=this.keyForId.get(r.id()),a=this.getCache(i,n);return a},"getForCachedKey")},{key:"hasCache",value:o(function(r,n){return this.getCachesAt(n).has(r)},"hasCache")},{key:"has",value:o(function(r,n){var i=this.getKey(r);return this.hasCache(i,n)},"has")},{key:"setCache",value:o(function(r,n,i){i.key=r,this.getCachesAt(n).set(r,i)},"setCache")},{key:"set",value:o(function(r,n,i){var a=this.getKey(r);this.setCache(a,n,i),this.updateKeyMappingFor(r)},"set")},{key:"deleteCache",value:o(function(r,n){this.getCachesAt(n).delete(r)},"deleteCache")},{key:"delete",value:o(function(r,n){var i=this.getKey(r);this.deleteCache(i,n)},"_delete")},{key:"invalidateKey",value:o(function(r){var n=this;this.lvls.forEach(function(i){return n.deleteCache(r,i)})},"invalidateKey")},{key:"invalidate",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteKeyMappingFor(r);var a=this.doesEleInvalidateKey(r);return a&&this.invalidateKey(i),a||this.getNumberOfIdsForKey(i)===0},"invalidate")}]),t}(),Hme=25,C6=50,B6=-4,NB=3,L1e=7.99,QZe=8,ZZe=1024,JZe=1024,eJe=1024,tJe=.2,rJe=.8,nJe=10,iJe=.15,aJe=.1,sJe=.9,oJe=.9,lJe=100,cJe=1,K1={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},uJe=oa({getKey:null,doesEleInvalidateKey:z6,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:bge,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),jb=o(function(e,r){var n=this;n.renderer=e,n.onDequeues=[];var i=uJe(r);ir(n,i),n.lookup=new KZe(i.getKey,i.doesEleInvalidateKey),n.setupDequeueing()},"ElementTextureCache"),Yi=jb.prototype;Yi.reasons=K1;Yi.getTextureQueue=function(t){var e=this;return e.eleImgCaches=e.eleImgCaches||{},e.eleImgCaches[t]=e.eleImgCaches[t]||[]};Yi.getRetiredTextureQueue=function(t){var e=this,r=e.eleImgCaches.retired=e.eleImgCaches.retired||{},n=r[t]=r[t]||[];return n};Yi.getElementQueue=function(){var t=this,e=t.eleCacheQueue=t.eleCacheQueue||new m4(function(r,n){return n.reqs-r.reqs});return e};Yi.getElementKeyToQueue=function(){var t=this,e=t.eleKeyToCacheQueue=t.eleKeyToCacheQueue||{};return e};Yi.getElement=function(t,e,r,n,i){var a=this,s=this.renderer,l=s.cy.zoom(),u=this.lookup;if(!e||e.w===0||e.h===0||isNaN(e.w)||isNaN(e.h)||!t.visible()||t.removed()||!a.allowEdgeTxrCaching&&t.isEdge()||!a.allowParentTxrCaching&&t.isParent())return null;if(n==null&&(n=Math.ceil(VB(l*r))),n=L1e||n>NB)return null;var h=Math.pow(2,n),f=e.h*h,d=e.w*h,p=s.eleTextBiggerThanMin(t,h);if(!this.isVisible(t,p))return null;var m=u.get(t,n);if(m&&m.invalidated&&(m.invalidated=!1,m.texture.invalidatedWidth-=m.width),m)return m;var g;if(f<=Hme?g=Hme:f<=C6?g=C6:g=Math.ceil(f/C6)*C6,f>eJe||d>JZe)return null;var y=a.getTextureQueue(g),v=y[y.length-2],x=o(function(){return a.recycleTexture(g,d)||a.addTexture(g,d)},"addNewTxr");v||(v=y[y.length-1]),v||(v=x()),v.width-v.usedWidthn;R--)D=a.getElement(t,e,r,R,K1.downscale);O()}else return a.queueElement(t,E.level-1),E;else{var k;if(!T&&!S&&!w)for(var L=n-1;L>=B6;L--){var A=u.get(t,L);if(A){k=A;break}}if(b(k))return a.queueElement(t,n),k;v.context.translate(v.usedWidth,0),v.context.scale(h,h),this.drawElement(v.context,t,e,p,!1),v.context.scale(1/h,1/h),v.context.translate(-v.usedWidth,0)}return m={x:v.usedWidth,texture:v,level:n,scale:h,width:d,height:f,scaledLabelShown:p},v.usedWidth+=Math.ceil(d+QZe),v.eleCaches.push(m),u.set(t,n,m),a.checkTextureFullness(v),m};Yi.invalidateElements=function(t){for(var e=0;e=tJe*t.width&&this.retireTexture(t)};Yi.checkTextureFullness=function(t){var e=this,r=e.getTextureQueue(t.height);t.usedWidth/t.width>rJe&&t.fullnessChecks>=nJe?Ff(r,t):t.fullnessChecks++};Yi.retireTexture=function(t){var e=this,r=t.height,n=e.getTextureQueue(r),i=this.lookup;Ff(n,t),t.retired=!0;for(var a=t.eleCaches,s=0;s=e)return s.retired=!1,s.usedWidth=0,s.invalidatedWidth=0,s.fullnessChecks=0,GB(s.eleCaches),s.context.setTransform(1,0,0,1,0,0),s.context.clearRect(0,0,s.width,s.height),Ff(i,s),n.push(s),s}};Yi.queueElement=function(t,e){var r=this,n=r.getElementQueue(),i=r.getElementKeyToQueue(),a=this.getKey(t),s=i[a];if(s)s.level=Math.max(s.level,e),s.eles.merge(t),s.reqs++,n.updateItem(s);else{var l={eles:t.spawn().merge(t),level:e,reqs:1,key:a};n.push(l),i[a]=l}};Yi.dequeue=function(t){for(var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=[],a=e.lookup,s=0;s0;s++){var l=r.pop(),u=l.key,h=l.eles[0],f=a.hasCache(h,l.level);if(n[u]=null,f)continue;i.push(l);var d=e.getBoundingBox(h);e.getElement(h,d,t,l.level,K1.dequeue)}return i};Yi.removeFromQueue=function(t){var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=this.getKey(t),a=n[i];a!=null&&(a.eles.length===1?(a.reqs=$B,r.updateItem(a),r.pop(),n[i]=null):a.eles.unmerge(t))};Yi.onDequeue=function(t){this.onDequeues.push(t)};Yi.offDequeue=function(t){Ff(this.onDequeues,t)};Yi.setupDequeueing=D1e.setupDequeueing({deqRedrawThreshold:lJe,deqCost:iJe,deqAvgCost:aJe,deqNoDrawCost:sJe,deqFastCost:oJe,deq:o(function(e,r,n){return e.dequeue(r,n)},"deq"),onDeqd:o(function(e,r){for(var n=0;n=fJe||r>X6)return null}n.validateLayersElesOrdering(r,t);var u=n.layersByLevel,h=Math.pow(2,r),f=u[r]=u[r]||[],d,p=n.levelIsComplete(r,t),m,g=o(function(){var O=o(function(I){if(n.validateLayersElesOrdering(I,t),n.levelIsComplete(I,t))return m=u[I],!0},"canUseAsTmpLvl"),R=o(function(I){if(!m)for(var M=r+I;Qb<=M&&M<=X6&&!O(M);M+=I);},"checkLvls");R(1),R(-1);for(var k=f.length-1;k>=0;k--){var L=f[k];L.invalid&&Ff(f,L)}},"checkTempLevels");if(!p)g();else return f;var y=o(function(){if(!d){d=Ys();for(var O=0;Oqme||L>qme)return null;var A=k*L;if(A>bJe)return null;var I=n.makeLayer(d,r);if(R!=null){var M=f.indexOf(R)+1;f.splice(M,0,I)}else(O.insert===void 0||O.insert)&&f.unshift(I);return I},"makeLayer");if(n.skipping&&!l)return null;for(var x=null,b=t.length/hJe,T=!l,S=0;S=b||!Age(x.bb,w.boundingBox()))&&(x=v({insert:!0,after:x}),!x))return null;m||T?n.queueLayer(x,w):n.drawEleInLayer(x,w,r,e),x.eles.push(w),_[r]=x}return m||(T?null:f)};Ca.getEleLevelForLayerLevel=function(t,e){return t};Ca.drawEleInLayer=function(t,e,r,n){var i=this,a=this.renderer,s=t.context,l=e.boundingBox();l.w===0||l.h===0||!e.visible()||(r=i.getEleLevelForLayerLevel(r,n),a.setImgSmoothing(s,!1),a.drawCachedElement(s,e,null,null,r,TJe),a.setImgSmoothing(s,!0))};Ca.levelIsComplete=function(t,e){var r=this,n=r.layersByLevel[t];if(!n||n.length===0)return!1;for(var i=0,a=0;a0||s.invalid)return!1;i+=s.eles.length}return i===e.length};Ca.validateLayersElesOrdering=function(t,e){var r=this.layersByLevel[t];if(r)for(var n=0;n0){e=!0;break}}return e};Ca.invalidateElements=function(t){var e=this;t.length!==0&&(e.lastInvalidationTime=nh(),!(t.length===0||!e.haveLayers())&&e.updateElementsInLayers(t,o(function(n,i,a){e.invalidateLayer(n)},"invalAssocLayers")))};Ca.invalidateLayer=function(t){if(this.lastInvalidationTime=nh(),!t.invalid){var e=t.level,r=t.eles,n=this.layersByLevel[e];Ff(n,t),t.elesQueue=[],t.invalid=!0,t.replacement&&(t.replacement.invalid=!0);for(var i=0;i3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l=e._private.rscratch;if(!(a&&!e.visible())&&!(l.badLine||l.allpts==null||isNaN(l.allpts[0]))){var u;r&&(u=r,t.translate(-u.x1,-u.y1));var h=a?e.pstyle("opacity").value:1,f=a?e.pstyle("line-opacity").value:1,d=e.pstyle("curve-style").value,p=e.pstyle("line-style").value,m=e.pstyle("width").pfValue,g=e.pstyle("line-cap").value,y=e.pstyle("line-outline-width").value,v=e.pstyle("line-outline-color").value,x=h*f,b=h*f,T=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;d==="straight-triangle"?(s.eleStrokeStyle(t,e,I),s.drawEdgeTrianglePath(e,t,l.allpts)):(t.lineWidth=m,t.lineCap=g,s.eleStrokeStyle(t,e,I),s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLine"),S=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;if(t.lineWidth=m+y,t.lineCap=g,y>0)s.colorStrokeStyle(t,v[0],v[1],v[2],I);else{t.lineCap="butt";return}d==="straight-triangle"?s.drawEdgeTrianglePath(e,t,l.allpts):(s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLineOutline"),w=o(function(){i&&s.drawEdgeOverlay(t,e)},"drawOverlay"),E=o(function(){i&&s.drawEdgeUnderlay(t,e)},"drawUnderlay"),_=o(function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:b;s.drawArrowheads(t,e,I)},"drawArrows"),C=o(function(){s.drawElementText(t,e,null,n)},"drawText");t.lineJoin="round";var D=e.pstyle("ghost").value==="yes";if(D){var O=e.pstyle("ghost-offset-x").pfValue,R=e.pstyle("ghost-offset-y").pfValue,k=e.pstyle("ghost-opacity").value,L=x*k;t.translate(O,R),T(L),_(L),t.translate(-O,-R)}else S();E(),T(),_(),w(),C(),r&&t.translate(u.x1,u.y1)}};M1e=o(function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(r,n){if(n.visible()){var i=n.pstyle("".concat(e,"-opacity")).value;if(i!==0){var a=this,s=a.usePaths(),l=n._private.rscratch,u=n.pstyle("".concat(e,"-padding")).pfValue,h=2*u,f=n.pstyle("".concat(e,"-color")).value;r.lineWidth=h,l.edgeType==="self"&&!s?r.lineCap="butt":r.lineCap="round",a.colorStrokeStyle(r,f[0],f[1],f[2],i),a.drawEdgePath(n,r,l.allpts,"solid")}}}},"drawEdgeOverlayUnderlay");oh.drawEdgeOverlay=M1e("overlay");oh.drawEdgeUnderlay=M1e("underlay");oh.drawEdgePath=function(t,e,r,n){var i=t._private.rscratch,a=e,s,l=!1,u=this.usePaths(),h=t.pstyle("line-dash-pattern").pfValue,f=t.pstyle("line-dash-offset").pfValue;if(u){var d=r.join("$"),p=i.pathCacheKey&&i.pathCacheKey===d;p?(s=e=i.pathCache,l=!0):(s=e=new Path2D,i.pathCacheKey=d,i.pathCache=s)}if(a.setLineDash)switch(n){case"dotted":a.setLineDash([1,1]);break;case"dashed":a.setLineDash(h),a.lineDashOffset=f;break;case"solid":a.setLineDash([]);break}if(!l&&!i.badLine)switch(e.beginPath&&e.beginPath(),e.moveTo(r[0],r[1]),i.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var m=2;m+35&&arguments[5]!==void 0?arguments[5]:!0,s=this;if(n==null){if(a&&!s.eleTextBiggerThanMin(e))return}else if(n===!1)return;if(e.isNode()){var l=e.pstyle("label");if(!l||!l.value)return;var u=s.getLabelJustification(e);t.textAlign=u,t.textBaseline="bottom"}else{var h=e.element()._private.rscratch.badLine,f=e.pstyle("label"),d=e.pstyle("source-label"),p=e.pstyle("target-label");if(h||(!f||!f.value)&&(!d||!d.value)&&(!p||!p.value))return;t.textAlign="center",t.textBaseline="bottom"}var m=!r,g;r&&(g=r,t.translate(-g.x1,-g.y1)),i==null?(s.drawText(t,e,null,m,a),e.isEdge()&&(s.drawText(t,e,"source",m,a),s.drawText(t,e,"target",m,a))):s.drawText(t,e,i,m,a),r&&t.translate(g.x1,g.y1)};n0.getFontCache=function(t){var e;this.fontCaches=this.fontCaches||[];for(var r=0;r2&&arguments[2]!==void 0?arguments[2]:!0,n=e.pstyle("font-style").strValue,i=e.pstyle("font-size").pfValue+"px",a=e.pstyle("font-family").strValue,s=e.pstyle("font-weight").strValue,l=r?e.effectiveOpacity()*e.pstyle("text-opacity").value:1,u=e.pstyle("text-outline-opacity").value*l,h=e.pstyle("color").value,f=e.pstyle("text-outline-color").value;t.font=n+" "+s+" "+i+" "+a,t.lineJoin="round",this.colorFillStyle(t,h[0],h[1],h[2],l),this.colorStrokeStyle(t,f[0],f[1],f[2],u)};o(mB,"roundRect");n0.getTextAngle=function(t,e){var r,n=t._private,i=n.rscratch,a=e?e+"-":"",s=t.pstyle(a+"text-rotation");if(s.strValue==="autorotate"){var l=Wl(i,"labelAngle",e);r=t.isEdge()?l:0}else s.strValue==="none"?r=0:r=s.pfValue;return r};n0.drawText=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=e._private,s=a.rscratch,l=i?e.effectiveOpacity():1;if(!(i&&(l===0||e.pstyle("text-opacity").value===0))){r==="main"&&(r=null);var u=Wl(s,"labelX",r),h=Wl(s,"labelY",r),f,d,p=this.getLabelText(e,r);if(p!=null&&p!==""&&!isNaN(u)&&!isNaN(h)){this.setupTextStyle(t,e,i);var m=r?r+"-":"",g=Wl(s,"labelWidth",r),y=Wl(s,"labelHeight",r),v=e.pstyle(m+"text-margin-x").pfValue,x=e.pstyle(m+"text-margin-y").pfValue,b=e.isEdge(),T=e.pstyle("text-halign").value,S=e.pstyle("text-valign").value;b&&(T="center",S="center"),u+=v,h+=x;var w;switch(n?w=this.getTextAngle(e,r):w=0,w!==0&&(f=u,d=h,t.translate(f,d),t.rotate(w),u=0,h=0),S){case"top":break;case"center":h+=y/2;break;case"bottom":h+=y;break}var E=e.pstyle("text-background-opacity").value,_=e.pstyle("text-border-opacity").value,C=e.pstyle("text-border-width").pfValue,D=e.pstyle("text-background-padding").pfValue,O=e.pstyle("text-background-shape").strValue,R=O.indexOf("round")===0,k=2;if(E>0||C>0&&_>0){var L=u-D;switch(T){case"left":L-=g;break;case"center":L-=g/2;break}var A=h-y-D,I=g+2*D,M=y+2*D;if(E>0){var P=t.fillStyle,B=e.pstyle("text-background-color").value;t.fillStyle="rgba("+B[0]+","+B[1]+","+B[2]+","+E*l+")",R?mB(t,L,A,I,M,k):t.fillRect(L,A,I,M),t.fillStyle=P}if(C>0&&_>0){var F=t.strokeStyle,z=t.lineWidth,$=e.pstyle("text-border-color").value,U=e.pstyle("text-border-style").value;if(t.strokeStyle="rgba("+$[0]+","+$[1]+","+$[2]+","+_*l+")",t.lineWidth=C,t.setLineDash)switch(U){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"double":t.lineWidth=C/4,t.setLineDash([]);break;case"solid":t.setLineDash([]);break}if(R?mB(t,L,A,I,M,k,"stroke"):t.strokeRect(L,A,I,M),U==="double"){var K=C/2;R?mB(t,L+K,A+K,I-K*2,M-K*2,k,"stroke"):t.strokeRect(L+K,A+K,I-K*2,M-K*2)}t.setLineDash&&t.setLineDash([]),t.lineWidth=z,t.strokeStyle=F}}var ee=2*e.pstyle("text-outline-width").pfValue;if(ee>0&&(t.lineWidth=ee),e.pstyle("text-wrap").value==="wrap"){var Y=Wl(s,"labelWrapCachedLines",r),ce=Wl(s,"labelLineHeight",r),Z=g/2,ue=this.getLabelJustification(e);switch(ue==="auto"||(T==="left"?ue==="left"?u+=-g:ue==="center"&&(u+=-Z):T==="center"?ue==="left"?u+=-Z:ue==="right"&&(u+=Z):T==="right"&&(ue==="center"?u+=Z:ue==="right"&&(u+=g))),S){case"top":h-=(Y.length-1)*ce;break;case"center":case"bottom":h-=(Y.length-1)*ce;break}for(var Q=0;Q0&&t.strokeText(Y[Q],u,h),t.fillText(Y[Q],u,h),h+=ce}else ee>0&&t.strokeText(p,u,h),t.fillText(p,u,h);w!==0&&(t.rotate(-w),t.translate(-f,-d))}}};py={};py.drawNode=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l,u,h=e._private,f=h.rscratch,d=e.position();if(!(!_t(d.x)||!_t(d.y))&&!(a&&!e.visible())){var p=a?e.effectiveOpacity():1,m=s.usePaths(),g,y=!1,v=e.padding();l=e.width()+2*v,u=e.height()+2*v;var x;r&&(x=r,t.translate(-x.x1,-x.y1));for(var b=e.pstyle("background-image"),T=b.value,S=new Array(T.length),w=new Array(T.length),E=0,_=0;_0&&arguments[0]!==void 0?arguments[0]:L;s.eleFillStyle(t,e,oe)},"setupShapeColor"),Q=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:$;s.colorStrokeStyle(t,A[0],A[1],A[2],oe)},"setupBorderColor"),j=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Y;s.colorStrokeStyle(t,K[0],K[1],K[2],oe)},"setupOutlineColor"),ne=o(function(oe,V,Te,W){var pe=s.nodePathCache=s.nodePathCache||[],ve=xge(Te==="polygon"?Te+","+W.join(","):Te,""+V,""+oe,""+Z),Pe=pe[ve],_e,be=!1;return Pe!=null?(_e=Pe,be=!0,f.pathCache=_e):(_e=new Path2D,pe[ve]=f.pathCache=_e),{path:_e,cacheHit:be}},"getPath"),te=e.pstyle("shape").strValue,he=e.pstyle("shape-polygon-points").pfValue;if(m){t.translate(d.x,d.y);var le=ne(l,u,te,he);g=le.path,y=le.cacheHit}var J=o(function(){if(!y){var oe=d;m&&(oe={x:0,y:0}),s.nodeShapes[s.getNodeShape(e)].draw(g||t,oe.x,oe.y,l,u,Z,f)}m?t.fill(g):t.fill()},"drawShape"),Se=o(function(){for(var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,Te=h.backgrounding,W=0,pe=0;pe0&&arguments[0]!==void 0?arguments[0]:!1,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:p;s.hasPie(e)&&(s.drawPie(t,e,V),oe&&(m||s.nodeShapes[s.getNodeShape(e)].draw(t,d.x,d.y,l,u,Z,f)))},"drawPie"),ae=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=(R>0?R:-R)*oe,Te=R>0?0:255;R!==0&&(s.colorFillStyle(t,Te,Te,Te,V),m?t.fill(g):t.fill())},"darken"),Oe=o(function(){if(k>0){if(t.lineWidth=k,t.lineCap=P,t.lineJoin=M,t.setLineDash)switch(I){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash(F),t.lineDashOffset=z;break;case"solid":case"double":t.setLineDash([]);break}if(B!=="center"){if(t.save(),t.lineWidth*=2,B==="inside")m?t.clip(g):t.clip();else{var oe=new Path2D;oe.rect(-l/2-k,-u/2-k,l+2*k,u+2*k),oe.addPath(g),t.clip(oe,"evenodd")}m?t.stroke(g):t.stroke(),t.restore()}else m?t.stroke(g):t.stroke();if(I==="double"){t.lineWidth=k/3;var V=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",m?t.stroke(g):t.stroke(),t.globalCompositeOperation=V}t.setLineDash&&t.setLineDash([])}},"drawBorder"),ye=o(function(){if(U>0){if(t.lineWidth=U,t.lineCap="butt",t.setLineDash)switch(ee){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"solid":case"double":t.setLineDash([]);break}var oe=d;m&&(oe={x:0,y:0});var V=s.getNodeShape(e),Te=k;B==="inside"&&(Te=0),B==="outside"&&(Te*=2);var W=(l+Te+(U+ce))/l,pe=(u+Te+(U+ce))/u,ve=l*W,Pe=u*pe,_e=s.nodeShapes[V].points,be;if(m){var Ve=ne(ve,Pe,V,_e);be=Ve.path}if(V==="ellipse")s.drawEllipsePath(be||t,oe.x,oe.y,ve,Pe);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(V)){var De=0,qe=0,at=0;V==="round-diamond"?De=(Te+ce+U)*1.4:V==="round-heptagon"?(De=(Te+ce+U)*1.075,at=-(Te/2+ce+U)/35):V==="round-hexagon"?De=(Te+ce+U)*1.12:V==="round-pentagon"?(De=(Te+ce+U)*1.13,at=-(Te/2+ce+U)/15):V==="round-tag"?(De=(Te+ce+U)*1.12,qe=(Te/2+U+ce)*.07):V==="round-triangle"&&(De=(Te+ce+U)*(Math.PI/2),at=-(Te+ce/2+U)/Math.PI),De!==0&&(W=(l+De)/l,ve=l*W,["round-hexagon","round-tag"].includes(V)||(pe=(u+De)/u,Pe=u*pe)),Z=Z==="auto"?Lge(ve,Pe):Z;for(var Rt=ve/2,st=Pe/2,Ue=Z+(Te+U+ce)/2,ct=new Array(_e.length/2),We=new Array(_e.length/2),ot=0;ot<_e.length/2;ot++)ct[ot]={x:oe.x+qe+Rt*_e[ot*2],y:oe.y+at+st*_e[ot*2+1]};var Yt,Tt,Mt,bt,ut=ct.length;for(Tt=ct[ut-1],Yt=0;Yt0){if(i=i||n.position(),a==null||s==null){var m=n.padding();a=n.width()+2*m,s=n.height()+2*m}l.colorFillStyle(r,f[0],f[1],f[2],h),l.nodeShapes[d].draw(r,i.x,i.y,a+u*2,s+u*2,p),r.fill()}}}},"drawNodeOverlayUnderlay");py.drawNodeOverlay=I1e("overlay");py.drawNodeUnderlay=I1e("underlay");py.hasPie=function(t){return t=t[0],t._private.hasPie};py.drawPie=function(t,e,r,n){e=e[0],n=n||e.position();var i=e.cy().style(),a=e.pstyle("pie-size"),s=n.x,l=n.y,u=e.width(),h=e.height(),f=Math.min(u,h)/2,d=0,p=this.usePaths();p&&(s=0,l=0),a.units==="%"?f=f*a.pfValue:a.pfValue!==void 0&&(f=a.pfValue/2);for(var m=1;m<=i.pieBackgroundN;m++){var g=e.pstyle("pie-"+m+"-background-size").value,y=e.pstyle("pie-"+m+"-background-color").value,v=e.pstyle("pie-"+m+"-background-opacity").value*r,x=g/100;x+d>1&&(x=1-d);var b=1.5*Math.PI+2*Math.PI*d,T=2*Math.PI*x,S=b+T;g===0||d>=1||d+x>1||(t.beginPath(),t.moveTo(s,l),t.arc(s,l,f,b,S),t.closePath(),this.colorFillStyle(t,y[0],y[1],y[2],v),t.fill(),d+=x)}};ws={},NJe=100;ws.getPixelRatio=function(){var t=this.data.contexts[0];if(this.forcedPixelRatio!=null)return this.forcedPixelRatio;var e=this.cy.window(),r=t.backingStorePixelRatio||t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return(e.devicePixelRatio||1)/r};ws.paintCache=function(t){for(var e=this.paintCaches=this.paintCaches||[],r=!0,n,i=0;ie.minMbLowQualFrames&&(e.motionBlurPxRatio=e.mbPxRBlurry)),e.clearingMotionBlur&&(e.motionBlurPxRatio=1),e.textureDrawLastFrame&&!d&&(f[e.NODE]=!0,f[e.SELECT_BOX]=!0);var b=r.style(),T=r.zoom(),S=s!==void 0?s:T,w=r.pan(),E={x:w.x,y:w.y},_={zoom:T,pan:{x:w.x,y:w.y}},C=e.prevViewport,D=C===void 0||_.zoom!==C.zoom||_.pan.x!==C.pan.x||_.pan.y!==C.pan.y;!D&&!(y&&!g)&&(e.motionBlurPxRatio=1),l&&(E=l),S*=u,E.x*=u,E.y*=u;var O=e.getCachedZSortedEles();function R(Q,j,ne,te,he){var le=Q.globalCompositeOperation;Q.globalCompositeOperation="destination-out",e.colorFillStyle(Q,255,255,255,e.motionBlurTransparency),Q.fillRect(j,ne,te,he),Q.globalCompositeOperation=le}o(R,"mbclear");function k(Q,j){var ne,te,he,le;!e.clearingMotionBlur&&(Q===h.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]||Q===h.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG])?(ne={x:w.x*m,y:w.y*m},te=T*m,he=e.canvasWidth*m,le=e.canvasHeight*m):(ne=E,te=S,he=e.canvasWidth,le=e.canvasHeight),Q.setTransform(1,0,0,1,0,0),j==="motionBlur"?R(Q,0,0,he,le):!n&&(j===void 0||j)&&Q.clearRect(0,0,he,le),i||(Q.translate(ne.x,ne.y),Q.scale(te,te)),l&&Q.translate(l.x,l.y),s&&Q.scale(s,s)}if(o(k,"setContextTransform"),d||(e.textureDrawLastFrame=!1),d){if(e.textureDrawLastFrame=!0,!e.textureCache){e.textureCache={},e.textureCache.bb=r.mutableElements().boundingBox(),e.textureCache.texture=e.data.bufferCanvases[e.TEXTURE_BUFFER];var L=e.data.bufferContexts[e.TEXTURE_BUFFER];L.setTransform(1,0,0,1,0,0),L.clearRect(0,0,e.canvasWidth*e.textureMult,e.canvasHeight*e.textureMult),e.render({forcedContext:L,drawOnlyNodeLayer:!0,forcedPxRatio:u*e.textureMult});var _=e.textureCache.viewport={zoom:r.zoom(),pan:r.pan(),width:e.canvasWidth,height:e.canvasHeight};_.mpan={x:(0-_.pan.x)/_.zoom,y:(0-_.pan.y)/_.zoom}}f[e.DRAG]=!1,f[e.NODE]=!1;var A=h.contexts[e.NODE],I=e.textureCache.texture,_=e.textureCache.viewport;A.setTransform(1,0,0,1,0,0),p?R(A,0,0,_.width,_.height):A.clearRect(0,0,_.width,_.height);var M=b.core("outside-texture-bg-color").value,P=b.core("outside-texture-bg-opacity").value;e.colorFillStyle(A,M[0],M[1],M[2],P),A.fillRect(0,0,_.width,_.height);var T=r.zoom();k(A,!1),A.clearRect(_.mpan.x,_.mpan.y,_.width/_.zoom/u,_.height/_.zoom/u),A.drawImage(I,_.mpan.x,_.mpan.y,_.width/_.zoom/u,_.height/_.zoom/u)}else e.textureOnViewport&&!n&&(e.textureCache=null);var B=r.extent(),F=e.pinching||e.hoverData.dragging||e.swipePanning||e.data.wheelZooming||e.hoverData.draggingEles||e.cy.animated(),z=e.hideEdgesOnViewport&&F,$=[];if($[e.NODE]=!f[e.NODE]&&p&&!e.clearedForMotionBlur[e.NODE]||e.clearingMotionBlur,$[e.NODE]&&(e.clearedForMotionBlur[e.NODE]=!0),$[e.DRAG]=!f[e.DRAG]&&p&&!e.clearedForMotionBlur[e.DRAG]||e.clearingMotionBlur,$[e.DRAG]&&(e.clearedForMotionBlur[e.DRAG]=!0),f[e.NODE]||i||a||$[e.NODE]){var U=p&&!$[e.NODE]&&m!==1,A=n||(U?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]:h.contexts[e.NODE]),K=p&&!U?"motionBlur":void 0;k(A,K),z?e.drawCachedNodes(A,O.nondrag,u,B):e.drawLayeredElements(A,O.nondrag,u,B),e.debug&&e.drawDebugPoints(A,O.nondrag),!i&&!p&&(f[e.NODE]=!1)}if(!a&&(f[e.DRAG]||i||$[e.DRAG])){var U=p&&!$[e.DRAG]&&m!==1,A=n||(U?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG]:h.contexts[e.DRAG]);k(A,p&&!U?"motionBlur":void 0),z?e.drawCachedNodes(A,O.drag,u,B):e.drawCachedElements(A,O.drag,u,B),e.debug&&e.drawDebugPoints(A,O.drag),!i&&!p&&(f[e.DRAG]=!1)}if(this.drawSelectionRectangle(t,k),p&&m!==1){var ee=h.contexts[e.NODE],Y=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_NODE],ce=h.contexts[e.DRAG],Z=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_DRAG],ue=o(function(j,ne,te){j.setTransform(1,0,0,1,0,0),te||!x?j.clearRect(0,0,e.canvasWidth,e.canvasHeight):R(j,0,0,e.canvasWidth,e.canvasHeight);var he=m;j.drawImage(ne,0,0,e.canvasWidth*he,e.canvasHeight*he,0,0,e.canvasWidth,e.canvasHeight)},"drawMotionBlur");(f[e.NODE]||$[e.NODE])&&(ue(ee,Y,$[e.NODE]),f[e.NODE]=!1),(f[e.DRAG]||$[e.DRAG])&&(ue(ce,Z,$[e.DRAG]),f[e.DRAG]=!1)}e.prevViewport=_,e.clearingMotionBlur&&(e.clearingMotionBlur=!1,e.motionBlurCleared=!0,e.motionBlur=!0),p&&(e.motionBlurTimeout=setTimeout(function(){e.motionBlurTimeout=null,e.clearedForMotionBlur[e.NODE]=!1,e.clearedForMotionBlur[e.DRAG]=!1,e.motionBlur=!1,e.clearingMotionBlur=!d,e.mbFrames=0,f[e.NODE]=!0,f[e.DRAG]=!0,e.redraw()},NJe)),n||r.emit("render")};ws.drawSelectionRectangle=function(t,e){var r=this,n=r.cy,i=r.data,a=n.style(),s=t.drawOnlyNodeLayer,l=t.drawAllLayers,u=i.canvasNeedsRedraw,h=t.forcedContext;if(r.showFps||!s&&u[r.SELECT_BOX]&&!l){var f=h||i.contexts[r.SELECT_BOX];if(e(f),r.selection[4]==1&&(r.hoverData.selecting||r.touchData.selecting)){var d=r.cy.zoom(),p=a.core("selection-box-border-width").value/d;f.lineWidth=p,f.fillStyle="rgba("+a.core("selection-box-color").value[0]+","+a.core("selection-box-color").value[1]+","+a.core("selection-box-color").value[2]+","+a.core("selection-box-opacity").value+")",f.fillRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]),p>0&&(f.strokeStyle="rgba("+a.core("selection-box-border-color").value[0]+","+a.core("selection-box-border-color").value[1]+","+a.core("selection-box-border-color").value[2]+","+a.core("selection-box-opacity").value+")",f.strokeRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]))}if(i.bgActivePosistion&&!r.hoverData.selecting){var d=r.cy.zoom(),m=i.bgActivePosistion;f.fillStyle="rgba("+a.core("active-bg-color").value[0]+","+a.core("active-bg-color").value[1]+","+a.core("active-bg-color").value[2]+","+a.core("active-bg-opacity").value+")",f.beginPath(),f.arc(m.x,m.y,a.core("active-bg-size").pfValue/d,0,2*Math.PI),f.fill()}var g=r.lastRedrawTime;if(r.showFps&&g){g=Math.round(g);var y=Math.round(1e3/g),v="1 frame = "+g+" ms = "+y+" fps";if(f.setTransform(1,0,0,1,0,0),f.fillStyle="rgba(255, 0, 0, 0.75)",f.strokeStyle="rgba(255, 0, 0, 0.75)",f.font="30px Arial",!Ub){var x=f.measureText(v);Ub=x.actualBoundingBoxAscent}f.fillText(v,0,Ub);var b=60;f.strokeRect(0,Ub+10,250,20),f.fillRect(0,Ub+10,250*Math.min(y/b,1),20)}l||(u[r.SELECT_BOX]=!1)}};o(Kme,"compileShader");o(MJe,"createProgram");o(IJe,"createTextureCanvas");o(aF,"getEffectivePanZoom");o(gB,"modelToRenderedPosition");o(A6,"toWebGLColor");o(_6,"indexToVec4");o(OJe,"vec4ToIndex");o(PJe,"createTexture");o(O1e,"getTypeInfo");o(P1e,"createTypedArray");o(BJe,"createTypedArrayView");o(FJe,"createBufferStaticDraw");o(yo,"createBufferDynamicDraw");o($Je,"createPickingFrameBuffer");Qme=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});o(Zb,"create");o(B1e,"identity");o(zJe,"multiply");o(j6,"translate");o(F1e,"rotate");o(sF,"scale");o(GJe,"projection");Jb={SCREEN:{name:"screen",screen:!0},PICKING:{name:"picking",picking:!0}},Hb=oa({getKey:null,drawElement:null,getBoundingBox:null,getRotation:null,getRotationPoint:null,getRotationOffset:null,isVisible:null,getPadding:null}),VJe=function(){function t(e,r){Vf(this,t),this.debugID=Math.floor(Math.random()*1e4),this.r=e,this.atlasSize=r.webglTexSize,this.rows=r.webglTexRows,this.enableWrapping=r.enableWrapping,this.texHeight=Math.floor(this.atlasSize/this.rows),this.maxTexWidth=this.atlasSize,this.texture=null,this.canvas=null,this.needsBuffer=!0,this.freePointer={x:0,row:0},this.keyToLocation=new Map,this.canvas=r.createTextureCanvas(e,this.atlasSize,this.atlasSize),this.scratch=r.createTextureCanvas(e,this.atlasSize,this.texHeight,"scratch")}return o(t,"Atlas"),Uf(t,[{key:"getKeys",value:o(function(){return new Set(this.keyToLocation.keys())},"getKeys")},{key:"getScale",value:o(function(r){var n=r.w,i=r.h,a=this.texHeight,s=this.maxTexWidth,l=a/i,u=n*l,h=i*l;return u>s&&(l=s/n,u=n*l,h=i*l),{scale:l,texW:u,texH:h}},"getScale")},{key:"draw",value:o(function(r,n,i){var a=this,s=this.atlasSize,l=this.rows,u=this.texHeight,h=this.getScale(n),f=h.scale,d=h.texW,p=h.texH,m=[null,null],g=o(function(T,S){if(i&&S){var w=S.context,E=T.x,_=T.row,C=E,D=u*_;w.save(),w.translate(C,D),w.scale(f,f),i(w,n),w.restore()}},"drawAt"),y=o(function(){g(a.freePointer,a.canvas),m[0]={x:a.freePointer.x,y:a.freePointer.row*u,w:d,h:p},m[1]={x:a.freePointer.x+d,y:a.freePointer.row*u,w:0,h:p},a.freePointer.x+=d,a.freePointer.x==s&&(a.freePointer.x=0,a.freePointer.row++)},"drawNormal"),v=o(function(){var T=a.scratch,S=a.canvas;T.clear(),g({x:0,row:0},T);var w=s-a.freePointer.x,E=d-w,_=u;{var C=a.freePointer.x,D=a.freePointer.row*u,O=w;S.context.drawImage(T,0,0,O,_,C,D,O,_),m[0]={x:C,y:D,w:O,h:p}}{var R=w,k=(a.freePointer.row+1)*u,L=E;S&&S.context.drawImage(T,R,0,L,_,0,k,L,_),m[1]={x:0,y:k,w:L,h:p}}a.freePointer.x=E,a.freePointer.row++},"drawWrapped"),x=o(function(){a.freePointer.x=0,a.freePointer.row++},"moveToStartOfNextRow");if(this.freePointer.x+d<=s)y();else{if(this.freePointer.row>=l-1)return!1;this.freePointer.x===s?(x(),y()):this.enableWrapping?v():(x(),y())}return this.keyToLocation.set(r,m),this.needsBuffer=!0,m},"draw")},{key:"getOffsets",value:o(function(r){return this.keyToLocation.get(r)},"getOffsets")},{key:"isEmpty",value:o(function(){return this.freePointer.x===0&&this.freePointer.row===0},"isEmpty")},{key:"canFit",value:o(function(r){var n=this.atlasSize,i=this.rows,a=this.getScale(r),s=a.texW;return this.freePointer.x+s>n?this.freePointer.row1&&arguments[1]!==void 0?arguments[1]:{},i=n.forceRedraw,a=i===void 0?!1:i,s=n.filterEle,l=s===void 0?function(){return!0}:s,u=n.filterType,h=u===void 0?function(){return!0}:u,f=!1,d=vo(r),p;try{for(d.s();!(p=d.n()).done;){var m=p.value;if(l(m)){var g=m.id(),y=vo(this.getRenderTypes()),v;try{for(y.s();!(v=y.n()).done;){var x=v.value;if(h(x.type)){var b=x.getKey(m);a?(x.atlasCollection.deleteKey(g,b),x.atlasCollection.styleKeyNeedsRedraw.add(b),f=!0):f|=x.atlasCollection.checkKeyIsInvalid(g,b)}}}catch(T){y.e(T)}finally{y.f()}}}}catch(T){d.e(T)}finally{d.f()}return f},"invalidate")},{key:"gc",value:o(function(){var r=vo(this.getRenderTypes()),n;try{for(r.s();!(n=r.n()).done;){var i=n.value;i.atlasCollection.gc()}}catch(a){r.e(a)}finally{r.f()}},"gc")},{key:"isRenderable",value:o(function(r,n){var i=this.getRenderTypeOpts(n);return i&&i.isVisible(r)},"isRenderable")},{key:"startBatch",value:o(function(){this.batchAtlases=[]},"startBatch")},{key:"getAtlasCount",value:o(function(){return this.batchAtlases.length},"getAtlasCount")},{key:"getAtlases",value:o(function(){return this.batchAtlases},"getAtlases")},{key:"getOrCreateAtlas",value:o(function(r,n,i){var a=this.renderTypes.get(i),s=a.getKey(r),l=r.id();return a.atlasCollection.draw(l,s,n,function(u){a.drawElement(u,r,n,!0,!0)})},"getOrCreateAtlas")},{key:"getAtlasIndexForBatch",value:o(function(r){var n=this.batchAtlases.indexOf(r);if(n<0){if(this.batchAtlases.length===this.maxAtlasesPerBatch)return;this.batchAtlases.push(r),n=this.batchAtlases.length-1}return n},"getAtlasIndexForBatch")},{key:"getIndexArray",value:o(function(){return Array.from({length:this.maxAtlases},function(r,n){return n})},"getIndexArray")},{key:"getAtlasInfo",value:o(function(r,n){var i=this.renderTypes.get(n),a=i.getBoundingBox(r),s=this.getOrCreateAtlas(r,a,n),l=this.getAtlasIndexForBatch(s);if(l!==void 0){var u=i.getKey(r),h=s.getOffsets(u),f=Ri(h,2),d=f[0],p=f[1];return{atlasID:l,tex:d,tex1:d,tex2:p,bb:a,type:n,styleKey:u}}},"getAtlasInfo")},{key:"canAddToCurrentBatch",value:o(function(r,n){if(this.batchAtlases.length===this.maxAtlasesPerBatch){var i=this.renderTypes.get(n),a=i.getKey(r),s=i.atlasCollection.getAtlas(a);return s&&this.batchAtlases.includes(s)}return!0},"canAddToCurrentBatch")},{key:"setTransformMatrix",value:o(function(r,n,i){var a=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,s=n.bb,l=n.type,u=n.tex1,h=n.tex2,f=this.getRenderTypeOpts(l),d=f.getPadding?f.getPadding(i):0,p=u.w/(u.w+h.w);a||(p=1-p);var m=this.getAdjustedBB(s,d,a,p),g,y;B1e(r);var v=f.getRotation?f.getRotation(i):0;if(v!==0){var x=f.getRotationPoint(i),b=x.x,T=x.y;j6(r,r,[b,T]),F1e(r,r,v);var S=f.getRotationOffset(i);g=S.x+m.xOffset,y=S.y}else g=m.x1,y=m.y1;j6(r,r,[g,y]),sF(r,r,[m.w,m.h])},"setTransformMatrix")},{key:"getTransformMatrix",value:o(function(r,n){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,a=Zb();return this.setTransformMatrix(a,r,n,i),a},"getTransformMatrix")},{key:"getAdjustedBB",value:o(function(r,n,i,a){var s=r.x1,l=r.y1,u=r.w,h=r.h;n&&(s-=n,l-=n,u+=2*n,h+=2*n);var f=0,d=u*a;return i&&a<1?u=d:!i&&a<1&&(f=u-d,s+=f,u=d),{x1:s,y1:l,w:u,h,xOffset:f}},"getAdjustedBB")},{key:"getDebugInfo",value:o(function(){var r=[],n=vo(this.renderTypes),i;try{for(n.s();!(i=n.n()).done;){var a=Ri(i.value,2),s=a[0],l=a[1],u=l.atlasCollection.getCounts(),h=u.keyCount,f=u.atlasCount;r.push({type:s,keyCount:h,atlasCount:f})}}catch(d){n.e(d)}finally{n.f()}return r},"getDebugInfo")}]),t}(),yB=0,Zme=1,Jme=2,vB=3,qJe=function(){function t(e,r,n){Vf(this,t),this.r=e,this.gl=r,this.maxInstances=n.webglBatchSize,this.maxAtlases=n.webglTexPerBatch,this.atlasSize=n.webglTexSize,this.bgColor=n.bgColor,n.enableWrapping=!0,n.createTextureCanvas=IJe,this.atlasManager=new WJe(e,n),this.program=this.createShaderProgram(Jb.SCREEN),this.pickingProgram=this.createShaderProgram(Jb.PICKING),this.vao=this.createVAO(),this.debugInfo=[]}return o(t,"ElementDrawingWebGL"),Uf(t,[{key:"addTextureRenderType",value:o(function(r,n){this.atlasManager.addRenderType(r,n)},"addTextureRenderType")},{key:"invalidate",value:o(function(r){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=n.type,a=this.atlasManager;return i?a.invalidate(r,{filterType:o(function(l){return l===i},"filterType"),forceRedraw:!0}):a.invalidate(r)},"invalidate")},{key:"gc",value:o(function(){this.atlasManager.gc()},"gc")},{key:"createShaderProgram",value:o(function(r){var n=this.gl,i=`#version 300 es - precision highp float; - - uniform mat3 uPanZoomMatrix; - uniform int uAtlasSize; - - // instanced - in vec2 aPosition; - - // what are we rendering? - in int aVertType; - - // for picking - in vec4 aIndex; - - // For textures - in int aAtlasId; // which shader unit/atlas to use - in vec4 aTex1; // x/y/w/h of texture in atlas - in vec4 aTex2; - - // for any transforms that are needed - in vec4 aScaleRotate1; // vectors use fewer attributes than matrices - in vec2 aTranslate1; - in vec4 aScaleRotate2; - in vec2 aTranslate2; - - // for edges - in vec4 aPointAPointB; - in vec4 aPointCPointD; - in float aLineWidth; - in vec4 aEdgeColor; - - out vec2 vTexCoord; - out vec4 vEdgeColor; - flat out int vAtlasId; - flat out vec4 vIndex; - flat out int vVertType; - - void main(void) { - int vid = gl_VertexID; - vec2 position = aPosition; - - if(aVertType == `.concat(yB,`) { - float texX; - float texY; - float texW; - float texH; - mat3 texMatrix; - - int vid = gl_VertexID; - if(vid <= 5) { - texX = aTex1.x; - texY = aTex1.y; - texW = aTex1.z; - texH = aTex1.w; - texMatrix = mat3( - vec3(aScaleRotate1.xy, 0.0), - vec3(aScaleRotate2.zw, 0.0), - vec3(aTranslate1, 1.0) - ); - } else { - texX = aTex2.x; - texY = aTex2.y; - texW = aTex2.z; - texH = aTex2.w; - texMatrix = mat3( - vec3(aScaleRotate2.xy, 0.0), - vec3(aScaleRotate2.zw, 0.0), - vec3(aTranslate2, 1.0) - ); - } - - if(vid == 1 || vid == 2 || vid == 4 || vid == 7 || vid == 8 || vid == 10) { - texX += texW; - } - if(vid == 2 || vid == 4 || vid == 5 || vid == 8 || vid == 10 || vid == 11) { - texY += texH; - } - - float d = float(uAtlasSize); - vTexCoord = vec2(texX / d, texY / d); // tex coords must be between 0 and 1 - - gl_Position = vec4(uPanZoomMatrix * texMatrix * vec3(position, 1.0), 1.0); - } - else if(aVertType == `).concat(Zme,` && vid < 6) { - vec2 source = aPointAPointB.xy; - vec2 target = aPointAPointB.zw; - - // adjust the geometry so that the line is centered on the edge - position.y = position.y - 0.5; - - vec2 xBasis = target - source; - vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x)); - vec2 point = source + xBasis * position.x + yBasis * aLineWidth * position.y; - - gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0); - vEdgeColor = aEdgeColor; - } - else if(aVertType == `).concat(Jme,` && vid < 6) { - vec2 pointA = aPointAPointB.xy; - vec2 pointB = aPointAPointB.zw; - vec2 pointC = aPointCPointD.xy; - vec2 pointD = aPointCPointD.zw; - - // adjust the geometry so that the line is centered on the edge - position.y = position.y - 0.5; - - vec2 p0 = pointA; - vec2 p1 = pointB; - vec2 p2 = pointC; - vec2 pos = position; - if(position.x == 1.0) { - p0 = pointD; - p1 = pointC; - p2 = pointB; - pos = vec2(0.0, -position.y); - } - - vec2 p01 = p1 - p0; - vec2 p12 = p2 - p1; - vec2 p21 = p1 - p2; - - // Find the normal vector. - vec2 tangent = normalize(normalize(p12) + normalize(p01)); - vec2 normal = vec2(-tangent.y, tangent.x); - - // Find the vector perpendicular to p0 -> p1. - vec2 p01Norm = normalize(vec2(-p01.y, p01.x)); - - // Determine the bend direction. - float sigma = sign(dot(p01 + p21, normal)); - float width = aLineWidth; - - if(sign(pos.y) == -sigma) { - // This is an intersecting vertex. Adjust the position so that there's no overlap. - vec2 point = 0.5 * width * normal * -sigma / dot(normal, p01Norm); - gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0); - } else { - // This is a non-intersecting vertex. Treat it like a mitre join. - vec2 point = 0.5 * width * normal * sigma * dot(normal, p01Norm); - gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0); - } - - vEdgeColor = aEdgeColor; - } - else if(aVertType == `).concat(vB,` && vid < 3) { - // massage the first triangle into an edge arrow - if(vid == 0) - position = vec2(-0.15, -0.3); - if(vid == 1) - position = vec2( 0.0, 0.0); - if(vid == 2) - position = vec2( 0.15, -0.3); - - mat3 transform = mat3( - vec3(aScaleRotate1.xy, 0.0), - vec3(aScaleRotate1.zw, 0.0), - vec3(aTranslate1, 1.0) - ); - gl_Position = vec4(uPanZoomMatrix * transform * vec3(position, 1.0), 1.0); - vEdgeColor = aEdgeColor; - } else { - gl_Position = vec4(2.0, 0.0, 0.0, 1.0); // discard vertex by putting it outside webgl clip space - } - - vAtlasId = aAtlasId; - vIndex = aIndex; - vVertType = aVertType; - } - `),a=this.atlasManager.getIndexArray(),s=`#version 300 es - precision highp float; - - // define texture unit for each node in the batch - `.concat(a.map(function(h){return"uniform sampler2D uTexture".concat(h,";")}).join(` - `),` - - uniform vec4 uBGColor; - - in vec2 vTexCoord; - in vec4 vEdgeColor; - flat in int vAtlasId; - flat in vec4 vIndex; - flat in int vVertType; - - out vec4 outColor; - - void main(void) { - if(vVertType == `).concat(yB,`) { - `).concat(a.map(function(h){return"if(vAtlasId == ".concat(h,") outColor = texture(uTexture").concat(h,", vTexCoord);")}).join(` - else `),` - } else if(vVertType == `).concat(vB,`) { - // blend arrow color with background (using premultiplied alpha) - outColor.rgb = vEdgeColor.rgb + (uBGColor.rgb * (1.0 - vEdgeColor.a)); - outColor.a = 1.0; // make opaque, masks out line under arrow - } else { - outColor = vEdgeColor; - } - - `).concat(r.picking?`if(outColor.a == 0.0) discard; - else outColor = vIndex;`:"",` - } - `),l=MJe(n,i,s);l.aPosition=n.getAttribLocation(l,"aPosition"),l.aIndex=n.getAttribLocation(l,"aIndex"),l.aVertType=n.getAttribLocation(l,"aVertType"),l.aAtlasId=n.getAttribLocation(l,"aAtlasId"),l.aTex1=n.getAttribLocation(l,"aTex1"),l.aTex2=n.getAttribLocation(l,"aTex2"),l.aScaleRotate1=n.getAttribLocation(l,"aScaleRotate1"),l.aTranslate1=n.getAttribLocation(l,"aTranslate1"),l.aScaleRotate2=n.getAttribLocation(l,"aScaleRotate2"),l.aTranslate2=n.getAttribLocation(l,"aTranslate2"),l.aPointAPointB=n.getAttribLocation(l,"aPointAPointB"),l.aPointCPointD=n.getAttribLocation(l,"aPointCPointD"),l.aLineWidth=n.getAttribLocation(l,"aLineWidth"),l.aEdgeColor=n.getAttribLocation(l,"aEdgeColor"),l.uPanZoomMatrix=n.getUniformLocation(l,"uPanZoomMatrix"),l.uAtlasSize=n.getUniformLocation(l,"uAtlasSize"),l.uBGColor=n.getUniformLocation(l,"uBGColor"),l.uTextures=[];for(var u=0;u2&&arguments[2]!==void 0?arguments[2]:Jb.SCREEN;this.panZoomMatrix=r,this.debugInfo=n,this.renderTarget=i,this.startBatch()},"startFrame")},{key:"startBatch",value:o(function(){this.instanceCount=0,this.atlasManager.startBatch()},"startBatch")},{key:"endFrame",value:o(function(){this.endBatch()},"endFrame")},{key:"getTempMatrix",value:o(function(){return this.tempMatrix=this.tempMatrix||Zb()},"getTempMatrix")},{key:"drawTexture",value:o(function(r,n,i){var a=this.atlasManager;if(a.isRenderable(r,i)){a.canAddToCurrentBatch(r,i)||this.endBatch();var s=this.instanceCount;this.vertTypeBuffer.getView(s)[0]=yB;var l=this.indexBuffer.getView(s);_6(n,l);var u=a.getAtlasInfo(r,i,u),h=u.atlasID,f=u.tex1,d=u.tex2,p=this.atlasIdBuffer.getView(s);p[0]=h;var m=this.tex1Buffer.getView(s);m[0]=f.x,m[1]=f.y,m[2]=f.w,m[3]=f.h;var g=this.tex2Buffer.getView(s);g[0]=d.x,g[1]=d.y,g[2]=d.w,g[3]=d.h;for(var y=this.getTempMatrix(),v=0,x=[1,2];v=this.maxInstances&&this.endBatch()}},"drawTexture")},{key:"drawEdgeArrow",value:o(function(r,n,i){var a=r._private.rscratch,s,l,u;if(i==="source"?(s=a.arrowStartX,l=a.arrowStartY,u=a.srcArrowAngle):(s=a.arrowEndX,l=a.arrowEndY,u=a.tgtArrowAngle),!(isNaN(s)||s==null||isNaN(l)||l==null||isNaN(u)||u==null)){var h=r.pstyle(i+"-arrow-shape").value;if(h!=="none"){var f=r.pstyle(i+"-arrow-color").value,d=r.pstyle("opacity").value,p=r.pstyle("line-opacity").value,m=d*p,g=r.pstyle("width").pfValue,y=r.pstyle("arrow-scale").value,v=this.r.getArrowWidth(g,y),x=this.getTempMatrix();B1e(x),j6(x,x,[s,l]),sF(x,x,[v,v]),F1e(x,x,u);var b=this.instanceCount;this.vertTypeBuffer.getView(b)[0]=vB;var T=this.indexBuffer.getView(b);_6(n,T);var S=this.edgeColorBuffer.getView(b);A6(f,m,S);var w=this.scaleRotate1Buffer.getView(b);w[0]=x[0],w[1]=x[1],w[2]=x[3],w[3]=x[4];var E=this.translate1Buffer.getView(b);E[0]=x[6],E[1]=x[7],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}},"drawEdgeArrow")},{key:"drawEdgeLine",value:o(function(r,n){var i=r.pstyle("opacity").value,a=r.pstyle("line-opacity").value,s=r.pstyle("width").pfValue,l=r.pstyle("line-color").value,u=i*a,h=this.getEdgePoints(r);if(h.length/2+this.instanceCount>this.maxInstances&&this.endBatch(),h.length==4){var f=this.instanceCount;this.vertTypeBuffer.getView(f)[0]=Zme;var d=this.indexBuffer.getView(f);_6(n,d);var p=this.edgeColorBuffer.getView(f);A6(l,u,p);var m=this.lineWidthBuffer.getView(f);m[0]=s;var g=this.pointAPointBBuffer.getView(f);g[0]=h[0],g[1]=h[1],g[2]=h[2],g[3]=h[3],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}else for(var y=0;y=this.maxInstances&&this.endBatch()}},"drawEdgeLine")},{key:"getEdgePoints",value:o(function(r){var n=r._private.rscratch,i=n.allpts;if(i.length==4)return i;var a=this.getNumSegments(r);return this.getCurveSegmentPoints(i,a)},"getEdgePoints")},{key:"getNumSegments",value:o(function(r){var n=15;return Math.min(Math.max(n,5),this.maxInstances)},"getNumSegments")},{key:"getCurveSegmentPoints",value:o(function(r,n){if(r.length==4)return r;for(var i=Array((n+1)*2),a=0;a<=n;a++)if(a==0)i[0]=r[0],i[1]=r[1];else if(a==n)i[a*2]=r[r.length-2],i[a*2+1]=r[r.length-1];else{var s=a/n;this.setCurvePoint(r,s,i,a*2)}return i},"getCurveSegmentPoints")},{key:"setCurvePoint",value:o(function(r,n,i,a){if(r.length<=2)i[a]=r[0],i[a+1]=r[1];else{for(var s=Array(r.length-2),l=0;l0},"isVisible")},{key:"getStyle",value:o(function(r,n){var i=n.pstyle("".concat(r,"-opacity")).value,a=n.pstyle("".concat(r,"-color")).value,s=n.pstyle("".concat(r,"-shape")).value;return{opacity:i,color:a,shape:s}},"getStyle")},{key:"getPadding",value:o(function(r,n){return n.pstyle("".concat(r,"-padding")).pfValue},"getPadding")},{key:"draw",value:o(function(r,n,i,a){if(this.isVisible(r,i)){var s=this.r,l=a.w,u=a.h,h=l/2,f=u/2,d=this.getStyle(r,i),p=d.shape,m=d.color,g=d.opacity;n.save(),n.fillStyle=ege(m,g),p==="round-rectangle"||p==="roundrectangle"?s.drawRoundRectanglePath(n,h,f,l,u,"auto"):p==="ellipse"&&s.drawEllipsePath(n,h,f,l,u),n.fill(),n.restore()}},"draw")}]),t}();o(XJe,"getBGColor");$1e={};$1e.initWebgl=function(t,e){var r=this,n=r.data.contexts[r.WEBGL],i=t.cy.container();t.bgColor=XJe(i),t.webglTexSize=Math.min(t.webglTexSize,n.getParameter(n.MAX_TEXTURE_SIZE)),t.webglTexRows=Math.min(t.webglTexRows,54),t.webglBatchSize=Math.min(t.webglBatchSize,16384),t.webglTexPerBatch=Math.min(t.webglTexPerBatch,n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),r.webglDebug=t.webglDebug,r.webglDebugShowAtlases=t.webglDebugShowAtlases,console.log("max texture units",n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),console.log("max texture size",n.getParameter(n.MAX_TEXTURE_SIZE)),console.log("webgl options",t),r.pickingFrameBuffer=$Je(n),r.pickingFrameBuffer.needsDraw=!0;var a=o(function(f){return r.getTextAngle(f,null)},"getLabelRotation"),s=o(function(f){var d=f.pstyle("label");return d&&d.value},"isLabelVisible");r.eleDrawing=new qJe(r,n,t);var l=new YJe(r);r.eleDrawing.addTextureRenderType("node-body",Hb({getKey:e.getStyleKey,getBoundingBox:e.getElementBox,drawElement:e.drawElement,isVisible:o(function(f){return f.visible()},"isVisible")})),r.eleDrawing.addTextureRenderType("node-label",Hb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s})),r.eleDrawing.addTextureRenderType("node-overlay",Hb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("overlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("overlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("overlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("overlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("node-underlay",Hb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("underlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("underlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("underlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("underlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("edge-label",Hb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s}));var u=p4(function(){console.log("garbage collect flag set"),r.data.gc=!0},1e4);r.onUpdateEleCalcs(function(h,f){var d=!1;f&&f.length>0&&(d|=r.eleDrawing.invalidate(f)),d&&u()}),jJe(r)};o(jJe,"overrideCanvasRendererFunctions");o(KJe,"clearWebgl");o(QJe,"clearCanvas");o(ZJe,"createPanZoomMatrix");o(z1e,"setContextTransform");o(JJe,"drawSelectionRectangle");o(eet,"drawAxes");o(tet,"drawAtlases");o(ret,"getPickingIndexes");o(net,"findNearestElementsWebgl");o(G1e,"renderWebgl");Wf={};Wf.drawPolygonPath=function(t,e,r,n,i,a){var s=n/2,l=i/2;t.beginPath&&t.beginPath(),t.moveTo(e+s*a[0],r+l*a[1]);for(var u=1;u0&&s>0){m.clearRect(0,0,a,s),m.globalCompositeOperation="source-over";var g=this.getCachedZSortedEles();if(t.full)m.translate(-n.x1*h,-n.y1*h),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(n.x1*h,n.y1*h);else{var y=e.pan(),v={x:y.x*h,y:y.y*h};h*=e.zoom(),m.translate(v.x,v.y),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(-v.x,-v.y)}t.bg&&(m.globalCompositeOperation="destination-over",m.fillStyle=t.bg,m.rect(0,0,a,s),m.fill())}return p};o(iet,"b64ToBlob");o(nge,"b64UriToB64");o(U1e,"output");b4.png=function(t){return U1e(t,this.bufferCanvasImage(t),"image/png")};b4.jpg=function(t){return U1e(t,this.bufferCanvasImage(t),"image/jpeg")};H1e={};H1e.nodeShapeImpl=function(t,e,r,n,i,a,s,l){switch(t){case"ellipse":return this.drawEllipsePath(e,r,n,i,a);case"polygon":return this.drawPolygonPath(e,r,n,i,a,s);case"round-polygon":return this.drawRoundPolygonPath(e,r,n,i,a,s,l);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(e,r,n,i,a,l);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(e,r,n,i,a,s,l);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(e,r,n,i,a,l);case"barrel":return this.drawBarrelPath(e,r,n,i,a)}};aet=W1e,Sr=W1e.prototype;Sr.CANVAS_LAYERS=3;Sr.SELECT_BOX=0;Sr.DRAG=1;Sr.NODE=2;Sr.WEBGL=3;Sr.CANVAS_TYPES=["2d","2d","2d","webgl2"];Sr.BUFFER_COUNT=3;Sr.TEXTURE_BUFFER=0;Sr.MOTIONBLUR_BUFFER_NODE=1;Sr.MOTIONBLUR_BUFFER_DRAG=2;o(W1e,"CanvasRenderer");Sr.redrawHint=function(t,e){var r=this;switch(t){case"eles":r.data.canvasNeedsRedraw[Sr.NODE]=e;break;case"drag":r.data.canvasNeedsRedraw[Sr.DRAG]=e;break;case"select":r.data.canvasNeedsRedraw[Sr.SELECT_BOX]=e;break;case"gc":r.data.gc=!0;break}};set=typeof Path2D<"u";Sr.path2dEnabled=function(t){if(t===void 0)return this.pathsEnabled;this.pathsEnabled=!!t};Sr.usePaths=function(){return set&&this.pathsEnabled};Sr.setImgSmoothing=function(t,e){t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled=e:(t.webkitImageSmoothingEnabled=e,t.mozImageSmoothingEnabled=e,t.msImageSmoothingEnabled=e)};Sr.getImgSmoothing=function(t){return t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled:t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled};Sr.makeOffscreenCanvas=function(t,e){var r;if((typeof OffscreenCanvas>"u"?"undefined":qi(OffscreenCanvas))!=="undefined")r=new OffscreenCanvas(t,e);else{var n=this.cy.window(),i=n.document;r=i.createElement("canvas"),r.width=t,r.height=e}return r};[N1e,tu,oh,iF,n0,py,ws,$1e,Wf,b4,H1e].forEach(function(t){ir(Sr,t)});oet=[{name:"null",impl:v1e},{name:"base",impl:_1e},{name:"canvas",impl:aet}],cet=[{type:"layout",extensions:HZe},{type:"renderer",extensions:oet}],q1e={},Y1e={};o(X1e,"setExtension");o(j1e,"getExtension");o(uet,"setModule");o(het,"getModule");OB=o(function(){if(arguments.length===2)return j1e.apply(null,arguments);if(arguments.length===3)return X1e.apply(null,arguments);if(arguments.length===4)return het.apply(null,arguments);if(arguments.length===5)return uet.apply(null,arguments);oi("Invalid extension access syntax")},"extension");u4.prototype.extension=OB;cet.forEach(function(t){t.extensions.forEach(function(e){X1e(t.type,e.name,e.impl)})});K1e=o(function t(){if(!(this instanceof t))return new t;this.length=0},"Stylesheet"),t0=K1e.prototype;t0.instanceString=function(){return"stylesheet"};t0.selector=function(t){var e=this.length++;return this[e]={selector:t,properties:[]},this};t0.css=function(t,e){var r=this.length-1;if(Zt(t))this[r].properties.push({name:t,value:e});else if(Ur(t))for(var n=t,i=Object.keys(n),a=0;a{"use strict";o(function(e,r){typeof T4=="object"&&typeof lF=="object"?lF.exports=r():typeof define=="function"&&define.amd?define([],r):typeof T4=="object"?T4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(T4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=26)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(4);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;yp&&(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)),this.labelHeight>m&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-m)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-m),this.setHeight(this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(6),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,T=0;T-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(w,1),x.target!=x.source&&x.target.edges.splice(E,1);var S=x.source.owner.getEdges().indexOf(x);if(S==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(S,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,T=this.getNodes(),S=T.length,w=0;wv&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(T[0].getParent().paddingLeft!=null?b=T[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,T,S,w,E,_,C=this.nodes,D=C.length,O=0;OT&&(y=T),vw&&(x=w),bT&&(y=T),vw&&(x=w),b=this.nodes.length){var D=0;v.forEach(function(O){O.owner==g&&D++}),D==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(5),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]d)return l[0]=u,l[1]=m,l[2]=f,l[3]=C,!1;if(hf)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(uf?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):A===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-I===M?f>u?(l[2]=_,l[3]=C,L=!0):(l[2]=E,l[3]=w,L=!0):I===M&&(f>u?(l[2]=S,l[3]=w,L=!0):(l[2]=D,l[3]=C,L=!0)),k&&L)return!1;if(u>f?h>d?(P=this.getCardinalDirection(A,M,4),B=this.getCardinalDirection(I,M,2)):(P=this.getCardinalDirection(-A,M,3),B=this.getCardinalDirection(-I,M,1)):h>d?(P=this.getCardinalDirection(-A,M,1),B=this.getCardinalDirection(-I,M,3)):(P=this.getCardinalDirection(A,M,2),B=this.getCardinalDirection(I,M,4)),!k)switch(P){case 1:z=m,F=u+-T/M,l[0]=F,l[1]=z;break;case 2:F=x,z=h+b*M,l[0]=F,l[1]=z;break;case 3:z=v,F=u+T/M,l[0]=F,l[1]=z;break;case 4:F=y,z=h+-b*M,l[0]=F,l[1]=z;break}if(!L)switch(B){case 1:U=w,$=f+-R/M,l[2]=$,l[3]=U;break;case 2:$=D,U=d+O*M,l[2]=$,l[3]=U;break;case 3:U=C,$=f+R/M,l[2]=$,l[3]=U;break;case 4:$=_,U=d+-O*M,l[2]=$,l[3]=U;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,T=void 0,S=void 0,w=void 0,E=void 0,_=void 0,C=void 0,D=void 0;return T=p-f,w=h-d,_=d*f-h*p,S=v-g,E=m-y,C=y*g-m*v,D=T*E-S*w,D===0?null:(x=(w*C-E*_)/D,b=(S*_-T*C)/D,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g0&&g;){for(T.push(w[0]);T.length>0&&g;){var E=T[0];T.splice(0,1),b.add(E);for(var _=E.getEdges(),x=0;x<_.length;x++){var C=_[x].getOtherEnd(E);if(S.get(E)!=C)if(!b.has(C))T.push(C),S.set(C,E);else{g=!1;break}}}if(!g)m=[];else{var D=[].concat(n(b));m.push(D);for(var x=0;x-1&&w.splice(R,1)}b=new Set,S=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x0){for(var v=this.edgeToDummyNodes.get(y),x=0;x=0&&g.splice(C,1);var D=S.getNeighborsList();D.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),A=L-1;A==1&&E.push(k),v.set(k,A)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(4);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);pa.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;mT||b>T)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(T=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>T||b>T)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement=x.length||T>=x[0].length)){for(var S=0;Sh},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l{"use strict";o(function(e,r){typeof w4=="object"&&typeof uF=="object"?uF.exports=r(cF()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof w4=="object"?w4.coseBase=r(cF()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(w4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=7)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).FDLayoutConstants;function a(){}o(a,"CoSEConstants");for(var s in i)a[s]=i[s];a.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,a.DEFAULT_RADIAL_SEPARATION=i.DEFAULT_EDGE_LENGTH,a.DEFAULT_COMPONENT_SEPERATION=60,a.TILE=!0,a.TILING_PADDING_VERTICAL=10,a.TILING_PADDING_HORIZONTAL=10,a.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutEdge;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEEdge"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraph;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEGraph"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraphManager;function a(l){i.call(this,l)}o(a,"CoSEGraphManager"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutNode,a=n(0).IMath;function s(u,h,f,d){i.call(this,u,h,f,d)}o(s,"CoSENode"),s.prototype=Object.create(i.prototype);for(var l in i)s[l]=i[l];s.prototype.move=function(){var u=this.graphManager.getLayout();this.displacementX=u.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=u.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementX=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementX)),Math.abs(this.displacementY)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementY=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementY)),this.child==null?this.moveBy(this.displacementX,this.displacementY):this.child.getNodes().length==0?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),u.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},s.prototype.propogateDisplacementToChildren=function(u,h){for(var f=this.getChild().getNodes(),d,p=0;p0)this.positionNodesRadially(w);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),_=this.nodesWithGravity.filter(function(C){return E.has(C)});this.graphManager.setAllNodesToApplyGravitation(_),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},T.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%f.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var w=new Set(this.getAllNodes()),E=this.nodesWithGravity.filter(function(D){return w.has(D)});this.graphManager.setAllNodesToApplyGravitation(E),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var _=!this.isTreeGrowing&&!this.isGrowthFinished,C=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(_,C),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},T.prototype.getPositionsData=function(){for(var w=this.graphManager.getAllNodes(),E={},_=0;_1){var k;for(k=0;kC&&(C=Math.floor(R.y)),O=Math.floor(R.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new m(d.WORLD_CENTER_X-R.x/2,d.WORLD_CENTER_Y-R.y/2))},T.radialLayout=function(w,E,_){var C=Math.max(this.maxDiagonalInTree(w),h.DEFAULT_RADIAL_SEPARATION);T.branchRadialLayout(E,null,0,359,0,C);var D=x.calculateBounds(w),O=new b;O.setDeviceOrgX(D.getMinX()),O.setDeviceOrgY(D.getMinY()),O.setWorldOrgX(_.x),O.setWorldOrgY(_.y);for(var R=0;R1;){var K=U[0];U.splice(0,1);var ee=P.indexOf(K);ee>=0&&P.splice(ee,1),z--,B--}E!=null?$=(P.indexOf(U[0])+1)%z:$=0;for(var Y=Math.abs(C-_)/B,ce=$;F!=B;ce=++ce%z){var Z=P[ce].getOtherEnd(w);if(Z!=E){var ue=(_+F*Y)%360,Q=(ue+Y)%360;T.branchRadialLayout(Z,w,ue,Q,D+O,O),F++}}},T.maxDiagonalInTree=function(w){for(var E=y.MIN_VALUE,_=0;_E&&(E=D)}return E},T.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},T.prototype.groupZeroDegreeMembers=function(){var w=this,E={};this.memberGroups={},this.idToDummyNode={};for(var _=[],C=this.graphManager.getAllNodes(),D=0;D"u"&&(E[k]=[]),E[k]=E[k].concat(O)}Object.keys(E).forEach(function(L){if(E[L].length>1){var A="DummyCompound_"+L;w.memberGroups[A]=E[L];var I=E[L][0].getParent(),M=new l(w.graphManager);M.id=A,M.paddingLeft=I.paddingLeft||0,M.paddingRight=I.paddingRight||0,M.paddingBottom=I.paddingBottom||0,M.paddingTop=I.paddingTop||0,w.idToDummyNode[A]=M;var P=w.getGraphManager().add(w.newGraph(),M),B=I.getChild();B.add(M);for(var F=0;F=0;w--){var E=this.compoundOrder[w],_=E.id,C=E.paddingLeft,D=E.paddingTop;this.adjustLocations(this.tiledMemberPack[_],E.rect.x,E.rect.y,C,D)}},T.prototype.repopulateZeroDegreeMembers=function(){var w=this,E=this.tiledZeroDegreePack;Object.keys(E).forEach(function(_){var C=w.idToDummyNode[_],D=C.paddingLeft,O=C.paddingTop;w.adjustLocations(E[_],C.rect.x,C.rect.y,D,O)})},T.prototype.getToBeTiled=function(w){var E=w.id;if(this.toBeTiled[E]!=null)return this.toBeTiled[E];var _=w.getChild();if(_==null)return this.toBeTiled[E]=!1,!1;for(var C=_.getNodes(),D=0;D0)return this.toBeTiled[E]=!1,!1;if(O.getChild()==null){this.toBeTiled[O.id]=!1;continue}if(!this.getToBeTiled(O))return this.toBeTiled[E]=!1,!1}return this.toBeTiled[E]=!0,!0},T.prototype.getNodeDegree=function(w){for(var E=w.id,_=w.getEdges(),C=0,D=0;D<_.length;D++){var O=_[D];O.getSource().id!==O.getTarget().id&&(C=C+1)}return C},T.prototype.getNodeDegreeWithChildren=function(w){var E=this.getNodeDegree(w);if(w.getChild()==null)return E;for(var _=w.getChild().getNodes(),C=0;C<_.length;C++){var D=_[C];E+=this.getNodeDegreeWithChildren(D)}return E},T.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},T.prototype.fillCompexOrderByDFS=function(w){for(var E=0;EL&&(L=I.rect.height)}_+=L+w.verticalPadding}},T.prototype.tileCompoundMembers=function(w,E){var _=this;this.tiledMemberPack=[],Object.keys(w).forEach(function(C){var D=E[C];_.tiledMemberPack[C]=_.tileNodes(w[C],D.paddingLeft+D.paddingRight),D.rect.width=_.tiledMemberPack[C].width,D.rect.height=_.tiledMemberPack[C].height})},T.prototype.tileNodes=function(w,E){var _=h.TILING_PADDING_VERTICAL,C=h.TILING_PADDING_HORIZONTAL,D={rows:[],rowWidth:[],rowHeight:[],width:0,height:E,verticalPadding:_,horizontalPadding:C};w.sort(function(k,L){return k.rect.width*k.rect.height>L.rect.width*L.rect.height?-1:k.rect.width*k.rect.height0&&(R+=w.horizontalPadding),w.rowWidth[_]=R,w.width0&&(k+=w.verticalPadding);var L=0;k>w.rowHeight[_]&&(L=w.rowHeight[_],w.rowHeight[_]=k,L=w.rowHeight[_]-L),w.height+=L,w.rows[_].push(E)},T.prototype.getShortestRowIndex=function(w){for(var E=-1,_=Number.MAX_VALUE,C=0;C_&&(E=C,_=w.rowWidth[C]);return E},T.prototype.canAddHorizontal=function(w,E,_){var C=this.getShortestRowIndex(w);if(C<0)return!0;var D=w.rowWidth[C];if(D+w.horizontalPadding+E<=w.width)return!0;var O=0;w.rowHeight[C]<_&&C>0&&(O=_+w.verticalPadding-w.rowHeight[C]);var R;w.width-D>=E+w.horizontalPadding?R=(w.height+O)/(D+E+w.horizontalPadding):R=(w.height+O)/w.width,O=_+w.verticalPadding;var k;return w.widthO&&E!=_){C.splice(-1,1),w.rows[_].push(D),w.rowWidth[E]=w.rowWidth[E]-O,w.rowWidth[_]=w.rowWidth[_]+O,w.width=w.rowWidth[instance.getLongestRowIndex(w)];for(var R=Number.MIN_VALUE,k=0;kR&&(R=C[k].height);E>0&&(R+=w.verticalPadding);var L=w.rowHeight[E]+w.rowHeight[_];w.rowHeight[E]=R,w.rowHeight[_]0)for(var B=D;B<=O;B++)P[0]+=this.grid[B][R-1].length+this.grid[B][R].length-1;if(O0)for(var B=R;B<=k;B++)P[3]+=this.grid[D-1][B].length+this.grid[D][B].length-1;for(var F=y.MAX_VALUE,z,$,U=0;U{"use strict";o(function(e,r){typeof k4=="object"&&typeof fF=="object"?fF.exports=r(hF()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof k4=="object"?k4.cytoscapeCoseBilkent=r(hF()):e.cytoscapeCoseBilkent=r(e.coseBase)},"webpackUniversalModuleDefinition")(k4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=1)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).layoutBase.LayoutConstants,a=n(0).layoutBase.FDLayoutConstants,s=n(0).CoSEConstants,l=n(0).CoSELayout,u=n(0).CoSENode,h=n(0).layoutBase.PointD,f=n(0).layoutBase.DimensionD,d={ready:o(function(){},"ready"),stop:o(function(){},"stop"),quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function p(v,x){var b={};for(var T in v)b[T]=v[T];for(var T in x)b[T]=x[T];return b}o(p,"extend");function m(v){this.options=p(d,v),g(this.options)}o(m,"_CoSELayout");var g=o(function(x){x.nodeRepulsion!=null&&(s.DEFAULT_REPULSION_STRENGTH=a.DEFAULT_REPULSION_STRENGTH=x.nodeRepulsion),x.idealEdgeLength!=null&&(s.DEFAULT_EDGE_LENGTH=a.DEFAULT_EDGE_LENGTH=x.idealEdgeLength),x.edgeElasticity!=null&&(s.DEFAULT_SPRING_STRENGTH=a.DEFAULT_SPRING_STRENGTH=x.edgeElasticity),x.nestingFactor!=null&&(s.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=x.nestingFactor),x.gravity!=null&&(s.DEFAULT_GRAVITY_STRENGTH=a.DEFAULT_GRAVITY_STRENGTH=x.gravity),x.numIter!=null&&(s.MAX_ITERATIONS=a.MAX_ITERATIONS=x.numIter),x.gravityRange!=null&&(s.DEFAULT_GRAVITY_RANGE_FACTOR=a.DEFAULT_GRAVITY_RANGE_FACTOR=x.gravityRange),x.gravityCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_STRENGTH=a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=x.gravityCompound),x.gravityRangeCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=x.gravityRangeCompound),x.initialEnergyOnIncremental!=null&&(s.DEFAULT_COOLING_FACTOR_INCREMENTAL=a.DEFAULT_COOLING_FACTOR_INCREMENTAL=x.initialEnergyOnIncremental),x.quality=="draft"?i.QUALITY=0:x.quality=="proof"?i.QUALITY=2:i.QUALITY=1,s.NODE_DIMENSIONS_INCLUDE_LABELS=a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=x.nodeDimensionsIncludeLabels,s.DEFAULT_INCREMENTAL=a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=!x.randomize,s.ANIMATE=a.ANIMATE=i.ANIMATE=x.animate,s.TILE=x.tile,s.TILING_PADDING_VERTICAL=typeof x.tilingPaddingVertical=="function"?x.tilingPaddingVertical.call():x.tilingPaddingVertical,s.TILING_PADDING_HORIZONTAL=typeof x.tilingPaddingHorizontal=="function"?x.tilingPaddingHorizontal.call():x.tilingPaddingHorizontal},"getUserOptions");m.prototype.run=function(){var v,x,b=this.options,T=this.idToLNode={},S=this.layout=new l,w=this;w.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var E=S.newGraphManager();this.gm=E;var _=this.options.eles.nodes(),C=this.options.eles.edges();this.root=E.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(_),S);for(var D=0;D0){var k;k=b.getGraphManager().add(b.newGraph(),_),this.processChildrenList(k,E,b)}}},m.prototype.stop=function(){return this.stopped=!0,this};var y=o(function(x){x("layout","cose-bilkent",m)},"register");typeof cytoscape<"u"&&y(cytoscape),e.exports=y}])})});function xet(t,e,r,n,i){return t.insert("polygon",":first-child").attr("points",n.map(function(a){return a.x+","+a.y}).join(" ")).attr("transform","translate("+(i.width-e)/2+", "+r+")")}var det,pet,met,get,yet,vet,bet,Tet,Z1e,J1e,eye=N(()=>{"use strict";ao();er();det=12,pet=o(function(t,e,r,n){e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 ${r.height-5} v${-r.height+2*5} q0,-5 5,-5 h${r.width-2*5} q5,0 5,5 v${r.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",r.height).attr("x2",r.width).attr("y2",r.height)},"defaultBkg"),met=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("width",r.width)},"rectBkg"),get=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n,s=.25*n,l=.35*n,u=.2*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 0 0,1 ${n*.25},${-1*n*.1} - a${l},${l} 1 0,1 ${n*.4},${-1*n*.1} - a${s},${s} 1 0,1 ${n*.35},${1*n*.2} - - a${a},${a} 1 0,1 ${n*.15},${1*i*.35} - a${u},${u} 1 0,1 ${-1*n*.15},${1*i*.65} - - a${s},${a} 1 0,1 ${-1*n*.25},${n*.15} - a${l},${l} 1 0,1 ${-1*n*.5},0 - a${a},${a} 1 0,1 ${-1*n*.25},${-1*n*.15} - - a${a},${a} 1 0,1 ${-1*n*.1},${-1*i*.35} - a${u},${u} 1 0,1 ${n*.1},${-1*i*.65} - - H0 V0 Z`)},"cloudBkg"),yet=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 1 0,0 ${n*.25},${-1*i*.1} - a${a},${a} 1 0,0 ${n*.25},0 - a${a},${a} 1 0,0 ${n*.25},0 - a${a},${a} 1 0,0 ${n*.25},${1*i*.1} - - a${a},${a} 1 0,0 ${n*.15},${1*i*.33} - a${a*.8},${a*.8} 1 0,0 0,${1*i*.34} - a${a},${a} 1 0,0 ${-1*n*.15},${1*i*.33} - - a${a},${a} 1 0,0 ${-1*n*.25},${i*.15} - a${a},${a} 1 0,0 ${-1*n*.25},0 - a${a},${a} 1 0,0 ${-1*n*.25},0 - a${a},${a} 1 0,0 ${-1*n*.25},${-1*i*.15} - - a${a},${a} 1 0,0 ${-1*n*.1},${-1*i*.33} - a${a*.8},${a*.8} 1 0,0 0,${-1*i*.34} - a${a},${a} 1 0,0 ${n*.1},${-1*i*.33} - - H0 V0 Z`)},"bangBkg"),vet=o(function(t,e,r){e.append("circle").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("r",r.width/2)},"circleBkg");o(xet,"insertPolygonShape");bet=o(function(t,e,r){let n=r.height,a=n/4,s=r.width-r.padding+2*a,l=[{x:a,y:0},{x:s-a,y:0},{x:s,y:-n/2},{x:s-a,y:-n},{x:a,y:-n},{x:0,y:-n/2}];xet(e,s,n,l,r)},"hexagonBkg"),Tet=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("rx",r.padding).attr("ry",r.padding).attr("width",r.width)},"roundedRectBkg"),Z1e=o(async function(t,e,r,n,i){let a=i.htmlLabels,s=n%(det-1),l=e.append("g");r.section=s;let u="section-"+s;s<0&&(u+=" section-root"),l.attr("class",(r.class?r.class+" ":"")+"mindmap-node "+u);let h=l.append("g"),f=l.append("g"),d=r.descr.replace(/()/g,` -`);await qn(f,d,{useHtmlLabels:a,width:r.width,classes:"mindmap-node-label"},i),a||f.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");let p=f.node().getBBox(),[m]=zo(i.fontSize);if(r.height=p.height+m*1.1*.5+r.padding,r.width=p.width+2*r.padding,r.icon)if(r.type===t.nodeType.CIRCLE)r.height+=50,r.width+=50,l.append("foreignObject").attr("height","50px").attr("width",r.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+r.width/2+", "+(r.height/2-1.5*r.padding)+")");else{r.width+=50;let g=r.height;r.height=Math.max(g,60);let y=Math.abs(r.height-g);l.append("foreignObject").attr("width","60px").attr("height",r.height).attr("style","text-align: center;margin-top:"+y/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+(25+r.width/2)+", "+(y/2+r.padding/2)+")")}else if(a){let g=(r.width-p.width)/2,y=(r.height-p.height)/2;f.attr("transform","translate("+g+", "+y+")")}else{let g=r.width/2,y=r.padding/2;f.attr("transform","translate("+g+", "+y+")")}switch(r.type){case t.nodeType.DEFAULT:pet(t,h,r,s);break;case t.nodeType.ROUNDED_RECT:Tet(t,h,r,s);break;case t.nodeType.RECT:met(t,h,r,s);break;case t.nodeType.CIRCLE:h.attr("transform","translate("+r.width/2+", "+ +r.height/2+")"),vet(t,h,r,s);break;case t.nodeType.CLOUD:get(t,h,r,s);break;case t.nodeType.BANG:yet(t,h,r,s);break;case t.nodeType.HEXAGON:bet(t,h,r,s);break}return t.setElementForId(r.id,l),r.height},"drawNode"),J1e=o(function(t,e){let r=t.getElementById(e.id),n=e.x||0,i=e.y||0;r.attr("transform","translate("+n+","+i+")")},"positionNode")});async function rye(t,e,r,n,i){await Z1e(t,e,r,n,i),r.children&&await Promise.all(r.children.map((a,s)=>rye(t,e,a,n<0?s:n,i)))}function wet(t,e){e.edges().map((r,n)=>{let i=r.data();if(r[0]._private.bodyBounds){let a=r[0]._private.rscratch;X.trace("Edge: ",n,i),t.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}})}function nye(t,e,r,n){e.add({group:"nodes",data:{id:t.id.toString(),labelText:t.descr,height:t.height,width:t.width,level:n,nodeId:t.id,padding:t.padding,type:t.type},position:{x:t.x,y:t.y}}),t.children&&t.children.forEach(i=>{nye(i,e,r,n+1),e.add({group:"edges",data:{id:`${t.id}_${i.id}`,source:t.id,target:i.id,depth:n,section:i.section}})})}function ket(t,e){return new Promise(r=>{let n=Ge("body").append("div").attr("id","cy").attr("style","display:none"),i=sl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});n.remove(),nye(t,i,e,0),i.nodes().forEach(function(a){a.layoutDimensions=()=>{let s=a.data();return{w:s.width,h:s.height}}}),i.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),i.ready(a=>{X.info("Ready",a),r(i)})})}function Eet(t,e){e.nodes().map((r,n)=>{let i=r.data();i.x=r.position().x,i.y=r.position().y,J1e(t,i);let a=t.getElementById(i.nodeId);X.info("id:",n,"Position: (",r.position().x,", ",r.position().y,")",i),a.attr("transform",`translate(${r.position().x-i.width/2}, ${r.position().y-i.height/2})`),a.attr("attr",`apa-${n})`)})}var tye,Cet,iye,aye=N(()=>{"use strict";oF();tye=Aa(Q1e(),1);fr();Gt();yt();Vl();xi();eye();_a();sl.use(tye.default);o(rye,"drawNodes");o(wet,"drawEdges");o(nye,"addNodes");o(ket,"layoutMindmap");o(Eet,"positionNodes");Cet=o(async(t,e,r,n)=>{X.debug(`Rendering mindmap diagram -`+t);let i=n.db,a=i.getMindmap();if(!a)return;let s=me();s.htmlLabels=!1;let l=Li(e),u=l.append("g");u.attr("class","mindmap-edges");let h=l.append("g");h.attr("class","mindmap-nodes"),await rye(i,h,a,-1,s);let f=await ket(a,s);wet(u,f),Eet(i,f),Lo(void 0,l,s.mindmap?.padding??or.mindmap.padding,s.mindmap?.useMaxWidth??or.mindmap.useMaxWidth)},"draw"),iye={draw:Cet}});var Aet,_et,sye,oye=N(()=>{"use strict";Ks();Aet=o(t=>{let e="";for(let r=0;r` - .edge { - stroke-width: 3; - } - ${Aet(t)} - .section-root rect, .section-root path, .section-root circle, .section-root polygon { - fill: ${t.git0}; - } - .section-root text { - fill: ${t.gitBranchLabel0}; - } - .icon-container { - height:100%; - display: flex; - justify-content: center; - align-items: center; - } - .edge { - fill: none; - } - .mindmap-node-label { - dy: 1em; - alignment-baseline: middle; - text-anchor: middle; - dominant-baseline: middle; - text-align: center; - } -`,"getStyles"),sye=_et});var lye={};ur(lye,{diagram:()=>Det});var Det,cye=N(()=>{"use strict";B0e();F0e();aye();oye();Det={get db(){return new p6},renderer:iye,parser:P0e,styles:sye}});var dF,fye,dye=N(()=>{"use strict";dF=function(){var t=o(function(_,C,D,O){for(D=D||{},O=_.length;O--;D[_[O]]=C);return D},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,31],g=[6,7,11,24],y=[1,6,13,16,17,20,23],v=[1,35],x=[1,36],b=[1,6,7,11,13,16,17,20,23],T=[1,38],S={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:o(function(C,D,O,R,k,L,A){var I=L.length-1;switch(k){case 6:case 7:return R;case 8:R.getLogger().trace("Stop NL ");break;case 9:R.getLogger().trace("Stop EOF ");break;case 11:R.getLogger().trace("Stop NL2 ");break;case 12:R.getLogger().trace("Stop EOF2 ");break;case 15:R.getLogger().info("Node: ",L[I-1].id),R.addNode(L[I-2].length,L[I-1].id,L[I-1].descr,L[I-1].type,L[I]);break;case 16:R.getLogger().info("Node: ",L[I].id),R.addNode(L[I-1].length,L[I].id,L[I].descr,L[I].type);break;case 17:R.getLogger().trace("Icon: ",L[I]),R.decorateNode({icon:L[I]});break;case 18:case 23:R.decorateNode({class:L[I]});break;case 19:R.getLogger().trace("SPACELIST");break;case 20:R.getLogger().trace("Node: ",L[I-1].id),R.addNode(0,L[I-1].id,L[I-1].descr,L[I-1].type,L[I]);break;case 21:R.getLogger().trace("Node: ",L[I].id),R.addNode(0,L[I].id,L[I].descr,L[I].type);break;case 22:R.decorateNode({icon:L[I]});break;case 27:R.getLogger().trace("node found ..",L[I-2]),this.$={id:L[I-1],descr:L[I-1],type:R.getType(L[I-2],L[I])};break;case 28:this.$={id:L[I],descr:L[I],type:0};break;case 29:R.getLogger().trace("node found ..",L[I-3]),this.$={id:L[I-3],descr:L[I-1],type:R.getType(L[I-2],L[I])};break;case 30:this.$=L[I-1]+L[I];break;case 31:this.$=L[I];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:r,9:22,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:h,7:f,10:23,11:d},t(p,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:s,23:l}),t(p,[2,19]),t(p,[2,21],{15:30,24:m}),t(p,[2,22]),t(p,[2,23]),t(g,[2,25]),t(g,[2,26]),t(g,[2,28],{20:[1,32]}),{21:[1,33]},{6:h,7:f,10:34,11:d},{1:[2,7],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(y,[2,14],{7:v,11:x}),t(b,[2,8]),t(b,[2,9]),t(b,[2,10]),t(p,[2,16],{15:37,24:m}),t(p,[2,17]),t(p,[2,18]),t(p,[2,20],{24:T}),t(g,[2,31]),{21:[1,39]},{22:[1,40]},t(y,[2,13],{7:v,11:x}),t(b,[2,11]),t(b,[2,12]),t(p,[2,15],{24:T}),t(g,[2,30]),{22:[1,41]},t(g,[2,27]),t(g,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(C,D){if(D.recoverable)this.trace(C);else{var O=new Error(C);throw O.hash=D,O}},"parseError"),parse:o(function(C){var D=this,O=[0],R=[],k=[null],L=[],A=this.table,I="",M=0,P=0,B=0,F=2,z=1,$=L.slice.call(arguments,1),U=Object.create(this.lexer),K={yy:{}};for(var ee in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ee)&&(K.yy[ee]=this.yy[ee]);U.setInput(C,K.yy),K.yy.lexer=U,K.yy.parser=this,typeof U.yylloc>"u"&&(U.yylloc={});var Y=U.yylloc;L.push(Y);var ce=U.options&&U.options.ranges;typeof K.yy.parseError=="function"?this.parseError=K.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Z(Be){O.length=O.length-2*Be,k.length=k.length-Be,L.length=L.length-Be}o(Z,"popStack");function ue(){var Be;return Be=R.pop()||U.lex()||z,typeof Be!="number"&&(Be instanceof Array&&(R=Be,Be=R.pop()),Be=D.symbols_[Be]||Be),Be}o(ue,"lex");for(var Q,j,ne,te,he,le,J={},Se,se,ae,Oe;;){if(ne=O[O.length-1],this.defaultActions[ne]?te=this.defaultActions[ne]:((Q===null||typeof Q>"u")&&(Q=ue()),te=A[ne]&&A[ne][Q]),typeof te>"u"||!te.length||!te[0]){var ye="";Oe=[];for(Se in A[ne])this.terminals_[Se]&&Se>F&&Oe.push("'"+this.terminals_[Se]+"'");U.showPosition?ye="Parse error on line "+(M+1)+`: -`+U.showPosition()+` -Expecting `+Oe.join(", ")+", got '"+(this.terminals_[Q]||Q)+"'":ye="Parse error on line "+(M+1)+": Unexpected "+(Q==z?"end of input":"'"+(this.terminals_[Q]||Q)+"'"),this.parseError(ye,{text:U.match,token:this.terminals_[Q]||Q,line:U.yylineno,loc:Y,expected:Oe})}if(te[0]instanceof Array&&te.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ne+", token: "+Q);switch(te[0]){case 1:O.push(Q),k.push(U.yytext),L.push(U.yylloc),O.push(te[1]),Q=null,j?(Q=j,j=null):(P=U.yyleng,I=U.yytext,M=U.yylineno,Y=U.yylloc,B>0&&B--);break;case 2:if(se=this.productions_[te[1]][1],J.$=k[k.length-se],J._$={first_line:L[L.length-(se||1)].first_line,last_line:L[L.length-1].last_line,first_column:L[L.length-(se||1)].first_column,last_column:L[L.length-1].last_column},ce&&(J._$.range=[L[L.length-(se||1)].range[0],L[L.length-1].range[1]]),le=this.performAction.apply(J,[I,P,M,K.yy,te[1],k,L].concat($)),typeof le<"u")return le;se&&(O=O.slice(0,-1*se*2),k=k.slice(0,-1*se),L=L.slice(0,-1*se)),O.push(this.productions_[te[1]][0]),k.push(J.$),L.push(J._$),ae=A[O[O.length-2]][O[O.length-1]],O.push(ae);break;case 3:return!0}}return!0},"parse")},w=function(){var _={EOF:1,parseError:o(function(D,O){if(this.yy.parser)this.yy.parser.parseError(D,O);else throw new Error(D)},"parseError"),setInput:o(function(C,D){return this.yy=D||this.yy||{},this._input=C,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var C=this._input[0];this.yytext+=C,this.yyleng++,this.offset++,this.match+=C,this.matched+=C;var D=C.match(/(?:\r\n?|\n).*/g);return D?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),C},"input"),unput:o(function(C){var D=C.length,O=C.split(/(?:\r\n?|\n)/g);this._input=C+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-D),this.offset-=D;var R=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),O.length-1&&(this.yylineno-=O.length-1);var k=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:O?(O.length===R.length?this.yylloc.first_column:0)+R[R.length-O.length].length-O[0].length:this.yylloc.first_column-D},this.options.ranges&&(this.yylloc.range=[k[0],k[0]+this.yyleng-D]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(C){this.unput(this.match.slice(C))},"less"),pastInput:o(function(){var C=this.matched.substr(0,this.matched.length-this.match.length);return(C.length>20?"...":"")+C.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var C=this.match;return C.length<20&&(C+=this._input.substr(0,20-C.length)),(C.substr(0,20)+(C.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var C=this.pastInput(),D=new Array(C.length+1).join("-");return C+this.upcomingInput()+` -`+D+"^"},"showPosition"),test_match:o(function(C,D){var O,R,k;if(this.options.backtrack_lexer&&(k={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(k.yylloc.range=this.yylloc.range.slice(0))),R=C[0].match(/(?:\r\n?|\n).*/g),R&&(this.yylineno+=R.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:R?R[R.length-1].length-R[R.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+C[0].length},this.yytext+=C[0],this.match+=C[0],this.matches=C,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(C[0].length),this.matched+=C[0],O=this.performAction.call(this,this.yy,this,D,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),O)return O;if(this._backtrack){for(var L in k)this[L]=k[L];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var C,D,O,R;this._more||(this.yytext="",this.match="");for(var k=this._currentRules(),L=0;LD[0].length)){if(D=O,R=L,this.options.backtrack_lexer){if(C=this.test_match(O,k[L]),C!==!1)return C;if(this._backtrack){D=!1;continue}else return!1}else if(!this.options.flex)break}return D?(C=this.test_match(D,k[R]),C!==!1?C:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var D=this.next();return D||this.lex()},"lex"),begin:o(function(D){this.conditionStack.push(D)},"begin"),popState:o(function(){var D=this.conditionStack.length-1;return D>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(D){return D=this.conditionStack.length-1-Math.abs(D||0),D>=0?this.conditionStack[D]:"INITIAL"},"topState"),pushState:o(function(D){this.begin(D)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(D,O,R,k){var L=k;switch(R){case 0:return this.pushState("shapeData"),O.yytext="",24;break;case 1:return this.pushState("shapeDataStr"),24;break;case 2:return this.popState(),24;break;case 3:let A=/\n\s*/g;return O.yytext=O.yytext.replace(A,"
    "),24;break;case 4:return 24;case 5:this.popState();break;case 6:return D.getLogger().trace("Found comment",O.yytext),6;break;case 7:return 8;case 8:this.begin("CLASS");break;case 9:return this.popState(),17;break;case 10:this.popState();break;case 11:D.getLogger().trace("Begin icon"),this.begin("ICON");break;case 12:return D.getLogger().trace("SPACELINE"),6;break;case 13:return 7;case 14:return 16;case 15:D.getLogger().trace("end icon"),this.popState();break;case 16:return D.getLogger().trace("Exploding node"),this.begin("NODE"),20;break;case 17:return D.getLogger().trace("Cloud"),this.begin("NODE"),20;break;case 18:return D.getLogger().trace("Explosion Bang"),this.begin("NODE"),20;break;case 19:return D.getLogger().trace("Cloud Bang"),this.begin("NODE"),20;break;case 20:return this.begin("NODE"),20;break;case 21:return this.begin("NODE"),20;break;case 22:return this.begin("NODE"),20;break;case 23:return this.begin("NODE"),20;break;case 24:return 13;case 25:return 23;case 26:return 11;case 27:this.begin("NSTR2");break;case 28:return"NODE_DESCR";case 29:this.popState();break;case 30:D.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 31:return D.getLogger().trace("description:",O.yytext),"NODE_DESCR";break;case 32:this.popState();break;case 33:return this.popState(),D.getLogger().trace("node end ))"),"NODE_DEND";break;case 34:return this.popState(),D.getLogger().trace("node end )"),"NODE_DEND";break;case 35:return this.popState(),D.getLogger().trace("node end ...",O.yytext),"NODE_DEND";break;case 36:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 37:return this.popState(),D.getLogger().trace("node end (-"),"NODE_DEND";break;case 38:return this.popState(),D.getLogger().trace("node end (-"),"NODE_DEND";break;case 39:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 40:return this.popState(),D.getLogger().trace("node end (("),"NODE_DEND";break;case 41:return D.getLogger().trace("Long description:",O.yytext),21;break;case 42:return D.getLogger().trace("Long description:",O.yytext),21;break}},"anonymous"),rules:[/^(?:@\{)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^\"]+)/i,/^(?:[^}^"]+)/i,/^(?:\})/i,/^(?:\s*%%.*)/i,/^(?:kanban\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}@]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{shapeDataEndBracket:{rules:[],inclusive:!1},shapeDataStr:{rules:[2,3],inclusive:!1},shapeData:{rules:[1,4,5],inclusive:!1},CLASS:{rules:[9,10],inclusive:!1},ICON:{rules:[14,15],inclusive:!1},NSTR2:{rules:[28,29],inclusive:!1},NSTR:{rules:[31,32],inclusive:!1},NODE:{rules:[27,30,33,34,35,36,37,38,39,40,41,42],inclusive:!1},INITIAL:{rules:[0,6,7,8,11,12,13,16,17,18,19,20,21,22,23,24,25,26],inclusive:!0}}};return _}();S.lexer=w;function E(){this.yy={}}return o(E,"Parser"),E.prototype=S,S.Parser=E,new E}();dF.parser=dF;fye=dF});var ol,mF,pF,gF,Met,Iet,pye,Oet,Pet,Xi,Bet,Fet,$et,zet,Get,Vet,Uet,mye,gye=N(()=>{"use strict";Gt();pr();yt();_a();PT();ol=[],mF=[],pF=0,gF={},Met=o(()=>{ol=[],mF=[],pF=0,gF={}},"clear"),Iet=o(t=>{if(ol.length===0)return null;let e=ol[0].level,r=null;for(let n=ol.length-1;n>=0;n--)if(ol[n].level===e&&!r&&(r=ol[n]),ol[n].levell.parentId===i.id);for(let l of s){let u={id:l.id,parentId:i.id,label:wr(l.label??"",n),isGroup:!1,ticket:l?.ticket,priority:l?.priority,assigned:l?.assigned,icon:l?.icon,shape:"kanbanItem",level:l.level,rx:5,ry:5,cssStyles:["text-align: left"]};e.push(u)}}return{nodes:e,edges:t,other:{},config:me()}},"getData"),Pet=o((t,e,r,n,i)=>{let a=me(),s=a.mindmap?.padding??or.mindmap.padding;switch(n){case Xi.ROUNDED_RECT:case Xi.RECT:case Xi.HEXAGON:s*=2}let l={id:wr(e,a)||"kbn"+pF++,level:t,label:wr(r,a),width:a.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:s,isGroup:!1};if(i!==void 0){let h;i.includes(` -`)?h=i+` -`:h=`{ -`+i+` -}`;let f=Tm(h,{schema:bm});if(f.shape&&(f.shape!==f.shape.toLowerCase()||f.shape.includes("_")))throw new Error(`No such shape: ${f.shape}. Shape names should be lowercase.`);f?.shape&&f.shape==="kanbanItem"&&(l.shape=f?.shape),f?.label&&(l.label=f?.label),f?.icon&&(l.icon=f?.icon.toString()),f?.assigned&&(l.assigned=f?.assigned.toString()),f?.ticket&&(l.ticket=f?.ticket.toString()),f?.priority&&(l.priority=f?.priority)}let u=Iet(t);u?l.parentId=u.id||"kbn"+pF++:mF.push(l),ol.push(l)},"addNode"),Xi={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},Bet=o((t,e)=>{switch(X.debug("In get type",t,e),t){case"[":return Xi.RECT;case"(":return e===")"?Xi.ROUNDED_RECT:Xi.CLOUD;case"((":return Xi.CIRCLE;case")":return Xi.CLOUD;case"))":return Xi.BANG;case"{{":return Xi.HEXAGON;default:return Xi.DEFAULT}},"getType"),Fet=o((t,e)=>{gF[t]=e},"setElementForId"),$et=o(t=>{if(!t)return;let e=me(),r=ol[ol.length-1];t.icon&&(r.icon=wr(t.icon,e)),t.class&&(r.cssClasses=wr(t.class,e))},"decorateNode"),zet=o(t=>{switch(t){case Xi.DEFAULT:return"no-border";case Xi.RECT:return"rect";case Xi.ROUNDED_RECT:return"rounded-rect";case Xi.CIRCLE:return"circle";case Xi.CLOUD:return"cloud";case Xi.BANG:return"bang";case Xi.HEXAGON:return"hexgon";default:return"no-border"}},"type2Str"),Get=o(()=>X,"getLogger"),Vet=o(t=>gF[t],"getElementById"),Uet={clear:Met,addNode:Pet,getSections:pye,getData:Oet,nodeType:Xi,getType:Bet,setElementForId:Fet,decorateNode:$et,type2Str:zet,getLogger:Get,getElementById:Vet},mye=Uet});var Het,yye,vye=N(()=>{"use strict";Gt();yt();Vl();xi();_a();aw();mw();Het=o(async(t,e,r,n)=>{X.debug(`Rendering kanban diagram -`+t);let a=n.db.getData(),s=me();s.htmlLabels=!1;let l=Li(e),u=l.append("g");u.attr("class","sections");let h=l.append("g");h.attr("class","items");let f=a.nodes.filter(v=>v.isGroup),d=0,p=10,m=[],g=25;for(let v of f){let x=s?.kanban?.sectionWidth||200;d=d+1,v.x=x*d+(d-1)*p/2,v.width=x,v.y=0,v.height=x*3,v.rx=5,v.ry=5,v.cssClasses=v.cssClasses+" section-"+d;let b=await Cm(u,v);g=Math.max(g,b?.labelBBox?.height),m.push(b)}let y=0;for(let v of f){let x=m[y];y=y+1;let b=s?.kanban?.sectionWidth||200,T=-b*3/2+g,S=T,w=a.nodes.filter(C=>C.parentId===v.id);for(let C of w){if(C.isGroup)throw new Error("Groups within groups are not allowed in Kanban diagrams");C.x=v.x,C.width=b-1.5*p;let O=(await Am(h,C,{config:s})).node().getBBox();C.y=S+O.height/2,await M2(C),S=C.y+O.height/2+p/2}let E=x.cluster.select("rect"),_=Math.max(S-T+3*p,50)+(g-25);E.attr("height",_)}Lo(void 0,l,s.mindmap?.padding??or.kanban.padding,s.mindmap?.useMaxWidth??or.kanban.useMaxWidth)},"draw"),yye={draw:Het}});var Wet,qet,xye,bye=N(()=>{"use strict";Ks();Xm();Wet=o(t=>{let e="";for(let n=0;nt.darkMode?Ot(n,i):Lt(n,i),"adjuster");for(let n=0;n` - .edge { - stroke-width: 3; - } - ${Wet(t)} - .section-root rect, .section-root path, .section-root circle, .section-root polygon { - fill: ${t.git0}; - } - .section-root text { - fill: ${t.gitBranchLabel0}; - } - .icon-container { - height:100%; - display: flex; - justify-content: center; - align-items: center; - } - .edge { - fill: none; - } - .cluster-label, .label { - color: ${t.textColor}; - fill: ${t.textColor}; - } - .kanban-label { - dy: 1em; - alignment-baseline: middle; - text-anchor: middle; - dominant-baseline: middle; - text-align: center; - } - ${Nc()} -`,"getStyles"),xye=qet});var Tye={};ur(Tye,{diagram:()=>Yet});var Yet,wye=N(()=>{"use strict";dye();gye();vye();bye();Yet={db:mye,renderer:yye,parser:fye,styles:xye}});var yF,E4,Sye=N(()=>{"use strict";yF=function(){var t=o(function(l,u,h,f){for(h=h||{},f=l.length;f--;h[l[f]]=u);return h},"o"),e=[1,9],r=[1,10],n=[1,5,10,12],i={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:o(function(u,h,f,d,p,m,g){var y=m.length-1;switch(p){case 7:let v=d.findOrCreateNode(m[y-4].trim().replaceAll('""','"')),x=d.findOrCreateNode(m[y-2].trim().replaceAll('""','"')),b=parseFloat(m[y].trim());d.addLink(v,x,b);break;case 8:case 9:case 11:this.$=m[y];break;case 10:this.$=m[y-1];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:e,20:r},{1:[2,6],7:11,10:[1,12]},t(r,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(n,[2,8]),t(n,[2,9]),{19:[1,16]},t(n,[2,11]),{1:[2,1]},{1:[2,5]},t(r,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:e,20:r},{15:18,16:7,17:8,18:e,20:r},{18:[1,19]},t(r,[2,3]),{12:[1,20]},t(n,[2,10]),{15:21,16:7,17:8,18:e,20:r},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:o(function(u,h){if(h.recoverable)this.trace(u);else{var f=new Error(u);throw f.hash=h,f}},"parseError"),parse:o(function(u){var h=this,f=[0],d=[],p=[null],m=[],g=this.table,y="",v=0,x=0,b=0,T=2,S=1,w=m.slice.call(arguments,1),E=Object.create(this.lexer),_={yy:{}};for(var C in this.yy)Object.prototype.hasOwnProperty.call(this.yy,C)&&(_.yy[C]=this.yy[C]);E.setInput(u,_.yy),_.yy.lexer=E,_.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var D=E.yylloc;m.push(D);var O=E.options&&E.options.ranges;typeof _.yy.parseError=="function"?this.parseError=_.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function R(Y){f.length=f.length-2*Y,p.length=p.length-Y,m.length=m.length-Y}o(R,"popStack");function k(){var Y;return Y=d.pop()||E.lex()||S,typeof Y!="number"&&(Y instanceof Array&&(d=Y,Y=d.pop()),Y=h.symbols_[Y]||Y),Y}o(k,"lex");for(var L,A,I,M,P,B,F={},z,$,U,K;;){if(I=f[f.length-1],this.defaultActions[I]?M=this.defaultActions[I]:((L===null||typeof L>"u")&&(L=k()),M=g[I]&&g[I][L]),typeof M>"u"||!M.length||!M[0]){var ee="";K=[];for(z in g[I])this.terminals_[z]&&z>T&&K.push("'"+this.terminals_[z]+"'");E.showPosition?ee="Parse error on line "+(v+1)+`: -`+E.showPosition()+` -Expecting `+K.join(", ")+", got '"+(this.terminals_[L]||L)+"'":ee="Parse error on line "+(v+1)+": Unexpected "+(L==S?"end of input":"'"+(this.terminals_[L]||L)+"'"),this.parseError(ee,{text:E.match,token:this.terminals_[L]||L,line:E.yylineno,loc:D,expected:K})}if(M[0]instanceof Array&&M.length>1)throw new Error("Parse Error: multiple actions possible at state: "+I+", token: "+L);switch(M[0]){case 1:f.push(L),p.push(E.yytext),m.push(E.yylloc),f.push(M[1]),L=null,A?(L=A,A=null):(x=E.yyleng,y=E.yytext,v=E.yylineno,D=E.yylloc,b>0&&b--);break;case 2:if($=this.productions_[M[1]][1],F.$=p[p.length-$],F._$={first_line:m[m.length-($||1)].first_line,last_line:m[m.length-1].last_line,first_column:m[m.length-($||1)].first_column,last_column:m[m.length-1].last_column},O&&(F._$.range=[m[m.length-($||1)].range[0],m[m.length-1].range[1]]),B=this.performAction.apply(F,[y,x,v,_.yy,M[1],p,m].concat(w)),typeof B<"u")return B;$&&(f=f.slice(0,-1*$*2),p=p.slice(0,-1*$),m=m.slice(0,-1*$)),f.push(this.productions_[M[1]][0]),p.push(F.$),m.push(F._$),U=g[f[f.length-2]][f[f.length-1]],f.push(U);break;case 3:return!0}}return!0},"parse")},a=function(){var l={EOF:1,parseError:o(function(h,f){if(this.yy.parser)this.yy.parser.parseError(h,f);else throw new Error(h)},"parseError"),setInput:o(function(u,h){return this.yy=h||this.yy||{},this._input=u,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var u=this._input[0];this.yytext+=u,this.yyleng++,this.offset++,this.match+=u,this.matched+=u;var h=u.match(/(?:\r\n?|\n).*/g);return h?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),u},"input"),unput:o(function(u){var h=u.length,f=u.split(/(?:\r\n?|\n)/g);this._input=u+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-h),this.offset-=h;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===d.length?this.yylloc.first_column:0)+d[d.length-f.length].length-f[0].length:this.yylloc.first_column-h},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-h]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(u){this.unput(this.match.slice(u))},"less"),pastInput:o(function(){var u=this.matched.substr(0,this.matched.length-this.match.length);return(u.length>20?"...":"")+u.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var u=this.match;return u.length<20&&(u+=this._input.substr(0,20-u.length)),(u.substr(0,20)+(u.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var u=this.pastInput(),h=new Array(u.length+1).join("-");return u+this.upcomingInput()+` -`+h+"^"},"showPosition"),test_match:o(function(u,h){var f,d,p;if(this.options.backtrack_lexer&&(p={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(p.yylloc.range=this.yylloc.range.slice(0))),d=u[0].match(/(?:\r\n?|\n).*/g),d&&(this.yylineno+=d.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:d?d[d.length-1].length-d[d.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+u[0].length},this.yytext+=u[0],this.match+=u[0],this.matches=u,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(u[0].length),this.matched+=u[0],f=this.performAction.call(this,this.yy,this,h,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),f)return f;if(this._backtrack){for(var m in p)this[m]=p[m];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var u,h,f,d;this._more||(this.yytext="",this.match="");for(var p=this._currentRules(),m=0;mh[0].length)){if(h=f,d=m,this.options.backtrack_lexer){if(u=this.test_match(f,p[m]),u!==!1)return u;if(this._backtrack){h=!1;continue}else return!1}else if(!this.options.flex)break}return h?(u=this.test_match(h,p[d]),u!==!1?u:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var h=this.next();return h||this.lex()},"lex"),begin:o(function(h){this.conditionStack.push(h)},"begin"),popState:o(function(){var h=this.conditionStack.length-1;return h>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(h){return h=this.conditionStack.length-1-Math.abs(h||0),h>=0?this.conditionStack[h]:"INITIAL"},"topState"),pushState:o(function(h){this.begin(h)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(h,f,d,p){var m=p;switch(d){case 0:return this.pushState("csv"),4;break;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;break;case 5:return 20;case 6:return this.popState("escaped_text"),18;break;case 7:return 19}},"anonymous"),rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};return l}();i.lexer=a;function s(){this.yy={}}return o(s,"Parser"),s.prototype=i,i.Parser=s,new s}();yF.parser=yF;E4=yF});var pC,mC,dC,Qet,vF,Zet,xF,Jet,ett,ttt,rtt,Cye,Aye=N(()=>{"use strict";Gt();pr();ci();pC=[],mC=[],dC=new Map,Qet=o(()=>{pC=[],mC=[],dC=new Map,kr()},"clear"),vF=class{constructor(e,r,n=0){this.source=e;this.target=r;this.value=n}static{o(this,"SankeyLink")}},Zet=o((t,e,r)=>{pC.push(new vF(t,e,r))},"addLink"),xF=class{constructor(e){this.ID=e}static{o(this,"SankeyNode")}},Jet=o(t=>{t=Ze.sanitizeText(t,me());let e=dC.get(t);return e===void 0&&(e=new xF(t),dC.set(t,e),mC.push(e)),e},"findOrCreateNode"),ett=o(()=>mC,"getNodes"),ttt=o(()=>pC,"getLinks"),rtt=o(()=>({nodes:mC.map(t=>({id:t.ID})),links:pC.map(t=>({source:t.source.ID,target:t.target.ID,value:t.value}))}),"getGraph"),Cye={nodesMap:dC,getConfig:o(()=>me().sankey,"getConfig"),getNodes:ett,getLinks:ttt,getGraph:rtt,addLink:Zet,findOrCreateNode:Jet,getAccTitle:Dr,setAccTitle:Ar,getAccDescription:Rr,setAccDescription:Lr,getDiagramTitle:Nr,setDiagramTitle:Or,clear:Qet}});function S4(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}var _ye=N(()=>{"use strict";o(S4,"max")});function my(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var Dye=N(()=>{"use strict";o(my,"min")});function gy(t,e){let r=0;if(e===void 0)for(let n of t)(n=+n)&&(r+=n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&(r+=i)}return r}var Lye=N(()=>{"use strict";o(gy,"sum")});var bF=N(()=>{"use strict";_ye();Dye();Lye()});function ntt(t){return t.target.depth}function TF(t){return t.depth}function wF(t,e){return e-1-t.height}function C4(t,e){return t.sourceLinks.length?t.depth:e-1}function kF(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?my(t.sourceLinks,ntt)-1:0}var EF=N(()=>{"use strict";bF();o(ntt,"targetDepth");o(TF,"left");o(wF,"right");o(C4,"justify");o(kF,"center")});function yy(t){return function(){return t}}var Rye=N(()=>{"use strict";o(yy,"constant")});function Nye(t,e){return gC(t.source,e.source)||t.index-e.index}function Mye(t,e){return gC(t.target,e.target)||t.index-e.index}function gC(t,e){return t.y0-e.y0}function SF(t){return t.value}function itt(t){return t.index}function att(t){return t.nodes}function stt(t){return t.links}function Iye(t,e){let r=t.get(e);if(!r)throw new Error("missing: "+e);return r}function Oye({nodes:t}){for(let e of t){let r=e.y0,n=r;for(let i of e.sourceLinks)i.y0=r+i.width/2,r+=i.width;for(let i of e.targetLinks)i.y1=n+i.width/2,n+=i.width}}function yC(){let t=0,e=0,r=1,n=1,i=24,a=8,s,l=itt,u=C4,h,f,d=att,p=stt,m=6;function g(){let I={nodes:d.apply(null,arguments),links:p.apply(null,arguments)};return y(I),v(I),x(I),b(I),w(I),Oye(I),I}o(g,"sankey"),g.update=function(I){return Oye(I),I},g.nodeId=function(I){return arguments.length?(l=typeof I=="function"?I:yy(I),g):l},g.nodeAlign=function(I){return arguments.length?(u=typeof I=="function"?I:yy(I),g):u},g.nodeSort=function(I){return arguments.length?(h=I,g):h},g.nodeWidth=function(I){return arguments.length?(i=+I,g):i},g.nodePadding=function(I){return arguments.length?(a=s=+I,g):a},g.nodes=function(I){return arguments.length?(d=typeof I=="function"?I:yy(I),g):d},g.links=function(I){return arguments.length?(p=typeof I=="function"?I:yy(I),g):p},g.linkSort=function(I){return arguments.length?(f=I,g):f},g.size=function(I){return arguments.length?(t=e=0,r=+I[0],n=+I[1],g):[r-t,n-e]},g.extent=function(I){return arguments.length?(t=+I[0][0],r=+I[1][0],e=+I[0][1],n=+I[1][1],g):[[t,e],[r,n]]},g.iterations=function(I){return arguments.length?(m=+I,g):m};function y({nodes:I,links:M}){for(let[B,F]of I.entries())F.index=B,F.sourceLinks=[],F.targetLinks=[];let P=new Map(I.map((B,F)=>[l(B,F,I),B]));for(let[B,F]of M.entries()){F.index=B;let{source:z,target:$}=F;typeof z!="object"&&(z=F.source=Iye(P,z)),typeof $!="object"&&($=F.target=Iye(P,$)),z.sourceLinks.push(F),$.targetLinks.push(F)}if(f!=null)for(let{sourceLinks:B,targetLinks:F}of I)B.sort(f),F.sort(f)}o(y,"computeNodeLinks");function v({nodes:I}){for(let M of I)M.value=M.fixedValue===void 0?Math.max(gy(M.sourceLinks,SF),gy(M.targetLinks,SF)):M.fixedValue}o(v,"computeNodeValues");function x({nodes:I}){let M=I.length,P=new Set(I),B=new Set,F=0;for(;P.size;){for(let z of P){z.depth=F;for(let{target:$}of z.sourceLinks)B.add($)}if(++F>M)throw new Error("circular link");P=B,B=new Set}}o(x,"computeNodeDepths");function b({nodes:I}){let M=I.length,P=new Set(I),B=new Set,F=0;for(;P.size;){for(let z of P){z.height=F;for(let{source:$}of z.targetLinks)B.add($)}if(++F>M)throw new Error("circular link");P=B,B=new Set}}o(b,"computeNodeHeights");function T({nodes:I}){let M=S4(I,F=>F.depth)+1,P=(r-t-i)/(M-1),B=new Array(M);for(let F of I){let z=Math.max(0,Math.min(M-1,Math.floor(u.call(null,F,M))));F.layer=z,F.x0=t+z*P,F.x1=F.x0+i,B[z]?B[z].push(F):B[z]=[F]}if(h)for(let F of B)F.sort(h);return B}o(T,"computeNodeLayers");function S(I){let M=my(I,P=>(n-e-(P.length-1)*s)/gy(P,SF));for(let P of I){let B=e;for(let F of P){F.y0=B,F.y1=B+F.value*M,B=F.y1+s;for(let z of F.sourceLinks)z.width=z.value*M}B=(n-B+s)/(P.length+1);for(let F=0;FP.length)-1)),S(M);for(let P=0;P0))continue;let ee=(U/K-$.y0)*M;$.y0+=ee,$.y1+=ee,R($)}h===void 0&&z.sort(gC),C(z,P)}}o(E,"relaxLeftToRight");function _(I,M,P){for(let B=I.length,F=B-2;F>=0;--F){let z=I[F];for(let $ of z){let U=0,K=0;for(let{target:Y,value:ce}of $.sourceLinks){let Z=ce*(Y.layer-$.layer);U+=A($,Y)*Z,K+=Z}if(!(K>0))continue;let ee=(U/K-$.y0)*M;$.y0+=ee,$.y1+=ee,R($)}h===void 0&&z.sort(gC),C(z,P)}}o(_,"relaxRightToLeft");function C(I,M){let P=I.length>>1,B=I[P];O(I,B.y0-s,P-1,M),D(I,B.y1+s,P+1,M),O(I,n,I.length-1,M),D(I,e,0,M)}o(C,"resolveCollisions");function D(I,M,P,B){for(;P1e-6&&(F.y0+=z,F.y1+=z),M=F.y1+s}}o(D,"resolveCollisionsTopToBottom");function O(I,M,P,B){for(;P>=0;--P){let F=I[P],z=(F.y1-M)*B;z>1e-6&&(F.y0-=z,F.y1-=z),M=F.y0-s}}o(O,"resolveCollisionsBottomToTop");function R({sourceLinks:I,targetLinks:M}){if(f===void 0){for(let{source:{sourceLinks:P}}of M)P.sort(Mye);for(let{target:{targetLinks:P}}of I)P.sort(Nye)}}o(R,"reorderNodeLinks");function k(I){if(f===void 0)for(let{sourceLinks:M,targetLinks:P}of I)M.sort(Mye),P.sort(Nye)}o(k,"reorderLinks");function L(I,M){let P=I.y0-(I.sourceLinks.length-1)*s/2;for(let{target:B,width:F}of I.sourceLinks){if(B===M)break;P+=F+s}for(let{source:B,width:F}of M.targetLinks){if(B===I)break;P-=F}return P}o(L,"targetTop");function A(I,M){let P=M.y0-(M.targetLinks.length-1)*s/2;for(let{source:B,width:F}of M.targetLinks){if(B===I)break;P+=F+s}for(let{target:B,width:F}of I.sourceLinks){if(B===M)break;P-=F}return P}return o(A,"sourceTop"),g}var Pye=N(()=>{"use strict";bF();EF();Rye();o(Nye,"ascendingSourceBreadth");o(Mye,"ascendingTargetBreadth");o(gC,"ascendingBreadth");o(SF,"value");o(itt,"defaultId");o(att,"defaultNodes");o(stt,"defaultLinks");o(Iye,"find");o(Oye,"computeLinkBreadths");o(yC,"Sankey")});function _F(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function Bye(){return new _F}var CF,AF,i0,ott,DF,Fye=N(()=>{"use strict";CF=Math.PI,AF=2*CF,i0=1e-6,ott=AF-i0;o(_F,"Path");o(Bye,"path");_F.prototype=Bye.prototype={constructor:_F,moveTo:o(function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},"moveTo"),closePath:o(function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},"closePath"),lineTo:o(function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},"lineTo"),quadraticCurveTo:o(function(t,e,r,n){this._+="Q"+ +t+","+ +e+","+(this._x1=+r)+","+(this._y1=+n)},"quadraticCurveTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._+="C"+ +t+","+ +e+","+ +r+","+ +n+","+(this._x1=+i)+","+(this._y1=+a)},"bezierCurveTo"),arcTo:o(function(t,e,r,n,i){t=+t,e=+e,r=+r,n=+n,i=+i;var a=this._x1,s=this._y1,l=r-t,u=n-e,h=a-t,f=s-e,d=h*h+f*f;if(i<0)throw new Error("negative radius: "+i);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(d>i0)if(!(Math.abs(f*l-u*h)>i0)||!i)this._+="L"+(this._x1=t)+","+(this._y1=e);else{var p=r-a,m=n-s,g=l*l+u*u,y=p*p+m*m,v=Math.sqrt(g),x=Math.sqrt(d),b=i*Math.tan((CF-Math.acos((g+d-y)/(2*v*x)))/2),T=b/x,S=b/v;Math.abs(T-1)>i0&&(this._+="L"+(t+T*h)+","+(e+T*f)),this._+="A"+i+","+i+",0,0,"+ +(f*p>h*m)+","+(this._x1=t+S*l)+","+(this._y1=e+S*u)}},"arcTo"),arc:o(function(t,e,r,n,i,a){t=+t,e=+e,r=+r,a=!!a;var s=r*Math.cos(n),l=r*Math.sin(n),u=t+s,h=e+l,f=1^a,d=a?n-i:i-n;if(r<0)throw new Error("negative radius: "+r);this._x1===null?this._+="M"+u+","+h:(Math.abs(this._x1-u)>i0||Math.abs(this._y1-h)>i0)&&(this._+="L"+u+","+h),r&&(d<0&&(d=d%AF+AF),d>ott?this._+="A"+r+","+r+",0,1,"+f+","+(t-s)+","+(e-l)+"A"+r+","+r+",0,1,"+f+","+(this._x1=u)+","+(this._y1=h):d>i0&&(this._+="A"+r+","+r+",0,"+ +(d>=CF)+","+f+","+(this._x1=t+r*Math.cos(i))+","+(this._y1=e+r*Math.sin(i))))},"arc"),rect:o(function(t,e,r,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +r+"v"+ +n+"h"+-r+"Z"},"rect"),toString:o(function(){return this._},"toString")};DF=Bye});var $ye=N(()=>{"use strict";Fye()});function vC(t){return o(function(){return t},"constant")}var zye=N(()=>{"use strict";o(vC,"default")});function Gye(t){return t[0]}function Vye(t){return t[1]}var Uye=N(()=>{"use strict";o(Gye,"x");o(Vye,"y")});var Hye,Wye=N(()=>{"use strict";Hye=Array.prototype.slice});function ltt(t){return t.source}function ctt(t){return t.target}function utt(t){var e=ltt,r=ctt,n=Gye,i=Vye,a=null;function s(){var l,u=Hye.call(arguments),h=e.apply(this,u),f=r.apply(this,u);if(a||(a=l=DF()),t(a,+n.apply(this,(u[0]=h,u)),+i.apply(this,u),+n.apply(this,(u[0]=f,u)),+i.apply(this,u)),l)return a=null,l+""||null}return o(s,"link"),s.source=function(l){return arguments.length?(e=l,s):e},s.target=function(l){return arguments.length?(r=l,s):r},s.x=function(l){return arguments.length?(n=typeof l=="function"?l:vC(+l),s):n},s.y=function(l){return arguments.length?(i=typeof l=="function"?l:vC(+l),s):i},s.context=function(l){return arguments.length?(a=l??null,s):a},s}function htt(t,e,r,n,i){t.moveTo(e,r),t.bezierCurveTo(e=(e+n)/2,r,e,i,n,i)}function LF(){return utt(htt)}var qye=N(()=>{"use strict";$ye();Wye();zye();Uye();o(ltt,"linkSource");o(ctt,"linkTarget");o(utt,"link");o(htt,"curveHorizontal");o(LF,"linkHorizontal")});var Yye=N(()=>{"use strict";qye()});function ftt(t){return[t.source.x1,t.y0]}function dtt(t){return[t.target.x0,t.y1]}function xC(){return LF().source(ftt).target(dtt)}var Xye=N(()=>{"use strict";Yye();o(ftt,"horizontalSource");o(dtt,"horizontalTarget");o(xC,"default")});var jye=N(()=>{"use strict";Pye();EF();Xye()});var A4,Kye=N(()=>{"use strict";A4=class t{static{o(this,"Uid")}static{this.count=0}static next(e){return new t(e+ ++t.count)}constructor(e){this.id=e,this.href=`#${e}`}toString(){return"url("+this.href+")"}}});var ptt,mtt,Qye,Zye=N(()=>{"use strict";Gt();fr();jye();xi();Kye();ptt={left:TF,right:wF,center:kF,justify:C4},mtt=o(function(t,e,r,n){let{securityLevel:i,sankey:a}=me(),s=$3.sankey,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=a?.width??s.width,d=a?.height??s.width,p=a?.useMaxWidth??s.useMaxWidth,m=a?.nodeAlignment??s.nodeAlignment,g=a?.prefix??s.prefix,y=a?.suffix??s.suffix,v=a?.showValues??s.showValues,x=n.db.getGraph(),b=ptt[m];yC().nodeId(O=>O.id).nodeWidth(10).nodePadding(10+(v?15:0)).nodeAlign(b).extent([[0,0],[f,d]])(x);let w=Js(PD);h.append("g").attr("class","nodes").selectAll(".node").data(x.nodes).join("g").attr("class","node").attr("id",O=>(O.uid=A4.next("node-")).id).attr("transform",function(O){return"translate("+O.x0+","+O.y0+")"}).attr("x",O=>O.x0).attr("y",O=>O.y0).append("rect").attr("height",O=>O.y1-O.y0).attr("width",O=>O.x1-O.x0).attr("fill",O=>w(O.id));let E=o(({id:O,value:R})=>v?`${O} -${g}${Math.round(R*100)/100}${y}`:O,"getText");h.append("g").attr("class","node-labels").attr("font-size",14).selectAll("text").data(x.nodes).join("text").attr("x",O=>O.x0(O.y1+O.y0)/2).attr("dy",`${v?"0":"0.35"}em`).attr("text-anchor",O=>O.x0(R.uid=A4.next("linearGradient-")).id).attr("gradientUnits","userSpaceOnUse").attr("x1",R=>R.source.x1).attr("x2",R=>R.target.x0);O.append("stop").attr("offset","0%").attr("stop-color",R=>w(R.source.id)),O.append("stop").attr("offset","100%").attr("stop-color",R=>w(R.target.id))}let D;switch(C){case"gradient":D=o(O=>O.uid,"coloring");break;case"source":D=o(O=>w(O.source.id),"coloring");break;case"target":D=o(O=>w(O.target.id),"coloring");break;default:D=C}_.append("path").attr("d",xC()).attr("stroke",D).attr("stroke-width",O=>Math.max(1,O.width)),Lo(void 0,h,0,p)},"draw"),Qye={draw:mtt}});var Jye,eve=N(()=>{"use strict";Jye=o(t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,` -`).trim(),"prepareTextForParsing")});var gtt,tve,rve=N(()=>{"use strict";gtt=o(t=>`.label { - font-family: ${t.fontFamily}; - }`,"getStyles"),tve=gtt});var nve={};ur(nve,{diagram:()=>vtt});var ytt,vtt,ive=N(()=>{"use strict";Sye();Aye();Zye();eve();rve();ytt=E4.parse.bind(E4);E4.parse=t=>ytt(Jye(t));vtt={styles:tve,parser:E4,db:Cye,renderer:Qye}});var ove,RF,wtt,ktt,Ett,Stt,Ctt,qf,NF=N(()=>{"use strict";mi();_a();er();ci();ove={packet:[]},RF=structuredClone(ove),wtt=or.packet,ktt=o(()=>{let t=$n({...wtt,...tr().packet});return t.showBits&&(t.paddingY+=10),t},"getConfig"),Ett=o(()=>RF.packet,"getPacket"),Stt=o(t=>{t.length>0&&RF.packet.push(t)},"pushWord"),Ctt=o(()=>{kr(),RF=structuredClone(ove)},"clear"),qf={pushWord:Stt,getPacket:Ett,getConfig:ktt,clear:Ctt,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var Att,_tt,Dtt,lve,cve=N(()=>{"use strict";bf();yt();Mp();NF();Att=1e4,_tt=o(t=>{Jo(t,qf);let e=-1,r=[],n=1,{bitsPerRow:i}=qf.getConfig();for(let{start:a,end:s,bits:l,label:u}of t.blocks){if(a!==void 0&&s!==void 0&&s{if(t.start===void 0)throw new Error("start should have been set during first phase");if(t.end===void 0)throw new Error("end should have been set during first phase");if(t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);if(t.end+1<=e*r)return[t,void 0];let n=e*r-1,i=e*r;return[{start:t.start,end:n,label:t.label,bits:n-t.start},{start:i,end:t.end,label:t.label,bits:t.end-i}]},"getNextFittingBlock"),lve={parse:o(async t=>{let e=await vs("packet",t);X.debug(e),_tt(e)},"parse")}});var Ltt,Rtt,uve,hve=N(()=>{"use strict";Vl();xi();Ltt=o((t,e,r,n)=>{let i=n.db,a=i.getConfig(),{rowHeight:s,paddingY:l,bitWidth:u,bitsPerRow:h}=a,f=i.getPacket(),d=i.getDiagramTitle(),p=s+l,m=p*(f.length+1)-(d?0:s),g=u*h+2,y=Li(e);y.attr("viewbox",`0 0 ${g} ${m}`),fn(y,m,g,a.useMaxWidth);for(let[v,x]of f.entries())Rtt(y,x,v,a);y.append("text").text(d).attr("x",g/2).attr("y",m-p/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),Rtt=o((t,e,r,{rowHeight:n,paddingX:i,paddingY:a,bitWidth:s,bitsPerRow:l,showBits:u})=>{let h=t.append("g"),f=r*(n+a)+a;for(let d of e){let p=d.start%l*s+1,m=(d.end-d.start+1)*s-i;if(h.append("rect").attr("x",p).attr("y",f).attr("width",m).attr("height",n).attr("class","packetBlock"),h.append("text").attr("x",p+m/2).attr("y",f+n/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(d.label),!u)continue;let g=d.end===d.start,y=f-2;h.append("text").attr("x",p+(g?m/2:0)).attr("y",y).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",g?"middle":"start").text(d.start),g||h.append("text").attr("x",p+m).attr("y",y).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(d.end)}},"drawWord"),uve={draw:Ltt}});var Ntt,fve,dve=N(()=>{"use strict";er();Ntt={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},fve=o(({packet:t}={})=>{let e=$n(Ntt,t);return` - .packetByte { - font-size: ${e.byteFontSize}; - } - .packetByte.start { - fill: ${e.startByteColor}; - } - .packetByte.end { - fill: ${e.endByteColor}; - } - .packetLabel { - fill: ${e.labelColor}; - font-size: ${e.labelFontSize}; - } - .packetTitle { - fill: ${e.titleColor}; - font-size: ${e.titleFontSize}; - } - .packetBlock { - stroke: ${e.blockStrokeColor}; - stroke-width: ${e.blockStrokeWidth}; - fill: ${e.blockFillColor}; - } - `},"styles")});var pve={};ur(pve,{diagram:()=>Mtt});var Mtt,mve=N(()=>{"use strict";NF();cve();hve();dve();Mtt={parser:lve,db:qf,renderer:uve,styles:fve}});var vy,vve,a0,Ptt,Btt,xve,Ftt,$tt,ztt,Gtt,Vtt,Utt,Htt,s0,MF=N(()=>{"use strict";mi();_a();er();ci();vy={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},vve={axes:[],curves:[],options:vy},a0=structuredClone(vve),Ptt=or.radar,Btt=o(()=>$n({...Ptt,...tr().radar}),"getConfig"),xve=o(()=>a0.axes,"getAxes"),Ftt=o(()=>a0.curves,"getCurves"),$tt=o(()=>a0.options,"getOptions"),ztt=o(t=>{a0.axes=t.map(e=>({name:e.name,label:e.label??e.name}))},"setAxes"),Gtt=o(t=>{a0.curves=t.map(e=>({name:e.name,label:e.label??e.name,entries:Vtt(e.entries)}))},"setCurves"),Vtt=o(t=>{if(t[0].axis==null)return t.map(r=>r.value);let e=xve();if(e.length===0)throw new Error("Axes must be populated before curves for reference entries");return e.map(r=>{let n=t.find(i=>i.axis?.$refText===r.name);if(n===void 0)throw new Error("Missing entry for axis "+r.label);return n.value})},"computeCurveEntries"),Utt=o(t=>{let e=t.reduce((r,n)=>(r[n.name]=n,r),{});a0.options={showLegend:e.showLegend?.value??vy.showLegend,ticks:e.ticks?.value??vy.ticks,max:e.max?.value??vy.max,min:e.min?.value??vy.min,graticule:e.graticule?.value??vy.graticule}},"setOptions"),Htt=o(()=>{kr(),a0=structuredClone(vve)},"clear"),s0={getAxes:xve,getCurves:Ftt,getOptions:$tt,setAxes:ztt,setCurves:Gtt,setOptions:Utt,getConfig:Btt,clear:Htt,setAccTitle:Ar,getAccTitle:Dr,setDiagramTitle:Or,getDiagramTitle:Nr,getAccDescription:Rr,setAccDescription:Lr}});var Wtt,bve,Tve=N(()=>{"use strict";bf();yt();Mp();MF();Wtt=o(t=>{Jo(t,s0);let{axes:e,curves:r,options:n}=t;s0.setAxes(e),s0.setCurves(r),s0.setOptions(n)},"populate"),bve={parse:o(async t=>{let e=await vs("radar",t);X.debug(e),Wtt(e)},"parse")}});function Ktt(t,e,r,n,i,a,s){let l=e.length,u=Math.min(s.width,s.height)/2;r.forEach((h,f)=>{if(h.entries.length!==l)return;let d=h.entries.map((p,m)=>{let g=2*Math.PI*m/l-Math.PI/2,y=Qtt(p,n,i,u),v=y*Math.cos(g),x=y*Math.sin(g);return{x:v,y:x}});a==="circle"?t.append("path").attr("d",Ztt(d,s.curveTension)).attr("class",`radarCurve-${f}`):a==="polygon"&&t.append("polygon").attr("points",d.map(p=>`${p.x},${p.y}`).join(" ")).attr("class",`radarCurve-${f}`)})}function Qtt(t,e,r,n){let i=Math.min(Math.max(t,e),r);return n*(i-e)/(r-e)}function Ztt(t,e){let r=t.length,n=`M${t[0].x},${t[0].y}`;for(let i=0;i{let h=t.append("g").attr("transform",`translate(${i}, ${a+u*s})`);h.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${u}`),h.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(l.label)})}var qtt,Ytt,Xtt,jtt,wve,kve=N(()=>{"use strict";Vl();qtt=o((t,e,r,n)=>{let i=n.db,a=i.getAxes(),s=i.getCurves(),l=i.getOptions(),u=i.getConfig(),h=i.getDiagramTitle(),f=Li(e),d=Ytt(f,u),p=l.max??Math.max(...s.map(y=>Math.max(...y.entries))),m=l.min,g=Math.min(u.width,u.height)/2;Xtt(d,a,g,l.ticks,l.graticule),jtt(d,a,g,u),Ktt(d,a,s,m,p,l.graticule,u),Jtt(d,s,l.showLegend,u),d.append("text").attr("class","radarTitle").text(h).attr("x",0).attr("y",-u.height/2-u.marginTop)},"draw"),Ytt=o((t,e)=>{let r=e.width+e.marginLeft+e.marginRight,n=e.height+e.marginTop+e.marginBottom,i={x:e.marginLeft+e.width/2,y:e.marginTop+e.height/2};return t.attr("viewbox",`0 0 ${r} ${n}`).attr("width",r).attr("height",n),t.append("g").attr("transform",`translate(${i.x}, ${i.y})`)},"drawFrame"),Xtt=o((t,e,r,n,i)=>{if(i==="circle")for(let a=0;a{let d=2*f*Math.PI/a-Math.PI/2,p=l*Math.cos(d),m=l*Math.sin(d);return`${p},${m}`}).join(" ");t.append("polygon").attr("points",u).attr("class","radarGraticule")}}},"drawGraticule"),jtt=o((t,e,r,n)=>{let i=e.length;for(let a=0;a{"use strict";er();By();mi();ert=o((t,e)=>{let r="";for(let n=0;n{let e=dh(),r=tr(),n=$n(e,r.themeVariables),i=$n(n.radar,t);return{themeVariables:n,radarOptions:i}},"buildRadarStyleOptions"),Eve=o(({radar:t}={})=>{let{themeVariables:e,radarOptions:r}=trt(t);return` - .radarTitle { - font-size: ${e.fontSize}; - color: ${e.titleColor}; - dominant-baseline: hanging; - text-anchor: middle; - } - .radarAxisLine { - stroke: ${r.axisColor}; - stroke-width: ${r.axisStrokeWidth}; - } - .radarAxisLabel { - dominant-baseline: middle; - text-anchor: middle; - font-size: ${r.axisLabelFontSize}px; - color: ${r.axisColor}; - } - .radarGraticule { - fill: ${r.graticuleColor}; - fill-opacity: ${r.graticuleOpacity}; - stroke: ${r.graticuleColor}; - stroke-width: ${r.graticuleStrokeWidth}; - } - .radarLegendText { - text-anchor: start; - font-size: ${r.legendFontSize}px; - dominant-baseline: hanging; - } - ${ert(e,r)} - `},"styles")});var Cve={};ur(Cve,{diagram:()=>rrt});var rrt,Ave=N(()=>{"use strict";MF();Tve();kve();Sve();rrt={parser:bve,db:s0,renderer:wve,styles:Eve}});var IF,Lve,Rve=N(()=>{"use strict";IF=function(){var t=o(function(T,S,w,E){for(w=w||{},E=T.length;E--;w[T[E]]=S);return w},"o"),e=[1,7],r=[1,13],n=[1,14],i=[1,15],a=[1,19],s=[1,16],l=[1,17],u=[1,18],h=[8,30],f=[8,21,28,29,30,31,32,40,44,47],d=[1,23],p=[1,24],m=[8,15,16,21,28,29,30,31,32,40,44,47],g=[8,15,16,21,27,28,29,30,31,32,40,44,47],y=[1,49],v={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:o(function(S,w,E,_,C,D,O){var R=D.length-1;switch(C){case 4:_.getLogger().debug("Rule: separator (NL) ");break;case 5:_.getLogger().debug("Rule: separator (Space) ");break;case 6:_.getLogger().debug("Rule: separator (EOF) ");break;case 7:_.getLogger().debug("Rule: hierarchy: ",D[R-1]),_.setHierarchy(D[R-1]);break;case 8:_.getLogger().debug("Stop NL ");break;case 9:_.getLogger().debug("Stop EOF ");break;case 10:_.getLogger().debug("Stop NL2 ");break;case 11:_.getLogger().debug("Stop EOF2 ");break;case 12:_.getLogger().debug("Rule: statement: ",D[R]),typeof D[R].length=="number"?this.$=D[R]:this.$=[D[R]];break;case 13:_.getLogger().debug("Rule: statement #2: ",D[R-1]),this.$=[D[R-1]].concat(D[R]);break;case 14:_.getLogger().debug("Rule: link: ",D[R],S),this.$={edgeTypeStr:D[R],label:""};break;case 15:_.getLogger().debug("Rule: LABEL link: ",D[R-3],D[R-1],D[R]),this.$={edgeTypeStr:D[R],label:D[R-1]};break;case 18:let k=parseInt(D[R]),L=_.generateId();this.$={id:L,type:"space",label:"",width:k,children:[]};break;case 23:_.getLogger().debug("Rule: (nodeStatement link node) ",D[R-2],D[R-1],D[R]," typestr: ",D[R-1].edgeTypeStr);let A=_.edgeStrToEdgeData(D[R-1].edgeTypeStr);this.$=[{id:D[R-2].id,label:D[R-2].label,type:D[R-2].type,directions:D[R-2].directions},{id:D[R-2].id+"-"+D[R].id,start:D[R-2].id,end:D[R].id,label:D[R-1].label,type:"edge",directions:D[R].directions,arrowTypeEnd:A,arrowTypeStart:"arrow_open"},{id:D[R].id,label:D[R].label,type:_.typeStr2Type(D[R].typeStr),directions:D[R].directions}];break;case 24:_.getLogger().debug("Rule: nodeStatement (abc88 node size) ",D[R-1],D[R]),this.$={id:D[R-1].id,label:D[R-1].label,type:_.typeStr2Type(D[R-1].typeStr),directions:D[R-1].directions,widthInColumns:parseInt(D[R],10)};break;case 25:_.getLogger().debug("Rule: nodeStatement (node) ",D[R]),this.$={id:D[R].id,label:D[R].label,type:_.typeStr2Type(D[R].typeStr),directions:D[R].directions,widthInColumns:1};break;case 26:_.getLogger().debug("APA123",this?this:"na"),_.getLogger().debug("COLUMNS: ",D[R]),this.$={type:"column-setting",columns:D[R]==="auto"?-1:parseInt(D[R])};break;case 27:_.getLogger().debug("Rule: id-block statement : ",D[R-2],D[R-1]);let I=_.generateId();this.$={...D[R-2],type:"composite",children:D[R-1]};break;case 28:_.getLogger().debug("Rule: blockStatement : ",D[R-2],D[R-1],D[R]);let M=_.generateId();this.$={id:M,type:"composite",label:"",children:D[R-1]};break;case 29:_.getLogger().debug("Rule: node (NODE_ID separator): ",D[R]),this.$={id:D[R]};break;case 30:_.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",D[R-1],D[R]),this.$={id:D[R-1],label:D[R].label,typeStr:D[R].typeStr,directions:D[R].directions};break;case 31:_.getLogger().debug("Rule: dirList: ",D[R]),this.$=[D[R]];break;case 32:_.getLogger().debug("Rule: dirList: ",D[R-1],D[R]),this.$=[D[R-1]].concat(D[R]);break;case 33:_.getLogger().debug("Rule: nodeShapeNLabel: ",D[R-2],D[R-1],D[R]),this.$={typeStr:D[R-2]+D[R],label:D[R-1]};break;case 34:_.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",D[R-3],D[R-2]," #3:",D[R-1],D[R]),this.$={typeStr:D[R-3]+D[R],label:D[R-2],directions:D[R-1]};break;case 35:case 36:this.$={type:"classDef",id:D[R-1].trim(),css:D[R].trim()};break;case 37:this.$={type:"applyClass",id:D[R-1].trim(),styleClass:D[R].trim()};break;case 38:this.$={type:"applyStyles",id:D[R-1].trim(),stylesStr:D[R].trim()};break}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{8:[1,20]},t(h,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:e,28:r,29:n,31:i,32:a,40:s,44:l,47:u}),t(f,[2,16],{14:22,15:d,16:p}),t(f,[2,17]),t(f,[2,18]),t(f,[2,19]),t(f,[2,20]),t(f,[2,21]),t(f,[2,22]),t(m,[2,25],{27:[1,25]}),t(f,[2,26]),{19:26,26:12,32:a},{11:27,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},t(g,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},t(h,[2,13]),{26:35,32:a},{32:[2,14]},{17:[1,36]},t(m,[2,24]),{11:37,13:4,14:22,15:d,16:p,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},t(g,[2,30]),{18:[1,43]},{18:[1,44]},t(m,[2,23]),{18:[1,45]},{30:[1,46]},t(f,[2,28]),t(f,[2,35]),t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),{37:[1,47]},{34:48,35:y},{15:[1,50]},t(f,[2,27]),t(g,[2,33]),{39:[1,51]},{34:52,35:y,39:[2,31]},{32:[2,15]},t(g,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:o(function(S,w){if(w.recoverable)this.trace(S);else{var E=new Error(S);throw E.hash=w,E}},"parseError"),parse:o(function(S){var w=this,E=[0],_=[],C=[null],D=[],O=this.table,R="",k=0,L=0,A=0,I=2,M=1,P=D.slice.call(arguments,1),B=Object.create(this.lexer),F={yy:{}};for(var z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,z)&&(F.yy[z]=this.yy[z]);B.setInput(S,F.yy),F.yy.lexer=B,F.yy.parser=this,typeof B.yylloc>"u"&&(B.yylloc={});var $=B.yylloc;D.push($);var U=B.options&&B.options.ranges;typeof F.yy.parseError=="function"?this.parseError=F.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function K(se){E.length=E.length-2*se,C.length=C.length-se,D.length=D.length-se}o(K,"popStack");function ee(){var se;return se=_.pop()||B.lex()||M,typeof se!="number"&&(se instanceof Array&&(_=se,se=_.pop()),se=w.symbols_[se]||se),se}o(ee,"lex");for(var Y,ce,Z,ue,Q,j,ne={},te,he,le,J;;){if(Z=E[E.length-1],this.defaultActions[Z]?ue=this.defaultActions[Z]:((Y===null||typeof Y>"u")&&(Y=ee()),ue=O[Z]&&O[Z][Y]),typeof ue>"u"||!ue.length||!ue[0]){var Se="";J=[];for(te in O[Z])this.terminals_[te]&&te>I&&J.push("'"+this.terminals_[te]+"'");B.showPosition?Se="Parse error on line "+(k+1)+`: -`+B.showPosition()+` -Expecting `+J.join(", ")+", got '"+(this.terminals_[Y]||Y)+"'":Se="Parse error on line "+(k+1)+": Unexpected "+(Y==M?"end of input":"'"+(this.terminals_[Y]||Y)+"'"),this.parseError(Se,{text:B.match,token:this.terminals_[Y]||Y,line:B.yylineno,loc:$,expected:J})}if(ue[0]instanceof Array&&ue.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Z+", token: "+Y);switch(ue[0]){case 1:E.push(Y),C.push(B.yytext),D.push(B.yylloc),E.push(ue[1]),Y=null,ce?(Y=ce,ce=null):(L=B.yyleng,R=B.yytext,k=B.yylineno,$=B.yylloc,A>0&&A--);break;case 2:if(he=this.productions_[ue[1]][1],ne.$=C[C.length-he],ne._$={first_line:D[D.length-(he||1)].first_line,last_line:D[D.length-1].last_line,first_column:D[D.length-(he||1)].first_column,last_column:D[D.length-1].last_column},U&&(ne._$.range=[D[D.length-(he||1)].range[0],D[D.length-1].range[1]]),j=this.performAction.apply(ne,[R,L,k,F.yy,ue[1],C,D].concat(P)),typeof j<"u")return j;he&&(E=E.slice(0,-1*he*2),C=C.slice(0,-1*he),D=D.slice(0,-1*he)),E.push(this.productions_[ue[1]][0]),C.push(ne.$),D.push(ne._$),le=O[E[E.length-2]][E[E.length-1]],E.push(le);break;case 3:return!0}}return!0},"parse")},x=function(){var T={EOF:1,parseError:o(function(w,E){if(this.yy.parser)this.yy.parser.parseError(w,E);else throw new Error(w)},"parseError"),setInput:o(function(S,w){return this.yy=w||this.yy||{},this._input=S,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var S=this._input[0];this.yytext+=S,this.yyleng++,this.offset++,this.match+=S,this.matched+=S;var w=S.match(/(?:\r\n?|\n).*/g);return w?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),S},"input"),unput:o(function(S){var w=S.length,E=S.split(/(?:\r\n?|\n)/g);this._input=S+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-w),this.offset-=w;var _=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),E.length-1&&(this.yylineno-=E.length-1);var C=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:E?(E.length===_.length?this.yylloc.first_column:0)+_[_.length-E.length].length-E[0].length:this.yylloc.first_column-w},this.options.ranges&&(this.yylloc.range=[C[0],C[0]+this.yyleng-w]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). -`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(S){this.unput(this.match.slice(S))},"less"),pastInput:o(function(){var S=this.matched.substr(0,this.matched.length-this.match.length);return(S.length>20?"...":"")+S.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var S=this.match;return S.length<20&&(S+=this._input.substr(0,20-S.length)),(S.substr(0,20)+(S.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var S=this.pastInput(),w=new Array(S.length+1).join("-");return S+this.upcomingInput()+` -`+w+"^"},"showPosition"),test_match:o(function(S,w){var E,_,C;if(this.options.backtrack_lexer&&(C={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(C.yylloc.range=this.yylloc.range.slice(0))),_=S[0].match(/(?:\r\n?|\n).*/g),_&&(this.yylineno+=_.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:_?_[_.length-1].length-_[_.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+S[0].length},this.yytext+=S[0],this.match+=S[0],this.matches=S,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(S[0].length),this.matched+=S[0],E=this.performAction.call(this,this.yy,this,w,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),E)return E;if(this._backtrack){for(var D in C)this[D]=C[D];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var S,w,E,_;this._more||(this.yytext="",this.match="");for(var C=this._currentRules(),D=0;Dw[0].length)){if(w=E,_=D,this.options.backtrack_lexer){if(S=this.test_match(E,C[D]),S!==!1)return S;if(this._backtrack){w=!1;continue}else return!1}else if(!this.options.flex)break}return w?(S=this.test_match(w,C[_]),S!==!1?S:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var w=this.next();return w||this.lex()},"lex"),begin:o(function(w){this.conditionStack.push(w)},"begin"),popState:o(function(){var w=this.conditionStack.length-1;return w>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(w){return w=this.conditionStack.length-1-Math.abs(w||0),w>=0?this.conditionStack[w]:"INITIAL"},"topState"),pushState:o(function(w){this.begin(w)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(w,E,_,C){var D=C;switch(_){case 0:return 10;case 1:return w.getLogger().debug("Found space-block"),31;break;case 2:return w.getLogger().debug("Found nl-block"),31;break;case 3:return w.getLogger().debug("Found space-block"),29;break;case 4:w.getLogger().debug(".",E.yytext);break;case 5:w.getLogger().debug("_",E.yytext);break;case 6:return 5;case 7:return E.yytext=-1,28;break;case 8:return E.yytext=E.yytext.replace(/columns\s+/,""),w.getLogger().debug("COLUMNS (LEX)",E.yytext),28;break;case 9:this.pushState("md_string");break;case 10:return"MD_STR";case 11:this.popState();break;case 12:this.pushState("string");break;case 13:w.getLogger().debug("LEX: POPPING STR:",E.yytext),this.popState();break;case 14:return w.getLogger().debug("LEX: STR end:",E.yytext),"STR";break;case 15:return E.yytext=E.yytext.replace(/space\:/,""),w.getLogger().debug("SPACE NUM (LEX)",E.yytext),21;break;case 16:return E.yytext="1",w.getLogger().debug("COLUMNS (LEX)",E.yytext),21;break;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;break;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 22:return this.popState(),this.pushState("CLASSDEFID"),41;break;case 23:return this.popState(),42;break;case 24:return this.pushState("CLASS"),44;break;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;break;case 26:return this.popState(),46;break;case 27:return this.pushState("STYLE_STMNT"),47;break;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;break;case 29:return this.popState(),49;break;case 30:return this.pushState("acc_title"),"acc_title";break;case 31:return this.popState(),"acc_title_value";break;case 32:return this.pushState("acc_descr"),"acc_descr";break;case 33:return this.popState(),"acc_descr_value";break;case 34:this.pushState("acc_descr_multiline");break;case 35:this.popState();break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 39:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 40:return this.popState(),w.getLogger().debug("Lex: ))"),"NODE_DEND";break;case 41:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 42:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 43:return this.popState(),w.getLogger().debug("Lex: (-"),"NODE_DEND";break;case 44:return this.popState(),w.getLogger().debug("Lex: -)"),"NODE_DEND";break;case 45:return this.popState(),w.getLogger().debug("Lex: (("),"NODE_DEND";break;case 46:return this.popState(),w.getLogger().debug("Lex: ]]"),"NODE_DEND";break;case 47:return this.popState(),w.getLogger().debug("Lex: ("),"NODE_DEND";break;case 48:return this.popState(),w.getLogger().debug("Lex: ])"),"NODE_DEND";break;case 49:return this.popState(),w.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 50:return this.popState(),w.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 51:return this.popState(),w.getLogger().debug("Lex: )]"),"NODE_DEND";break;case 52:return this.popState(),w.getLogger().debug("Lex: )"),"NODE_DEND";break;case 53:return this.popState(),w.getLogger().debug("Lex: ]>"),"NODE_DEND";break;case 54:return this.popState(),w.getLogger().debug("Lex: ]"),"NODE_DEND";break;case 55:return w.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;break;case 56:return w.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;break;case 57:return w.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;break;case 58:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 59:return w.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;break;case 60:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 61:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 62:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 63:return w.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;break;case 64:return w.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;break;case 65:return w.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 66:return this.pushState("NODE"),36;break;case 67:return this.pushState("NODE"),36;break;case 68:return this.pushState("NODE"),36;break;case 69:return this.pushState("NODE"),36;break;case 70:return this.pushState("NODE"),36;break;case 71:return this.pushState("NODE"),36;break;case 72:return this.pushState("NODE"),36;break;case 73:return w.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;break;case 74:return this.pushState("BLOCK_ARROW"),w.getLogger().debug("LEX ARR START"),38;break;case 75:return w.getLogger().debug("Lex: NODE_ID",E.yytext),32;break;case 76:return w.getLogger().debug("Lex: EOF",E.yytext),8;break;case 77:this.pushState("md_string");break;case 78:this.pushState("md_string");break;case 79:return"NODE_DESCR";case 80:this.popState();break;case 81:w.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:w.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return w.getLogger().debug("LEX: NODE_DESCR:",E.yytext),"NODE_DESCR";break;case 84:w.getLogger().debug("LEX POPPING"),this.popState();break;case 85:w.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (right): dir:",E.yytext),"DIR";break;case 87:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (left):",E.yytext),"DIR";break;case 88:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (x):",E.yytext),"DIR";break;case 89:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (y):",E.yytext),"DIR";break;case 90:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (up):",E.yytext),"DIR";break;case 91:return E.yytext=E.yytext.replace(/^,\s*/,""),w.getLogger().debug("Lex (down):",E.yytext),"DIR";break;case 92:return E.yytext="]>",w.getLogger().debug("Lex (ARROW_DIR end):",E.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";break;case 93:return w.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 94:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 95:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 96:return w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 97:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 98:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 99:return w.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 100:this.pushState("md_string");break;case 101:return w.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";break;case 102:return this.popState(),w.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 103:return this.popState(),w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 104:return this.popState(),w.getLogger().debug("Lex: LINK",E.yytext),15;break;case 105:return w.getLogger().debug("Lex: COLON",E.yytext),E.yytext=E.yytext.slice(1),27;break}},"anonymous"),rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}};return T}();v.lexer=x;function b(){this.yy={}}return o(b,"Parser"),b.prototype=v,v.Parser=b,new b}();IF.parser=IF;Lve=IF});function frt(t){switch(X.debug("typeStr2Type",t),t){case"[]":return"square";case"()":return X.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}}function drt(t){switch(X.debug("typeStr2Type",t),t){case"==":return"thick";default:return"normal"}}function prt(t){switch(t.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}}var Yl,PF,OF,Nve,Mve,art,Ove,srt,bC,ort,lrt,crt,urt,Pve,BF,_4,hrt,Ive,mrt,grt,yrt,vrt,xrt,brt,Trt,wrt,krt,Ert,Srt,Bve,Fve=N(()=>{"use strict";JL();mi();Gt();yt();pr();ci();Yl=new Map,PF=[],OF=new Map,Nve="color",Mve="fill",art="bgFill",Ove=",",srt=me(),bC=new Map,ort=o(t=>Ze.sanitizeText(t,srt),"sanitizeText"),lrt=o(function(t,e=""){let r=bC.get(t);r||(r={id:t,styles:[],textStyles:[]},bC.set(t,r)),e?.split(Ove).forEach(n=>{let i=n.replace(/([^;]*);/,"$1").trim();if(RegExp(Nve).exec(n)){let s=i.replace(Mve,art).replace(Nve,Mve);r.textStyles.push(s)}r.styles.push(i)})},"addStyleClass"),crt=o(function(t,e=""){let r=Yl.get(t);e!=null&&(r.styles=e.split(Ove))},"addStyle2Node"),urt=o(function(t,e){t.split(",").forEach(function(r){let n=Yl.get(r);if(n===void 0){let i=r.trim();n={id:i,type:"na",children:[]},Yl.set(i,n)}n.classes||(n.classes=[]),n.classes.push(e)})},"setCssClass"),Pve=o((t,e)=>{let r=t.flat(),n=[];for(let i of r){if(i.label&&(i.label=ort(i.label)),i.type==="classDef"){lrt(i.id,i.css);continue}if(i.type==="applyClass"){urt(i.id,i?.styleClass??"");continue}if(i.type==="applyStyles"){i?.stylesStr&&crt(i.id,i?.stylesStr);continue}if(i.type==="column-setting")e.columns=i.columns??-1;else if(i.type==="edge"){let a=(OF.get(i.id)??0)+1;OF.set(i.id,a),i.id=a+"-"+i.id,PF.push(i)}else{i.label||(i.type==="composite"?i.label="":i.label=i.id);let a=Yl.get(i.id);if(a===void 0?Yl.set(i.id,i):(i.type!=="na"&&(a.type=i.type),i.label!==i.id&&(a.label=i.label)),i.children&&Pve(i.children,i),i.type==="space"){let s=i.width??1;for(let l=0;l{X.debug("Clear called"),kr(),_4={id:"root",type:"composite",children:[],columns:-1},Yl=new Map([["root",_4]]),BF=[],bC=new Map,PF=[],OF=new Map},"clear");o(frt,"typeStr2Type");o(drt,"edgeTypeStr2Type");o(prt,"edgeStrToEdgeData");Ive=0,mrt=o(()=>(Ive++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Ive),"generateId"),grt=o(t=>{_4.children=t,Pve(t,_4),BF=_4.children},"setHierarchy"),yrt=o(t=>{let e=Yl.get(t);return e?e.columns?e.columns:e.children?e.children.length:-1:-1},"getColumns"),vrt=o(()=>[...Yl.values()],"getBlocksFlat"),xrt=o(()=>BF||[],"getBlocks"),brt=o(()=>PF,"getEdges"),Trt=o(t=>Yl.get(t),"getBlock"),wrt=o(t=>{Yl.set(t.id,t)},"setBlock"),krt=o(()=>X,"getLogger"),Ert=o(function(){return bC},"getClasses"),Srt={getConfig:o(()=>tr().block,"getConfig"),typeStr2Type:frt,edgeTypeStr2Type:drt,edgeStrToEdgeData:prt,getLogger:krt,getBlocksFlat:vrt,getBlocks:xrt,getEdges:brt,setHierarchy:grt,getBlock:Trt,setBlock:wrt,getColumns:yrt,getClasses:Ert,clear:hrt,generateId:mrt},Bve=Srt});var TC,Crt,$ve,zve=N(()=>{"use strict";Ks();Xm();TC=o((t,e)=>{let r=id,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return Qa(n,i,a,e)},"fade"),Crt=o(t=>`.label { - font-family: ${t.fontFamily}; - color: ${t.nodeTextColor||t.textColor}; - } - .cluster-label text { - fill: ${t.titleColor}; - } - .cluster-label span,p { - color: ${t.titleColor}; - } - - - - .label text,span,p { - fill: ${t.nodeTextColor||t.textColor}; - color: ${t.nodeTextColor||t.textColor}; - } - - .node rect, - .node circle, - .node ellipse, - .node polygon, - .node path { - fill: ${t.mainBkg}; - stroke: ${t.nodeBorder}; - stroke-width: 1px; - } - .flowchart-label text { - text-anchor: middle; - } - // .flowchart-label .text-outer-tspan { - // text-anchor: middle; - // } - // .flowchart-label .text-inner-tspan { - // text-anchor: start; - // } - - .node .label { - text-align: center; - } - .node.clickable { - cursor: pointer; - } - - .arrowheadPath { - fill: ${t.arrowheadColor}; - } - - .edgePath .path { - stroke: ${t.lineColor}; - stroke-width: 2.0px; - } - - .flowchart-link { - stroke: ${t.lineColor}; - fill: none; - } - - .edgeLabel { - background-color: ${t.edgeLabelBackground}; - rect { - opacity: 0.5; - background-color: ${t.edgeLabelBackground}; - fill: ${t.edgeLabelBackground}; - } - text-align: center; - } - - /* For html labels only */ - .labelBkg { - background-color: ${TC(t.edgeLabelBackground,.5)}; - // background-color: - } - - .node .cluster { - // fill: ${TC(t.mainBkg,.5)}; - fill: ${TC(t.clusterBkg,.5)}; - stroke: ${TC(t.clusterBorder,.2)}; - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - stroke-width: 1px; - } - - .cluster text { - fill: ${t.titleColor}; - } - - .cluster span,p { - color: ${t.titleColor}; - } - /* .cluster div { - color: ${t.titleColor}; - } */ - - div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: ${t.fontFamily}; - font-size: 12px; - background: ${t.tertiaryColor}; - border: 1px solid ${t.border2}; - border-radius: 2px; - pointer-events: none; - z-index: 100; - } - - .flowchartTitleText { - text-anchor: middle; - font-size: 18px; - fill: ${t.textColor}; - } - ${Nc()} -`,"getStyles"),$ve=Crt});var Art,_rt,Drt,Lrt,Rrt,Nrt,Mrt,Irt,Ort,Prt,Brt,Gve,Vve=N(()=>{"use strict";yt();Art=o((t,e,r,n)=>{e.forEach(i=>{Brt[i](t,r,n)})},"insertMarkers"),_rt=o((t,e,r)=>{X.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),Drt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),Lrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),Rrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),Nrt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),Mrt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),Irt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),Ort=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),Prt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),Brt={extension:_rt,composition:Drt,aggregation:Lrt,dependency:Rrt,lollipop:Nrt,point:Mrt,circle:Irt,cross:Ort,barb:Prt},Gve=Art});function Frt(t,e){if(t===0||!Number.isInteger(t))throw new Error("Columns must be an integer !== 0.");if(e<0||!Number.isInteger(e))throw new Error("Position must be a non-negative integer."+e);if(t<0)return{px:e,py:0};if(t===1)return{px:0,py:e};let r=e%t,n=Math.floor(e/t);return{px:r,py:n}}function FF(t,e,r=0,n=0){X.debug("setBlockSizes abc95 (start)",t.id,t?.size?.x,"block width =",t?.size,"siblingWidth",r),t?.size?.width||(t.size={width:r,height:n,x:0,y:0});let i=0,a=0;if(t.children?.length>0){for(let m of t.children)FF(m,e);let s=$rt(t);i=s.width,a=s.height,X.debug("setBlockSizes abc95 maxWidth of",t.id,":s children is ",i,a);for(let m of t.children)m.size&&(X.debug(`abc95 Setting size of children of ${t.id} id=${m.id} ${i} ${a} ${JSON.stringify(m.size)}`),m.size.width=i*(m.widthInColumns??1)+ki*((m.widthInColumns??1)-1),m.size.height=a,m.size.x=0,m.size.y=0,X.debug(`abc95 updating size of ${t.id} children child:${m.id} maxWidth:${i} maxHeight:${a}`));for(let m of t.children)FF(m,e,i,a);let l=t.columns??-1,u=0;for(let m of t.children)u+=m.widthInColumns??1;let h=t.children.length;l>0&&l0?Math.min(t.children.length,l):t.children.length;if(m>0){let g=(d-m*ki-ki)/m;X.debug("abc95 (growing to fit) width",t.id,d,t.size?.width,g);for(let y of t.children)y.size&&(y.size.width=g)}}t.size={width:d,height:p,x:0,y:0}}X.debug("setBlockSizes abc94 (done)",t.id,t?.size?.x,t?.size?.width,t?.size?.y,t?.size?.height)}function Uve(t,e){X.debug(`abc85 layout blocks (=>layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`);let r=t.columns??-1;if(X.debug("layoutBlocks columns abc95",t.id,"=>",r,t),t.children&&t.children.length>0){let n=t?.children[0]?.size?.width??0,i=t.children.length*n+(t.children.length-1)*ki;X.debug("widthOfChildren 88",i,"posX");let a=0;X.debug("abc91 block?.size?.x",t.id,t?.size?.x);let s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-ki,l=0;for(let u of t.children){let h=t;if(!u.size)continue;let{width:f,height:d}=u.size,{px:p,py:m}=Frt(r,a);if(m!=l&&(l=m,s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-ki,X.debug("New row in layout for block",t.id," and child ",u.id,l)),X.debug(`abc89 layout blocks (child) id: ${u.id} Pos: ${a} (px, py) ${p},${m} (${h?.size?.x},${h?.size?.y}) parent: ${h.id} width: ${f}${ki}`),h.size){let g=f/2;u.size.x=s+ki+g,X.debug(`abc91 layout blocks (calc) px, pyid:${u.id} startingPos=X${s} new startingPosX${u.size.x} ${g} padding=${ki} width=${f} halfWidth=${g} => x:${u.size.x} y:${u.size.y} ${u.widthInColumns} (width * (child?.w || 1)) / 2 ${f*(u?.widthInColumns??1)/2}`),s=u.size.x+g,u.size.y=h.size.y-h.size.height/2+m*(d+ki)+d/2+ki,X.debug(`abc88 layout blocks (calc) px, pyid:${u.id}startingPosX${s}${ki}${g}=>x:${u.size.x}y:${u.size.y}${u.widthInColumns}(width * (child?.w || 1)) / 2${f*(u?.widthInColumns??1)/2}`)}u.children&&Uve(u,e),a+=u?.widthInColumns??1,X.debug("abc88 columnsPos",u,a)}}X.debug(`layout blocks (<==layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`)}function Hve(t,{minX:e,minY:r,maxX:n,maxY:i}={minX:0,minY:0,maxX:0,maxY:0}){if(t.size&&t.id!=="root"){let{x:a,y:s,width:l,height:u}=t.size;a-l/2n&&(n=a+l/2),s+u/2>i&&(i=s+u/2)}if(t.children)for(let a of t.children)({minX:e,minY:r,maxX:n,maxY:i}=Hve(a,{minX:e,minY:r,maxX:n,maxY:i}));return{minX:e,minY:r,maxX:n,maxY:i}}function Wve(t){let e=t.getBlock("root");if(!e)return;FF(e,t,0,0),Uve(e,t),X.debug("getBlocks",JSON.stringify(e,null,2));let{minX:r,minY:n,maxX:i,maxY:a}=Hve(e),s=a-n,l=i-r;return{x:r,y:n,width:l,height:s}}var ki,$rt,qve=N(()=>{"use strict";yt();Gt();ki=me()?.block?.padding??8;o(Frt,"calculateBlockPosition");$rt=o(t=>{let e=0,r=0;for(let n of t.children){let{width:i,height:a,x:s,y:l}=n.size??{width:0,height:0,x:0,y:0};X.debug("getMaxChildSize abc95 child:",n.id,"width:",i,"height:",a,"x:",s,"y:",l,n.type),n.type!=="space"&&(i>e&&(e=i/(t.widthInColumns??1)),a>r&&(r=a))}return{width:e,height:r}},"getMaxChildSize");o(FF,"setBlockSizes");o(Uve,"layoutBlocks");o(Hve,"findBounds");o(Wve,"layout")});function Yve(t,e){e&&t.attr("style",e)}function zrt(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label,i=t.isNode?"nodeLabel":"edgeLabel",a=r.append("span");return a.html(n),Yve(a,t.labelStyle),a.attr("class",i),Yve(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var Grt,ks,wC=N(()=>{"use strict";fr();yt();Gt();pr();er();ao();o(Yve,"applyStyle");o(zrt,"addHtmlLabel");Grt=o(async(t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),dr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"
    "),X.debug("vertexText"+i);let a=await dL(na(i)),s={isNode:n,label:a,labelStyle:e.replace("fill:","color:")};return zrt(s)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),ks=Grt});var jve,Vrt,Xve,Kve=N(()=>{"use strict";yt();jve=o((t,e,r,n,i)=>{e.arrowTypeStart&&Xve(t,"start",e.arrowTypeStart,r,n,i),e.arrowTypeEnd&&Xve(t,"end",e.arrowTypeEnd,r,n,i)},"addEdgeMarkers"),Vrt={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},Xve=o((t,e,r,n,i,a)=>{let s=Vrt[r];if(!s){X.warn(`Unknown arrow type: ${r}`);return}let l=e==="start"?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${a}-${s}${l})`)},"addEdgeMarker")});function kC(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}var $F,Xa,Zve,Jve,Urt,Hrt,Qve,e2e,t2e=N(()=>{"use strict";yt();wC();ao();fr();Gt();er();pr();PL();R2();Kve();$F={},Xa={},Zve=o(async(t,e)=>{let r=me(),n=dr(r.flowchart.htmlLabels),i=e.labelType==="markdown"?qn(t,e.label,{style:e.labelStyle,useHtmlLabels:n,addSvgBackground:!0},r):await ks(e.label,e.labelStyle),a=t.insert("g").attr("class","edgeLabel"),s=a.insert("g").attr("class","label");s.node().appendChild(i);let l=i.getBBox();if(n){let h=i.children[0],f=Ge(i);l=h.getBoundingClientRect(),f.attr("width",l.width),f.attr("height",l.height)}s.attr("transform","translate("+-l.width/2+", "+-l.height/2+")"),$F[e.id]=a,e.width=l.width,e.height=l.height;let u;if(e.startLabelLeft){let h=await ks(e.startLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].startLeft=f,kC(u,e.startLabelLeft)}if(e.startLabelRight){let h=await ks(e.startLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=f.node().appendChild(h),d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].startRight=f,kC(u,e.startLabelRight)}if(e.endLabelLeft){let h=await ks(e.endLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].endLeft=f,kC(u,e.endLabelLeft)}if(e.endLabelRight){let h=await ks(e.endLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Xa[e.id]||(Xa[e.id]={}),Xa[e.id].endRight=f,kC(u,e.endLabelRight)}return i},"insertEdgeLabel");o(kC,"setTerminalWidth");Jve=o((t,e)=>{X.debug("Moving label abc88 ",t.id,t.label,$F[t.id],e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Bu(n);if(t.label){let a=$F[t.id],s=t.x,l=t.y;if(r){let u=Vt.calcLabelPosition(r);X.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=Xa[t.id].startLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=Xa[t.id].startRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=Xa[t.id].endLeft,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=Xa[t.id].endRight,s=t.x,l=t.y;if(r){let u=Vt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),Urt=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),Hrt=o((t,e,r)=>{X.debug(`intersection calc abc89: - outsidePoint: ${JSON.stringify(e)} - insidePoint : ${JSON.stringify(r)} - node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.xMath.abs(n-e.x)*u){let d=r.y{X.debug("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(!Urt(e,a)&&!i){let s=Hrt(e,n,a),l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)||r.push(s),i=!0}else n=a,i||r.push(a)}),r},"cutPathAtIntersect"),e2e=o(function(t,e,r,n,i,a,s){let l=r.points;X.debug("abc88 InsertEdge: edge=",r,"e=",e);let u=!1,h=a.node(e.v);var f=a.node(e.w);f?.intersect&&h?.intersect&&(l=l.slice(1,r.points.length-1),l.unshift(h.intersect(l[0])),l.push(f.intersect(l[l.length-1]))),r.toCluster&&(X.debug("to cluster abc88",n[r.toCluster]),l=Qve(r.points,n[r.toCluster].node),u=!0),r.fromCluster&&(X.debug("from cluster abc88",n[r.fromCluster]),l=Qve(l.reverse(),n[r.fromCluster].node).reverse(),u=!0);let d=l.filter(S=>!Number.isNaN(S.y)),p=No;r.curve&&(i==="graph"||i==="flowchart")&&(p=r.curve);let{x:m,y:g}=ow(r),y=Cl().x(m).y(g).curve(p),v;switch(r.thickness){case"normal":v="edge-thickness-normal";break;case"thick":v="edge-thickness-thick";break;case"invisible":v="edge-thickness-thick";break;default:v=""}switch(r.pattern){case"solid":v+=" edge-pattern-solid";break;case"dotted":v+=" edge-pattern-dotted";break;case"dashed":v+=" edge-pattern-dashed";break}let x=t.append("path").attr("d",y(d)).attr("id",r.id).attr("class"," "+v+(r.classes?" "+r.classes:"")).attr("style",r.style),b="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(b=mu(!0)),jve(x,r,b,s,i);let T={};return u&&(T.updatedPath=l),T.originalPath=r.points,T},"insertEdge")});var Wrt,r2e,n2e=N(()=>{"use strict";Wrt=o(t=>{let e=new Set;for(let r of t)switch(r){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(r);break}return e},"expandAndDeduplicateDirections"),r2e=o((t,e,r)=>{let n=Wrt(t),i=2,a=e.height+2*r.padding,s=a/i,l=e.width+2*s+r.padding,u=r.padding/2;return n.has("right")&&n.has("left")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:s,y:0},{x:l/2,y:2*u},{x:l-s,y:0},{x:l,y:0},{x:l,y:-a/3},{x:l+2*u,y:-a/2},{x:l,y:-2*a/3},{x:l,y:-a},{x:l-s,y:-a},{x:l/2,y:-a-2*u},{x:s,y:-a},{x:0,y:-a},{x:0,y:-2*a/3},{x:-2*u,y:-a/2},{x:0,y:-a/3}]:n.has("right")&&n.has("left")&&n.has("up")?[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}]:n.has("right")&&n.has("left")&&n.has("down")?[{x:0,y:0},{x:s,y:-a},{x:l-s,y:-a},{x:l,y:0}]:n.has("right")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:l,y:-s},{x:l,y:-a+s},{x:0,y:-a}]:n.has("left")&&n.has("up")&&n.has("down")?[{x:l,y:0},{x:0,y:-s},{x:0,y:-a+s},{x:l,y:-a}]:n.has("right")&&n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")&&n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:n.has("right")&&n.has("up")?[{x:0,y:0},{x:l,y:-s},{x:0,y:-a}]:n.has("right")&&n.has("down")?[{x:0,y:0},{x:l,y:0},{x:0,y:-a}]:n.has("left")&&n.has("up")?[{x:l,y:0},{x:0,y:-s},{x:l,y:-a}]:n.has("left")&&n.has("down")?[{x:l,y:0},{x:0,y:0},{x:l,y:-a}]:n.has("right")?[{x:s,y:-u},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a+u}]:n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")?[{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u}]:n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:[{x:0,y:0}]},"getArrowPoints")});function qrt(t,e){return t.intersect(e)}var i2e,a2e=N(()=>{"use strict";o(qrt,"intersectNode");i2e=qrt});function Yrt(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x{"use strict";o(Yrt,"intersectEllipse");EC=Yrt});function Xrt(t,e,r){return EC(t,e,e,r)}var s2e,o2e=N(()=>{"use strict";zF();o(Xrt,"intersectCircle");s2e=Xrt});function jrt(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&l2e(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&l2e(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function l2e(t,e){return t*e>0}var c2e,u2e=N(()=>{"use strict";o(jrt,"intersectLine");o(l2e,"sameSign");c2e=jrt});function Krt(t,e,r){var n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(g){s=Math.min(s,g.x),l=Math.min(l,g.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var u=n-t.width/2-s,h=i-t.height/2-l,f=0;f1&&a.sort(function(g,y){var v=g.x-r.x,x=g.y-r.y,b=Math.sqrt(v*v+x*x),T=y.x-r.x,S=y.y-r.y,w=Math.sqrt(T*T+S*S);return b{"use strict";u2e();h2e=Krt;o(Krt,"intersectPolygon")});var Qrt,d2e,p2e=N(()=>{"use strict";Qrt=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),d2e=Qrt});var In,GF=N(()=>{"use strict";a2e();o2e();zF();f2e();p2e();In={node:i2e,circle:s2e,ellipse:EC,polygon:h2e,rect:d2e}});function Xl(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var Ni,Jn,VF=N(()=>{"use strict";wC();ao();Gt();fr();pr();er();Ni=o(async(t,e,r,n)=>{let i=me(),a,s=e.useHtmlLabels||dr(i.flowchart.htmlLabels);r?a=r:a="node default";let l=t.insert("g").attr("class",a).attr("id",e.domId||e.id),u=l.insert("g").attr("class","label").attr("style",e.labelStyle),h;e.labelText===void 0?h="":h=typeof e.labelText=="string"?e.labelText:e.labelText[0];let f=u.node(),d;e.labelType==="markdown"?d=qn(u,wr(na(h),i),{useHtmlLabels:s,width:e.width||i.flowchart.wrappingWidth,classes:"markdown-node-label"},i):d=f.appendChild(await ks(wr(na(h),i),e.labelStyle,!1,n));let p=d.getBBox(),m=e.padding/2;if(dr(i.flowchart.htmlLabels)){let g=d.children[0],y=Ge(d),v=g.getElementsByTagName("img");if(v){let x=h.replace(/]*>/g,"").trim()==="";await Promise.all([...v].map(b=>new Promise(T=>{function S(){if(b.style.display="flex",b.style.flexDirection="column",x){let w=i.fontSize?i.fontSize:window.getComputedStyle(document.body).fontSize,_=parseInt(w,10)*5+"px";b.style.minWidth=_,b.style.maxWidth=_}else b.style.width="100%";T(b)}o(S,"setupImage"),setTimeout(()=>{b.complete&&S()}),b.addEventListener("error",S),b.addEventListener("load",S)})))}p=g.getBoundingClientRect(),y.attr("width",p.width),y.attr("height",p.height)}return s?u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"):u.attr("transform","translate(0, "+-p.height/2+")"),e.centerLabel&&u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),u.insert("rect",":first-child"),{shapeSvg:l,bbox:p,halfPadding:m,label:u}},"labelHelper"),Jn=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds");o(Xl,"insertPolygonShape")});var Zrt,m2e,g2e=N(()=>{"use strict";VF();yt();Gt();GF();Zrt=o(async(t,e)=>{e.useHtmlLabels||me().flowchart.htmlLabels||(e.centerLabel=!0);let{shapeSvg:n,bbox:i,halfPadding:a}=await Ni(t,e,"node "+e.classes,!0);X.info("Classes = ",e.classes);let s=n.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-a).attr("y",-i.height/2-a).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Jn(e,s),e.intersect=function(l){return In.rect(e,l)},n},"note"),m2e=Zrt});function UF(t,e,r,n){let i=[],a=o(l=>{i.push(l,0)},"addBorder"),s=o(l=>{i.push(0,l)},"skipBorder");e.includes("t")?(X.debug("add top border"),a(r)):s(r),e.includes("r")?(X.debug("add right border"),a(n)):s(n),e.includes("b")?(X.debug("add bottom border"),a(r)):s(r),e.includes("l")?(X.debug("add left border"),a(n)):s(n),t.attr("stroke-dasharray",i.join(" "))}var y2e,bo,v2e,Jrt,ent,tnt,rnt,nnt,int,ant,snt,ont,lnt,cnt,unt,hnt,fnt,dnt,pnt,mnt,gnt,ynt,x2e,vnt,xnt,b2e,SC,HF,T2e,w2e=N(()=>{"use strict";fr();Gt();pr();yt();n2e();wC();GF();g2e();VF();y2e=o(t=>t?" "+t:"","formatClass"),bo=o((t,e)=>`${e||"node default"}${y2e(t.classes)} ${y2e(t.class)}`,"getClassesFromNode"),v2e=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=i+a,l=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];X.info("Question main (Circle)");let u=Xl(r,s,s,l);return u.attr("style",e.style),Jn(e,u),e.intersect=function(h){return X.warn("Intersect called"),In.polygon(e,l,h)},r},"question"),Jrt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=28,i=[{x:0,y:n/2},{x:n/2,y:0},{x:0,y:-n/2},{x:-n/2,y:0}];return r.insert("polygon",":first-child").attr("points",i.map(function(s){return s.x+","+s.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(s){return In.circle(e,14,s)},r},"choice"),ent=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=4,a=n.height+e.padding,s=a/i,l=n.width+2*s+e.padding,u=[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}],h=Xl(r,l,a,u);return h.attr("style",e.style),Jn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"hexagon"),tnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,void 0,!0),i=2,a=n.height+2*e.padding,s=a/i,l=n.width+2*s+e.padding,u=r2e(e.directions,n,e),h=Xl(r,l,a,u);return h.attr("style",e.style),Jn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"block_arrow"),rnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-a/2,y:0},{x:i,y:0},{x:i,y:-a},{x:-a/2,y:-a},{x:0,y:-a/2}];return Xl(r,i,a,s).attr("style",e.style),e.width=i+a,e.height=a,e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_left_inv_arrow"),nnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_right"),int=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:2*a/6,y:0},{x:i+a/6,y:0},{x:i-2*a/6,y:-a},{x:-a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_left"),ant=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i+2*a/6,y:0},{x:i-a/6,y:-a},{x:a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"trapezoid"),snt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:-2*a/6,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"inv_trapezoid"),ont=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i+a/2,y:0},{x:i,y:-a/2},{x:i+a/2,y:-a},{x:0,y:-a}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_right_inv_arrow"),lnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=i/2,s=a/(2.5+i/50),l=n.height+s+e.padding,u="M 0,"+s+" a "+a+","+s+" 0,0,0 "+i+" 0 a "+a+","+s+" 0,0,0 "+-i+" 0 l 0,"+l+" a "+a+","+s+" 0,0,0 "+i+" 0 l 0,"+-l,h=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",u).attr("transform","translate("+-i/2+","+-(l/2+s)+")");return Jn(e,h),e.intersect=function(f){let d=In.rect(e,f),p=d.x-e.x;if(a!=0&&(Math.abs(p)e.height/2-s)){let m=s*s*(1-p*p/(a*a));m!=0&&(m=Math.sqrt(m)),m=s-m,f.y-e.y>0&&(m=-m),d.y+=m}return d},r},"cylinder"),cnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,"node "+e.classes+" "+e.class,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(UF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{X.warn(`Unknown node property ${d}`)})}return Jn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"rect"),unt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,"node "+e.classes,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(UF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{X.warn(`Unknown node property ${d}`)})}return Jn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"composite"),hnt=o(async(t,e)=>{let{shapeSvg:r}=await Ni(t,e,"label",!0);X.trace("Classes = ",e.class);let n=r.insert("rect",":first-child"),i=0,a=0;if(n.attr("width",i).attr("height",a),r.attr("class","label edgeLabel"),e.props){let s=new Set(Object.keys(e.props));e.props.borders&&(UF(n,e.props.borders,i,a),s.delete("borders")),s.forEach(l=>{X.warn(`Unknown node property ${l}`)})}return Jn(e,n),e.intersect=function(s){return In.rect(e,s)},r},"labelRect");o(UF,"applyNodePropertyBorders");fnt=o(async(t,e)=>{let r;e.classes?r="node "+e.classes:r="node default";let n=t.insert("g").attr("class",r).attr("id",e.domId||e.id),i=n.insert("rect",":first-child"),a=n.insert("line"),s=n.insert("g").attr("class","label"),l=e.labelText.flat?e.labelText.flat():e.labelText,u="";typeof l=="object"?u=l[0]:u=l,X.info("Label text abc79",u,l,typeof l=="object");let h=s.node().appendChild(await ks(u,e.labelStyle,!0,!0)),f={width:0,height:0};if(dr(me().flowchart.htmlLabels)){let y=h.children[0],v=Ge(h);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}X.info("Text 2",l);let d=l.slice(1,l.length),p=h.getBBox(),m=s.node().appendChild(await ks(d.join?d.join("
    "):d,e.labelStyle,!0,!0));if(dr(me().flowchart.htmlLabels)){let y=m.children[0],v=Ge(m);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}let g=e.padding/2;return Ge(m).attr("transform","translate( "+(f.width>p.width?0:(p.width-f.width)/2)+", "+(p.height+g+5)+")"),Ge(h).attr("transform","translate( "+(f.width{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.height+e.padding,a=n.width+i/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",i/2).attr("ry",i/2).attr("x",-a/2).attr("y",-i/2).attr("width",a).attr("height",i);return Jn(e,s),e.intersect=function(l){return In.rect(e,l)},r},"stadium"),pnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,bo(e,void 0),!0),a=r.insert("circle",":first-child");return a.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),X.info("Circle main"),Jn(e,a),e.intersect=function(s){return X.info("Circle intersect",e,n.width/2+i,s),In.circle(e,n.width/2+i,s)},r},"circle"),mnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Ni(t,e,bo(e,void 0),!0),a=5,s=r.insert("g",":first-child"),l=s.insert("circle"),u=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+a).attr("width",n.width+e.padding+a*2).attr("height",n.height+e.padding+a*2),u.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),X.info("DoubleCircle main"),Jn(e,l),e.intersect=function(h){return X.info("DoubleCircle intersect",e,n.width/2+i+a,h),In.circle(e,n.width/2+i+a,h)},r},"doublecircle"),gnt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Ni(t,e,bo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i,y:0},{x:i,y:-a},{x:0,y:-a},{x:0,y:0},{x:-8,y:0},{x:i+8,y:0},{x:i+8,y:-a},{x:-8,y:-a},{x:-8,y:0}],l=Xl(r,i,a,s);return l.attr("style",e.style),Jn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"subroutine"),ynt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),Jn(e,n),e.intersect=function(i){return In.circle(e,7,i)},r},"start"),x2e=o((t,e,r)=>{let n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=70,a=10;r==="LR"&&(i=10,a=70);let s=n.append("rect").attr("x",-1*i/2).attr("y",-1*a/2).attr("width",i).attr("height",a).attr("class","fork-join");return Jn(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(l){return In.rect(e,l)},n},"forkJoin"),vnt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child"),i=r.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),n.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),Jn(e,i),e.intersect=function(a){return In.circle(e,7,a)},r},"end"),xnt=o(async(t,e)=>{let r=e.padding/2,n=4,i=8,a;e.classes?a="node "+e.classes:a="node default";let s=t.insert("g").attr("class",a).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),u=s.insert("line"),h=s.insert("line"),f=0,d=n,p=s.insert("g").attr("class","label"),m=0,g=e.classData.annotations?.[0],y=e.classData.annotations[0]?"\xAB"+e.classData.annotations[0]+"\xBB":"",v=p.node().appendChild(await ks(y,e.labelStyle,!0,!0)),x=v.getBBox();if(dr(me().flowchart.htmlLabels)){let C=v.children[0],D=Ge(v);x=C.getBoundingClientRect(),D.attr("width",x.width),D.attr("height",x.height)}e.classData.annotations[0]&&(d+=x.height+n,f+=x.width);let b=e.classData.label;e.classData.type!==void 0&&e.classData.type!==""&&(me().flowchart.htmlLabels?b+="<"+e.classData.type+">":b+="<"+e.classData.type+">");let T=p.node().appendChild(await ks(b,e.labelStyle,!0,!0));Ge(T).attr("class","classTitle");let S=T.getBBox();if(dr(me().flowchart.htmlLabels)){let C=T.children[0],D=Ge(T);S=C.getBoundingClientRect(),D.attr("width",S.width),D.attr("height",S.height)}d+=S.height+n,S.width>f&&(f=S.width);let w=[];e.classData.members.forEach(async C=>{let D=C.getDisplayDetails(),O=D.displayText;me().flowchart.htmlLabels&&(O=O.replace(//g,">"));let R=p.node().appendChild(await ks(O,D.cssStyle?D.cssStyle:e.labelStyle,!0,!0)),k=R.getBBox();if(dr(me().flowchart.htmlLabels)){let L=R.children[0],A=Ge(R);k=L.getBoundingClientRect(),A.attr("width",k.width),A.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,w.push(R)}),d+=i;let E=[];if(e.classData.methods.forEach(async C=>{let D=C.getDisplayDetails(),O=D.displayText;me().flowchart.htmlLabels&&(O=O.replace(//g,">"));let R=p.node().appendChild(await ks(O,D.cssStyle?D.cssStyle:e.labelStyle,!0,!0)),k=R.getBBox();if(dr(me().flowchart.htmlLabels)){let L=R.children[0],A=Ge(R);k=L.getBoundingClientRect(),A.attr("width",k.width),A.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,E.push(R)}),d+=i,g){let C=(f-x.width)/2;Ge(v).attr("transform","translate( "+(-1*f/2+C)+", "+-1*d/2+")"),m=x.height+n}let _=(f-S.width)/2;return Ge(T).attr("transform","translate( "+(-1*f/2+_)+", "+(-1*d/2+m)+")"),m+=S.height+n,u.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,w.forEach(C=>{Ge(C).attr("transform","translate( "+-f/2+", "+(-1*d/2+m+i/2)+")");let D=C?.getBBox();m+=(D?.height??0)+n}),m+=i,h.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,E.forEach(C=>{Ge(C).attr("transform","translate( "+-f/2+", "+(-1*d/2+m)+")");let D=C?.getBBox();m+=(D?.height??0)+n}),l.attr("style",e.style).attr("class","outer title-state").attr("x",-f/2-r).attr("y",-(d/2)-r).attr("width",f+e.padding).attr("height",d+e.padding),Jn(e,l),e.intersect=function(C){return In.rect(e,C)},s},"class_box"),b2e={rhombus:v2e,composite:unt,question:v2e,rect:cnt,labelRect:hnt,rectWithTitle:fnt,choice:Jrt,circle:pnt,doublecircle:mnt,stadium:dnt,hexagon:ent,block_arrow:tnt,rect_left_inv_arrow:rnt,lean_right:nnt,lean_left:int,trapezoid:ant,inv_trapezoid:snt,rect_right_inv_arrow:ont,cylinder:lnt,start:ynt,end:vnt,note:m2e,subroutine:gnt,fork:x2e,join:x2e,class_box:xnt},SC={},HF=o(async(t,e,r)=>{let n,i;if(e.link){let a;me().securityLevel==="sandbox"?a="_top":e.linkTarget&&(a=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",a),i=await b2e[e.shape](n,e,r)}else i=await b2e[e.shape](t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),SC[e.id]=n,e.haveCallback&&SC[e.id].attr("class",SC[e.id].attr("class")+" clickable"),n},"insertNode"),T2e=o(t=>{let e=SC[t.id];X.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});function k2e(t,e,r=!1){let n=t,i="default";(n?.classes?.length||0)>0&&(i=(n?.classes??[]).join(" ")),i=i+" flowchart-label";let a=0,s="",l;switch(n.type){case"round":a=5,s="rect";break;case"composite":a=0,s="composite",l=0;break;case"square":s="rect";break;case"diamond":s="question";break;case"hexagon":s="hexagon";break;case"block_arrow":s="block_arrow";break;case"odd":s="rect_left_inv_arrow";break;case"lean_right":s="lean_right";break;case"lean_left":s="lean_left";break;case"trapezoid":s="trapezoid";break;case"inv_trapezoid":s="inv_trapezoid";break;case"rect_left_inv_arrow":s="rect_left_inv_arrow";break;case"circle":s="circle";break;case"ellipse":s="ellipse";break;case"stadium":s="stadium";break;case"subroutine":s="subroutine";break;case"cylinder":s="cylinder";break;case"group":s="rect";break;case"doublecircle":s="doublecircle";break;default:s="rect"}let u=D9(n?.styles??[]),h=n.label,f=n.size??{width:0,height:0,x:0,y:0};return{labelStyle:u.labelStyle,shape:s,labelText:h,rx:a,ry:a,class:i,style:u.style,id:n.id,directions:n.directions,width:f.width,height:f.height,x:f.x,y:f.y,positioned:r,intersect:void 0,type:n.type,padding:l??tr()?.block?.padding??0}}async function bnt(t,e,r){let n=k2e(e,r,!1);if(n.type==="group")return;let i=tr(),a=await HF(t,n,{config:i}),s=a.node().getBBox(),l=r.getBlock(n.id);l.size={width:s.width,height:s.height,x:0,y:0,node:a},r.setBlock(l),a.remove()}async function Tnt(t,e,r){let n=k2e(e,r,!0);if(r.getBlock(n.id).type!=="space"){let a=tr();await HF(t,n,{config:a}),e.intersect=n?.intersect,T2e(n)}}async function WF(t,e,r,n){for(let i of e)await n(t,i,r),i.children&&await WF(t,i.children,r,n)}async function E2e(t,e,r){await WF(t,e,r,bnt)}async function S2e(t,e,r){await WF(t,e,r,Tnt)}async function C2e(t,e,r,n,i){let a=new sn({multigraph:!0,compound:!0});a.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(let s of r)s.size&&a.setNode(s.id,{width:s.size.width,height:s.size.height,intersect:s.intersect});for(let s of e)if(s.start&&s.end){let l=n.getBlock(s.start),u=n.getBlock(s.end);if(l?.size&&u?.size){let h=l.size,f=u.size,d=[{x:h.x,y:h.y},{x:h.x+(f.x-h.x)/2,y:h.y+(f.y-h.y)/2},{x:f.x,y:f.y}];e2e(t,{v:s.start,w:s.end,name:s.id},{...s,arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",a,i),s.label&&(await Zve(t,{...s,label:s.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),Jve({...s,x:d[1].x,y:d[1].y},{originalPath:d}))}}}var A2e=N(()=>{"use strict";Wo();mi();t2e();w2e();er();o(k2e,"getNodeFromBlock");o(bnt,"calculateBlockSize");o(Tnt,"insertBlockPositioned");o(WF,"performOperations");o(E2e,"calculateBlockSizes");o(S2e,"insertBlocks");o(C2e,"insertEdges")});var wnt,knt,_2e,D2e=N(()=>{"use strict";fr();mi();Vve();yt();xi();qve();A2e();wnt=o(function(t,e){return e.db.getClasses()},"getClasses"),knt=o(async function(t,e,r,n){let{securityLevel:i,block:a}=tr(),s=n.db,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`);Gve(h,["point","circle","cross"],n.type,e);let d=s.getBlocks(),p=s.getBlocksFlat(),m=s.getEdges(),g=h.insert("g").attr("class","block");await E2e(g,d,s);let y=Wve(s);if(await S2e(g,d,s),await C2e(g,m,p,s,e),y){let v=y,x=Math.max(1,Math.round(.125*(v.width/v.height))),b=v.height+x+10,T=v.width+10,{useMaxWidth:S}=a;fn(h,b,T,!!S),X.debug("Here Bounds",y,v),h.attr("viewBox",`${v.x-5} ${v.y-5} ${v.width+10} ${v.height+10}`)}},"draw"),_2e={draw:knt,getClasses:wnt}});var L2e={};ur(L2e,{diagram:()=>Ent});var Ent,R2e=N(()=>{"use strict";Rve();Fve();zve();D2e();Ent={parser:Lve,db:Bve,renderer:_2e,styles:$ve}});var qF,YF,D4,I2e,XF,ja,ru,L4,O2e,_nt,R4,P2e,B2e,F2e,$2e,z2e,CC,Yf,AC=N(()=>{"use strict";qF={L:"left",R:"right",T:"top",B:"bottom"},YF={L:o(t=>`${t},${t/2} 0,${t} 0,0`,"L"),R:o(t=>`0,${t/2} ${t},0 ${t},${t}`,"R"),T:o(t=>`0,0 ${t},0 ${t/2},${t}`,"T"),B:o(t=>`${t/2},0 ${t},${t} 0,${t}`,"B")},D4={L:o((t,e)=>t-e+2,"L"),R:o((t,e)=>t-2,"R"),T:o((t,e)=>t-e+2,"T"),B:o((t,e)=>t-2,"B")},I2e=o(function(t){return ja(t)?t==="L"?"R":"L":t==="T"?"B":"T"},"getOppositeArchitectureDirection"),XF=o(function(t){let e=t;return e==="L"||e==="R"||e==="T"||e==="B"},"isArchitectureDirection"),ja=o(function(t){let e=t;return e==="L"||e==="R"},"isArchitectureDirectionX"),ru=o(function(t){let e=t;return e==="T"||e==="B"},"isArchitectureDirectionY"),L4=o(function(t,e){let r=ja(t)&&ru(e),n=ru(t)&&ja(e);return r||n},"isArchitectureDirectionXY"),O2e=o(function(t){let e=t[0],r=t[1],n=ja(e)&&ru(r),i=ru(e)&&ja(r);return n||i},"isArchitecturePairXY"),_nt=o(function(t){return t!=="LL"&&t!=="RR"&&t!=="TT"&&t!=="BB"},"isValidArchitectureDirectionPair"),R4=o(function(t,e){let r=`${t}${e}`;return _nt(r)?r:void 0},"getArchitectureDirectionPair"),P2e=o(function([t,e],r){let n=r[0],i=r[1];return ja(n)?ru(i)?[t+(n==="L"?-1:1),e+(i==="T"?1:-1)]:[t+(n==="L"?-1:1),e]:ja(i)?[t+(i==="L"?1:-1),e+(n==="T"?1:-1)]:[t,e+(n==="T"?1:-1)]},"shiftPositionByArchitectureDirectionPair"),B2e=o(function(t){return t==="LT"||t==="TL"?[1,1]:t==="BL"||t==="LB"?[1,-1]:t==="BR"||t==="RB"?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),F2e=o(function(t,e){return L4(t,e)?"bend":ja(t)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),$2e=o(function(t){return t.type==="service"},"isArchitectureService"),z2e=o(function(t){return t.type==="junction"},"isArchitectureJunction"),CC=o(t=>t.data(),"edgeData"),Yf=o(t=>t.data(),"nodeData")});function Mi(t){return V2e()[t]}var G2e,vr,Dnt,Lnt,Rnt,Nnt,Mnt,Int,jF,Ont,Pnt,Bnt,Fnt,$nt,znt,Gnt,V2e,o0,N4=N(()=>{"use strict";_a();mi();SS();ci();AC();er();G2e=or.architecture,vr=new Tf(()=>({nodes:{},groups:{},edges:[],registeredIds:{},config:G2e,dataStructures:void 0,elements:{}})),Dnt=o(()=>{vr.reset(),kr()},"clear"),Lnt=o(function({id:t,icon:e,in:r,title:n,iconText:i}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The service id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The service [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The service [${t}]'s parent does not exist. Please make sure the parent is created before this service`);if(vr.records.registeredIds[r]==="node")throw new Error(`The service [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"service",icon:e,iconText:i,title:n,edges:[],in:r}},"addService"),Rnt=o(()=>Object.values(vr.records.nodes).filter($2e),"getServices"),Nnt=o(function({id:t,in:e}){vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"junction",edges:[],in:e}},"addJunction"),Mnt=o(()=>Object.values(vr.records.nodes).filter(z2e),"getJunctions"),Int=o(()=>Object.values(vr.records.nodes),"getNodes"),jF=o(t=>vr.records.nodes[t],"getNode"),Ont=o(function({id:t,icon:e,in:r,title:n}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The group id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The group [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The group [${t}]'s parent does not exist. Please make sure the parent is created before this group`);if(vr.records.registeredIds[r]==="node")throw new Error(`The group [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="group",vr.records.groups[t]={id:t,icon:e,title:n,in:r}},"addGroup"),Pnt=o(()=>Object.values(vr.records.groups),"getGroups"),Bnt=o(function({lhsId:t,rhsId:e,lhsDir:r,rhsDir:n,lhsInto:i,rhsInto:a,lhsGroup:s,rhsGroup:l,title:u}){if(!XF(r))throw new Error(`Invalid direction given for left hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${r}`);if(!XF(n))throw new Error(`Invalid direction given for right hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${n}`);if(vr.records.nodes[t]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The left-hand id [${t}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(vr.records.nodes[e]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The right-hand id [${e}] does not yet exist. Please create the service/group before declaring an edge to it.`);let h=vr.records.nodes[t].in,f=vr.records.nodes[e].in;if(s&&h&&f&&h==f)throw new Error(`The left-hand id [${t}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(l&&h&&f&&h==f)throw new Error(`The right-hand id [${e}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);let d={lhsId:t,lhsDir:r,lhsInto:i,lhsGroup:s,rhsId:e,rhsDir:n,rhsInto:a,rhsGroup:l,title:u};vr.records.edges.push(d),vr.records.nodes[t]&&vr.records.nodes[e]&&(vr.records.nodes[t].edges.push(vr.records.edges[vr.records.edges.length-1]),vr.records.nodes[e].edges.push(vr.records.edges[vr.records.edges.length-1]))},"addEdge"),Fnt=o(()=>vr.records.edges,"getEdges"),$nt=o(()=>{if(vr.records.dataStructures===void 0){let t={},e=Object.entries(vr.records.nodes).reduce((l,[u,h])=>(l[u]=h.edges.reduce((f,d)=>{let p=jF(d.lhsId)?.in,m=jF(d.rhsId)?.in;if(p&&m&&p!==m){let g=F2e(d.lhsDir,d.rhsDir);g!=="bend"&&(t[p]??={},t[p][m]=g,t[m]??={},t[m][p]=g)}if(d.lhsId===u){let g=R4(d.lhsDir,d.rhsDir);g&&(f[g]=d.rhsId)}else{let g=R4(d.rhsDir,d.lhsDir);g&&(f[g]=d.lhsId)}return f},{}),l),{}),r=Object.keys(e)[0],n={[r]:1},i=Object.keys(e).reduce((l,u)=>u===r?l:{...l,[u]:1},{}),a=o(l=>{let u={[l]:[0,0]},h=[l];for(;h.length>0;){let f=h.shift();if(f){n[f]=1,delete i[f];let d=e[f],[p,m]=u[f];Object.entries(d).forEach(([g,y])=>{n[y]||(u[y]=P2e([p,m],g),h.push(y))})}}return u},"BFS"),s=[a(r)];for(;Object.keys(i).length>0;)s.push(a(Object.keys(i)[0]));vr.records.dataStructures={adjList:e,spatialMaps:s,groupAlignments:t}}return vr.records.dataStructures},"getDataStructures"),znt=o((t,e)=>{vr.records.elements[t]=e},"setElementForId"),Gnt=o(t=>vr.records.elements[t],"getElementById"),V2e=o(()=>$n({...G2e,...tr().architecture}),"getConfig"),o0={clear:Dnt,setDiagramTitle:Or,getDiagramTitle:Nr,setAccTitle:Ar,getAccTitle:Dr,setAccDescription:Lr,getAccDescription:Rr,getConfig:V2e,addService:Lnt,getServices:Rnt,addJunction:Nnt,getJunctions:Mnt,getNodes:Int,getNode:jF,addGroup:Ont,getGroups:Pnt,addEdge:Bnt,getEdges:Fnt,setElementForId:znt,getElementById:Gnt,getDataStructures:$nt};o(Mi,"getConfigField")});var Vnt,U2e,H2e=N(()=>{"use strict";bf();yt();Mp();N4();Vnt=o((t,e)=>{Jo(t,e),t.groups.map(e.addGroup),t.services.map(r=>e.addService({...r,type:"service"})),t.junctions.map(r=>e.addJunction({...r,type:"junction"})),t.edges.map(e.addEdge)},"populateDb"),U2e={parse:o(async t=>{let e=await vs("architecture",t);X.debug(e),Vnt(e,o0)},"parse")}});var Unt,W2e,q2e=N(()=>{"use strict";Unt=o(t=>` - .edge { - stroke-width: ${t.archEdgeWidth}; - stroke: ${t.archEdgeColor}; - fill: none; - } - - .arrow { - fill: ${t.archEdgeArrowColor}; - } - - .node-bkg { - fill: none; - stroke: ${t.archGroupBorderColor}; - stroke-width: ${t.archGroupBorderWidth}; - stroke-dasharray: 8; - } - .node-icon-text { - display: flex; - align-items: center; - } - - .node-icon-text > div { - color: #fff; - margin: 1px; - height: fit-content; - text-align: center; - overflow: hidden; - display: -webkit-box; - -webkit-box-orient: vertical; - } -`,"getStyles"),W2e=Unt});var QF=Pi((M4,KF)=>{"use strict";o(function(e,r){typeof M4=="object"&&typeof KF=="object"?KF.exports=r():typeof define=="function"&&define.amd?define([],r):typeof M4=="object"?M4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(M4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=28)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(5);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;yp?(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)):this.labelPosHorizontal=="right"&&this.setWidth(p+this.labelWidth)),this.labelHeight&&(this.labelPosVertical=="top"?(this.rect.y-=this.labelHeight,this.setHeight(m+this.labelHeight)):this.labelPosVertical=="center"&&this.labelHeight>m?(this.rect.y-=(this.labelHeight-m)/2,this.setHeight(this.labelHeight)):this.labelPosVertical=="bottom"&&this.setHeight(m+this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";var n=r(0);function i(){}o(i,"FDLayoutConstants");for(var a in n)i[a]=n[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=i.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=i},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(7),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,T=0;T-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(w,1),x.target!=x.source&&x.target.edges.splice(E,1);var S=x.source.owner.getEdges().indexOf(x);if(S==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(S,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,T=this.getNodes(),S=T.length,w=0;wv&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(T[0].getParent().paddingLeft!=null?b=T[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,T,S,w,E,_,C=this.nodes,D=C.length,O=0;OT&&(y=T),vw&&(x=w),bT&&(y=T),vw&&(x=w),b=this.nodes.length){var D=0;v.forEach(function(O){O.owner==g&&D++}),D==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(6),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]d)return l[0]=u,l[1]=m,l[2]=f,l[3]=C,!1;if(hf)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(uf?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):A===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-I===M?f>u?(l[2]=_,l[3]=C,L=!0):(l[2]=E,l[3]=w,L=!0):I===M&&(f>u?(l[2]=S,l[3]=w,L=!0):(l[2]=D,l[3]=C,L=!0)),k&&L)return!1;if(u>f?h>d?(P=this.getCardinalDirection(A,M,4),B=this.getCardinalDirection(I,M,2)):(P=this.getCardinalDirection(-A,M,3),B=this.getCardinalDirection(-I,M,1)):h>d?(P=this.getCardinalDirection(-A,M,1),B=this.getCardinalDirection(-I,M,3)):(P=this.getCardinalDirection(A,M,2),B=this.getCardinalDirection(I,M,4)),!k)switch(P){case 1:z=m,F=u+-T/M,l[0]=F,l[1]=z;break;case 2:F=x,z=h+b*M,l[0]=F,l[1]=z;break;case 3:z=v,F=u+T/M,l[0]=F,l[1]=z;break;case 4:F=y,z=h+-b*M,l[0]=F,l[1]=z;break}if(!L)switch(B){case 1:U=w,$=f+-R/M,l[2]=$,l[3]=U;break;case 2:$=D,U=d+O*M,l[2]=$,l[3]=U;break;case 3:U=C,$=f+R/M,l[2]=$,l[3]=U;break;case 4:$=_,U=d+-O*M,l[2]=$,l[3]=U;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,T=void 0,S=void 0,w=void 0,E=void 0,_=void 0,C=void 0,D=void 0;return T=p-f,w=h-d,_=d*f-h*p,S=v-g,E=m-y,C=y*g-m*v,D=T*E-S*w,D===0?null:(x=(w*C-E*_)/D,b=(S*_-T*C)/D,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l=0){var v=(-m+Math.sqrt(m*m-4*p*g))/(2*p),x=(-m-Math.sqrt(m*m-4*p*g))/(2*p),b=null;return v>=0&&v<=1?[v]:x>=0&&x<=1?[x]:b}else return null},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,t.exports=i},function(t,e,r){"use strict";function n(){}o(n,"IMath"),n.sign=function(i){return i>0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g0&&g;){for(T.push(w[0]);T.length>0&&g;){var E=T[0];T.splice(0,1),b.add(E);for(var _=E.getEdges(),x=0;x<_.length;x++){var C=_[x].getOtherEnd(E);if(S.get(E)!=C)if(!b.has(C))T.push(C),S.set(C,E);else{g=!1;break}}}if(!g)m=[];else{var D=[].concat(n(b));m.push(D);for(var x=0;x-1&&w.splice(R,1)}b=new Set,S=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x0){for(var v=this.edgeToDummyNodes.get(y),x=0;x=0&&g.splice(C,1);var D=S.getNeighborsList();D.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),A=L-1;A==1&&E.push(k),v.set(k,A)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(5);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);pa.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.displacementThresholdPerNode=3*a.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;mT||b>T)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(T=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>T||b>T)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement=x.length||T>=x[0].length)){for(var S=0;Sh},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";function n(){}o(n,"SVD"),n.svd=function(i){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=i.length,this.n=i[0].length;var a=Math.min(this.m,this.n);this.s=function(bt){for(var ut=[];bt-- >0;)ut.push(0);return ut}(Math.min(this.m+1,this.n)),this.U=function(bt){var ut=o(function St(ft){if(ft.length==0)return 0;for(var vt=[],nt=0;nt0;)ut.push(0);return ut}(this.n),l=function(bt){for(var ut=[];bt-- >0;)ut.push(0);return ut}(this.m),u=!0,h=!0,f=Math.min(this.m-1,this.n),d=Math.max(0,Math.min(this.n-2,this.m)),p=0;p=0;M--)if(this.s[M]!==0){for(var P=M+1;P=0;ee--){if(function(bt,ut){return bt&&ut}(ee0;){var le=void 0,J=void 0;for(le=L-2;le>=-1&&le!==-1;le--)if(Math.abs(s[le])<=he+te*(Math.abs(this.s[le])+Math.abs(this.s[le+1]))){s[le]=0;break}if(le===L-2)J=4;else{var Se=void 0;for(Se=L-1;Se>=le&&Se!==le;Se--){var se=(Se!==L?Math.abs(s[Se]):0)+(Se!==le+1?Math.abs(s[Se-1]):0);if(Math.abs(this.s[Se])<=he+te*se){this.s[Se]=0;break}}Se===le?J=3:Se===L-1?J=1:(J=2,le=Se)}switch(le++,J){case 1:{var ae=s[L-2];s[L-2]=0;for(var Oe=L-2;Oe>=le;Oe--){var ye=n.hypot(this.s[Oe],ae),Be=this.s[Oe]/ye,He=ae/ye;if(this.s[Oe]=ye,Oe!==le&&(ae=-He*s[Oe-1],s[Oe-1]=Be*s[Oe-1]),h)for(var ze=0;ze=this.s[le+1]);){var ot=this.s[le];if(this.s[le]=this.s[le+1],this.s[le+1]=ot,h&&leMath.abs(a)?(s=a/i,s=Math.abs(i)*Math.sqrt(1+s*s)):a!=0?(s=i/a,s=Math.abs(a)*Math.sqrt(1+s*s)):s=0,s},t.exports=n},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l{"use strict";o(function(e,r){typeof I4=="object"&&typeof ZF=="object"?ZF.exports=r(QF()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof I4=="object"?I4.coseBase=r(QF()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(I4,function(t){return(()=>{"use strict";var e={45:(a,s,l)=>{var u={};u.layoutBase=l(551),u.CoSEConstants=l(806),u.CoSEEdge=l(767),u.CoSEGraph=l(880),u.CoSEGraphManager=l(578),u.CoSELayout=l(765),u.CoSENode=l(991),u.ConstraintHandler=l(902),a.exports=u},806:(a,s,l)=>{var u=l(551).FDLayoutConstants;function h(){}o(h,"CoSEConstants");for(var f in u)h[f]=u[f];h.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,h.DEFAULT_RADIAL_SEPARATION=u.DEFAULT_EDGE_LENGTH,h.DEFAULT_COMPONENT_SEPERATION=60,h.TILE=!0,h.TILING_PADDING_VERTICAL=10,h.TILING_PADDING_HORIZONTAL=10,h.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,h.ENFORCE_CONSTRAINTS=!0,h.APPLY_LAYOUT=!0,h.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,h.TREE_REDUCTION_ON_INCREMENTAL=!0,h.PURE_INCREMENTAL=h.DEFAULT_INCREMENTAL,a.exports=h},767:(a,s,l)=>{var u=l(551).FDLayoutEdge;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEEdge"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},880:(a,s,l)=>{var u=l(551).LGraph;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEGraph"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},578:(a,s,l)=>{var u=l(551).LGraphManager;function h(d){u.call(this,d)}o(h,"CoSEGraphManager"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},765:(a,s,l)=>{var u=l(551).FDLayout,h=l(578),f=l(880),d=l(991),p=l(767),m=l(806),g=l(902),y=l(551).FDLayoutConstants,v=l(551).LayoutConstants,x=l(551).Point,b=l(551).PointD,T=l(551).DimensionD,S=l(551).Layout,w=l(551).Integer,E=l(551).IGeometry,_=l(551).LGraph,C=l(551).Transform,D=l(551).LinkedList;function O(){u.call(this),this.toBeTiled={},this.constraints={}}o(O,"CoSELayout"),O.prototype=Object.create(u.prototype);for(var R in u)O[R]=u[R];O.prototype.newGraphManager=function(){var k=new h(this);return this.graphManager=k,k},O.prototype.newGraph=function(k){return new f(null,this.graphManager,k)},O.prototype.newNode=function(k){return new d(this.graphManager,k)},O.prototype.newEdge=function(k){return new p(null,null,k)},O.prototype.initParameters=function(){u.prototype.initParameters.call(this,arguments),this.isSubLayout||(m.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=m.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=m.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=y.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=y.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=y.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},O.prototype.initSpringEmbedder=function(){u.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/y.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},O.prototype.layout=function(){var k=v.DEFAULT_CREATE_BENDS_AS_NEEDED;return k&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},O.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(m.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(P){return L.has(P)});this.graphManager.setAllNodesToApplyGravitation(A)}}else{var k=this.getFlatForest();if(k.length>0)this.positionNodesRadially(k);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(I){return L.has(I)});this.graphManager.setAllNodesToApplyGravitation(A),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(g.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),m.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},O.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%y.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var k=new Set(this.getAllNodes()),L=this.nodesWithGravity.filter(function(M){return k.has(M)});this.graphManager.setAllNodesToApplyGravitation(L),this.graphManager.updateBounds(),this.updateGrid(),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var A=!this.isTreeGrowing&&!this.isGrowthFinished,I=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(A,I),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},O.prototype.getPositionsData=function(){for(var k=this.graphManager.getAllNodes(),L={},A=0;A0&&this.updateDisplacements();for(var A=0;A0&&(I.fixedNodeWeight=P)}}if(this.constraints.relativePlacementConstraint){var B=new Map,F=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(Z){k.fixedNodesOnHorizontal.add(Z),k.fixedNodesOnVertical.add(Z)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var z=this.constraints.alignmentConstraint.vertical,A=0;A=2*Z.length/3;j--)ue=Math.floor(Math.random()*(j+1)),Q=Z[j],Z[j]=Z[ue],Z[ue]=Q;return Z},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(Z){if(Z.left){var ue=B.has(Z.left)?B.get(Z.left):Z.left,Q=B.has(Z.right)?B.get(Z.right):Z.right;k.nodesInRelativeHorizontal.includes(ue)||(k.nodesInRelativeHorizontal.push(ue),k.nodeToRelativeConstraintMapHorizontal.set(ue,[]),k.dummyToNodeForVerticalAlignment.has(ue)?k.nodeToTempPositionMapHorizontal.set(ue,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(ue)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(ue,k.idToNodeMap.get(ue).getCenterX())),k.nodesInRelativeHorizontal.includes(Q)||(k.nodesInRelativeHorizontal.push(Q),k.nodeToRelativeConstraintMapHorizontal.set(Q,[]),k.dummyToNodeForVerticalAlignment.has(Q)?k.nodeToTempPositionMapHorizontal.set(Q,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(Q)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(Q,k.idToNodeMap.get(Q).getCenterX())),k.nodeToRelativeConstraintMapHorizontal.get(ue).push({right:Q,gap:Z.gap}),k.nodeToRelativeConstraintMapHorizontal.get(Q).push({left:ue,gap:Z.gap})}else{var j=F.has(Z.top)?F.get(Z.top):Z.top,ne=F.has(Z.bottom)?F.get(Z.bottom):Z.bottom;k.nodesInRelativeVertical.includes(j)||(k.nodesInRelativeVertical.push(j),k.nodeToRelativeConstraintMapVertical.set(j,[]),k.dummyToNodeForHorizontalAlignment.has(j)?k.nodeToTempPositionMapVertical.set(j,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(j)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(j,k.idToNodeMap.get(j).getCenterY())),k.nodesInRelativeVertical.includes(ne)||(k.nodesInRelativeVertical.push(ne),k.nodeToRelativeConstraintMapVertical.set(ne,[]),k.dummyToNodeForHorizontalAlignment.has(ne)?k.nodeToTempPositionMapVertical.set(ne,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(ne)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(ne,k.idToNodeMap.get(ne).getCenterY())),k.nodeToRelativeConstraintMapVertical.get(j).push({bottom:ne,gap:Z.gap}),k.nodeToRelativeConstraintMapVertical.get(ne).push({top:j,gap:Z.gap})}});else{var U=new Map,K=new Map;this.constraints.relativePlacementConstraint.forEach(function(Z){if(Z.left){var ue=B.has(Z.left)?B.get(Z.left):Z.left,Q=B.has(Z.right)?B.get(Z.right):Z.right;U.has(ue)?U.get(ue).push(Q):U.set(ue,[Q]),U.has(Q)?U.get(Q).push(ue):U.set(Q,[ue])}else{var j=F.has(Z.top)?F.get(Z.top):Z.top,ne=F.has(Z.bottom)?F.get(Z.bottom):Z.bottom;K.has(j)?K.get(j).push(ne):K.set(j,[ne]),K.has(ne)?K.get(ne).push(j):K.set(ne,[j])}});var ee=o(function(ue,Q){var j=[],ne=[],te=new D,he=new Set,le=0;return ue.forEach(function(J,Se){if(!he.has(Se)){j[le]=[],ne[le]=!1;var se=Se;for(te.push(se),he.add(se),j[le].push(se);te.length!=0;){se=te.shift(),Q.has(se)&&(ne[le]=!0);var ae=ue.get(se);ae.forEach(function(Oe){he.has(Oe)||(te.push(Oe),he.add(Oe),j[le].push(Oe))})}le++}}),{components:j,isFixed:ne}},"constructComponents"),Y=ee(U,k.fixedNodesOnHorizontal);this.componentsOnHorizontal=Y.components,this.fixedComponentsOnHorizontal=Y.isFixed;var ce=ee(K,k.fixedNodesOnVertical);this.componentsOnVertical=ce.components,this.fixedComponentsOnVertical=ce.isFixed}}},O.prototype.updateDisplacements=function(){var k=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function(ce){var Z=k.idToNodeMap.get(ce.nodeId);Z.displacementX=0,Z.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var L=this.constraints.alignmentConstraint.vertical,A=0;A1){var F;for(F=0;FI&&(I=Math.floor(B.y)),P=Math.floor(B.x+m.DEFAULT_COMPONENT_SEPERATION)}this.transform(new b(v.WORLD_CENTER_X-B.x/2,v.WORLD_CENTER_Y-B.y/2))},O.radialLayout=function(k,L,A){var I=Math.max(this.maxDiagonalInTree(k),m.DEFAULT_RADIAL_SEPARATION);O.branchRadialLayout(L,null,0,359,0,I);var M=_.calculateBounds(k),P=new C;P.setDeviceOrgX(M.getMinX()),P.setDeviceOrgY(M.getMinY()),P.setWorldOrgX(A.x),P.setWorldOrgY(A.y);for(var B=0;B1;){var j=Q[0];Q.splice(0,1);var ne=ee.indexOf(j);ne>=0&&ee.splice(ne,1),Z--,Y--}L!=null?ue=(ee.indexOf(Q[0])+1)%Z:ue=0;for(var te=Math.abs(I-A)/Y,he=ue;ce!=Y;he=++he%Z){var le=ee[he].getOtherEnd(k);if(le!=L){var J=(A+ce*te)%360,Se=(J+te)%360;O.branchRadialLayout(le,k,J,Se,M+P,P),ce++}}},O.maxDiagonalInTree=function(k){for(var L=w.MIN_VALUE,A=0;AL&&(L=M)}return L},O.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},O.prototype.groupZeroDegreeMembers=function(){var k=this,L={};this.memberGroups={},this.idToDummyNode={};for(var A=[],I=this.graphManager.getAllNodes(),M=0;M"u"&&(L[F]=[]),L[F]=L[F].concat(P)}Object.keys(L).forEach(function(z){if(L[z].length>1){var $="DummyCompound_"+z;k.memberGroups[$]=L[z];var U=L[z][0].getParent(),K=new d(k.graphManager);K.id=$,K.paddingLeft=U.paddingLeft||0,K.paddingRight=U.paddingRight||0,K.paddingBottom=U.paddingBottom||0,K.paddingTop=U.paddingTop||0,k.idToDummyNode[$]=K;var ee=k.getGraphManager().add(k.newGraph(),K),Y=U.getChild();Y.add(K);for(var ce=0;ceM?(I.rect.x-=(I.labelWidth-M)/2,I.setWidth(I.labelWidth),I.labelMarginLeft=(I.labelWidth-M)/2):I.labelPosHorizontal=="right"&&I.setWidth(M+I.labelWidth)),I.labelHeight&&(I.labelPosVertical=="top"?(I.rect.y-=I.labelHeight,I.setHeight(P+I.labelHeight),I.labelMarginTop=I.labelHeight):I.labelPosVertical=="center"&&I.labelHeight>P?(I.rect.y-=(I.labelHeight-P)/2,I.setHeight(I.labelHeight),I.labelMarginTop=(I.labelHeight-P)/2):I.labelPosVertical=="bottom"&&I.setHeight(P+I.labelHeight))}})},O.prototype.repopulateCompounds=function(){for(var k=this.compoundOrder.length-1;k>=0;k--){var L=this.compoundOrder[k],A=L.id,I=L.paddingLeft,M=L.paddingTop,P=L.labelMarginLeft,B=L.labelMarginTop;this.adjustLocations(this.tiledMemberPack[A],L.rect.x,L.rect.y,I,M,P,B)}},O.prototype.repopulateZeroDegreeMembers=function(){var k=this,L=this.tiledZeroDegreePack;Object.keys(L).forEach(function(A){var I=k.idToDummyNode[A],M=I.paddingLeft,P=I.paddingTop,B=I.labelMarginLeft,F=I.labelMarginTop;k.adjustLocations(L[A],I.rect.x,I.rect.y,M,P,B,F)})},O.prototype.getToBeTiled=function(k){var L=k.id;if(this.toBeTiled[L]!=null)return this.toBeTiled[L];var A=k.getChild();if(A==null)return this.toBeTiled[L]=!1,!1;for(var I=A.getNodes(),M=0;M0)return this.toBeTiled[L]=!1,!1;if(P.getChild()==null){this.toBeTiled[P.id]=!1;continue}if(!this.getToBeTiled(P))return this.toBeTiled[L]=!1,!1}return this.toBeTiled[L]=!0,!0},O.prototype.getNodeDegree=function(k){for(var L=k.id,A=k.getEdges(),I=0,M=0;MU&&(U=ee.rect.height)}A+=U+k.verticalPadding}},O.prototype.tileCompoundMembers=function(k,L){var A=this;this.tiledMemberPack=[],Object.keys(k).forEach(function(I){var M=L[I];if(A.tiledMemberPack[I]=A.tileNodes(k[I],M.paddingLeft+M.paddingRight),M.rect.width=A.tiledMemberPack[I].width,M.rect.height=A.tiledMemberPack[I].height,M.setCenter(A.tiledMemberPack[I].centerX,A.tiledMemberPack[I].centerY),M.labelMarginLeft=0,M.labelMarginTop=0,m.NODE_DIMENSIONS_INCLUDE_LABELS){var P=M.rect.width,B=M.rect.height;M.labelWidth&&(M.labelPosHorizontal=="left"?(M.rect.x-=M.labelWidth,M.setWidth(P+M.labelWidth),M.labelMarginLeft=M.labelWidth):M.labelPosHorizontal=="center"&&M.labelWidth>P?(M.rect.x-=(M.labelWidth-P)/2,M.setWidth(M.labelWidth),M.labelMarginLeft=(M.labelWidth-P)/2):M.labelPosHorizontal=="right"&&M.setWidth(P+M.labelWidth)),M.labelHeight&&(M.labelPosVertical=="top"?(M.rect.y-=M.labelHeight,M.setHeight(B+M.labelHeight),M.labelMarginTop=M.labelHeight):M.labelPosVertical=="center"&&M.labelHeight>B?(M.rect.y-=(M.labelHeight-B)/2,M.setHeight(M.labelHeight),M.labelMarginTop=(M.labelHeight-B)/2):M.labelPosVertical=="bottom"&&M.setHeight(B+M.labelHeight))}})},O.prototype.tileNodes=function(k,L){var A=this.tileNodesByFavoringDim(k,L,!0),I=this.tileNodesByFavoringDim(k,L,!1),M=this.getOrgRatio(A),P=this.getOrgRatio(I),B;return PF&&(F=ce.getWidth())});var z=P/M,$=B/M,U=Math.pow(A-I,2)+4*(z+I)*($+A)*M,K=(I-A+Math.sqrt(U))/(2*(z+I)),ee;L?(ee=Math.ceil(K),ee==K&&ee++):ee=Math.floor(K);var Y=ee*(z+I)-I;return F>Y&&(Y=F),Y+=I*2,Y},O.prototype.tileNodesByFavoringDim=function(k,L,A){var I=m.TILING_PADDING_VERTICAL,M=m.TILING_PADDING_HORIZONTAL,P=m.TILING_COMPARE_BY,B={rows:[],rowWidth:[],rowHeight:[],width:0,height:L,verticalPadding:I,horizontalPadding:M,centerX:0,centerY:0};P&&(B.idealRowWidth=this.calcIdealRowWidth(k,A));var F=o(function(Z){return Z.rect.width*Z.rect.height},"getNodeArea"),z=o(function(Z,ue){return F(ue)-F(Z)},"areaCompareFcn");k.sort(function(ce,Z){var ue=z;return B.idealRowWidth?(ue=P,ue(ce.id,Z.id)):ue(ce,Z)});for(var $=0,U=0,K=0;K0&&(B+=k.horizontalPadding),k.rowWidth[A]=B,k.width0&&(F+=k.verticalPadding);var z=0;F>k.rowHeight[A]&&(z=k.rowHeight[A],k.rowHeight[A]=F,z=k.rowHeight[A]-z),k.height+=z,k.rows[A].push(L)},O.prototype.getShortestRowIndex=function(k){for(var L=-1,A=Number.MAX_VALUE,I=0;IA&&(L=I,A=k.rowWidth[I]);return L},O.prototype.canAddHorizontal=function(k,L,A){if(k.idealRowWidth){var I=k.rows.length-1,M=k.rowWidth[I];return M+L+k.horizontalPadding<=k.idealRowWidth}var P=this.getShortestRowIndex(k);if(P<0)return!0;var B=k.rowWidth[P];if(B+k.horizontalPadding+L<=k.width)return!0;var F=0;k.rowHeight[P]0&&(F=A+k.verticalPadding-k.rowHeight[P]);var z;k.width-B>=L+k.horizontalPadding?z=(k.height+F)/(B+L+k.horizontalPadding):z=(k.height+F)/k.width,F=A+k.verticalPadding;var $;return k.widthP&&L!=A){I.splice(-1,1),k.rows[A].push(M),k.rowWidth[L]=k.rowWidth[L]-P,k.rowWidth[A]=k.rowWidth[A]+P,k.width=k.rowWidth[instance.getLongestRowIndex(k)];for(var B=Number.MIN_VALUE,F=0;FB&&(B=I[F].height);L>0&&(B+=k.verticalPadding);var z=k.rowHeight[L]+k.rowHeight[A];k.rowHeight[L]=B,k.rowHeight[A]0)for(var Y=M;Y<=P;Y++)ee[0]+=this.grid[Y][B-1].length+this.grid[Y][B].length-1;if(P0)for(var Y=B;Y<=F;Y++)ee[3]+=this.grid[M-1][Y].length+this.grid[M][Y].length-1;for(var ce=w.MAX_VALUE,Z,ue,Q=0;Q{var u=l(551).FDLayoutNode,h=l(551).IMath;function f(p,m,g,y){u.call(this,p,m,g,y)}o(f,"CoSENode"),f.prototype=Object.create(u.prototype);for(var d in u)f[d]=u[d];f.prototype.calculateDisplacement=function(){var p=this.graphManager.getLayout();this.getChild()!=null&&this.fixedNodeWeight?(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementX=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementX)),Math.abs(this.displacementY)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementY=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},f.prototype.propogateDisplacementToChildren=function(p,m){for(var g=this.getChild().getNodes(),y,v=0;v{function u(g){if(Array.isArray(g)){for(var y=0,v=Array(g.length);y0){var ct=0;Ue.forEach(function(ot){Te=="horizontal"?(be.set(ot,x.has(ot)?b[x.get(ot)]:pe.get(ot)),ct+=be.get(ot)):(be.set(ot,x.has(ot)?T[x.get(ot)]:pe.get(ot)),ct+=be.get(ot))}),ct=ct/Ue.length,st.forEach(function(ot){W.has(ot)||be.set(ot,ct)})}else{var We=0;st.forEach(function(ot){Te=="horizontal"?We+=x.has(ot)?b[x.get(ot)]:pe.get(ot):We+=x.has(ot)?T[x.get(ot)]:pe.get(ot)}),We=We/st.length,st.forEach(function(ot){be.set(ot,We)})}});for(var qe=o(function(){var Ue=De.shift(),ct=V.get(Ue);ct.forEach(function(We){if(be.get(We.id)ot&&(ot=vt),ntYt&&(Yt=nt)}}catch(Dt){Mt=!0,bt=Dt}finally{try{!Tt&&ut.return&&ut.return()}finally{if(Mt)throw bt}}var pn=(ct+ot)/2-(We+Yt)/2,kt=!0,On=!1,tn=void 0;try{for(var Mr=st[Symbol.iterator](),Ir;!(kt=(Ir=Mr.next()).done);kt=!0){var Pn=Ir.value;be.set(Pn,be.get(Pn)+pn)}}catch(Dt){On=!0,tn=Dt}finally{try{!kt&&Mr.return&&Mr.return()}finally{if(On)throw tn}}})}return be},"findAppropriatePositionForRelativePlacement"),R=o(function(V){var Te=0,W=0,pe=0,ve=0;if(V.forEach(function(Ve){Ve.left?b[x.get(Ve.left)]-b[x.get(Ve.right)]>=0?Te++:W++:T[x.get(Ve.top)]-T[x.get(Ve.bottom)]>=0?pe++:ve++}),Te>W&&pe>ve)for(var Pe=0;PeW)for(var _e=0;_eve)for(var be=0;be1)y.fixedNodeConstraint.forEach(function(oe,V){I[V]=[oe.position.x,oe.position.y],M[V]=[b[x.get(oe.nodeId)],T[x.get(oe.nodeId)]]}),P=!0;else if(y.alignmentConstraint)(function(){var oe=0;if(y.alignmentConstraint.vertical){for(var V=y.alignmentConstraint.vertical,Te=o(function(be){var Ve=new Set;V[be].forEach(function(at){Ve.add(at)});var De=new Set([].concat(u(Ve)).filter(function(at){return F.has(at)})),qe=void 0;De.size>0?qe=b[x.get(De.values().next().value)]:qe=D(Ve).x,V[be].forEach(function(at){I[oe]=[qe,T[x.get(at)]],M[oe]=[b[x.get(at)],T[x.get(at)]],oe++})},"_loop2"),W=0;W0?qe=b[x.get(De.values().next().value)]:qe=D(Ve).y,pe[be].forEach(function(at){I[oe]=[b[x.get(at)],qe],M[oe]=[b[x.get(at)],T[x.get(at)]],oe++})},"_loop3"),Pe=0;PeK&&(K=U[Y].length,ee=Y);if(K<$.size/2)R(y.relativePlacementConstraint),P=!1,B=!1;else{var ce=new Map,Z=new Map,ue=[];U[ee].forEach(function(oe){z.get(oe).forEach(function(V){V.direction=="horizontal"?(ce.has(oe)?ce.get(oe).push(V):ce.set(oe,[V]),ce.has(V.id)||ce.set(V.id,[]),ue.push({left:oe,right:V.id})):(Z.has(oe)?Z.get(oe).push(V):Z.set(oe,[V]),Z.has(V.id)||Z.set(V.id,[]),ue.push({top:oe,bottom:V.id}))})}),R(ue),B=!1;var Q=O(ce,"horizontal"),j=O(Z,"vertical");U[ee].forEach(function(oe,V){M[V]=[b[x.get(oe)],T[x.get(oe)]],I[V]=[],Q.has(oe)?I[V][0]=Q.get(oe):I[V][0]=b[x.get(oe)],j.has(oe)?I[V][1]=j.get(oe):I[V][1]=T[x.get(oe)]}),P=!0}}if(P){for(var ne=void 0,te=d.transpose(I),he=d.transpose(M),le=0;le0){var Be={x:0,y:0};y.fixedNodeConstraint.forEach(function(oe,V){var Te={x:b[x.get(oe.nodeId)],y:T[x.get(oe.nodeId)]},W=oe.position,pe=C(W,Te);Be.x+=pe.x,Be.y+=pe.y}),Be.x/=y.fixedNodeConstraint.length,Be.y/=y.fixedNodeConstraint.length,b.forEach(function(oe,V){b[V]+=Be.x}),T.forEach(function(oe,V){T[V]+=Be.y}),y.fixedNodeConstraint.forEach(function(oe){b[x.get(oe.nodeId)]=oe.position.x,T[x.get(oe.nodeId)]=oe.position.y})}if(y.alignmentConstraint){if(y.alignmentConstraint.vertical)for(var He=y.alignmentConstraint.vertical,ze=o(function(V){var Te=new Set;He[V].forEach(function(ve){Te.add(ve)});var W=new Set([].concat(u(Te)).filter(function(ve){return F.has(ve)})),pe=void 0;W.size>0?pe=b[x.get(W.values().next().value)]:pe=D(Te).x,Te.forEach(function(ve){F.has(ve)||(b[x.get(ve)]=pe)})},"_loop4"),Le=0;Le0?pe=T[x.get(W.values().next().value)]:pe=D(Te).y,Te.forEach(function(ve){F.has(ve)||(T[x.get(ve)]=pe)})},"_loop5"),q=0;q{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(45);return i})()})});var Y2e=Pi((O4,e$)=>{"use strict";o(function(e,r){typeof O4=="object"&&typeof e$=="object"?e$.exports=r(JF()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof O4=="object"?O4.cytoscapeFcose=r(JF()):e.cytoscapeFcose=r(e.coseBase)},"webpackUniversalModuleDefinition")(O4,function(t){return(()=>{"use strict";var e={658:a=>{a.exports=Object.assign!=null?Object.assign.bind(Object):function(s){for(var l=arguments.length,u=Array(l>1?l-1:0),h=1;h{var u=function(){function d(p,m){var g=[],y=!0,v=!1,x=void 0;try{for(var b=p[Symbol.iterator](),T;!(y=(T=b.next()).done)&&(g.push(T.value),!(m&&g.length===m));y=!0);}catch(S){v=!0,x=S}finally{try{!y&&b.return&&b.return()}finally{if(v)throw x}}return g}return o(d,"sliceIterator"),function(p,m){if(Array.isArray(p))return p;if(Symbol.iterator in Object(p))return d(p,m);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),h=l(140).layoutBase.LinkedList,f={};f.getTopMostNodes=function(d){for(var p={},m=0;m0&&P.merge($)});for(var B=0;B1){T=x[0],S=T.connectedEdges().length,x.forEach(function(M){M.connectedEdges().length0&&g.set("dummy"+(g.size+1),_),C},f.relocateComponent=function(d,p,m){if(!m.fixedNodeConstraint){var g=Number.POSITIVE_INFINITY,y=Number.NEGATIVE_INFINITY,v=Number.POSITIVE_INFINITY,x=Number.NEGATIVE_INFINITY;if(m.quality=="draft"){var b=!0,T=!1,S=void 0;try{for(var w=p.nodeIndexes[Symbol.iterator](),E;!(b=(E=w.next()).done);b=!0){var _=E.value,C=u(_,2),D=C[0],O=C[1],R=m.cy.getElementById(D);if(R){var k=R.boundingBox(),L=p.xCoords[O]-k.w/2,A=p.xCoords[O]+k.w/2,I=p.yCoords[O]-k.h/2,M=p.yCoords[O]+k.h/2;Ly&&(y=A),Ix&&(x=M)}}}catch($){T=!0,S=$}finally{try{!b&&w.return&&w.return()}finally{if(T)throw S}}var P=d.x-(y+g)/2,B=d.y-(x+v)/2;p.xCoords=p.xCoords.map(function($){return $+P}),p.yCoords=p.yCoords.map(function($){return $+B})}else{Object.keys(p).forEach(function($){var U=p[$],K=U.getRect().x,ee=U.getRect().x+U.getRect().width,Y=U.getRect().y,ce=U.getRect().y+U.getRect().height;Ky&&(y=ee),Yx&&(x=ce)});var F=d.x-(y+g)/2,z=d.y-(x+v)/2;Object.keys(p).forEach(function($){var U=p[$];U.setCenter(U.getCenterX()+F,U.getCenterY()+z)})}}},f.calcBoundingBox=function(d,p,m,g){for(var y=Number.MAX_SAFE_INTEGER,v=Number.MIN_SAFE_INTEGER,x=Number.MAX_SAFE_INTEGER,b=Number.MIN_SAFE_INTEGER,T=void 0,S=void 0,w=void 0,E=void 0,_=d.descendants().not(":parent"),C=_.length,D=0;DT&&(y=T),vw&&(x=w),b{var u=l(548),h=l(140).CoSELayout,f=l(140).CoSENode,d=l(140).layoutBase.PointD,p=l(140).layoutBase.DimensionD,m=l(140).layoutBase.LayoutConstants,g=l(140).layoutBase.FDLayoutConstants,y=l(140).CoSEConstants,v=o(function(b,T){var S=b.cy,w=b.eles,E=w.nodes(),_=w.edges(),C=void 0,D=void 0,O=void 0,R={};b.randomize&&(C=T.nodeIndexes,D=T.xCoords,O=T.yCoords);var k=o(function($){return typeof $=="function"},"isFn"),L=o(function($,U){return k($)?$(U):$},"optFn"),A=u.calcParentsWithoutChildren(S,w),I=o(function z($,U,K,ee){for(var Y=U.length,ce=0;ce0){var te=void 0;te=K.getGraphManager().add(K.newGraph(),Q),z(te,ue,K,ee)}}},"processChildrenList"),M=o(function($,U,K){for(var ee=0,Y=0,ce=0;ce0?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=ee/Y:k(b.idealEdgeLength)?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=50:y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=b.idealEdgeLength,y.MIN_REPULSION_DIST=g.MIN_REPULSION_DIST=g.DEFAULT_EDGE_LENGTH/10,y.DEFAULT_RADIAL_SEPARATION=g.DEFAULT_EDGE_LENGTH)},"processEdges"),P=o(function($,U){U.fixedNodeConstraint&&($.constraints.fixedNodeConstraint=U.fixedNodeConstraint),U.alignmentConstraint&&($.constraints.alignmentConstraint=U.alignmentConstraint),U.relativePlacementConstraint&&($.constraints.relativePlacementConstraint=U.relativePlacementConstraint)},"processConstraints");b.nestingFactor!=null&&(y.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=g.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=b.nestingFactor),b.gravity!=null&&(y.DEFAULT_GRAVITY_STRENGTH=g.DEFAULT_GRAVITY_STRENGTH=b.gravity),b.numIter!=null&&(y.MAX_ITERATIONS=g.MAX_ITERATIONS=b.numIter),b.gravityRange!=null&&(y.DEFAULT_GRAVITY_RANGE_FACTOR=g.DEFAULT_GRAVITY_RANGE_FACTOR=b.gravityRange),b.gravityCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_STRENGTH=g.DEFAULT_COMPOUND_GRAVITY_STRENGTH=b.gravityCompound),b.gravityRangeCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=g.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=b.gravityRangeCompound),b.initialEnergyOnIncremental!=null&&(y.DEFAULT_COOLING_FACTOR_INCREMENTAL=g.DEFAULT_COOLING_FACTOR_INCREMENTAL=b.initialEnergyOnIncremental),b.tilingCompareBy!=null&&(y.TILING_COMPARE_BY=b.tilingCompareBy),b.quality=="proof"?m.QUALITY=2:m.QUALITY=0,y.NODE_DIMENSIONS_INCLUDE_LABELS=g.NODE_DIMENSIONS_INCLUDE_LABELS=m.NODE_DIMENSIONS_INCLUDE_LABELS=b.nodeDimensionsIncludeLabels,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!b.randomize,y.ANIMATE=g.ANIMATE=m.ANIMATE=b.animate,y.TILE=b.tile,y.TILING_PADDING_VERTICAL=typeof b.tilingPaddingVertical=="function"?b.tilingPaddingVertical.call():b.tilingPaddingVertical,y.TILING_PADDING_HORIZONTAL=typeof b.tilingPaddingHorizontal=="function"?b.tilingPaddingHorizontal.call():b.tilingPaddingHorizontal,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!0,y.PURE_INCREMENTAL=!b.randomize,m.DEFAULT_UNIFORM_LEAF_NODE_SIZES=b.uniformNodeDimensions,b.step=="transformed"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!1),b.step=="enforced"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!1),b.step=="cose"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!0),b.step=="all"&&(b.randomize?y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!0),b.fixedNodeConstraint||b.alignmentConstraint||b.relativePlacementConstraint?y.TREE_REDUCTION_ON_INCREMENTAL=!1:y.TREE_REDUCTION_ON_INCREMENTAL=!0;var B=new h,F=B.newGraphManager();return I(F.addRoot(),u.getTopMostNodes(E),B,b),M(B,F,_),P(B,b),B.runLayout(),R},"coseLayout");a.exports={coseLayout:v}},212:(a,s,l)=>{var u=function(){function b(T,S){for(var w=0;w0)if(M){var F=d.getTopMostNodes(w.eles.nodes());if(k=d.connectComponents(E,w.eles,F),k.forEach(function(se){var ae=se.boundingBox();L.push({x:ae.x1+ae.w/2,y:ae.y1+ae.h/2})}),w.randomize&&k.forEach(function(se){w.eles=se,C.push(m(w))}),w.quality=="default"||w.quality=="proof"){var z=E.collection();if(w.tile){var $=new Map,U=[],K=[],ee=0,Y={nodeIndexes:$,xCoords:U,yCoords:K},ce=[];if(k.forEach(function(se,ae){se.edges().length==0&&(se.nodes().forEach(function(Oe,ye){z.merge(se.nodes()[ye]),Oe.isParent()||(Y.nodeIndexes.set(se.nodes()[ye].id(),ee++),Y.xCoords.push(se.nodes()[0].position().x),Y.yCoords.push(se.nodes()[0].position().y))}),ce.push(ae))}),z.length>1){var Z=z.boundingBox();L.push({x:Z.x1+Z.w/2,y:Z.y1+Z.h/2}),k.push(z),C.push(Y);for(var ue=ce.length-1;ue>=0;ue--)k.splice(ce[ue],1),C.splice(ce[ue],1),L.splice(ce[ue],1)}}k.forEach(function(se,ae){w.eles=se,R.push(y(w,C[ae])),d.relocateComponent(L[ae],R[ae],w)})}else k.forEach(function(se,ae){d.relocateComponent(L[ae],C[ae],w)});var Q=new Set;if(k.length>1){var j=[],ne=_.filter(function(se){return se.css("display")=="none"});k.forEach(function(se,ae){var Oe=void 0;if(w.quality=="draft"&&(Oe=C[ae].nodeIndexes),se.nodes().not(ne).length>0){var ye={};ye.edges=[],ye.nodes=[];var Be=void 0;se.nodes().not(ne).forEach(function(He){if(w.quality=="draft")if(!He.isParent())Be=Oe.get(He.id()),ye.nodes.push({x:C[ae].xCoords[Be]-He.boundingbox().w/2,y:C[ae].yCoords[Be]-He.boundingbox().h/2,width:He.boundingbox().w,height:He.boundingbox().h});else{var ze=d.calcBoundingBox(He,C[ae].xCoords,C[ae].yCoords,Oe);ye.nodes.push({x:ze.topLeftX,y:ze.topLeftY,width:ze.width,height:ze.height})}else R[ae][He.id()]&&ye.nodes.push({x:R[ae][He.id()].getLeft(),y:R[ae][He.id()].getTop(),width:R[ae][He.id()].getWidth(),height:R[ae][He.id()].getHeight()})}),se.edges().forEach(function(He){var ze=He.source(),Le=He.target();if(ze.css("display")!="none"&&Le.css("display")!="none")if(w.quality=="draft"){var Ie=Oe.get(ze.id()),xe=Oe.get(Le.id()),q=[],de=[];if(ze.isParent()){var ie=d.calcBoundingBox(ze,C[ae].xCoords,C[ae].yCoords,Oe);q.push(ie.topLeftX+ie.width/2),q.push(ie.topLeftY+ie.height/2)}else q.push(C[ae].xCoords[Ie]),q.push(C[ae].yCoords[Ie]);if(Le.isParent()){var oe=d.calcBoundingBox(Le,C[ae].xCoords,C[ae].yCoords,Oe);de.push(oe.topLeftX+oe.width/2),de.push(oe.topLeftY+oe.height/2)}else de.push(C[ae].xCoords[xe]),de.push(C[ae].yCoords[xe]);ye.edges.push({startX:q[0],startY:q[1],endX:de[0],endY:de[1]})}else R[ae][ze.id()]&&R[ae][Le.id()]&&ye.edges.push({startX:R[ae][ze.id()].getCenterX(),startY:R[ae][ze.id()].getCenterY(),endX:R[ae][Le.id()].getCenterX(),endY:R[ae][Le.id()].getCenterY()})}),ye.nodes.length>0&&(j.push(ye),Q.add(ae))}});var te=I.packComponents(j,w.randomize).shifts;if(w.quality=="draft")C.forEach(function(se,ae){var Oe=se.xCoords.map(function(Be){return Be+te[ae].dx}),ye=se.yCoords.map(function(Be){return Be+te[ae].dy});se.xCoords=Oe,se.yCoords=ye});else{var he=0;Q.forEach(function(se){Object.keys(R[se]).forEach(function(ae){var Oe=R[se][ae];Oe.setCenter(Oe.getCenterX()+te[he].dx,Oe.getCenterY()+te[he].dy)}),he++})}}}else{var P=w.eles.boundingBox();if(L.push({x:P.x1+P.w/2,y:P.y1+P.h/2}),w.randomize){var B=m(w);C.push(B)}w.quality=="default"||w.quality=="proof"?(R.push(y(w,C[0])),d.relocateComponent(L[0],R[0],w)):d.relocateComponent(L[0],C[0],w)}var le=o(function(ae,Oe){if(w.quality=="default"||w.quality=="proof"){typeof ae=="number"&&(ae=Oe);var ye=void 0,Be=void 0,He=ae.data("id");return R.forEach(function(Le){He in Le&&(ye={x:Le[He].getRect().getCenterX(),y:Le[He].getRect().getCenterY()},Be=Le[He])}),w.nodeDimensionsIncludeLabels&&(Be.labelWidth&&(Be.labelPosHorizontal=="left"?ye.x+=Be.labelWidth/2:Be.labelPosHorizontal=="right"&&(ye.x-=Be.labelWidth/2)),Be.labelHeight&&(Be.labelPosVertical=="top"?ye.y+=Be.labelHeight/2:Be.labelPosVertical=="bottom"&&(ye.y-=Be.labelHeight/2))),ye==null&&(ye={x:ae.position("x"),y:ae.position("y")}),{x:ye.x,y:ye.y}}else{var ze=void 0;return C.forEach(function(Le){var Ie=Le.nodeIndexes.get(ae.id());Ie!=null&&(ze={x:Le.xCoords[Ie],y:Le.yCoords[Ie]})}),ze==null&&(ze={x:ae.position("x"),y:ae.position("y")}),{x:ze.x,y:ze.y}}},"getPositions");if(w.quality=="default"||w.quality=="proof"||w.randomize){var J=d.calcParentsWithoutChildren(E,_),Se=_.filter(function(se){return se.css("display")=="none"});w.eles=_.not(Se),_.nodes().not(":parent").not(Se).layoutPositions(S,w,le),J.length>0&&J.forEach(function(se){se.position(le(se))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")},"run")}]),b}();a.exports=x},657:(a,s,l)=>{var u=l(548),h=l(140).layoutBase.Matrix,f=l(140).layoutBase.SVD,d=o(function(m){var g=m.cy,y=m.eles,v=y.nodes(),x=y.nodes(":parent"),b=new Map,T=new Map,S=new Map,w=[],E=[],_=[],C=[],D=[],O=[],R=[],k=[],L=void 0,A=void 0,I=1e8,M=1e-9,P=m.piTol,B=m.samplingType,F=m.nodeSeparation,z=void 0,$=o(function(){for(var Te=0,W=0,pe=!1;W=Pe;){be=ve[Pe++];for(var st=w[be],Ue=0;Ueqe&&(qe=D[We],at=We)}return at},"BFS"),K=o(function(Te){var W=void 0;if(Te){W=Math.floor(Math.random()*A),L=W;for(var ve=0;ve=1)break;qe=De}for(var st=0;st=1)break;qe=De}for(var ct=0;ct0&&(W.isParent()?w[Te].push(S.get(W.id())):w[Te].push(W.id()))})});var J=o(function(Te){var W=T.get(Te),pe=void 0;b.get(Te).forEach(function(ve){g.getElementById(ve).isParent()?pe=S.get(ve):pe=ve,w[W].push(pe),w[T.get(pe)].push(Te)})},"_loop"),Se=!0,se=!1,ae=void 0;try{for(var Oe=b.keys()[Symbol.iterator](),ye;!(Se=(ye=Oe.next()).done);Se=!0){var Be=ye.value;J(Be)}}catch(V){se=!0,ae=V}finally{try{!Se&&Oe.return&&Oe.return()}finally{if(se)throw ae}}A=T.size;var He=void 0;if(A>2){z=A{var u=l(212),h=o(function(d){d&&d("layout","fcose",u)},"register");typeof cytoscape<"u"&&h(cytoscape),a.exports=h},140:a=>{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(579);return i})()})});var xy,l0,t$=N(()=>{"use strict";jl();xy=o(t=>`${t}`,"wrapIcon"),l0={prefix:"mermaid-architecture",height:80,width:80,icons:{database:{body:xy('')},server:{body:xy('')},disk:{body:xy('')},internet:{body:xy('')},cloud:{body:xy('')},unknown:t7,blank:{body:xy("")}}}});var X2e,j2e,K2e,Q2e,Z2e=N(()=>{"use strict";jl();Gt();ao();N4();t$();AC();X2e=o(async function(t,e){let r=Mi("padding"),n=Mi("iconSize"),i=n/2,a=n/6,s=a/2;await Promise.all(e.edges().map(async l=>{let{source:u,sourceDir:h,sourceArrow:f,sourceGroup:d,target:p,targetDir:m,targetArrow:g,targetGroup:y,label:v}=CC(l),{x,y:b}=l[0].sourceEndpoint(),{x:T,y:S}=l[0].midpoint(),{x:w,y:E}=l[0].targetEndpoint(),_=r+4;if(d&&(ja(h)?x+=h==="L"?-_:_:b+=h==="T"?-_:_+18),y&&(ja(m)?w+=m==="L"?-_:_:E+=m==="T"?-_:_+18),!d&&o0.getNode(u)?.type==="junction"&&(ja(h)?x+=h==="L"?i:-i:b+=h==="T"?i:-i),!y&&o0.getNode(p)?.type==="junction"&&(ja(m)?w+=m==="L"?i:-i:E+=m==="T"?i:-i),l[0]._private.rscratch){let C=t.insert("g");if(C.insert("path").attr("d",`M ${x},${b} L ${T},${S} L${w},${E} `).attr("class","edge"),f){let D=ja(h)?D4[h](x,a):x-s,O=ru(h)?D4[h](b,a):b-s;C.insert("polygon").attr("points",YF[h](a)).attr("transform",`translate(${D},${O})`).attr("class","arrow")}if(g){let D=ja(m)?D4[m](w,a):w-s,O=ru(m)?D4[m](E,a):E-s;C.insert("polygon").attr("points",YF[m](a)).attr("transform",`translate(${D},${O})`).attr("class","arrow")}if(v){let D=L4(h,m)?"XY":ja(h)?"X":"Y",O=0;D==="X"?O=Math.abs(x-w):D==="Y"?O=Math.abs(b-E)/1.5:O=Math.abs(x-w)/2;let R=C.append("g");if(await qn(R,v,{useHtmlLabels:!1,width:O,classes:"architecture-service-label"},me()),R.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),D==="X")R.attr("transform","translate("+T+", "+S+")");else if(D==="Y")R.attr("transform","translate("+T+", "+S+") rotate(-90)");else if(D==="XY"){let k=R4(h,m);if(k&&O2e(k)){let L=R.node().getBoundingClientRect(),[A,I]=B2e(k);R.attr("dominant-baseline","auto").attr("transform",`rotate(${-1*A*I*45})`);let M=R.node().getBoundingClientRect();R.attr("transform",` - translate(${T}, ${S-L.height/2}) - translate(${A*M.width/2}, ${I*M.height/2}) - rotate(${-1*A*I*45}, 0, ${L.height/2}) - `)}}}}}))},"drawEdges"),j2e=o(async function(t,e){let n=Mi("padding")*.75,i=Mi("fontSize"),s=Mi("iconSize")/2;await Promise.all(e.nodes().map(async l=>{let u=Yf(l);if(u.type==="group"){let{h,w:f,x1:d,y1:p}=l.boundingBox();t.append("rect").attr("x",d+s).attr("y",p+s).attr("width",f).attr("height",h).attr("class","node-bkg");let m=t.append("g"),g=d,y=p;if(u.icon){let v=m.append("g");v.html(`${await Es(u.icon,{height:n,width:n,fallbackPrefix:l0.prefix})}`),v.attr("transform","translate("+(g+s+1)+", "+(y+s+1)+")"),g+=n,y+=i/2-1-2}if(u.label){let v=m.append("g");await qn(v,u.label,{useHtmlLabels:!1,width:f,classes:"architecture-service-label"},me()),v.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","start").attr("text-anchor","start"),v.attr("transform","translate("+(g+s+4)+", "+(y+s+2)+")")}}}))},"drawGroups"),K2e=o(async function(t,e,r){for(let n of r){let i=e.append("g"),a=Mi("iconSize");if(n.title){let h=i.append("g");await qn(h,n.title,{useHtmlLabels:!1,width:a*1.5,classes:"architecture-service-label"},me()),h.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),h.attr("transform","translate("+a/2+", "+a+")")}let s=i.append("g");if(n.icon)s.html(`${await Es(n.icon,{height:a,width:a,fallbackPrefix:l0.prefix})}`);else if(n.iconText){s.html(`${await Es("blank",{height:a,width:a,fallbackPrefix:l0.prefix})}`);let d=s.append("g").append("foreignObject").attr("width",a).attr("height",a).append("div").attr("class","node-icon-text").attr("style",`height: ${a}px;`).append("div").html(n.iconText),p=parseInt(window.getComputedStyle(d.node(),null).getPropertyValue("font-size").replace(/\D/g,""))??16;d.attr("style",`-webkit-line-clamp: ${Math.floor((a-2)/p)};`)}else s.append("path").attr("class","node-bkg").attr("id","node-"+n.id).attr("d",`M0 ${a} v${-a} q0,-5 5,-5 h${a} q5,0 5,5 v${a} H0 Z`);i.attr("class","architecture-service");let{width:l,height:u}=i._groups[0][0].getBBox();n.width=l,n.height=u,t.setElementForId(n.id,i)}return 0},"drawServices"),Q2e=o(function(t,e,r){r.forEach(n=>{let i=e.append("g"),a=Mi("iconSize");i.append("g").append("rect").attr("id","node-"+n.id).attr("fill-opacity","0").attr("width",a).attr("height",a),i.attr("class","architecture-junction");let{width:l,height:u}=i._groups[0][0].getBBox();i.width=l,i.height=u,t.setElementForId(n.id,i)})},"drawJunctions")});function Hnt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"service",id:r.id,icon:r.icon,label:r.title,parent:r.in,width:Mi("iconSize"),height:Mi("iconSize")},classes:"node-service"})})}function Wnt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"junction",id:r.id,parent:r.in,width:Mi("iconSize"),height:Mi("iconSize")},classes:"node-junction"})})}function qnt(t,e){e.nodes().map(r=>{let n=Yf(r);if(n.type==="group")return;n.x=r.position().x,n.y=r.position().y,t.getElementById(n.id).attr("transform","translate("+(n.x||0)+","+(n.y||0)+")")})}function Ynt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"group",id:r.id,icon:r.icon,label:r.title,parent:r.in},classes:"node-group"})})}function Xnt(t,e){t.forEach(r=>{let{lhsId:n,rhsId:i,lhsInto:a,lhsGroup:s,rhsInto:l,lhsDir:u,rhsDir:h,rhsGroup:f,title:d}=r,p=L4(r.lhsDir,r.rhsDir)?"segments":"straight",m={id:`${n}-${i}`,label:d,source:n,sourceDir:u,sourceArrow:a,sourceGroup:s,sourceEndpoint:u==="L"?"0 50%":u==="R"?"100% 50%":u==="T"?"50% 0":"50% 100%",target:i,targetDir:h,targetArrow:l,targetGroup:f,targetEndpoint:h==="L"?"0 50%":h==="R"?"100% 50%":h==="T"?"50% 0":"50% 100%"};e.add({group:"edges",data:m,classes:p})})}function jnt(t,e,r){let n=o((l,u)=>Object.entries(l).reduce((h,[f,d])=>{let p=0,m=Object.entries(d);if(m.length===1)return h[f]=m[0][1],h;for(let g=0;g{let u={},h={};return Object.entries(l).forEach(([f,[d,p]])=>{let m=t.getNode(f)?.in??"default";u[p]??={},u[p][m]??=[],u[p][m].push(f),h[d]??={},h[d][m]??=[],h[d][m].push(f)}),{horiz:Object.values(n(u,"horizontal")).filter(f=>f.length>1),vert:Object.values(n(h,"vertical")).filter(f=>f.length>1)}}),[a,s]=i.reduce(([l,u],{horiz:h,vert:f})=>[[...l,...h],[...u,...f]],[[],[]]);return{horizontal:a,vertical:s}}function Knt(t){let e=[],r=o(i=>`${i[0]},${i[1]}`,"posToStr"),n=o(i=>i.split(",").map(a=>parseInt(a)),"strToPos");return t.forEach(i=>{let a=Object.fromEntries(Object.entries(i).map(([h,f])=>[r(f),h])),s=[r([0,0])],l={},u={L:[-1,0],R:[1,0],T:[0,1],B:[0,-1]};for(;s.length>0;){let h=s.shift();if(h){l[h]=1;let f=a[h];if(f){let d=n(h);Object.entries(u).forEach(([p,m])=>{let g=r([d[0]+m[0],d[1]+m[1]]),y=a[g];y&&!l[g]&&(s.push(g),e.push({[qF[p]]:y,[qF[I2e(p)]]:f,gap:1.5*Mi("iconSize")}))})}}}}),e}function Qnt(t,e,r,n,i,{spatialMaps:a,groupAlignments:s}){return new Promise(l=>{let u=Ge("body").append("div").attr("id","cy").attr("style","display:none"),h=sl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"straight",label:"data(label)","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"edge.segments",style:{"curve-style":"segments","segment-weights":"0","segment-distances":[.5],"edge-distances":"endpoints","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"node",style:{"compound-sizing-wrt-labels":"include"}},{selector:"node[label]",style:{"text-valign":"bottom","text-halign":"center","font-size":`${Mi("fontSize")}px`}},{selector:".node-service",style:{label:"data(label)",width:"data(width)",height:"data(height)"}},{selector:".node-junction",style:{width:"data(width)",height:"data(height)"}},{selector:".node-group",style:{padding:`${Mi("padding")}px`}}],layout:{name:"grid",boundingBox:{x1:0,x2:100,y1:0,y2:100}}});u.remove(),Ynt(r,h),Hnt(t,h),Wnt(e,h),Xnt(n,h);let f=jnt(i,a,s),d=Knt(a),p=h.layout({name:"fcose",quality:"proof",styleEnabled:!1,animate:!1,nodeDimensionsIncludeLabels:!1,idealEdgeLength(m){let[g,y]=m.connectedNodes(),{parent:v}=Yf(g),{parent:x}=Yf(y);return v===x?1.5*Mi("iconSize"):.5*Mi("iconSize")},edgeElasticity(m){let[g,y]=m.connectedNodes(),{parent:v}=Yf(g),{parent:x}=Yf(y);return v===x?.45:.001},alignmentConstraint:f,relativePlacementConstraint:d});p.one("layoutstop",()=>{function m(g,y,v,x){let b,T,{x:S,y:w}=g,{x:E,y:_}=y;T=(x-w+(S-v)*(w-_)/(S-E))/Math.sqrt(1+Math.pow((w-_)/(S-E),2)),b=Math.sqrt(Math.pow(x-w,2)+Math.pow(v-S,2)-Math.pow(T,2));let C=Math.sqrt(Math.pow(E-S,2)+Math.pow(_-w,2));b=b/C;let D=(E-S)*(x-w)-(_-w)*(v-S);switch(!0){case D>=0:D=1;break;case D<0:D=-1;break}let O=(E-S)*(v-S)+(_-w)*(x-w);switch(!0){case O>=0:O=1;break;case O<0:O=-1;break}return T=Math.abs(T)*D,b=b*O,{distances:T,weights:b}}o(m,"getSegmentWeights"),h.startBatch();for(let g of Object.values(h.edges()))if(g.data?.()){let{x:y,y:v}=g.source().position(),{x,y:b}=g.target().position();if(y!==x&&v!==b){let T=g.sourceEndpoint(),S=g.targetEndpoint(),{sourceDir:w}=CC(g),[E,_]=ru(w)?[T.x,S.y]:[S.x,T.y],{weights:C,distances:D}=m(T,S,E,_);g.style("segment-distances",D),g.style("segment-weights",C)}}h.endBatch(),p.run()}),p.run(),h.ready(m=>{X.info("Ready",m),l(h)})})}var J2e,Znt,exe,txe=N(()=>{"use strict";jl();oF();J2e=Aa(Y2e(),1);fr();yt();Vl();xi();N4();t$();AC();Z2e();X4([{name:l0.prefix,icons:l0}]);sl.use(J2e.default);o(Hnt,"addServices");o(Wnt,"addJunctions");o(qnt,"positionNodes");o(Ynt,"addGroups");o(Xnt,"addEdges");o(jnt,"getAlignments");o(Knt,"getRelativeConstraints");o(Qnt,"layoutArchitecture");Znt=o(async(t,e,r,n)=>{let i=n.db,a=i.getServices(),s=i.getJunctions(),l=i.getGroups(),u=i.getEdges(),h=i.getDataStructures(),f=Li(e),d=f.append("g");d.attr("class","architecture-edges");let p=f.append("g");p.attr("class","architecture-services");let m=f.append("g");m.attr("class","architecture-groups"),await K2e(i,p,a),Q2e(i,p,s);let g=await Qnt(a,s,l,u,i,h);await X2e(d,g),await j2e(m,g),qnt(i,g),Lo(void 0,f,Mi("padding"),Mi("useMaxWidth"))},"draw"),exe={draw:Znt}});var rxe={};ur(rxe,{diagram:()=>Jnt});var Jnt,nxe=N(()=>{"use strict";H2e();N4();q2e();txe();Jnt={parser:U2e,db:o0,renderer:exe,styles:W2e}});var by,r$=N(()=>{"use strict";_a();mi();er();zt();ci();by=class{constructor(){this.nodes=[];this.levels=new Map;this.outerNodes=[];this.classes=new Map;this.setAccTitle=Ar;this.getAccTitle=Dr;this.setDiagramTitle=Or;this.getDiagramTitle=Nr;this.getAccDescription=Rr;this.setAccDescription=Lr}static{o(this,"TreeMapDB")}getNodes(){return this.nodes}getConfig(){let e=or,r=tr();return $n({...e.treemap,...r.treemap??{}})}addNode(e,r){this.nodes.push(e),this.levels.set(e,r),r===0&&(this.outerNodes.push(e),this.root??=e)}getRoot(){return{name:"",children:this.outerNodes}}addClass(e,r){let n=this.classes.get(e)??{id:e,styles:[],textStyles:[]},i=r.replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");i&&i.forEach(a=>{S2(a)&&(n?.textStyles?n.textStyles.push(a):n.textStyles=[a]),n?.styles?n.styles.push(a):n.styles=[a]}),this.classes.set(e,n)}getClasses(){return this.classes}getStylesForClass(e){return this.classes.get(e)?.styles??[]}clear(){kr(),this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.root=void 0}}});function sxe(t){if(!t.length)return[];let e=[],r=[];return t.forEach(n=>{let i={name:n.name,children:n.type==="Leaf"?void 0:[]};for(i.classSelector=n?.classSelector,n?.cssCompiledStyles&&(i.cssCompiledStyles=[n.cssCompiledStyles]),n.type==="Leaf"&&n.value!==void 0&&(i.value=n.value);r.length>0&&r[r.length-1].level>=n.level;)r.pop();if(r.length===0)e.push(i);else{let a=r[r.length-1].node;a.children?a.children.push(i):a.children=[i]}n.type!=="Leaf"&&r.push({node:i,level:n.level})}),e}var oxe=N(()=>{"use strict";o(sxe,"buildHierarchy")});var nit,iit,n$,lxe=N(()=>{"use strict";bf();yt();Mp();oxe();r$();nit=o((t,e)=>{Jo(t,e);let r=[];for(let a of t.TreemapRows??[])a.$type==="ClassDefStatement"&&e.addClass(a.className??"",a.styleText??"");for(let a of t.TreemapRows??[]){let s=a.item;if(!s)continue;let l=a.indent?parseInt(a.indent):0,u=iit(s),h=s.classSelector?e.getStylesForClass(s.classSelector):[],f=h.length>0?h.join(";"):void 0,d={level:l,name:u,type:s.$type,value:s.value,classSelector:s.classSelector,cssCompiledStyles:f};r.push(d)}let n=sxe(r),i=o((a,s)=>{for(let l of a)e.addNode(l,s),l.children&&l.children.length>0&&i(l.children,s+1)},"addNodesRecursively");i(n,0)},"populate"),iit=o(t=>t.name?String(t.name):"","getItemName"),n$={parser:{yy:void 0},parse:o(async t=>{try{let r=await vs("treemap",t);X.debug("Treemap AST:",r);let n=n$.parser?.yy;if(!(n instanceof by))throw new Error("parser.parser?.yy was not a TreemapDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");nit(r,n)}catch(e){throw X.error("Error parsing treemap:",e),e}},"parse")}});var ait,Ty,P4,sit,oit,cxe,uxe=N(()=>{"use strict";Vl();np();xi();fr();zt();mi();yt();ait=10,Ty=10,P4=25,sit=o((t,e,r,n)=>{let i=n.db,a=i.getConfig(),s=a.padding??ait,l=i.getDiagramTitle(),u=i.getRoot(),{themeVariables:h}=tr();if(!u)return;let f=l?30:0,d=Li(e),p=a.nodeWidth?a.nodeWidth*Ty:960,m=a.nodeHeight?a.nodeHeight*Ty:500,g=p,y=m+f;d.attr("viewBox",`0 0 ${g} ${y}`),fn(d,y,g,a.useMaxWidth);let v;try{let A=a.valueFormat||",";if(A==="$0,0")v=o(I=>"$"+cc(",")(I),"valueFormat");else if(A.startsWith("$")&&A.includes(",")){let I=/\.\d+/.exec(A),M=I?I[0]:"";v=o(P=>"$"+cc(","+M)(P),"valueFormat")}else if(A.startsWith("$")){let I=A.substring(1);v=o(M=>"$"+cc(I||"")(M),"valueFormat")}else v=cc(A)}catch(A){X.error("Error creating format function:",A),v=cc(",")}let x=Js().range(["transparent",h.cScale0,h.cScale1,h.cScale2,h.cScale3,h.cScale4,h.cScale5,h.cScale6,h.cScale7,h.cScale8,h.cScale9,h.cScale10,h.cScale11]),b=Js().range(["transparent",h.cScalePeer0,h.cScalePeer1,h.cScalePeer2,h.cScalePeer3,h.cScalePeer4,h.cScalePeer5,h.cScalePeer6,h.cScalePeer7,h.cScalePeer8,h.cScalePeer9,h.cScalePeer10,h.cScalePeer11]),T=Js().range([h.cScaleLabel0,h.cScaleLabel1,h.cScaleLabel2,h.cScaleLabel3,h.cScaleLabel4,h.cScaleLabel5,h.cScaleLabel6,h.cScaleLabel7,h.cScaleLabel8,h.cScaleLabel9,h.cScaleLabel10,h.cScaleLabel11]);l&&d.append("text").attr("x",g/2).attr("y",f/2).attr("class","treemapTitle").attr("text-anchor","middle").attr("dominant-baseline","middle").text(l);let S=d.append("g").attr("transform",`translate(0, ${f})`).attr("class","treemapContainer"),w=z0(u).sum(A=>A.value??0).sort((A,I)=>(I.value??0)-(A.value??0)),_=D5().size([p,m]).paddingTop(A=>A.children&&A.children.length>0?P4+Ty:0).paddingInner(s).paddingLeft(A=>A.children&&A.children.length>0?Ty:0).paddingRight(A=>A.children&&A.children.length>0?Ty:0).paddingBottom(A=>A.children&&A.children.length>0?Ty:0).round(!0)(w),C=_.descendants().filter(A=>A.children&&A.children.length>0),D=S.selectAll(".treemapSection").data(C).enter().append("g").attr("class","treemapSection").attr("transform",A=>`translate(${A.x0},${A.y0})`);D.append("rect").attr("width",A=>A.x1-A.x0).attr("height",P4).attr("class","treemapSectionHeader").attr("fill","none").attr("fill-opacity",.6).attr("stroke-width",.6).attr("style",A=>A.depth===0?"display: none;":""),D.append("clipPath").attr("id",(A,I)=>`clip-section-${e}-${I}`).append("rect").attr("width",A=>Math.max(0,A.x1-A.x0-12)).attr("height",P4),D.append("rect").attr("width",A=>A.x1-A.x0).attr("height",A=>A.y1-A.y0).attr("class",(A,I)=>`treemapSection section${I}`).attr("fill",A=>x(A.data.name)).attr("fill-opacity",.6).attr("stroke",A=>b(A.data.name)).attr("stroke-width",2).attr("stroke-opacity",.4).attr("style",A=>{if(A.depth===0)return"display: none;";let I=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I.nodeStyles+";"+I.borderStyles.join(";")}),D.append("text").attr("class","treemapSectionLabel").attr("x",6).attr("y",P4/2).attr("dominant-baseline","middle").text(A=>A.depth===0?"":A.data.name).attr("font-weight","bold").attr("style",A=>{if(A.depth===0)return"display: none;";let I="dominant-baseline: middle; font-size: 12px; fill:"+T(A.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")}).each(function(A){if(A.depth===0)return;let I=Ge(this),M=A.data.name;I.text(M);let P=A.x1-A.x0,B=6,F;a.showValues!==!1&&A.value?F=P-10-30-10-B:F=P-B-6;let $=Math.max(15,F),U=I.node();if(U.getComputedTextLength()>$){let ee="...",Y=M;for(;Y.length>0;){if(Y=M.substring(0,Y.length-1),Y.length===0){I.text(ee),U.getComputedTextLength()>$&&I.text("");break}if(I.text(Y+ee),U.getComputedTextLength()<=$)break}}}),a.showValues!==!1&&D.append("text").attr("class","treemapSectionValue").attr("x",A=>A.x1-A.x0-10).attr("y",P4/2).attr("text-anchor","end").attr("dominant-baseline","middle").text(A=>A.value?v(A.value):"").attr("font-style","italic").attr("style",A=>{if(A.depth===0)return"display: none;";let I="text-anchor: end; dominant-baseline: middle; font-size: 10px; fill:"+T(A.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")});let O=_.leaves(),R=S.selectAll(".treemapLeafGroup").data(O).enter().append("g").attr("class",(A,I)=>`treemapNode treemapLeafGroup leaf${I}${A.data.classSelector?` ${A.data.classSelector}`:""}x`).attr("transform",A=>`translate(${A.x0},${A.y0})`);R.append("rect").attr("width",A=>A.x1-A.x0).attr("height",A=>A.y1-A.y0).attr("class","treemapLeaf").attr("fill",A=>A.parent?x(A.parent.data.name):x(A.data.name)).attr("style",A=>Ye({cssCompiledStyles:A.data.cssCompiledStyles}).nodeStyles).attr("fill-opacity",.3).attr("stroke",A=>A.parent?x(A.parent.data.name):x(A.data.name)).attr("stroke-width",3),R.append("clipPath").attr("id",(A,I)=>`clip-${e}-${I}`).append("rect").attr("width",A=>Math.max(0,A.x1-A.x0-4)).attr("height",A=>Math.max(0,A.y1-A.y0-4)),R.append("text").attr("class","treemapLabel").attr("x",A=>(A.x1-A.x0)/2).attr("y",A=>(A.y1-A.y0)/2).attr("style",A=>{let I="text-anchor: middle; dominant-baseline: middle; font-size: 38px;fill:"+T(A.data.name)+";",M=Ye({cssCompiledStyles:A.data.cssCompiledStyles});return I+M.labelStyles.replace("color:","fill:")}).attr("clip-path",(A,I)=>`url(#clip-${e}-${I})`).text(A=>A.data.name).each(function(A){let I=Ge(this),M=A.x1-A.x0,P=A.y1-A.y0,B=I.node(),F=4,z=M-2*F,$=P-2*F;if(z<10||$<10){I.style("display","none");return}let U=parseInt(I.style("font-size"),10),K=8,ee=28,Y=.6,ce=6,Z=2;for(;B.getComputedTextLength()>z&&U>K;)U--,I.style("font-size",`${U}px`);let ue=Math.max(ce,Math.min(ee,Math.round(U*Y))),Q=U+Z+ue;for(;Q>$&&U>K&&(U--,ue=Math.max(ce,Math.min(ee,Math.round(U*Y))),!(ue$;I.style("font-size",`${U}px`),(B.getComputedTextLength()>z||U(I.x1-I.x0)/2).attr("y",function(I){return(I.y1-I.y0)/2}).attr("style",I=>{let M="text-anchor: middle; dominant-baseline: hanging; font-size: 28px;fill:"+T(I.data.name)+";",P=Ye({cssCompiledStyles:I.data.cssCompiledStyles});return M+P.labelStyles.replace("color:","fill:")}).attr("clip-path",(I,M)=>`url(#clip-${e}-${M})`).text(I=>I.value?v(I.value):"").each(function(I){let M=Ge(this),P=this.parentNode;if(!P){M.style("display","none");return}let B=Ge(P).select(".treemapLabel");if(B.empty()||B.style("display")==="none"){M.style("display","none");return}let F=parseFloat(B.style("font-size")),z=28,$=.6,U=6,K=2,ee=Math.max(U,Math.min(z,Math.round(F*$)));M.style("font-size",`${ee}px`);let ce=(I.y1-I.y0)/2+F/2+K;M.attr("y",ce);let Z=I.x1-I.x0,j=I.y1-I.y0-4,ne=Z-2*4;M.node().getComputedTextLength()>ne||ce+ee>j||ee{"use strict";er();lit={sectionStrokeColor:"black",sectionStrokeWidth:"1",sectionFillColor:"#efefef",leafStrokeColor:"black",leafStrokeWidth:"1",leafFillColor:"#efefef",labelColor:"black",labelFontSize:"12px",valueFontSize:"10px",valueColor:"black",titleColor:"black",titleFontSize:"14px"},cit=o(({treemap:t}={})=>{let e=$n(lit,t);return` - .treemapNode.section { - stroke: ${e.sectionStrokeColor}; - stroke-width: ${e.sectionStrokeWidth}; - fill: ${e.sectionFillColor}; - } - .treemapNode.leaf { - stroke: ${e.leafStrokeColor}; - stroke-width: ${e.leafStrokeWidth}; - fill: ${e.leafFillColor}; - } - .treemapLabel { - fill: ${e.labelColor}; - font-size: ${e.labelFontSize}; - } - .treemapValue { - fill: ${e.valueColor}; - font-size: ${e.valueFontSize}; - } - .treemapTitle { - fill: ${e.titleColor}; - font-size: ${e.titleFontSize}; - } - `},"getStyles"),hxe=cit});var dxe={};ur(dxe,{diagram:()=>uit});var uit,pxe=N(()=>{"use strict";r$();lxe();uxe();fxe();uit={parser:n$,get db(){return new by},renderer:cxe,styles:hxe}});var Kit={};ur(Kit,{default:()=>jit});jl();r7();rd();var cK="c4",lAe=o(t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),"detector"),cAe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(lK(),oK));return{id:cK,diagram:t}},"loader"),uAe={id:cK,detector:lAe,loader:cAe},uK=uAe;var use="flowchart",qPe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-wrapper"||e?.flowchart?.defaultRenderer==="elk"?!1:/^\s*graph/.test(t),"detector"),YPe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:use,diagram:t}},"loader"),XPe={id:use,detector:qPe,loader:YPe},hse=XPe;var fse="flowchart-v2",jPe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-d3"?!1:(e?.flowchart?.defaultRenderer==="elk"&&(e.layout="elk"),/^\s*graph/.test(t)&&e?.flowchart?.defaultRenderer==="dagre-wrapper"?!0:/^\s*flowchart/.test(t)),"detector"),KPe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:fse,diagram:t}},"loader"),QPe={id:fse,detector:jPe,loader:KPe},dse=QPe;var wse="er",rBe=o(t=>/^\s*erDiagram/.test(t),"detector"),nBe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Tse(),bse));return{id:wse,diagram:t}},"loader"),iBe={id:wse,detector:rBe,loader:nBe},kse=iBe;var Lhe="gitGraph",IGe=o(t=>/^\s*gitGraph/.test(t),"detector"),OGe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Dhe(),_he));return{id:Lhe,diagram:t}},"loader"),PGe={id:Lhe,detector:IGe,loader:OGe},Rhe=PGe;var ofe="gantt",kVe=o(t=>/^\s*gantt/.test(t),"detector"),EVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(sfe(),afe));return{id:ofe,diagram:t}},"loader"),SVe={id:ofe,detector:kVe,loader:EVe},lfe=SVe;var yfe="info",RVe=o(t=>/^\s*info/.test(t),"detector"),NVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(gfe(),mfe));return{id:yfe,diagram:t}},"loader"),vfe={id:yfe,detector:RVe,loader:NVe};var _fe="pie",WVe=o(t=>/^\s*pie/.test(t),"detector"),qVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Afe(),Cfe));return{id:_fe,diagram:t}},"loader"),Dfe={id:_fe,detector:WVe,loader:qVe};var Vfe="quadrantChart",uUe=o(t=>/^\s*quadrantChart/.test(t),"detector"),hUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Gfe(),zfe));return{id:Vfe,diagram:t}},"loader"),fUe={id:Vfe,detector:uUe,loader:hUe},Ufe=fUe;var gde="xychart",DUe=o(t=>/^\s*xychart-beta/.test(t),"detector"),LUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(mde(),pde));return{id:gde,diagram:t}},"loader"),RUe={id:gde,detector:DUe,loader:LUe},yde=RUe;var Cde="requirement",OUe=o(t=>/^\s*requirement(Diagram)?/.test(t),"detector"),PUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Sde(),Ede));return{id:Cde,diagram:t}},"loader"),BUe={id:Cde,detector:OUe,loader:PUe},Ade=BUe;var Yde="sequence",bHe=o(t=>/^\s*sequenceDiagram/.test(t),"detector"),THe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(qde(),Wde));return{id:Yde,diagram:t}},"loader"),wHe={id:Yde,detector:bHe,loader:THe},Xde=wHe;var epe="class",_He=o((t,e)=>e?.class?.defaultRenderer==="dagre-wrapper"?!1:/^\s*classDiagram/.test(t),"detector"),DHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Jde(),Zde));return{id:epe,diagram:t}},"loader"),LHe={id:epe,detector:_He,loader:DHe},tpe=LHe;var ipe="classDiagram",NHe=o((t,e)=>/^\s*classDiagram/.test(t)&&e?.class?.defaultRenderer==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(t),"detector"),MHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(npe(),rpe));return{id:ipe,diagram:t}},"loader"),IHe={id:ipe,detector:NHe,loader:MHe},ape=IHe;var Ppe="state",aWe=o((t,e)=>e?.state?.defaultRenderer==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(t),"detector"),sWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Ope(),Ipe));return{id:Ppe,diagram:t}},"loader"),oWe={id:Ppe,detector:aWe,loader:sWe},Bpe=oWe;var zpe="stateDiagram",cWe=o((t,e)=>!!(/^\s*stateDiagram-v2/.test(t)||/^\s*stateDiagram/.test(t)&&e?.state?.defaultRenderer==="dagre-wrapper"),"detector"),uWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>($pe(),Fpe));return{id:zpe,diagram:t}},"loader"),hWe={id:zpe,detector:cWe,loader:uWe},Gpe=hWe;var n0e="journey",NWe=o(t=>/^\s*journey/.test(t),"detector"),MWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(r0e(),t0e));return{id:n0e,diagram:t}},"loader"),IWe={id:n0e,detector:NWe,loader:MWe},i0e=IWe;yt();Vl();xi();var OWe=o((t,e,r)=>{X.debug(`rendering svg for syntax error -`);let n=Li(e),i=n.append("g");n.attr("viewBox","0 0 2412 512"),fn(n,100,512,!0),i.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),i.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),i.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),i.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),i.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),i.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),i.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),i.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw"),QP={draw:OWe},a0e=QP;var PWe={db:{},renderer:QP,parser:{parse:o(()=>{},"parse")}},s0e=PWe;var o0e="flowchart-elk",BWe=o((t,e={})=>/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&e?.flowchart?.defaultRenderer==="elk"?(e.layout="elk",!0):!1,"detector"),FWe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(bk(),xk));return{id:o0e,diagram:t}},"loader"),$We={id:o0e,detector:BWe,loader:FWe},l0e=$We;var I0e="timeline",iqe=o(t=>/^\s*timeline/.test(t),"detector"),aqe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(M0e(),N0e));return{id:I0e,diagram:t}},"loader"),sqe={id:I0e,detector:iqe,loader:aqe},O0e=sqe;var uye="mindmap",Let=o(t=>/^\s*mindmap/.test(t),"detector"),Ret=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(cye(),lye));return{id:uye,diagram:t}},"loader"),Net={id:uye,detector:Let,loader:Ret},hye=Net;var kye="kanban",Xet=o(t=>/^\s*kanban/.test(t),"detector"),jet=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(wye(),Tye));return{id:kye,diagram:t}},"loader"),Ket={id:kye,detector:Xet,loader:jet},Eye=Ket;var ave="sankey",xtt=o(t=>/^\s*sankey-beta/.test(t),"detector"),btt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ive(),nve));return{id:ave,diagram:t}},"loader"),Ttt={id:ave,detector:xtt,loader:btt},sve=Ttt;var gve="packet",Itt=o(t=>/^\s*packet(-beta)?/.test(t),"detector"),Ott=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(mve(),pve));return{id:gve,diagram:t}},"loader"),yve={id:gve,detector:Itt,loader:Ott};var _ve="radar",nrt=o(t=>/^\s*radar-beta/.test(t),"detector"),irt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Ave(),Cve));return{id:_ve,diagram:t}},"loader"),Dve={id:_ve,detector:nrt,loader:irt};var N2e="block",Snt=o(t=>/^\s*block-beta/.test(t),"detector"),Cnt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(R2e(),L2e));return{id:N2e,diagram:t}},"loader"),Ant={id:N2e,detector:Snt,loader:Cnt},M2e=Ant;var ixe="architecture",eit=o(t=>/^\s*architecture/.test(t),"detector"),tit=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(nxe(),rxe));return{id:ixe,diagram:t}},"loader"),rit={id:ixe,detector:eit,loader:tit},axe=rit;rd();Gt();var mxe="treemap",hit=o(t=>/^\s*treemap/.test(t),"detector"),fit=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(pxe(),dxe));return{id:mxe,diagram:t}},"loader"),gxe={id:mxe,detector:hit,loader:fit};var yxe=!1,wy=o(()=>{yxe||(yxe=!0,dd("error",s0e,t=>t.toLowerCase().trim()==="error"),dd("---",{db:{clear:o(()=>{},"clear")},styles:{},renderer:{draw:o(()=>{},"draw")},parser:{parse:o(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:o(()=>null,"init")},t=>t.toLowerCase().trimStart().startsWith("---")),Ly(l0e,hye,axe),Ly(uK,Eye,ape,tpe,kse,lfe,vfe,Dfe,Ade,Xde,dse,hse,O0e,Rhe,Gpe,Bpe,i0e,Ufe,sve,yve,yde,M2e,Dve,gxe))},"addDiagrams");yt();rd();Gt();var vxe=o(async()=>{X.debug("Loading registered diagrams");let e=(await Promise.allSettled(Object.entries(au).map(async([r,{detector:n,loader:i}])=>{if(i)try{iv(r)}catch{try{let{diagram:a,id:s}=await i();dd(s,a,n)}catch(a){throw X.error(`Failed to load external diagram with key ${r}. Removing from detectors.`),delete au[r],a}}}))).filter(r=>r.status==="rejected");if(e.length>0){X.error(`Failed to load ${e.length} external diagrams`);for(let r of e)X.error(r);throw new Error(`Failed to load ${e.length} external diagrams`)}},"loadRegisteredDiagrams");yt();fr();var _C="comm",DC="rule",LC="decl";var xxe="@import";var bxe="@namespace",Txe="@keyframes";var wxe="@layer";var i$=Math.abs,B4=String.fromCharCode;function RC(t){return t.trim()}o(RC,"trim");function F4(t,e,r){return t.replace(e,r)}o(F4,"replace");function kxe(t,e,r){return t.indexOf(e,r)}o(kxe,"indexof");function Xf(t,e){return t.charCodeAt(e)|0}o(Xf,"charat");function jf(t,e,r){return t.slice(e,r)}o(jf,"substr");function To(t){return t.length}o(To,"strlen");function Exe(t){return t.length}o(Exe,"sizeof");function ky(t,e){return e.push(t),t}o(ky,"append");var NC=1,Ey=1,Sxe=0,ll=0,Ii=0,Cy="";function MC(t,e,r,n,i,a,s,l){return{value:t,root:e,parent:r,type:n,props:i,children:a,line:NC,column:Ey,length:s,return:"",siblings:l}}o(MC,"node");function Cxe(){return Ii}o(Cxe,"char");function Axe(){return Ii=ll>0?Xf(Cy,--ll):0,Ey--,Ii===10&&(Ey=1,NC--),Ii}o(Axe,"prev");function cl(){return Ii=ll2||Sy(Ii)>3?"":" "}o(Lxe,"whitespace");function Rxe(t,e){for(;--e&&cl()&&!(Ii<48||Ii>102||Ii>57&&Ii<65||Ii>70&&Ii<97););return IC(t,$4()+(e<6&&lh()==32&&cl()==32))}o(Rxe,"escaping");function a$(t){for(;cl();)switch(Ii){case t:return ll;case 34:case 39:t!==34&&t!==39&&a$(Ii);break;case 40:t===41&&a$(t);break;case 92:cl();break}return ll}o(a$,"delimiter");function Nxe(t,e){for(;cl()&&t+Ii!==57;)if(t+Ii===84&&lh()===47)break;return"/*"+IC(e,ll-1)+"*"+B4(t===47?t:cl())}o(Nxe,"commenter");function Mxe(t){for(;!Sy(lh());)cl();return IC(t,ll)}o(Mxe,"identifier");function Pxe(t){return Dxe(PC("",null,null,null,[""],t=_xe(t),0,[0],t))}o(Pxe,"compile");function PC(t,e,r,n,i,a,s,l,u){for(var h=0,f=0,d=s,p=0,m=0,g=0,y=1,v=1,x=1,b=0,T="",S=i,w=a,E=n,_=T;v;)switch(g=b,b=cl()){case 40:if(g!=108&&Xf(_,d-1)==58){kxe(_+=F4(OC(b),"&","&\f"),"&\f",i$(h?l[h-1]:0))!=-1&&(x=-1);break}case 34:case 39:case 91:_+=OC(b);break;case 9:case 10:case 13:case 32:_+=Lxe(g);break;case 92:_+=Rxe($4()-1,7);continue;case 47:switch(lh()){case 42:case 47:ky(dit(Nxe(cl(),$4()),e,r,u),u),(Sy(g||1)==5||Sy(lh()||1)==5)&&To(_)&&jf(_,-1,void 0)!==" "&&(_+=" ");break;default:_+="/"}break;case 123*y:l[h++]=To(_)*x;case 125*y:case 59:case 0:switch(b){case 0:case 125:v=0;case 59+f:x==-1&&(_=F4(_,/\f/g,"")),m>0&&(To(_)-d||y===0&&g===47)&&ky(m>32?Oxe(_+";",n,r,d-1,u):Oxe(F4(_," ","")+";",n,r,d-2,u),u);break;case 59:_+=";";default:if(ky(E=Ixe(_,e,r,h,f,i,l,T,S=[],w=[],d,a),a),b===123)if(f===0)PC(_,e,E,E,S,a,d,l,w);else{switch(p){case 99:if(Xf(_,3)===110)break;case 108:if(Xf(_,2)===97)break;default:f=0;case 100:case 109:case 115:}f?PC(t,E,E,n&&ky(Ixe(t,E,E,0,0,i,l,T,i,S=[],d,w),w),i,w,d,l,n?S:w):PC(_,E,E,E,[""],w,0,l,w)}}h=f=m=0,y=x=1,T=_="",d=s;break;case 58:d=1+To(_),m=g;default:if(y<1){if(b==123)--y;else if(b==125&&y++==0&&Axe()==125)continue}switch(_+=B4(b),b*y){case 38:x=f>0?1:(_+="\f",-1);break;case 44:l[h++]=(To(_)-1)*x,x=1;break;case 64:lh()===45&&(_+=OC(cl())),p=lh(),f=d=To(T=_+=Mxe($4())),b++;break;case 45:g===45&&To(_)==2&&(y=0)}}return a}o(PC,"parse");function Ixe(t,e,r,n,i,a,s,l,u,h,f,d){for(var p=i-1,m=i===0?a:[""],g=Exe(m),y=0,v=0,x=0;y0?m[b]+" "+T:F4(T,/&\f/g,m[b])))&&(u[x++]=S);return MC(t,e,r,i===0?DC:l,u,h,f,d)}o(Ixe,"ruleset");function dit(t,e,r,n){return MC(t,e,r,_C,B4(Cxe()),jf(t,2,-2),0,n)}o(dit,"comment");function Oxe(t,e,r,n,i){return MC(t,e,r,LC,jf(t,0,n),jf(t,n+1,-1),n,i)}o(Oxe,"declaration");function BC(t,e){for(var r="",n=0;n{zxe.forEach(t=>{t()}),zxe=[]},"attachFunctions");yt();var Vxe=o(t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart(),"cleanupComments");Q4();PT();function Uxe(t){let e=t.match(K4);if(!e)return{text:t,metadata:{}};let r=Tm(e[1],{schema:bm})??{};r=typeof r=="object"&&!Array.isArray(r)?r:{};let n={};return r.displayMode&&(n.displayMode=r.displayMode.toString()),r.title&&(n.title=r.title.toString()),r.config&&(n.config=r.config),{text:t.slice(e[0].length),metadata:n}}o(Uxe,"extractFrontMatter");er();var mit=o(t=>t.replace(/\r\n?/g,` -`).replace(/<(\w+)([^>]*)>/g,(e,r,n)=>"<"+r+n.replace(/="([^"]*)"/g,"='$1'")+">"),"cleanupText"),git=o(t=>{let{text:e,metadata:r}=Uxe(t),{displayMode:n,title:i,config:a={}}=r;return n&&(a.gantt||(a.gantt={}),a.gantt.displayMode=n),{title:i,config:a,text:e}},"processFrontmatter"),yit=o(t=>{let e=Vt.detectInit(t)??{},r=Vt.detectDirective(t,"wrap");return Array.isArray(r)?e.wrap=r.some(({type:n})=>n==="wrap"):r?.type==="wrap"&&(e.wrap=!0),{text:Kj(t),directive:e}},"processDirectives");function s$(t){let e=mit(t),r=git(e),n=yit(r.text),i=$n(r.config,n.directive);return t=Vxe(n.text),{code:t,title:r.title,config:i}}o(s$,"preprocessDiagram");TA();n3();er();function Hxe(t){let e=new TextEncoder().encode(t),r=Array.from(e,n=>String.fromCodePoint(n)).join("");return btoa(r)}o(Hxe,"toBase64");var vit=5e4,xit="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa",bit="sandbox",Tit="loose",wit="http://www.w3.org/2000/svg",kit="http://www.w3.org/1999/xlink",Eit="http://www.w3.org/1999/xhtml",Sit="100%",Cit="100%",Ait="border:0;margin:0;",_it="margin:0",Dit="allow-top-navigation-by-user-activation allow-popups",Lit='The "iframe" tag is not supported by your browser.',Rit=["foreignobject"],Nit=["dominant-baseline"];function Xxe(t){let e=s$(t);return $y(),Mz(e.config??{}),e}o(Xxe,"processAndSetConfigs");async function Mit(t,e){wy();try{let{code:r,config:n}=Xxe(t);return{diagramType:(await jxe(r)).type,config:n}}catch(r){if(e?.suppressErrors)return!1;throw r}}o(Mit,"parse");var Wxe=o((t,e,r=[])=>` -.${t} ${e} { ${r.join(" !important; ")} !important; }`,"cssImportantStyles"),Iit=o((t,e=new Map)=>{let r="";if(t.themeCSS!==void 0&&(r+=` -${t.themeCSS}`),t.fontFamily!==void 0&&(r+=` -:root { --mermaid-font-family: ${t.fontFamily}}`),t.altFontFamily!==void 0&&(r+=` -:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),e instanceof Map){let s=t.htmlLabels??t.flowchart?.htmlLabels?["> *","span"]:["rect","polygon","ellipse","circle","path"];e.forEach(l=>{hr(l.styles)||s.forEach(u=>{r+=Wxe(l.id,u,l.styles)}),hr(l.textStyles)||(r+=Wxe(l.id,"tspan",(l?.textStyles||[]).map(u=>u.replace("color","fill"))))})}return r},"createCssStyles"),Oit=o((t,e,r,n)=>{let i=Iit(t,r),a=MV(e,i,t.themeVariables);return BC(Pxe(`${n}{${a}}`),Bxe)},"createUserStyles"),Pit=o((t="",e,r)=>{let n=t;return!r&&!e&&(n=n.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),n=na(n),n=n.replace(/
    /g,"
    "),n},"cleanUpSvgCode"),Bit=o((t="",e)=>{let r=e?.viewBox?.baseVal?.height?e.viewBox.baseVal.height+"px":Cit,n=Hxe(`${t}`);return``},"putIntoIFrame"),qxe=o((t,e,r,n,i)=>{let a=t.append("div");a.attr("id",r),n&&a.attr("style",n);let s=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns",wit);return i&&s.attr("xmlns:xlink",i),s.append("g"),t},"appendDivSvgG");function Yxe(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}o(Yxe,"sandboxedIframe");var Fit=o((t,e,r,n)=>{t.getElementById(e)?.remove(),t.getElementById(r)?.remove(),t.getElementById(n)?.remove()},"removeExistingElements"),$it=o(async function(t,e,r){wy();let n=Xxe(e);e=n.code;let i=tr();X.debug(i),e.length>(i?.maxTextSize??vit)&&(e=xit);let a="#"+t,s="i"+t,l="#"+s,u="d"+t,h="#"+u,f=o(()=>{let L=Ge(p?l:h).node();L&&"remove"in L&&L.remove()},"removeTempElements"),d=Ge("body"),p=i.securityLevel===bit,m=i.securityLevel===Tit,g=i.fontFamily;if(r!==void 0){if(r&&(r.innerHTML=""),p){let k=Yxe(Ge(r),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge(r);qxe(d,t,u,`font-family: ${g}`,kit)}else{if(Fit(document,t,u,s),p){let k=Yxe(Ge("body"),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge("body");qxe(d,t,u)}let y,v;try{y=await Ay.fromText(e,{title:n.title})}catch(k){if(i.suppressErrorRendering)throw f(),k;y=await Ay.fromText("error"),v=k}let x=d.select(h).node(),b=y.type,T=x.firstChild,S=T.firstChild,w=y.renderer.getClasses?.(e,y),E=Oit(i,b,w,a),_=document.createElement("style");_.innerHTML=E,T.insertBefore(_,S);try{await y.renderer.draw(e,t,Db.version,y)}catch(k){throw i.suppressErrorRendering?f():a0e.draw(e,t,Db.version),k}let C=d.select(`${h} svg`),D=y.db.getAccTitle?.(),O=y.db.getAccDescription?.();Git(b,C,D,O),d.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",Eit);let R=d.select(h).node().innerHTML;if(X.debug("config.arrowMarkerAbsolute",i.arrowMarkerAbsolute),R=Pit(R,p,dr(i.arrowMarkerAbsolute)),p){let k=d.select(h+" svg").node();R=Bit(R,k)}else m||(R=mh.sanitize(R,{ADD_TAGS:Rit,ADD_ATTR:Nit,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));if(Gxe(),v)throw v;return f(),{diagramType:b,svg:R,bindFunctions:y.db.bindFunctions}},"render");function zit(t={}){let e=Un({},t);e?.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables||(e.themeVariables={}),e.themeVariables.fontFamily=e.fontFamily),Lz(e),e?.theme&&e.theme in Eo?e.themeVariables=Eo[e.theme].getThemeVariables(e.themeVariables):e&&(e.themeVariables=Eo.default.getThemeVariables(e.themeVariables));let r=typeof e=="object"?T7(e):w7();Dy(r.logLevel),wy()}o(zit,"initialize");var jxe=o((t,e={})=>{let{code:r}=s$(t);return Ay.fromText(r,e)},"getDiagramFromText");function Git(t,e,r,n){Fxe(e,t),$xe(e,r,n,e.attr("id"))}o(Git,"addA11yInfo");var Kf=Object.freeze({render:$it,parse:Mit,getDiagramFromText:jxe,initialize:zit,getConfig:tr,setConfig:a3,getSiteConfig:w7,updateSiteConfig:Rz,reset:o(()=>{$y()},"reset"),globalReset:o(()=>{$y(ph)},"globalReset"),defaultConfig:ph});Dy(tr().logLevel);$y(tr());rp();er();var Vit=o((t,e,r)=>{X.warn(t),I9(t)?(r&&r(t.str,t.hash),e.push({...t,message:t.str,error:t})):(r&&r(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),Kxe=o(async function(t={querySelector:".mermaid"}){try{await Uit(t)}catch(e){if(I9(e)&&X.error(e.str),ch.parseError&&ch.parseError(e),!t.suppressErrors)throw X.error("Use the suppressErrors option to suppress these errors"),e}},"run"),Uit=o(async function({postRenderCallback:t,querySelector:e,nodes:r}={querySelector:".mermaid"}){let n=Kf.getConfig();X.debug(`${t?"":"No "}Callback function found`);let i;if(r)i=r;else if(e)i=document.querySelectorAll(e);else throw new Error("Nodes and querySelector are both undefined");X.debug(`Found ${i.length} diagrams`),n?.startOnLoad!==void 0&&(X.debug("Start On Load: "+n?.startOnLoad),Kf.updateSiteConfig({startOnLoad:n?.startOnLoad}));let a=new Vt.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed),s,l=[];for(let u of Array.from(i)){X.info("Rendering diagram: "+u.id);if(u.getAttribute("data-processed"))continue;u.setAttribute("data-processed","true");let h=`mermaid-${a.next()}`;s=u.innerHTML,s=j4(Vt.entityDecode(s)).trim().replace(//gi,"
    ");let f=Vt.detectInit(s);f&&X.debug("Detected early reinit: ",f);try{let{svg:d,bindFunctions:p}=await ebe(h,s,u);u.innerHTML=d,t&&await t(h),p&&p(u)}catch(d){Vit(d,l,ch.parseError)}}if(l.length>0)throw l[0]},"runThrowsErrors"),Qxe=o(function(t){Kf.initialize(t)},"initialize"),Hit=o(async function(t,e,r){X.warn("mermaid.init is deprecated. Please use run instead."),t&&Qxe(t);let n={postRenderCallback:r,querySelector:".mermaid"};typeof e=="string"?n.querySelector=e:e&&(e instanceof HTMLElement?n.nodes=[e]:n.nodes=e),await Kxe(n)},"init"),Wit=o(async(t,{lazyLoad:e=!0}={})=>{wy(),Ly(...t),e===!1&&await vxe()},"registerExternalDiagrams"),Zxe=o(function(){if(ch.startOnLoad){let{startOnLoad:t}=Kf.getConfig();t&&ch.run().catch(e=>X.error("Mermaid failed to initialize",e))}},"contentLoaded");if(typeof document<"u"){window.addEventListener("load",Zxe,!1)}var qit=o(function(t){ch.parseError=t},"setParseErrorHandler"),FC=[],o$=!1,Jxe=o(async()=>{if(!o$){for(o$=!0;FC.length>0;){let t=FC.shift();if(t)try{await t()}catch(e){X.error("Error executing queue",e)}}o$=!1}},"executeQueue"),Yit=o(async(t,e)=>new Promise((r,n)=>{let i=o(()=>new Promise((a,s)=>{Kf.parse(t,e).then(l=>{a(l),r(l)},l=>{X.error("Error parsing",l),ch.parseError?.(l),s(l),n(l)})}),"performCall");FC.push(i),Jxe().catch(n)}),"parse"),ebe=o((t,e,r)=>new Promise((n,i)=>{let a=o(()=>new Promise((s,l)=>{Kf.render(t,e,r).then(u=>{s(u),n(u)},u=>{X.error("Error parsing",u),ch.parseError?.(u),l(u),i(u)})}),"performCall");FC.push(a),Jxe().catch(i)}),"render"),Xit=o(()=>Object.keys(au).map(t=>({id:t})),"getRegisteredDiagramsMetadata"),ch={startOnLoad:!0,mermaidAPI:Kf,parse:Yit,render:ebe,init:Hit,run:Kxe,registerExternalDiagrams:Wit,registerLayoutLoaders:tN,initialize:Qxe,parseError:void 0,contentLoaded:Zxe,setParseErrorHandler:qit,detectType:m0,registerIconPacks:X4,getRegisteredDiagramsMetadata:Xit},jit=ch;return ube(Kit);})(); -/*! Check if previously processed */ -/*! - * Wait for document loaded before starting the execution - */ -/*! Bundled license information: - -dompurify/dist/purify.es.mjs: - (*! @license DOMPurify 3.2.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.5/LICENSE *) - -js-yaml/dist/js-yaml.mjs: - (*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT *) - -lodash-es/lodash.js: - (** - * @license - * Lodash (Custom Build) - * Build: `lodash modularize exports="es" -o ./` - * Copyright OpenJS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - *) - -cytoscape/dist/cytoscape.esm.mjs: - (*! - Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable - Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) - Licensed under The MIT License (http://opensource.org/licenses/MIT) - *) - (*! - Event object based on jQuery events, MIT license - - https://jquery.org/license/ - https://tldrlegal.com/license/mit-license - https://github.com/jquery/jquery/blob/master/src/event.js - *) - (*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License *) - (*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License *) -*/ -globalThis["mermaid"] = globalThis.__esbuild_esm_mermaid_nm["mermaid"].default; \ No newline at end of file diff --git a/docs/public/reference/configuration/index.html b/docs/public/reference/configuration/index.html deleted file mode 100644 index d41db60..0000000 --- a/docs/public/reference/configuration/index.html +++ /dev/null @@ -1,200 +0,0 @@ -Configuration Reference | dhamps-vdb Documentation - -

    Configuration Reference#

    Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.

    Overview#

    dhamps-vdb is configured through a combination of:

    1. Environment variables (recommended)
    2. Command-line flags (overrides environment variables)
    3. .env files (for Docker and local development)

    Configuration is loaded in the following priority order (highest to lowest):

    1. Command-line flags
    2. Environment variables
    3. .env file values
    4. Default values from options.go

    Configuration Options#

    Service Configuration#

    Options for controlling the API service behavior.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    DebugSERVICE_DEBUG-d, --debugBooleantrueNoEnable verbose debug logging
    HostSERVICE_HOST--hostStringlocalhostNoHostname or IP to bind to
    PortSERVICE_PORT-p, --portInteger8880NoPort number to listen on

    Debug Mode:

    • true - Detailed logs including SQL queries, request details, internal operations
    • false - Minimal logs for production use

    Host Configuration:

    • localhost - Local development only
    • 0.0.0.0 - Listen on all interfaces (required for Docker)
    • Specific IP - Bind to particular network interface

    Port Configuration:

    • Default: 8880
    • Ports below 1024 require elevated privileges
    • Ensure port is not in use by another service

    Database Configuration#

    Options for connecting to the PostgreSQL database with pgvector extension.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    DB HostSERVICE_DBHOST--db-hostStringlocalhostYesPostgreSQL server hostname
    DB PortSERVICE_DBPORT--db-portInteger5432NoPostgreSQL server port
    DB UserSERVICE_DBUSER--db-userStringpostgresYesDatabase username
    DB PasswordSERVICE_DBPASSWORD--db-passwordStringpasswordYesDatabase password
    DB NameSERVICE_DBNAME--db-nameStringpostgresYesDatabase name

    Database Requirements:

    • PostgreSQL 12+ (16+ recommended)
    • pgvector extension installed and enabled
    • User must have CREATE, ALTER, DROP, INSERT, SELECT, UPDATE, DELETE privileges
    • Database must exist before starting dhamps-vdb

    Common Database Hosts:

    • localhost - Local PostgreSQL instance
    • postgres - Docker Compose service name
    • db.example.com - Remote database server
    • IP address - Direct connection to database

    Security Configuration#

    Critical security settings for authentication and encryption.

    OptionEnvironment VariableCLI FlagTypeDefaultRequiredDescription
    Admin KeySERVICE_ADMINKEY--admin-keyString-YesMaster API key for admin operations
    Encryption KeyENCRYPTION_KEY-String-YesAES-256 key for API key encryption

    Admin Key (SERVICE_ADMINKEY):

    • Master API key with full administrative privileges
    • Used to create users and manage global resources
    • Generate with: openssl rand -base64 32
    • Must be kept secure and rotated regularly
    • Transmitted via Authorization: Bearer header

    Encryption Key (ENCRYPTION_KEY):

    • Used to encrypt user API keys in the database
    • Minimum 32 characters required
    • Uses AES-256-GCM encryption with SHA-256 hashing
    • CRITICAL: If lost, all stored API keys become unrecoverable
    • Cannot be changed without re-encrypting all existing API keys
    • Generate with: openssl rand -hex 32
    • Must be backed up securely and separately from database

    Configuration Files#

    .env File#

    The recommended way to configure dhamps-vdb. Create a .env file in the project root:

    # Copy template
    -cp template.env .env
    -
    -# Edit with your values
    -nano .env

    Example .env file:

    # Service Configuration
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -
    -# Database Configuration
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=secure_password_here
    -SERVICE_DBNAME=dhamps_vdb
    -
    -# Security Configuration
    -SERVICE_ADMINKEY=generated_admin_key_here
    -ENCRYPTION_KEY=generated_encryption_key_min_32_chars

    Security Notes:

    • .env files are in .gitignore by default
    • Never commit .env files to version control
    • Set restrictive permissions: chmod 600 .env
    • Use different keys for dev/staging/production

    template.env#

    Starting template for configuration:

    #!/usr/bin/env bash
    -
    -SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8888
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=postgres
    -SERVICE_DBNAME=postgres
    -SERVICE_ADMINKEY=Ch4ngeM3!
    -
    -# Encryption key for API keys in LLM service instances
    -# Must be secure random string, at least 32 characters
    -# Generate with: openssl rand -hex 32
    -ENCRYPTION_KEY=ChangeThisToASecureRandomKey123456789012

    Docker Configuration#

    Docker Compose#

    The docker-compose.yml file defines the full stack including PostgreSQL:

    services:
    -  postgres:
    -    image: pgvector/pgvector:0.7.4-pg16
    -    environment:
    -      POSTGRES_USER: ${SERVICE_DBUSER:-postgres}
    -      POSTGRES_PASSWORD: ${SERVICE_DBPASSWORD:-postgres}
    -      POSTGRES_DB: ${SERVICE_DBNAME:-dhamps_vdb}
    -    ports:
    -      - "${POSTGRES_PORT:-5432}:5432"
    -    volumes:
    -      - postgres_data:/var/lib/postgresql/data
    -
    -  dhamps-vdb:
    -    build:
    -      context: .
    -      dockerfile: Dockerfile
    -    depends_on:
    -      postgres:
    -        condition: service_healthy
    -    environment:
    -      SERVICE_DEBUG: ${SERVICE_DEBUG:-false}
    -      SERVICE_HOST: ${SERVICE_HOST:-0.0.0.0}
    -      SERVICE_PORT: ${SERVICE_PORT:-8880}
    -      SERVICE_DBHOST: ${SERVICE_DBHOST:-postgres}
    -      SERVICE_DBPORT: ${SERVICE_DBPORT:-5432}
    -      SERVICE_DBUSER: ${SERVICE_DBUSER:-postgres}
    -      SERVICE_DBPASSWORD: ${SERVICE_DBPASSWORD:-postgres}
    -      SERVICE_DBNAME: ${SERVICE_DBNAME:-dhamps_vdb}
    -      SERVICE_ADMINKEY: ${SERVICE_ADMINKEY}
    -      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
    -    ports:
    -      - "${API_PORT:-8880}:8880"

    Docker-Specific Variables:

    • POSTGRES_PORT - External port for PostgreSQL (default: 5432)
    • API_PORT - External port for dhamps-vdb API (default: 8880)

    Docker Setup Script#

    Automated setup using docker-setup.sh:

    # Run automated setup (generates secure keys)
    -./docker-setup.sh
    -
    -# Start services
    -docker-compose up -d
    -
    -# View logs
    -docker-compose logs -f dhamps-vdb

    The script automatically:

    • Generates secure SERVICE_ADMINKEY
    • Generates secure ENCRYPTION_KEY
    • Creates .env file with proper configuration
    • Validates Docker and docker-compose installation

    Docker Run Command#

    For standalone container deployment:

    docker run -d \
    -  --name dhamps-vdb \
    -  -e SERVICE_DEBUG=false \
    -  -e SERVICE_HOST=0.0.0.0 \
    -  -e SERVICE_PORT=8880 \
    -  -e SERVICE_DBHOST=db.example.com \
    -  -e SERVICE_DBPORT=5432 \
    -  -e SERVICE_DBUSER=dhamps_user \
    -  -e SERVICE_DBPASSWORD=secure_password \
    -  -e SERVICE_DBNAME=dhamps_vdb \
    -  -e SERVICE_ADMINKEY=admin_key_here \
    -  -e ENCRYPTION_KEY=encryption_key_here \
    -  -p 8880:8880 \
    -  dhamps-vdb:latest

    External Database#

    Using docker-compose.external-db.yml for external PostgreSQL:

    # Set database connection in .env
    -SERVICE_DBHOST=db.external.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=secure_password
    -SERVICE_DBNAME=dhamps_vdb
    -
    -# Start without bundled PostgreSQL
    -docker-compose -f docker-compose.external-db.yml up -d

    Configuration Scenarios#

    Development Environment#

    Optimized for local development with verbose logging:

    # .env for development
    -SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=localhost
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=postgres
    -SERVICE_DBNAME=dhamps_vdb_dev
    -SERVICE_ADMINKEY=dev-admin-key-not-for-production
    -ENCRYPTION_KEY=dev-encryption-key-at-least-32-chars

    Start service:

    ./dhamps-vdb

    Docker Development#

    Docker-based development with hot reload:

    # .env for Docker development
    -SERVICE_DEBUG=true
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=postgres
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=postgres
    -SERVICE_DBPASSWORD=postgres
    -SERVICE_DBNAME=dhamps_vdb
    -SERVICE_ADMINKEY=dev-admin-key
    -ENCRYPTION_KEY=dev-encryption-32-chars-minimum

    Start with:

    docker-compose up

    Production Environment#

    Production-ready configuration with security hardening:

    # .env for production
    -SERVICE_DEBUG=false
    -SERVICE_HOST=0.0.0.0
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=prod-db.internal.example.com
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_prod_user
    -SERVICE_DBPASSWORD=<from-secrets-manager>
    -SERVICE_DBNAME=dhamps_vdb_prod
    -SERVICE_ADMINKEY=<from-secrets-manager>
    -ENCRYPTION_KEY=<from-secrets-manager>

    Production Best Practices:

    • Use secrets management (Vault, AWS Secrets Manager, etc.)
    • Disable debug logging (SERVICE_DEBUG=false)
    • Use dedicated database user (not superuser)
    • Enable SSL/TLS for database connections
    • Deploy behind reverse proxy (nginx, Traefik)
    • Set up monitoring and alerting
    • Regular key rotation (except ENCRYPTION_KEY)
    • Firewall rules to restrict access

    Testing Environment#

    Configuration for running tests:

    # Tests use testcontainers - no external config needed
    -go test -v ./...

    Test-specific setup:

    # Enable Docker for testcontainers
    -systemctl --user start podman.socket
    -export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
    -
    -# Run tests
    -go test -v ./...

    Validation and Verification#

    Startup Validation#

    dhamps-vdb validates configuration on startup:

    1. Required variables check - Fails if missing
    2. Database connection test - Verifies connectivity
    3. Schema migration - Applies pending migrations
    4. Extension check - Verifies pgvector is available

    Configuration Test#

    Verify configuration is working:

    # Check service health
    -curl http://localhost:8880/docs
    -
    -# Test admin authentication
    -curl -X GET http://localhost:8880/v1/users \
    -  -H "Authorization: Bearer ${SERVICE_ADMINKEY}"
    -
    -# Check database connectivity
    -docker-compose exec dhamps-vdb echo "Config OK"

    Common Issues#

    Missing Required Variables:

    Error: SERVICE_ADMINKEY environment variable is not set

    Solution: Set all required variables.

    Database Connection Failed:

    Error: failed to connect to database

    Solution: Verify SERVICE_DBHOST, credentials, and that PostgreSQL is running.

    Invalid Encryption Key:

    Error: ENCRYPTION_KEY must be at least 32 characters

    Solution: Generate proper key with openssl rand -hex 32.

    Port Already in Use:

    Error: bind: address already in use

    Solution: Change SERVICE_PORT or stop conflicting service.

    Generating Secure Keys#

    Admin Key Generation#

    # Base64 encoded (recommended)
    -openssl rand -base64 32
    -
    -# Hex encoded (alternative)
    -openssl rand -hex 24
    -
    -# Output example:
    -# Kx7mP9nQ2rT5vY8zA1bC4dF6gH9jK0lM3nP5qR7sT9u=

    Encryption Key Generation#

    # 32-byte hex key (required format)
    -openssl rand -hex 32
    -
    -# Output example:
    -# a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6

    Secure Key Storage#

    Development:

    • Store in .env file (not committed)
    • Use password manager for team sharing

    Production:

    • Use secrets management system
    • Rotate admin key every 90 days
    • Never rotate encryption key (breaks existing API keys)
    • Store encryption key backup separately from database

    Environment-Specific Examples#

    Local with External PostgreSQL#

    SERVICE_DEBUG=true
    -SERVICE_HOST=localhost
    -SERVICE_PORT=8880
    -SERVICE_DBHOST=192.168.1.100
    -SERVICE_DBPORT=5432
    -SERVICE_DBUSER=dhamps_user
    -SERVICE_DBPASSWORD=user_password
    -SERVICE_DBNAME=dhamps_vdb
    -SERVICE_ADMINKEY=$(openssl rand -base64 32)
    -ENCRYPTION_KEY=$(openssl rand -hex 32)

    Kubernetes ConfigMap + Secrets#

    ConfigMap:

    apiVersion: v1
    -kind: ConfigMap
    -metadata:
    -  name: dhamps-vdb-config
    -data:
    -  SERVICE_DEBUG: "false"
    -  SERVICE_HOST: "0.0.0.0"
    -  SERVICE_PORT: "8880"
    -  SERVICE_DBHOST: "postgres-service"
    -  SERVICE_DBPORT: "5432"
    -  SERVICE_DBUSER: "dhamps_user"
    -  SERVICE_DBNAME: "dhamps_vdb"

    Secrets:

    apiVersion: v1
    -kind: Secret
    -metadata:
    -  name: dhamps-vdb-secrets
    -type: Opaque
    -stringData:
    -  SERVICE_DBPASSWORD: "secure_db_password"
    -  SERVICE_ADMINKEY: "secure_admin_key"
    -  ENCRYPTION_KEY: "secure_encryption_key_32_chars_min"

    Docker Swarm Secrets#

    # Create secrets
    -echo "admin_key_here" | docker secret create dhamps_admin_key -
    -echo "encryption_key" | docker secret create dhamps_encryption_key -
    -
    -# Reference in stack file
    -services:
    -  dhamps-vdb:
    -    secrets:
    -      - dhamps_admin_key
    -      - dhamps_encryption_key
    -    environment:
    -      SERVICE_ADMINKEY_FILE: /run/secrets/dhamps_admin_key
    -      ENCRYPTION_KEY_FILE: /run/secrets/dhamps_encryption_key
    \ No newline at end of file diff --git a/docs/public/reference/database-schema/index.html b/docs/public/reference/database-schema/index.html deleted file mode 100644 index 12de6e1..0000000 --- a/docs/public/reference/database-schema/index.html +++ /dev/null @@ -1,67 +0,0 @@ -Database Schema Reference | dhamps-vdb Documentation - -

    Database Schema Reference#

    Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.

    Overview#

    The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in internal/database/migrations/.

    Key Features:

    • Vector embeddings stored as halfvec for efficient storage
    • HNSW indexes for fast approximate nearest neighbor search
    • Automatic timestamp tracking (created_at, updated_at)
    • Foreign key constraints with CASCADE deletion
    • Role-based access control through association tables
    • Multi-tenancy support (user-owned resources)

    Schema Migrations#

    Current schema version is defined by 4 migration files:

    1. 001_create_initial_scheme.sql - Core tables and relationships
    2. 002_create_emb_index.sql - HNSW vector indexes
    3. 003_add_public_read_flag.sql - Public access support
    4. 004_refactor_llm_services_architecture.sql - LLM service architecture refactor

    Core Tables#

    users#

    Stores user accounts with API authentication.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)PRIMARY KEYUnique user identifier (username)
    nameTEXTFull name or display name
    emailTEXTUNIQUE, NOT NULLEmail address
    vdb_keyCHAR(64)UNIQUE, NOT NULLAPI key (64-character hex)
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Indexes:

    • Primary key on user_handle
    • Unique constraint on email
    • Unique constraint on vdb_key

    Special Users:

    • _system - Reserved system user for global LLM service definitions

    Relationships:

    • Owns projects (1:N)
    • Owns LLM service instances (1:N)
    • Owns embeddings (1:N)
    • Can share projects (N:M via users_projects)
    • Can share LLM service instances (N:M via instances_shared_with)

    Notes:

    • vdb_key is generated during user creation and returned once
    • Cannot be recovered if lost
    • Transmitted as Authorization: Bearer token

    projects#

    Stores embedding projects owned by users.

    ColumnTypeConstraintsDescription
    project_idSERIALPRIMARY KEYAuto-incrementing project ID
    project_handleVARCHAR(20)NOT NULLProject identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersProject owner user handle
    descriptionTEXTProject description
    metadata_schemeTEXTJSON Schema for validating embedding metadata
    public_readBOOLEANDEFAULT FALSEAllow unauthenticated read access
    instance_idINTEGERFK→instancesLLM service instance used for embeddings
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, project_handle) - Project handles unique per owner
    • ON DELETE CASCADE - Delete project when owner deleted
    • ON DELETE RESTRICT - Prevent instance deletion if used by project

    Relationships:

    • Owned by one user (N:1)
    • Uses one LLM service instance (N:1)
    • Has many embeddings (1:N)
    • Can be shared with users (N:M via users_projects)

    Metadata Schema:

    • Stored as JSON Schema string
    • Used to validate embedding metadata
    • Optional (can be NULL)
    • See Data Validation for details

    Public Access:

    • When public_read=TRUE, allows unauthenticated embedding queries
    • Controlled via API or by setting shared_with to ["*"]

    embeddings#

    Stores vector embeddings with text identifiers and metadata.

    ColumnTypeConstraintsDescription
    embeddings_idSERIALPRIMARY KEYAuto-incrementing embedding ID
    text_idTEXTINDEXEDText identifier (URL, DOI, custom ID)
    ownerVARCHAR(20)NOT NULL, FK→usersEmbedding owner user handle
    project_idSERIALNOT NULL, FK→projectsProject the embedding belongs to
    instance_idSERIALNOT NULL, FK→instancesLLM service instance used
    textTEXTOptional full text of the embedded content
    vectorhalfvecNOT NULLEmbedding vector (half-precision float)
    vector_dimINTEGERNOT NULLVector dimensionality
    metadatajsonbOptional metadata (validated if schema defined)
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (text_id, owner, project_id, instance_id) - Unique text IDs per project/instance
    • ON DELETE CASCADE - Delete embeddings when owner, project, or instance deleted

    Indexes:

    • Primary key on embeddings_id
    • B-tree index on text_id
    • HNSW vector indexes for dimensions: 384, 768, 1024, 1536, 3072 (see Vector Indexes)

    Vector Storage:

    • Uses halfvec type (16-bit floating point) for efficient storage
    • Dimensions must match LLM service instance configuration
    • Validated on upload against instance dimensions

    Relationships:

    • Owned by one user (N:1)
    • Belongs to one project (N:1)
    • Created with one LLM service instance (N:1)

    LLM Service Architecture#

    The LLM service architecture separates service definitions (templates) from user-specific instances.

    definitions#

    Templates for LLM embedding services (shared or user-specific).

    ColumnTypeConstraintsDescription
    definition_idSERIALPRIMARY KEYAuto-incrementing definition ID
    definition_handleVARCHAR(20)NOT NULLDefinition identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersDefinition owner (_system for global)
    endpointTEXTNOT NULLAPI endpoint URL
    descriptionTEXTService description
    api_standardVARCHAR(20)NOT NULL, FK→api_standardsAPI standard handle
    modelTEXTNOT NULLModel name (e.g., text-embedding-3-large)
    dimensionsINTEGERNOT NULLVector dimensions produced by model
    context_limitINTEGERNOT NULLMaximum context length (tokens/chars)
    is_publicBOOLEANNOT NULL, DEFAULT FALSEShare with all users if true
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, definition_handle) - Definition handles unique per owner
    • ON DELETE CASCADE - Delete definition when owner deleted

    Built-in Definitions:

    System-provided definitions (owned by _system, is_public=TRUE):

    HandleModelDimensionsContext LimitAPI Standard
    openai-largetext-embedding-3-large30728192openai
    openai-smalltext-embedding-3-small15368191openai
    cohere-v4embed-v4.01536128000cohere
    gemini-embedding-001gemini-embedding-00130722048gemini

    Relationships:

    • Owned by one user (N:1)
    • References one API standard (N:1)
    • Can be shared with users (N:M via definitions_shared_with)
    • Used by instances (1:N)

    instances#

    User-specific configurations of LLM services with API keys.

    ColumnTypeConstraintsDescription
    instance_idSERIALPRIMARY KEYAuto-incrementing instance ID
    instance_handleVARCHAR(20)NOT NULLInstance identifier (unique per owner)
    ownerVARCHAR(20)NOT NULL, FK→usersInstance owner user handle
    endpointTEXTNOT NULLAPI endpoint URL
    descriptionTEXTInstance description
    api_standardVARCHAR(20)NOT NULL, FK→api_standardsAPI standard handle
    modelTEXTNOT NULLModel name
    dimensionsINTEGERNOT NULLVector dimensions
    context_limitINTEGERNOT NULLMaximum context length
    definition_idINTEGERFK→definitionsReference to definition template
    api_key_encryptedBYTEAEncrypted API key for service authentication
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • UNIQUE (owner, instance_handle) - Instance handles unique per owner
    • ON DELETE CASCADE - Delete instance when owner deleted
    • ON DELETE SET NULL - Keep instance if definition deleted

    Indexes:

    • Composite index on (owner, instance_handle)

    API Key Encryption:

    • Encrypted using AES-256-GCM
    • Encryption key from ENCRYPTION_KEY environment variable
    • Cannot be recovered if encryption key is lost
    • Stored as base64-encoded BYTEA

    Relationships:

    • Owned by one user (N:1)
    • References one API standard (N:1)
    • Based on one definition template (N:1, optional)
    • Used by projects (1:N)
    • Used by embeddings (1:N)
    • Can be shared with users (N:M via instances_shared_with)

    api_standards#

    Defines API specifications for LLM embedding services.

    ColumnTypeConstraintsDescription
    api_standard_handleVARCHAR(20)PRIMARY KEYStandard identifier (e.g., openai, cohere)
    descriptionTEXTAPI description and version info
    key_methodVARCHAR(20)NOT NULL, FK→key_methodsAuthentication method
    key_fieldVARCHAR(20)Header/field name for API key
    created_atTIMESTAMPNOT NULLCreation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Built-in Standards:

    HandleDescriptionKey MethodKey Field
    openaiOpenAI Embeddings API v1auth_bearerAuthorization
    cohereCohere Embed API v2auth_bearerAuthorization
    geminiGemini Embeddings APIauth_bearerx-goog-api-key

    Relationships:

    • Used by definitions (1:N)
    • Used by instances (1:N)
    • References one key_method (N:1)

    Association Tables#

    users_projects#

    Defines project sharing and access control.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    project_idSERIALFK→projects, PKProject being shared
    roleVARCHAR(20)NOT NULL, FK→vdb_rolesAccess level (owner/editor/reader)
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, project_id) - One role per user per project
    • ON DELETE CASCADE - Remove sharing when user or project deleted

    Roles:

    • owner - Full control (only project creator)
    • editor - Can add/modify/delete embeddings
    • reader - Read-only access to embeddings

    instances_shared_with#

    Defines LLM service instance sharing.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    instance_idINTEGERFK→instances, PKInstance being shared
    roleVARCHAR(20)NOT NULL, FK→vdb_rolesAccess level
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, instance_id) - One role per user per instance
    • ON DELETE CASCADE - Remove sharing when user or instance deleted

    definitions_shared_with#

    Defines LLM service definition sharing.

    ColumnTypeConstraintsDescription
    user_handleVARCHAR(20)FK→users, PKUser being granted access
    definition_idINTEGERFK→definitions, PKDefinition being shared
    created_atTIMESTAMPNOT NULLShare creation timestamp
    updated_atTIMESTAMPNOT NULLLast update timestamp

    Constraints:

    • PRIMARY KEY (user_handle, definition_id) - One share per user per definition
    • ON DELETE CASCADE - Remove sharing when user or definition deleted

    Indexes:

    • Index on user_handle for efficient user lookups
    • Index on definition_id for efficient definition lookups

    Reference Tables#

    vdb_roles#

    Enumeration of valid access roles.

    ColumnTypeConstraintsDescription
    vdb_roleVARCHAR(20)PRIMARY KEYRole name

    Values:

    • owner - Full control over resource
    • editor - Read and write access
    • reader - Read-only access

    key_methods#

    Enumeration of API authentication methods.

    ColumnTypeConstraintsDescription
    key_methodVARCHAR(20)PRIMARY KEYAuthentication method

    Values:

    • auth_bearer - Bearer token in Authorization header
    • body_form - API key in request body
    • query_param - API key in URL query parameter
    • custom_header - API key in custom header

    Vector Indexes#

    HNSW (Hierarchical Navigable Small World) indexes for fast approximate nearest neighbor search.

    Index Configuration#

    All vector indexes use HNSW with these parameters:

    • m = 24 - Number of neighbors per node
    • ef_construction = 200 - Build-time accuracy parameter
    • ef_search = 100 - Query-time accuracy parameter
    • Expected recall: ~99.8%

    Dimension-Specific Indexes#

    Index NameDimensionsCommon Models
    embeddings_vector_384384Cohere embed-multilingual-light-v3.0, embed-english-light-v3.0
    embeddings_vector_768768BERT base, Cohere embed-multilingual-v2.0, Gemini Embeddings
    embeddings_vector_10241024BERT large, SBERT, Cohere embed-multilingual-v3.0, embed-english-v3.0
    embeddings_vector_15361536OpenAI text-embedding-ada-002, text-embedding-3-small, Cohere embed-v4.0
    embeddings_vector_30723072OpenAI text-embedding-3-large, Gemini embedding-001

    Index Structure:

    CREATE INDEX embeddings_vector_1536 ON embeddings 
    -USING hnsw ((vector::halfvec(1536)) halfvec_cosine_ops) 
    -WITH (m = 24, ef_construction = 200) 
    -WHERE (vector_dim = 1536);

    Usage:

    • Indexes are partial - only include vectors of matching dimension
    • Automatically used for similarity queries with matching dimensions
    • Use cosine distance for similarity calculation

    Relationships Diagram#

    users (1) ──owns──> (N) projects (1) ──contains──> (N) embeddings
    -  │                      │                              │
    -  │                      └─> uses (1) instances (N) <───┘
    -  │                                    │
    -  │                                    └─> based on (1) definitions
    -  │                                              │
    -  ├──owns──> (N) instances ──uses──> (1) api_standards
    -  │               │                          │
    -  │               └─> references (1) definitions
    -  │
    -  └──owns──> (N) definitions ──references──> (1) api_standards
    -
    -Sharing:
    -  users (N) <──shares─> (M) projects (via users_projects)
    -  users (N) <──shares─> (M) instances (via instances_shared_with)
    -  users (N) <──shares─> (M) definitions (via definitions_shared_with)

    Data Validation#

    Dimension Validation#

    Embeddings must have dimensions matching their LLM service instance:

    • embeddings.vector_dim must equal instances.dimensions
    • Enforced at API level during upload
    • Similarity queries automatically filter by matching dimensions

    Metadata Validation#

    Projects can define JSON Schema in metadata_scheme:

    • Validates all embedding metadata on upload
    • Optional - if NULL, metadata not validated
    • Enforced at API level
    • Admin sanity check validates all existing metadata

    Sanity Check Queries#

    The /v1/admin/sanity-check endpoint verifies:

    1. All embeddings have dimensions matching their instance
    2. All metadata conforms to project schemas (if defined)

    Common Queries#

    Find User’s Projects#

    SELECT p.project_handle, p.description, p.created_at
    -FROM projects p
    -WHERE p.owner = 'alice'
    -ORDER BY p.created_at DESC;

    Find Shared Projects#

    SELECT p.project_handle, p.owner, up.role
    -FROM users_projects up
    -JOIN projects p ON up.project_id = p.project_id
    -WHERE up.user_handle = 'bob'
    -ORDER BY p.owner, p.project_handle;

    Find Similar Embeddings#

    SELECT text_id, vector <-> '[0.1, 0.2, ...]'::vector AS distance
    -FROM embeddings
    -WHERE project_id = 123 AND vector_dim = 1536
    -ORDER BY vector <-> '[0.1, 0.2, ...]'::vector
    -LIMIT 10;

    Count Embeddings by Project#

    SELECT p.project_handle, COUNT(e.embeddings_id) AS embedding_count
    -FROM projects p
    -LEFT JOIN embeddings e ON p.project_id = e.project_id
    -WHERE p.owner = 'alice'
    -GROUP BY p.project_id, p.project_handle
    -ORDER BY embedding_count DESC;

    Database Maintenance#

    Backup Recommendations#

    Critical Data:

    • User accounts (users)
    • API keys (vdb_key in users, api_key_encrypted in instances)
    • ENCRYPTION_KEY environment variable (backup separately!)
    • Projects and embeddings

    Backup Strategy:

    # Full database backup
    -pg_dump -U postgres dhamps_vdb > backup.sql
    -
    -# Backup encryption key separately
    -echo "$ENCRYPTION_KEY" > encryption_key.backup
    -chmod 400 encryption_key.backup

    Vacuum and Analyze#

    -- Regular maintenance
    -VACUUM ANALYZE embeddings;
    -VACUUM ANALYZE projects;
    -
    --- Rebuild vector indexes if needed
    -REINDEX INDEX embeddings_vector_1536;

    Monitoring Queries#

    -- Check index usage
    -SELECT schemaname, tablename, indexname, idx_scan
    -FROM pg_stat_user_indexes
    -WHERE tablename = 'embeddings'
    -ORDER BY idx_scan DESC;
    -
    --- Check table sizes
    -SELECT relname, pg_size_pretty(pg_total_relation_size(oid))
    -FROM pg_class
    -WHERE relname IN ('embeddings', 'projects', 'users')
    -ORDER BY pg_total_relation_size(oid) DESC;
    \ No newline at end of file diff --git a/docs/public/reference/index.html b/docs/public/reference/index.html deleted file mode 100644 index a50ad14..0000000 --- a/docs/public/reference/index.html +++ /dev/null @@ -1,6 +0,0 @@ -Reference | dhamps-vdb Documentation - -

    Reference Documentation#

    Technical reference materials and specifications.

    Contents#

    Additional Resources#

    • OpenAPI Specification: Available at /openapi.yaml on any running instance
    • Go Package Documentation: Coming soon
    • Source Code: github.com/mpilhlt/dhamps-vdb
    \ No newline at end of file diff --git a/docs/public/reference/index.xml b/docs/public/reference/index.xml deleted file mode 100644 index 9bea3a4..0000000 --- a/docs/public/reference/index.xml +++ /dev/null @@ -1,56 +0,0 @@ -Reference on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/reference/Recent content in Reference on dhamps-vdb DocumentationHugoen-usConfiguration Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/configuration/<h1 id="configuration-reference">Configuration Reference<a class="anchor" href="#configuration-reference">#</a></h1> -<p>Complete reference for configuring dhamps-vdb. This guide consolidates all configuration options, including environment variables, command-line flags, and Docker configuration.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>dhamps-vdb is configured through a combination of:</p> -<ol> -<li><strong>Environment variables</strong> (recommended)</li> -<li><strong>Command-line flags</strong> (overrides environment variables)</li> -<li><strong><code>.env</code> files</strong> (for Docker and local development)</li> -</ol> -<p>Configuration is loaded in the following priority order (highest to lowest):</p> -<ol> -<li>Command-line flags</li> -<li>Environment variables</li> -<li><code>.env</code> file values</li> -<li>Default values from <code>options.go</code></li> -</ol> -<h2 id="configuration-options">Configuration Options<a class="anchor" href="#configuration-options">#</a></h2> -<h3 id="service-configuration">Service Configuration<a class="anchor" href="#service-configuration">#</a></h3> -<p>Options for controlling the API service behavior.</p>Database Schema Referencehttps://mpilhlt.github.io/dhamps-vdb/reference/database-schema/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/<h1 id="database-schema-reference">Database Schema Reference<a class="anchor" href="#database-schema-reference">#</a></h1> -<p>Complete reference for the dhamps-vdb PostgreSQL database schema. This document describes all tables, columns, types, constraints, relationships, and indexes.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>The database uses PostgreSQL 12+ with the pgvector extension for vector similarity search. The schema is managed through migrations in <code>internal/database/migrations/</code>.</p> -<p><strong>Key Features:</strong></p> -<ul> -<li>Vector embeddings stored as <code>halfvec</code> for efficient storage</li> -<li>HNSW indexes for fast approximate nearest neighbor search</li> -<li>Automatic timestamp tracking (<code>created_at</code>, <code>updated_at</code>)</li> -<li>Foreign key constraints with CASCADE deletion</li> -<li>Role-based access control through association tables</li> -<li>Multi-tenancy support (user-owned resources)</li> -</ul> -<h2 id="schema-migrations">Schema Migrations<a class="anchor" href="#schema-migrations">#</a></h2> -<p>Current schema version is defined by 4 migration files:</p>Product Roadmaphttps://mpilhlt.github.io/dhamps-vdb/reference/roadmap/Mon, 01 Jan 0001 00:00:00 +0000https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/<h1 id="product-roadmap">Product Roadmap<a class="anchor" href="#product-roadmap">#</a></h1> -<p>Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.</p> -<h2 id="overview">Overview<a class="anchor" href="#overview">#</a></h2> -<p>This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.</p> -<h2 id="completed-features">Completed Features<a class="anchor" href="#completed-features">#</a></h2> -<h3 id="core-functionality">Core Functionality<a class="anchor" href="#core-functionality">#</a></h3> -<ul> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>User authentication &amp; restrictions on some API calls</strong></p> -<ul> -<li>Bearer token authentication</li> -<li>Role-based access control</li> -<li>Admin vs user permissions</li> -</ul> -</li> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>API versioning</strong></p> -<ul> -<li>Version 1 API with <code>/v1/</code> prefix</li> -<li>Backward compatibility support</li> -</ul> -</li> -<li> -<p><input checked="" disabled="" type="checkbox"> <strong>Better options handling</strong></p> \ No newline at end of file diff --git a/docs/public/reference/roadmap/index.html b/docs/public/reference/roadmap/index.html deleted file mode 100644 index 93ca238..0000000 --- a/docs/public/reference/roadmap/index.html +++ /dev/null @@ -1,16 +0,0 @@ -Product Roadmap | dhamps-vdb Documentation - -

    Product Roadmap#

    Development roadmap for dhamps-vdb, tracking completed features, in-progress work, and planned enhancements.

    Overview#

    This roadmap outlines the development priorities for dhamps-vdb. Items marked with [x] are completed, items in progress are noted, and planned features are listed by priority.

    Completed Features#

    Core Functionality#

    • User authentication & restrictions on some API calls

      • Bearer token authentication
      • Role-based access control
      • Admin vs user permissions
    • API versioning

      • Version 1 API with /v1/ prefix
      • Backward compatibility support
    • Better options handling

      • Command-line flags via Huma CLI
      • Environment variable configuration
      • .env file support
    • Handle metadata

      • JSONB storage for flexible metadata
      • Metadata attached to embeddings
    • Validation with metadata schema

      • JSON Schema validation for embedding metadata
      • Project-level schema definitions
      • Automatic validation on upload
    • Filter similar passages by metadata field

      • Metadata-based filtering in similarity queries
      • Exclude documents by metadata value
      • Query parameters: metadata_path and metadata_value

    Data Management#

    • Use transactions

      • Atomic operations for multi-step actions
      • Consistency for project creation with sharing
      • Rollback on errors
    • Catch POST to existing resources

      • Prevent duplicate creation
      • Return appropriate error codes
      • Suggest using PUT for updates
    • Always use specific error messages

      • Detailed error descriptions
      • Helpful troubleshooting information
      • Consistent error response format

    Testing & Quality#

    • Tests

      • Integration tests for all major operations
      • Testcontainers for isolated database testing
      • Cleanup verification queries
    • When testing, check cleanup by adding a new query/function to see if all tables are empty

      • Verify test isolation
      • Ensure no data leakage between tests
    • Make sure input is validated consistently

      • Dimension validation for embeddings
      • Schema validation for metadata
      • Request validation via Huma

    Collaboration Features#

    • Add project sharing/unsharing functions & API paths

      • Share projects with specific users
      • Define roles: owner, editor, reader
      • API endpoints for managing sharing
    • Add mechanism to allow anonymous/public reading access to embeddings

      • public_read flag on projects
      • Wildcard sharing via "*" in shared_with
      • Unauthenticated access to public embeddings
    • Transfer of projects from one owner to another as new operation

      • Owner-initiated project transfers
      • Ownership verification
      • Automatic cleanup of old owner associations

    Service Architecture#

    • Add definition creation/listing/deletion functions & paths
      • LLM service definitions (templates)
      • Instances (user-specific configurations)
      • System-provided global definitions

    Deployment & Operations#

    • Dockerization

      • Multi-stage Dockerfile
      • Docker Compose with PostgreSQL
      • External database support
      • Automated setup script
    • Make sure pagination is supported consistently

      • Limit and offset parameters
      • Consistent across all list endpoints
      • Documented pagination behavior

    Security#

    • Prevent acceptance of requests as user “_system”
      • Reserved system user for internal use
      • Blocked from external authentication
      • Protected system-owned resources

    In Progress#

    Documentation#

    • Revisit all documentation

      • Comprehensive reference documentation
      • Updated API examples
      • Docker deployment guides
    • Add documentation for metadata filtering of similars

      • Document metadata_path and metadata_value parameters
      • Provide usage examples
      • Explain use cases (exclude same author, etc.)
      • Note: Query parameters are: metadata_path and metadata_value as in: https://xy.org/vdb-api/v1/similars/sal/sal-openai-large/https%3A%2F%2Fid.myproject.net%2Ftexts%2FW0011%3A1.3.1.3.1?threshold=0.7&limit=5&metadata_path=author_id&metadata_value=A0083

    Planned Features#

    High Priority#

    Network Connectivity#

    • Implement and make consequent use of max_idle (5), max_concurr (5), timeouts, and cancellations

      • Connection pool management
      • Maximum idle connections: 5
      • Maximum concurrent connections: 5
      • Request timeouts
      • Context cancellation support
    • Concurrency (leaky bucket approach) and Rate limiting

      • Leaky bucket algorithm for concurrency control
      • Rate limiting using Redis
      • Sliding window implementation
      • Standard rate limit headers
      • See Huma request limits for implementation
    • Caching

      • Response caching for frequently accessed data
      • Cache invalidation strategies
      • Redis or in-memory caching
      • Configurable TTL

    API Standards#

    • Add API standards for anthropic, mistral, llama.cpp, ollama, vllm, llmstudio
      • Anthropic embeddings API
      • Mistral embeddings API
      • llama.cpp server API
      • Ollama embeddings API
      • vLLM embeddings API
      • LM Studio embeddings API
      • Standard authentication methods
      • Example definitions in testdata

    Medium Priority#

    User Experience#

    • HTML UI

      • Web-based interface for API management
      • User-friendly project creation
      • Visual embedding explorer
      • API key management
      • Alternative to CLI/API usage
    • Allow to request verbose information even in list outputs

      • verbose=yes query parameter
      • Full object details in list endpoints
      • Optional vs default minimal output
      • Performance considerations
    • Add possibility to use PATCH method to change existing resources

      • Partial updates without full replacement
      • PATCH support for users, projects, instances
      • Merge semantics for nested objects
      • Validation of partial updates
      • Status: Partially implemented via automatic PATCH handler

    Logging and Monitoring#

    • Proper logging with --verbose and --quiet modes
      • Structured logging (JSON format)
      • Log levels: ERROR, WARN, INFO, DEBUG, TRACE
      • --verbose flag for detailed logs
      • --quiet flag for minimal logs
      • Request/response logging
      • Performance metrics logging
      • Integration with log aggregation systems

    Future Enhancements#

    Advanced Features#

    • Bulk Operations

      • Batch embedding upload
      • Bulk deletion
      • Transaction support for large operations
    • Advanced Search

      • Combined vector + metadata filtering
      • Hybrid search (vector + keyword)
      • Multi-vector search
      • Weighted search results
    • Embeddings Management

      • Update embeddings in place
      • Re-embedding workflows
      • Embedding versioning
      • Dimension conversion utilities

    Performance#

    • Query Optimization

      • Query plan analysis
      • Index optimization
      • Materialized views for common queries
      • Database connection pooling improvements
    • Scaling

      • Horizontal scaling support
      • Read replicas for query load
      • Partitioning strategies for large datasets
      • Distributed vector search

    Security & Access Control#

    • Fine-grained Permissions

      • Custom roles beyond owner/editor/reader
      • Permission inheritance
      • Temporary access grants
      • IP-based access control
    • Audit Logging

      • Track all API operations
      • User action history
      • Security event logging
      • Compliance reporting
    • OAuth/SAML Integration

      • OAuth 2.0 authentication
      • SAML SSO support
      • Identity provider integration
      • External authentication services

    Integration#

    • Webhooks

      • Event notifications for embeddings changes
      • Project updates notifications
      • Configurable webhook endpoints
      • Retry logic and delivery guarantees
    • Export/Import

      • Project export to standard formats
      • Bulk embedding export
      • Import from other vector databases
      • Migration utilities
    • SDK Support

      • Python SDK
      • JavaScript/TypeScript SDK
      • Go SDK
      • CLI improvements

    Development Process#

    Release Cycle#

    • Minor versions (0.x.0): New features, API additions
    • Patch versions (0.0.x): Bug fixes, documentation updates
    • Major versions (x.0.0): Breaking API changes (future)

    Feature Requests#

    To request a feature or suggest improvements:

    1. Check existing issues on GitHub
    2. Open a new issue with:
      • Clear description of the feature
      • Use cases and motivation
      • Proposed implementation (if any)
    3. Engage in discussion with maintainers

    Contribution Guidelines#

    Contributions are welcome! See the main repository for:

    • Development setup instructions
    • Code style guidelines
    • Testing requirements
    • Pull request process

    Version History#

    v0.1.0 (2026-02-08)#

    • Fix many things
    • Add many things
    • Still API v1 on the way to stable

    v0.0.1 (2024-12-10)#

    • Initial public release
    • API v1 (work in progress)
    • Core functionality implemented
    • Docker support
    • Project sharing
    • Metadata validation

    Feedback#

    We value your feedback! Please share:

    • Feature requests - What would make dhamps-vdb more useful?
    • Bug reports - Help us improve quality
    • Use cases - How are you using dhamps-vdb?
    • Documentation - What needs clarification?

    Open an issue on GitHub or contact the maintainers directly.

    \ No newline at end of file diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml deleted file mode 100644 index dfd8e94..0000000 --- a/docs/public/sitemap.xml +++ /dev/null @@ -1 +0,0 @@ -https://mpilhlt.github.io/dhamps-vdb/concepts/architecture/https://mpilhlt.github.io/dhamps-vdb/api/authentication/https://mpilhlt.github.io/dhamps-vdb/reference/configuration/https://mpilhlt.github.io/dhamps-vdb/deployment/docker/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/https://mpilhlt.github.io/dhamps-vdb/getting-started/https://mpilhlt.github.io/dhamps-vdb/getting-started/installation/https://mpilhlt.github.io/dhamps-vdb/guides/rag-workflow/https://mpilhlt.github.io/dhamps-vdb/development/testing/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/users/https://mpilhlt.github.io/dhamps-vdb/concepts/https://mpilhlt.github.io/dhamps-vdb/getting-started/configuration/https://mpilhlt.github.io/dhamps-vdb/development/contributing/https://mpilhlt.github.io/dhamps-vdb/reference/database-schema/https://mpilhlt.github.io/dhamps-vdb/deployment/database/https://mpilhlt.github.io/dhamps-vdb/getting-started/docker/https://mpilhlt.github.io/dhamps-vdb/guides/project-sharing/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/projects/https://mpilhlt.github.io/dhamps-vdb/concepts/users-and-auth/https://mpilhlt.github.io/dhamps-vdb/development/architecture/https://mpilhlt.github.io/dhamps-vdb/deployment/environment-variables/https://mpilhlt.github.io/dhamps-vdb/guides/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/llm-services/https://mpilhlt.github.io/dhamps-vdb/reference/roadmap/https://mpilhlt.github.io/dhamps-vdb/concepts/projects/https://mpilhlt.github.io/dhamps-vdb/guides/public-projects/https://mpilhlt.github.io/dhamps-vdb/getting-started/quick-start/https://mpilhlt.github.io/dhamps-vdb/api/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/api-standards/https://mpilhlt.github.io/dhamps-vdb/concepts/embeddings/https://mpilhlt.github.io/dhamps-vdb/getting-started/first-project/https://mpilhlt.github.io/dhamps-vdb/guides/ownership-transfer/https://mpilhlt.github.io/dhamps-vdb/development/performance/https://mpilhlt.github.io/dhamps-vdb/deployment/security/https://mpilhlt.github.io/dhamps-vdb/deployment/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/embeddings/https://mpilhlt.github.io/dhamps-vdb/concepts/llm-services/https://mpilhlt.github.io/dhamps-vdb/guides/metadata-validation/https://mpilhlt.github.io/dhamps-vdb/development/https://mpilhlt.github.io/dhamps-vdb/guides/metadata-filtering/https://mpilhlt.github.io/dhamps-vdb/concepts/similarity-search/https://mpilhlt.github.io/dhamps-vdb/api/endpoints/similars/https://mpilhlt.github.io/dhamps-vdb/guides/batch-operations/https://mpilhlt.github.io/dhamps-vdb/concepts/metadata/https://mpilhlt.github.io/dhamps-vdb/api/query-parameters/https://mpilhlt.github.io/dhamps-vdb/reference/https://mpilhlt.github.io/dhamps-vdb/guides/instance-management/https://mpilhlt.github.io/dhamps-vdb/api/patch-updates/https://mpilhlt.github.io/dhamps-vdb/api/error-handling/https://mpilhlt.github.io/dhamps-vdb/categories/https://mpilhlt.github.io/dhamps-vdb/https://mpilhlt.github.io/dhamps-vdb/tags/ \ No newline at end of file diff --git a/docs/public/tags/index.html b/docs/public/tags/index.html deleted file mode 100644 index 8278ae2..0000000 --- a/docs/public/tags/index.html +++ /dev/null @@ -1,3 +0,0 @@ -Tags | dhamps-vdb Documentation - -
    \ No newline at end of file diff --git a/docs/public/tags/index.xml b/docs/public/tags/index.xml deleted file mode 100644 index c74ecd9..0000000 --- a/docs/public/tags/index.xml +++ /dev/null @@ -1 +0,0 @@ -Tags on dhamps-vdb Documentationhttps://mpilhlt.github.io/dhamps-vdb/tags/Recent content in Tags on dhamps-vdb DocumentationHugoen-us \ No newline at end of file diff --git a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content deleted file mode 100644 index db845ba..0000000 --- a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.content +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";:root{--font-size:16px;--font-size-smaller:0.875rem;--font-size-smallest:0.75rem;--body-font-weight:400;--body-background:white;--body-background-tint:transparent;--body-font-color:black;--border-radius:0.25rem}/*!modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize*/*,::before,::after{box-sizing:border-box}html{font-family:system-ui,segoe ui,Roboto,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji;line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,liberation mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:initial}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}.flex{display:flex}.flex.gap{gap:1rem}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-small,small{font-size:.875em}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}html{font-size:var(--font-size);scroll-behavior:smooth;touch-action:manipulation;scrollbar-gutter:stable}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background)var(--body-background-tint);font-weight:var(--body-font-weight);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-weight:inherit}a{flex:auto;align-items:center;gap:.5em;text-decoration:none;cursor:default}a[href],a[role=button]{color:var(--color-link);cursor:pointer}:focus-visible,input.toggle:focus-visible+label{outline-style:auto;outline-color:var(--color-link)}nav ul{padding:0;margin:0;list-style:none}nav ul li{position:relative}nav ul a{padding:.5em 0;display:flex;transition:opacity .1s ease-in-out}nav ul a[href]:hover,nav ul a[role=button]:hover{opacity:.5}nav ul ul{padding-inline-start:1.5em}ul.pagination{display:flex;justify-content:center;list-style-type:none;padding-inline-start:0}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}a .book-icon{height:1em;width:1em}.book-brand{margin-top:0;margin-bottom:1rem}.book-brand img{height:1.5em;width:1.5em}.book-menu{flex:0 0 16rem;font-size:var(--font-size-smaller)}.book-menu .book-menu-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;word-wrap:break-word;display:flex}.book-menu a.active{color:var(--color-link)}.book-menu label>img:last-child{height:1em;width:1em;cursor:pointer;align-self:center;transition:transform .1s ease-in-out}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-menu input.toggle:checked+label+ul{display:block}body[dir=rtl] .book-menu input.toggle+label>img:last-child{transform:rotate(180deg)}body[dir=rtl] .book-menu input.toggle:checked+label>img:last-child{transform:rotate(90deg)}.book-section-flat{margin:1rem 0}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:4rem}.book-post .book-post-date img{height:1em;width:1em;margin-inline-end:.5em}.book-post .book-post-content{margin-top:1rem}.book-post .book-post-thumbnail{flex:0 0 34%}.book-post .book-post-thumbnail img{width:100%;aspect-ratio:4/3;object-fit:cover}.book-header{margin-bottom:1rem}.book-header label{line-height:0}.book-header h3{overflow:hidden;text-overflow:ellipsis;margin:0 1rem}.book-layout-landing .book-header{display:block;position:relative;z-index:1}.book-layout-landing .book-header nav>ul{display:flex;gap:1rem;justify-content:end}.book-layout-landing .book-header nav>ul>li{display:block;white-space:nowrap}.book-layout-landing .book-header nav>ul>li>ul{display:none;position:absolute;padding:0}.book-layout-landing .book-header nav>ul>li:hover>ul,.book-layout-landing .book-header nav>ul>li:focus-within>ul{display:block}.book-search{position:relative;margin:.5rem 0}.book-search input{width:100%;padding:.5rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search ul a{padding-bottom:0}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:var(--font-size-smallest)}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc a{display:block}.book-toc img{height:1em;width:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:var(--font-size-smaller)}.book-footer a{margin:.25rem 0;padding:.25rem 0}.book-comments{margin-top:1rem}.book-copyright{margin-top:1rem}.book-languages{margin-bottom:1rem}.book-languages span{padding:0}.book-languages ul{padding-inline-start:1.5em}.book-menu-content,.book-toc-content{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){.book-menu{visibility:hidden;margin-inline-start:-16rem;z-index:1}.book-menu .book-menu-content{background:var(--body-background)}.book-toc{display:none}.book-header{display:block}.book-post-container{flex-direction:column-reverse}#menu-control,#toc-control{display:inline}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:fixed;top:0;bottom:0;left:0;right:0}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked~main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:inherit;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;margin-inline-start:.25em}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus-visible,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus-visible,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus-visible,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus-visible,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus-visible,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus-visible{opacity:initial;text-decoration:none}.markdown h1{font-size:2rem}.markdown h2{font-size:1.5rem}.markdown h3{font-size:1.25rem}.markdown h4{font-size:1.125rem}.markdown h5{font-size:1rem}.markdown h6{font-size:.875rem}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a[href]:hover{text-decoration:underline}.markdown a[href]:visited{color:var(--color-visited-link)}.markdown img{max-width:100%;height:auto}.markdown code{direction:ltr;unicode-bidi:embed;padding:.125em .25em;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border:1px solid var(--gray-200);border-radius:var(--border-radius);overflow-x:auto}.markdown pre:focus{outline-style:auto;outline-color:var(--color-link)}.markdown pre code{padding:0;border:0;background:0 0}.markdown p{word-wrap:break-word}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:var(--border-radius)}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200);text-align:start}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem;word-wrap:break-word}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:0;margin-bottom:1rem}.markdown .highlight{direction:ltr;unicode-bidi:embed;border-radius:var(--border-radius)}.markdown .highlight table tbody{border:1px solid var(--gray-200)}.markdown .highlight table tr pre{border:0}.markdown .highlight table tr td pre code>span{display:flex}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;margin:1rem 0;border:1px solid var(--gray-200);border-radius:var(--border-radius)}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer;list-style:none}.markdown details summary::before{content:"›";display:inline-block;margin-inline-end:.5rem;transition:transform .1s ease-in-out}.markdown details[open] summary{margin-bottom:0}.markdown details[open] summary::before{transform:rotate(90deg)}.markdown figure{margin:1rem 0}.markdown figure figcaption{margin-top:1rem}.markdown-inner>:first-child,.markdown .book-steps>ol>li>:first-child,.markdown figure figcaption>:first-child{margin-top:0}.markdown-inner>:last-child,.markdown .book-steps>ol>li>:last-child,.markdown figure figcaption>:last-child{margin-bottom:0}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:var(--border-radius);display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-columns{gap:1rem}.markdown .book-columns>div{margin:1rem 0;min-width:13.2rem}.markdown .book-columns>ul{list-style:none;display:flex;padding:0;flex-wrap:wrap;gap:1rem}.markdown .book-columns>ul>li{flex:1 1;min-width:13.2rem}.markdown a.book-btn[href]{display:inline-block;font-size:var(--font-size-smaller);color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:var(--border-radius);cursor:pointer}.markdown a.book-btn[href]:hover{text-decoration:none}.markdown .book-hint.note{border-color:var(--color-accent-note);background-color:var(--color-accent-note-tint)}.markdown .book-hint.tip{border-color:var(--color-accent-tip);background-color:var(--color-accent-tip-tint)}.markdown .book-hint.important{border-color:var(--color-accent-important);background-color:var(--color-accent-important-tint)}.markdown .book-hint.warning{border-color:var(--color-accent-warning);background-color:var(--color-accent-warning-tint)}.markdown .book-hint.caution{border-color:var(--color-accent-caution);background-color:var(--color-accent-caution-tint)}.markdown .book-hint.default{border-color:var(--color-accent-default);background-color:var(--color-accent-default-tint)}.markdown .book-hint.info{border-color:var(--color-accent-info);background-color:var(--color-accent-info-tint)}.markdown .book-hint.success{border-color:var(--color-accent-success);background-color:var(--color-accent-success-tint)}.markdown .book-hint.danger{border-color:var(--color-accent-danger);background-color:var(--color-accent-danger-tint)}.markdown .book-badge{display:inline-block;font-size:var(--font-size-smaller);font-weight:var(--body-font-weight);vertical-align:middle;border-radius:var(--border-radius);border:1px solid var(--accent-color);overflow:hidden;text-wrap:nowrap;color:var(--body-font-color)}.markdown .book-badge.note{--accent-color:var(--color-accent-note)}.markdown .book-badge.tip{--accent-color:var(--color-accent-tip)}.markdown .book-badge.important{--accent-color:var(--color-accent-important)}.markdown .book-badge.warning{--accent-color:var(--color-accent-warning)}.markdown .book-badge.caution{--accent-color:var(--color-accent-caution)}.markdown .book-badge.default{--accent-color:var(--color-accent-default)}.markdown .book-badge.info{--accent-color:var(--color-accent-info)}.markdown .book-badge.success{--accent-color:var(--color-accent-success)}.markdown .book-badge.danger{--accent-color:var(--color-accent-danger)}.markdown .book-badge span{display:inline-block;padding:0 .5rem}.markdown .book-badge span.book-badge-value{color:var(--body-background);background-color:var(--accent-color)}.markdown .book-steps{position:relative}.markdown .book-steps>ol{counter-reset:steps;list-style:none;padding-inline-start:1.25rem;margin-top:2rem}.markdown .book-steps>ol>li::before{content:counter(steps);counter-increment:steps;position:absolute;display:flex;justify-content:center;left:.5rem;height:1.5rem;width:1.5rem;padding:.25rem;border-radius:.5rem;white-space:nowrap;line-height:1rem;color:var(--body-background);background:var(--gray-500);outline:.25rem solid var(--body-background)}.markdown .book-steps>ol>li{border-inline-start:1px solid var(--gray-500);padding-inline-start:3rem;padding-bottom:2rem}.markdown .book-steps>ol>li:last-child{border:0}.markdown .book-card{display:block;overflow:hidden;height:100%;border-radius:var(--border-radius);border:1px solid var(--gray-200)}.markdown .book-card>a{display:block;height:100%}.markdown .book-card>a[href],.markdown .book-card>a[href]:visited{color:var(--body-font-color)}.markdown .book-card>a[href]:hover{text-decoration:none;background:var(--gray-100)}.markdown .book-card>a>img,.markdown .book-card>img{width:100%;display:block;aspect-ratio:4/3;object-fit:cover}.markdown .book-card .markdown-inner,.markdown .book-card figure figcaption,.markdown figure .book-card figcaption,.markdown .book-card .book-steps>ol>li{padding:1rem}.markdown .book-image input+img{cursor:zoom-in;transition:transform .2s ease-in-out}.markdown .book-image input:checked+img{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--body-background);object-fit:contain;width:100%;height:100%;z-index:1;cursor:zoom-out;padding:1rem}.markdown .book-asciinema{margin:1rem 0}.markdown .book-hero{min-height:24rem;align-content:center}.markdown .book-hero h1{font-size:3em}.markdown .book-codeblock-filename{background:var(--gray-100);border:1px solid var(--gray-200);border-bottom:0;font-size:var(--font-size-smaller);margin-top:1rem;padding:.25rem .5rem;border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}.markdown .book-codeblock-filename a{color:var(--body-font-color)}.markdown .book-codeblock-filename+.highlight pre{margin-top:0;border-start-start-radius:0;border-start-end-radius:0}:root{--body-background:white;--body-background-tint:none;--body-font-color:black;--color-link:#0055bb;--color-visited-link:#5500bb;--icon-filter:none;--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-accent-default:#64748b;--color-accent-default-tint:rgba(100, 116, 139, 0.1);--color-accent-note:#4486dd;--color-accent-note-tint:rgba(68, 134, 221, 0.1);--color-accent-tip:#3bad3b;--color-accent-tip-tint:rgba(59, 173, 59, 0.1);--color-accent-important:#8144dd;--color-accent-important-tint:rgba(129, 68, 221, 0.1);--color-accent-warning:#f59e42;--color-accent-warning-tint:rgba(245, 158, 66, 0.1);--color-accent-caution:#d84747;--color-accent-caution-tint:rgba(216, 71, 71, 0.1);--color-accent-info:#4486dd;--color-accent-info-tint:rgba(68, 134, 221, 0.1);--color-accent-success:#3bad3b;--color-accent-success-tint:rgba(59, 173, 59, 0.1);--color-accent-danger:#d84747;--color-accent-danger-tint:rgba(216, 71, 71, 0.1)} \ No newline at end of file diff --git a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json b/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json deleted file mode 100644 index 322e46d..0000000 --- a/docs/resources/_gen/assets/book.scss_b807c86e8030af4cdc30edccea379f5f.json +++ /dev/null @@ -1 +0,0 @@ -{"Target":"book.min.cc2c524ed250aac81b23d1f4af87344917b325208841feca0968fe450f570575.css","MediaType":"text/css","Data":{"Integrity":"sha256-zCxSTtJQqsgbI9H0r4c0SRezJSCIQf7KCWj+RQ9XBXU="}} \ No newline at end of file