From 1b62e8284cdcb65b18a2ef01799c9e3e6acb0518 Mon Sep 17 00:00:00 2001
From: Adesh Nalpet Adimurthy <390.adesh@gmail.com>
Date: Fri, 14 Aug 2026 23:57:55 -0400
Subject: [PATCH] Docs first release
---
.github/workflows/ci.yml | 1 +
.github/workflows/docs.yml | 56 +
.gitignore | 8 +-
README.md | 40 +-
docs/.vitepress/config.mts | 74 +
docs/.vitepress/theme/ColorSwitch.vue | 182 ++
docs/.vitepress/theme/HeroDither.vue | 105 +
docs/.vitepress/theme/HomeBento.vue | 248 ++
docs/.vitepress/theme/HomeChips.vue | 183 ++
docs/.vitepress/theme/SiteLogo.vue | 28 +
docs/.vitepress/theme/accent.ts | 68 +
docs/.vitepress/theme/custom.css | 430 +++
docs/.vitepress/theme/index.ts | 24 +
docs/package-lock.json | 2544 +++++++++++++++++
docs/package.json | 16 +
.../assets/images}/architecture-dark.svg | 0
.../assets/images}/architecture-light.svg | 0
docs/pages/assets/images/favicon.ico | Bin 0 -> 2005 bytes
docs/pages/assets/images/logo.svg | 7 +
docs/pages/benchmark.md | 69 +
docs/pages/deployment.md | 83 +
docs/pages/index.md | 15 +
docs/pages/introduction.md | 3 +
docs/pages/quickstart.md | 78 +
harness/BENCH.md | 64 +
harness/README.md | 100 +-
harness/{configs => aws}/.env.example | 1 -
.../docker-compose.cluster.ds.yml | 10 +-
harness/{docker => aws}/docker-compose.ds.yml | 6 +-
harness/{docker => aws}/docker-compose.s2.yml | 6 +-
harness/aws/topo.cluster.yaml | 25 +
.../{configs/topo.aws.yaml => aws/topo.yaml} | 1 +
harness/docker/Dockerfile | 6 +
harness/docker/entrypoint.sh | 46 +-
harness/fly/fly.cluster.toml | 44 +
harness/fly/fly.toml | 38 +
harness/fly/topo.cluster.yaml | 25 +
harness/fly/topo.yaml | 15 +
.../{configs/minio.env => local/.env.example} | 1 -
harness/local/docker-compose.cluster.ds.yml | 50 +
harness/local/docker-compose.ds.yml | 28 +
.../docker-compose.minio.yml | 0
harness/local/docker-compose.s2.yml | 28 +
harness/{configs => local}/topo.cluster.yaml | 1 +
.../topo.minio.yaml => local/topo.yaml} | 1 +
45 files changed, 4682 insertions(+), 76 deletions(-)
create mode 100644 .github/workflows/docs.yml
create mode 100644 docs/.vitepress/config.mts
create mode 100644 docs/.vitepress/theme/ColorSwitch.vue
create mode 100644 docs/.vitepress/theme/HeroDither.vue
create mode 100644 docs/.vitepress/theme/HomeBento.vue
create mode 100644 docs/.vitepress/theme/HomeChips.vue
create mode 100644 docs/.vitepress/theme/SiteLogo.vue
create mode 100644 docs/.vitepress/theme/accent.ts
create mode 100644 docs/.vitepress/theme/custom.css
create mode 100644 docs/.vitepress/theme/index.ts
create mode 100644 docs/package-lock.json
create mode 100644 docs/package.json
rename docs/{assets => pages/assets/images}/architecture-dark.svg (100%)
rename docs/{assets => pages/assets/images}/architecture-light.svg (100%)
create mode 100644 docs/pages/assets/images/favicon.ico
create mode 100644 docs/pages/assets/images/logo.svg
create mode 100644 docs/pages/benchmark.md
create mode 100644 docs/pages/deployment.md
create mode 100644 docs/pages/index.md
create mode 100644 docs/pages/introduction.md
create mode 100644 docs/pages/quickstart.md
create mode 100644 harness/BENCH.md
rename harness/{configs => aws}/.env.example (67%)
rename harness/{docker => aws}/docker-compose.cluster.ds.yml (78%)
rename harness/{docker => aws}/docker-compose.ds.yml (86%)
rename harness/{docker => aws}/docker-compose.s2.yml (86%)
create mode 100644 harness/aws/topo.cluster.yaml
rename harness/{configs/topo.aws.yaml => aws/topo.yaml} (80%)
create mode 100644 harness/fly/fly.cluster.toml
create mode 100644 harness/fly/fly.toml
create mode 100644 harness/fly/topo.cluster.yaml
create mode 100644 harness/fly/topo.yaml
rename harness/{configs/minio.env => local/.env.example} (60%)
create mode 100644 harness/local/docker-compose.cluster.ds.yml
create mode 100644 harness/local/docker-compose.ds.yml
rename harness/{docker => local}/docker-compose.minio.yml (100%)
create mode 100644 harness/local/docker-compose.s2.yml
rename harness/{configs => local}/topo.cluster.yaml (88%)
rename harness/{configs/topo.minio.yaml => local/topo.yaml} (88%)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cada55b..c7eafff 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,6 +2,7 @@ name: CI
on:
push:
+ branches: [main]
pull_request:
workflow_dispatch: {}
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 0000000..ad7b31e
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,56 @@
+name: docs
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - "docs/**"
+ - ".github/workflows/docs.yml"
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ BASE_PATH: /${{ github.event.repository.name }}/
+ steps:
+ - uses: actions/checkout@v6
+
+ - uses: actions/setup-node@v6
+ with:
+ node-version: "24"
+ cache: npm
+ cache-dependency-path: docs/package-lock.json
+
+ - uses: actions/configure-pages@v5
+
+ - name: Install docs dependencies
+ working-directory: docs
+ run: npm ci
+
+ - name: Build site
+ working-directory: docs
+ run: npm run build
+
+ - uses: actions/upload-pages-artifact@v5
+ with:
+ path: docs/.vitepress/dist
+
+ deploy:
+ needs: build
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - id: deployment
+ uses: actions/deploy-pages@v5
diff --git a/.gitignore b/.gitignore
index df4a039..7e8e06b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,9 +32,13 @@ dependency-reduced-pom.xml
*.log
.env
.env.*
-harness/configs/.env
-!harness/configs/.env.example
+!.env.example
### Conformance / temp ###
server/conformance-run.log
**/node_modules/
+
+### Docs ###
+/docs/node_modules/
+/docs/.vitepress/cache/
+/docs/.vitepress/dist/
diff --git a/README.md b/README.md
index bef1a2f..3216704 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,8 @@ A durable stream engine on object storage, with storage, metadata, and protocol
-
-
+
+
@@ -20,34 +20,48 @@ mvn clean package
## Quickstart
```bash
-docker compose --env-file harness/configs/minio.env \
- -f harness/docker/docker-compose.minio.yml \
- -f harness/docker/docker-compose.ds.yml \
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
up -d --build
```
-Node listens on `127.0.0.1:4437`. MinIO, cluster, and topo files: [harness/README.md](harness/README.md).
+Node listens on `127.0.0.1:4437`. MinIO, cluster, AWS, and Fly: [harness/README.md](harness/README.md).
## Deployment
-Create data and WAL S3 buckets. Copy `harness/configs/.env.example` to `harness/configs/.env` and fill `AWS_*`, `DATA_BUCKET`, and `WAL_BUCKET`.
+Create data and WAL S3 buckets. Copy `harness/aws/.env.example` to `harness/aws/.env` and fill `AWS_*`, `DATA_BUCKET`, and `WAL_BUCKET`.
```bash
-docker compose --env-file harness/configs/.env \
- -f harness/docker/docker-compose.ds.yml \
+docker compose --env-file harness/aws/.env \
+ -f harness/aws/docker-compose.ds.yml \
up -d --build
```
-Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run S2 facade. Node listens on `127.0.0.1:4437`.
+Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run S2 facade. Node listens on `127.0.0.1:4437`. Three nodes: `harness/aws/docker-compose.cluster.ds.yml`.
-Multi-Node (3 nodes) cluster (ports 4437–4439):
+Multi-node (3 nodes) local cluster (ports 4437–4439):
```bash
-docker compose --env-file harness/configs/.env \
- -f harness/docker/docker-compose.cluster.ds.yml \
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.cluster.ds.yml \
up -d --build
```
+## Documentation
+
+The documentation source is in [`docs/pages`](docs/pages).
+
+```bash
+cd docs
+npm install
+npm run dev
+```
+
+Open http://localhost:5173.
+
## License
Apache 2.0.
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
new file mode 100644
index 0000000..4523c23
--- /dev/null
+++ b/docs/.vitepress/config.mts
@@ -0,0 +1,74 @@
+import { defineConfig } from 'vitepress';
+
+function sideItem(label: string, link: string, path: string) {
+ return {
+ text: `${label}`,
+ link,
+ };
+}
+
+export default defineConfig({
+ title: 'Stream Stack',
+ description: 'A durable stream engine on object storage.',
+ base: process.env.BASE_PATH ?? '/',
+ cleanUrls: true,
+ appearance: 'force-dark',
+ srcDir: 'pages',
+ vite: {
+ publicDir: 'assets',
+ },
+ markdown: {
+ theme: 'github-dark',
+ },
+ head: [
+ ['link', { rel: 'icon', href: '/images/favicon.ico', sizes: 'any' }],
+ ['link', { rel: 'icon', type: 'image/svg+xml', href: '/images/logo.svg' }],
+ [
+ 'script',
+ {},
+ `(function(){function m(h,a){var n=parseInt(h.slice(1),16),r=n>>16,g=n>>8&255,b=n&255;return'#'+[r,g,b].map(function(c){c=Math.round(c+(255-c)*a);return c.toString(16).padStart(2,'0')}).join('')}try{var h=localStorage.getItem('ss-accent-hex-v2');if(h&&/^#[0-9a-fA-F]{6}$/.test(h)){var s=document.documentElement.style;var n=parseInt(h.slice(1),16);s.setProperty('--vp-c-brand-1',h);s.setProperty('--vp-c-brand-2',m(h,.18));s.setProperty('--vp-c-brand-3',m(h,.36));s.setProperty('--vp-c-brand-soft','rgb('+(n>>16)+' '+(n>>8&255)+' '+(n&255)+' / 0.14)')}}catch(e){}})();`,
+ ],
+ ],
+ themeConfig: {
+ siteTitle: false,
+ nav: [
+ { text: 'Home', link: '/' },
+ { text: 'Docs', link: '/introduction' },
+ ],
+ sidebar: [
+ sideItem(
+ 'Introduction',
+ '/introduction',
+ '',
+ ),
+ sideItem(
+ 'Quickstart',
+ '/quickstart',
+ '',
+ ),
+ sideItem(
+ 'Benchmark',
+ '/benchmark',
+ '',
+ ),
+ sideItem(
+ 'Deployment',
+ '/deployment',
+ '',
+ ),
+ ],
+ search: {
+ provider: 'local',
+ },
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/Modak-Labs/streamstack' },
+ ],
+ outline: {
+ level: [1, 3],
+ label: 'On this page',
+ },
+ footer: {
+ copyright: '© 2026 Modak Labs. Apache 2.0.',
+ },
+ },
+});
diff --git a/docs/.vitepress/theme/ColorSwitch.vue b/docs/.vitepress/theme/ColorSwitch.vue
new file mode 100644
index 0000000..bafefea
--- /dev/null
+++ b/docs/.vitepress/theme/ColorSwitch.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/HeroDither.vue b/docs/.vitepress/theme/HeroDither.vue
new file mode 100644
index 0000000..021d08e
--- /dev/null
+++ b/docs/.vitepress/theme/HeroDither.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/HomeBento.vue b/docs/.vitepress/theme/HomeBento.vue
new file mode 100644
index 0000000..3f84cac
--- /dev/null
+++ b/docs/.vitepress/theme/HomeBento.vue
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
Unlimited streams
+
+ Stream data and the WAL live on S3-compatible object storage,
+ so create as many as you need with no topic tax.
+
+
+
+
+
+
+
+
+
Blazing fast
+
+ Battle-tested S3Stream storage backend for high
+ throughput. Transparent, reproducible benchmarks.
+
+
+
+
+
+
+
Multi-node
+
+ N nodes, one cluster. JRaft replicated metadata for
+ high availability and fault tolerance.
+
+
+
+
+
+ Decoupled layers
+
+
+
+
Many protocols, one engine
+
+ durable-streams and S2 compatible today.
+ Protocol is a separate layer, so more can land. Opinionated native
+ API coming soon.
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/HomeChips.vue b/docs/.vitepress/theme/HomeChips.vue
new file mode 100644
index 0000000..7ae7a19
--- /dev/null
+++ b/docs/.vitepress/theme/HomeChips.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+ Infinite streams
+ Create as many as you need. Partitions are now streams, no topic tax.
+
+
+
+
+
+
+ Cheap storage
+ Cost effective with S3-compatible object storage for WAL and data.
+
+
+
+
+
+
+ High throughput
+
+ Battle-tested S3Stream storage backend. Transparent
+ benchmark suite.
+
+
+
+
+
+
+
+ High availability
+ N nodes, one cluster. JRaft replicated metadata.
+
+
+
+
+
+
+ Open source
+ Apache 2.0 licensed. No hidden capabilities.
+
+
+
+
+
+
+ Many protocols
+
+ durable-streams and S2 compatible today.
+ Opinionated native API coming soon.
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/SiteLogo.vue b/docs/.vitepress/theme/SiteLogo.vue
new file mode 100644
index 0000000..25dce63
--- /dev/null
+++ b/docs/.vitepress/theme/SiteLogo.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/docs/.vitepress/theme/accent.ts b/docs/.vitepress/theme/accent.ts
new file mode 100644
index 0000000..d619e2f
--- /dev/null
+++ b/docs/.vitepress/theme/accent.ts
@@ -0,0 +1,68 @@
+const KEY = 'ss-accent-hex-v2';
+export const DEFAULT_ACCENT = '#ffffff';
+
+export const SWATCHES = [
+ '#ffffff',
+ '#8096ff',
+ '#cc8b00',
+ '#80ff96',
+ '#ff6b6b',
+ '#f97316',
+ '#a78bfa',
+ '#22d3ee',
+] as const;
+
+function safeGet(key: string): string | null {
+ try {
+ return localStorage.getItem(key);
+ } catch {
+ return null;
+ }
+}
+
+function isHex(value: string): boolean {
+ return /^#[0-9a-fA-F]{6}$/.test(value);
+}
+
+function parseRgb(hex: string): [number, number, number] {
+ const n = parseInt(hex.slice(1), 16);
+
+ return [n >> 16, (n >> 8) & 255, n & 255];
+}
+
+function toHex(r: number, g: number, b: number): string {
+ return `#${[r, g, b]
+ .map((c) => Math.round(c).toString(16).padStart(2, '0'))
+ .join('')}`;
+}
+
+function mixWhite(hex: string, amount: number): string {
+ const [r, g, b] = parseRgb(hex);
+
+ return toHex(r + (255 - r) * amount, g + (255 - g) * amount, b + (255 - b) * amount);
+}
+
+export function readAccentHex(): string {
+ const stored = safeGet(KEY);
+
+ return stored && isHex(stored) ? stored : DEFAULT_ACCENT;
+}
+
+export function applyAccentHex(hex: string) {
+ const value = isHex(hex) ? hex : DEFAULT_ACCENT;
+ const [r, g, b] = parseRgb(value);
+ const root = document.documentElement.style;
+
+ root.setProperty('--vp-c-brand-1', value);
+ root.setProperty('--vp-c-brand-2', mixWhite(value, 0.18));
+ root.setProperty('--vp-c-brand-3', mixWhite(value, 0.36));
+ root.setProperty('--vp-c-brand-soft', `rgb(${r} ${g} ${b} / 0.14)`);
+
+ try {
+ localStorage.setItem(KEY, value);
+ } catch {
+ // ignore
+ }
+
+ window.dispatchEvent(new CustomEvent('ss-accent', { detail: value }));
+}
diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css
new file mode 100644
index 0000000..22326c2
--- /dev/null
+++ b/docs/.vitepress/theme/custom.css
@@ -0,0 +1,430 @@
+:root {
+ --vp-font-family-base:
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
+ sans-serif;
+ --vp-font-family-mono:
+ "JetBrains Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
+ --vp-c-brand-1: #ffffff;
+ --vp-c-brand-2: #ffffff;
+ --vp-c-brand-3: #ffffff;
+ --vp-c-brand-soft: rgb(255 255 255 / 0.14);
+ --vp-c-bg: #0c0c0d;
+ --vp-c-bg-alt: #141416;
+ --vp-c-bg-elv: #19191c;
+ --vp-c-divider: #2b2b2f;
+ --vp-c-gutter: #202024;
+ --vp-c-text-1: #f5f5f3;
+ --vp-c-text-2: #a7a7a1;
+ --vp-nav-bg-color: rgb(12 12 13 / 0.9);
+ --vp-sidebar-bg-color: var(--vp-c-bg);
+ --vp-code-color: var(--vp-c-brand-2);
+ --vp-code-bg: rgb(20 20 22 / 0.85);
+ --vp-code-block-bg: #141416;
+ --vp-code-block-color: #c8c8c2;
+ --vp-code-block-divider-color: #2b2b2f;
+ --vp-code-copy-code-bg: #19191c;
+ --vp-code-copy-code-hover-bg: #0c0c0d;
+ --vp-home-hero-name-color: #f5f5f3;
+ --vp-home-hero-name-background: none;
+ --ss-content-max: 1180px;
+ --ss-content-pad: 24px;
+ --ss-radius: 2px;
+ --vp-sidebar-width: 320px;
+ --ss-outline-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M8 6.5h12M8 12h12M8 17.5h12' stroke='black' stroke-width='1.7' stroke-linecap='round'/%3E%3Cpath d='M4 6.5h.01M4 12h.01M4 17.5h.01' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
+}
+
+@media (min-width: 640px) {
+ :root {
+ --ss-content-pad: 48px;
+ }
+}
+
+@media (min-width: 960px) {
+ :root {
+ --ss-content-pad: 64px;
+ }
+}
+
+.ss-wrap,
+.VPFooter .container {
+ box-sizing: border-box;
+ width: min(var(--ss-content-max), calc(100% - (2 * var(--ss-content-pad))));
+ margin-inline: auto;
+}
+
+.VPNav {
+ backdrop-filter: blur(14px);
+}
+
+.VPNavBar,
+.VPNavBar.home,
+.VPNavBar.home.top,
+.VPNavBar .content-body {
+ background-color: var(--vp-nav-bg-color) !important;
+}
+
+.VPNavBar .wrapper {
+ padding-left: var(--ss-content-pad) !important;
+ padding-right: var(--ss-content-pad) !important;
+}
+
+.VPNavBar .container {
+ max-width: var(--ss-content-max) !important;
+ width: 100%;
+}
+
+.VPNavBar .title {
+ width: auto !important;
+}
+
+.VPNavBar .title svg {
+ width: 32px !important;
+ height: 32px !important;
+ max-height: 32px !important;
+ flex: none;
+}
+
+@media (min-width: 960px) {
+ .VPNavBar.has-sidebar .title {
+ position: static !important;
+ width: auto !important;
+ padding: 0 !important;
+ height: calc(var(--vp-nav-height) - 1px) !important;
+ }
+
+ .VPNavBar.has-sidebar .content {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+
+ .VPNavBar.has-sidebar .divider {
+ padding-left: 0 !important;
+ }
+
+ .VPNavBarTitle.has-sidebar .title {
+ border-bottom-color: transparent !important;
+ }
+}
+
+.VPHome,
+.VPContent.is-home {
+ overflow: visible;
+}
+
+.VPHome {
+ position: relative;
+}
+
+.VPHero {
+ position: relative;
+ isolation: isolate;
+ overflow: visible;
+ padding-top: clamp(5rem, 12vw, 9rem) !important;
+ padding-bottom: clamp(4rem, 8vw, 7rem) !important;
+}
+
+.VPHero .container {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ flex-direction: column;
+ max-width: var(--ss-content-max);
+}
+
+.VPHero .main {
+ width: 100% !important;
+ max-width: 900px;
+}
+
+.VPHero .name {
+ margin-bottom: 0.85rem;
+ font-size: clamp(1rem, 1.55vw, 1.15rem);
+ font-weight: 400;
+ line-height: 1.2;
+ letter-spacing: 0.02em;
+ color: var(--vp-c-text-1);
+}
+
+.VPHero .text {
+ max-width: 900px;
+ font-size: clamp(3rem, 7vw, 6.5rem);
+ line-height: 0.96;
+ letter-spacing: -0.065em;
+ color: var(--vp-c-text-1);
+}
+
+.VPHero .tagline {
+ max-width: 650px;
+ margin-top: 2rem;
+ font-size: clamp(1.1rem, 2vw, 1.4rem);
+ line-height: 1.55;
+}
+
+.VPHero .actions {
+ padding-top: 2rem;
+}
+
+.VPButton {
+ display: inline-flex !important;
+ align-items: center;
+ justify-content: center;
+ min-height: 46px;
+ padding: 0 22px !important;
+ border-radius: var(--ss-radius) !important;
+ font-size: 15px !important;
+ line-height: 1 !important;
+}
+
+.VPButton.brand {
+ border-color: var(--vp-c-text-1) !important;
+ background: var(--vp-c-text-1) !important;
+ color: var(--vp-c-bg) !important;
+}
+
+.VPButton.brand:hover {
+ opacity: 0.82;
+}
+
+.VPButton.alt {
+ border-color: var(--vp-c-divider) !important;
+ background: transparent !important;
+}
+
+.VPDoc h1,
+.VPDoc h2,
+.VPDoc h3 {
+ letter-spacing: -0.035em;
+}
+
+.VPDoc h1 {
+ font-size: clamp(2.25rem, 5vw, 3.5rem);
+ line-height: 1.05;
+}
+
+.vp-doc h2:first-of-type {
+ margin-top: 1.25rem;
+ padding-top: 0;
+ border-top: none;
+}
+
+.vp-doc div[class*="language-"] {
+ border: 1px solid var(--vp-c-divider);
+ border-radius: var(--ss-radius) !important;
+ background: var(--vp-code-block-bg) !important;
+}
+
+.vp-doc div[class*="language-"] pre,
+.vp-doc div[class*="language-"] code,
+.vp-doc div[class*="language-"] .shiki {
+ background: transparent !important;
+}
+
+.DocSearch-Button,
+.vp-doc .custom-block,
+.vp-doc [class*="language-"] > button.copy,
+.vp-code-group,
+.vp-code-group .tabs,
+.VPDocFooter .pager-link,
+.VPLocalNavOutlineDropdown .items,
+.VPLocalSearchBox .shell,
+.VPLocalSearchBox input,
+.VPLocalSearchBox div[class*="language-"],
+.VPMenu,
+.VPFlyout,
+.vp-doc :not(pre) > code,
+.vp-doc kbd {
+ border-radius: var(--ss-radius) !important;
+}
+
+.DocSearch-Button .DocSearch-Button-Key {
+ border-radius: var(--ss-radius) 0 0 var(--ss-radius) !important;
+}
+
+.DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
+ border-radius: 0 var(--ss-radius) var(--ss-radius) 0 !important;
+}
+
+.VPFooter {
+ padding: 0 0 2rem !important;
+ border-top: none !important;
+ background: transparent !important;
+}
+
+.VPFooter .container {
+ max-width: none;
+ margin-top: 0;
+ padding: 1.25rem 0 0;
+ border-top: 1px solid rgb(255 255 255 / 0.08);
+ text-align: left;
+}
+
+.VPFooter .copyright,
+.ss-doc-copyright {
+ font-size: 0.8rem;
+ font-weight: 500;
+ color: var(--vp-c-text-2);
+}
+
+.VPDocFooter .ss-side-ico {
+ display: none;
+}
+
+@media (min-width: 960px) {
+ .VPDoc.has-sidebar {
+ padding-left: 16px !important;
+ }
+
+ .VPDoc.has-sidebar .content {
+ padding-bottom: 2.5rem;
+ padding-left: 16px;
+ }
+
+ .VPSidebar {
+ padding-top: calc(var(--vp-nav-height) + 48px) !important;
+ padding-right: 20px !important;
+ }
+}
+
+.VPSidebarItem.level-0 {
+ padding-bottom: 4px !important;
+}
+
+.VPSidebarItem.level-0.is-link .text {
+ font-weight: 500;
+ color: var(--vp-c-text-2);
+}
+
+.VPSidebarItem .item {
+ border-radius: var(--ss-radius);
+}
+
+.VPSidebarItem .link {
+ min-height: 2.15rem;
+ padding: 0.35rem 0.65rem;
+ border-radius: var(--ss-radius);
+}
+
+.VPSidebarItem .text {
+ display: flex;
+ align-items: center;
+ gap: 0.55rem;
+}
+
+.VPSidebarItem .link:hover {
+ background: rgb(255 255 255 / 0.04);
+}
+
+.VPSidebarItem .link:hover .text,
+.VPSidebarItem .link:hover .ss-side-ico {
+ color: var(--vp-c-brand-1) !important;
+}
+
+.VPSidebarItem.is-active > .item > .link {
+ background: var(--vp-c-brand-soft);
+}
+
+.VPSidebarItem.is-active > .item .link > .text,
+.VPSidebarItem.is-active .ss-side-ico {
+ color: var(--vp-c-brand-1) !important;
+}
+
+.ss-side-ico {
+ display: inline-flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+ width: 1.05rem;
+ height: 1.05rem;
+ color: var(--vp-c-text-2);
+}
+
+.ss-side-ico svg {
+ width: 100%;
+ height: 100%;
+}
+
+.VPDocAsideOutline {
+ display: block !important;
+}
+
+.VPDocAsideOutline .outline-title {
+ display: flex;
+ align-items: center;
+ gap: 0.55rem;
+ letter-spacing: -0.02em;
+ color: var(--vp-c-text-1);
+}
+
+.VPDocAsideOutline .outline-title::before {
+ flex-shrink: 0;
+ width: 1.05rem;
+ height: 1.05rem;
+ background-color: currentColor;
+ -webkit-mask: var(--ss-outline-ico) center / contain no-repeat;
+ mask: var(--ss-outline-ico) center / contain no-repeat;
+ content: "";
+}
+
+.ss-cli {
+ display: grid;
+ gap: 0.75rem;
+ margin: 1.1rem 0 1.35rem;
+}
+
+.ss-cli__row {
+ display: grid;
+ grid-template-columns: 5.5rem minmax(0, 1fr);
+ align-items: stretch;
+ gap: 0.65rem;
+}
+
+.ss-cli__row > p {
+ display: flex;
+ align-items: center;
+ margin: 0;
+}
+
+.ss-cli__label {
+ font-size: 0.72rem;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ line-height: 1.2;
+ text-transform: uppercase;
+ color: var(--vp-c-text-2);
+}
+
+.vp-doc .ss-cli div[class*="language-"] {
+ margin: 0;
+}
+
+@media (max-width: 639px) {
+ .ss-cli__row {
+ grid-template-columns: minmax(0, 1fr);
+ gap: 0.35rem;
+ }
+}
+
+.VPNavBar .social-links {
+ margin-right: 0 !important;
+}
+
+.VPNavBar .VPSocialLinks {
+ height: var(--vp-nav-height);
+}
+
+.VPNavBar .VPSocialLink {
+ width: 36px;
+ height: 36px;
+}
+
+.VPNavBar .VPSocialLink > * {
+ display: block;
+ flex-shrink: 0;
+}
+
+.VPNavBar .VPSocialLink svg,
+.VPNavBar .VPSocialLink [class^="vpi-social-"] {
+ display: block;
+ width: 20px;
+ height: 20px;
+}
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
new file mode 100644
index 0000000..2300b26
--- /dev/null
+++ b/docs/.vitepress/theme/index.ts
@@ -0,0 +1,24 @@
+import DefaultTheme from 'vitepress/theme';
+import { h } from 'vue';
+import type { Theme } from 'vitepress';
+import ColorSwitch from './ColorSwitch.vue';
+import HeroDither from './HeroDither.vue';
+import HomeChips from './HomeChips.vue';
+import HomeBento from './HomeBento.vue';
+import SiteLogo from './SiteLogo.vue';
+import './custom.css';
+
+export default {
+ extends: DefaultTheme,
+ Layout: () => {
+ return h(DefaultTheme.Layout, null, {
+ 'nav-bar-title-before': () => h(SiteLogo),
+ 'nav-bar-content-after': () => h(ColorSwitch),
+ 'home-hero-before': () => h(HeroDither),
+ 'home-hero-after': () => h(HomeChips),
+ 'home-features-after': () => h(HomeBento),
+ 'doc-after': () =>
+ h('p', { class: 'ss-doc-copyright' }, '© 2026 Modak Labs. Apache 2.0.'),
+ });
+ },
+} satisfies Theme;
diff --git a/docs/package-lock.json b/docs/package-lock.json
new file mode 100644
index 0000000..ba85e1c
--- /dev/null
+++ b/docs/package-lock.json
@@ -0,0 +1,2544 @@
+{
+ "name": "streamstack-docs",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "streamstack-docs",
+ "dependencies": {
+ "@paper-design/shaders": "0.0.80"
+ },
+ "devDependencies": {
+ "vitepress": "^1.6.4"
+ }
+ },
+ "node_modules/@algolia/abtesting": {
+ "version": "1.22.0",
+ "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.22.0.tgz",
+ "integrity": "sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/autocomplete-core": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz",
+ "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.17.7",
+ "@algolia/autocomplete-shared": "1.17.7"
+ }
+ },
+ "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz",
+ "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "search-insights": ">= 1 < 3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz",
+ "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-shared": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz",
+ "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.56.0.tgz",
+ "integrity": "sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.56.0.tgz",
+ "integrity": "sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.56.0.tgz",
+ "integrity": "sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.56.0.tgz",
+ "integrity": "sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.56.0.tgz",
+ "integrity": "sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.56.0.tgz",
+ "integrity": "sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.56.0.tgz",
+ "integrity": "sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.56.0.tgz",
+ "integrity": "sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.56.0.tgz",
+ "integrity": "sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.56.0.tgz",
+ "integrity": "sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.56.0.tgz",
+ "integrity": "sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.56.0.tgz",
+ "integrity": "sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.56.0.tgz",
+ "integrity": "sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@docsearch/css": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz",
+ "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz",
+ "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/react": "3.8.2",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/react": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz",
+ "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.2",
+ "algoliasearch": "^5.14.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@iconify-json/simple-icons": {
+ "version": "1.2.93",
+ "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.93.tgz",
+ "integrity": "sha512-/XhANjfGYOuqvSR3TmUnkQkINvQ4GVjVuukvymRbxtVFBvIq/yiXJqCDycKcQPT401OYT9H2vIY6ihAlz1QIAw==",
+ "dev": true,
+ "license": "CC0-1.0",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@napi-rs/lzma-linux-x64-gnu": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
+ "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^22.20 || ^24.12 || >=25"
+ }
+ },
+ "node_modules/@paper-design/shaders": {
+ "version": "0.0.80",
+ "resolved": "https://registry.npmjs.org/@paper-design/shaders/-/shaders-0.0.80.tgz",
+ "integrity": "sha512-pcabvt5xDlFoEhpjUj4b1tGJMfqb0i5mXifWMNQf6z7FoOJYxYDo7F8R6k0JAh5D/7ouxjX5+N0cIq5WURyQ1Q==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz",
+ "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz",
+ "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz",
+ "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz",
+ "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz",
+ "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz",
+ "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz",
+ "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz",
+ "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz",
+ "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz",
+ "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz",
+ "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz",
+ "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz",
+ "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz",
+ "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz",
+ "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz",
+ "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz",
+ "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz",
+ "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz",
+ "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz",
+ "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz",
+ "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz",
+ "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz",
+ "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz",
+ "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz",
+ "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@shikijs/core": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz",
+ "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.4"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz",
+ "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^3.1.0"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz",
+ "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz",
+ "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz",
+ "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz",
+ "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
+ "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz",
+ "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.41.tgz",
+ "integrity": "sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/shared": "3.5.41",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.41.tgz",
+ "integrity": "sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.41",
+ "@vue/shared": "3.5.41"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.41.tgz",
+ "integrity": "sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/compiler-core": "3.5.41",
+ "@vue/compiler-dom": "3.5.41",
+ "@vue/compiler-ssr": "3.5.41",
+ "@vue/shared": "3.5.41",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.19",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.41.tgz",
+ "integrity": "sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.41",
+ "@vue/shared": "3.5.41"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.10.tgz",
+ "integrity": "sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.10"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz",
+ "integrity": "sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.10",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz",
+ "integrity": "sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.41.tgz",
+ "integrity": "sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.41"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.41.tgz",
+ "integrity": "sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.41",
+ "@vue/shared": "3.5.41"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.41.tgz",
+ "integrity": "sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.41",
+ "@vue/runtime-core": "3.5.41",
+ "@vue/shared": "3.5.41",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.41.tgz",
+ "integrity": "sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.41",
+ "@vue/runtime-dom": "3.5.41",
+ "@vue/shared": "3.5.41"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.41.tgz",
+ "integrity": "sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vueuse/core": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz",
+ "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/integrations": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz",
+ "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vueuse/core": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz",
+ "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz",
+ "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/algoliasearch": {
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.56.0.tgz",
+ "integrity": "sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/abtesting": "1.22.0",
+ "@algolia/client-abtesting": "5.56.0",
+ "@algolia/client-analytics": "5.56.0",
+ "@algolia/client-common": "5.56.0",
+ "@algolia/client-insights": "5.56.0",
+ "@algolia/client-personalization": "5.56.0",
+ "@algolia/client-query-suggestions": "5.56.0",
+ "@algolia/client-search": "5.56.0",
+ "@algolia/ingestion": "1.56.0",
+ "@algolia/monitoring": "1.56.0",
+ "@algolia/recommend": "5.56.0",
+ "@algolia/requester-browser-xhr": "5.56.0",
+ "@algolia/requester-fetch": "5.56.0",
+ "@algolia/requester-node-http": "5.56.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz",
+ "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/emoji-regex-xs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
+ "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/focus-trap": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz",
+ "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tabbable": "^6.4.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz",
+ "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/minisearch": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz",
+ "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/oniguruma-to-es": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz",
+ "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex-xs": "^1.0.0",
+ "regex": "^6.0.1",
+ "regex-recursion": "^6.0.2"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.5.26",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",
+ "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.17",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.29.8",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz",
+ "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "preact-render-to-string": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "preact-render-to-string": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/property-information": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz",
+ "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
+ "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-recursion": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz",
+ "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-utilities": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
+ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.62.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz",
+ "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@napi-rs/lzma-linux-x64-gnu": "1.5.1",
+ "@rollup/rollup-android-arm-eabi": "4.62.4",
+ "@rollup/rollup-android-arm64": "4.62.4",
+ "@rollup/rollup-darwin-arm64": "4.62.4",
+ "@rollup/rollup-darwin-x64": "4.62.4",
+ "@rollup/rollup-freebsd-arm64": "4.62.4",
+ "@rollup/rollup-freebsd-x64": "4.62.4",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.62.4",
+ "@rollup/rollup-linux-arm-musleabihf": "4.62.4",
+ "@rollup/rollup-linux-arm64-gnu": "4.62.4",
+ "@rollup/rollup-linux-arm64-musl": "4.62.4",
+ "@rollup/rollup-linux-loong64-gnu": "4.62.4",
+ "@rollup/rollup-linux-loong64-musl": "4.62.4",
+ "@rollup/rollup-linux-ppc64-gnu": "4.62.4",
+ "@rollup/rollup-linux-ppc64-musl": "4.62.4",
+ "@rollup/rollup-linux-riscv64-gnu": "4.62.4",
+ "@rollup/rollup-linux-riscv64-musl": "4.62.4",
+ "@rollup/rollup-linux-s390x-gnu": "4.62.4",
+ "@rollup/rollup-linux-x64-gnu": "4.62.4",
+ "@rollup/rollup-linux-x64-musl": "4.62.4",
+ "@rollup/rollup-openbsd-x64": "4.62.4",
+ "@rollup/rollup-openharmony-arm64": "4.62.4",
+ "@rollup/rollup-win32-arm64-msvc": "4.62.4",
+ "@rollup/rollup-win32-ia32-msvc": "4.62.4",
+ "@rollup/rollup-win32-x64-gnu": "4.62.4",
+ "@rollup/rollup-win32-x64-msvc": "4.62.4",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/search-insights": {
+ "version": "2.17.3",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
+ "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/shiki": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz",
+ "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/langs": "2.5.0",
+ "@shikijs/themes": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz",
+ "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz",
+ "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz",
+ "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz",
+ "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz",
+ "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz",
+ "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz",
+ "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/css": "3.8.2",
+ "@docsearch/js": "3.8.2",
+ "@iconify-json/simple-icons": "^1.2.21",
+ "@shikijs/core": "^2.1.0",
+ "@shikijs/transformers": "^2.1.0",
+ "@shikijs/types": "^2.1.0",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.2.1",
+ "@vue/devtools-api": "^7.7.0",
+ "@vue/shared": "^3.5.13",
+ "@vueuse/core": "^12.4.0",
+ "@vueuse/integrations": "^12.4.0",
+ "focus-trap": "^7.6.4",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.1",
+ "shiki": "^2.1.0",
+ "vite": "^5.4.14",
+ "vue": "^3.5.13"
+ },
+ "bin": {
+ "vitepress": "bin/vitepress.js"
+ },
+ "peerDependencies": {
+ "markdown-it-mathjax3": "^4",
+ "postcss": "^8"
+ },
+ "peerDependenciesMeta": {
+ "markdown-it-mathjax3": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.41",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.41.tgz",
+ "integrity": "sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.41",
+ "@vue/compiler-sfc": "3.5.41",
+ "@vue/runtime-dom": "3.5.41",
+ "@vue/server-renderer": "3.5.41",
+ "@vue/shared": "3.5.41"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 0000000..da61b3c
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "streamstack-docs",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vitepress dev",
+ "build": "vitepress build",
+ "preview": "vitepress preview"
+ },
+ "devDependencies": {
+ "vitepress": "^1.6.4"
+ },
+ "dependencies": {
+ "@paper-design/shaders": "0.0.80"
+ }
+}
diff --git a/docs/assets/architecture-dark.svg b/docs/pages/assets/images/architecture-dark.svg
similarity index 100%
rename from docs/assets/architecture-dark.svg
rename to docs/pages/assets/images/architecture-dark.svg
diff --git a/docs/assets/architecture-light.svg b/docs/pages/assets/images/architecture-light.svg
similarity index 100%
rename from docs/assets/architecture-light.svg
rename to docs/pages/assets/images/architecture-light.svg
diff --git a/docs/pages/assets/images/favicon.ico b/docs/pages/assets/images/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..e9b21d638b02ff80435dad6b83b1eddf219ef894
GIT binary patch
literal 2005
zcmai!S5(v47Ki@{5HT4vB4~^#NeqYqAtFSiXb6yk2%!rDm|&<Hz|bOdQ4A|-+%
zMZ^i+fD{c<28;;GI7G29VJLz~Q;I{maeTQCcddIK_Bp$(^RU1D+W-IpqyRV^kQ@}y
z00IEQj~D8vA0Pz)Q<4}S|I?2G1Hc&>07#)*QskgWs3a;!qng@C?jJwEWg!x)ytv5(
z08k{&)Y$IQtuotMU$8MeDzec9eaPaVYODcQg!n_b=9%ISe;HduP1;$8|G6Dc+HuQL
z1tiQy>}hO)>RZ##7_98Quw%?+`Z>DsA|uyhq%A-Es4#gFCfJ(MaqIwQDp=oJr(nb-
zaXKP$&(*sO0vFBgd#Y32ZdUW=GKseo!(REt6x*-KesQFbBNmGz3O8KZtGSE~}5h}Fw+
zbTzCDks`oj>@;)7xG*ze9ld(UW0!Ti_MoRs!&O-I_~N6>>f));7Vn47Y}c@{_OlwJ
zPo)NRvMf}GRDBB|9m#jzb4~<6`ToK>_u2<%$G)K0#!R)GFV-5nqGIiEiM=dLqeVk)
zAe8j3ZvPQPEAM%+N%3^|xI*P?94-eM*FIPnS)*ffYkozFKVxMK#mdtZpkcDo;0wYf
zV|zutjMU)o-MiOk!!|(dyKqf5+oM`S1E85%npTk*asPuEN|HwX%j{xA#8&{2(*4P-
z&+)X?PHP3DqlMaM^oca8^!by!aC;dlu+!|W?eJ9@jiA`~#7($n0z+0z=C8nH8C367
z-6qt4{zDo4qy4vr@@X(^_e#ZwQXhl1wuyJuVY7n?a08$S1TUKKA<4cg^Dcn64sE>)
zTCotcn60HFzP|H{Cl$x|KD4V`08j+J&9YJdG&@kM{X
z3h3?jt$1j;PaSb!a4UtTp*i}EL&-0pvs)-Hx&cK2LwXC<7<`)=E(m~pT
zKV&cwNx=k^$GdWtQ_$CM--`FT2gjLc8|vd2QR_zTwUHdw#$$w2|L3^kVzk9+qa3|g
zgqE1PmKJrJ`whvzA7(nOg9j3-C<*1C%-tF&$`p!naz}?r3hgrx
zP?1O7YjNm^_p(@wS?gn<>7re!si|tYPo8PgU&b{U3!HgLJYMF45$cbs;0bYaRbCMX
zZJT9Y#%hjNn4FBmKYKZuo|Nq_T^yi;6p2KF-rle`o4&S;bJ3fE#>n)TiQVMdGo4SL
zp0~qI(6x{d2;^xtKOT51vgr+Rz2A9XguH<>z2nU5u?pt5$)<8ec1C7qAlW{c=IQAf
zP$)w-*i$YDQYst9C+c=tM{`}{SD8plE2}Kw7+p=l<6wmgdHUOJJ-rpoj9azVfgai;
zm+tZLE#WLOW}~^3DvQwT%D$PkZL9YQt|=y#lDWUc&ex0>0+YYOg*#p-0-=wi6NWgt
z59}&AyDOd)yu7%rHRD14%683rtwkp{DMO2eXF2`9wWyxZy7hn5_G5?Q|5ckKc=ZYZ
zfK7j@Z6^Ooz+1XP_sJ@McA4Fwno{|=#PniStC16=dfn%jXk1>JPi0*x%oqErVoyP$
zN_e7OI)j9f+b3!*JylPyUsYal@SGHwA;KzVdEc{Jl?wmj{JC1yKToqZ{|NR5s3sbQ
z0OgSReJPaGksuS00@wtlx8Oc9KCW(Q`F3vo&?S;J>+?*TU@0`@VN88}W>Zs>bf%g)
z^4>jVhg>>bdL##xmog(+QC*#R^3F-+M#coL$#tr{G0!1Y>yGp5ftk>Dbu12@dupkV
zg1)h3gDQCcK1|P2KJHS2tr_^=q
zIj@N~t&XWGsLzn_)tdbBl+n>;afBd9bf2yU5;DxGL$}3KQ%5hKbXsh#YWbjKdAy77
zU+H7tTsuFvY+F5)Zy0cjYHxqTysO7BK;}2t5V(6Z=1h(RVu{qY0-%UoxFe9#P^*
zIyw01c_5m3DjCWTQL%`jjwsgs?PsxdPZH?ka+6CvGO4|DGjJ+=E(R7Pp*Sn8xT9!w
Ra`$5)Go?(br1igt?>`AQen|iT
literal 0
HcmV?d00001
diff --git a/docs/pages/assets/images/logo.svg b/docs/pages/assets/images/logo.svg
new file mode 100644
index 0000000..4bc2882
--- /dev/null
+++ b/docs/pages/assets/images/logo.svg
@@ -0,0 +1,7 @@
+
diff --git a/docs/pages/benchmark.md b/docs/pages/benchmark.md
new file mode 100644
index 0000000..c000c2f
--- /dev/null
+++ b/docs/pages/benchmark.md
@@ -0,0 +1,69 @@
+# Benchmark
+
+Java 17+ (Java 21 recommended). Maven. [Docker](https://docs.docker.com/get-docker/).
+
+## Install
+
+```bash
+mvn clean package
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
+ up -d --build
+```
+
+The node listens on `127.0.0.1:4437`. CLI jar: `cli/target/streamstack.jar`. MinIO console: http://127.0.0.1:9001 (`minioadmin` / `minioadmin`).
+
+If the node comes up before the buckets exist (`NoSuchBucket`):
+
+```bash
+docker restart local-node1-1
+```
+
+If ports `9000-9001` are taken, stop leftover MinIO (`docker-minio-1` or similar) first.
+
+This bench can run against the Durable Streams protocol or the S2 protocol. Examples below use Durable Streams.
+
+## Smoke
+
+```bash
+java -jar cli/target/streamstack.jar ds bench --endpoint http://127.0.0.1:4437 \
+ -b 1024 -n 64 -w 8 -d 8
+```
+
+Creates a temporary stream, pipelines 64-record JSON batches with 8 in-flight appends for 8s, live-reads them, then deletes. That path covers create, append, SSE read, and delete.
+
+`-b` is record size in bytes, `-n` records per append, `-w` concurrent appends, `-d` duration in seconds. `-t` throttles write MiB/s (`0` is unthrottled).
+
+## Load
+
+```bash
+java -jar cli/target/streamstack.jar ds bench --endpoint http://127.0.0.1:4437 \
+ -b 1024 -n 256 -w 32 -d 20
+```
+
+Same path: 256 records per append, 32 in-flight, 20s. The node should sustain pipelined writes without 409s or timeouts. This is the run used on the homepage.
+
+```bash
+java -jar cli/target/streamstack.jar ds bench --endpoint http://127.0.0.1:4437 \
+ -b 1024 -n 512 -w 64 -d 60
+```
+
+## Protocol
+
+The same runs work against S2. Stop the Durable Streams compose file, keep MinIO, bring S2 up on the same port. Basin names must be 8-48 characters. For S2, `-w` is in-flight MiB, not concurrent appends.
+
+```bash
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.ds.yml stop
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.s2.yml up -d --build
+```
+
+```bash
+java -jar cli/target/streamstack.jar s2 bench --endpoint http://127.0.0.1:4437 demobasin \
+ -b 1024 -n 64 -w 8 -d 8
+```
+
+Creates basin `demobasin`, then a temp stream, producer-batches 64 records with an 8 MiB in-flight window, live-reads, then tears down. Heavier run: `-n 256 -w 16 -d 20`. A pass means no `SeqNumMismatch` or request-size errors.
diff --git a/docs/pages/deployment.md b/docs/pages/deployment.md
new file mode 100644
index 0000000..2d4efbb
--- /dev/null
+++ b/docs/pages/deployment.md
@@ -0,0 +1,83 @@
+# Deployment
+
+`harness/docker` is the image. `local`, `aws`, and `fly` are how to run it. Each process is one node: raft, metadata, and the storage engine in one JVM. Durable Streams and S2 are protocol facades over that engine. Pick one per deployment.
+
+Storage comes from the topo file (`TOPO`). `DATA_BUCKET` / `WAL_BUCKET` / `BUCKET_NAME` override the topo S3 URIs.
+
+## Local cluster
+
+Three DS nodes on one host, ports `4437-4439` / `8091-8093`, against local MinIO.
+
+```bash
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.cluster.ds.yml \
+ up -d --build
+```
+
+Each service is a fixed `NODE_ID` (1 / 2 / 3). Host network so they bind the ports in `local/topo.cluster.yaml`.
+
+Bare JVM, same topo, one process per id:
+
+```bash
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 1
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 2
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 3
+```
+
+## AWS
+
+Create data and WAL buckets. Copy `harness/aws/.env.example` to `harness/aws/.env` and fill `AWS_*`, `DATA_BUCKET`, and `WAL_BUCKET`.
+
+```bash
+docker compose --env-file harness/aws/.env \
+ -f harness/aws/docker-compose.ds.yml \
+ up -d --build
+```
+
+Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run the S2 facade. The node listens on `127.0.0.1:4437`.
+
+Three nodes on one host, ports `4437-4439`:
+
+```bash
+docker compose --env-file harness/aws/.env \
+ -f harness/aws/docker-compose.cluster.ds.yml \
+ up -d --build
+```
+
+Bare JVM (creds from env / `~/.aws` / IAM):
+
+```bash
+java -jar frontend/ds/server/target/ds-server.jar \
+ --topo harness/aws/topo.yaml --node-id 1 \
+ --storage "0@s3://${DATA_BUCKET}?region=${AWS_REGION}" \
+ --wal "0@s3://${WAL_BUCKET}?region=${AWS_REGION}"
+```
+
+## Fly.io
+
+App name must stay `streamstack`. Storage is Tigris.
+
+```bash
+fly launch --config harness/fly/fly.toml
+fly storage create
+fly deploy --config harness/fly/fly.toml
+```
+
+Three nodes: `--config harness/fly/fly.cluster.toml`.
+
+## Topology
+
+| File | Storage |
+|------|---------|
+| `local/topo.yaml` | MinIO via `host.docker.internal:9000` (container to host) |
+| `local/topo.cluster.yaml` | Three nodes. MinIO via `127.0.0.1:9000` (host network / JVM) |
+| `aws/topo.yaml` | Real `s3://` (no endpoint) |
+| `aws/topo.cluster.yaml` | Three nodes on one host. Real `s3://` |
+| `fly/topo.yaml` | One Fly Machine. Tigris (`region=auto`) |
+| `fly/topo.cluster.yaml` | Three Fly process groups `n1-n3` |
+
+URI forms: `0@s3://bucket?region=us-east-1`, `-2@file:///path`, `0@mem://bucket` (tests). Omit `global.wal` to default WAL to the storage URI when storage is S3.
+
+`--topo` requires `--node-id`. CLI flags override topo values. Export credentials in the environment that starts the process.
diff --git a/docs/pages/index.md b/docs/pages/index.md
new file mode 100644
index 0000000..cfa0ff4
--- /dev/null
+++ b/docs/pages/index.md
@@ -0,0 +1,15 @@
+---
+layout: home
+
+hero:
+ name: STREAM STACK
+ text: Durable streams on object storage
+ tagline: Storage, metadata, and protocol as decoupled layers.
+ actions:
+ - theme: brand
+ text: Get started
+ link: /quickstart
+ - theme: alt
+ text: Docs
+ link: /introduction
+---
diff --git a/docs/pages/introduction.md b/docs/pages/introduction.md
new file mode 100644
index 0000000..84c188a
--- /dev/null
+++ b/docs/pages/introduction.md
@@ -0,0 +1,3 @@
+# Introduction
+
+A durable stream engine on object storage, with storage, metadata, and protocol as the three primary decoupled layers.
diff --git a/docs/pages/quickstart.md b/docs/pages/quickstart.md
new file mode 100644
index 0000000..4c3390b
--- /dev/null
+++ b/docs/pages/quickstart.md
@@ -0,0 +1,78 @@
+# Quickstart
+
+Java 17+ (Java 21 recommended). Maven. [Docker](https://docs.docker.com/get-docker/).
+
+Each node includes the `S3Stream` storage engine, the WAL, `JRaft` metadata, and a protocol facade. All of that lives in the same server.
+
+## Start a node
+
+```bash
+mvn clean package
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
+ up -d --build
+```
+
+The node listens on `127.0.0.1:4437`. MinIO console: http://127.0.0.1:9001 (`minioadmin` / `minioadmin`).
+
+If the node comes up before the buckets exist (`NoSuchBucket`):
+
+```bash
+docker restart local-node1-1
+```
+
+## Append and tail
+
+Create a stream, then tail in one terminal and append in another.
+
+
+
+
+
+Create
+
+```bash
+java -jar cli/target/streamstack.jar ds create \
+ --endpoint http://127.0.0.1:4437 demo
+```
+
+
+
+
+
+Tail
+
+```bash
+java -jar cli/target/streamstack.jar ds tail -f \
+ --endpoint http://127.0.0.1:4437 demo
+```
+
+
+
+
+
+Append
+
+```bash
+java -jar cli/target/streamstack.jar ds append \
+ --endpoint http://127.0.0.1:4437 demo
+```
+
+
+
+
+
+`append` reads stdin. Type a line, press enter, repeat. `tail -f` prints each line as it lands.
+
+## Protocol
+
+This example speaks Durable Streams. Same MinIO and port, S2 instead:
+
+```bash
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.s2.yml \
+ up -d --build
+```
diff --git a/harness/BENCH.md b/harness/BENCH.md
new file mode 100644
index 0000000..6dacdf5
--- /dev/null
+++ b/harness/BENCH.md
@@ -0,0 +1,64 @@
+# Bench
+
+CLI jar: `cli/target/streamstack.jar`. Node: `127.0.0.1:4437`.
+
+If ports 9000–9001 are taken, stop leftover MinIO (`docker-minio-1` or similar) first.
+
+## Start DS + Local MinIO
+
+```bash
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
+ up -d --build
+```
+
+If the node starts before buckets exist (`NoSuchBucket`):
+
+```bash
+docker restart local-node1-1
+```
+
+## DS Server
+
+```bash
+java -jar cli/target/streamstack.jar ds bench --endpoint http://127.0.0.1:4437 \
+ -b 1024 -n 64 -w 8 -d 8
+```
+
+Creates a temporary stream, pipelines 64-record JSON batches with 8 in-flight appends for 8s, live-reads them, then deletes. Verifies: create / appends / SSE read / delete on the durable-streams protocol.
+
+```bash
+java -jar cli/target/streamstack.jar ds bench --endpoint http://127.0.0.1:4437 \
+ -b 1024 -n 256 -w 32 -d 20
+```
+
+Same path, but heavier: 256 records per append, 32 in-flight, 20s. Verifies: the node can sustain pipelined writes without 409s or timeouts (expect ~40–80 MiB/s).
+
+## Start S2 + Local MinIO
+
+```bash
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.ds.yml stop
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.s2.yml up -d --build
+```
+
+Note: `Basin` name must be 8–48 chars.
+
+## S2 Server
+
+```bash
+java -jar cli/target/streamstack.jar s2 bench --endpoint http://127.0.0.1:4437 demobasin \
+ -b 1024 -n 64 -w 8 -d 8
+```
+
+Creates basin `demobasin`, then a temp stream, producer-batches 64 records with an 8 MiB in-flight window, live-reads, then tears down. Verifies: basin, stream, appends, live reads on S2 facade.
+
+```bash
+java -jar cli/target/streamstack.jar s2 bench --endpoint http://127.0.0.1:4437 demobasin \
+ -b 1024 -n 256 -w 16 -d 20
+```
+
+Same path, but heavier: 256-record batches and a 16 MiB in-flight window. Verifies: a single S2 writer can pipeline without `SeqNumMismatch` or request-size errors.
diff --git a/harness/README.md b/harness/README.md
index c78ba27..ed7b61b 100644
--- a/harness/README.md
+++ b/harness/README.md
@@ -1,43 +1,36 @@
# Streamstack Harness
-The server **is** also the node: `DurableStreamsServer` and `S2Server` each embed the full `StreamStackNode` (raft, metadata, storage engine) in one JVM.
+The server **is** also the node: `DurableStreamsServer` and `S2Server` each embed the full `StreamStackNode` (raft, metadata, storage engine) in one JVM.
Running streamstack means running one server process per node. DS and S2 are alternative protocol facades over the same engine, pick one per deployment.
-Storage is chosen by the topo file (`TOPO`), not by the facade compose file. Stack compose files with `-f` to combine a node with MinIO.
-For AWS, set `DATA_BUCKET` / `WAL_BUCKET` to override the topo's S3 URIs without editing YAML, that rewrite drops any MinIO `endpoint` / `pathStyle`.
+`harness/docker` is the image. `local`, `aws`, and `fly` are how to run it. Storage is chosen by the topo file (`TOPO`). `DATA_BUCKET` / `WAL_BUCKET` / `BUCKET_NAME` override the topo S3 URIs.
-## Docker Compose
-
-| Compose file | What it runs |
-|--------------|--------------|
-| `docker-compose.minio.yml` | MinIO + bucket init |
-| `docker-compose.ds.yml` | one DS node (`NODE_ID` 1) |
-| `docker-compose.s2.yml` | one S2 node (`NODE_ID` 1) |
-| `docker-compose.cluster.ds.yml` | three DS nodes (`topo.cluster.yaml`) |
-
-## MinIO
+## Local (MinIO)
```bash
-docker compose --env-file harness/configs/minio.env \
- -f harness/docker/docker-compose.minio.yml \
- -f harness/docker/docker-compose.ds.yml \
+cp harness/local/.env.example harness/local/.env
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
up -d --build
```
-Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run S2 instead. Node listens on `127.0.0.1:4437`.
-MinIO console: http://127.0.0.1:9001 (`minioadmin` / `minioadmin`). On Linux, add `extra_hosts: ["host.docker.internal:host-gateway"]` to the node service so `topo.minio.yaml` can reach MinIO on the host.
+Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run S2 instead. Node listens on `127.0.0.1:4437`.
-Bare JVM (`topo.minio.yaml` uses `host.docker.internal` for Docker, override to `127.0.0.1` on the host):
+[BENCH.md](BENCH.md) has DS and S2 smoke/load tests.
+MinIO console: http://127.0.0.1:9001 (`minioadmin` / `minioadmin`).
+
+Bare JVM (`local/topo.yaml` uses `host.docker.internal` for Docker, override to `127.0.0.1` on the host):
```bash
-docker compose -f harness/docker/docker-compose.minio.yml up -d
+docker compose -f harness/local/docker-compose.minio.yml up -d
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin
export AWS_REGION=us-east-1
mvn -pl frontend/ds/server -am package -DskipTests
-java -jar frontend/ds/server/target/ds-server.jar --topo harness/configs/topo.minio.yaml --node-id 1 \
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.yaml --node-id 1 \
--storage "0@s3://streams-data?region=us-east-1&endpoint=http://127.0.0.1:9000&pathStyle=true" \
--wal "0@s3://streams-wal?region=us-east-1&endpoint=http://127.0.0.1:9000&pathStyle=true"
```
@@ -47,53 +40,74 @@ Swap `frontend/ds/server` / `ds-server.jar` for `frontend/s2/server` / `s2-serve
## AWS S3
1. Create data + WAL buckets.
-2. `cp harness/configs/.env.example harness/configs/.env` and fill `AWS_*`, `DATA_BUCKET`, `WAL_BUCKET`.
+2. `cp harness/aws/.env.example harness/aws/.env` and fill `AWS_*`, `DATA_BUCKET`, `WAL_BUCKET`.
+
+```bash
+docker compose --env-file harness/aws/.env \
+ -f harness/aws/docker-compose.ds.yml \
+ up -d --build
+```
+
+Swap `docker-compose.ds.yml` for `docker-compose.s2.yml` to run S2. Three nodes (ports 4437–4439):
```bash
-docker compose --env-file harness/configs/.env \
- -f harness/docker/docker-compose.ds.yml \
+docker compose --env-file harness/aws/.env \
+ -f harness/aws/docker-compose.cluster.ds.yml \
up -d --build
```
-Or bare JVM (creds from env / `~/.aws` / IAM):
+Bare JVM (creds from env / `~/.aws` / IAM):
```bash
java -jar frontend/ds/server/target/ds-server.jar \
- --topo harness/configs/topo.aws.yaml --node-id 1 \
+ --topo harness/aws/topo.yaml --node-id 1 \
--storage "0@s3://${DATA_BUCKET}?region=${AWS_REGION}" \
--wal "0@s3://${WAL_BUCKET}?region=${AWS_REGION}"
```
-## Multi-node
+## Multi-node (local)
-`docker-compose.cluster.ds.yml` starts three DS processes against `topo.cluster.yaml`. Each service is a fixed `NODE_ID` (1 / 2 / 3). Host network so they bind 4437–4439 / 8091–8093 as in the topo.
+`docker-compose.cluster.ds.yml` starts three DS processes against `local/topo.cluster.yaml`. Each service is a fixed `NODE_ID` (1 / 2 / 3). Host network so they bind 4437–4439 / 8091–8093 as in the topo.
```bash
-docker compose --env-file harness/configs/minio.env \
- -f harness/docker/docker-compose.minio.yml \
- -f harness/docker/docker-compose.cluster.ds.yml \
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.cluster.ds.yml \
up -d --build
```
Bare JVM, same topo, one process per id:
```bash
-java -jar frontend/ds/server/target/ds-server.jar --topo harness/configs/topo.cluster.yaml --node-id 1
-java -jar frontend/ds/server/target/ds-server.jar --topo harness/configs/topo.cluster.yaml --node-id 2
-java -jar frontend/ds/server/target/ds-server.jar --topo harness/configs/topo.cluster.yaml --node-id 3
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 1
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 2
+java -jar frontend/ds/server/target/ds-server.jar --topo harness/local/topo.cluster.yaml --node-id 3
```
-`topo.cluster.yaml` defaults to MinIO storage; set `DATA_BUCKET` / `WAL_BUCKET` (compose) or `--storage` / `--wal` (JVM) for AWS.
+## Fly.io + Tigris
+
+App name must stay `streamstack`.
+
+```bash
+fly launch --config harness/fly/fly.toml
+fly storage create
+fly deploy --config harness/fly/fly.toml
+```
+
+Three nodes: `--config harness/fly/fly.cluster.toml`.
## Topology
| File | Storage |
|------|---------|
-| `topo.minio.yaml` | MinIO via `host.docker.internal:9000` (container → host) |
-| `topo.aws.yaml` | Real `s3://` (no endpoint) |
-| `topo.cluster.yaml` | Three nodes; MinIO via `127.0.0.1:9000` (host network / JVM) |
-
-URI forms: `0@s3://bucket?region=…`, `-2@file:///path`, `0@mem://bucket` (tests).
+| `local/topo.yaml` | MinIO via `host.docker.internal:9000` (container → host) |
+| `local/topo.cluster.yaml` | Three nodes; MinIO via `127.0.0.1:9000` (host network / JVM) |
+| `aws/topo.yaml` | Real `s3://` (no endpoint) |
+| `aws/topo.cluster.yaml` | Three nodes on one host; real `s3://` |
+| `fly/topo.yaml` | One Fly Machine; Tigris (`region=auto`) |
+| `fly/topo.cluster.yaml` | Three Fly process groups `n1`–`n3` |
+
+URI forms: `0@s3://bucket?region=…`, `-2@file:///path`, `0@mem://bucket` (tests).
Omit `global.wal` to default WAL to the storage URI when storage is S3.
`--topo` requires `--node-id`. CLI flags override topo values. Topo `global.envs` are informational — export credentials in the environment that starts the process.
@@ -101,8 +115,8 @@ Omit `global.wal` to default WAL to the storage URI when storage is S3.
## Clean up
```bash
-docker compose --env-file harness/configs/minio.env \
- -f harness/docker/docker-compose.minio.yml \
- -f harness/docker/docker-compose.ds.yml \
+docker compose --env-file harness/local/.env \
+ -f harness/local/docker-compose.minio.yml \
+ -f harness/local/docker-compose.ds.yml \
down -v
```
diff --git a/harness/configs/.env.example b/harness/aws/.env.example
similarity index 67%
rename from harness/configs/.env.example
rename to harness/aws/.env.example
index 49b917a..c749fa8 100644
--- a/harness/configs/.env.example
+++ b/harness/aws/.env.example
@@ -2,6 +2,5 @@ AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_SESSION_TOKEN=
AWS_REGION=us-east-1
-TOPO=/opt/streamstack/harness/configs/topo.aws.yaml
DATA_BUCKET=
WAL_BUCKET=
diff --git a/harness/docker/docker-compose.cluster.ds.yml b/harness/aws/docker-compose.cluster.ds.yml
similarity index 78%
rename from harness/docker/docker-compose.cluster.ds.yml
rename to harness/aws/docker-compose.cluster.ds.yml
index fdaa6a1..8376274 100644
--- a/harness/docker/docker-compose.cluster.ds.yml
+++ b/harness/aws/docker-compose.cluster.ds.yml
@@ -3,7 +3,7 @@ x-env: &env
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
AWS_REGION: ${AWS_REGION:-us-east-1}
- TOPO: /opt/streamstack/harness/configs/topo.cluster.yaml
+ TOPO: /opt/streamstack/topo/topo.cluster.yaml
DATA_BUCKET: ${DATA_BUCKET:-}
WAL_BUCKET: ${WAL_BUCKET:-}
@@ -15,7 +15,7 @@ x-node: &node
MODULE: frontend/ds/server
JAR: ds-server.jar
env_file:
- - path: ../configs/.env
+ - path: .env
required: false
network_mode: host
restart: on-failure
@@ -27,7 +27,7 @@ services:
<<: *env
NODE_ID: "1"
volumes:
- - ../configs:/opt/streamstack/harness/configs:ro
+ - .:/opt/streamstack/topo:ro
- node1-data:/tmp/streamstack
node2:
<<: *node
@@ -35,7 +35,7 @@ services:
<<: *env
NODE_ID: "2"
volumes:
- - ../configs:/opt/streamstack/harness/configs:ro
+ - .:/opt/streamstack/topo:ro
- node2-data:/tmp/streamstack
node3:
<<: *node
@@ -43,7 +43,7 @@ services:
<<: *env
NODE_ID: "3"
volumes:
- - ../configs:/opt/streamstack/harness/configs:ro
+ - .:/opt/streamstack/topo:ro
- node3-data:/tmp/streamstack
volumes:
diff --git a/harness/docker/docker-compose.ds.yml b/harness/aws/docker-compose.ds.yml
similarity index 86%
rename from harness/docker/docker-compose.ds.yml
rename to harness/aws/docker-compose.ds.yml
index 9df9b72..bd22119 100644
--- a/harness/docker/docker-compose.ds.yml
+++ b/harness/aws/docker-compose.ds.yml
@@ -7,19 +7,19 @@ services:
MODULE: frontend/ds/server
JAR: ds-server.jar
env_file:
- - path: ../configs/.env
+ - path: .env
required: false
environment:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
AWS_REGION: ${AWS_REGION:-us-east-1}
- TOPO: ${TOPO}
+ TOPO: /opt/streamstack/topo/topo.yaml
NODE_ID: "1"
DATA_BUCKET: ${DATA_BUCKET:-}
WAL_BUCKET: ${WAL_BUCKET:-}
volumes:
- - ../configs:/opt/streamstack/harness/configs:ro
+ - .:/opt/streamstack/topo:ro
- node1-data:/tmp/streamstack
ports:
- "4437:4437"
diff --git a/harness/docker/docker-compose.s2.yml b/harness/aws/docker-compose.s2.yml
similarity index 86%
rename from harness/docker/docker-compose.s2.yml
rename to harness/aws/docker-compose.s2.yml
index 8ff9d56..fa6efae 100644
--- a/harness/docker/docker-compose.s2.yml
+++ b/harness/aws/docker-compose.s2.yml
@@ -7,19 +7,19 @@ services:
MODULE: frontend/s2/server
JAR: s2-server.jar
env_file:
- - path: ../configs/.env
+ - path: .env
required: false
environment:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
AWS_REGION: ${AWS_REGION:-us-east-1}
- TOPO: ${TOPO}
+ TOPO: /opt/streamstack/topo/topo.yaml
NODE_ID: "1"
DATA_BUCKET: ${DATA_BUCKET:-}
WAL_BUCKET: ${WAL_BUCKET:-}
volumes:
- - ../configs:/opt/streamstack/harness/configs:ro
+ - .:/opt/streamstack/topo:ro
- node1-data:/tmp/streamstack
ports:
- "4437:4437"
diff --git a/harness/aws/topo.cluster.yaml b/harness/aws/topo.cluster.yaml
new file mode 100644
index 0000000..ba7eb15
--- /dev/null
+++ b/harness/aws/topo.cluster.yaml
@@ -0,0 +1,25 @@
+# Three nodes on one host (ports 4437–4439 / 8091–8093). Real S3. DATA_BUCKET / WAL_BUCKET override the URIs.
+global:
+ clusterName: aws
+ storage: 0@s3://streamstack-data?region=us-east-1
+ wal: 0@s3://streamstack-wal?region=us-east-1
+ config:
+ routing: REDIRECT
+ walCacheSize: 209715200
+ blockCacheSize: 104857600
+nodes:
+ - host: 127.0.0.1
+ nodeId: 1
+ httpPort: 4437
+ raftPort: 8091
+ dataDir: /tmp/streamstack/aws/n1
+ - host: 127.0.0.1
+ nodeId: 2
+ httpPort: 4438
+ raftPort: 8092
+ dataDir: /tmp/streamstack/aws/n2
+ - host: 127.0.0.1
+ nodeId: 3
+ httpPort: 4439
+ raftPort: 8093
+ dataDir: /tmp/streamstack/aws/n3
diff --git a/harness/configs/topo.aws.yaml b/harness/aws/topo.yaml
similarity index 80%
rename from harness/configs/topo.aws.yaml
rename to harness/aws/topo.yaml
index 1f2ba3e..ff8a08f 100644
--- a/harness/configs/topo.aws.yaml
+++ b/harness/aws/topo.yaml
@@ -1,3 +1,4 @@
+# Single node. Real S3 (no endpoint). DATA_BUCKET / WAL_BUCKET override the URIs.
global:
clusterName: aws
storage: 0@s3://streamstack-data?region=us-east-1
diff --git a/harness/docker/Dockerfile b/harness/docker/Dockerfile
index 56eaa7e..b1cee54 100644
--- a/harness/docker/Dockerfile
+++ b/harness/docker/Dockerfile
@@ -9,6 +9,12 @@ ARG MODULE=frontend/ds/server
ARG JAR=ds-server.jar
COPY --from=build /build/${MODULE}/target/${JAR} /opt/streamstack/server.jar
COPY harness/docker/entrypoint.sh /opt/streamstack/entrypoint.sh
+COPY harness/local/topo.yaml /opt/streamstack/topo/local.yaml
+COPY harness/local/topo.cluster.yaml /opt/streamstack/topo/local.cluster.yaml
+COPY harness/aws/topo.yaml /opt/streamstack/topo/aws.yaml
+COPY harness/aws/topo.cluster.yaml /opt/streamstack/topo/aws.cluster.yaml
+COPY harness/fly/topo.yaml /opt/streamstack/topo/fly.yaml
+COPY harness/fly/topo.cluster.yaml /opt/streamstack/topo/fly.cluster.yaml
WORKDIR /opt/streamstack
RUN chmod +x /opt/streamstack/entrypoint.sh
ENTRYPOINT ["/opt/streamstack/entrypoint.sh"]
diff --git a/harness/docker/entrypoint.sh b/harness/docker/entrypoint.sh
index 1c72a14..60ab46b 100755
--- a/harness/docker/entrypoint.sh
+++ b/harness/docker/entrypoint.sh
@@ -1,10 +1,46 @@
#!/bin/sh
set -eu
-set -- --topo "${TOPO:?}" --node-id "${NODE_ID:-1}" --http-host 0.0.0.0
-if [ -n "${DATA_BUCKET:-}" ]; then
- set -- "$@" --storage "0@s3://${DATA_BUCKET}?region=${AWS_REGION:-us-east-1}"
+
+extra="$*"
+
+set -- --http-host 0.0.0.0
+
+if [ -n "${TOPO:-}" ]; then
+ set -- "$@" --topo "$TOPO"
fi
-if [ -n "${WAL_BUCKET:-}" ]; then
- set -- "$@" --wal "0@s3://${WAL_BUCKET}?region=${AWS_REGION:-us-east-1}"
+if [ -n "${NODE_ID:-}" ]; then
+ set -- "$@" --node-id "$NODE_ID"
fi
+if [ -n "${DATA_DIR:-}" ]; then
+ set -- "$@" --data-dir "$DATA_DIR"
+fi
+if [ -n "${ROUTING:-}" ]; then
+ set -- "$@" --routing "$ROUTING"
+fi
+
+bucket="${DATA_BUCKET:-${BUCKET_NAME:-}}"
+if [ -n "$bucket" ]; then
+ region="${AWS_REGION:-us-east-1}"
+ endpoint="${AWS_ENDPOINT_URL_S3:-}"
+ endpoint="${endpoint%/}"
+ qs="region=${region}"
+ if [ -n "$endpoint" ]; then
+ qs="${qs}&endpoint=${endpoint}"
+ fi
+ if [ "${PATH_STYLE:-}" = "true" ]; then
+ qs="${qs}&pathStyle=true"
+ fi
+ wal="${WAL_BUCKET:-$bucket}"
+ set -- "$@" --storage "0@s3://${bucket}?${qs}" --wal "0@s3://${wal}?${qs}"
+fi
+
+if [ -n "$extra" ]; then
+ set -- "$@" $extra
+fi
+
+if [ -z "${TOPO:-}" ] && [ -z "$extra" ]; then
+ echo "TOPO or command args required" >&2
+ exit 1
+fi
+
exec java -jar /opt/streamstack/server.jar "$@"
diff --git a/harness/fly/fly.cluster.toml b/harness/fly/fly.cluster.toml
new file mode 100644
index 0000000..8301c2b
--- /dev/null
+++ b/harness/fly/fly.cluster.toml
@@ -0,0 +1,44 @@
+app = "streamstack"
+primary_region = "iad"
+kill_timeout = 30
+
+[build]
+ dockerfile = "harness/docker/Dockerfile"
+
+[build.args]
+ MODULE = "frontend/ds/server"
+ JAR = "ds-server.jar"
+
+[deploy]
+ strategy = "rolling"
+ max_unavailable = 1
+
+[env]
+ TOPO = "/opt/streamstack/topo/fly.cluster.yaml"
+ DATA_DIR = "/data"
+ ROUTING = "LOCAL_ALWAYS"
+ AWS_REGION = "auto"
+ JAVA_TOOL_OPTIONS = "-Djava.net.preferIPv6Addresses=true"
+
+[processes]
+ n1 = "--node-id 1"
+ n2 = "--node-id 2"
+ n3 = "--node-id 3"
+
+[http_service]
+ internal_port = 4437
+ force_https = true
+ auto_stop_machines = "off"
+ auto_start_machines = false
+ min_machines_running = 3
+ processes = ["n1", "n2", "n3"]
+
+[[mounts]]
+ source = "streamstack"
+ destination = "/data"
+ initial_size = "1gb"
+ processes = ["n1", "n2", "n3"]
+
+[[vm]]
+ size = "shared-cpu-2x"
+ memory = "2gb"
diff --git a/harness/fly/fly.toml b/harness/fly/fly.toml
new file mode 100644
index 0000000..a9aeacf
--- /dev/null
+++ b/harness/fly/fly.toml
@@ -0,0 +1,38 @@
+app = "streamstack"
+primary_region = "iad"
+kill_timeout = 30
+
+[build]
+ dockerfile = "harness/docker/Dockerfile"
+
+[build.args]
+ MODULE = "frontend/ds/server"
+ JAR = "ds-server.jar"
+
+[deploy]
+ strategy = "rolling"
+ max_unavailable = 1
+
+[env]
+ TOPO = "/opt/streamstack/topo/fly.yaml"
+ NODE_ID = "1"
+ DATA_DIR = "/data"
+ ROUTING = "LOCAL_ALWAYS"
+ AWS_REGION = "auto"
+ JAVA_TOOL_OPTIONS = "-Djava.net.preferIPv6Addresses=true"
+
+[http_service]
+ internal_port = 4437
+ force_https = true
+ auto_stop_machines = "off"
+ auto_start_machines = false
+ min_machines_running = 1
+
+[mounts]
+ source = "streamstack"
+ destination = "/data"
+ initial_size = "1gb"
+
+[[vm]]
+ size = "shared-cpu-2x"
+ memory = "2gb"
diff --git a/harness/fly/topo.cluster.yaml b/harness/fly/topo.cluster.yaml
new file mode 100644
index 0000000..6d31e75
--- /dev/null
+++ b/harness/fly/topo.cluster.yaml
@@ -0,0 +1,25 @@
+# Three Fly process groups (n1–n3). App name must stay streamstack. BUCKET_NAME overrides the URIs.
+global:
+ clusterName: streamstack
+ storage: 0@s3://streamstack-data?region=auto
+ wal: 0@s3://streamstack-wal?region=auto
+ config:
+ routing: LOCAL_ALWAYS
+ walCacheSize: 67108864
+ blockCacheSize: 67108864
+nodes:
+ - host: n1.process.streamstack.internal
+ nodeId: 1
+ httpPort: 4437
+ raftPort: 8091
+ dataDir: /data
+ - host: n2.process.streamstack.internal
+ nodeId: 2
+ httpPort: 4437
+ raftPort: 8091
+ dataDir: /data
+ - host: n3.process.streamstack.internal
+ nodeId: 3
+ httpPort: 4437
+ raftPort: 8091
+ dataDir: /data
diff --git a/harness/fly/topo.yaml b/harness/fly/topo.yaml
new file mode 100644
index 0000000..2d2f5ec
--- /dev/null
+++ b/harness/fly/topo.yaml
@@ -0,0 +1,15 @@
+# Single Fly Machine. Tigris via AWS_ENDPOINT_URL_S3; BUCKET_NAME overrides the URIs.
+global:
+ clusterName: streamstack
+ storage: 0@s3://streamstack-data?region=auto
+ wal: 0@s3://streamstack-wal?region=auto
+ config:
+ routing: LOCAL_ALWAYS
+ walCacheSize: 67108864
+ blockCacheSize: 67108864
+nodes:
+ - host: fly-local-6pn
+ nodeId: 1
+ httpPort: 4437
+ raftPort: 8091
+ dataDir: /data
diff --git a/harness/configs/minio.env b/harness/local/.env.example
similarity index 60%
rename from harness/configs/minio.env
rename to harness/local/.env.example
index 9372933..08a9322 100644
--- a/harness/configs/minio.env
+++ b/harness/local/.env.example
@@ -1,4 +1,3 @@
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
AWS_REGION=us-east-1
-TOPO=/opt/streamstack/harness/configs/topo.minio.yaml
diff --git a/harness/local/docker-compose.cluster.ds.yml b/harness/local/docker-compose.cluster.ds.yml
new file mode 100644
index 0000000..5b4b5b5
--- /dev/null
+++ b/harness/local/docker-compose.cluster.ds.yml
@@ -0,0 +1,50 @@
+x-env: &env
+ AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
+ AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
+ AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
+ AWS_REGION: ${AWS_REGION:-us-east-1}
+ TOPO: /opt/streamstack/topo/topo.cluster.yaml
+
+x-node: &node
+ build:
+ context: ../..
+ dockerfile: harness/docker/Dockerfile
+ args:
+ MODULE: frontend/ds/server
+ JAR: ds-server.jar
+ env_file:
+ - path: .env
+ required: false
+ network_mode: host
+ restart: on-failure
+
+services:
+ node1:
+ <<: *node
+ environment:
+ <<: *env
+ NODE_ID: "1"
+ volumes:
+ - .:/opt/streamstack/topo:ro
+ - node1-data:/tmp/streamstack
+ node2:
+ <<: *node
+ environment:
+ <<: *env
+ NODE_ID: "2"
+ volumes:
+ - .:/opt/streamstack/topo:ro
+ - node2-data:/tmp/streamstack
+ node3:
+ <<: *node
+ environment:
+ <<: *env
+ NODE_ID: "3"
+ volumes:
+ - .:/opt/streamstack/topo:ro
+ - node3-data:/tmp/streamstack
+
+volumes:
+ node1-data:
+ node2-data:
+ node3-data:
diff --git a/harness/local/docker-compose.ds.yml b/harness/local/docker-compose.ds.yml
new file mode 100644
index 0000000..b968ba3
--- /dev/null
+++ b/harness/local/docker-compose.ds.yml
@@ -0,0 +1,28 @@
+services:
+ node1:
+ build:
+ context: ../..
+ dockerfile: harness/docker/Dockerfile
+ args:
+ MODULE: frontend/ds/server
+ JAR: ds-server.jar
+ env_file:
+ - path: .env
+ required: false
+ environment:
+ AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
+ AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
+ AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
+ AWS_REGION: ${AWS_REGION:-us-east-1}
+ TOPO: /opt/streamstack/topo/topo.yaml
+ NODE_ID: "1"
+ volumes:
+ - .:/opt/streamstack/topo:ro
+ - node1-data:/tmp/streamstack
+ ports:
+ - "4437:4437"
+ - "8091:8091"
+ restart: on-failure
+
+volumes:
+ node1-data:
diff --git a/harness/docker/docker-compose.minio.yml b/harness/local/docker-compose.minio.yml
similarity index 100%
rename from harness/docker/docker-compose.minio.yml
rename to harness/local/docker-compose.minio.yml
diff --git a/harness/local/docker-compose.s2.yml b/harness/local/docker-compose.s2.yml
new file mode 100644
index 0000000..aac08e1
--- /dev/null
+++ b/harness/local/docker-compose.s2.yml
@@ -0,0 +1,28 @@
+services:
+ node1:
+ build:
+ context: ../..
+ dockerfile: harness/docker/Dockerfile
+ args:
+ MODULE: frontend/s2/server
+ JAR: s2-server.jar
+ env_file:
+ - path: .env
+ required: false
+ environment:
+ AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
+ AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
+ AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN:-}
+ AWS_REGION: ${AWS_REGION:-us-east-1}
+ TOPO: /opt/streamstack/topo/topo.yaml
+ NODE_ID: "1"
+ volumes:
+ - .:/opt/streamstack/topo:ro
+ - node1-data:/tmp/streamstack
+ ports:
+ - "4437:4437"
+ - "8091:8091"
+ restart: on-failure
+
+volumes:
+ node1-data:
diff --git a/harness/configs/topo.cluster.yaml b/harness/local/topo.cluster.yaml
similarity index 88%
rename from harness/configs/topo.cluster.yaml
rename to harness/local/topo.cluster.yaml
index c8aaec7..9be11c2 100644
--- a/harness/configs/topo.cluster.yaml
+++ b/harness/local/topo.cluster.yaml
@@ -1,3 +1,4 @@
+# Three nodes on one host (ports 4437–4439 / 8091–8093). MinIO at 127.0.0.1:9000 (host network).
global:
clusterName: cluster
storage: 0@s3://streams-data?region=us-east-1&endpoint=http://127.0.0.1:9000&pathStyle=true
diff --git a/harness/configs/topo.minio.yaml b/harness/local/topo.yaml
similarity index 88%
rename from harness/configs/topo.minio.yaml
rename to harness/local/topo.yaml
index e68b8e4..e32e911 100644
--- a/harness/configs/topo.minio.yaml
+++ b/harness/local/topo.yaml
@@ -1,3 +1,4 @@
+# Single node. MinIO on the Docker host (container → host.docker.internal:9000).
global:
clusterName: minio
storage: 0@s3://streams-data?region=us-east-1&endpoint=http://host.docker.internal:9000&pathStyle=true