From c7ee34e5a0d3db4f315ddb252cdfd6a2b60bb083 Mon Sep 17 00:00:00 2001 From: Praneeth Bedapudi Date: Fri, 27 Mar 2026 22:31:33 +0530 Subject: [PATCH 1/5] update docs Signed-off-by: Praneeth Bedapudi --- docs/llm-gateway/integration-guide.md | 20 ++++++++++++ docs/llm-gateway/ux-changelog.md | 15 +++++++++ docs/mcp-gateway/quick-start.md | 45 ++++++++++++++++++--------- docusaurus.config.js | 4 +-- package-lock.json | 36 --------------------- 5 files changed, 67 insertions(+), 53 deletions(-) create mode 100644 docs/llm-gateway/ux-changelog.md diff --git a/docs/llm-gateway/integration-guide.md b/docs/llm-gateway/integration-guide.md index 7ea4477..cd07cc4 100644 --- a/docs/llm-gateway/integration-guide.md +++ b/docs/llm-gateway/integration-guide.md @@ -105,6 +105,26 @@ message = client.messages.create( print(message.content[0].text) ``` +### Anthropic — JavaScript + +```javascript +import Anthropic from "@anthropic-ai/sdk"; + +// Point the client to QuilrAI's gateway +const client = new Anthropic({ + baseURL: "https://guardrails.quilr.ai/anthropic_messages/", + apiKey: "sk-quilr-xxx", +}); + +// Everything below stays exactly the same +const message = await client.messages.create({ + model: "claude-sonnet-4-20250514", + max_tokens: 1024, + messages: [{ role: "user", content: "Hello!" }], +}); +console.log(message.content[0].text); +``` + ### Anthropic — cURL ```bash diff --git a/docs/llm-gateway/ux-changelog.md b/docs/llm-gateway/ux-changelog.md new file mode 100644 index 0000000..4303771 --- /dev/null +++ b/docs/llm-gateway/ux-changelog.md @@ -0,0 +1,15 @@ +--- +sidebar_position: 4 +--- + +# UX Changelog + +Recent interface improvements and quality-of-life changes. + +## Tags + +Add custom tags to API keys to organize by team, environment, or use case. + +- Add custom tags to API keys to organize by team, environment, or use case +- Filter and search keys by tag from the top bar +- Tags persist per app across sessions and can be removed inline diff --git a/docs/mcp-gateway/quick-start.md b/docs/mcp-gateway/quick-start.md index 7421ee1..f5439c1 100644 --- a/docs/mcp-gateway/quick-start.md +++ b/docs/mcp-gateway/quick-start.md @@ -4,32 +4,47 @@ sidebar_position: 1 # Quick Start -Get up and running with MCP Gateway in 3 steps. +Get up and running with MCP Gateway in 4 steps. ## 1. Add an MCP Server -- **Install from the MCP Library** — browse the catalog and one-click install pre-built integrations -- Or click **"Add MCP"** to register a custom server by providing its transport URL (ending in `/sse` or `/mcp`) -- OAuth MCPs will prompt you to authorize; token-based MCPs get API tokens +Go to the **MCP Gateway** tab and install from the **MCP Library** for one-click pre-built integrations, or click **Add MCP** to register any server by its transport URL (ending in `/sse` or `/mcp`). -## 2. Configure Settings +OAuth MCPs will prompt you to authorize; token-based MCPs receive API tokens automatically. -Open **Settings** on the MCP card and configure what you need: +## 2. Configure Your MCP + +Open **Settings** on any MCP card to fine-tune its behavior. Sensible defaults are applied automatically. | Setting | Description | |---------|-------------| -| **Tools** | Enable/disable individual tools by category (read-only, write, destructive) | -| **Guardrails** | Data risk detection (PII/PHI/PCI), adversarial risk blocking on tool calls | -| **Access Control** | Restrict which AI agents can use this MCP | -| **Web Search Policy** | Domain exclusions via Zscaler/Palo Alto/Fortinet/Cisco (Web Search MCP only) | +| **[Tools Management](./features/tools-management)** | Enable/disable tools by category (read-only, write, destructive) | +| **[Security Guardrails](./features/security-guardrails)** | PII/PHI/PCI detection, adversarial blocking | +| **[Access Control](./features/access-control)** | Restrict which AI agents can use this MCP | +| **[Web Search Policy](./features/web-search-policy)** | Domain exclusions via firewall integrations | +| **[OAuth Connect](./features/oauth-connect)** | One-click OAuth authorization flow | +| **[Agents Configuration](./features/agents-configuration)** | Define and manage AI agent profiles | ## 3. Connect Your Agent -- Point your AI agent/client to the **MCP endpoint URL** shown on the card -- Use `Authorization: Bearer ` + `mcpuser: user@email.com` headers for token-based MCPs -- For OAuth MCPs, authorization happens via the Connect flow +Point your AI agent or client to the **MCP endpoint URL** shown on the card. Use **Authorization: Bearer <token>** and **mcpuser** headers for token-based MCPs. OAuth MCPs use the Connect flow instead. ---- +```json +{ + "mcpServers": { + "quilr-mcp": { + "url": "https://mcp.quilr.ai//mcp", + "headers": { + "Authorization": "Bearer ", + "mcpuser": "user@company.com" + } + } + } +} +``` + +See the [Integration Guide](./integration-guide) for more client examples. -**Next step:** See the [Integration Guide](./integration-guide) for endpoint details, authentication methods, and connection examples. +## 4. Monitor Tool Calls +Every tool call through the gateway is logged with **tool name, parameters, guardrail actions, and user identity**. Check your **Logs** tab to verify requests are flowing through. diff --git a/docusaurus.config.js b/docusaurus.config.js index 3f3ae15..0e14c6e 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -21,8 +21,8 @@ const config = { }, // GitHub Pages: https://docusaurus.io/docs/deployment#deploying-to-github-pages - url: 'https://quilrai.github.io', - baseUrl: '/docs/', + url: 'https://localhost:3001', + baseUrl: '/', organizationName: 'quilrai', projectName: 'docs', diff --git a/package-lock.json b/package-lock.json index 93e4bd6..1afadfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4965,9 +4965,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4984,9 +4981,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5003,9 +4997,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5022,9 +5013,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5790,9 +5778,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5810,9 +5795,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5830,9 +5812,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5850,9 +5829,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -11398,9 +11374,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11422,9 +11395,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11446,9 +11416,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11470,9 +11437,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ From 9c0afb266273ee814887328fdbe40bfbbf23a79e Mon Sep 17 00:00:00 2001 From: Praneeth Bedapudi Date: Fri, 27 Mar 2026 22:43:28 +0530 Subject: [PATCH 2/5] update docs Signed-off-by: Praneeth Bedapudi --- docusaurus.config.js | 230 +++++++++++++++++++++---------------------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index 0e14c6e..ab6ce90 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -4,136 +4,136 @@ // There are various equivalent ways to declare your Docusaurus config. // See: https://docusaurus.io/docs/api/docusaurus-config -import {prismLight} from './src/themes/prismLight.js'; -import {prismDark} from './src/themes/prismDark.js'; +import { prismLight } from './src/themes/prismLight.js'; +import { prismDark } from './src/themes/prismDark.js'; // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) /** @type {import('@docusaurus/types').Config} */ const config = { - title: 'QuilrAI Docs', - tagline: 'Documentation for QuilrAI', - favicon: 'img/favicon.ico', + title: 'QuilrAI Docs', + tagline: 'Documentation for QuilrAI', + favicon: 'img/favicon.ico', - // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future - future: { - v4: true, // Improve compatibility with the upcoming Docusaurus v4 - }, + // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future + future: { + v4: true, // Improve compatibility with the upcoming Docusaurus v4 + }, - // GitHub Pages: https://docusaurus.io/docs/deployment#deploying-to-github-pages - url: 'https://localhost:3001', - baseUrl: '/', + // GitHub Pages: https://docusaurus.io/docs/deployment#deploying-to-github-pages + url: 'https://quilrai.github.io', + baseUrl: '/docs/', - organizationName: 'quilrai', - projectName: 'docs', + organizationName: 'quilrai', + projectName: 'docs', - trailingSlash: false, + trailingSlash: false, - onBrokenLinks: 'throw', + onBrokenLinks: 'throw', - // Even if you don't use internationalization, you can use this field to set - // useful metadata like html lang. For example, if your site is Chinese, you - // may want to replace "en" with "zh-Hans". - i18n: { - defaultLocale: 'en', - locales: ['en'], - }, + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, - themes: [ - [ - // @ts-ignore - '@easyops-cn/docusaurus-search-local', - /** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */ - // @ts-ignore - ({ - hashed: true, - language: ['en'], - indexDocs: true, - indexBlog: false, - indexPages: false, - docsRouteBasePath: '/', - explicitSearchResultPath: true, - searchBarShortcut: true, - searchBarShortcutHint: true, - }), + themes: [ + [ + // @ts-ignore + '@easyops-cn/docusaurus-search-local', + /** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */ + // @ts-ignore + ({ + hashed: true, + language: ['en'], + indexDocs: true, + indexBlog: false, + indexPages: false, + docsRouteBasePath: '/', + explicitSearchResultPath: true, + searchBarShortcut: true, + searchBarShortcutHint: true, + }), + ], ], - ], - presets: [ - [ - 'classic', - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - routeBasePath: '/', - sidebarPath: './sidebars.js', - }, - blog: false, - theme: { - customCss: './src/css/custom.css', - }, - }), + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + routeBasePath: '/', + sidebarPath: './sidebars.js', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + }), + ], ], - ], - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - image: 'img/QuilrAi-Open-Graph.png', - colorMode: { - defaultMode: 'light', - respectPrefersColorScheme: true, - disableSwitch: false, - }, - navbar: { - title: '', - logo: { - alt: 'QuilrAi', - src: 'img/QuilrAI-light.png', - srcDark: 'img/QuilrAI-dark.png', - }, - items: [ - { - type: 'docSidebar', - sidebarId: 'docsSidebar', - position: 'left', - label: 'Documentation', - }, - { - href: 'https://www.quilr.ai/resources', - label: 'Resources', - position: 'right', - target: '_blank', - rel: 'noopener noreferrer', - }, - ], - }, - footer: { - links: [ - { - title: 'Docs', - items: [ - { - label: 'Documentation', - to: '/', - }, - { - label: 'Resources', - href: 'https://www.quilr.ai/resources', - target: '_blank', - rel: 'noopener noreferrer', - } - ], - }, - - ], - copyright: `Copyright © ${new Date().getFullYear()} QuilrAI. Built with Docusaurus.`, - }, - prism: { - theme: prismLight, - darkTheme: prismDark, - }, - }), + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + image: 'img/QuilrAi-Open-Graph.png', + colorMode: { + defaultMode: 'light', + respectPrefersColorScheme: true, + disableSwitch: false, + }, + navbar: { + title: '', + logo: { + alt: 'QuilrAi', + src: 'img/QuilrAI-light.png', + srcDark: 'img/QuilrAI-dark.png', + }, + items: [ + { + type: 'docSidebar', + sidebarId: 'docsSidebar', + position: 'left', + label: 'Documentation', + }, + { + href: 'https://www.quilr.ai/resources', + label: 'Resources', + position: 'right', + target: '_blank', + rel: 'noopener noreferrer', + }, + ], + }, + footer: { + links: [ + { + title: 'Docs', + items: [ + { + label: 'Documentation', + to: '/', + }, + { + label: 'Resources', + href: 'https://www.quilr.ai/resources', + target: '_blank', + rel: 'noopener noreferrer', + } + ], + }, + + ], + copyright: `Copyright © ${new Date().getFullYear()} QuilrAI. Built with Docusaurus.`, + }, + prism: { + theme: prismLight, + darkTheme: prismDark, + }, + }), }; -export default config; +export default config; \ No newline at end of file From 23240d0503a73095530733d4431d875becca0fd4 Mon Sep 17 00:00:00 2001 From: Praneeth Bedapudi Date: Fri, 27 Mar 2026 22:59:46 +0530 Subject: [PATCH 3/5] update llm integration guides Signed-off-by: Praneeth Bedapudi --- docs/llm-gateway/integration-guide.md | 96 +++++++++++++++++- src/css/custom.css | 28 ++++++ .../CodeBlock/Buttons/CopyButton/index.js | 99 +++++++++++++++++++ .../Buttons/CopyButton/styles.module.css | 40 ++++++++ 4 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 src/theme/CodeBlock/Buttons/CopyButton/index.js create mode 100644 src/theme/CodeBlock/Buttons/CopyButton/styles.module.css diff --git a/docs/llm-gateway/integration-guide.md b/docs/llm-gateway/integration-guide.md index cd07cc4..7fa81d3 100644 --- a/docs/llm-gateway/integration-guide.md +++ b/docs/llm-gateway/integration-guide.md @@ -39,7 +39,11 @@ from openai import OpenAI # Point the client to QuilrAI's gateway client = OpenAI( + # diff-add base_url='https://guardrails.quilr.ai/openai_compatible/', + # diff-remove + api_key='sk-openai-xxx' + # diff-add api_key='sk-quilr-xxx' ) @@ -63,11 +67,17 @@ print(embedding.data[0].embedding[:5]) ```javascript import OpenAI from "openai"; +// Point the client to QuilrAI's gateway const client = new OpenAI({ + // diff-add baseURL: "https://guardrails.quilr.ai/openai_compatible/", + // diff-remove + apiKey: "sk-openai-xxx", + // diff-add apiKey: "sk-quilr-xxx", }); +// Everything below stays exactly the same const response = await client.chat.completions.create({ model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello!" }], @@ -78,8 +88,15 @@ console.log(response.choices[0].message.content); ### OpenAI — cURL ```bash +# Point the request to QuilrAI's gateway +# diff-remove +curl https://api.openai.com/v1/chat/completions \ +# diff-add curl https://guardrails.quilr.ai/openai_compatible/v1/chat/completions \ -H "Content-Type: application/json" \ + # diff-remove + -H "Authorization: Bearer sk-openai-xxx" \ + # diff-add -H "Authorization: Bearer sk-quilr-xxx" \ -d '{ "model": "gpt-4o-mini", @@ -92,11 +109,19 @@ curl https://guardrails.quilr.ai/openai_compatible/v1/chat/completions \ ```python import anthropic +# Point the client to QuilrAI's gateway client = anthropic.Anthropic( + # diff-remove + # uses default base URL + # diff-add base_url='https://guardrails.quilr.ai/anthropic_messages/', + # diff-remove + api_key='sk-ant-xxx' + # diff-add api_key='sk-quilr-xxx' ) +# Everything below stays exactly the same message = client.messages.create( model='claude-sonnet-4-20250514', max_tokens=1024, @@ -112,7 +137,13 @@ import Anthropic from "@anthropic-ai/sdk"; // Point the client to QuilrAI's gateway const client = new Anthropic({ + // diff-remove + // uses default base URL + // diff-add baseURL: "https://guardrails.quilr.ai/anthropic_messages/", + // diff-remove + apiKey: "sk-ant-xxx", + // diff-add apiKey: "sk-quilr-xxx", }); @@ -128,8 +159,15 @@ console.log(message.content[0].text); ### Anthropic — cURL ```bash +# Point the request to QuilrAI's gateway +# diff-remove +curl https://api.anthropic.com/v1/messages \ +# diff-add curl https://guardrails.quilr.ai/anthropic_messages/v1/messages \ -H "Content-Type: application/json" \ + # diff-remove + -H "x-api-key: sk-ant-xxx" \ + # diff-add -H "x-api-key: sk-quilr-xxx" \ -H "anthropic-version: 2023-06-01" \ -d '{ @@ -144,25 +182,51 @@ curl https://guardrails.quilr.ai/anthropic_messages/v1/messages \ ```python from google import genai from google.genai.types import HttpOptions +# diff-remove +from google.oauth2 import service_account +# diff-add from google.auth import credentials as auth_credentials +# diff-add class APIKeyCredentials(auth_credentials.Credentials): + # diff-add """Pass the QuilrAI API key as a Bearer token.""" + # diff-add + # diff-add def __init__(self, api_key): + # diff-add super().__init__() + # diff-add self.api_key = api_key + # diff-add self.token = api_key + # diff-add + # diff-add def refresh(self, request): + # diff-add self.token = self.api_key + # diff-add + # diff-add @property + # diff-add def valid(self): + # diff-add return True +# diff-remove +credentials = service_account.Credentials.from_service_account_file( + # diff-remove + 'service.json', + # diff-remove + scopes=['https://www.googleapis.com/auth/cloud-platform'] +# diff-remove +) +# diff-add credentials = APIKeyCredentials('sk-quilr-xxx') client = genai.Client( @@ -170,9 +234,13 @@ client = genai.Client( project='your-gcp-project', location='us-central1', credentials=credentials, + # diff-remove + # uses default Vertex AI endpoint + # diff-add http_options=HttpOptions(base_url='https://guardrails.quilr.ai/vertex_ai'), ) +# Everything below stays exactly the same response = client.models.generate_content( model='gemini-2.5-flash', contents='Hello!' @@ -183,35 +251,61 @@ print(response.text) ### Vertex AI — LangChain ```python +# diff-remove +from google.oauth2 import service_account +# diff-add from google.oauth2 import credentials as ga_credentials from langchain_google_genai import ChatGoogleGenerativeAI +# diff-add class _NoopCredentials(ga_credentials.Credentials): + # diff-add """Inject the QuilrAI API key as a Bearer token.""" + # diff-add + # diff-add def __init__(self, api_key): + # diff-add super().__init__(token=api_key) + # diff-add + # diff-add def refresh(self, request): + # diff-add pass + # diff-add + # diff-add @property + # diff-add def valid(self): + # diff-add return True +# diff-remove +credentials = service_account.Credentials.from_service_account_file( + # diff-remove + 'service.json', + # diff-remove + scopes=['https://www.googleapis.com/auth/cloud-platform'] +# diff-remove +) +# diff-add credentials = _NoopCredentials('sk-quilr-xxx') llm = ChatGoogleGenerativeAI( model='gemini-2.5-flash', credentials=credentials, + # diff-add base_url='https://guardrails.quilr.ai/vertex_ai', project='your-gcp-project', - location='global', + location='us-central1', vertexai=True, ) +# Everything below stays exactly the same response = llm.invoke('Hello!') print(response.content) ``` diff --git a/src/css/custom.css b/src/css/custom.css index 105579e..ea1e9c4 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1180,3 +1180,31 @@ main > .container.padding-top--md.padding-bottom--lg, width: 100% !important; box-sizing: border-box; } + +/* ────────────────────────────────── Diff-style code lines ─────────────── */ +.code-block-diff-add-line { + background-color: rgba(16, 185, 129, 0.10); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); + border-left: 3px solid #10b981; +} + +.code-block-diff-remove-line { + background-color: rgba(239, 68, 68, 0.10); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); + border-left: 3px solid #ef4444; + opacity: 0.65; + text-decoration: line-through; + text-decoration-color: rgba(239, 68, 68, 0.4); +} + +[data-theme="dark"] .code-block-diff-add-line { + background-color: rgba(16, 185, 129, 0.08); +} + +[data-theme="dark"] .code-block-diff-remove-line { + background-color: rgba(239, 68, 68, 0.08); +} diff --git a/src/theme/CodeBlock/Buttons/CopyButton/index.js b/src/theme/CodeBlock/Buttons/CopyButton/index.js new file mode 100644 index 0000000..8e90b22 --- /dev/null +++ b/src/theme/CodeBlock/Buttons/CopyButton/index.js @@ -0,0 +1,99 @@ +import React, {useCallback, useState, useRef, useEffect} from 'react'; +import clsx from 'clsx'; +import {translate} from '@docusaurus/Translate'; +import {useCodeBlockContext} from '@docusaurus/theme-common/internal'; +import Button from '@theme/CodeBlock/Buttons/Button'; +import IconCopy from '@theme/Icon/Copy'; +import IconSuccess from '@theme/Icon/Success'; + +import styles from './styles.module.css'; + +function title() { + return translate({ + id: 'theme.CodeBlock.copy', + message: 'Copy', + description: 'The copy button label on code blocks', + }); +} + +function ariaLabel(isCopied) { + return isCopied + ? translate({ + id: 'theme.CodeBlock.copied', + message: 'Copied', + description: 'The copied button label on code blocks', + }) + : translate({ + id: 'theme.CodeBlock.copyButtonAriaLabel', + message: 'Copy code to clipboard', + description: 'The ARIA label for copy code blocks button', + }); +} + +/** + * Reads code from the DOM, skipping lines marked as diff-remove. + * Falls back to metadata.code if no diff lines are present. + */ +function getCodeToCopy(buttonEl, fallbackCode) { + if (!buttonEl) return fallbackCode; + + const codeBlock = buttonEl.closest('.theme-code-block'); + if (!codeBlock) return fallbackCode; + + // Only do DOM-based filtering if there are diff-remove lines + if (!codeBlock.querySelector('.code-block-diff-remove-line')) { + return fallbackCode; + } + + const codeEl = codeBlock.querySelector('pre code'); + if (!codeEl) return fallbackCode; + + const lineSpans = codeEl.querySelectorAll(':scope > span'); + const lines = []; + + for (const span of lineSpans) { + if (span.classList.contains('code-block-diff-remove-line')) continue; + lines.push(span.textContent.replace(/\n$/, '')); + } + + return lines.join('\n'); +} + +export default function CopyButton({className}) { + const {metadata: {code}} = useCodeBlockContext(); + const [isCopied, setIsCopied] = useState(false); + const copyTimeout = useRef(undefined); + + const handleCopy = useCallback( + (e) => { + const textToCopy = getCodeToCopy(e.currentTarget, code); + + navigator.clipboard.writeText(textToCopy).then(() => { + setIsCopied(true); + copyTimeout.current = window.setTimeout(() => { + setIsCopied(false); + }, 1000); + }); + }, + [code], + ); + + useEffect(() => () => window.clearTimeout(copyTimeout.current), []); + + return ( + + ); +} diff --git a/src/theme/CodeBlock/Buttons/CopyButton/styles.module.css b/src/theme/CodeBlock/Buttons/CopyButton/styles.module.css new file mode 100644 index 0000000..d5268e9 --- /dev/null +++ b/src/theme/CodeBlock/Buttons/CopyButton/styles.module.css @@ -0,0 +1,40 @@ +:global(.theme-code-block:hover) .copyButtonCopied { + opacity: 1 !important; +} + +.copyButtonIcons { + position: relative; + width: 1.125rem; + height: 1.125rem; +} + +.copyButtonIcon, +.copyButtonSuccessIcon { + position: absolute; + top: 0; + left: 0; + fill: currentColor; + opacity: inherit; + width: inherit; + height: inherit; + transition: all var(--ifm-transition-fast) ease; +} + +.copyButtonSuccessIcon { + top: 50%; + left: 50%; + transform: translate(-50%, -50%) scale(0.33); + opacity: 0; + color: #00d600; +} + +.copyButtonCopied .copyButtonIcon { + transform: scale(0.33); + opacity: 0; +} + +.copyButtonCopied .copyButtonSuccessIcon { + transform: translate(-50%, -50%) scale(1); + opacity: 1; + transition-delay: 0.075s; +} From 2081f168344fd59c318ce6cb5336f8b18add6d31 Mon Sep 17 00:00:00 2001 From: Praneeth Bedapudi Date: Fri, 27 Mar 2026 23:47:14 +0530 Subject: [PATCH 4/5] add components for better diagrams Signed-off-by: Praneeth Bedapudi --- docs/llm-gateway/features/identity-aware.md | 24 + docs/llm-gateway/features/prompt-store.md | 24 + docs/llm-gateway/features/request-routing.md | 25 + docs/llm-gateway/features/tags.md | 18 - docs/llm-gateway/features/token-saving.md | 24 + docs/llm-gateway/quick-start.md | 35 + .../features/agents-configuration.md | 27 + docs/mcp-gateway/features/mcp-library.md | 27 + docs/mcp-gateway/features/oauth-connect.md | 27 + docs/mcp-gateway/features/tools-management.md | 27 + .../mcp-gateway/features/web-search-policy.md | 27 + docs/mcp-gateway/quick-start.md | 35 + docusaurus.config.js | 21 + package-lock.json | 1458 +++++++++++++++-- package.json | 1 + src/components/StepFlow/index.js | 66 + src/components/StepFlow/styles.module.css | 205 +++ src/theme/MDXComponents.js | 7 + 18 files changed, 1962 insertions(+), 116 deletions(-) delete mode 100644 docs/llm-gateway/features/tags.md create mode 100644 src/components/StepFlow/index.js create mode 100644 src/components/StepFlow/styles.module.css create mode 100644 src/theme/MDXComponents.js diff --git a/docs/llm-gateway/features/identity-aware.md b/docs/llm-gateway/features/identity-aware.md index 6beb000..80b3f08 100644 --- a/docs/llm-gateway/features/identity-aware.md +++ b/docs/llm-gateway/features/identity-aware.md @@ -8,6 +8,30 @@ Authenticate and track users behind each API key. ## How It Works + + 1. **Request Arrives** — App sends an API call with identity info 2. **Gateway Identifies User** — Extracts identity via header or JWT token 3. **Per-User Tracking** — Usage tracked per user with rate limits and analytics diff --git a/docs/llm-gateway/features/prompt-store.md b/docs/llm-gateway/features/prompt-store.md index ce6c796..2e661ff 100644 --- a/docs/llm-gateway/features/prompt-store.md +++ b/docs/llm-gateway/features/prompt-store.md @@ -8,6 +8,30 @@ Manage and version system prompts centrally. ## How It Works + + 1. **Create** — Store a prompt with a unique ID (e.g., `code-reviewer`) 2. **Reference** — Use it as the system message content: `quilrai-prompt-store-code-reviewer` 3. **Gateway Resolves** — The gateway resolves the prompt and sends the full text to the LLM diff --git a/docs/llm-gateway/features/request-routing.md b/docs/llm-gateway/features/request-routing.md index 4a54f62..6906523 100644 --- a/docs/llm-gateway/features/request-routing.md +++ b/docs/llm-gateway/features/request-routing.md @@ -8,6 +8,31 @@ Multi-provider load balancing and failover behind a single API key. ## How It Works + + 1. **Create Group** — Define a named routing group (e.g., `Group1`) 2. **Add Models** — Add providers with traffic weights (e.g., `gpt-4o 60%`, `claude 40%`) 3. **Use as Model** — Pass the group name as the `model` parameter in your API call diff --git a/docs/llm-gateway/features/tags.md b/docs/llm-gateway/features/tags.md deleted file mode 100644 index 04622aa..0000000 --- a/docs/llm-gateway/features/tags.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Tags - -Organize and filter your API keys with custom labels. - -## Key Features - -- Add custom tags to any API key directly from the card -- Filter the keys list by tags using the top filter bar -- Tags are searchable — type a tag name in the search bar -- Tags are stored per app and persist across sessions - -## Details - -Tags let you categorize API keys by team, environment, use case, or any label you choose. Click the **+** button next to an app name to add tags. Tags can be removed by clicking the **x** on each tag pill. Use the **Tag filter** dropdown in the top bar to narrow down the list. Each tag can be up to 30 characters. diff --git a/docs/llm-gateway/features/token-saving.md b/docs/llm-gateway/features/token-saving.md index 959cd5c..de2b66a 100644 --- a/docs/llm-gateway/features/token-saving.md +++ b/docs/llm-gateway/features/token-saving.md @@ -8,6 +8,30 @@ Reduce token usage by compressing input content automatically. ## How It Works + + 1. **Request Arrives** — Your app sends a normal API call 2. **Gateway Compresses** — Content is transformed to use fewer tokens 3. **Forwarded to LLM** — Optimized content sent — same accuracy, lower cost diff --git a/docs/llm-gateway/quick-start.md b/docs/llm-gateway/quick-start.md index 0e47c6e..a3d36dc 100644 --- a/docs/llm-gateway/quick-start.md +++ b/docs/llm-gateway/quick-start.md @@ -6,6 +6,41 @@ sidebar_position: 1 Get up and running with the LLM Gateway in 4 steps. + + ## 1. Create an API Key Go to the **LLM Gateway** tab and click **Create New Key**. Select your provider (OpenAI, Anthropic, Azure, Bedrock, Vertex AI, or any OpenAI-compatible endpoint), choose which models to expose, and generate your key. diff --git a/docs/mcp-gateway/features/agents-configuration.md b/docs/mcp-gateway/features/agents-configuration.md index 0f4d5cc..a10d378 100644 --- a/docs/mcp-gateway/features/agents-configuration.md +++ b/docs/mcp-gateway/features/agents-configuration.md @@ -8,6 +8,33 @@ Map AI clients to MCPs and monitor per-agent usage. ## How It Works + + 1. **Register Agents** — Use predefined agents or create custom ones 2. **Map to MCPs** — Enable or disable MCPs per agent 3. **Monitor Usage** — Track per-agent tool call statistics diff --git a/docs/mcp-gateway/features/mcp-library.md b/docs/mcp-gateway/features/mcp-library.md index 565a45a..2b0ed92 100644 --- a/docs/mcp-gateway/features/mcp-library.md +++ b/docs/mcp-gateway/features/mcp-library.md @@ -8,6 +8,33 @@ One-click install pre-built MCP integrations from the catalog. ## How It Works + + 1. **Browse** — Open the MCP Library catalog 2. **Install** — One-click install, no URLs needed 3. **Configure** — Open Settings to customize tools and guardrails diff --git a/docs/mcp-gateway/features/oauth-connect.md b/docs/mcp-gateway/features/oauth-connect.md index a22dd31..a0b6a59 100644 --- a/docs/mcp-gateway/features/oauth-connect.md +++ b/docs/mcp-gateway/features/oauth-connect.md @@ -8,6 +8,33 @@ Authorize OAuth-protected MCP servers with one click. ## How It Works + + 1. **Probe URL** — The gateway detects the MCP server's auth requirements 2. **Authorize** — You're redirected to the MCP's OAuth authorization page 3. **Fetch Capabilities** — Tools, resources, and prompts are cached automatically diff --git a/docs/mcp-gateway/features/tools-management.md b/docs/mcp-gateway/features/tools-management.md index 976cb61..20096e0 100644 --- a/docs/mcp-gateway/features/tools-management.md +++ b/docs/mcp-gateway/features/tools-management.md @@ -8,6 +8,33 @@ Control which MCP tools are available to AI agents, organized by risk level. ## How It Works + + 1. **MCP Exposes Tools** — The server declares its available tools 2. **Gateway Categorizes** — Tools are sorted by risk level automatically 3. **Admin Controls** — Enable or disable each tool individually diff --git a/docs/mcp-gateway/features/web-search-policy.md b/docs/mcp-gateway/features/web-search-policy.md index f6d3a7d..82c1194 100644 --- a/docs/mcp-gateway/features/web-search-policy.md +++ b/docs/mcp-gateway/features/web-search-policy.md @@ -8,6 +8,33 @@ Filter web search domains using enterprise security gateway rules. ## How It Works + + 1. **Connect Gateway** — Link your enterprise security gateway 2. **Sync Rules** — Cache groups, users, and URL filter rules 3. **Enforce** — Domain checks run on every web search tool call diff --git a/docs/mcp-gateway/quick-start.md b/docs/mcp-gateway/quick-start.md index f5439c1..24b8773 100644 --- a/docs/mcp-gateway/quick-start.md +++ b/docs/mcp-gateway/quick-start.md @@ -6,6 +6,41 @@ sidebar_position: 1 Get up and running with MCP Gateway in 4 steps. +", + "mcpuser: user@company.com", + ], + }, + { + label: "Monitor", + items: [ + "Tool calls: 3,421", + "Agents: 4 connected", + "Blocked: 12 requests", + ], + }, +]} /> + ## 1. Add an MCP Server Go to the **MCP Gateway** tab and install from the **MCP Library** for one-click pre-built integrations, or click **Add MCP** to register any server by its transport URL (ending in `/sse` or `/mcp`). diff --git a/docusaurus.config.js b/docusaurus.config.js index ab6ce90..6da1beb 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -39,7 +39,13 @@ const config = { locales: ['en'], }, + markdown: { + mermaid: true, + format: 'mdx', + }, + themes: [ + '@docusaurus/theme-mermaid', [ // @ts-ignore '@easyops-cn/docusaurus-search-local', @@ -132,6 +138,21 @@ const config = { prism: { theme: prismLight, darkTheme: prismDark, + magicComments: [ + { + className: 'theme-code-block-highlighted-line', + line: 'highlight-next-line', + block: { start: 'highlight-start', end: 'highlight-end' }, + }, + { + className: 'code-block-diff-add-line', + line: 'diff-add', + }, + { + className: 'code-block-diff-remove-line', + line: 'diff-remove', + }, + ], }, }), }; diff --git a/package-lock.json b/package-lock.json index 1afadfa..24d066d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/theme-mermaid": "^3.9.2", "@easyops-cn/docusaurus-search-local": "^0.55.1", "@fontsource/geist": "^5.2.8", "@fontsource/geist-mono": "^5.2.7", @@ -276,6 +277,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -1989,6 +2003,51 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", + "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", + "license": "MIT" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz", + "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.1.2", + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz", + "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz", + "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz", + "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==", + "license": "Apache-2.0" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3929,6 +3988,34 @@ "react-dom": "^18.0.0 || ^19.0.0" } }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.9.2.tgz", + "integrity": "sha512-5vhShRDq/ntLzdInsQkTdoKWSzw8d1jB17sNPYhA/KvYYFXfuVEGHLM6nrf8MFbV8TruAHDG21Fn3W4lO8GaDw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "mermaid": ">=11.6.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@mermaid-js/layout-elk": "^0.1.9", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@mermaid-js/layout-elk": { + "optional": true + } + } + }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", @@ -4256,6 +4343,23 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz", + "integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "mlly": "^1.8.0" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -4809,6 +4913,15 @@ "react": ">=16" } }, + "node_modules/@mermaid-js/parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.0.1.tgz", + "integrity": "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==", + "license": "MIT", + "dependencies": { + "langium": "^4.0.0" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", @@ -5991,6 +6104,259 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", @@ -6059,6 +6425,12 @@ "@types/send": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/gtag.js": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", @@ -6295,6 +6667,13 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -6331,6 +6710,16 @@ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, + "node_modules/@upsetjs/venn.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", + "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==", + "license": "MIT", + "optionalDependencies": { + "d3-selection": "^3.0.0", + "d3-transition": "^3.0.1" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -7431,6 +7820,32 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz", + "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.1.2", + "@chevrotain/gast": "11.1.2", + "@chevrotain/regexp-to-ast": "11.1.2", + "@chevrotain/types": "11.1.2", + "@chevrotain/utils": "11.1.2", + "lodash-es": "4.17.23" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -7728,6 +8143,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -7928,6 +8349,15 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -8287,130 +8717,656 @@ "lilconfig": "^3.1.1" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/cytoscape": { + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", + "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "license": "MIT", + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" + "d3-array": "2 - 3" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=12" } }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "license": "MIT", + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" + "d3-time": "1 - 3" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=12" } }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=12" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { - "css-tree": "~2.2.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" + "node_modules/dagre-d3-es": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz", + "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", "license": "MIT" }, "node_modules/debounce": { @@ -8574,6 +9530,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -8722,6 +9687,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", @@ -9979,6 +10953,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -10666,6 +11646,15 @@ "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", "license": "MIT" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -11161,6 +12150,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.44", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.44.tgz", + "integrity": "sha512-EkxoDTk8ufHqHlf9QxGwcxeLkWRR3iOuYfRpfORgYfqc8s13bgb+YtRY59NK5ZpRaCwq1kqA6a5lpX8C/eLphQ==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -11170,6 +12184,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -11197,6 +12216,23 @@ "node": ">=6" } }, + "node_modules/langium": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-4.2.1.tgz", + "integrity": "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.1.1", + "chevrotain-allstar": "~0.3.1", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.1.0" + }, + "engines": { + "node": ">=20.10.0", + "npm": ">=10.2.3" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", @@ -11222,6 +12258,12 @@ "shell-quote": "^1.8.3" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -11558,6 +12600,12 @@ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -11678,6 +12726,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -12157,6 +13217,48 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.13.0.tgz", + "integrity": "sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.1.1", + "@iconify/utils": "^3.0.2", + "@mermaid-js/parser": "^1.0.1", + "@types/d3": "^7.4.3", + "@upsetjs/venn.js": "^2.0.0", + "cytoscape": "^3.33.1", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.14", + "dayjs": "^1.11.19", + "dompurify": "^3.3.1", + "katex": "^0.16.25", + "khroma": "^2.1.0", + "lodash-es": "^4.17.23", + "marked": "^16.3.0", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -14064,6 +15166,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -14520,6 +15634,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -14659,6 +15779,12 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -14707,6 +15833,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -14740,6 +15872,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/pkijs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", @@ -14757,6 +15900,22 @@ "node": ">=16.0.0" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", @@ -17186,6 +18345,24 @@ "node": ">=0.10.0" } }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -17239,6 +18416,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -18071,6 +19254,12 @@ "postcss": "^8.4.31" } }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18275,6 +19464,15 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "license": "MIT" }, + "node_modules/tinyexec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinypool": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", @@ -18350,6 +19548,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -18429,6 +19636,12 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, "node_modules/undici": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", @@ -18932,6 +20145,55 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" + }, "node_modules/watchpack": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", diff --git a/package.json b/package.json index 0dcd40f..6704e65 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/theme-mermaid": "^3.9.2", "@easyops-cn/docusaurus-search-local": "^0.55.1", "@fontsource/geist": "^5.2.8", "@fontsource/geist-mono": "^5.2.7", diff --git a/src/components/StepFlow/index.js b/src/components/StepFlow/index.js new file mode 100644 index 0000000..7f82dc4 --- /dev/null +++ b/src/components/StepFlow/index.js @@ -0,0 +1,66 @@ +import React from 'react'; +import styles from './styles.module.css'; + +function Chevron() { + return ( + + + + ); +} + +function renderLine(text) { + const parts = text.split(/(✓|✗)/g); + if (parts.length === 1) return text; + return parts.map((part, i) => { + if (part === '✓') return ; + if (part === '✗') return ; + return {part}; + }); +} + +export default function StepFlow({ steps = [] }) { + return ( +
+
+ {steps.map((step, i) => ( + + {i > 0 && ( + + )} +
+
+ {step.label} +
+
+ {(step.items || []).map((item, j) => ( +
+ {renderLine(item)} +
+ ))} +
+
+
+ ))} +
+
+ + QuilrAI +
+
+ ); +} diff --git a/src/components/StepFlow/styles.module.css b/src/components/StepFlow/styles.module.css new file mode 100644 index 0000000..e60e204 --- /dev/null +++ b/src/components/StepFlow/styles.module.css @@ -0,0 +1,205 @@ +/* ─── Wrapper ────────────────────────────────────────────────────────── */ +.wrapper { + border: 1px solid #e5e7eb; + border-radius: 0.75rem; + padding: 1.5rem 1.125rem 0.75rem; + background: #ffffff; + margin: 1.5rem 0; + position: relative; + overflow: hidden; +} + +.wrapper::before { + content: ""; + position: absolute; + inset: 0 0 auto 0; + height: 2.5px; + background: linear-gradient(90deg, #86efac, #34d399, #059669); +} + +:global([data-theme="dark"]) .wrapper { + background: #0f0f0f; + border-color: #262626; +} + +:global([data-theme="dark"]) .wrapper::before { + background: linear-gradient(90deg, #059669, #10b981, #34d399); +} + +/* ─── Horizontal card row ────────────────────────────────────────────── */ +.flow { + display: flex; + align-items: stretch; +} + +/* ─── Card ───────────────────────────────────────────────────────────── */ +.card { + flex: 1; + border: 1px solid #e5e7eb; + border-radius: 0.5rem; + overflow: hidden; + min-width: 0; + display: flex; + flex-direction: column; +} + +:global([data-theme="dark"]) .card { + border-color: #333; +} + +/* ─── Card header — green progression ────────────────────────────────── */ +.cardHeader { + padding: 0.45rem 0.75rem; + font-weight: 600; + font-size: 0.8125rem; + letter-spacing: 0.01em; + border-bottom: 1px solid #e5e7eb; +} + +:global([data-theme="dark"]) .cardHeader { + border-bottom-color: #333; +} + +/* Light mode */ +.cardHeader[data-step="0"] { + background: #f0fdf4; + color: #166534; +} +.cardHeader[data-step="1"] { + background: #dcfce7; + color: #15803d; +} +.cardHeader[data-step="2"] { + background: #d1fae5; + color: #059669; +} +.cardHeader[data-step="3"] { + background: #a7f3d0; + color: #047857; +} +.cardHeader[data-step="4"] { + background: #6ee7b7; + color: #065f46; +} +.cardHeader[data-step="5"] { + background: #34d399; + color: #064e3b; +} + +/* Dark mode */ +:global([data-theme="dark"]) .cardHeader[data-step="0"] { + background: rgba(74, 222, 128, 0.1); + color: #4ade80; +} +:global([data-theme="dark"]) .cardHeader[data-step="1"] { + background: rgba(52, 211, 153, 0.1); + color: #34d399; +} +:global([data-theme="dark"]) .cardHeader[data-step="2"] { + background: rgba(16, 185, 129, 0.1); + color: #10b981; +} +:global([data-theme="dark"]) .cardHeader[data-step="3"] { + background: rgba(5, 150, 105, 0.12); + color: #059669; +} +:global([data-theme="dark"]) .cardHeader[data-step="4"] { + background: rgba(4, 120, 87, 0.14); + color: #047857; +} +:global([data-theme="dark"]) .cardHeader[data-step="5"] { + background: rgba(6, 95, 70, 0.16); + color: #065f46; +} + +/* ─── Card body ──────────────────────────────────────────────────────── */ +.cardBody { + padding: 0.5rem 0.75rem; + flex: 1; +} + +.line { + font-family: var(--ifm-font-family-monospace); + font-size: 0.75rem; + line-height: 1.7; + color: var(--ifm-color-content-secondary, #64748b); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* ─── Status markers ─────────────────────────────────────────────────── */ +.check { + color: #16a34a; + font-weight: 600; +} + +.cross { + color: #dc2626; + font-weight: 600; +} + +:global([data-theme="dark"]) .check { + color: #4ade80; +} + +:global([data-theme="dark"]) .cross { + color: #f87171; +} + +/* ─── Chevron connector ──────────────────────────────────────────────── */ +.connector { + display: flex; + align-self: center; + flex-shrink: 0; + color: var(--ifm-color-primary, #059669); + opacity: 0.4; + padding: 0 2px; +} + +/* ─── Brand tag ──────────────────────────────────────────────────────── */ +.brand { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 5px; + font-size: 0.6875rem; + color: var(--ifm-color-primary, #059669); + font-weight: 600; + margin-top: 0.75rem; + letter-spacing: 0.04em; + opacity: 0.5; +} + +.brandDot { + width: 5px; + height: 5px; + border-radius: 50%; + background: currentColor; +} + +/* ─── Responsive ─────────────────────────────────────────────────────── */ +@media (max-width: 640px) { + .wrapper { + padding: 1.25rem 0.875rem 0.625rem; + } + + .flow { + flex-direction: column; + gap: 0; + } + + .card { + flex: none; + } + + .connector { + padding: 2px 0; + margin-left: 1rem; + transform: rotate(90deg); + } + + .line { + white-space: normal; + } +} diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js new file mode 100644 index 0000000..6c0ddaa --- /dev/null +++ b/src/theme/MDXComponents.js @@ -0,0 +1,7 @@ +import MDXComponents from '@theme-original/MDXComponents'; +import StepFlow from '@site/src/components/StepFlow'; + +export default { + ...MDXComponents, + StepFlow, +}; From 46f87f2216cef0e48c4ad1f78f46ccca47a5151c Mon Sep 17 00:00:00 2001 From: Praneeth Bedapudi Date: Sat, 28 Mar 2026 00:05:43 +0530 Subject: [PATCH 5/5] add architecture digrams and flow diagrasmsd Signed-off-by: Praneeth Bedapudi --- docs/llm-gateway/_category_.json | 2 +- docs/llm-gateway/architecture.md | 81 +++++ docs/llm-gateway/features/_category_.json | 2 +- docs/llm-gateway/features/custom-intents.md | 6 +- docs/llm-gateway/features/identity-aware.md | 14 +- docs/llm-gateway/features/prompt-store.md | 6 +- docs/llm-gateway/features/rate-limits.md | 8 +- docs/llm-gateway/features/request-routing.md | 8 +- .../features/security-guardrails.md | 14 +- docs/llm-gateway/features/token-saving.md | 14 +- docs/llm-gateway/integration-guide.md | 20 +- docs/llm-gateway/provider-support.md | 30 +- docs/llm-gateway/quick-start.md | 4 +- docs/mcp-gateway/_category_.json | 2 +- docs/mcp-gateway/features/_category_.json | 2 +- docs/mcp-gateway/features/access-control.md | 8 +- .../features/agents-configuration.md | 24 +- docs/mcp-gateway/features/api-tokens.md | 6 +- docs/mcp-gateway/features/mcp-library.md | 6 +- docs/mcp-gateway/features/oauth-connect.md | 10 +- .../features/security-guardrails.md | 28 +- docs/mcp-gateway/features/tools-management.md | 18 +- .../mcp-gateway/features/web-search-policy.md | 6 +- docs/mcp-gateway/integration-guide.md | 6 +- src/components/ArchitectureDiagram/index.js | 99 ++++++ .../ArchitectureDiagram/styles.module.css | 293 ++++++++++++++++++ src/theme/MDXComponents.js | 2 + 27 files changed, 597 insertions(+), 122 deletions(-) create mode 100644 docs/llm-gateway/architecture.md create mode 100644 src/components/ArchitectureDiagram/index.js create mode 100644 src/components/ArchitectureDiagram/styles.module.css diff --git a/docs/llm-gateway/_category_.json b/docs/llm-gateway/_category_.json index b09f1eb..6b4abdf 100644 --- a/docs/llm-gateway/_category_.json +++ b/docs/llm-gateway/_category_.json @@ -3,6 +3,6 @@ "position": 3, "link": { "type": "generated-index", - "description": "Unified API gateway for LLM providers — route, secure, monitor, and optimize all your LLM traffic through a single endpoint." + "description": "Unified API gateway for LLM providers - route, secure, monitor, and optimize all your LLM traffic through a single endpoint." } } diff --git a/docs/llm-gateway/architecture.md b/docs/llm-gateway/architecture.md new file mode 100644 index 0000000..aaf389a --- /dev/null +++ b/docs/llm-gateway/architecture.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 2 +--- + +# Architecture + +How the QuilrAI LLM Gateway processes every request - from your application to the LLM provider and back. + + + +## Pipeline Stages + +Every API request flows through these stages in order. Each stage is independently configurable per API key from the dashboard. + +| Stage | Description | Details | +|-------|-------------|---------| +| **Identity & Auth** | Validates request identity via JWT, JWKS, or header. Enforces domain restrictions. | [Identity Aware →](./features/identity-aware) | +| **Rate Limits** | Enforces request rates, token budgets, and key expiration before reaching the provider. | [Rate Limits →](./features/rate-limits) | +| **Security Guardrails** | Detects PII, PHI, PCI, and financial data. Catches prompt injection, jailbreak, and social engineering. | [Security Guardrails →](./features/security-guardrails) | +| **Custom Intents** | User-defined detection categories trained with positive and negative examples. | [Custom Intents →](./features/custom-intents) | +| **Prompt Store** | Resolves centralized system prompts by ID with template variable substitution. | [Prompt Store →](./features/prompt-store) | +| **Token Saving** | Compresses input tokens - JSON to TOON, HTML/Markdown to plain text. Responses unchanged. | [Token Saving →](./features/token-saving) | +| **Request Routing** | Routes to the optimal provider using weighted load balancing with automatic failover. | [Request Routing →](./features/request-routing) | + +## Response Path + +Responses from the LLM provider pass back through the **security guardrails** for output scanning before being returned to your application. The same detection categories and configurable actions (block, redact, anonymize, monitor) apply to both requests and responses. + +## Observability + +Every request is logged with cost, latency, token counts, and guardrail actions. Use the **Logs** tab to review request history and the **Red Team Testing** tool to [validate your guardrail configuration](./features/red-team-testing) against adversarial prompts. diff --git a/docs/llm-gateway/features/_category_.json b/docs/llm-gateway/features/_category_.json index 92f56cd..086eca1 100644 --- a/docs/llm-gateway/features/_category_.json +++ b/docs/llm-gateway/features/_category_.json @@ -3,6 +3,6 @@ "position": 3, "link": { "type": "generated-index", - "description": "Detailed documentation for each LLM Gateway capability — Routing, Token Saving, Guardrails, Prompt Store, Identity Aware, and more." + "description": "Detailed documentation for each LLM Gateway capability - Routing, Token Saving, Guardrails, Prompt Store, Identity Aware, and more." } } diff --git a/docs/llm-gateway/features/custom-intents.md b/docs/llm-gateway/features/custom-intents.md index 7b678df..ff0ef07 100644 --- a/docs/llm-gateway/features/custom-intents.md +++ b/docs/llm-gateway/features/custom-intents.md @@ -20,8 +20,8 @@ Custom intents extend the guardrails system with your own detection logic. Provi 1. **Name** your intent (e.g., `competitor-mentions`) 2. **Describe** what the intent should detect -3. **Add positive examples** — prompts that should trigger the intent -4. **Add negative examples** — prompts that should not trigger the intent -5. **Assign an action** — block, monitor, or redact +3. **Add positive examples** - prompts that should trigger the intent +4. **Add negative examples** - prompts that should not trigger the intent +5. **Assign an action** - block, monitor, or redact The classifier learns from your examples and applies the configured action when a match is detected. diff --git a/docs/llm-gateway/features/identity-aware.md b/docs/llm-gateway/features/identity-aware.md index 80b3f08..850ab57 100644 --- a/docs/llm-gateway/features/identity-aware.md +++ b/docs/llm-gateway/features/identity-aware.md @@ -32,21 +32,21 @@ Authenticate and track users behind each API key. }, ]} /> -1. **Request Arrives** — App sends an API call with identity info -2. **Gateway Identifies User** — Extracts identity via header or JWT token -3. **Per-User Tracking** — Usage tracked per user with rate limits and analytics +1. **Request Arrives** - App sends an API call with identity info +2. **Gateway Identifies User** - Extracts identity via header or JWT token +3. **Per-User Tracking** - Usage tracked per user with rate limits and analytics ## Authentication Modes -### Header Based — Recommended for trusted clients +### Header Based - Recommended for trusted clients -Uses the `X-User-Email` header to identify users. If your app handles user login and makes LLM calls from your own backend, this is the easiest and recommended approach — just pass the logged-in user's email as a header. +Uses the `X-User-Email` header to identify users. If your app handles user login and makes LLM calls from your own backend, this is the easiest and recommended approach - just pass the logged-in user's email as a header. ``` X-User-Email: user@company.com ``` -### JWKS Endpoint — For untrusted clients +### JWKS Endpoint - For untrusted clients Validates JWT tokens using a JWKS URL for dynamic key rotation. Ideal for production OAuth/OIDC flows with providers like Auth0, Okta, or Google. @@ -75,7 +75,7 @@ MIIBIjANBgkqh... ### Enforce Identity -When enabled, requests without valid identity (header or JWT) are **rejected at the gateway** — bare API key access is blocked. +When enabled, requests without valid identity (header or JWT) are **rejected at the gateway** - bare API key access is blocked. ### Allowed User Domains diff --git a/docs/llm-gateway/features/prompt-store.md b/docs/llm-gateway/features/prompt-store.md index 2e661ff..f5bf26f 100644 --- a/docs/llm-gateway/features/prompt-store.md +++ b/docs/llm-gateway/features/prompt-store.md @@ -32,9 +32,9 @@ Manage and version system prompts centrally. }, ]} /> -1. **Create** — Store a prompt with a unique ID (e.g., `code-reviewer`) -2. **Reference** — Use it as the system message content: `quilrai-prompt-store-code-reviewer` -3. **Gateway Resolves** — The gateway resolves the prompt and sends the full text to the LLM +1. **Create** - Store a prompt with a unique ID (e.g., `code-reviewer`) +2. **Reference** - Use it as the system message content: `quilrai-prompt-store-code-reviewer` +3. **Gateway Resolves** - The gateway resolves the prompt and sends the full text to the LLM ## Template Variables diff --git a/docs/llm-gateway/features/rate-limits.md b/docs/llm-gateway/features/rate-limits.md index 29f062c..ead9e28 100644 --- a/docs/llm-gateway/features/rate-limits.md +++ b/docs/llm-gateway/features/rate-limits.md @@ -12,10 +12,10 @@ Rate limits protect your LLM spend and availability. All limits are enforced at ## Key Features -- **Per-key rate limits** — Requests per minute, hour, or day -- **Token limits** — Input and output token budgets per request or over time -- **API key expiration** — Configurable epoch time for automatic key expiry -- **Response timeout** — Maximum wait time to prevent hung requests from consuming resources +- **Per-key rate limits** - Requests per minute, hour, or day +- **Token limits** - Input and output token budgets per request or over time +- **API key expiration** - Configurable epoch time for automatic key expiry +- **Response timeout** - Maximum wait time to prevent hung requests from consuming resources ## Configuration diff --git a/docs/llm-gateway/features/request-routing.md b/docs/llm-gateway/features/request-routing.md index 6906523..b0235aa 100644 --- a/docs/llm-gateway/features/request-routing.md +++ b/docs/llm-gateway/features/request-routing.md @@ -33,9 +33,9 @@ Multi-provider load balancing and failover behind a single API key. }, ]} /> -1. **Create Group** — Define a named routing group (e.g., `Group1`) -2. **Add Models** — Add providers with traffic weights (e.g., `gpt-4o 60%`, `claude 40%`) -3. **Use as Model** — Pass the group name as the `model` parameter in your API call +1. **Create Group** - Define a named routing group (e.g., `Group1`) +2. **Add Models** - Add providers with traffic weights (e.g., `gpt-4o 60%`, `claude 40%`) +3. **Use as Model** - Pass the group name as the `model` parameter in your API call ## Weight-Based Routing @@ -89,7 +89,7 @@ Group names can match actual model names. Your application keeps sending request |-----------|-----------| | `gpt-4.1` | `gpt-4.1-nano` (70%), `gpt-4.1-mini` (30%) | -Your code still sends `model="gpt-4.1"` — zero code changes, but requests get routed to cheaper or faster models behind the scenes. +Your code still sends `model="gpt-4.1"` - zero code changes, but requests get routed to cheaper or faster models behind the scenes. ## Code Examples diff --git a/docs/llm-gateway/features/security-guardrails.md b/docs/llm-gateway/features/security-guardrails.md index 554bbe0..8458f33 100644 --- a/docs/llm-gateway/features/security-guardrails.md +++ b/docs/llm-gateway/features/security-guardrails.md @@ -16,10 +16,10 @@ Contextual detection identifies sensitive data categories and applies the config ### Supported Categories -- **PII** — Personally Identifiable Information -- **PHI** — Protected Health Information -- **PCI** — Payment Card Industry data -- **Financial data** — Financial records and account information +- **PII** - Personally Identifiable Information +- **PHI** - Protected Health Information +- **PCI** - Payment Card Industry data +- **Financial data** - Financial records and account information ### Exact Data Matching (EDM) @@ -29,9 +29,9 @@ Pattern matching with custom EDM rules for specific data formats. Catches adversarial attack patterns in requests: -- **Prompt injection** — Attempts to override system instructions -- **Jailbreak** — Attempts to bypass safety controls -- **Social engineering** — Manipulation attempts targeting the AI model +- **Prompt injection** - Attempts to override system instructions +- **Jailbreak** - Attempts to bypass safety controls +- **Social engineering** - Manipulation attempts targeting the AI model ## Configurable Actions diff --git a/docs/llm-gateway/features/token-saving.md b/docs/llm-gateway/features/token-saving.md index de2b66a..7ee2108 100644 --- a/docs/llm-gateway/features/token-saving.md +++ b/docs/llm-gateway/features/token-saving.md @@ -32,15 +32,15 @@ Reduce token usage by compressing input content automatically. }, ]} /> -1. **Request Arrives** — Your app sends a normal API call -2. **Gateway Compresses** — Content is transformed to use fewer tokens -3. **Forwarded to LLM** — Optimized content sent — same accuracy, lower cost +1. **Request Arrives** - Your app sends a normal API call +2. **Gateway Compresses** - Content is transformed to use fewer tokens +3. **Forwarded to LLM** - Optimized content sent - same accuracy, lower cost ## Compression Methods -### Smart JSON Compression — Up to 20% savings +### Smart JSON Compression - Up to 20% savings -Converts JSON objects in LLM inputs to TOON format — ideal for tool call responses and structured data. +Converts JSON objects in LLM inputs to TOON format - ideal for tool call responses and structured data. | Before | After | |--------|-------| @@ -48,7 +48,7 @@ Converts JSON objects in LLM inputs to TOON format — ideal for tool call respo ### HTML to Text -Strips HTML tags and extracts clean text — removes markup overhead from scraped pages or rich content. +Strips HTML tags and extracts clean text - removes markup overhead from scraped pages or rich content. | Before | After | |--------|-------| @@ -64,4 +64,4 @@ Removes Markdown syntax characters that consume tokens without adding meaning fo ## Seamless and Input-Only -Compression is applied **only to input tokens** before they reach the LLM. Responses are returned untouched. Your application code stays exactly the same — no SDK changes, no prompt rewrites, just lower costs. +Compression is applied **only to input tokens** before they reach the LLM. Responses are returned untouched. Your application code stays exactly the same - no SDK changes, no prompt rewrites, just lower costs. diff --git a/docs/llm-gateway/integration-guide.md b/docs/llm-gateway/integration-guide.md index 7fa81d3..b23ed80 100644 --- a/docs/llm-gateway/integration-guide.md +++ b/docs/llm-gateway/integration-guide.md @@ -1,10 +1,10 @@ --- -sidebar_position: 2 +sidebar_position: 3 --- # Integration Guide -Connect to the QuilrAI gateway in minutes — same SDK, one-line change. +Connect to the QuilrAI gateway in minutes - same SDK, one-line change. ## 1. Choose Your Endpoint @@ -32,7 +32,7 @@ https://guardrails.quilr.ai/openai_compatible/ ## 2. Code Examples -### OpenAI — Python +### OpenAI - Python ```python from openai import OpenAI @@ -62,7 +62,7 @@ embedding = client.embeddings.create( print(embedding.data[0].embedding[:5]) ``` -### OpenAI — JavaScript +### OpenAI - JavaScript ```javascript import OpenAI from "openai"; @@ -85,7 +85,7 @@ const response = await client.chat.completions.create({ console.log(response.choices[0].message.content); ``` -### OpenAI — cURL +### OpenAI - cURL ```bash # Point the request to QuilrAI's gateway @@ -104,7 +104,7 @@ curl https://guardrails.quilr.ai/openai_compatible/v1/chat/completions \ }' ``` -### Anthropic — Python +### Anthropic - Python ```python import anthropic @@ -130,7 +130,7 @@ message = client.messages.create( print(message.content[0].text) ``` -### Anthropic — JavaScript +### Anthropic - JavaScript ```javascript import Anthropic from "@anthropic-ai/sdk"; @@ -156,7 +156,7 @@ const message = await client.messages.create({ console.log(message.content[0].text); ``` -### Anthropic — cURL +### Anthropic - cURL ```bash # Point the request to QuilrAI's gateway @@ -177,7 +177,7 @@ curl https://guardrails.quilr.ai/anthropic_messages/v1/messages \ }' ``` -### Vertex AI — Google GenAI SDK +### Vertex AI - Google GenAI SDK ```python from google import genai @@ -248,7 +248,7 @@ response = client.models.generate_content( print(response.text) ``` -### Vertex AI — LangChain +### Vertex AI - LangChain ```python # diff-remove diff --git a/docs/llm-gateway/provider-support.md b/docs/llm-gateway/provider-support.md index 69168b6..ef5c4af 100644 --- a/docs/llm-gateway/provider-support.md +++ b/docs/llm-gateway/provider-support.md @@ -16,13 +16,13 @@ Your app authenticates to the gateway using a QuilrAI API key. Provider credenti |----------|:----:|:----------:|:---:|:---:|:------:| | OpenAI | ✓ | ✓ | ✓ | ✓ | ✓ | | Azure OpenAI | ✓ | ✓ | ✓ | ✓ | ✓ | -| Anthropic (Chat Completions) | ✓ | — | — | — | ✓ | -| DeepSeek | ✓ | — | — | — | ✓ | -| Gemini (Chat Completions) | ✓ | — | — | — | ✓ | -| General LLM | ✓ | — | — | — | ✓ | -| Anthropic (Messages) | ✓ | — | — | — | — | -| AWS Bedrock (Anthropic) | ✓ | — | — | — | — | -| Vertex AI | ✓ | — | — | — | — | +| Anthropic (Chat Completions) | ✓ | - | - | - | ✓ | +| DeepSeek | ✓ | - | - | - | ✓ | +| Gemini (Chat Completions) | ✓ | - | - | - | ✓ | +| General LLM | ✓ | - | - | - | ✓ | +| Anthropic (Messages) | ✓ | - | - | - | - | +| AWS Bedrock (Anthropic) | ✓ | - | - | - | - | +| Vertex AI | ✓ | - | - | - | - | ## Chat Completions @@ -31,12 +31,12 @@ Your app authenticates to the gateway using a QuilrAI API key. Provider credenti | Provider | Auth Mode | Required Fields | Optional Fields | |----------|-----------|-----------------|-----------------| -| OpenAI | API Key | `api_key` | — | +| OpenAI | API Key | `api_key` | - | | Azure OpenAI | API Key | `api_key`, `azure_endpoint` | `azure_api_version` | -| Anthropic (OpenAI-compatible) | API Key | `api_key` | — | -| DeepSeek | API Key | `api_key` | — | -| Gemini (OpenAI-compatible) | API Key | `api_key` | — | -| General LLM (vLLM, Ollama, etc.) | API Key | `api_key`, `base_url` | — | +| Anthropic (OpenAI-compatible) | API Key | `api_key` | - | +| DeepSeek | API Key | `api_key` | - | +| Gemini (OpenAI-compatible) | API Key | `api_key` | - | +| General LLM (vLLM, Ollama, etc.) | API Key | `api_key`, `base_url` | - | ## Anthropic Messages @@ -45,7 +45,7 @@ Your app authenticates to the gateway using a QuilrAI API key. Provider credenti | Provider | Auth Mode | Required Fields | Optional Fields | |----------|-----------|-----------------|-----------------| -| Anthropic (Native Messages API) | API Key | `api_key` | — | +| Anthropic (Native Messages API) | API Key | `api_key` | - | | AWS Bedrock (Anthropic via Bedrock) | AWS Credentials | `aws_access_key`, `aws_secret_key` | `aws_region`, `aws_session_token` | AWS Bedrock default region: `us-east-1` @@ -60,7 +60,7 @@ Vertex AI supports multiple authentication modes. Select the mode when creating | Auth Mode | Required Fields | Optional Fields | Notes | |-----------|-----------------|-----------------|-------| | API Key | `api_key`, `gcp_project_id` | `gcp_region` | Default region: `us-central1` | -| Express | `api_key` | — | No project ID needed | +| Express | `api_key` | - | No project ID needed | | Service Account | `service_account_json` | `gcp_project_id`, `gcp_region` | Project ID derived from JSON if omitted | | ADC | `gcp_project_id` | `gcp_region` | Application Default Credentials from environment | @@ -86,7 +86,7 @@ Support for OpenAI's Responses API format is in development. **API Endpoint:** `/sdk/v1/check` **Auth:** `Authorization: Bearer sk-quilr-xxx` -The SDK provides guardrails-only scanning — no upstream LLM provider needed. Check text for PII, PHI, adversarial prompts, and custom intents without forwarding to any model. +The SDK provides guardrails-only scanning - no upstream LLM provider needed. Check text for PII, PHI, adversarial prompts, and custom intents without forwarding to any model. ### Python diff --git a/docs/llm-gateway/quick-start.md b/docs/llm-gateway/quick-start.md index a3d36dc..79e0785 100644 --- a/docs/llm-gateway/quick-start.md +++ b/docs/llm-gateway/quick-start.md @@ -45,11 +45,11 @@ Get up and running with the LLM Gateway in 4 steps. Go to the **LLM Gateway** tab and click **Create New Key**. Select your provider (OpenAI, Anthropic, Azure, Bedrock, Vertex AI, or any OpenAI-compatible endpoint), choose which models to expose, and generate your key. -Your provider API key is stored securely — developers only see the QuilrAI proxy key. +Your provider API key is stored securely - developers only see the QuilrAI proxy key. ## 2. Swap the Base URL -Replace your provider's base URL with the QuilrAI gateway URL and use your QuilrAI key. Everything else — SDK, parameters, response format — stays exactly the same. +Replace your provider's base URL with the QuilrAI gateway URL and use your QuilrAI key. Everything else - SDK, parameters, response format - stays exactly the same. ```python # Point the client to QuilrAI's gateway diff --git a/docs/mcp-gateway/_category_.json b/docs/mcp-gateway/_category_.json index b558bae..3cc6306 100644 --- a/docs/mcp-gateway/_category_.json +++ b/docs/mcp-gateway/_category_.json @@ -3,6 +3,6 @@ "position": 2, "link": { "type": "generated-index", - "description": "Enterprise-grade management layer for MCP servers — install, configure, secure, and monitor MCP integrations used by AI agents." + "description": "Enterprise-grade management layer for MCP servers - install, configure, secure, and monitor MCP integrations used by AI agents." } } diff --git a/docs/mcp-gateway/features/_category_.json b/docs/mcp-gateway/features/_category_.json index d6f068f..37ffa23 100644 --- a/docs/mcp-gateway/features/_category_.json +++ b/docs/mcp-gateway/features/_category_.json @@ -3,6 +3,6 @@ "position": 3, "link": { "type": "generated-index", - "description": "Detailed documentation for each MCP Gateway capability — MCP Library, Tools Management, Guardrails, Access Control, and more." + "description": "Detailed documentation for each MCP Gateway capability - MCP Library, Tools Management, Guardrails, Access Control, and more." } } diff --git a/docs/mcp-gateway/features/access-control.md b/docs/mcp-gateway/features/access-control.md index 7013ef3..c7bc4d4 100644 --- a/docs/mcp-gateway/features/access-control.md +++ b/docs/mcp-gateway/features/access-control.md @@ -12,10 +12,10 @@ Access Control lets you restrict each MCP to specific AI agents. When enabled, o ## How It Works -- **Per-MCP agent-level access control** — Configure allowed agents for each MCP independently -- **Toggle access for predefined agents** — OpenAI, Claude, Cursor, Gemini -- **Support for custom agents** — User-Agent keyword matching for any AI client -- **Changes take effect immediately** — No restart needed +- **Per-MCP agent-level access control** - Configure allowed agents for each MCP independently +- **Toggle access for predefined agents** - OpenAI, Claude, Cursor, Gemini +- **Support for custom agents** - User-Agent keyword matching for any AI client +- **Changes take effect immediately** - No restart needed ## Predefined Agents diff --git a/docs/mcp-gateway/features/agents-configuration.md b/docs/mcp-gateway/features/agents-configuration.md index a10d378..ac6ca9d 100644 --- a/docs/mcp-gateway/features/agents-configuration.md +++ b/docs/mcp-gateway/features/agents-configuration.md @@ -35,9 +35,9 @@ Map AI clients to MCPs and monitor per-agent usage. }, ]} /> -1. **Register Agents** — Use predefined agents or create custom ones -2. **Map to MCPs** — Enable or disable MCPs per agent -3. **Monitor Usage** — Track per-agent tool call statistics +1. **Register Agents** - Use predefined agents or create custom ones +2. **Map to MCPs** - Enable or disable MCPs per agent +3. **Monitor Usage** - Track per-agent tool call statistics ## Predefined Agents @@ -54,28 +54,28 @@ Built-in agents are identified by their User-Agent header keywords: Create custom agents for any AI client not in the predefined list. Each custom agent requires: -- **User-Agent Keyword** — The keyword to match in the User-Agent header (e.g., `my-custom-agent`) -- **Display Name** — A human-readable name for the dashboard (e.g., `My Custom Agent`) +- **User-Agent Keyword** - The keyword to match in the User-Agent header (e.g., `my-custom-agent`) +- **Display Name** - A human-readable name for the dashboard (e.g., `My Custom Agent`) ## Per-Agent Dashboard Each agent card shows: -- **Total tool calls** — Cumulative tool invocations for the agent -- **MCP access** — Which MCPs are enabled vs. disabled -- **Toggle controls** — Enable or disable individual MCP access per agent directly from this view +- **Total tool calls** - Cumulative tool invocations for the agent +- **MCP access** - Which MCPs are enabled vs. disabled +- **Toggle controls** - Enable or disable individual MCP access per agent directly from this view ### Example | Agent | Tool Calls | MCPs | |-------|-----------|------| -| OpenAI | 1,247 | GitHub, Slack, Jira, Confluence (enabled) — S3, Internal API (disabled) | +| OpenAI | 1,247 | GitHub, Slack, Jira, Confluence (enabled) - S3, Internal API (disabled) | ## Agents Configuration vs. Access Control | View | Best For | |------|----------| -| **Agents Configuration** | Global view — see all MCPs for each agent. Best for managing agent permissions across your entire MCP fleet. | -| **Access Control** | Per-MCP view — see all agents for one MCP. Best when configuring a single MCP's permissions. | +| **Agents Configuration** | Global view - see all MCPs for each agent. Best for managing agent permissions across your entire MCP fleet. | +| **Access Control** | Per-MCP view - see all agents for one MCP. Best when configuring a single MCP's permissions. | -Both views control the same underlying permissions — use whichever is more convenient for your workflow. +Both views control the same underlying permissions - use whichever is more convenient for your workflow. diff --git a/docs/mcp-gateway/features/api-tokens.md b/docs/mcp-gateway/features/api-tokens.md index 3c65e7b..d5d24a3 100644 --- a/docs/mcp-gateway/features/api-tokens.md +++ b/docs/mcp-gateway/features/api-tokens.md @@ -14,7 +14,7 @@ API tokens provide programmatic access to MCP servers that don't use OAuth. Each - **Create named API tokens** for non-OAuth MCPs - **Assign each token to a specific agent** (OpenAI, Claude, Cursor, or custom) -- **Token shown once at creation** — copy immediately +- **Token shown once at creation** - copy immediately - **Revoke tokens at any time** from the Settings panel - **Track last-used date** per token for auditing @@ -34,7 +34,7 @@ mcpuser: user@company.com ## Security -- Tokens are displayed **only once** at creation — copy and store them securely +- Tokens are displayed **only once** at creation - copy and store them securely - Revoke any token instantly from the Settings panel - Each token tracks its last usage timestamp for auditing -- Tokens are scoped to a specific agent — a token created for OpenAI cannot be used by Claude +- Tokens are scoped to a specific agent - a token created for OpenAI cannot be used by Claude diff --git a/docs/mcp-gateway/features/mcp-library.md b/docs/mcp-gateway/features/mcp-library.md index 2b0ed92..a2c6afc 100644 --- a/docs/mcp-gateway/features/mcp-library.md +++ b/docs/mcp-gateway/features/mcp-library.md @@ -35,9 +35,9 @@ One-click install pre-built MCP integrations from the catalog. }, ]} /> -1. **Browse** — Open the MCP Library catalog -2. **Install** — One-click install, no URLs needed -3. **Configure** — Open Settings to customize tools and guardrails +1. **Browse** - Open the MCP Library catalog +2. **Install** - One-click install, no URLs needed +3. **Configure** - Open Settings to customize tools and guardrails ## Pre-Built Integrations diff --git a/docs/mcp-gateway/features/oauth-connect.md b/docs/mcp-gateway/features/oauth-connect.md index a0b6a59..fd544d7 100644 --- a/docs/mcp-gateway/features/oauth-connect.md +++ b/docs/mcp-gateway/features/oauth-connect.md @@ -35,15 +35,15 @@ Authorize OAuth-protected MCP servers with one click. }, ]} /> -1. **Probe URL** — The gateway detects the MCP server's auth requirements -2. **Authorize** — You're redirected to the MCP's OAuth authorization page -3. **Fetch Capabilities** — Tools, resources, and prompts are cached automatically +1. **Probe URL** - The gateway detects the MCP server's auth requirements +2. **Authorize** - You're redirected to the MCP's OAuth authorization page +3. **Fetch Capabilities** - Tools, resources, and prompts are cached automatically ## OAuth Modes -### Dynamic Client Registration (DCR) — Recommended +### Dynamic Client Registration (DCR) - Recommended -The gateway automatically registers as an OAuth client with the MCP server. No Client ID or Secret needed — just click **Connect** and authorize. +The gateway automatically registers as an OAuth client with the MCP server. No Client ID or Secret needed - just click **Connect** and authorize. ### Manual OAuth diff --git a/docs/mcp-gateway/features/security-guardrails.md b/docs/mcp-gateway/features/security-guardrails.md index 74e4454..8a1c937 100644 --- a/docs/mcp-gateway/features/security-guardrails.md +++ b/docs/mcp-gateway/features/security-guardrails.md @@ -8,7 +8,7 @@ Detect and act on sensitive data in MCP tool call inputs and outputs. ## Overview -Security guardrails inspect data flowing through MCP tool calls — both the inputs your agent sends and the outputs the tool returns. Each category can be independently enabled with separate request and response actions. +Security guardrails inspect data flowing through MCP tool calls - both the inputs your agent sends and the outputs the tool returns. Each category can be independently enabled with separate request and response actions. ## Data Risk Detection @@ -16,12 +16,12 @@ Identifies sensitive data categories and applies the configured action. ### Supported Categories -- **PII** — Personally Identifiable Information -- **PHI** — Protected Health Information -- **PFI** — Personal Financial Information -- **PCI** — Payment Card Industry data -- **Insurance** — Insurance-related sensitive data -- **Auth & Secrets** — Authentication credentials and secrets +- **PII** - Personally Identifiable Information +- **PHI** - Protected Health Information +- **PFI** - Personal Financial Information +- **PCI** - Payment Card Industry data +- **Insurance** - Insurance-related sensitive data +- **Auth & Secrets** - Authentication credentials and secrets ### Exact Data Matching (EDM) @@ -41,11 +41,11 @@ Pattern matching for specific data formats: Catches adversarial attack patterns in tool call data: -- **Prompt injection** — Attempts to override agent instructions -- **Jailbreak** — Attempts to bypass safety controls -- **Context corruption** — Attempts to pollute agent context -- **Semantic adversarial** — Semantically crafted adversarial inputs -- **Social engineering** — Manipulation attempts targeting the AI agent +- **Prompt injection** - Attempts to override agent instructions +- **Jailbreak** - Attempts to bypass safety controls +- **Context corruption** - Attempts to pollute agent context +- **Semantic adversarial** - Semantically crafted adversarial inputs +- **Social engineering** - Manipulation attempts targeting the AI agent ## Configurable Actions @@ -60,5 +60,5 @@ Each detection category supports per-direction actions: Actions are configured independently for: -- **Request (input)** — Data the agent sends to the MCP tool -- **Response (output)** — Data the MCP tool returns to the agent +- **Request (input)** - Data the agent sends to the MCP tool +- **Response (output)** - Data the MCP tool returns to the agent diff --git a/docs/mcp-gateway/features/tools-management.md b/docs/mcp-gateway/features/tools-management.md index 20096e0..78f3769 100644 --- a/docs/mcp-gateway/features/tools-management.md +++ b/docs/mcp-gateway/features/tools-management.md @@ -35,27 +35,27 @@ Control which MCP tools are available to AI agents, organized by risk level. }, ]} /> -1. **MCP Exposes Tools** — The server declares its available tools -2. **Gateway Categorizes** — Tools are sorted by risk level automatically -3. **Admin Controls** — Enable or disable each tool individually +1. **MCP Exposes Tools** - The server declares its available tools +2. **Gateway Categorizes** - Tools are sorted by risk level automatically +3. **Admin Controls** - Enable or disable each tool individually ## Tool Categories -### Read Only — Low Risk +### Read Only - Low Risk -Tools that only read data. Safe to enable by default — no modifications to external systems. +Tools that only read data. Safe to enable by default - no modifications to external systems. Examples: `get_file`, `list_repos`, `search_docs`, `read_database` -### Write Access — Medium Risk +### Write Access - Medium Risk -Tools that create or modify data. Review before enabling — changes can be undone but may have side effects. +Tools that create or modify data. Review before enabling - changes can be undone but may have side effects. Examples: `create_issue`, `update_record`, `send_message`, `write_file` -### Destructive — High Risk +### Destructive - High Risk -Tools that delete or irreversibly modify data. Disabled by default — enable only when explicitly needed. +Tools that delete or irreversibly modify data. Disabled by default - enable only when explicitly needed. Examples: `delete_repo`, `drop_table`, `revoke_access`, `purge_data` diff --git a/docs/mcp-gateway/features/web-search-policy.md b/docs/mcp-gateway/features/web-search-policy.md index 82c1194..bd94ad2 100644 --- a/docs/mcp-gateway/features/web-search-policy.md +++ b/docs/mcp-gateway/features/web-search-policy.md @@ -35,9 +35,9 @@ Filter web search domains using enterprise security gateway rules. }, ]} /> -1. **Connect Gateway** — Link your enterprise security gateway -2. **Sync Rules** — Cache groups, users, and URL filter rules -3. **Enforce** — Domain checks run on every web search tool call +1. **Connect Gateway** - Link your enterprise security gateway +2. **Sync Rules** - Cache groups, users, and URL filter rules +3. **Enforce** - Domain checks run on every web search tool call ## Supported Security Gateways diff --git a/docs/mcp-gateway/integration-guide.md b/docs/mcp-gateway/integration-guide.md index fbedf72..6f86b84 100644 --- a/docs/mcp-gateway/integration-guide.md +++ b/docs/mcp-gateway/integration-guide.md @@ -31,11 +31,11 @@ mcpuser: user@company.com - Each token is scoped to a specific agent - The `mcpuser` header identifies the end user for per-user tracking -### OAuth — Dynamic Client Registration (DCR) +### OAuth - Dynamic Client Registration (DCR) -The gateway automatically registers as an OAuth client with the MCP server. No Client ID or Secret needed — just click **Connect** and authorize. +The gateway automatically registers as an OAuth client with the MCP server. No Client ID or Secret needed - just click **Connect** and authorize. -### OAuth — Manual +### OAuth - Manual For MCP servers without DCR support. Provide your **Client ID** and **Client Secret** during MCP setup. The gateway uses these credentials for the authorization flow. diff --git a/src/components/ArchitectureDiagram/index.js b/src/components/ArchitectureDiagram/index.js new file mode 100644 index 0000000..6521d04 --- /dev/null +++ b/src/components/ArchitectureDiagram/index.js @@ -0,0 +1,99 @@ +import React from 'react'; +import styles from './styles.module.css'; + +function DownArrow({ small }) { + if (small) { + return ( + + ); + } + return ( + + ); +} + +function Chevron() { + return ( + + ); +} + +export default function ArchitectureDiagram({ source, gateway, destination }) { + return ( +
+ {/* Source */} +
+
{source.label}
+
{source.code}
+
+ + + + {/* Gateway */} +
+
{gateway.label}
+
+ {gateway.phases.map((phase, pi) => ( + + {pi > 0 && } +
+ {phase.label && ( +
{phase.label}
+ )} +
+ {phase.stages.map((stage, si) => ( + + {si > 0 && } +
+
{stage.label}
+
+ {(stage.items || []).map((item, k) => ( +
{item}
+ ))} +
+
+
+ ))} +
+
+
+ ))} + {gateway.footer && ( +
{gateway.footer}
+ )} +
+
+ + + + {/* Destination */} +
+
{destination.label}
+
+ {destination.items.map((item, i) => ( + {item} + ))} +
+
+ +
+ + QuilrAI +
+
+ ); +} diff --git a/src/components/ArchitectureDiagram/styles.module.css b/src/components/ArchitectureDiagram/styles.module.css new file mode 100644 index 0000000..c13f29e --- /dev/null +++ b/src/components/ArchitectureDiagram/styles.module.css @@ -0,0 +1,293 @@ +/* ─── Wrapper ────────────────────────────────────────────────────────── */ +.wrapper { + border: 1px solid #e5e7eb; + border-radius: 0.75rem; + padding: 1.5rem 1.125rem 0.75rem; + background: #ffffff; + margin: 1.5rem 0; + position: relative; + overflow: hidden; +} + +.wrapper::before { + content: ""; + position: absolute; + inset: 0 0 auto 0; + height: 2.5px; + background: linear-gradient(90deg, #86efac, #34d399, #059669); +} + +:global([data-theme="dark"]) .wrapper { + background: #0f0f0f; + border-color: #262626; +} + +:global([data-theme="dark"]) .wrapper::before { + background: linear-gradient(90deg, #059669, #10b981, #34d399); +} + +/* ─── External boxes (source / destination) ──────────────────────────── */ +.externalBox { + border: 1px solid #e5e7eb; + border-radius: 0.5rem; + overflow: hidden; +} + +:global([data-theme="dark"]) .externalBox { + border-color: #333; +} + +.externalHeader { + padding: 0.45rem 0.75rem; + font-weight: 600; + font-size: 0.8125rem; + letter-spacing: 0.01em; + border-bottom: 1px solid #e5e7eb; + background: #f8fafc; + color: #475569; +} + +:global([data-theme="dark"]) .externalHeader { + border-bottom-color: #333; + background: rgba(148, 163, 184, 0.08); + color: #94a3b8; +} + +/* ─── Code block ─────────────────────────────────────────────────────── */ +.codeBlock { + margin: 0; + padding: 0.625rem 0.75rem; + font-family: var(--ifm-font-family-monospace); + font-size: 0.6875rem; + line-height: 1.7; + background: transparent; + color: var(--ifm-color-content-secondary, #64748b); + overflow-x: auto; + border: none; + white-space: pre; +} + +/* ─── Down arrow ─────────────────────────────────────────────────────── */ +.arrow { + display: flex; + justify-content: center; + padding: 0.375rem 0; + color: var(--ifm-color-primary, #059669); + opacity: 0.4; +} + +.arrowSmall { + padding: 0.2rem 0; + opacity: 0.3; +} + +/* ─── Gateway box ────────────────────────────────────────────────────── */ +.gatewayBox { + border: 1.5px solid #10b981; + border-radius: 0.75rem; + overflow: hidden; +} + +:global([data-theme="dark"]) .gatewayBox { + border-color: #059669; +} + +.gatewayHeader { + padding: 0.6rem 1rem; + font-weight: 700; + font-size: 0.875rem; + letter-spacing: 0.02em; + background: linear-gradient(135deg, #059669, #10b981); + color: white; +} + +.gatewayBody { + padding: 1rem; +} + +:global([data-theme="dark"]) .gatewayBody { + background: rgba(5, 150, 105, 0.02); +} + +/* ─── Phase ──────────────────────────────────────────────────────────── */ +.phaseLabel { + font-size: 0.625rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--ifm-color-content-secondary, #94a3b8); + margin-bottom: 0.375rem; + opacity: 0.6; +} + +.phaseStages { + display: flex; + align-items: stretch; +} + +/* ─── Chevron between stages ─────────────────────────────────────────── */ +.chevron { + display: flex; + align-self: center; + flex-shrink: 0; + color: var(--ifm-color-primary, #059669); + opacity: 0.35; + padding: 0 3px; +} + +/* ─── Stage card ─────────────────────────────────────────────────────── */ +.stage { + flex: 1; + min-width: 0; + border: 1px solid #e5e7eb; + border-radius: 0.375rem; + overflow: hidden; + background: white; + display: flex; + flex-direction: column; +} + +:global([data-theme="dark"]) .stage { + border-color: #333; + background: #0f0f0f; +} + +.stageName { + padding: 0.3rem 0.625rem; + font-weight: 600; + font-size: 0.75rem; + letter-spacing: 0.01em; + border-bottom: 1px solid #e5e7eb; +} + +:global([data-theme="dark"]) .stageName { + border-bottom-color: #333; +} + +/* Phase color progression — light mode */ +.stage[data-phase="0"] .stageName { background: #f0fdf4; color: #166534; } +.stage[data-phase="1"] .stageName { background: #dcfce7; color: #15803d; } +.stage[data-phase="2"] .stageName { background: #d1fae5; color: #059669; } +.stage[data-phase="3"] .stageName { background: #a7f3d0; color: #047857; } + +/* Phase color progression — dark mode */ +:global([data-theme="dark"]) .stage[data-phase="0"] .stageName { + background: rgba(74, 222, 128, 0.1); + color: #4ade80; +} +:global([data-theme="dark"]) .stage[data-phase="1"] .stageName { + background: rgba(52, 211, 153, 0.1); + color: #34d399; +} +:global([data-theme="dark"]) .stage[data-phase="2"] .stageName { + background: rgba(16, 185, 129, 0.1); + color: #10b981; +} +:global([data-theme="dark"]) .stage[data-phase="3"] .stageName { + background: rgba(5, 150, 105, 0.12); + color: #059669; +} + +.stageBody { + padding: 0.25rem 0.625rem 0.375rem; + flex: 1; +} + +.stageItem { + font-family: var(--ifm-font-family-monospace); + font-size: 0.6875rem; + line-height: 1.65; + color: var(--ifm-color-content-secondary, #64748b); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* ─── Gateway footer ─────────────────────────────────────────────────── */ +.gatewayFooter { + margin-top: 0.75rem; + padding: 0.45rem 0.75rem; + border: 1px dashed #d1d5db; + border-radius: 0.375rem; + font-size: 0.75rem; + font-weight: 500; + color: var(--ifm-color-content-secondary, #64748b); + text-align: center; + letter-spacing: 0.02em; +} + +:global([data-theme="dark"]) .gatewayFooter { + border-color: #333; +} + +/* ─── Destination grid ───────────────────────────────────────────────── */ +.destGrid { + display: flex; + flex-wrap: wrap; + gap: 0.375rem; + padding: 0.625rem 0.75rem; +} + +.destPill { + font-family: var(--ifm-font-family-monospace); + font-size: 0.6875rem; + padding: 0.2rem 0.5rem; + border-radius: 0.25rem; + background: #f0fdf4; + border: 1px solid #d1fae5; + color: #059669; + font-weight: 500; +} + +:global([data-theme="dark"]) .destPill { + background: rgba(5, 150, 105, 0.08); + border-color: rgba(5, 150, 105, 0.2); + color: #34d399; +} + +/* ─── Brand tag ──────────────────────────────────────────────────────── */ +.brand { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 5px; + font-size: 0.6875rem; + color: var(--ifm-color-primary, #059669); + font-weight: 600; + margin-top: 0.75rem; + letter-spacing: 0.04em; + opacity: 0.5; +} + +.brandDot { + width: 5px; + height: 5px; + border-radius: 50%; + background: currentColor; +} + +/* ─── Responsive ─────────────────────────────────────────────────────── */ +@media (max-width: 640px) { + .wrapper { + padding: 1.25rem 0.875rem 0.625rem; + } + + .phaseStages { + flex-direction: column; + gap: 0; + } + + .stage { + flex: none; + } + + .chevron { + padding: 2px 0; + margin-left: 1rem; + transform: rotate(90deg); + } + + .stageItem { + white-space: normal; + } +} diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js index 6c0ddaa..1c298cd 100644 --- a/src/theme/MDXComponents.js +++ b/src/theme/MDXComponents.js @@ -1,7 +1,9 @@ import MDXComponents from '@theme-original/MDXComponents'; import StepFlow from '@site/src/components/StepFlow'; +import ArchitectureDiagram from '@site/src/components/ArchitectureDiagram'; export default { ...MDXComponents, StepFlow, + ArchitectureDiagram, };