diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0702cf9..e4faa89 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,22 +56,56 @@ jobs: with: go-version: '1.24' + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + cache-dependency-path: internal/dashboard/ui/package-lock.json + + - name: Install dashboard dependencies + working-directory: internal/dashboard/ui + run: npm ci + + - name: Type-check dashboard + working-directory: internal/dashboard/ui + run: npm run typecheck + + - name: Build dashboard + working-directory: internal/dashboard/ui + run: npm run build + + - name: Verify committed dashboard assets + run: git diff --exit-code -- internal/dashboard/static/dashboard.js internal/dashboard/static/styles.css + - name: Install SQLite driver (CGO) run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev - name: Test core module + env: + GOTOOLCHAIN: local run: go test -v ./... - - name: Test submodules + - name: Test Go 1.24 submodules env: + GOTOOLCHAIN: local PG_CONN: postgres://testuser:testpass@localhost:5432/testdb?sslmode=disable REDIS_CONN: redis://localhost:6379/0 MONGO_URI: mongodb://root:root@localhost:27017 run: | - for m in store/postgres store/redis store/mongodb store/sqlite telemetry mcp; do + for m in store/postgres store/redis store/mongodb store/sqlite mcp; do echo "== $m" (cd "$m" && go test -v ./...) done - - name: Build examples - run: cd cmd/examples && go build ./... + - name: Set up Go 1.25 + uses: actions/setup-go@v5 + with: + go-version: '1.25' + + - name: Test Go 1.25 modules and build examples + env: + GOTOOLCHAIN: local + run: | + (cd telemetry && go test -v ./...) + (cd cmd/examples && go build ./...) diff --git a/.gitignore b/.gitignore index 0069a59..02206ec 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,6 @@ Thumbs.db # Node.js dependencies node_modules/ -package-lock.json # Built frontend files (these are committed for Go embed) # internal/dashboard/static/dashboard.js @@ -37,4 +36,4 @@ package-lock.json # Example binaries cmd/examples/*/profiling-example -test-build \ No newline at end of file +test-build diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d744b8..38e388a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,35 @@ All notable changes to GoVisual are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.0.1] - 2026-09-03 + +This patch release hardens the capture-to-replay workflow and fixes several cases where observability could change application behavior or present misleading data. + +### Security + +- Dashboard and MCP endpoints now reject untrusted Host values and cross-origin browser requests, and dashboard SSE no longer opts into wildcard CORS. +- Dashboard replay loads a stored request by ID and pins the destination to `WithReplayBaseURL(...)` or a validated loopback dashboard origin. Remote dashboards require an explicit replay base URL. +- MCP replay and generated curl commands now require and use `WithBaseURL(...)`; captured Host values are never used as destinations. Existing MCP replay setups that relied on captured Host must configure `WithBaseURL(...)`. +- Replay strips Host, content length, hop-by-hop headers, connection-nominated headers, and stored redaction placeholders. Redirect following remains disabled. + +### Fixed + +- Capped request-body capture no longer replaces the application's body with the truncated copy. The handler receives the complete original stream, including read failures and close behavior. +- Response headers are captured at commit time and credential-bearing values are redacted before storage. +- `RequestLog.RawPath` preserves encoded path semantics during replay; PostgreSQL and SQLite persist both it and `Host` while migrating existing tables safely. +- SQL instrumentation preserves optional `database/sql/driver` interfaces used for context-aware connections, health checks, session reset, validation, named values, and column conversion. +- Store write failures are logged by default and can be routed through `WithErrorHandler(...)` without failing the application request. +- `ResponseWriter.Unwrap()` now works with `http.ResponseController` and compatible middleware. +- Dashboard Errors includes captured errors and panics, live updates no longer race the initial fetch, comparisons retain requested order, and duration units render correctly. +- Profiling now reports allocation and GC deltas for the request window while identifying process-wide heap and goroutine gauges accurately. Existing persisted v2.0.0 records retain their original cumulative GC values. +- MCP outputs have hard ceilings, replay reports omitted redacted headers, `diff_replay` accepts credential/body overrides and compares the full bounded replay body, and `save_as_test` accepts an optional `expected_status`. +- Generated curl commands quote custom methods, disable curl's `@file` body expansion, use only safe destinations, and reject incomplete or oversized captured bodies. + +### Developer experience + +- The dashboard dependency lockfile is committed, and the development build moves to a patched esbuild release. CI now installs the locked graph, type-checks and rebuilds the UI, verifies generated assets, and tests modules against their declared Go versions. +- Dashboard, configuration, API, request-logging, and contributor documentation now match the v2 runtime behavior. + ## [v2.0.0] - 2026-07-02 The 2.0 release turns GoVisual into a runtime debugger a coding agent can drive, keeps the core module dependency-free, and hardens every prior rough edge with a full test suite. diff --git a/README.md b/README.md index 32517cc..877e269 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ claude mcp add govisual --transport http http://localhost:8080/mcp **Tools:** `get_last_error`, `list_requests`, `get_request`, `search_requests`, `get_stats`, `get_debug_context`, `replay_request`, `diff_replay`, `await_request`, `save_as_test`, `copy_as_curl`, `clear_requests`. -Responses are token-aware: bounded list sizes, capped body excerpts, sizes reported so the agent knows when to ask for more. The endpoint is loopback-only by default. Replays are pinned to the base URL you configured, so an agent cannot use it to reach arbitrary hosts. +Responses are token-aware: bounded lists and diagnostics, capped body excerpts, and sizes reported so the agent knows when to ask for more. The endpoint is loopback-only by default. Replay, diff, and generated curl commands require and are pinned to `WithBaseURL(...)`. Full guide: [docs/claude-code.md](docs/claude-code.md). @@ -165,7 +165,7 @@ The event appears on the request's Logs tab and (with profiling on) inside the m `http://localhost:8080/__viz` by default. Customize with `WithDashboardPath("/__debug")`. - **Inbox, Errors, Slow**: filter captured requests by status and duration. -- **Request drawer** per request: Overview, Headers, Body, Trace (middleware, SQL, outbound HTTP), Logs, Performance (CPU, memory, GC, flame graph when profiling is on). +- **Request drawer** per request: Overview, Headers, Body, Trace (middleware, SQL, outbound HTTP), Logs, Performance (allocations, process heap, goroutines, GC, and a flame graph when profiling is on). - **Analytics**: per-route request counts, p50/p95, error rates. - **Agents**: recent MCP tool calls with their arguments, so you can watch a coding agent debug the app in real time. - **Environment**: Go version, GOOS/GOARCH, memory stats, allowlisted env vars. @@ -253,11 +253,13 @@ handler := govisual.Wrap( // Storage (in-memory by default) govisual.WithStore(myStore), + govisual.WithErrorHandler(func(err error) { logger.Error("capture failed", "error", err) }), // Dashboard security govisual.WithAllowRemote(), // loopback-only by default govisual.WithBasicAuth("admin", "s3cret"), - govisual.WithReplayEnabled(true), // opt-in, SSRF-checked + govisual.WithReplayEnabled(true), // opt-in; destination is pinned + govisual.WithReplayBaseURL("http://127.0.0.1:8080"), // required with WithAllowRemote govisual.WithSystemInfo("GOPATH", "HOME"), // env vars require an explicit allowlist // Profiling (feeds the Performance tab and the bottleneck analyzer) @@ -278,8 +280,8 @@ Full option reference: [docs/api-reference.md](docs/api-reference.md). Longer co The dashboard sees every captured request and response, so v2 defaults are conservative: -- **Loopback-only** unless `WithAllowRemote()`. Pair remote access with auth. -- **Request replay** is off unless `WithReplayEnabled(true)`. Enabling it opens `POST /__viz/api/replay`, which makes the server issue an outbound request. Targets that resolve to private IPs are rejected before the call. +- **Loopback-only** unless `WithAllowRemote()`. Never expose a remote dashboard without `WithBasicAuth`, `WithDashboardAuth`, or equivalent authentication in an outer handler. +- **Request replay** is off unless `WithReplayEnabled(true)`. Replays load a captured request by ID and are pinned to `WithReplayBaseURL(...)`, or to a validated loopback dashboard origin when no base URL is configured. `WithAllowRemote()` requires an explicit replay base URL. Clients may edit the method, path, headers, and body, but cannot choose another destination host. - **System info** is off unless `WithSystemInfo(...)`. Environment variables are only exposed if you list them by name. - **Basic auth** via `WithBasicAuth(user, pass)`, or a custom check via `WithDashboardAuth(func(*http.Request) bool)`. - **Sensitive headers** (Authorization, Cookie, Set-Cookie, X-Api-Key, X-Auth-Token, X-Csrf-Token) are redacted at capture time. The header name is kept, the value is replaced. diff --git a/cmd/examples/go.mod b/cmd/examples/go.mod index 256f92c..55524f8 100644 --- a/cmd/examples/go.mod +++ b/cmd/examples/go.mod @@ -8,7 +8,7 @@ require ( github.com/doganarif/govisual/store/redis v0.0.0-00010101000000-000000000000 github.com/doganarif/govisual/store/sqlite v0.0.0-00010101000000-000000000000 github.com/doganarif/govisual/telemetry v0.0.0-00010101000000-000000000000 - github.com/doganarif/govisual/v2 v2.0.0 + github.com/doganarif/govisual/v2 v2.0.1 github.com/mattn/go-sqlite3 v1.14.47 go.opentelemetry.io/otel v1.44.0 go.opentelemetry.io/otel/trace v1.44.0 diff --git a/docs/api-reference.md b/docs/api-reference.md index 86a0ab2..7fb3622 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -157,6 +157,24 @@ govisual.WithStore(pg) --- +### `WithErrorHandler` + +```go +func WithErrorHandler(fn func(error)) Option +``` + +Receives request-capture persistence errors synchronously after the wrapped handler returns. The callback should return promptly; its panics are recovered and logged so they cannot replace the application result. When omitted, GoVisual logs storage errors through the standard library logger. + +**Example:** + +```go +govisual.WithErrorHandler(func(err error) { + logger.Error("govisual capture failed", "error", err) +}) +``` + +--- + ### `WithShutdownContext` ```go @@ -254,7 +272,7 @@ govisual.WithDashboardAuth(func(r *http.Request) bool { func WithReplayEnabled(enabled bool) Option ``` -Enables the dashboard's `/api/replay` endpoint. Disabled by default because the endpoint lets the server make arbitrary outbound HTTP requests (an SSRF primitive). Only enable it behind authentication and/or loopback-only access. +Enables the dashboard's `/api/replay` endpoint. Disabled by default. Replay loads a captured request by ID and sends it only to the configured replay base URL or, for a loopback-only dashboard, the validated dashboard origin. `WithAllowRemote()` requires an explicit replay base URL. Only enable replay behind authentication and/or loopback-only access. **Example:** @@ -264,6 +282,22 @@ govisual.WithReplayEnabled(true) --- +### `WithReplayBaseURL` + +```go +func WithReplayBaseURL(baseURL string) Option +``` + +Pins request replay to a server-configured HTTP or HTTPS origin. It is required with `WithAllowRemote()` and is also useful when the application is behind a reverse proxy or the browser-facing dashboard origin is not reachable from the application process. Dashboard clients cannot override this authority. + +**Example:** + +```go +govisual.WithReplayBaseURL("http://127.0.0.1:8080") +``` + +--- + ### `WithSystemInfo` ```go @@ -288,7 +322,7 @@ govisual.WithSystemInfo("GOPATH", "GOOS") func WithProfiling(enabled bool) Option ``` -Enables per-request performance profiling. When enabled, each request captures CPU time, memory allocations, goroutine counts, SQL queries (via `WrapDriver`), and outbound HTTP calls (via `WrapTransport`). +Enables per-request performance profiling. Requests that meet `WithProfileThreshold` retain metrics for the selected profile types, including allocation and GC deltas for the profiling window, process heap and goroutine gauges, SQL queries (via `WrapDriver`), and outbound HTTP calls (via `WrapTransport`). **Example:** diff --git a/docs/claude-code.md b/docs/claude-code.md index 3595f50..5fef348 100644 --- a/docs/claude-code.md +++ b/docs/claude-code.md @@ -74,6 +74,8 @@ failing request, and verify fixes with `diff_replay` (expect ## Security notes -- The MCP endpoint answers loopback addresses only, unless `gvmcp.WithAllowRemote()` is set. Pair remote access with `gvmcp.WithToken("...")`. +- The MCP endpoint answers loopback addresses only, unless `gvmcp.WithAllowRemote()` is set. Never enable remote access without `gvmcp.WithToken("...")` or equivalent authentication in an outer handler. - `replay_request` can change the method, path, headers, and body — but never the destination. Replays always target your app (`WithBaseURL`), so the endpoint is not an SSRF primitive. +- Replay, diff, and generated curl commands require `WithBaseURL`; captured Host values are never trusted as destinations. +- Redacted credentials are never replayed implicitly. Supply deliberate header overrides to `replay_request` or `diff_replay` when an authenticated comparison is required. - Sensitive headers (Authorization, Cookie, API keys) are redacted at capture time, before anything reaches the store or the agent. diff --git a/docs/configuration.md b/docs/configuration.md index 80edd32..92b1ff7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -22,30 +22,32 @@ handler := govisual.Wrap( | `WithDashboardPath(string)` | URL path for the dashboard | `/__viz` | `govisual.WithDashboardPath("/__debug")` | | `WithRequestBodyLogging(bool)` | Capture request bodies | false | `govisual.WithRequestBodyLogging(true)` | | `WithResponseBodyLogging(bool)` | Capture response bodies | false | `govisual.WithResponseBodyLogging(true)` | -| `WithIgnorePaths(...string)` | Path patterns to exclude from capture | `[]` | `govisual.WithIgnorePaths("/health", "/metrics")` | +| `WithIgnorePaths(...string)` | Path patterns to exclude from capture | `["/favicon.ico"]` | `govisual.WithIgnorePaths("/health", "/metrics")` | | `WithMaxBodyBytes(int)` | Cap on captured body size in bytes. `0` = 1 MiB default, positive = explicit cap, negative = unbounded. | 1 MiB | `govisual.WithMaxBodyBytes(64 << 10)` | | `WithSampleRate(float64)` | Fraction of requests to capture (0..1). Uncaptured requests pass through untouched. | 1.0 | `govisual.WithSampleRate(0.1)` | | `WithStore(store.Store)` | Storage backend for captured requests. Omit to use an in-memory store bounded by `WithMaxRequests`. | in-memory | `govisual.WithStore(pg)` | +| `WithErrorHandler(func(error))` | Route capture persistence failures synchronously; callbacks should return promptly and panics are recovered. | standard logger | `govisual.WithErrorHandler(reportError)` | | `WithShutdownContext(ctx)` | Cancel this context to release storage resources on shutdown. | none | `govisual.WithShutdownContext(ctx)` | ### Dashboard Security -The dashboard is loopback-only by default. `WithAllowRemote` opts out of that restriction; pair it with an auth option when you do. +The dashboard is loopback-only by default. `WithAllowRemote` opts out of that restriction; never use it without `WithBasicAuth`, `WithDashboardAuth`, or equivalent authentication in an outer handler. | Option | Description | Default | Example | | --- | --- | --- | --- | | `WithLocalhostOnly()` | Restrict the dashboard to loopback addresses. This is the default; the option exists to make intent explicit. | on | `govisual.WithLocalhostOnly()` | -| `WithAllowRemote()` | Allow non-loopback addresses to reach the dashboard. Pair with `WithBasicAuth` or `WithDashboardAuth`. | off | `govisual.WithAllowRemote()` | +| `WithAllowRemote()` | Allow non-loopback addresses to reach the dashboard. Must be paired with `WithBasicAuth`, `WithDashboardAuth`, or equivalent outer authentication. | off | `govisual.WithAllowRemote()` | | `WithBasicAuth(user, pass)` | Protect the dashboard with HTTP Basic Auth (constant-time compare) | off | `govisual.WithBasicAuth("admin", "secret")` | | `WithDashboardAuth(fn)` | Custom auth function run on every dashboard request; return true to allow | off | `govisual.WithDashboardAuth(myCheck)` | -| `WithReplayEnabled(bool)` | Enable the request replay endpoint (SSRF primitive — keep it gated) | false | `govisual.WithReplayEnabled(true)` | +| `WithReplayEnabled(bool)` | Enable request replay. Replays load a captured request by ID and use a server-pinned destination. | false | `govisual.WithReplayEnabled(true)` | +| `WithReplayBaseURL(string)` | Pin replay to an application origin. Required with `WithAllowRemote()`; a loopback-only dashboard can use its validated origin. | validated loopback dashboard origin | `govisual.WithReplayBaseURL("http://127.0.0.1:8080")` | | `WithSystemInfo(...string)` | Enable the system-info endpoint; env vars shown only if allowlisted | false | `govisual.WithSystemInfo("GOPATH")` | ### Profiling Options | Option | Description | Default | Example | | --- | --- | --- | --- | -| `WithProfiling(bool)` | Enable per-request CPU/memory/goroutine profiling | false | `govisual.WithProfiling(true)` | +| `WithProfiling(bool)` | Enable per-request allocation, GC, goroutine, SQL, and outbound HTTP profiling | false | `govisual.WithProfiling(true)` | | `WithProfileType(ProfileType)` | Which profiles to collect: `ProfileCPU`, `ProfileMemory`, `ProfileGoroutine`, `ProfileAll` | `ProfileAll` | `govisual.WithProfileType(govisual.ProfileCPU)` | | `WithProfileThreshold(duration)` | Only keep profiles for requests slower than this | 10ms | `govisual.WithProfileThreshold(50 * time.Millisecond)` | | `WithMaxProfileMetrics(int)` | Maximum number of profile records to retain | 1000 | `govisual.WithMaxProfileMetrics(500)` | @@ -81,6 +83,7 @@ handler := govisual.Wrap( mux, govisual.WithBasicAuth("admin", "secret"), govisual.WithReplayEnabled(true), + govisual.WithReplayBaseURL("http://127.0.0.1:8080"), govisual.WithSystemInfo("GOPATH", "GOOS"), ) ``` diff --git a/docs/contributing.md b/docs/contributing.md index cd4a310..28c7fe5 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,127 +1,97 @@ # Contributing to GoVisual -Thank you for your interest in contributing to GoVisual! This document provides guidelines and instructions for contributing to the project. +Thanks for helping improve GoVisual. Keep changes focused, add tests for behavior changes, and update generated dashboard assets when the UI changes. -## Development Setup +## Prerequisites -### Prerequisites +- Go 1.24 for the core, MCP, and storage modules; Go 1.25 for telemetry and examples (or Go 1.25 for the full repository) +- Node.js 22 and npm for dashboard work +- Docker for PostgreSQL, Redis, MongoDB, and integration examples +- CGO and SQLite development headers for the SQLite module -- Go 1.20 or higher -- Docker and Docker Compose (for running the examples with databases) -- Git +## Set up a checkout -### Getting Started +```bash +git clone https://github.com/YOUR_GITHUB_USER/GoVisual.git +cd GoVisual +git remote add upstream https://github.com/doganarif/GoVisual.git +go mod download +``` -1. Fork the repository on GitHub -2. Clone your fork locally - ```bash - git clone https://github.com/yourusername/govisual.git - cd govisual - ``` -3. Add the original repository as an upstream remote - ```bash - git remote add upstream https://github.com/doganarif/govisual.git - ``` -4. Install dependencies - ```bash - go mod download - ``` +Use a short semantic branch name such as `fix/replay-validation`, `feat/request-filter`, or `docs/dashboard-guide`. -## Running Tests +## Run the tests -Run the tests with: +Test the core v2 module: ```bash go test ./... ``` -For tests involving storage backends, you can use the provided Docker Compose files: +The storage backends, telemetry package, MCP server, and examples are separate Go modules. Run them from their module directories: ```bash -# For PostgreSQL tests -cd cmd/examples/multistorage -GOVISUAL_STORAGE_TYPE=postgres \ -GOVISUAL_PG_CONN="postgres://postgres:postgres@localhost:5432/govisual?sslmode=disable" \ -go test ../../internal/store/... - -# For Redis tests -GOVISUAL_STORAGE_TYPE=redis \ -GOVISUAL_REDIS_CONN="redis://localhost:6379/0" \ -go test ../../internal/store/... +for module in store/postgres store/redis store/mongodb store/sqlite telemetry mcp cmd/examples; do + (cd "$module" && go test ./...) +done ``` -## Code Style Guidelines - -GoVisual follows standard Go coding conventions: - -- Run `go fmt` before committing to ensure consistent formatting -- Follow [Effective Go](https://golang.org/doc/effective_go) guidelines -- Use `golint` and `go vet` to check for common issues -- Write meaningful comments, especially for exported functions and types -- Keep functions small and focused on a single responsibility -- Use meaningful variable and function names that describe their purpose - -## Contribution Workflow +PostgreSQL, Redis, and MongoDB tests need running services and the same connection variables used by CI: -1. Create a new branch for your feature or bugfix - - ```bash - git checkout -b feature/your-feature-name - ``` - -2. Make your changes, following the code style guidelines - -3. Add tests for your changes - -4. Run tests to make sure everything works +```bash +export PG_CONN='postgres://testuser:testpass@localhost:5432/testdb?sslmode=disable' +export REDIS_CONN='redis://localhost:6379/0' +export MONGO_URI='mongodb://root:root@localhost:27017' +``` - ```bash - go test ./... - ``` +Build all examples with: -5. Commit your changes with a clear and descriptive commit message +```bash +(cd cmd/examples && go build ./...) +``` - ```bash - git commit -m "Add support for new feature X" - ``` +Before opening a pull request, format changed Go files and run static checks: -6. Push to your fork +```bash +gofmt -w path/to/changed.go +go vet ./... +``` - ```bash - git push origin feature/your-feature-name - ``` +## Dashboard development -7. Create a Pull Request against the main repository +The dashboard source is in `internal/dashboard/ui`. Its production JavaScript and CSS are committed under `internal/dashboard/static` because the Go binary embeds them. -## Pull Request Guidelines +Install exactly the locked dependency set, type-check, and rebuild: -- Provide a clear description of the problem you're solving -- Update documentation if necessary -- Add or update tests as appropriate -- Keep PRs focused on a single issue/feature to make them easier to review -- Make sure CI tests pass +```bash +cd internal/dashboard/ui +npm ci +npm run typecheck +npm run build +``` -## Adding Storage Backends +Commit `package-lock.json` whenever dependencies change. After any UI change, include the regenerated `internal/dashboard/static/dashboard.js` and `internal/dashboard/static/styles.css`. CI rebuilds both files and fails when the committed assets differ. -When adding a new storage backend: +For local watch mode: -1. Implement the `Store` interface in `internal/store/store.go` -2. Add relevant configuration options in `options.go` -3. Update factory methods in `internal/store/factory.go` -4. Add documentation in `docs/storage-backends.md` -5. Create examples showing usage +```bash +npm run dev +``` -## Reporting Issues +## Adding a storage backend -When reporting issues, please include: +1. Implement the `store.Store` interface from `store/store.go`. +2. Put the backend in its own module under `store/`. +3. Reuse `store/storetest` for contract coverage. +4. Test persistence, ordering, capacity, cleanup, and schema migration behavior. +5. Document installation and configuration in [storage-backends.md](storage-backends.md). -- A clear description of the problem -- Steps to reproduce -- Expected vs. actual behavior -- Version of GoVisual you're using -- Go version and OS -- Any relevant logs or error messages +## Pull requests -## License +- Explain the user-visible problem and the chosen behavior. +- Add focused regression tests. +- Update documentation and generated assets where applicable. +- Keep unrelated refactors out of the change. +- Ensure the core module, affected submodules, dashboard checks, and example build pass. -By contributing to GoVisual, you agree that your contributions will be licensed under the project's MIT license. +By contributing, you agree that your contribution is licensed under the project's MIT license. diff --git a/docs/dashboard.md b/docs/dashboard.md index 2e25006..93f5130 100644 --- a/docs/dashboard.md +++ b/docs/dashboard.md @@ -1,108 +1,111 @@ # GoVisual Dashboard -The GoVisual dashboard provides a real-time view of HTTP requests flowing through your application. +The embedded dashboard is a live view of requests captured by GoVisual v2. It is served by the same handler as your application and does not require a separate process. ![GoVisual Dashboard](dashboard.png) -## Accessing the Dashboard +## Open the dashboard -By default, the dashboard is available at `http://localhost:/__viz`. You can customize this path using the `WithDashboardPath` option: +The default URL is `http://localhost:/__viz`. To mount it elsewhere: ```go handler := govisual.Wrap( - mux, - govisual.WithDashboardPath("/__debug"), + mux, + govisual.WithDashboardPath("/__debug"), ) ``` -## Dashboard Features +Dashboard traffic is loopback-only by default. If you allow remote access, protect it with authentication because captured headers and bodies may contain application data: -### Request Table - -The main view displays a table of recent HTTP requests with the following information: - -- **Method**: HTTP method (GET, POST, PUT, etc.) -- **Path**: The request URL path -- **Status**: HTTP status code (color-coded) -- **Time**: Response time in milliseconds -- **Timestamp**: When the request was received - -The table automatically updates as new requests come in. +```go +handler := govisual.Wrap( + mux, + govisual.WithAllowRemote(), + govisual.WithBasicAuth("admin", os.Getenv("DASHBOARD_PASSWORD")), +) +``` -### Request Details +## Views -Clicking on a request in the table reveals detailed information: +- **Inbox** shows all captured requests. +- **Errors** includes HTTP 4xx/5xx responses, requests with a recorded `Error`, and captured panics. +- **Slow** shows requests that took at least 200ms. +- **Analytics** summarizes throughput, response classes, latency, and endpoints. JSON/CSV export, client-local JSON import, and clearing the store are available here. Imported rows are temporary UI state and are replaced by the next authoritative live snapshot or reload. +- **Agents** shows recent MCP activity when the same `*store.ActivityLog` is passed to GoVisual and the MCP module. +- **Environment** shows runtime information only when `WithSystemInfo(...)` is enabled. Environment variables are limited to the names you explicitly allowlist. -#### Request Tab +Use the path search and 2xx/3xx/4xx/5xx chips to narrow the request list. New requests arrive over Server-Sent Events, so the list updates without polling or reloading. -- Full URL (including query parameters) -- HTTP method -- Headers -- Request body (if enabled) -- Cookies +## Request details -#### Response Tab +Select a request to inspect: -- Status code -- Headers -- Response body (if enabled) -- Content type -- Response size +- **Overview**: method, path, status, duration, query, captured error, and panic stack. +- **Headers**: captured request and response headers. Credential-bearing values are redacted at capture time. +- **Body**: request and response bodies when body logging is enabled. +- **Trace**: middleware entries plus instrumented SQL queries and outbound HTTP calls. +- **Logs**: `slog` records and custom events attached to the request context. +- **Performance**: allocation, process, GC, bottleneck, and flame-graph data when profiling is enabled. -#### Timing Tab +Select two or more requests with **Compare** to compare their metadata, bodies, headers, and performance data in selection order. -- Total response time -- Time spent in each middleware -- Network latency +## Optional data sources -#### Middleware Trace Tab +Body capture is off by default: -- Visual representation of middleware execution -- Time spent in each middleware -- Call hierarchy +```go +handler := govisual.Wrap( + mux, + govisual.WithRequestBodyLogging(true), + govisual.WithResponseBodyLogging(true), +) +``` -### Filtering and Searching +Profiling powers SQL, outbound HTTP, bottleneck, and performance panels: -The dashboard includes filtering capabilities: +```go +handler := govisual.Wrap(mux, govisual.WithProfiling(true)) +``` -- Filter by HTTP method (GET, POST, etc.) -- Filter by status code or status code range (2xx, 4xx, etc.) -- Search by URL path -- Filter by time range +Application logs appear when they use a request context and a wrapped handler: -### Dashboard Controls +```go +logger := slog.New(govisual.SlogHandler(slog.NewJSONHandler(os.Stdout, nil))) +logger.InfoContext(r.Context(), "loaded account", "account_id", accountID) +``` -- **Clear All**: Remove all requests from the view -- **Auto-refresh**: Toggle automatic updates -- **Columns**: Show/hide specific columns -- **Export**: Download request data as JSON +## Request replay -## Browser Support +Replay is disabled by default. Enable it only on a protected dashboard: -The GoVisual dashboard is compatible with all modern browsers: +```go +handler := govisual.Wrap( + mux, + govisual.WithBasicAuth("admin", os.Getenv("DASHBOARD_PASSWORD")), + govisual.WithReplayEnabled(true), + govisual.WithReplayBaseURL("http://127.0.0.1:8080"), // required with WithAllowRemote +) +``` -- Chrome (recommended) -- Firefox -- Safari -- Edge +The replay endpoint loads the original request by ID. The dashboard can override its method, path, headers, and body, but cannot supply an arbitrary destination URL. The destination is `WithReplayBaseURL(...)` when configured, otherwise a loopback-only dashboard can use its validated origin. Remote dashboards must configure `WithReplayBaseURL(...)`. Replay paths must start with `/`; redirects, host overrides, hop-by-hop headers, content length, and stored redaction markers are not forwarded. ## Troubleshooting -If you can't access the dashboard: +If the dashboard does not load: -1. Verify that the dashboard path is correct -2. Check that your application is running -3. Ensure no path conflict with your application's routes -4. Check if any security middleware is blocking access +1. Confirm the configured dashboard path. +2. Remember that remote clients are rejected unless `WithAllowRemote()` is set. +3. Check that an outer router or authentication middleware is not intercepting the dashboard path. -If requests aren't showing up: +If requests do not appear: -1. Ensure the routes are passing through the GoVisual middleware -2. Check if the routes are in the ignored paths list -3. Make sure you're sending requests to the instrumented handler +1. Confirm traffic passes through the handler returned by `govisual.Wrap`. +2. Check `WithIgnorePaths(...)` and `WithSampleRate(...)`. +3. Check the browser network panel for a connected `__viz/api/events` stream. -## Related Documentation +## Related documentation -- [Configuration Options](configuration.md) - Configure dashboard behavior -- [Request Logging](request-logging.md) - Control what gets logged -- [Middleware Tracing](middleware-tracing.md) - How middleware tracing works +- [Configuration options](configuration.md) +- [Request logging](request-logging.md) +- [Middleware tracing](middleware-tracing.md) +- [Storage backends](storage-backends.md) diff --git a/docs/installation.md b/docs/installation.md index c8e5670..9a188d3 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -4,7 +4,7 @@ This guide covers installing GoVisual for your Go web applications. ## Requirements -- Go 1.24 or higher +- Go 1.24 or higher for core, MCP, and storage modules; the optional telemetry module requires Go 1.25 - (Optional) a database for persistent storage — each backend is its own module under `store/` - (Optional) an OpenTelemetry collector, via the `telemetry` module diff --git a/docs/request-logging.md b/docs/request-logging.md index 010e2f8..afa9ae7 100644 --- a/docs/request-logging.md +++ b/docs/request-logging.md @@ -1,112 +1,140 @@ # Request Logging -GoVisual can capture and log HTTP requests and responses passing through your application. This document explains how request logging works and how to configure it. +GoVisual v2 captures request metadata around the `http.Handler` you pass to `govisual.Wrap`. Metadata capture is on by default; request and response bodies are opt-in. -## Basic Logging +## Captured metadata -By default, GoVisual logs basic request and response metadata: +Each sampled request records: -- HTTP method (GET, POST, PUT, etc.) -- URL path -- Query parameters -- Status code -- Response time -- Timestamp -- Request and response headers +- ID and timestamp +- method, host, path, and raw query +- request and response headers +- status code and duration in milliseconds +- request-scoped logs and custom events +- middleware and route trace data when supplied +- profiling data when profiling is enabled and the request meets the configured threshold +- an error and stack trace when the wrapped handler panics -This basic information is always captured and does not require any special configuration. +Panics are recorded and then re-raised, so recovery middleware and `net/http` keep their normal behavior. -## Body Logging +## Body logging and limits -For more detailed logging, you can enable request and response body logging: +Body capture is disabled by default: ```go handler := govisual.Wrap( - mux, - govisual.WithRequestBodyLogging(true), // Log request bodies - govisual.WithResponseBodyLogging(true), // Log response bodies + mux, + govisual.WithRequestBodyLogging(true), + govisual.WithResponseBodyLogging(true), ) ``` -### Important Considerations +Captured request and response bodies are each limited to 1 MiB by default. Larger bodies are truncated in the stored copy; the application still receives or sends the request normally. Set an explicit cap when needed: -When enabling body logging, keep in mind: +```go +handler := govisual.Wrap( + mux, + govisual.WithRequestBodyLogging(true), + govisual.WithResponseBodyLogging(true), + govisual.WithMaxBodyBytes(256<<10), // 256 KiB per captured body +) +``` + +A negative `WithMaxBodyBytes` value disables the cap and is not recommended. Body logging may retain passwords, tokens, personal data, or large payloads; enable it only where that tradeoff is acceptable. + +## Header redaction -1. **Performance Impact**: Logging bodies requires reading them completely into memory, which may impact performance for large payloads -2. **Security Concerns**: Request and response bodies may contain sensitive information (passwords, tokens, PII) -3. **Memory Usage**: Bodies are stored in memory by default, which can increase memory usage +Headers are captured, but these credential-bearing values are replaced with `[redacted by govisual]` before the request reaches any storage backend: -## Ignoring Paths +- `Authorization` +- `Proxy-Authorization` +- `Cookie` +- `Set-Cookie` +- `X-Api-Key` +- `X-Auth-Token` +- `X-Csrf-Token` -To prevent logging of certain paths (like health checks or static assets), use the `WithIgnorePaths` option: +Header names remain visible. Apply application-specific redaction before `govisual.Wrap` if your service uses other sensitive headers. Body values are not automatically redacted. + +## Sampling and ignored paths + +Capture only a fraction of traffic with a rate from 0 to 1: + +```go +handler := govisual.Wrap(mux, govisual.WithSampleRate(0.1)) // about 10% +``` + +Exclude noisy or sensitive paths: ```go handler := govisual.Wrap( - mux, - govisual.WithIgnorePaths( - "/health", // Exact match - "/metrics", // Exact match - "/static/*", // Wildcard pattern - "/api/auth/*" // Wildcard pattern - ), + mux, + govisual.WithIgnorePaths( + "/health", + "/metrics", + "/static/*", + ), ) ``` -The dashboard path (`/__viz` by default) is automatically ignored to prevent recursive logging. +Patterns use Go's `filepath.Match`; a pattern ending in `/` also acts as a prefix. The dashboard path and its API are always ignored to prevent recursive logging. `/favicon.ico` is ignored by default. -## Storage Considerations +## Request-scoped logs and events -How requests are stored depends on your configured storage backend: +Wrap a `slog.Handler`, then log with the incoming request context: -- **Memory Storage**: Logs are kept in memory and lost when the application restarts -- **PostgreSQL Storage**: Logs are stored in a database table and persist across restarts -- **Redis Storage**: Logs are stored with a configurable time-to-live (TTL) +```go +logger := slog.New(govisual.SlogHandler(slog.NewJSONHandler(os.Stdout, nil))) +logger.InfoContext(r.Context(), "cache lookup", "hit", true) +``` -See [Storage Backends](storage-backends.md) for more details. +Add structured diagnostic events without a logger: -## Custom Headers +```go +govisual.Event(r.Context(), "cache miss", "key", key, "tier", "redis") +``` -All headers are logged by default. If some headers contain sensitive information, you should handle them at the application level before they reach GoVisual. +Both appear on the request's Logs tab. Records written without the request context still pass to the underlying `slog.Handler`, but GoVisual cannot associate them with a request. -## Request Log Format +## Stored shape -Internally, GoVisual stores request logs with the following structure: +The core request record is `store.RequestLog`: ```go type RequestLog struct { - ID string // Unique identifier - Timestamp time.Time // When the request was received - Method string // HTTP method - Path string // URL path - Query string // Query parameters - RequestHeaders map[string][]string // Request headers - ResponseHeaders map[string][]string // Response headers - StatusCode int // HTTP status code - Duration time.Duration // Response time - RequestBody string // Request body (if enabled) - ResponseBody string // Response body (if enabled) - Error string // Error message (if any) - MiddlewareTrace []MiddlewareTraceEntry // Middleware execution trace - RouteTrace []RouteTraceEntry // Route matching trace + ID string + Timestamp time.Time + Method string + Host string + Path string + RawPath string // optional encoded path, such as /users/a%2Fb + Query string + RequestHeaders http.Header + ResponseHeaders http.Header + StatusCode int + Duration int64 // milliseconds + RequestBody string + ResponseBody string + Error string + MiddlewareTrace []map[string]interface{} + RouteTrace map[string]interface{} + PerformanceMetrics *PerformanceMetrics + Logs []LogEntry + PanicStack string } ``` -## Example +Durations inside `PerformanceMetrics`, SQL calls, outbound HTTP calls, and nested trace entries are Go `time.Duration` values and therefore encode as nanoseconds in JSON. `RequestLog.Duration`, replay-response duration, and the top-level `MiddlewareTrace` map duration encode as milliseconds; the latter remains in milliseconds for compatibility with persisted v2.0.0 records. -A complete example of request logging configuration: +## Storage behavior -```go -handler := govisual.Wrap( - mux, - govisual.WithRequestBodyLogging(true), - govisual.WithResponseBodyLogging(true), - govisual.WithIgnorePaths("/health", "/metrics", "/static/*"), - govisual.WithMaxRequests(1000), -) -``` +Without `WithStore`, records live in an in-memory ring bounded by `WithMaxRequests` (100 by default). PostgreSQL, Redis, MongoDB, and SQLite are separate modules and persist records according to their own configuration. See [Storage Backends](storage-backends.md). + +Storage failures do not fail the application request path. Monitor your selected backend separately if durable capture is required. -## Related Documentation +## Related documentation -- [Configuration Options](configuration.md) - All available configuration options -- [Storage Backends](storage-backends.md) - Configure where logs are stored -- [Middleware Tracing](middleware-tracing.md) - How middleware tracing works +- [Dashboard](dashboard.md) +- [Configuration options](configuration.md) +- [Storage backends](storage-backends.md) +- [Middleware tracing](middleware-tracing.md) diff --git a/internal/dashboard/handler.go b/internal/dashboard/handler.go index 7413712..7681c79 100644 --- a/internal/dashboard/handler.go +++ b/internal/dashboard/handler.go @@ -4,7 +4,6 @@ import ( "context" "embed" "encoding/json" - "errors" "fmt" "io" "io/fs" @@ -30,6 +29,13 @@ var staticFiles embed.FS type HandlerOptions struct { // EnableReplay opens POST /api/replay. EnableReplay bool + // ReplayBaseURL pins replay traffic to an application URL. When empty, a + // localhost-only handler may use its validated request scheme and Host. + ReplayBaseURL string + // AllowLocalhostReplay permits the request Host fallback, but only when it + // names localhost or a literal loopback IP. Remote dashboards must instead + // configure ReplayBaseURL explicitly. + AllowLocalhostReplay bool // ExposeSystemInfo opens GET /api/system-info. ExposeSystemInfo bool // ExposeEnvVars is the explicit allowlist of env var names the @@ -40,6 +46,15 @@ type HandlerOptions struct { ActivityLog *store.ActivityLog } +const captureTruncationMarker = "...[truncated by govisual]" + +const ( + maxReplayRequestBody = 1 << 20 + maxReplayPayload = 8 << 20 + maxReplayHeaders = 100 + maxReplayHeaderBytes = 64 << 10 +) + // Handler is the HTTP handler for the dashboard type Handler struct { store store.Store @@ -172,7 +187,6 @@ func (h *Handler) handleSSE(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") - w.Header().Set("Access-Control-Allow-Origin", "*") flusher, ok := w.(http.Flusher) if !ok { @@ -327,47 +341,85 @@ func (h *Handler) handleCompareRequests(w http.ResponseWriter, r *http.Request) encoder.Encode(compareRequests) } -// handleReplayRequest replays a captured HTTP request against an arbitrary -// destination. This is a powerful primitive and is therefore opt-in via -// HandlerOptions.EnableReplay. Even when enabled, we deny: -// - non-http(s) schemes (gopher://, file://, ftp://, etc.) -// - hostnames that resolve to loopback / link-local / private / multicast IPs -// -// to mitigate SSRF against cloud metadata services or internal networks. Any -// caller that needs to point replay at internal hosts is expected to manage -// network policy themselves; we will not undo the deny-by-default. +// handleReplayRequest loads a captured request by ID, applies shape-only +// overrides, and replays it against the application origin. The client cannot +// supply or alter the destination authority. func (h *Handler) handleReplayRequest(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } + r.Body = http.MaxBytesReader(w, r.Body, maxReplayPayload) decoder := json.NewDecoder(r.Body) var replayRequest struct { - RequestID string `json:"requestId"` - URL string `json:"url"` - Method string `json:"method"` - Headers map[string]string `json:"headers"` - Body string `json:"body"` + RequestID string `json:"requestId"` + // URL accepts the v2.0.0 dashboard payload for compatibility. Its + // authority is ignored; only its path and query can be replayed. + URL *string `json:"url,omitempty"` + Method *string `json:"method,omitempty"` + Path *string `json:"path,omitempty"` + Headers map[string]string `json:"headers"` + Body *string `json:"body,omitempty"` } if err := decoder.Decode(&replayRequest); err != nil { http.Error(w, "Invalid request format: "+err.Error(), http.StatusBadRequest) return } - if err := validateReplayTarget(replayRequest.URL); err != nil { - http.Error(w, "Replay target rejected: "+err.Error(), http.StatusForbidden) + if replayRequest.RequestID == "" { + http.Error(w, "Request ID is required", http.StatusBadRequest) + return + } + original, ok := h.store.Get(replayRequest.RequestID) + if !ok { + http.Error(w, "Request not found", http.StatusNotFound) return } - // Block redirects — a 30x to a private IP would defeat the pre-flight - // check. Use a custom DialContext that re-validates the resolved IP at - // dial time so DNS-rebinding can't slip past the pre-flight check (the - // pre-flight resolves and validates, but DefaultTransport would otherwise - // resolve again from the OS cache moments later). - transport := &http.Transport{ - DialContext: safeDialContext, + method := original.Method + if replayRequest.Method != nil && *replayRequest.Method != "" { + method = *replayRequest.Method + } + body := original.RequestBody + if strings.HasSuffix(original.RequestBody, captureTruncationMarker) && + (replayRequest.Body == nil || *replayRequest.Body == original.RequestBody) { + http.Error(w, "Captured request body is truncated; provide the complete body before replaying", http.StatusBadRequest) + return + } + if replayRequest.Body != nil { + body = *replayRequest.Body + } + if len(body) > maxReplayRequestBody { + http.Error(w, "Replay request body exceeds 1 MiB", http.StatusRequestEntityTooLarge) + return + } + pathOverride := replayRequest.Path + if pathOverride == nil && replayRequest.URL != nil { + legacyURL, err := url.Parse(*replayRequest.URL) + if err != nil || legacyURL == nil || (legacyURL.Scheme != "http" && legacyURL.Scheme != "https") || legacyURL.Host == "" || legacyURL.User != nil || legacyURL.Fragment != "" { + http.Error(w, "Invalid replay target: invalid legacy URL", http.StatusBadRequest) + return + } + legacyPath := legacyURL.EscapedPath() + if legacyPath == "" { + legacyPath = "/" + } + if legacyURL.RawQuery != "" { + legacyPath += "?" + legacyURL.RawQuery + } + pathOverride = &legacyPath } + target, err := h.replayTarget(r, original, pathOverride) + if err != nil { + http.Error(w, "Invalid replay target: "+err.Error(), http.StatusBadRequest) + return + } + + // Preserve captured Accept-Encoding semantics and exact response bytes; + // automatic decompression would otherwise silently change the replay. + transport := &http.Transport{Proxy: nil, DisableCompression: true} + defer transport.CloseIdleConnections() client := &http.Client{ Timeout: 30 * time.Second, Transport: transport, @@ -379,13 +431,23 @@ func (h *Handler) handleReplayRequest(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second) defer cancel() - req, err := http.NewRequestWithContext(ctx, replayRequest.Method, replayRequest.URL, strings.NewReader(replayRequest.Body)) + req, err := http.NewRequestWithContext(ctx, method, target, strings.NewReader(body)) if err != nil { - http.Error(w, "Error creating request: "+err.Error(), http.StatusInternalServerError) + http.Error(w, "Error creating request: "+err.Error(), http.StatusBadRequest) return } - for key, value := range replayRequest.Headers { - req.Header.Add(key, value) + if replayRequest.Headers == nil { + // An omitted header map is the legacy "replay unchanged" shape. + copyReplayHeaders(req.Header, original.RequestHeaders, nil) + } else { + // The dashboard sends the complete edited map, so an absent key means + // the user removed that captured header. + copyReplayHeaders(req.Header, nil, replayRequest.Headers) + } + req.Header.Set("X-Govisual-Replay", "1") + if err := validateReplayHeaders(req.Header); err != nil { + http.Error(w, "Invalid replay headers: "+err.Error(), http.StatusBadRequest) + return } startTime := time.Now() @@ -399,29 +461,33 @@ func (h *Handler) handleReplayRequest(w http.ResponseWriter, r *http.Request) { // Cap the captured response body so a hostile target can't OOM us. const maxReplayBody = 1 << 20 // 1 MiB - respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxReplayBody)) + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxReplayBody+1)) if err != nil { http.Error(w, "Error reading response body: "+err.Error(), http.StatusBadGateway) return } - - headers := make(map[string][]string, len(resp.Header)) - for k, v := range resp.Header { - headers[k] = v + bodyTruncated := len(respBody) > maxReplayBody + if bodyTruncated { + respBody = respBody[:maxReplayBody] } + headerLog := &store.RequestLog{} + headerLog.SetResponseHeaders(resp.Header) + replayResponse := struct { - StatusCode int `json:"statusCode"` - Headers map[string][]string `json:"headers"` - Body string `json:"body"` - Duration int64 `json:"duration"` - OriginalRequest string `json:"originalRequest"` + StatusCode int `json:"statusCode"` + Headers http.Header `json:"headers"` + Body string `json:"body"` + Duration int64 `json:"duration"` + OriginalRequest string `json:"originalRequest"` + BodyTruncated bool `json:"bodyTruncated,omitempty"` }{ StatusCode: resp.StatusCode, - Headers: headers, + Headers: headerLog.ResponseHeaders, Body: string(respBody), Duration: duration, OriginalRequest: replayRequest.RequestID, + BodyTruncated: bodyTruncated, } w.Header().Set("Content-Type", "application/json") @@ -433,78 +499,150 @@ func (h *Handler) handleReplayRequest(w http.ResponseWriter, r *http.Request) { } } -// validateReplayTarget rejects replay URLs that point at unsafe schemes or at -// IPs the caller almost certainly did not mean to expose: loopback, link-local, -// multicast, private ranges, and (critically on cloud) the IMDS address. -func validateReplayTarget(raw string) error { - u, err := url.Parse(raw) - if err != nil { - return fmt.Errorf("invalid url: %w", err) - } - scheme := strings.ToLower(u.Scheme) - if scheme != "http" && scheme != "https" { - return fmt.Errorf("scheme %q not allowed", u.Scheme) +func (h *Handler) replayTarget(r *http.Request, original *store.RequestLog, override *string) (string, error) { + baseRaw := h.opts.ReplayBaseURL + if baseRaw == "" { + if !h.opts.AllowLocalhostReplay || !isLocalReplayHost(r.Host) { + return "", fmt.Errorf("replay base URL is required unless the dashboard is localhost-only") + } + scheme := "http" + if r.TLS != nil { + scheme = "https" + } + baseRaw = scheme + "://" + r.Host } - host := u.Hostname() - if host == "" { - return errors.New("missing host") + base, err := url.Parse(baseRaw) + if err != nil || base == nil { + return "", fmt.Errorf("invalid replay base URL") } - ips, err := net.LookupIP(host) - if err != nil { - return fmt.Errorf("dns lookup failed: %w", err) + base.Scheme = strings.ToLower(base.Scheme) + if (base.Scheme != "http" && base.Scheme != "https") || base.Host == "" || base.User != nil || base.Opaque != "" || base.RawQuery != "" || base.ForceQuery || base.Fragment != "" { + return "", fmt.Errorf("invalid replay base URL") } - for _, ip := range ips { - if isInternalIP(ip) { - return fmt.Errorf("target resolves to non-public address %s", ip) + + requestPath := original.Path + requestRawPath := original.RawPath + rawQuery := original.Query + if override != nil { + relative, err := url.Parse(*override) + if err != nil || relative.IsAbs() || relative.Host != "" || relative.Fragment != "" || !strings.HasPrefix(relative.Path, "/") { + return "", fmt.Errorf("path must be an absolute path without a host") } + requestPath = relative.Path + requestRawPath = relative.RawPath + rawQuery = relative.RawQuery } - return nil + if requestPath == "" || !strings.HasPrefix(requestPath, "/") { + return "", fmt.Errorf("captured request has an invalid path") + } + + target := *base + target.Path = strings.TrimSuffix(base.Path, "/") + requestPath + if requestRawPath != "" { + target.RawPath = strings.TrimSuffix(base.EscapedPath(), "/") + requestRawPath + } else { + target.RawPath = "" + } + target.RawQuery = rawQuery + return target.String(), nil } -// isInternalIP reports whether ip is one we should refuse to dial from a -// replay endpoint. It normalizes IPv4-mapped IPv6 addresses (::ffff:a.b.c.d) -// to their IPv4 form so an attacker cannot bypass the check by encoding a -// private IPv4 address as IPv6. -func isInternalIP(ip net.IP) bool { - if ip4 := ip.To4(); ip4 != nil { - ip = ip4 +var fixedHopByHopHeaders = map[string]struct{}{ + "Connection": {}, + "Keep-Alive": {}, + "Proxy-Authenticate": {}, + "Proxy-Authorization": {}, + "Proxy-Connection": {}, + "Te": {}, + "Trailer": {}, + "Transfer-Encoding": {}, + "Upgrade": {}, + "Host": {}, + "Content-Length": {}, +} + +func copyReplayHeaders(dst http.Header, captured http.Header, overrides map[string]string) { + blocked := make(map[string]struct{}, len(fixedHopByHopHeaders)) + for name := range fixedHopByHopHeaders { + blocked[name] = struct{}{} } - if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || - ip.IsMulticast() || ip.IsUnspecified() || ip.IsPrivate() { - return true + for key, values := range captured { + if http.CanonicalHeaderKey(key) == "Connection" { + blockConnectionTokens(blocked, values...) + } } - // AWS / GCP / Azure IMDS endpoint. - if ip.Equal(net.IPv4(169, 254, 169, 254)) { - return true + for key, value := range overrides { + if http.CanonicalHeaderKey(key) == "Connection" { + blockConnectionTokens(blocked, value) + } + } + + for key, values := range captured { + canonical := http.CanonicalHeaderKey(key) + if _, skip := blocked[canonical]; skip || canonical == "" { + continue + } + for _, value := range values { + if value != "[redacted by govisual]" { + dst.Add(canonical, value) + } + } + } + for key, value := range overrides { + canonical := http.CanonicalHeaderKey(key) + if _, skip := blocked[canonical]; skip || canonical == "" { + continue + } + if value == "[redacted by govisual]" { + continue + } + dst.Set(canonical, value) } - return false } -// safeDialContext resolves the host and rejects the dial if any resolved -// address is private/loopback/IMDS. Crucially, the same resolution result is -// used for the actual connection — this closes the DNS-rebinding TOCTOU -// window between a pre-flight LookupIP and the transport's own resolution. -func safeDialContext(ctx context.Context, network, addr string) (net.Conn, error) { - host, port, err := net.SplitHostPort(addr) - if err != nil { - return nil, err +func isLocalReplayHost(authority string) bool { + u, err := url.Parse("http://" + authority) + if err != nil || u.User != nil || u.Host == "" || u.Path != "" || u.RawQuery != "" || u.Fragment != "" { + return false } - ips, err := net.DefaultResolver.LookupIPAddr(ctx, host) - if err != nil { - return nil, err + host := strings.TrimSuffix(strings.ToLower(u.Hostname()), ".") + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + ip = ip4 + } + return ip.IsLoopback() } - if len(ips) == 0 { - return nil, fmt.Errorf("no addresses for %s", host) + return host == "localhost" || strings.HasSuffix(host, ".localhost") +} + +func blockConnectionTokens(blocked map[string]struct{}, values ...string) { + for _, value := range values { + for _, token := range strings.Split(value, ",") { + if canonical := http.CanonicalHeaderKey(strings.TrimSpace(token)); canonical != "" { + blocked[canonical] = struct{}{} + } + } + } +} + +func validateReplayHeaders(headers http.Header) error { + if len(headers) > maxReplayHeaders { + return fmt.Errorf("too many headers (maximum %d)", maxReplayHeaders) } - for _, ip := range ips { - if isInternalIP(ip.IP) { - return nil, fmt.Errorf("dial rejected: %s resolves to non-public address %s", host, ip.IP) + remaining := maxReplayHeaderBytes + for key, values := range headers { + if len(key) > remaining { + return fmt.Errorf("headers exceed %d bytes", maxReplayHeaderBytes) + } + remaining -= len(key) + for _, value := range values { + if len(value) > remaining { + return fmt.Errorf("headers exceed %d bytes", maxReplayHeaderBytes) + } + remaining -= len(value) } } - dialer := &net.Dialer{Timeout: 10 * time.Second} - // Dial the first resolved address directly so the kernel does not perform - // a second lookup that could race with the validation above. - return dialer.DialContext(ctx, network, net.JoinHostPort(ips[0].IP.String(), port)) + return nil } func (h *Handler) handleMetrics(w http.ResponseWriter, r *http.Request) { diff --git a/internal/dashboard/handler_test.go b/internal/dashboard/handler_test.go index f1922d1..ff9c91c 100644 --- a/internal/dashboard/handler_test.go +++ b/internal/dashboard/handler_test.go @@ -2,6 +2,8 @@ package dashboard import ( "bufio" + "encoding/json" + "io" "net/http" "net/http/httptest" "strings" @@ -21,6 +23,9 @@ func TestSSEPushesOnAdd(t *testing.T) { t.Fatalf("connect SSE: %v", err) } defer resp.Body.Close() + if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "" { + t.Fatalf("SSE exposed wildcard CORS header %q", got) + } events := make(chan string, 16) go func() { @@ -54,3 +59,181 @@ func TestSSEPushesOnAdd(t *testing.T) { t.Fatal("append was not pushed; SSE still waiting on the ticker") } } + +func TestReplayUsesCapturedRequestAndPinnedDashboardOrigin(t *testing.T) { + st := store.NewMemory(10) + st.Add(&store.RequestLog{ + ID: "captured-1", + Method: http.MethodPost, + Path: "/original", + RawPath: "/orig%69nal", + Query: "from=capture", + RequestBody: "captured body", + RequestHeaders: http.Header{ + "X-Keep": []string{"captured"}, + "X-Remove": []string{"captured"}, + "Accept-Encoding": []string{"br"}, + "Authorization": []string{"[redacted by govisual]"}, + "Connection": []string{"X-Captured-Hop"}, + "X-Captured-Hop": []string{"remove me"}, + "Host": []string{"attacker.invalid"}, + "Content-Length": []string{"999"}, + }, + }) + + type received struct { + method string + path string + escapedPath string + query string + body string + header http.Header + host string + contentLength int64 + } + got := make(chan received, 3) + dashboardHandler := NewHandler(st, nil, HandlerOptions{EnableReplay: true, AllowLocalhostReplay: true}) + root := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/dashboard/") { + http.StripPrefix("/dashboard", dashboardHandler).ServeHTTP(w, r) + return + } + body, _ := io.ReadAll(r.Body) + got <- received{method: r.Method, path: r.URL.Path, escapedPath: r.URL.EscapedPath(), query: r.URL.RawQuery, body: string(body), header: r.Header.Clone(), host: r.Host, contentLength: r.ContentLength} + w.Header().Set("X-Replayed", "yes") + w.Header().Set("Set-Cookie", "session=secret") + w.WriteHeader(http.StatusAccepted) + w.Write([]byte("replayed")) + }) + srv := httptest.NewServer(root) + defer srv.Close() + + postReplay := func(payload map[string]any) received { + t.Helper() + body, err := json.Marshal(payload) + if err != nil { + t.Fatal(err) + } + resp, err := http.Post(srv.URL+"/dashboard/api/replay", "application/json", strings.NewReader(string(body))) + if err != nil { + t.Fatalf("replay: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + data, _ := io.ReadAll(resp.Body) + t.Fatalf("replay returned %d: %s", resp.StatusCode, data) + } + var result struct { + StatusCode int `json:"statusCode"` + Headers http.Header `json:"headers"` + } + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + t.Fatalf("decode replay response: %v", err) + } + if result.StatusCode != http.StatusAccepted { + t.Fatalf("replayed status = %d, want %d", result.StatusCode, http.StatusAccepted) + } + if got := result.Headers.Get("Set-Cookie"); got != "[redacted by govisual]" { + t.Fatalf("replay response Set-Cookie = %q, want redaction", got) + } + select { + case req := <-got: + return req + case <-time.After(time.Second): + t.Fatal("pinned application did not receive replay") + return received{} + } + } + + first := postReplay(map[string]any{ + "requestId": "captured-1", + "url": "http://attacker.invalid/stolen?legacy=1", + }) + if first.method != http.MethodPost || first.path != "/stolen" || first.query != "legacy=1" || first.body != "captured body" { + t.Fatalf("legacy URL shape not applied to pinned destination: %+v", first) + } + if first.host != strings.TrimPrefix(srv.URL, "http://") { + t.Fatalf("replay Host = %q, want dashboard host", first.host) + } + if first.header.Get("Authorization") != "" { + t.Fatalf("stored redacted authorization was forwarded: %v", first.header) + } + if first.header.Get("Accept-Encoding") != "br" { + t.Fatalf("end-to-end Accept-Encoding was not preserved: %v", first.header) + } + + second := postReplay(map[string]any{ + "requestId": "captured-1", + "method": http.MethodPut, + "path": "/changed?from=override", + "body": "", + "headers": map[string]string{ + "X-Keep": "override", + "Connection": "X-Override-Hop", + "X-Override-Hop": "remove me too", + "Host": "attacker.invalid", + "Content-Length": "1234", + "Authorization": "Bearer deliberate-override", + "X-Api-Key": "[redacted by govisual]", + }, + }) + if second.method != http.MethodPut || second.path != "/changed" || second.query != "from=override" || second.body != "" { + t.Fatalf("replay overrides not applied: %+v", second) + } + if second.header.Get("X-Keep") != "override" || second.header.Get("X-Govisual-Replay") != "1" { + t.Fatalf("safe headers missing: %v", second.header) + } + for _, name := range []string{"Connection", "X-Captured-Hop", "X-Override-Hop"} { + if value := second.header.Get(name); value != "" { + t.Fatalf("hop-by-hop header %s forwarded as %q", name, value) + } + } + if second.contentLength != 0 { + t.Fatalf("caller-controlled Content-Length was forwarded: got %d", second.contentLength) + } + if second.host != strings.TrimPrefix(srv.URL, "http://") { + t.Fatalf("Host override escaped pinned destination: %q", second.host) + } + if second.header.Get("Authorization") != "Bearer deliberate-override" { + t.Fatalf("explicit authorization override missing: %v", second.header) + } + if second.header.Get("X-Api-Key") != "" { + t.Fatalf("redaction placeholder override was forwarded: %v", second.header) + } + if second.header.Get("X-Remove") != "" { + t.Fatalf("header removed in the dashboard was still forwarded: %v", second.header) + } + + third := postReplay(map[string]any{"requestId": "captured-1"}) + if third.path != "/original" || third.escapedPath != "/orig%69nal" { + t.Fatalf("captured encoded path was not preserved: %+v", third) + } +} + +func TestReplayRequiresExistingRequestAndRelativePath(t *testing.T) { + st := store.NewMemory(10) + st.Add(&store.RequestLog{ID: "one", Method: http.MethodGet, Path: "/ok"}) + st.Add(&store.RequestLog{ID: "truncated", Method: http.MethodPost, Path: "/ok", RequestBody: "prefix" + captureTruncationMarker}) + h := NewHandler(st, nil, HandlerOptions{EnableReplay: true, ReplayBaseURL: "http://localhost:1"}) + + for _, tc := range []struct { + name string + payload string + want int + }{ + {name: "missing id", payload: `{}`, want: http.StatusBadRequest}, + {name: "unknown id", payload: `{"requestId":"missing"}`, want: http.StatusNotFound}, + {name: "absolute url path", payload: `{"requestId":"one","path":"http://attacker.invalid/x"}`, want: http.StatusBadRequest}, + {name: "authority path", payload: `{"requestId":"one","path":"//attacker.invalid/x"}`, want: http.StatusBadRequest}, + {name: "truncated body", payload: `{"requestId":"truncated"}`, want: http.StatusBadRequest}, + } { + t.Run(tc.name, func(t *testing.T) { + req := httptest.NewRequest(http.MethodPost, "/api/replay", strings.NewReader(tc.payload)) + rec := httptest.NewRecorder() + h.ServeHTTP(rec, req) + if rec.Code != tc.want { + t.Fatalf("got %d, want %d: %s", rec.Code, tc.want, rec.Body.String()) + } + }) + } +} diff --git a/internal/dashboard/static/dashboard.js b/internal/dashboard/static/dashboard.js index 63ca59b..91d10ba 100644 --- a/internal/dashboard/static/dashboard.js +++ b/internal/dashboard/static/dashboard.js @@ -1,14 +1,14 @@ -"use strict";(()=>{var ho=Object.defineProperty;var Il=(e,t,r)=>t in e?ho(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var Pl=(e,t)=>{for(var r in t)ho(e,r,{get:t[r],enumerable:!0})};var jt=(e,t,r)=>(Il(e,typeof t!="symbol"?t+"":t,r),r);var bt,z,vo,Ll,Me,go,yo,_o,Qr,Kt,gt,wo,rn,Jr,Zr,Ro,Qt={},Jt=[],Ol=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,vt=Array.isArray;function me(e,t){for(var r in t)e[r]=t[r];return e}function nn(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function g(e,t,r){var n,o,i,a={};for(i in t)i=="key"?n=t[i]:i=="ref"?o=t[i]:a[i]=t[i];if(arguments.length>2&&(a.children=arguments.length>3?bt.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(i in e.defaultProps)a[i]===void 0&&(a[i]=e.defaultProps[i]);return xt(e,a,n,o,null)}function xt(e,t,r,n,o){var i={type:e,props:t,key:r,ref:n,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++vo,__i:-1,__u:0};return o==null&&z.vnode!=null&&z.vnode(i),i}function er(){return{current:null}}function m(e){return e.children}function ue(e,t){this.props=e,this.context=t}function nt(e,t){if(t==null)return e.__?nt(e.__,e.__i+1):null;for(var r;tt&&Me.sort(_o),e=Me.shift(),t=Me.length,Dl(e)}finally{Me.length=Zt.__r=0}}function ko(e,t,r,n,o,i,a,l,u,f,d){var p,c,h,x,b,v,w,R=n&&n.__k||Jt,S=t.length;for(u=Fl(r,t,R,u,S),p=0;p0?a=e.__k[i]=xt(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):e.__k[i]=a,u=i+c,a.__=e,a.__b=e.__b+1,l=null,(f=a.__i=Hl(a,r,u,p))!=-1&&(p--,(l=r[f])&&(l.__u|=2)),l==null||l.__v==null?(f==-1&&(o>d?c--:ou?c--:c++,a.__u|=4))):e.__k[i]=null;if(p)for(i=0;i(d?1:0)){for(o=r-1,i=r+1;o>=0||i=0?o--:i++])!=null&&!(2&f.__u)&&l==f.key&&u==f.type)return a}return-1}function xo(e,t,r){t[0]=="-"?e.setProperty(t,r??""):e[t]=r==null?"":typeof r!="number"||Ol.test(t)?r:r+"px"}function Yt(e,t,r,n,o){var i,a;e:if(t=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof n=="string"&&(e.style.cssText=n=""),n)for(t in n)r&&t in r||xo(e.style,t,"");if(r)for(t in r)n&&r[t]==n[t]||xo(e.style,t,r[t])}else if(t[0]=="o"&&t[1]=="n")i=t!=(t=t.replace(wo,"$1")),a=t.toLowerCase(),t=a in e||t=="onFocusOut"||t=="onFocusIn"?a.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=r,r?n?r[gt]=n[gt]:(r[gt]=rn,e.addEventListener(t,i?Zr:Jr,i)):e.removeEventListener(t,i?Zr:Jr,i);else{if(o=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=r??"";break e}catch{}typeof r=="function"||(r==null||r===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&r==1?"":r))}}function bo(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t[Kt]==null)t[Kt]=rn++;else if(t[Kt]0?e:vt(e)?e.map(No):e.constructor!==void 0?null:me({},e)}function Bl(e,t,r,n,o,i,a,l,u){var f,d,p,c,h,x,b,v=r.props||Qt,w=t.props,R=t.type;if(R=="svg"?o="http://www.w3.org/2000/svg":R=="math"?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),i!=null){for(f=0;f2&&(l.children=arguments.length>3?bt.call(arguments,2):r),xt(e.type,l,n||e.key,o||e.ref,null)}function Re(e){function t(r){var n,o;return this.getChildContext||(n=new Set,(o={})[t.__c]=this,this.getChildContext=function(){return o},this.componentWillUnmount=function(){n=null},this.shouldComponentUpdate=function(i){this.props.value!=i.value&&n.forEach(function(a){a.__e=!0,en(a)})},this.sub=function(i){n.add(i);var a=i.componentWillUnmount;i.componentWillUnmount=function(){n&&n.delete(i),a&&a.call(i)}}),r.children}return t.__c="__cC"+Ro++,t.__=e,t.Provider=t.__l=(t.Consumer=function(r,n){return r.children(n)}).contextType=t,t}bt=Jt.slice,z={__e:function(e,t,r,n){for(var o,i,a;t=t.__;)if((o=t.__c)&&!o.__)try{if((i=o.constructor)&&i.getDerivedStateFromError!=null&&(o.setState(i.getDerivedStateFromError(e)),a=o.__d),o.componentDidCatch!=null&&(o.componentDidCatch(e,n||{}),a=o.__d),a)return o.__E=o}catch(l){e=l}throw e}},vo=0,Ll=function(e){return e!=null&&e.constructor===void 0},ue.prototype.setState=function(e,t){var r;r=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=me({},this.state),typeof e=="function"&&(e=e(me({},r),this.props)),e&&me(r,e),e!=null&&this.__v&&(t&&this._sb.push(t),en(this))},ue.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),en(this))},ue.prototype.render=m,Me=[],yo=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,_o=function(e,t){return e.__v.__b-t.__v.__b},Zt.__r=0,Qr=Math.random().toString(8),Kt="__d"+Qr,gt="__a"+Qr,wo=/(PointerCapture)$|Capture$/i,rn=0,Jr=bo(!1),Zr=bo(!0),Ro=0;var Ce,H,ln,Ao,ot=0,Bo=[],G=z,Mo=G.__b,Io=G.__r,Po=G.diffed,Lo=G.__c,Oo=G.unmount,Do=G.__;function Xe(e,t){G.__h&&G.__h(H,e,ot||t),ot=0;var r=H.__H||(H.__H={__:[],__h:[]});return e>=r.__.length&&r.__.push({}),r.__[e]}function N(e){return ot=1,Pe(qo,e)}function Pe(e,t,r){var n=Xe(Ce++,2);if(n.t=e,!n.__c&&(n.__=[r?r(t):qo(void 0,t),function(l){var u=n.__N?n.__N[0]:n.__[0],f=n.t(u,l);u!==f&&(n.__N=[f,n.__[1]],n.__c.setState({}))}],n.__c=H,!H.__f)){var o=function(l,u,f){if(!n.__c.__H)return!0;var d=!1,p=n.__c.props!==l;if(n.__c.__H.__.some(function(h){if(h.__N){d=!0;var x=h.__[0];h.__=h.__N,h.__N=void 0,x!==h.__[0]&&(p=!0)}}),i){var c=i.call(this,l,u,f);return d?c||p:c}return!d||p};H.__f=!0;var i=H.shouldComponentUpdate,a=H.componentWillUpdate;H.componentWillUpdate=function(l,u,f){if(this.__e){var d=i;i=void 0,o(l,u,f),i=d}a&&a.call(this,l,u,f)},H.shouldComponentUpdate=o}return n.__N||n.__}function I(e,t){var r=Xe(Ce++,3);!G.__s&&un(r.__H,t)&&(r.__=e,r.u=t,H.__H.__h.push(r))}function ke(e,t){var r=Xe(Ce++,4);!G.__s&&un(r.__H,t)&&(r.__=e,r.u=t,H.__h.push(r))}function F(e){return ot=5,q(function(){return{current:e}},[])}function tr(e,t,r){ot=6,ke(function(){if(typeof e=="function"){var n=e(t());return function(){e(null),n&&typeof n=="function"&&n()}}if(e)return e.current=t(),function(){return e.current=null}},r==null?r:r.concat(e))}function q(e,t){var r=Xe(Ce++,7);return un(r.__H,t)&&(r.__=e(),r.__H=t,r.__h=e),r.__}function X(e,t){return ot=8,q(function(){return e},t)}function Le(e){var t=H.context[e.__c],r=Xe(Ce++,9);return r.c=e,t?(r.__==null&&(r.__=!0,t.sub(H)),t.props.value):e.__}function rr(e,t){G.useDebugValue&&G.useDebugValue(t?t(e):e)}function ql(e){var t=Xe(Ce++,10),r=N();return t.__=e,H.componentDidCatch||(H.componentDidCatch=function(n,o){t.__&&t.__(n,o),r[1](n)}),[r[0],function(){r[1](void 0)}]}function nr(){var e=Xe(Ce++,11);if(!e.__){for(var t=H.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var r=t.__m||(t.__m=[0,0]);e.__="P"+r[0]+"-"+r[1]++}return e.__}function Fo(){for(var e;e=Bo.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(cn),t.__h.some($o),t.__h=[]}catch(r){t.__h=[],G.__e(r,e.__v)}}}G.__b=function(e){H=null,Mo&&Mo(e)},G.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Do&&Do(e,t)},G.__r=function(e){Io&&Io(e),Ce=0;var t=(H=e.__c).__H;t&&(ln===H?(t.__h=[],H.__h=[],t.__.some(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(t.__h.length&&Fo(),Ce=0)),ln=H},G.diffed=function(e){Po&&Po(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(Bo.push(t)!==1&&Ao===G.requestAnimationFrame||((Ao=G.requestAnimationFrame)||Gl)(Fo)),t.__H.__.some(function(r){r.u&&(r.__H=r.u,r.u=void 0)})),ln=H=null},G.__c=function(e,t){t.some(function(r){try{r.__h.some(cn),r.__h=r.__h.filter(function(n){return!n.__||$o(n)})}catch(n){t.some(function(o){o.__h&&(o.__h=[])}),t=[],G.__e(n,r.__v)}}),Lo&&Lo(e,t)},G.unmount=function(e){Oo&&Oo(e);var t,r=e.__c;r&&r.__H&&(r.__H.__.some(function(n){try{cn(n)}catch(o){t=o}}),r.__H=void 0,t&&G.__e(t,r.__v))};var Ho=typeof requestAnimationFrame=="function";function Gl(e){var t,r=function(){clearTimeout(n),Ho&&cancelAnimationFrame(t),setTimeout(e)},n=setTimeout(r,35);Ho&&(t=requestAnimationFrame(r))}function cn(e){var t=H,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),H=t}function $o(e){var t=H;e.__c=e.__(),H=t}function un(e,t){return!e||e.length!==t.length||t.some(function(r,n){return r!==e[n]})}function qo(e,t){return typeof t=="function"?t(e):t}var ge=class extends Error{constructor(r,n,o){super(o||n||`request failed (${r})`);jt(this,"status");jt(this,"body");this.status=r,this.body=n}get isNotFound(){return this.status===404}get isUnauthorized(){return this.status===401||this.status===403}};async function Se(e,t){let r=await fetch(e,t);if(!r.ok){let o=await r.text().catch(()=>"");throw new ge(r.status,o)}if((r.headers.get("content-type")||"").includes("application/json"))return r.json()}var fn=class{constructor(){jt(this,"baseURL",window.location.pathname.replace(/\/$/,"")+"/api")}getRequests(t){return Se(`${this.baseURL}/requests`,{signal:t})}async clearRequests(){await Se(`${this.baseURL}/clear`,{method:"POST"})}compareRequests(t,r){let n=t.map(o=>`id=${encodeURIComponent(o)}`).join("&");return Se(`${this.baseURL}/compare?${n}`,{signal:r})}replayRequest(t){return Se(`${this.baseURL}/replay`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}getMetrics(t,r){return Se(`${this.baseURL}/metrics?id=${encodeURIComponent(t)}`,{signal:r})}getFlameGraph(t,r){return Se(`${this.baseURL}/flamegraph?id=${encodeURIComponent(t)}`,{signal:r})}getBottlenecks(t){return Se(`${this.baseURL}/bottlenecks`,{signal:t})}getSystemInfo(t){return Se(`${this.baseURL}/system-info`,{signal:t})}getAgentActivity(t){return Se(`${this.baseURL}/agent-activity`,{signal:t})}subscribeToEvents(t,r){let n=new EventSource(`${this.baseURL}/events`),o=i=>a=>{try{let l=JSON.parse(a.data);t({kind:i,data:l})}catch(l){console.error(`Failed to parse ${i} event:`,l)}};return n.addEventListener("snapshot",o("snapshot")),n.addEventListener("append",o("append")),r&&(n.onerror=r),n}exportRequests(t){return JSON.stringify(t,null,2)}importRequests(t){let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid format: expected an array of requests");return r}},te=new fn;function Go(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var o=e.length;for(t=0;t{let r=new Array(e.length+t.length);for(let n=0;n({classGroupId:e,validator:t}),Ko=(e=new Map,t=null,r)=>({nextPart:e,validators:t,classGroupId:r}),ar="-",Vo=[],Wl="arbitrary..",Xl=e=>{let t=Yl(e),{conflictingClassGroups:r,conflictingClassGroupModifiers:n}=e;return{getClassGroupId:a=>{if(a.startsWith("[")&&a.endsWith("]"))return jl(a);let l=a.split(ar),u=l[0]===""&&l.length>1?1:0;return Qo(l,u,t)},getConflictingClassGroupIds:(a,l)=>{if(l){let u=n[a],f=r[a];return u?f?Vl(f,u):u:f||Vo}return r[a]||Vo}}},Qo=(e,t,r)=>{if(e.length-t===0)return r.classGroupId;let o=e[t],i=r.nextPart.get(o);if(i){let f=Qo(e,t+1,i);if(f)return f}let a=r.validators;if(a===null)return;let l=t===0?e.join(ar):e.slice(t).join(ar),u=a.length;for(let f=0;fe.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let t=e.slice(1,-1),r=t.indexOf(":"),n=t.slice(0,r);return n?Wl+n:void 0})(),Yl=e=>{let{theme:t,classGroups:r}=e;return Kl(r,t)},Kl=(e,t)=>{let r=Ko();for(let n in e){let o=e[n];mn(o,r,n,t)}return r},mn=(e,t,r,n)=>{let o=e.length;for(let i=0;i{if(typeof e=="string"){Jl(e,t,r);return}if(typeof e=="function"){Zl(e,t,r,n);return}ec(e,t,r,n)},Jl=(e,t,r)=>{let n=e===""?t:Jo(t,e);n.classGroupId=r},Zl=(e,t,r,n)=>{if(tc(e)){mn(e(n),t,r,n);return}t.validators===null&&(t.validators=[]),t.validators.push(Ul(r,e))},ec=(e,t,r,n)=>{let o=Object.entries(e),i=o.length;for(let a=0;a{let r=e,n=t.split(ar),o=n.length;for(let i=0;i"isThemeGetter"in e&&e.isThemeGetter===!0,rc=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,r=Object.create(null),n=Object.create(null),o=(i,a)=>{r[i]=a,t++,t>e&&(t=0,n=r,r=Object.create(null))};return{get(i){let a=r[i];if(a!==void 0)return a;if((a=n[i])!==void 0)return o(i,a),a},set(i,a){i in r?r[i]=a:o(i,a)}}},pn="!",Uo=":",nc=[],Wo=(e,t,r,n,o)=>({modifiers:e,hasImportantModifier:t,baseClassName:r,maybePostfixModifierPosition:n,isExternal:o}),oc=e=>{let{prefix:t,experimentalParseClassName:r}=e,n=o=>{let i=[],a=0,l=0,u=0,f,d=o.length;for(let b=0;bu?f-u:void 0;return Wo(i,h,c,x)};if(t){let o=t+Uo,i=n;n=a=>a.startsWith(o)?i(a.slice(o.length)):Wo(nc,!1,a,void 0,!0)}if(r){let o=n;n=i=>r({className:i,parseClassName:o})}return n},sc=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((r,n)=>{t.set(r,1e6+n)}),r=>{let n=[],o=[];for(let i=0;i0&&(o.sort(),n.push(...o),o=[]),n.push(a)):o.push(a)}return o.length>0&&(o.sort(),n.push(...o)),n}},ic=e=>({cache:rc(e.cacheSize),parseClassName:oc(e),sortModifiers:sc(e),postfixLookupClassGroupIds:ac(e),...Xl(e)}),ac=e=>{let t=Object.create(null),r=e.postfixLookupClassGroups;if(r)for(let n=0;n{let{parseClassName:r,getClassGroupId:n,getConflictingClassGroupIds:o,sortModifiers:i,postfixLookupClassGroupIds:a}=t,l=[],u=e.trim().split(lc),f="";for(let d=u.length-1;d>=0;d-=1){let p=u[d],{isExternal:c,modifiers:h,hasImportantModifier:x,baseClassName:b,maybePostfixModifierPosition:v}=r(p);if(c){f=p+(f.length>0?" "+f:f);continue}let w=!!v,R;if(w){let D=b.substring(0,v);R=n(D);let _=R&&a[R]?n(b):void 0;_&&_!==R&&(R=_,w=!1)}else R=n(b);if(!R){if(!w){f=p+(f.length>0?" "+f:f);continue}if(R=n(b),!R){f=p+(f.length>0?" "+f:f);continue}w=!1}let S=h.length===0?"":h.length===1?h[0]:i(h).join(":"),P=x?S+pn:S,y=P+R;if(l.indexOf(y)>-1)continue;l.push(y);let L=o(R,w);for(let D=0;D0?" "+f:f)}return f},uc=(...e)=>{let t=0,r,n,o="";for(;t{if(typeof e=="string")return e;let t,r="";for(let n=0;n{let r,n,o,i,a=u=>{let f=t.reduce((d,p)=>p(d),e());return r=ic(f),n=r.cache.get,o=r.cache.set,i=l,l(u)},l=u=>{let f=n(u);if(f)return f;let d=cc(u,r);return o(u,d),d};return i=a,(...u)=>i(uc(...u))},dc=[],Y=e=>{let t=r=>r[e]||dc;return t.isThemeGetter=!0,t},es=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,ts=/^\((?:(\w[\w-]*):)?(.+)\)$/i,pc=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,mc=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,hc=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,gc=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,xc=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,bc=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Oe=e=>pc.test(e),O=e=>!!e&&!Number.isNaN(Number(e)),xe=e=>!!e&&Number.isInteger(Number(e)),dn=e=>e.endsWith("%")&&O(e.slice(0,-1)),Te=e=>mc.test(e),rs=()=>!0,vc=e=>hc.test(e)&&!gc.test(e),hn=()=>!1,yc=e=>xc.test(e),_c=e=>bc.test(e),wc=e=>!C(e)&&!k(e),Rc=e=>e.startsWith("@container")&&(e[10]==="/"&&e[11]!==void 0||e[11]==="s"&&e[16]!==void 0&&e.startsWith("-size/",10)||e[11]==="n"&&e[18]!==void 0&&e.startsWith("-normal/",10)),Cc=e=>De(e,ss,hn),C=e=>es.test(e),je=e=>De(e,is,vc),Xo=e=>De(e,Mc,O),kc=e=>De(e,ls,rs),Sc=e=>De(e,as,hn),jo=e=>De(e,ns,hn),Tc=e=>De(e,os,_c),sr=e=>De(e,cs,yc),k=e=>ts.test(e),yt=e=>Ye(e,is),Nc=e=>Ye(e,as),Yo=e=>Ye(e,ns),Ec=e=>Ye(e,ss),zc=e=>Ye(e,os),ir=e=>Ye(e,cs,!0),Ac=e=>Ye(e,ls,!0),De=(e,t,r)=>{let n=es.exec(e);return n?n[1]?t(n[1]):r(n[2]):!1},Ye=(e,t,r=!1)=>{let n=ts.exec(e);return n?n[1]?t(n[1]):r:!1},ns=e=>e==="position"||e==="percentage",os=e=>e==="image"||e==="url",ss=e=>e==="length"||e==="size"||e==="bg-size",is=e=>e==="length",Mc=e=>e==="number",as=e=>e==="family-name",ls=e=>e==="number"||e==="weight",cs=e=>e==="shadow";var Ic=()=>{let e=Y("color"),t=Y("font"),r=Y("text"),n=Y("font-weight"),o=Y("tracking"),i=Y("leading"),a=Y("breakpoint"),l=Y("container"),u=Y("spacing"),f=Y("radius"),d=Y("shadow"),p=Y("inset-shadow"),c=Y("text-shadow"),h=Y("drop-shadow"),x=Y("blur"),b=Y("perspective"),v=Y("aspect"),w=Y("ease"),R=Y("animate"),S=()=>["auto","avoid","all","avoid-page","page","left","right","column"],P=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],y=()=>[...P(),k,C],L=()=>["auto","hidden","clip","visible","scroll"],D=()=>["auto","contain","none"],_=()=>[k,C,u],W=()=>[Oe,"full","auto",..._()],re=()=>[xe,"none","subgrid",k,C],M=()=>["auto",{span:["full",xe,k,C]},xe,k,C],V=()=>[xe,"auto",k,C],$=()=>["auto","min","max","fr",k,C],Ae=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],ce=()=>["start","end","center","stretch","center-safe","end-safe"],j=()=>["auto",..._()],We=()=>[Oe,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",..._()],Xr=()=>[Oe,"screen","full","dvw","lvw","svw","min","max","fit",..._()],jr=()=>[Oe,"screen","full","lh","dvh","lvh","svh","min","max","fit",..._()],E=()=>[e,k,C],co=()=>[...P(),Yo,jo,{position:[k,C]}],uo=()=>["no-repeat",{repeat:["","x","y","space","round"]}],fo=()=>["auto","cover","contain",Ec,Cc,{size:[k,C]}],Yr=()=>[dn,yt,je],se=()=>["","none","full",f,k,C],ie=()=>["",O,yt,je],Vt=()=>["solid","dashed","dotted","double"],po=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],ee=()=>[O,dn,Yo,jo],mo=()=>["","none",x,k,C],Ut=()=>["none",O,k,C],Wt=()=>["none",O,k,C],Kr=()=>[O,k,C],Xt=()=>[Oe,"full",..._()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Te],breakpoint:[Te],color:[rs],container:[Te],"drop-shadow":[Te],ease:["in","out","in-out"],font:[wc],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Te],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Te],shadow:[Te],spacing:["px",O],text:[Te],"text-shadow":[Te],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",Oe,C,k,v]}],container:["container"],"container-type":[{"@container":["","normal","size",k,C]}],"container-named":[Rc],columns:[{columns:[O,C,k,l]}],"break-after":[{"break-after":S()}],"break-before":[{"break-before":S()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:y()}],overflow:[{overflow:L()}],"overflow-x":[{"overflow-x":L()}],"overflow-y":[{"overflow-y":L()}],overscroll:[{overscroll:D()}],"overscroll-x":[{"overscroll-x":D()}],"overscroll-y":[{"overscroll-y":D()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:W()}],"inset-x":[{"inset-x":W()}],"inset-y":[{"inset-y":W()}],start:[{"inset-s":W(),start:W()}],end:[{"inset-e":W(),end:W()}],"inset-bs":[{"inset-bs":W()}],"inset-be":[{"inset-be":W()}],top:[{top:W()}],right:[{right:W()}],bottom:[{bottom:W()}],left:[{left:W()}],visibility:["visible","invisible","collapse"],z:[{z:[xe,"auto",k,C]}],basis:[{basis:[Oe,"full","auto",l,..._()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[O,Oe,"auto","initial","none",C]}],grow:[{grow:["",O,k,C]}],shrink:[{shrink:["",O,k,C]}],order:[{order:[xe,"first","last","none",k,C]}],"grid-cols":[{"grid-cols":re()}],"col-start-end":[{col:M()}],"col-start":[{"col-start":V()}],"col-end":[{"col-end":V()}],"grid-rows":[{"grid-rows":re()}],"row-start-end":[{row:M()}],"row-start":[{"row-start":V()}],"row-end":[{"row-end":V()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":$()}],"auto-rows":[{"auto-rows":$()}],gap:[{gap:_()}],"gap-x":[{"gap-x":_()}],"gap-y":[{"gap-y":_()}],"justify-content":[{justify:[...Ae(),"normal"]}],"justify-items":[{"justify-items":[...ce(),"normal"]}],"justify-self":[{"justify-self":["auto",...ce()]}],"align-content":[{content:["normal",...Ae()]}],"align-items":[{items:[...ce(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...ce(),{baseline:["","last"]}]}],"place-content":[{"place-content":Ae()}],"place-items":[{"place-items":[...ce(),"baseline"]}],"place-self":[{"place-self":["auto",...ce()]}],p:[{p:_()}],px:[{px:_()}],py:[{py:_()}],ps:[{ps:_()}],pe:[{pe:_()}],pbs:[{pbs:_()}],pbe:[{pbe:_()}],pt:[{pt:_()}],pr:[{pr:_()}],pb:[{pb:_()}],pl:[{pl:_()}],m:[{m:j()}],mx:[{mx:j()}],my:[{my:j()}],ms:[{ms:j()}],me:[{me:j()}],mbs:[{mbs:j()}],mbe:[{mbe:j()}],mt:[{mt:j()}],mr:[{mr:j()}],mb:[{mb:j()}],ml:[{ml:j()}],"space-x":[{"space-x":_()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":_()}],"space-y-reverse":["space-y-reverse"],size:[{size:We()}],"inline-size":[{inline:["auto",...Xr()]}],"min-inline-size":[{"min-inline":["auto",...Xr()]}],"max-inline-size":[{"max-inline":["none",...Xr()]}],"block-size":[{block:["auto",...jr()]}],"min-block-size":[{"min-block":["auto",...jr()]}],"max-block-size":[{"max-block":["none",...jr()]}],w:[{w:[l,"screen",...We()]}],"min-w":[{"min-w":[l,"screen","none",...We()]}],"max-w":[{"max-w":[l,"screen","none","prose",{screen:[a]},...We()]}],h:[{h:["screen","lh",...We()]}],"min-h":[{"min-h":["screen","lh","none",...We()]}],"max-h":[{"max-h":["screen","lh",...We()]}],"font-size":[{text:["base",r,yt,je]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[n,Ac,kc]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",dn,C]}],"font-family":[{font:[Nc,Sc,t]}],"font-features":[{"font-features":[C]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[o,k,C]}],"line-clamp":[{"line-clamp":[O,"none",k,Xo]}],leading:[{leading:[i,..._()]}],"list-image":[{"list-image":["none",k,C]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",k,C]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:E()}],"text-color":[{text:E()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...Vt(),"wavy"]}],"text-decoration-thickness":[{decoration:[O,"from-font","auto",k,je]}],"text-decoration-color":[{decoration:E()}],"underline-offset":[{"underline-offset":[O,"auto",k,C]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:_()}],"tab-size":[{tab:[xe,k,C]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",k,C]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",k,C]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:co()}],"bg-repeat":[{bg:uo()}],"bg-size":[{bg:fo()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},xe,k,C],radial:["",k,C],conic:[xe,k,C]},zc,Tc]}],"bg-color":[{bg:E()}],"gradient-from-pos":[{from:Yr()}],"gradient-via-pos":[{via:Yr()}],"gradient-to-pos":[{to:Yr()}],"gradient-from":[{from:E()}],"gradient-via":[{via:E()}],"gradient-to":[{to:E()}],rounded:[{rounded:se()}],"rounded-s":[{"rounded-s":se()}],"rounded-e":[{"rounded-e":se()}],"rounded-t":[{"rounded-t":se()}],"rounded-r":[{"rounded-r":se()}],"rounded-b":[{"rounded-b":se()}],"rounded-l":[{"rounded-l":se()}],"rounded-ss":[{"rounded-ss":se()}],"rounded-se":[{"rounded-se":se()}],"rounded-ee":[{"rounded-ee":se()}],"rounded-es":[{"rounded-es":se()}],"rounded-tl":[{"rounded-tl":se()}],"rounded-tr":[{"rounded-tr":se()}],"rounded-br":[{"rounded-br":se()}],"rounded-bl":[{"rounded-bl":se()}],"border-w":[{border:ie()}],"border-w-x":[{"border-x":ie()}],"border-w-y":[{"border-y":ie()}],"border-w-s":[{"border-s":ie()}],"border-w-e":[{"border-e":ie()}],"border-w-bs":[{"border-bs":ie()}],"border-w-be":[{"border-be":ie()}],"border-w-t":[{"border-t":ie()}],"border-w-r":[{"border-r":ie()}],"border-w-b":[{"border-b":ie()}],"border-w-l":[{"border-l":ie()}],"divide-x":[{"divide-x":ie()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":ie()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...Vt(),"hidden","none"]}],"divide-style":[{divide:[...Vt(),"hidden","none"]}],"border-color":[{border:E()}],"border-color-x":[{"border-x":E()}],"border-color-y":[{"border-y":E()}],"border-color-s":[{"border-s":E()}],"border-color-e":[{"border-e":E()}],"border-color-bs":[{"border-bs":E()}],"border-color-be":[{"border-be":E()}],"border-color-t":[{"border-t":E()}],"border-color-r":[{"border-r":E()}],"border-color-b":[{"border-b":E()}],"border-color-l":[{"border-l":E()}],"divide-color":[{divide:E()}],"outline-style":[{outline:[...Vt(),"none","hidden"]}],"outline-offset":[{"outline-offset":[O,k,C]}],"outline-w":[{outline:["",O,yt,je]}],"outline-color":[{outline:E()}],shadow:[{shadow:["","none",d,ir,sr]}],"shadow-color":[{shadow:E()}],"inset-shadow":[{"inset-shadow":["none",p,ir,sr]}],"inset-shadow-color":[{"inset-shadow":E()}],"ring-w":[{ring:ie()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:E()}],"ring-offset-w":[{"ring-offset":[O,je]}],"ring-offset-color":[{"ring-offset":E()}],"inset-ring-w":[{"inset-ring":ie()}],"inset-ring-color":[{"inset-ring":E()}],"text-shadow":[{"text-shadow":["none",c,ir,sr]}],"text-shadow-color":[{"text-shadow":E()}],opacity:[{opacity:[O,k,C]}],"mix-blend":[{"mix-blend":[...po(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":po()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[O]}],"mask-image-linear-from-pos":[{"mask-linear-from":ee()}],"mask-image-linear-to-pos":[{"mask-linear-to":ee()}],"mask-image-linear-from-color":[{"mask-linear-from":E()}],"mask-image-linear-to-color":[{"mask-linear-to":E()}],"mask-image-t-from-pos":[{"mask-t-from":ee()}],"mask-image-t-to-pos":[{"mask-t-to":ee()}],"mask-image-t-from-color":[{"mask-t-from":E()}],"mask-image-t-to-color":[{"mask-t-to":E()}],"mask-image-r-from-pos":[{"mask-r-from":ee()}],"mask-image-r-to-pos":[{"mask-r-to":ee()}],"mask-image-r-from-color":[{"mask-r-from":E()}],"mask-image-r-to-color":[{"mask-r-to":E()}],"mask-image-b-from-pos":[{"mask-b-from":ee()}],"mask-image-b-to-pos":[{"mask-b-to":ee()}],"mask-image-b-from-color":[{"mask-b-from":E()}],"mask-image-b-to-color":[{"mask-b-to":E()}],"mask-image-l-from-pos":[{"mask-l-from":ee()}],"mask-image-l-to-pos":[{"mask-l-to":ee()}],"mask-image-l-from-color":[{"mask-l-from":E()}],"mask-image-l-to-color":[{"mask-l-to":E()}],"mask-image-x-from-pos":[{"mask-x-from":ee()}],"mask-image-x-to-pos":[{"mask-x-to":ee()}],"mask-image-x-from-color":[{"mask-x-from":E()}],"mask-image-x-to-color":[{"mask-x-to":E()}],"mask-image-y-from-pos":[{"mask-y-from":ee()}],"mask-image-y-to-pos":[{"mask-y-to":ee()}],"mask-image-y-from-color":[{"mask-y-from":E()}],"mask-image-y-to-color":[{"mask-y-to":E()}],"mask-image-radial":[{"mask-radial":[k,C]}],"mask-image-radial-from-pos":[{"mask-radial-from":ee()}],"mask-image-radial-to-pos":[{"mask-radial-to":ee()}],"mask-image-radial-from-color":[{"mask-radial-from":E()}],"mask-image-radial-to-color":[{"mask-radial-to":E()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":P()}],"mask-image-conic-pos":[{"mask-conic":[O]}],"mask-image-conic-from-pos":[{"mask-conic-from":ee()}],"mask-image-conic-to-pos":[{"mask-conic-to":ee()}],"mask-image-conic-from-color":[{"mask-conic-from":E()}],"mask-image-conic-to-color":[{"mask-conic-to":E()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:co()}],"mask-repeat":[{mask:uo()}],"mask-size":[{mask:fo()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",k,C]}],filter:[{filter:["","none",k,C]}],blur:[{blur:mo()}],brightness:[{brightness:[O,k,C]}],contrast:[{contrast:[O,k,C]}],"drop-shadow":[{"drop-shadow":["","none",h,ir,sr]}],"drop-shadow-color":[{"drop-shadow":E()}],grayscale:[{grayscale:["",O,k,C]}],"hue-rotate":[{"hue-rotate":[O,k,C]}],invert:[{invert:["",O,k,C]}],saturate:[{saturate:[O,k,C]}],sepia:[{sepia:["",O,k,C]}],"backdrop-filter":[{"backdrop-filter":["","none",k,C]}],"backdrop-blur":[{"backdrop-blur":mo()}],"backdrop-brightness":[{"backdrop-brightness":[O,k,C]}],"backdrop-contrast":[{"backdrop-contrast":[O,k,C]}],"backdrop-grayscale":[{"backdrop-grayscale":["",O,k,C]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[O,k,C]}],"backdrop-invert":[{"backdrop-invert":["",O,k,C]}],"backdrop-opacity":[{"backdrop-opacity":[O,k,C]}],"backdrop-saturate":[{"backdrop-saturate":[O,k,C]}],"backdrop-sepia":[{"backdrop-sepia":["",O,k,C]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":_()}],"border-spacing-x":[{"border-spacing-x":_()}],"border-spacing-y":[{"border-spacing-y":_()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",k,C]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[O,"initial",k,C]}],ease:[{ease:["linear","initial",w,k,C]}],delay:[{delay:[O,k,C]}],animate:[{animate:["none",R,k,C]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[b,k,C]}],"perspective-origin":[{"perspective-origin":y()}],rotate:[{rotate:Ut()}],"rotate-x":[{"rotate-x":Ut()}],"rotate-y":[{"rotate-y":Ut()}],"rotate-z":[{"rotate-z":Ut()}],scale:[{scale:Wt()}],"scale-x":[{"scale-x":Wt()}],"scale-y":[{"scale-y":Wt()}],"scale-z":[{"scale-z":Wt()}],"scale-3d":["scale-3d"],skew:[{skew:Kr()}],"skew-x":[{"skew-x":Kr()}],"skew-y":[{"skew-y":Kr()}],transform:[{transform:[k,C,"","none","gpu","cpu"]}],"transform-origin":[{origin:y()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:Xt()}],"translate-x":[{"translate-x":Xt()}],"translate-y":[{"translate-y":Xt()}],"translate-z":[{"translate-z":Xt()}],"translate-none":["translate-none"],zoom:[{zoom:[xe,k,C]}],accent:[{accent:E()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:E()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",k,C]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":E()}],"scrollbar-track-color":[{"scrollbar-track":E()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":_()}],"scroll-mx":[{"scroll-mx":_()}],"scroll-my":[{"scroll-my":_()}],"scroll-ms":[{"scroll-ms":_()}],"scroll-me":[{"scroll-me":_()}],"scroll-mbs":[{"scroll-mbs":_()}],"scroll-mbe":[{"scroll-mbe":_()}],"scroll-mt":[{"scroll-mt":_()}],"scroll-mr":[{"scroll-mr":_()}],"scroll-mb":[{"scroll-mb":_()}],"scroll-ml":[{"scroll-ml":_()}],"scroll-p":[{"scroll-p":_()}],"scroll-px":[{"scroll-px":_()}],"scroll-py":[{"scroll-py":_()}],"scroll-ps":[{"scroll-ps":_()}],"scroll-pe":[{"scroll-pe":_()}],"scroll-pbs":[{"scroll-pbs":_()}],"scroll-pbe":[{"scroll-pbe":_()}],"scroll-pt":[{"scroll-pt":_()}],"scroll-pr":[{"scroll-pr":_()}],"scroll-pb":[{"scroll-pb":_()}],"scroll-pl":[{"scroll-pl":_()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",k,C]}],fill:[{fill:["none",...E()]}],"stroke-w":[{stroke:[O,yt,je,Xo]}],stroke:[{stroke:["none",...E()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}};var us=fc(Ic);function T(...e){return us(or(e))}var fs="govisual:theme";function Pc(){try{let e=localStorage.getItem(fs);if(e==="light"||e==="dark")return e}catch{}return window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}function Lc(e){document.documentElement.classList.toggle("dark",e==="dark")}function ds(){let[e,t]=N(Pc);I(()=>{Lc(e);try{localStorage.setItem(fs,e)}catch{}},[e]);let r=X(()=>{t(n=>n==="dark"?"light":"dark")},[]);return[e,r]}var Oc=0,im=Array.isArray;function s(e,t,r,n,o,i){t||(t={});var a,l,u=t;if("ref"in u)for(l in u={},t)l=="ref"?a=t[l]:u[l]=t[l];var f={type:e,props:u,key:r,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Oc,__i:-1,__u:0,__source:o,__self:i};if(typeof e=="function"&&(a=e.defaultProps))for(l in a)u[l]===void 0&&(u[l]=a[l]);return z.vnode&&z.vnode(f),f}var Dc=[{id:"inbox",label:"Inbox",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("path",{d:"M22 12h-6l-2 3h-4l-2-3H2"}),s("path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"})]})},{id:"errors",label:"Errors",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"10"}),s("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),s("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]})},{id:"slow",label:"Slow",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"10"}),s("polyline",{points:"12 6 12 12 16 14"})]})},{id:"analytics",label:"Analytics",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("line",{x1:"18",y1:"20",x2:"18",y2:"10"}),s("line",{x1:"12",y1:"20",x2:"12",y2:"4"}),s("line",{x1:"6",y1:"20",x2:"6",y2:"14"})]})},{id:"agents",label:"Agents",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("path",{d:"M12 8V4H8"}),s("rect",{x:"4",y:"8",width:"16",height:"12",rx:"2"}),s("path",{d:"M2 14h2M20 14h2M15 13v2M9 13v2"})]})},{id:"environment",label:"Environment",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),s("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),s("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]})}];function ps({active:e,onChange:t,errorCount:r=0}){let[n,o]=ds();return s("aside",{class:"w-14 border-r border-zinc-200 bg-white flex flex-col items-center py-3 gap-1 shrink-0",children:[s("a",{href:"https://github.com/doganarif/GoVisual",target:"_blank",rel:"noopener noreferrer",title:"GoVisual on GitHub",class:"w-8 h-8 rounded bg-zinc-900 text-white flex items-center justify-center text-sm font-bold mb-4",children:"G"}),Dc.map(i=>{let a=e===i.id;return s("button",{onClick:()=>t(i.id),title:i.label,class:T("w-9 h-9 rounded-md flex items-center justify-center relative",a?"bg-zinc-100 text-zinc-900":"text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"),children:[i.icon,i.id==="errors"&&r>0&&s("span",{class:"absolute -top-0.5 -right-0.5 min-w-[16px] h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-medium flex items-center justify-center",children:r>99?"99+":r})]},i.id)}),s("div",{class:"flex-1"}),s("button",{onClick:o,title:n==="dark"?"Switch to light theme":"Switch to dark theme",class:"w-9 h-9 rounded-md hover:bg-zinc-100 flex items-center justify-center text-zinc-500",children:n==="dark"?s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"5"}),s("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),s("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),s("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),s("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),s("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),s("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),s("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),s("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})]}):s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:s("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})})}),s("a",{href:"https://github.com/doganarif/GoVisual",target:"_blank",rel:"noopener noreferrer",title:"View source",class:"w-9 h-9 rounded-md hover:bg-zinc-100 flex items-center justify-center text-zinc-500",children:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"currentColor",children:s("path",{d:"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.387.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"})})})]})}var Fc={GET:"text-blue-700",POST:"text-emerald-700",PUT:"text-amber-700",PATCH:"text-amber-700",DELETE:"text-red-700",HEAD:"text-zinc-500",OPTIONS:"text-zinc-500"},Hc=e=>e>=200&&e<300?"bg-emerald-50 text-emerald-700":e>=300&&e<400?"bg-amber-50 text-amber-700":e>=400&&e<500?"bg-orange-50 text-orange-700":e>=500?"bg-red-50 text-red-700":"bg-zinc-100 text-zinc-700";function Bc(e){let t=new Date(e);if(isNaN(t.getTime()))return"";let r=new Date,n=t.getFullYear()===r.getFullYear()&&t.getMonth()===r.getMonth()&&t.getDate()===r.getDate(),o=t.getHours().toString().padStart(2,"0"),i=t.getMinutes().toString().padStart(2,"0");return n?`Today, ${o}:${i}`:t.toLocaleString()}function ms({title:e,subtitle:t,requests:r,selectedId:n,onSelect:o,statusFilter:i,onStatusFilterChange:a,search:l,onSearchChange:u,live:f}){let d=q(()=>{let c=[],h="";for(let x of r){let b=Bc(x.Timestamp);b!==h?(c.push({label:b,items:[x]}),h=b):c[c.length-1].items.push(x)}return c},[r]),p=c=>{let h=new Set(i);h.has(c)?h.delete(c):h.add(c),a(h)};return s("aside",{class:"w-[340px] border-r border-zinc-200 bg-white flex flex-col shrink-0",children:[s("div",{class:"px-4 py-3 border-b border-zinc-200",children:[s("div",{class:"flex items-center justify-between mb-2",children:[s("h2",{class:"text-sm font-semibold tracking-tight",children:e}),s("span",{class:"text-[11px] text-zinc-500 font-mono",children:r.length})]}),t&&s("p",{class:"text-[11px] text-zinc-500 mb-2 -mt-1",children:t}),s("input",{value:l,onInput:c=>u(c.target.value),placeholder:"Filter by path...",class:"w-full text-sm px-2.5 py-1.5 bg-zinc-50 border border-zinc-200 rounded-md focus:outline-none focus:ring-2 focus:ring-zinc-900/10 placeholder:text-zinc-400"}),s("div",{class:"flex items-center gap-1.5 flex-wrap mt-2",children:["2xx","3xx","4xx","5xx"].map(c=>{let h=i.has(c);return s("button",{onClick:()=>p(c),class:T("text-[11px] px-2 py-0.5 rounded-full ring-1",h?c==="2xx"?"bg-emerald-50 text-emerald-700 ring-emerald-600/10":c==="3xx"?"bg-amber-50 text-amber-700 ring-amber-600/10":c==="4xx"?"bg-orange-50 text-orange-700 ring-orange-600/10":"bg-red-50 text-red-700 ring-red-600/10":"bg-zinc-50 text-zinc-500 ring-zinc-200"),children:c},c)})})]}),s("div",{class:"flex-1 overflow-auto",children:d.length===0?s("div",{class:"px-4 py-10 text-center text-xs text-zinc-500",children:"No matching requests yet."}):d.map(c=>s(m,{children:[s("div",{class:"px-4 py-1.5 text-[10px] uppercase tracking-wide text-zinc-500 bg-zinc-50/50 sticky top-0",children:c.label}),c.items.map(h=>{let x=h.ID===n;return s("button",{onClick:()=>o(h),class:T("w-full text-left px-4 py-2.5 border-b border-zinc-100",x?"bg-zinc-50 border-l-2 border-l-zinc-900":"hover:bg-zinc-50 border-l-2 border-l-transparent"),children:[s("div",{class:"flex items-center justify-between mb-0.5",children:[s("span",{class:"flex items-center gap-2 min-w-0",children:[s("span",{class:T("text-[10px] font-semibold shrink-0",Fc[h.Method]||"text-zinc-700"),children:h.Method}),s("span",{class:"text-[10px] text-zinc-400",children:"\xB7"}),s("span",{class:T("text-[10px] font-mono px-1.5 py-0.5 rounded shrink-0",Hc(h.StatusCode)),children:h.StatusCode})]}),s("span",{class:"text-[11px] text-zinc-500 font-mono",children:$c(h.Duration)})]}),s("div",{class:"text-sm font-mono truncate text-zinc-900",children:h.Path})]},h.ID)})]},c.label))}),s("div",{class:"border-t border-zinc-200 px-3 py-2 text-[11px] text-zinc-500 flex items-center justify-between",children:[s("span",{children:[r.length," requests"]}),s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:T("w-1.5 h-1.5 rounded-full",f?"bg-emerald-500 animate-pulse":"bg-zinc-300")}),f?"Live":"Idle"]})]})]})}function $c(e){return e<1?"<1ms":e<1e3?`${e}ms`:`${(e/1e3).toFixed(2)}s`}var st=class extends Map{constructor(t,r=Vc){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),t!=null)for(let[n,o]of t)this.set(n,o)}get(t){return super.get(hs(this,t))}has(t){return super.has(hs(this,t))}set(t,r){return super.set(qc(this,t),r)}delete(t){return super.delete(Gc(this,t))}};function hs({_intern:e,_key:t},r){let n=t(r);return e.has(n)?e.get(n):r}function qc({_intern:e,_key:t},r){let n=t(r);return e.has(n)?e.get(n):(e.set(n,r),r)}function Gc({_intern:e,_key:t},r){let n=t(r);return e.has(n)&&(r=e.get(n),e.delete(n)),r}function Vc(e){return e!==null&&typeof e=="object"?e.valueOf():e}var Uc={value:()=>{}};function xs(){for(var e=0,t=arguments.length,r={},n;e=0&&(n=r.slice(o+1),r=r.slice(0,o)),r&&!t.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}lr.prototype=xs.prototype={constructor:lr,on:function(e,t){var r=this._,n=Wc(e+"",r),o,i=-1,a=n.length;if(arguments.length<2){for(;++i0)for(var r=new Array(o),n=0,o,i;n=0&&(t=e.slice(0,r))!=="xmlns"&&(e=e.slice(r+1)),xn.hasOwnProperty(t)?{space:xn[t],local:e}:e}function jc(e){return function(){var t=this.ownerDocument,r=this.namespaceURI;return r===cr&&t.documentElement.namespaceURI===cr?t.createElement(e):t.createElementNS(r,e)}}function Yc(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function ur(e){var t=Ne(e);return(t.local?Yc:jc)(t)}function Kc(){}function Ke(e){return e==null?Kc:function(){return this.querySelector(e)}}function bs(e){typeof e!="function"&&(e=Ke(e));for(var t=this._groups,r=t.length,n=new Array(r),o=0;o=S&&(S=R+1);!(y=v[S])&&++S=0;)(a=n[o])&&(i&&a.compareDocumentPosition(i)^4&&i.parentNode.insertBefore(a,i),i=a);return this}function zs(e){e||(e=cu);function t(p,c){return p&&c?e(p.__data__,c.__data__):!p-!c}for(var r=this._groups,n=r.length,o=new Array(n),i=0;it?1:e>=t?0:NaN}function As(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Ms(){return Array.from(this)}function Is(){for(var e=this._groups,t=0,r=e.length;t1?this.each((t==null?gu:typeof t=="function"?bu:xu)(e,t,r??"")):Fe(this.node(),e)}function Fe(e,t){return e.style.getPropertyValue(t)||pr(e).getComputedStyle(e,null).getPropertyValue(t)}function vu(e){return function(){delete this[e]}}function yu(e,t){return function(){this[e]=t}}function _u(e,t){return function(){var r=t.apply(this,arguments);r==null?delete this[e]:this[e]=r}}function Hs(e,t){return arguments.length>1?this.each((t==null?vu:typeof t=="function"?_u:yu)(e,t)):this.node()[e]}function Bs(e){return e.trim().split(/^|\s+/)}function vn(e){return e.classList||new $s(e)}function $s(e){this._node=e,this._names=Bs(e.getAttribute("class")||"")}$s.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function qs(e,t){for(var r=vn(e),n=-1,o=t.length;++n=0&&(r=t.slice(n+1),t=t.slice(0,n)),{type:t,name:r}})}function Hu(e){return function(){var t=this.__on;if(t){for(var r=0,n=-1,o=t.length,i;r>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?hr(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?hr(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=Uu.exec(e))?new le(t[1],t[2],t[3],1):(t=Wu.exec(e))?new le(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Xu.exec(e))?hr(t[1],t[2],t[3],t[4]):(t=ju.exec(e))?hr(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=Yu.exec(e))?fi(t[1],t[2]/100,t[3]/100,1):(t=Ku.exec(e))?fi(t[1],t[2]/100,t[3]/100,t[4]):si.hasOwnProperty(e)?li(si[e]):e==="transparent"?new le(NaN,NaN,NaN,0):null}function li(e){return new le(e>>16&255,e>>8&255,e&255,1)}function hr(e,t,r,n){return n<=0&&(e=t=r=NaN),new le(e,t,r,n)}function Zu(e){return e instanceof St||(e=He(e)),e?(e=e.rgb(),new le(e.r,e.g,e.b,e.opacity)):new le}function at(e,t,r,n){return arguments.length===1?Zu(e):new le(e,t,r,n??1)}function le(e,t,r,n){this.r=+e,this.g=+t,this.b=+r,this.opacity=+n}mr(le,at,wn(St,{brighter(e){return e=e==null?xr:Math.pow(xr,e),new le(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Ct:Math.pow(Ct,e),new le(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new le(Je(this.r),Je(this.g),Je(this.b),br(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:ci,formatHex:ci,formatHex8:ef,formatRgb:ui,toString:ui}));function ci(){return`#${Qe(this.r)}${Qe(this.g)}${Qe(this.b)}`}function ef(){return`#${Qe(this.r)}${Qe(this.g)}${Qe(this.b)}${Qe((isNaN(this.opacity)?1:this.opacity)*255)}`}function ui(){let e=br(this.opacity);return`${e===1?"rgb(":"rgba("}${Je(this.r)}, ${Je(this.g)}, ${Je(this.b)}${e===1?")":`, ${e})`}`}function br(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Je(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Qe(e){return e=Je(e),(e<16?"0":"")+e.toString(16)}function fi(e,t,r,n){return n<=0?e=t=r=NaN:r<=0||r>=1?e=t=NaN:t<=0&&(e=NaN),new de(e,t,r,n)}function pi(e){if(e instanceof de)return new de(e.h,e.s,e.l,e.opacity);if(e instanceof St||(e=He(e)),!e)return new de;if(e instanceof de)return e;e=e.rgb();var t=e.r/255,r=e.g/255,n=e.b/255,o=Math.min(t,r,n),i=Math.max(t,r,n),a=NaN,l=i-o,u=(i+o)/2;return l?(t===i?a=(r-n)/l+(r0&&u<1?0:a,new de(a,l,u,e.opacity)}function mi(e,t,r,n){return arguments.length===1?pi(e):new de(e,t,r,n??1)}function de(e,t,r,n){this.h=+e,this.s=+t,this.l=+r,this.opacity=+n}mr(de,mi,wn(St,{brighter(e){return e=e==null?xr:Math.pow(xr,e),new de(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Ct:Math.pow(Ct,e),new de(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*t,o=2*r-n;return new le(Rn(e>=240?e-240:e+120,o,n),Rn(e,o,n),Rn(e<120?e+240:e-120,o,n),this.opacity)},clamp(){return new de(di(this.h),gr(this.s),gr(this.l),br(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=br(this.opacity);return`${e===1?"hsl(":"hsla("}${di(this.h)}, ${gr(this.s)*100}%, ${gr(this.l)*100}%${e===1?")":`, ${e})`}`}}));function di(e){return e=(e||0)%360,e<0?e+360:e}function gr(e){return Math.max(0,Math.min(1,e||0))}function Rn(e,t,r){return(e<60?t+(r-t)*e/60:e<180?r:e<240?t+(r-t)*(240-e)/60:t)*255}function Cn(e,t,r,n,o){var i=e*e,a=i*e;return((1-3*e+3*i-a)*t+(4-6*i+3*a)*r+(1+3*e+3*i-3*a)*n+a*o)/6}function hi(e){var t=e.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,t-1):Math.floor(r*t),o=e[n],i=e[n+1],a=n>0?e[n-1]:2*o-i,l=n()=>e;function tf(e,t){return function(r){return e+r*t}}function rf(e,t,r){return e=Math.pow(e,r),t=Math.pow(t,r)-e,r=1/r,function(n){return Math.pow(e+n*t,r)}}function xi(e){return(e=+e)==1?vr:function(t,r){return r-t?rf(t,r,e):kn(isNaN(t)?r:t)}}function vr(e,t){var r=t-e;return r?tf(e,r):kn(isNaN(e)?t:e)}var yr=function e(t){var r=xi(t);function n(o,i){var a=r((o=at(o)).r,(i=at(i)).r),l=r(o.g,i.g),u=r(o.b,i.b),f=vr(o.opacity,i.opacity);return function(d){return o.r=a(d),o.g=l(d),o.b=u(d),o.opacity=f(d),o+""}}return n.gamma=e,n}(1);function bi(e){return function(t){var r=t.length,n=new Array(r),o=new Array(r),i=new Array(r),a,l;for(a=0;ar&&(i=t.slice(r,i),l[a]?l[a]+=i:l[++a]=i),(n=n[0])===(o=o[0])?l[a]?l[a]+=o:l[++a]=o:(l[++a]=null,u.push({i:a,x:fe(n,o)})),r=Sn.lastIndex;return r180?d+=360:d-f>180&&(f+=360),c.push({i:p.push(o(p)+"rotate(",null,n)-2,x:fe(f,d)})):d&&p.push(o(p)+"rotate("+d+n)}function l(f,d,p,c){f!==d?c.push({i:p.push(o(p)+"skewX(",null,n)-2,x:fe(f,d)}):d&&p.push(o(p)+"skewX("+d+n)}function u(f,d,p,c,h,x){if(f!==p||d!==c){var b=h.push(o(h)+"scale(",null,",",null,")");x.push({i:b-4,x:fe(f,p)},{i:b-2,x:fe(d,c)})}else(p!==1||c!==1)&&h.push(o(h)+"scale("+p+","+c+")")}return function(f,d){var p=[],c=[];return f=e(f),d=e(d),i(f.translateX,f.translateY,d.translateX,d.translateY,p,c),a(f.rotate,d.rotate,p,c),l(f.skewX,d.skewX,p,c),u(f.scaleX,f.scaleY,d.scaleX,d.scaleY,p,c),f=d=null,function(h){for(var x=-1,b=c.length,v;++x=0&&e._call.call(void 0,t),e=e._next;--lt}function Ri(){Ze=(Cr=zt.now())+kr,lt=Nt=0;try{Si()}finally{lt=0,uf(),Ze=0}}function cf(){var e=zt.now(),t=e-Cr;t>Ci&&(kr-=t,Cr=e)}function uf(){for(var e,t=Rr,r,n=1/0;t;)t._call?(n>t._time&&(n=t._time),e=t,t=t._next):(r=t._next,t._next=null,t=e?e._next=r:Rr=r);Et=e,Mn(n)}function Mn(e){if(!lt){Nt&&(Nt=clearTimeout(Nt));var t=e-Ze;t>24?(e<1/0&&(Nt=setTimeout(Ri,e-zt.now()-kr)),Tt&&(Tt=clearInterval(Tt))):(Tt||(Cr=zt.now(),Tt=setInterval(cf,Ci)),lt=1,ki(Ri))}}function Tr(e,t,r){var n=new At;return t=t==null?0:+t,n.restart(o=>{n.stop(),e(o+t)},t,r),n}var ff=gn("start","end","cancel","interrupt"),df=[],Ei=0,Ti=1,Er=2,Nr=3,Ni=4,zr=5,It=6;function Be(e,t,r,n,o,i){var a=e.__transition;if(!a)e.__transition={};else if(r in a)return;pf(e,r,{name:t,index:n,group:o,on:ff,tween:df,time:i.time,delay:i.delay,duration:i.duration,ease:i.ease,timer:null,state:Ei})}function Pt(e,t){var r=K(e,t);if(r.state>Ei)throw new Error("too late; already scheduled");return r}function ne(e,t){var r=K(e,t);if(r.state>Nr)throw new Error("too late; already running");return r}function K(e,t){var r=e.__transition;if(!r||!(r=r[t]))throw new Error("transition not found");return r}function pf(e,t,r){var n=e.__transition,o;n[t]=r,r.timer=Sr(i,0,r.time);function i(f){r.state=Ti,r.timer.restart(a,r.delay,r.time),r.delay<=f&&a(f-r.delay)}function a(f){var d,p,c,h;if(r.state!==Ti)return u();for(d in n)if(h=n[d],h.name===r.name){if(h.state===Nr)return Tr(a);h.state===Ni?(h.state=It,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete n[d]):+dEr&&n.state=0&&(t=t.slice(0,r)),!t||t==="start"})}function If(e,t,r){var n,o,i=Mf(t)?Pt:ne;return function(){var a=i(this,e),l=a.on;l!==n&&(o=(n=l).copy()).on(t,r),a.on=o}}function Bi(e,t){var r=this._id;return arguments.length<2?K(this.node(),r).on.on(e):this.each(If(r,e,t))}function Pf(e){return function(){var t=this.parentNode;for(var r in this.__transition)if(+r!==e)return;t&&t.removeChild(this)}}function $i(){return this.on("end.remove",Pf(this._id))}function qi(e){var t=this._name,r=this._id;typeof e!="function"&&(e=Ke(e));for(var n=this._groups,o=n.length,i=new Array(o),a=0;a=0;)t+=r[n].value;e.value=t}function ta(){return this.eachAfter(Kf)}function ra(e,t){let r=-1;for(let n of this)e.call(t,n,++r,this);return this}function na(e,t){for(var r=this,n=[r],o,i,a=-1;r=n.pop();)if(e.call(t,r,++a,this),o=r.children)for(i=o.length-1;i>=0;--i)n.push(o[i]);return this}function oa(e,t){for(var r=this,n=[r],o=[],i,a,l,u=-1;r=n.pop();)if(o.push(r),i=r.children)for(a=0,l=i.length;a=0;)r+=n[o].value;t.value=r})}function aa(e){return this.eachBefore(function(t){t.children&&t.children.sort(e)})}function la(e){for(var t=this,r=Qf(t,e),n=[t];t!==r;)t=t.parent,n.push(t);for(var o=n.length;e!==r;)n.splice(o,0,e),e=e.parent;return n}function Qf(e,t){if(e===t)return e;var r=e.ancestors(),n=t.ancestors(),o=null;for(e=r.pop(),t=n.pop();e===t;)o=e,e=r.pop(),t=n.pop();return o}function ca(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t}function ua(){return Array.from(this)}function fa(){var e=[];return this.eachBefore(function(t){t.children||e.push(t)}),e}function da(){var e=this,t=[];return e.each(function(r){r!==e&&t.push({source:r.parent,target:r})}),t}function*pa(){var e=this,t,r=[e],n,o,i;do for(t=r.reverse(),r=[];e=t.pop();)if(yield e,n=e.children)for(o=0,i=n.length;o=0;--l)o.push(i=a[l]=new Lt(a[l])),i.parent=n,i.depth=n.depth+1;return r.eachBefore(rd)}function Jf(){return ut(this).eachBefore(td)}function Zf(e){return e.children}function ed(e){return Array.isArray(e)?e[1]:null}function td(e){e.data.value!==void 0&&(e.value=e.data.value),e.data=e.data.data}function rd(e){var t=0;do e.height=t;while((e=e.parent)&&e.height<++t)}function Lt(e){this.data=e,this.depth=this.height=0,this.parent=null}Lt.prototype=ut.prototype={constructor:Lt,count:ta,each:ra,eachAfter:oa,eachBefore:na,find:sa,sum:ia,sort:aa,path:la,ancestors:ca,descendants:ua,leaves:fa,links:da,copy:Jf,[Symbol.iterator]:pa};function ma(e){e.x0=Math.round(e.x0),e.y0=Math.round(e.y0),e.x1=Math.round(e.x1),e.y1=Math.round(e.y1)}function ha(e,t,r,n,o){for(var i=e.children,a,l=-1,u=i.length,f=e.value&&(n-t)/e.value;++l{if(!e||!n.current)return;let i=_n(n.current);i.selectAll("*").remove();let a=20,l=r||400,u=ut(e).sum(c=>c.value||0).sort((c,h)=>(h.value||0)-(c.value||0));Pn().size([t,l]).padding(1).round(!0)(u);let d=Ot(On),p=i.selectAll("g").data(u.descendants()).join("g").attr("transform",c=>`translate(${c.x0},${c.depth*a})`);p.append("rect").attr("x",0).attr("width",c=>Math.max(0,c.x1-c.x0)).attr("height",a-1).attr("fill",c=>c.depth?d(c.data.name):"#f3f4f6").style("stroke","#fff").style("cursor","pointer").on("mouseover",function(c,h){if(o.current){let x=((h.value||0)/(u.value||1)*100).toFixed(2);o.current.innerHTML=` -
${h.data.name}
-
${x}% of total
-
Value: ${h.value}
- `,o.current.style.display="block",o.current.style.left=c.pageX+10+"px",o.current.style.top=c.pageY-28+"px"}}).on("mousemove",function(c){o.current&&(o.current.style.left=c.pageX+10+"px",o.current.style.top=c.pageY-28+"px")}).on("mouseout",function(){o.current&&(o.current.style.display="none")}),p.append("text").attr("x",4).attr("y",a/2).attr("dy","0.32em").text(c=>{let h=c.x1-c.x0;if(h<30)return"";let x=c.data.name,b=Math.floor(h/7);return x.length>b?x.substring(0,b-1)+"\u2026":x}).style("pointer-events","none").style("fill",c=>c.depth?"#fff":"#000").style("font-size","12px").style("font-family","monospace")},[e,t,r]),e?s("div",{className:"relative",children:[s("svg",{ref:n,width:t,height:r,style:{width:"100%",height:"auto"},viewBox:`0 0 ${t} ${r}`}),s("div",{ref:o,className:"absolute bg-gray-900 text-white p-2 rounded shadow-lg text-sm",style:{display:"none",pointerEvents:"none",zIndex:1e3,position:"fixed"}})]}):s("div",{className:"flex items-center justify-center h-64 text-muted-foreground",children:"No flame graph data available"})}function _a({request:e,onReplay:t,onCompareAdd:r,comparePending:n}){let[o,i]=N("overview"),[a,l]=N(null),[u,f]=N(null),[d,p]=N(!1);if(I(()=>{if(!e?.ID){l(null),f(null),i("overview");return}let b=new AbortController;return i("overview"),l(null),f(null),p(!0),te.getMetrics(e.ID,b.signal).then(v=>l(v)).catch(v=>{if(v?.name!=="AbortError"){if(v instanceof ge&&(v.status===501||v.status===404)){l(null);return}console.error("Failed to load metrics:",v),l(null)}}).finally(()=>{b.signal.aborted||p(!1)}),()=>b.abort()},[e?.ID]),I(()=>{if(o!=="performance"||!e?.ID||u)return;let b=new AbortController;return te.getFlameGraph(e.ID,b.signal).then(f).catch(v=>{if(v?.name!=="AbortError"){if(v instanceof ge&&(v.status===404||v.status===501)){f(null);return}console.error("Failed to load flame graph:",v)}}),()=>b.abort()},[o,e?.ID]),!e)return s("main",{class:"flex-1 flex items-center justify-center bg-zinc-50/40",children:s("div",{class:"text-center max-w-sm",children:[s("div",{class:"w-12 h-12 mx-auto rounded-full bg-zinc-100 flex items-center justify-center mb-3 text-zinc-400",children:s("svg",{class:"w-5 h-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("polyline",{points:"9 11 12 14 22 4"}),s("path",{d:"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"})]})}),s("h3",{class:"text-sm font-medium text-zinc-900",children:"No request selected"}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Pick a request from the list to see headers, body, and timing."})]})});let c=!!a||!!e.PerformanceMetrics,h=a||e.PerformanceMetrics||null,x=!!e.Logs&&e.Logs.length>0;return s("main",{class:"flex-1 flex flex-col bg-white overflow-hidden",children:[s("div",{class:"px-6 py-4 border-b border-zinc-200 flex items-start justify-between gap-4",children:[s("div",{class:"min-w-0",children:[s("div",{class:"flex items-center gap-2 mb-1 flex-wrap",children:[s("span",{class:"text-xs font-semibold text-blue-700 px-1.5 py-0.5 rounded bg-blue-50",children:e.Method}),s("h2",{class:"text-base font-mono truncate",children:e.Path}),s("span",{class:T("text-xs font-mono px-1.5 py-0.5 rounded",sd(e.StatusCode)),children:e.StatusCode})]}),s("div",{class:"text-xs text-zinc-500 flex items-center gap-3 flex-wrap",children:[s("span",{children:Dt(e.Duration)}),s("span",{children:"\xB7"}),s("span",{children:new Date(e.Timestamp).toLocaleString()}),s("span",{children:"\xB7"}),s("span",{class:"font-mono truncate",title:e.ID,children:[e.ID.slice(0,12),"\u2026"]})]})]}),s("div",{class:"flex items-center gap-1 shrink-0",children:[t&&s("button",{onClick:()=>t(e),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50",children:"Replay"}),r&&s("button",{onClick:()=>r(e),class:T("text-xs border rounded-md px-2.5 py-1.5",n?"bg-zinc-900 text-white border-zinc-900":"border-zinc-200 hover:bg-zinc-50"),children:n?"Selected":"Compare"}),s("button",{onClick:()=>ad(e),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50",title:"Copy as curl",children:"Copy cURL"})]})]}),s("div",{class:"px-6 border-b border-zinc-200",children:s("nav",{class:"flex gap-1 -mb-px",children:[["overview","headers","body","trace"].map(b=>s("button",{onClick:()=>i(b),class:T("px-3 py-2.5 text-sm border-b-2",o===b?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:od(b)},b)),x&&s("button",{onClick:()=>i("logs"),class:T("px-3 py-2.5 text-sm border-b-2",o==="logs"?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:["Logs \xB7 ",e.Logs.length]}),c&&s("button",{onClick:()=>i("performance"),class:T("px-3 py-2.5 text-sm border-b-2",o==="performance"?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:"Performance"})]})}),s("div",{class:"flex-1 overflow-auto p-6 space-y-5",children:[o==="overview"&&s(ld,{request:e}),o==="headers"&&s(pd,{request:e}),o==="body"&&s(md,{request:e}),o==="trace"&&s(hd,{request:e,metrics:h}),o==="logs"&&s(cd,{request:e}),o==="performance"&&s(gd,{metrics:h,flame:u,loading:d})]})]})}function od(e){switch(e){case"overview":return"Overview";case"headers":return"Headers";case"body":return"Body";case"trace":return"Trace";case"logs":return"Logs";case"performance":return"Performance"}}function sd(e){return e>=200&&e<300?"bg-emerald-50 text-emerald-700":e>=300&&e<400?"bg-amber-50 text-amber-700":e>=400&&e<500?"bg-orange-50 text-orange-700":e>=500?"bg-red-50 text-red-700":"bg-zinc-100 text-zinc-700"}function Dt(e){return e<1?"<1ms":e<1e3?`${e}ms`:`${(e/1e3).toFixed(2)}s`}function Ft(e){if(!e)return"0ms";let t=e/1e6;return t<1?Math.round(e/1e3)+"\u03BCs":t<1e3?t.toFixed(2)+"ms":(t/1e3).toFixed(2)+"s"}function wa(e){if(!e)return"0 B";let t=["B","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(1024));return Math.round(e/Math.pow(1024,r)*100)/100+" "+t[r]}function id(e){if(!e)return"No body";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function ad(e){let r=`http://${e.RequestHeaders?.Host?.[0]||"localhost"}${e.Path}${e.Query?"?"+e.Query:""}`,n=[`curl -X ${e.Method} ${Hn(r)}`];for(let[i,a]of Object.entries(e.RequestHeaders||{}))for(let l of a)n.push(`-H ${Hn(`${i}: ${l}`)}`);e.RequestBody&&n.push(`-d ${Hn(e.RequestBody)}`);let o=n.join(` \\ - `);navigator.clipboard.writeText(o).catch(()=>{})}function Hn(e){return`'${e.replace(/'/g,"'\\''")}'`}function ld({request:e}){return s(m,{children:[s("section",{class:"grid grid-cols-4 gap-3",children:[s(qe,{label:"Duration",value:Dt(e.Duration)}),s(qe,{label:"Status",value:String(e.StatusCode)}),s(qe,{label:"Response size",value:wa(e.ResponseBody?.length||0)}),s(qe,{label:"Query",value:e.Query||"\u2014",mono:!0})]}),s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:"Timeline"}),s("span",{class:"text-xs text-zinc-500",children:["total ",Dt(e.Duration)]})]}),s("div",{class:"p-4",children:s("div",{class:"flex items-center gap-3 text-xs font-mono",children:[s("span",{class:"w-24 text-zinc-500",children:"Duration"}),s("div",{class:"flex-1 h-1.5 bg-zinc-100 rounded-full overflow-hidden",children:s("div",{class:"h-1.5 bg-blue-400 rounded-full",style:{width:"100%"}})}),s("span",{class:"w-16 text-right",children:Dt(e.Duration)})]})})]}),e.Error&&s("section",{class:"border border-red-200 bg-red-50/50 rounded-lg p-4",children:[s("h3",{class:"text-sm font-medium text-red-800 mb-1",children:"Error"}),s("pre",{class:"text-xs font-mono text-red-700 whitespace-pre-wrap",children:e.Error}),e.PanicStack&&s("pre",{class:"text-[11px] font-mono text-red-600/80 whitespace-pre-wrap break-all mt-3 pt-3 border-t border-red-200 max-h-64 overflow-auto",children:e.PanicStack})]})]})}function cd({request:e}){let t=e.Logs||[];return t.length===0?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["No log lines captured. Wrap your slog handler with"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.SlogHandler(...)"})," ","and log with the request context to capture per-request lines here."]}):s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:"Application logs"}),s("span",{class:"text-[11px] text-zinc-500",children:[t.length," lines"]})]}),s("div",{class:"divide-y divide-zinc-100",children:t.map((r,n)=>s(ud,{entry:r},n))})]})}function ud({entry:e}){let t=e.attrs?Object.entries(e.attrs):[],r=new Date(e.time),n=isNaN(r.getTime())?"":r.toLocaleTimeString("en-US",{hour12:!1})+"."+String(r.getMilliseconds()).padStart(3,"0");return s("div",{class:"px-4 py-2 text-xs",children:[s("div",{class:"flex items-baseline gap-2 font-mono",children:[n&&s("span",{class:"text-zinc-400 shrink-0",children:n}),s("span",{class:T("shrink-0 font-semibold",dd(e.level)),children:e.level}),s("span",{class:"text-zinc-900 break-all",children:e.message})]}),t.length>0&&s("div",{class:"mt-1 pl-4 flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] font-mono text-zinc-500",children:t.map(([o,i])=>s("span",{children:[s("span",{class:"text-zinc-400",children:[o,"="]}),s("span",{class:"text-zinc-700",children:fd(i)})]},o))})]})}function fd(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function dd(e){switch(e.toUpperCase()){case"ERROR":return"text-red-600";case"WARN":case"WARNING":return"text-amber-600";case"EVENT":return"text-blue-600";case"DEBUG":return"text-zinc-500";default:return"text-emerald-700"}}function qe({label:e,value:t,mono:r}){return s("div",{class:"border border-zinc-200 rounded-lg p-3",children:[s("div",{class:"text-[11px] text-zinc-500 mb-1",children:e}),s("div",{class:T("font-semibold truncate",r?"text-sm font-mono":"text-lg"),children:t})]})}function pd({request:e}){return s(m,{children:[s(va,{title:"Request headers",headers:e.RequestHeaders}),s(va,{title:"Response headers",headers:e.ResponseHeaders})]})}function va({title:e,headers:t}){let r=Object.entries(t||{});return s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:e})}),r.length===0?s("div",{class:"px-4 py-3 text-xs text-zinc-500",children:"No headers"}):s("div",{class:"divide-y divide-zinc-100",children:r.map(([n,o])=>s("div",{class:"grid grid-cols-[180px_1fr] gap-3 px-4 py-2 text-xs font-mono",children:[s("div",{class:"text-zinc-500 truncate",title:n,children:n}),s("div",{class:"text-zinc-900 break-all",children:o.join(", ")})]},n))})]})}function md({request:e}){return s(m,{children:[s(ya,{title:"Request body",body:e.RequestBody}),s(ya,{title:"Response body",body:e.ResponseBody})]})}function ya({title:e,body:t}){return s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:e}),s("span",{class:"text-[11px] text-zinc-500",children:[t?.length||0," bytes"]})]}),s("pre",{class:"p-4 text-xs font-mono overflow-auto max-h-96 bg-zinc-50/50 rounded-b-lg whitespace-pre-wrap break-all",children:id(t)})]})}function hd({request:e,metrics:t}){let r=e.MiddlewareTrace||[],n=t?.sql_queries||[],o=t?.http_calls||[];return s(m,{children:[r.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"Middleware"})}),s("div",{class:"divide-y divide-zinc-100",children:r.map((i,a)=>s("div",{class:"px-4 py-2 flex items-center justify-between text-xs",children:[s("span",{class:"font-mono",children:i.name||`Middleware ${a+1}`}),s("span",{class:"text-zinc-500 font-mono",children:Dt(i.duration||0)})]},a))})]}),n.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:["SQL queries \xB7 ",n.length]})}),s("div",{class:"divide-y divide-zinc-100",children:n.slice(0,10).map((i,a)=>s("div",{class:"px-4 py-2 text-xs",children:[s("pre",{class:"font-mono text-emerald-700 whitespace-pre-wrap break-all",children:i.query}),s("div",{class:"text-zinc-500 mt-1 font-mono",children:[Ft(i.duration)," \xB7 ",i.rows," rows",i.error&&s("span",{class:"text-red-600 ml-2",children:["\xB7 ",i.error]})]})]},a))})]}),o.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:["HTTP calls \xB7 ",o.length]})}),s("div",{class:"divide-y divide-zinc-100",children:o.slice(0,10).map((i,a)=>s("div",{class:"px-4 py-2 text-xs flex items-center justify-between",children:[s("span",{class:"font-mono truncate",children:[s("span",{class:"text-blue-700 font-semibold mr-2",children:i.method}),i.url]}),s("span",{class:"text-zinc-500 font-mono shrink-0 ml-2",children:[i.status," \xB7 ",Ft(i.duration)]})]},a))})]}),r.length===0&&n.length===0&&o.length===0&&s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["No trace data captured for this request.",s("br",{}),"Enable profiling with ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.WithProfiling(true)"})," to see SQL queries and outbound HTTP calls."]})]})}function gd({metrics:e,flame:t,loading:r}){return r?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:"Loading metrics\u2026"}):e?s(m,{children:[s("section",{class:"grid grid-cols-4 gap-3",children:[s(qe,{label:"CPU time",value:Ft(e.cpu_time)}),s(qe,{label:"Memory",value:wa(e.memory_alloc)}),s(qe,{label:"Goroutines",value:String(e.num_goroutines||0)}),s(qe,{label:"GC pause",value:Ft(e.gc_pause_total)})]}),e.bottlenecks&&e.bottlenecks.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"Bottlenecks"})}),s("div",{class:"divide-y divide-zinc-100",children:e.bottlenecks.map((n,o)=>s("div",{class:"px-4 py-3",children:[s("div",{class:"flex items-center justify-between mb-1",children:[s("span",{class:"text-xs font-medium uppercase tracking-wide text-zinc-500",children:n.type}),s("span",{class:"text-xs font-mono text-zinc-700",children:[(n.impact*100).toFixed(1),"% \xB7 ",Ft(n.duration)]})]}),s("div",{class:"text-sm text-zinc-900",children:n.description}),n.suggestion&&s("div",{class:"text-xs text-zinc-500 mt-1",children:n.suggestion})]},o))})]}),t&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"CPU flame graph"})}),s("div",{class:"p-4 overflow-x-auto",children:s(ba,{data:t,width:900,height:400})})]})]}):s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["Profiling is not enabled. Pass"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.WithProfiling(true)"})," ","on the server to see CPU and memory metrics here."]})}function Ra(){let[e,t]=N([]),[r,n]=N(!0);return I(()=>{let o=!0,i=()=>{te.getAgentActivity().then(l=>{o&&(t(l||[]),n(!1))}).catch(()=>{o&&n(!1)})};i();let a=setInterval(i,3e3);return()=>{o=!1,clearInterval(a)}},[]),s("main",{class:"flex-1 flex flex-col bg-white overflow-hidden",children:[s("div",{class:"px-6 py-4 border-b border-zinc-200",children:[s("h2",{class:"text-base font-medium",children:"Agent activity"}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Recent MCP tool calls, newest first. Refreshes every 3s."})]}),s("div",{class:"flex-1 overflow-auto p-6",children:r?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:"Loading\u2026"}):e.length===0?s(xd,{}):s("ul",{class:"border border-zinc-200 rounded-lg divide-y divide-zinc-100",children:e.map((o,i)=>s("li",{class:"px-4 py-3 text-xs",children:[s("div",{class:"flex items-baseline gap-2 flex-wrap",children:[s("span",{class:"text-zinc-400 font-mono shrink-0",children:bd(o.time)}),s("span",{class:T("px-1.5 py-0.5 rounded font-mono text-[11px]",o.mutating?"bg-amber-50 text-amber-700":"bg-blue-50 text-blue-700"),children:o.tool}),s("span",{class:"text-zinc-500 font-mono",children:vd(o.duration)}),o.error&&s("span",{class:"text-red-600 font-mono truncate",children:o.error})]}),o.args&&Object.keys(o.args).length>0&&s("div",{class:"mt-1 pl-4 flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] font-mono text-zinc-500",children:Object.entries(o.args).map(([a,l])=>s("span",{children:[s("span",{class:"text-zinc-400",children:[a,"="]}),s("span",{class:"text-zinc-700 break-all",children:l})]},a))})]},i))})})]})}function xd(){return s(m,{children:s("div",{class:"text-xs text-zinc-500 max-w-lg mx-auto text-center py-8",children:[s("p",{class:"mb-3",children:"No agent activity yet."}),s("p",{class:"mb-2",children:["Share a"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"store.NewActivityLog(200)"})," ","between"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.Wrap"})," ","and the MCP handler:"]}),s("pre",{class:"text-left text-[11px] font-mono bg-zinc-50 border border-zinc-200 rounded p-3 overflow-x-auto",children:`log := store.NewActivityLog(200) +"use strict";(()=>{var Vo=Object.defineProperty;var Uo=e=>{throw TypeError(e)};var Sc=(e,t,r)=>t in e?Vo(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var Tc=(e,t)=>{for(var r in t)Vo(e,r,{get:t[r],enumerable:!0})};var ar=(e,t,r)=>Sc(e,typeof t!="symbol"?t+"":t,r),jo=(e,t,r)=>t.has(e)||Uo("Cannot "+r);var ae=(e,t,r)=>(jo(e,t,"read from private field"),r?r.call(e):t.get(e)),Wo=(e,t,r)=>t.has(e)?Uo("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),dn=(e,t,r,n)=>(jo(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r);var Nt,A,Qo,Ec,We,Xo,Jo,Zo,pn,cr,Tt,es,xn,mn,hn,ts,ur={},fr=[],Nc=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,It=Array.isArray;function Re(e,t){for(var r in t)e[r]=t[r];return e}function bn(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function g(e,t,r){var n,o,i,a={};for(i in t)i=="key"?n=t[i]:i=="ref"?o=t[i]:a[i]=t[i];if(arguments.length>2&&(a.children=arguments.length>3?Nt.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(i in e.defaultProps)a[i]===void 0&&(a[i]=e.defaultProps[i]);return Et(e,a,n,o,null)}function Et(e,t,r,n,o){var i={type:e,props:t,key:r,ref:n,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++Qo,__i:-1,__u:0};return o==null&&A.vnode!=null&&A.vnode(i),i}function pr(){return{current:null}}function h(e){return e.children}function de(e,t){this.props=e,this.context=t}function ot(e,t){if(t==null)return e.__?ot(e.__,e.__i+1):null;for(var r;tt&&We.sort(Zo),e=We.shift(),t=We.length,Ic(e)}finally{We.length=dr.__r=0}}function ns(e,t,r,n,o,i,a,l,c,u,p){var d,f,m,x,b,y,w=n&&n.__k||fr,_=t.length;for(c=Pc(r,t,w,c,_),d=0;d<_;d++)(m=r.__k[d])!=null&&(f=m.__i!=-1&&w[m.__i]||ur,m.__i=d,y=vn(e,m,f,o,i,a,l,c,u,p),x=m.__e,m.ref&&f.ref!=m.ref&&(f.ref&&yn(f.ref,null,m),p.push(m.ref,m.__c||x,m)),b==null&&x!=null&&(b=x),4&m.__u?(c=os(m,c,e),f.__e&&(f.__e=null)):typeof m.type=="function"&&y!==void 0?c=y:x&&(c=x.nextSibling),m.__u&=-7);return r.__e=b,c}function Pc(e,t,r,n,o){var i,a,l,c,u,p=r.length,d=p,f=0;for(e.__k=new Array(o),i=0;i0?a=e.__k[i]=Et(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):e.__k[i]=a,c=i+f,a.__=e,a.__b=e.__b+1,l=null,(u=a.__i=Ac(a,r,c,d))!=-1&&(d--,(l=r[u])&&(l.__u|=2)),l==null||l.__v==null?(u==-1&&(o>p?f--:oc?f--:f++,a.__u|=4))):e.__k[i]=null;if(d)for(i=0;i(p?1:0)){for(o=r-1,i=r+1;o>=0||i=0?o--:i++])!=null&&(2&u.__u)==0&&l==u.key&&c==u.type)return a}return-1}function Yo(e,t,r){t[0]=="-"?e.setProperty(t,r??""):e[t]=r==null?"":typeof r!="number"||Nc.test(t)?r:r+"px"}function lr(e,t,r,n,o){var i,a;e:if(t=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof n=="string"&&(e.style.cssText=n=""),n)for(t in n)r&&t in r||Yo(e.style,t,"");if(r)for(t in r)n&&r[t]==n[t]||Yo(e.style,t,r[t])}else if(t[0]=="o"&&t[1]=="n")i=t!=(t=t.replace(es,"$1")),a=t.toLowerCase(),t=a in e||t=="onFocusOut"||t=="onFocusIn"?a.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=r,r?n?r[Tt]=n[Tt]:(r[Tt]=xn,e.addEventListener(t,i?hn:mn,i)):e.removeEventListener(t,i?hn:mn,i);else{if(o=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=r??"";break e}catch{}typeof r=="function"||(r==null||r===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&r==1?"":r))}}function Ko(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t[cr]==null)t[cr]=xn++;else if(t[cr]0?e:It(e)?e.map(as):e.constructor!==void 0?null:Re({},e)}function Mc(e,t,r,n,o,i,a,l,c){var u,p,d,f,m,x,b,y=r.props||ur,w=t.props,_=t.type;if(_=="svg"?o="http://www.w3.org/2000/svg":_=="math"?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),i!=null){for(u=0;u2&&(l.children=arguments.length>3?Nt.call(arguments,2):r),Et(e.type,l,n||e.key,o||e.ref,null)}function ke(e){function t(r){var n,o;return this.getChildContext||(n=new Set,(o={})[t.__c]=this,this.getChildContext=function(){return o},this.componentWillUnmount=function(){n=null},this.shouldComponentUpdate=function(i){this.props.value!=i.value&&n.forEach(function(a){a.__e=!0,gn(a)})},this.sub=function(i){n.add(i);var a=i.componentWillUnmount;i.componentWillUnmount=function(){n&&n.delete(i),a&&a.call(i)}}),r.children}return t.__c="__cC"+ts++,t.__=e,t.Provider=t.__l=(t.Consumer=function(r,n){return r.children(n)}).contextType=t,t}Nt=fr.slice,A={__e:function(e,t,r,n){for(var o,i,a;t=t.__;)if((o=t.__c)&&!o.__)try{if((i=o.constructor)&&i.getDerivedStateFromError!=null&&(o.setState(i.getDerivedStateFromError(e)),a=o.__d),o.componentDidCatch!=null&&(o.componentDidCatch(e,n||{}),a=o.__d),a)return o.__E=o}catch(l){e=l}throw e}},Qo=0,Ec=function(e){return e!=null&&e.constructor===void 0},de.prototype.setState=function(e,t){var r;r=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=Re({},this.state),typeof e=="function"&&(e=e(Re({},r),this.props)),e&&Re(r,e),e!=null&&this.__v&&(t&&this._sb.push(t),gn(this))},de.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),gn(this))},de.prototype.render=h,We=[],Jo=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Zo=function(e,t){return e.__v.__b-t.__v.__b},dr.__r=0,pn=Math.random().toString(8),cr="__d"+pn,Tt="__a"+pn,es=/(PointerCapture)$|Capture$/i,xn=0,mn=Ko(!1),hn=Ko(!0),ts=0;var ze,G,wn,us,mt=0,bs=[],U=A,fs=U.__b,ds=U.__r,ps=U.diffed,ms=U.__c,hs=U.unmount,gs=U.__;function st(e,t){U.__h&&U.__h(G,e,mt||t),mt=0;var r=G.__H||(G.__H={__:[],__h:[]});return e>=r.__.length&&r.__.push({}),r.__[e]}function E(e){return mt=1,Le(vs,e)}function Le(e,t,r){var n=st(ze++,2);if(n.t=e,!n.__c&&(n.__=[r?r(t):vs(void 0,t),function(l){var c=n.__N?n.__N[0]:n.__[0],u=n.t(c,l);c!==u&&(n.__N=[u,n.__[1]],n.__c.setState({}))}],n.__c=G,!G.__f)){var o=function(l,c,u){if(!n.__c.__H)return!0;var p=!1,d=n.__c.props!==l;if(n.__c.__H.__.some(function(m){if(m.__N){p=!0;var x=m.__[0];m.__=m.__N,m.__N=void 0,x!==m.__[0]&&(d=!0)}}),i){var f=i.call(this,l,c,u);return p?f||d:f}return!p||d};G.__f=!0;var i=G.shouldComponentUpdate,a=G.componentWillUpdate;G.componentWillUpdate=function(l,c,u){if(this.__e){var p=i;i=void 0,o(l,c,u),i=p}a&&a.call(this,l,c,u)},G.shouldComponentUpdate=o}return n.__N||n.__}function L(e,t){var r=st(ze++,3);!U.__s&&Cn(r.__H,t)&&(r.__=e,r.u=t,G.__H.__h.push(r))}function Oe(e,t){var r=st(ze++,4);!U.__s&&Cn(r.__H,t)&&(r.__=e,r.u=t,G.__h.push(r))}function D(e){return mt=5,$(function(){return{current:e}},[])}function hr(e,t,r){mt=6,Oe(function(){if(typeof e=="function"){var n=e(t());return function(){e(null),n&&typeof n=="function"&&n()}}if(e)return e.current=t(),function(){return e.current=null}},r==null?r:r.concat(e))}function $(e,t){var r=st(ze++,7);return Cn(r.__H,t)&&(r.__=e(),r.__H=t,r.__h=e),r.__}function W(e,t){return mt=8,$(function(){return e},t)}function De(e){var t=G.context[e.__c],r=st(ze++,9);return r.c=e,t?(r.__==null&&(r.__=!0,t.sub(G)),t.props.value):e.__}function gr(e,t){U.useDebugValue&&U.useDebugValue(t?t(e):e)}function Lc(e){var t=st(ze++,10),r=E();return t.__=e,G.componentDidCatch||(G.componentDidCatch=function(n,o){t.__&&t.__(n,o),r[1](n)}),[r[0],function(){r[1](void 0)}]}function xr(){var e=st(ze++,11);if(!e.__){for(var t=G.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var r=t.__m||(t.__m=[0,0]);e.__="P"+r[0]+"-"+r[1]++}return e.__}function Oc(){for(var e;e=bs.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(mr),t.__h.some(Rn),t.__h=[]}catch(r){t.__h=[],U.__e(r,e.__v)}}}U.__b=function(e){G=null,fs&&fs(e)},U.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),gs&&gs(e,t)},U.__r=function(e){ds&&ds(e),ze=0;var t=(G=e.__c).__H;t&&(wn===G?(t.__h=[],G.__h=[],t.__.some(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(t.__h.some(mr),t.__h.some(Rn),t.__h=[],ze=0)),wn=G},U.diffed=function(e){ps&&ps(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(bs.push(t)!==1&&us===U.requestAnimationFrame||((us=U.requestAnimationFrame)||Dc)(Oc)),t.__H.__.some(function(r){r.u&&(r.__H=r.u,r.u=void 0)})),wn=G=null},U.__c=function(e,t){t.some(function(r){try{r.__h.some(mr),r.__h=r.__h.filter(function(n){return!n.__||Rn(n)})}catch(n){t.some(function(o){o.__h&&(o.__h=[])}),t=[],U.__e(n,r.__v)}}),ms&&ms(e,t)},U.unmount=function(e){hs&&hs(e);var t,r=e.__c;r&&r.__H&&(r.__H.__.some(function(n){try{mr(n)}catch(o){t=o}}),r.__H=void 0,t&&U.__e(t,r.__v))};var xs=typeof requestAnimationFrame=="function";function Dc(e){var t,r=function(){clearTimeout(n),xs&&cancelAnimationFrame(t),setTimeout(e)},n=setTimeout(r,35);xs&&(t=requestAnimationFrame(r))}function mr(e){var t=G,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),G=t}function Rn(e){var t=G;e.__c=e.__(),G=t}function Cn(e,t){return!e||e.length!==t.length||t.some(function(r,n){return r!==e[n]})}function vs(e,t){return typeof t=="function"?t(e):t}var Se=class extends Error{constructor(r,n,o){super(o||n||`request failed (${r})`);ar(this,"status");ar(this,"body");this.status=r,this.body=n}get isNotFound(){return this.status===404}get isUnauthorized(){return this.status===401||this.status===403}};async function Fe(e,t){let r=await fetch(e,t);if(!r.ok){let o=await r.text().catch(()=>"");throw new Se(r.status,o)}if((r.headers.get("content-type")||"").includes("application/json"))return r.json()}var kn=class{constructor(){ar(this,"baseURL",window.location.pathname.replace(/\/$/,"")+"/api")}getRequests(t){return Fe(`${this.baseURL}/requests`,{signal:t})}async clearRequests(){await Fe(`${this.baseURL}/clear`,{method:"POST"})}compareRequests(t,r){let n=t.map(o=>`id=${encodeURIComponent(o)}`).join("&");return Fe(`${this.baseURL}/compare?${n}`,{signal:r})}replayRequest(t){return Fe(`${this.baseURL}/replay`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}getMetrics(t,r){return Fe(`${this.baseURL}/metrics?id=${encodeURIComponent(t)}`,{signal:r})}getFlameGraph(t,r){return Fe(`${this.baseURL}/flamegraph?id=${encodeURIComponent(t)}`,{signal:r})}getBottlenecks(t){return Fe(`${this.baseURL}/bottlenecks`,{signal:t})}getSystemInfo(t){return Fe(`${this.baseURL}/system-info`,{signal:t})}getAgentActivity(t){return Fe(`${this.baseURL}/agent-activity`,{signal:t})}subscribeToEvents(t,r){let n=new EventSource(`${this.baseURL}/events`),o=i=>a=>{try{let l=JSON.parse(a.data);t({kind:i,data:l})}catch(l){console.error(`Failed to parse ${i} event:`,l)}};return n.addEventListener("snapshot",o("snapshot")),n.addEventListener("append",o("append")),r&&(n.onerror=r),n}exportRequests(t){return JSON.stringify(t,null,2)}importRequests(t){let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid format: expected an array of requests");return r}},re=new kn;function ys(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var o=e.length;for(t=0;t{let r=new Array(e.length+t.length);for(let n=0;n({classGroupId:e,validator:t}),Ss=(e=new Map,t=null,r)=>({nextPart:e,validators:t,classGroupId:r});var _s=[],Bc="arbitrary..",$c=e=>{let t=Gc(e),{conflictingClassGroups:r,conflictingClassGroupModifiers:n}=e;return{getClassGroupId:a=>{if(a.startsWith("[")&&a.endsWith("]"))return qc(a);let l=a.split("-"),c=l[0]===""&&l.length>1?1:0;return Ts(l,c,t)},getConflictingClassGroupIds:(a,l)=>{if(l){let c=n[a],u=r[a];return c?u?Fc(u,c):c:u||_s}return r[a]||_s}}},Ts=(e,t,r)=>{if(e.length-t===0)return r.classGroupId;let o=e[t],i=r.nextPart.get(o);if(i){let u=Ts(e,t+1,i);if(u)return u}let a=r.validators;if(a===null)return;let l=t===0?e.join("-"):e.slice(t).join("-"),c=a.length;for(let u=0;ue.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let t=e.slice(1,-1),r=t.indexOf(":"),n=t.slice(0,r);return n?Bc+n:void 0})(),Gc=e=>{let{theme:t,classGroups:r}=e;return Vc(r,t)},Vc=(e,t)=>{let r=Ss();for(let n in e){let o=e[n];Tn(o,r,n,t)}return r},Tn=(e,t,r,n)=>{let o=e.length;for(let i=0;i{if(typeof e=="string"){jc(e,t,r);return}if(typeof e=="function"){Wc(e,t,r,n);return}Xc(e,t,r,n)},jc=(e,t,r)=>{let n=e===""?t:Es(t,e);n.classGroupId=r},Wc=(e,t,r,n)=>{if(Yc(e)){Tn(e(n),t,r,n);return}t.validators===null&&(t.validators=[]),t.validators.push(Hc(r,e))},Xc=(e,t,r,n)=>{let o=Object.entries(e),i=o.length;for(let a=0;a{let r=e,n=t.split("-"),o=n.length;for(let i=0;i"isThemeGetter"in e&&e.isThemeGetter===!0,Kc=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,r=Object.create(null),n=Object.create(null),o=(i,a)=>{r[i]=a,t++,t>e&&(t=0,n=r,r=Object.create(null))};return{get(i){let a=r[i];if(a!==void 0)return a;if((a=n[i])!==void 0)return o(i,a),a},set(i,a){i in r?r[i]=a:o(i,a)}}};var Qc=[],ws=(e,t,r,n,o)=>({modifiers:e,hasImportantModifier:t,baseClassName:r,maybePostfixModifierPosition:n,isExternal:o}),Jc=e=>{let{prefix:t,experimentalParseClassName:r}=e,n=o=>{let i=[],a=0,l=0,c=0,u,p=o.length;for(let b=0;bc?u-c:void 0;return ws(i,m,f,x)};if(t){let o=t+":",i=n;n=a=>a.startsWith(o)?i(a.slice(o.length)):ws(Qc,!1,a,void 0,!0)}if(r){let o=n;n=i=>r({className:i,parseClassName:o})}return n},Zc=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((r,n)=>{t.set(r,1e6+n)}),r=>{let n=[],o=[];for(let i=0;i0&&(o.sort(),n.push(...o),o=[]),n.push(a)):o.push(a)}return o.length>0&&(o.sort(),n.push(...o)),n}},eu=e=>({cache:Kc(e.cacheSize),parseClassName:Jc(e),sortModifiers:Zc(e),postfixLookupClassGroupIds:tu(e),...$c(e)}),tu=e=>{let t=Object.create(null),r=e.postfixLookupClassGroups;if(r)for(let n=0;n{let{parseClassName:r,getClassGroupId:n,getConflictingClassGroupIds:o,sortModifiers:i,postfixLookupClassGroupIds:a}=t,l=[],c=e.trim().split(ru),u="";for(let p=c.length-1;p>=0;p-=1){let d=c[p],{isExternal:f,modifiers:m,hasImportantModifier:x,baseClassName:b,maybePostfixModifierPosition:y}=r(d);if(f){u=d+(u.length>0?" "+u:u);continue}let w=!!y,_;if(w){let R=b.substring(0,y);_=n(R);let v=_&&a[_]?n(b):void 0;v&&v!==_&&(_=v,w=!1)}else _=n(b);if(!_){if(!w){u=d+(u.length>0?" "+u:u);continue}if(_=n(b),!_){u=d+(u.length>0?" "+u:u);continue}w=!1}let T=m.length===0?"":m.length===1?m[0]:i(m).join(":"),P=x?T+"!":T,z=P+_;if(l.indexOf(z)>-1)continue;l.push(z);let O=o(_,w);for(let R=0;R0?" "+u:u)}return u},ou=(...e)=>{let t=0,r,n,o="";for(;t{if(typeof e=="string")return e;let t,r="";for(let n=0;n{let r,n,o,i,a=c=>{let u=t.reduce((p,d)=>d(p),e());return r=eu(u),n=r.cache.get,o=r.cache.set,i=l,l(c)},l=c=>{let u=n(c);if(u)return u;let p=nu(c,r);return o(c,p),p};return i=a,(...c)=>i(ou(...c))},iu=[],K=e=>{let t=r=>r[e]||iu;return t.isThemeGetter=!0,t},Is=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ps=/^\((?:(\w[\w-]*):)?(.+)\)$/i,au=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,lu=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,cu=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,uu=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,fu=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,du=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Ye=e=>au.test(e),F=e=>!!e&&!Number.isNaN(Number(e)),Te=e=>!!e&&Number.isInteger(Number(e)),Sn=e=>e.endsWith("%")&&F(e.slice(0,-1)),He=e=>lu.test(e),As=()=>!0,pu=e=>cu.test(e)&&!uu.test(e),En=()=>!1,mu=e=>fu.test(e),hu=e=>du.test(e),gu=e=>!k(e)&&!S(e),xu=e=>e.startsWith("@container")&&(e[10]==="/"&&e[11]!==void 0||e[11]==="s"&&e[16]!==void 0&&e.startsWith("-size/",10)||e[11]==="n"&&e[18]!==void 0&&e.startsWith("-normal/",10)),bu=e=>Ke(e,Ls,En),k=e=>Is.test(e),it=e=>Ke(e,Os,pu),Rs=e=>Ke(e,Su,F),vu=e=>Ke(e,Fs,As),yu=e=>Ke(e,Ds,En),Cs=e=>Ke(e,Ms,En),_u=e=>Ke(e,zs,hu),vr=e=>Ke(e,Hs,mu),S=e=>Ps.test(e),Pt=e=>at(e,Os),wu=e=>at(e,Ds),ks=e=>at(e,Ms),Ru=e=>at(e,Ls),Cu=e=>at(e,zs),yr=e=>at(e,Hs,!0),ku=e=>at(e,Fs,!0),Ke=(e,t,r)=>{let n=Is.exec(e);return n?n[1]?t(n[1]):r(n[2]):!1},at=(e,t,r=!1)=>{let n=Ps.exec(e);return n?n[1]?t(n[1]):r:!1},Ms=e=>e==="position"||e==="percentage",zs=e=>e==="image"||e==="url",Ls=e=>e==="length"||e==="size"||e==="bg-size",Os=e=>e==="length",Su=e=>e==="number",Ds=e=>e==="family-name",Fs=e=>e==="number"||e==="weight",Hs=e=>e==="shadow";var Tu=()=>{let e=K("color"),t=K("font"),r=K("text"),n=K("font-weight"),o=K("tracking"),i=K("leading"),a=K("breakpoint"),l=K("container"),c=K("spacing"),u=K("radius"),p=K("shadow"),d=K("inset-shadow"),f=K("text-shadow"),m=K("drop-shadow"),x=K("blur"),b=K("perspective"),y=K("aspect"),w=K("ease"),_=K("animate"),T=()=>["auto","avoid","all","avoid-page","page","left","right","column"],P=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],z=()=>[...P(),S,k],O=()=>["auto","hidden","clip","visible","scroll"],R=()=>["auto","contain","none"],v=()=>[S,k,c],C=()=>[Ye,"full","auto",...v()],H=()=>[Te,"none","subgrid",S,k],q=()=>["auto",{span:["full",Te,S,k]},Te,S,k],Y=()=>[Te,"auto",S,k],be=()=>["auto","min","max","fr",S,k],Me=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],we=()=>["start","end","center","stretch","center-safe","end-safe"],ie=()=>["auto",...v()],V=()=>[Ye,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...v()],ln=()=>[Ye,"screen","full","dvw","lvw","svw","min","max","fit",...v()],cn=()=>[Ye,"screen","full","lh","dvh","lvh","svh","min","max","fit",...v()],I=()=>[e,S,k],Ho=()=>[...P(),ks,Cs,{position:[S,k]}],Bo=()=>["no-repeat",{repeat:["","x","y","space","round"]}],$o=()=>["auto","cover","contain",Ru,bu,{size:[S,k]}],un=()=>[Sn,Pt,it],le=()=>["","none","full",u,S,k],ce=()=>["",F,Pt,it],nr=()=>["solid","dashed","dotted","double"],qo=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],te=()=>[F,Sn,ks,Cs],Go=()=>["","none",x,S,k],or=()=>["none",F,S,k],sr=()=>["none",F,S,k],fn=()=>[F,S,k],ir=()=>[Ye,"full",...v()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[He],breakpoint:[He],color:[As],container:[He],"drop-shadow":[He],ease:["in","out","in-out"],font:[gu],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[He],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[He],shadow:[He],spacing:["px",F],text:[He],"text-shadow":[He],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",Ye,k,S,y]}],container:["container"],"container-type":[{"@container":["","normal","size",S,k]}],"container-named":[xu],columns:[{columns:[F,k,S,l]}],"break-after":[{"break-after":T()}],"break-before":[{"break-before":T()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:z()}],overflow:[{overflow:O()}],"overflow-x":[{"overflow-x":O()}],"overflow-y":[{"overflow-y":O()}],overscroll:[{overscroll:R()}],"overscroll-x":[{"overscroll-x":R()}],"overscroll-y":[{"overscroll-y":R()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:C()}],"inset-x":[{"inset-x":C()}],"inset-y":[{"inset-y":C()}],start:[{"inset-s":C(),start:C()}],end:[{"inset-e":C(),end:C()}],"inset-bs":[{"inset-bs":C()}],"inset-be":[{"inset-be":C()}],top:[{top:C()}],right:[{right:C()}],bottom:[{bottom:C()}],left:[{left:C()}],visibility:["visible","invisible","collapse"],z:[{z:[Te,"auto",S,k]}],basis:[{basis:[Ye,"full","auto",l,...v()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[F,Ye,"auto","initial","none",k]}],grow:[{grow:["",F,S,k]}],shrink:[{shrink:["",F,S,k]}],order:[{order:[Te,"first","last","none",S,k]}],"grid-cols":[{"grid-cols":H()}],"col-start-end":[{col:q()}],"col-start":[{"col-start":Y()}],"col-end":[{"col-end":Y()}],"grid-rows":[{"grid-rows":H()}],"row-start-end":[{row:q()}],"row-start":[{"row-start":Y()}],"row-end":[{"row-end":Y()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":be()}],"auto-rows":[{"auto-rows":be()}],gap:[{gap:v()}],"gap-x":[{"gap-x":v()}],"gap-y":[{"gap-y":v()}],"justify-content":[{justify:[...Me(),"normal"]}],"justify-items":[{"justify-items":[...we(),"normal"]}],"justify-self":[{"justify-self":["auto",...we()]}],"align-content":[{content:["normal",...Me()]}],"align-items":[{items:[...we(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...we(),{baseline:["","last"]}]}],"place-content":[{"place-content":Me()}],"place-items":[{"place-items":[...we(),"baseline"]}],"place-self":[{"place-self":["auto",...we()]}],p:[{p:v()}],px:[{px:v()}],py:[{py:v()}],ps:[{ps:v()}],pe:[{pe:v()}],pbs:[{pbs:v()}],pbe:[{pbe:v()}],pt:[{pt:v()}],pr:[{pr:v()}],pb:[{pb:v()}],pl:[{pl:v()}],m:[{m:ie()}],mx:[{mx:ie()}],my:[{my:ie()}],ms:[{ms:ie()}],me:[{me:ie()}],mbs:[{mbs:ie()}],mbe:[{mbe:ie()}],mt:[{mt:ie()}],mr:[{mr:ie()}],mb:[{mb:ie()}],ml:[{ml:ie()}],"space-x":[{"space-x":v()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":v()}],"space-y-reverse":["space-y-reverse"],size:[{size:V()}],"inline-size":[{inline:["auto",...ln()]}],"min-inline-size":[{"min-inline":["auto",...ln()]}],"max-inline-size":[{"max-inline":["none",...ln()]}],"block-size":[{block:["auto",...cn()]}],"min-block-size":[{"min-block":["auto",...cn()]}],"max-block-size":[{"max-block":["none",...cn()]}],w:[{w:[l,"screen",...V()]}],"min-w":[{"min-w":[l,"screen","none",...V()]}],"max-w":[{"max-w":[l,"screen","none","prose",{screen:[a]},...V()]}],h:[{h:["screen","lh",...V()]}],"min-h":[{"min-h":["screen","lh","none",...V()]}],"max-h":[{"max-h":["screen","lh",...V()]}],"font-size":[{text:["base",r,Pt,it]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[n,ku,vu]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",Sn,k]}],"font-family":[{font:[wu,yu,t]}],"font-features":[{"font-features":[k]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[o,S,k]}],"line-clamp":[{"line-clamp":[F,"none",S,Rs]}],leading:[{leading:[i,...v()]}],"list-image":[{"list-image":["none",S,k]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",S,k]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:I()}],"text-color":[{text:I()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...nr(),"wavy"]}],"text-decoration-thickness":[{decoration:[F,"from-font","auto",S,it]}],"text-decoration-color":[{decoration:I()}],"underline-offset":[{"underline-offset":[F,"auto",S,k]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:v()}],"tab-size":[{tab:[Te,S,k]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",S,k]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",S,k]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:Ho()}],"bg-repeat":[{bg:Bo()}],"bg-size":[{bg:$o()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Te,S,k],radial:["",S,k],conic:[Te,S,k]},Cu,_u]}],"bg-color":[{bg:I()}],"gradient-from-pos":[{from:un()}],"gradient-via-pos":[{via:un()}],"gradient-to-pos":[{to:un()}],"gradient-from":[{from:I()}],"gradient-via":[{via:I()}],"gradient-to":[{to:I()}],rounded:[{rounded:le()}],"rounded-s":[{"rounded-s":le()}],"rounded-e":[{"rounded-e":le()}],"rounded-t":[{"rounded-t":le()}],"rounded-r":[{"rounded-r":le()}],"rounded-b":[{"rounded-b":le()}],"rounded-l":[{"rounded-l":le()}],"rounded-ss":[{"rounded-ss":le()}],"rounded-se":[{"rounded-se":le()}],"rounded-ee":[{"rounded-ee":le()}],"rounded-es":[{"rounded-es":le()}],"rounded-tl":[{"rounded-tl":le()}],"rounded-tr":[{"rounded-tr":le()}],"rounded-br":[{"rounded-br":le()}],"rounded-bl":[{"rounded-bl":le()}],"border-w":[{border:ce()}],"border-w-x":[{"border-x":ce()}],"border-w-y":[{"border-y":ce()}],"border-w-s":[{"border-s":ce()}],"border-w-e":[{"border-e":ce()}],"border-w-bs":[{"border-bs":ce()}],"border-w-be":[{"border-be":ce()}],"border-w-t":[{"border-t":ce()}],"border-w-r":[{"border-r":ce()}],"border-w-b":[{"border-b":ce()}],"border-w-l":[{"border-l":ce()}],"divide-x":[{"divide-x":ce()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":ce()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...nr(),"hidden","none"]}],"divide-style":[{divide:[...nr(),"hidden","none"]}],"border-color":[{border:I()}],"border-color-x":[{"border-x":I()}],"border-color-y":[{"border-y":I()}],"border-color-s":[{"border-s":I()}],"border-color-e":[{"border-e":I()}],"border-color-bs":[{"border-bs":I()}],"border-color-be":[{"border-be":I()}],"border-color-t":[{"border-t":I()}],"border-color-r":[{"border-r":I()}],"border-color-b":[{"border-b":I()}],"border-color-l":[{"border-l":I()}],"divide-color":[{divide:I()}],"outline-style":[{outline:[...nr(),"none","hidden"]}],"outline-offset":[{"outline-offset":[F,S,k]}],"outline-w":[{outline:["",F,Pt,it]}],"outline-color":[{outline:I()}],shadow:[{shadow:["","none",p,yr,vr]}],"shadow-color":[{shadow:I()}],"inset-shadow":[{"inset-shadow":["none",d,yr,vr]}],"inset-shadow-color":[{"inset-shadow":I()}],"ring-w":[{ring:ce()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:I()}],"ring-offset-w":[{"ring-offset":[F,it]}],"ring-offset-color":[{"ring-offset":I()}],"inset-ring-w":[{"inset-ring":ce()}],"inset-ring-color":[{"inset-ring":I()}],"text-shadow":[{"text-shadow":["none",f,yr,vr]}],"text-shadow-color":[{"text-shadow":I()}],opacity:[{opacity:[F,S,k]}],"mix-blend":[{"mix-blend":[...qo(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":qo()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[F]}],"mask-image-linear-from-pos":[{"mask-linear-from":te()}],"mask-image-linear-to-pos":[{"mask-linear-to":te()}],"mask-image-linear-from-color":[{"mask-linear-from":I()}],"mask-image-linear-to-color":[{"mask-linear-to":I()}],"mask-image-t-from-pos":[{"mask-t-from":te()}],"mask-image-t-to-pos":[{"mask-t-to":te()}],"mask-image-t-from-color":[{"mask-t-from":I()}],"mask-image-t-to-color":[{"mask-t-to":I()}],"mask-image-r-from-pos":[{"mask-r-from":te()}],"mask-image-r-to-pos":[{"mask-r-to":te()}],"mask-image-r-from-color":[{"mask-r-from":I()}],"mask-image-r-to-color":[{"mask-r-to":I()}],"mask-image-b-from-pos":[{"mask-b-from":te()}],"mask-image-b-to-pos":[{"mask-b-to":te()}],"mask-image-b-from-color":[{"mask-b-from":I()}],"mask-image-b-to-color":[{"mask-b-to":I()}],"mask-image-l-from-pos":[{"mask-l-from":te()}],"mask-image-l-to-pos":[{"mask-l-to":te()}],"mask-image-l-from-color":[{"mask-l-from":I()}],"mask-image-l-to-color":[{"mask-l-to":I()}],"mask-image-x-from-pos":[{"mask-x-from":te()}],"mask-image-x-to-pos":[{"mask-x-to":te()}],"mask-image-x-from-color":[{"mask-x-from":I()}],"mask-image-x-to-color":[{"mask-x-to":I()}],"mask-image-y-from-pos":[{"mask-y-from":te()}],"mask-image-y-to-pos":[{"mask-y-to":te()}],"mask-image-y-from-color":[{"mask-y-from":I()}],"mask-image-y-to-color":[{"mask-y-to":I()}],"mask-image-radial":[{"mask-radial":[S,k]}],"mask-image-radial-from-pos":[{"mask-radial-from":te()}],"mask-image-radial-to-pos":[{"mask-radial-to":te()}],"mask-image-radial-from-color":[{"mask-radial-from":I()}],"mask-image-radial-to-color":[{"mask-radial-to":I()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":P()}],"mask-image-conic-pos":[{"mask-conic":[F]}],"mask-image-conic-from-pos":[{"mask-conic-from":te()}],"mask-image-conic-to-pos":[{"mask-conic-to":te()}],"mask-image-conic-from-color":[{"mask-conic-from":I()}],"mask-image-conic-to-color":[{"mask-conic-to":I()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:Ho()}],"mask-repeat":[{mask:Bo()}],"mask-size":[{mask:$o()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",S,k]}],filter:[{filter:["","none",S,k]}],blur:[{blur:Go()}],brightness:[{brightness:[F,S,k]}],contrast:[{contrast:[F,S,k]}],"drop-shadow":[{"drop-shadow":["","none",m,yr,vr]}],"drop-shadow-color":[{"drop-shadow":I()}],grayscale:[{grayscale:["",F,S,k]}],"hue-rotate":[{"hue-rotate":[F,S,k]}],invert:[{invert:["",F,S,k]}],saturate:[{saturate:[F,S,k]}],sepia:[{sepia:["",F,S,k]}],"backdrop-filter":[{"backdrop-filter":["","none",S,k]}],"backdrop-blur":[{"backdrop-blur":Go()}],"backdrop-brightness":[{"backdrop-brightness":[F,S,k]}],"backdrop-contrast":[{"backdrop-contrast":[F,S,k]}],"backdrop-grayscale":[{"backdrop-grayscale":["",F,S,k]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[F,S,k]}],"backdrop-invert":[{"backdrop-invert":["",F,S,k]}],"backdrop-opacity":[{"backdrop-opacity":[F,S,k]}],"backdrop-saturate":[{"backdrop-saturate":[F,S,k]}],"backdrop-sepia":[{"backdrop-sepia":["",F,S,k]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":v()}],"border-spacing-x":[{"border-spacing-x":v()}],"border-spacing-y":[{"border-spacing-y":v()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",S,k]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[F,"initial",S,k]}],ease:[{ease:["linear","initial",w,S,k]}],delay:[{delay:[F,S,k]}],animate:[{animate:["none",_,S,k]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[b,S,k]}],"perspective-origin":[{"perspective-origin":z()}],rotate:[{rotate:or()}],"rotate-x":[{"rotate-x":or()}],"rotate-y":[{"rotate-y":or()}],"rotate-z":[{"rotate-z":or()}],scale:[{scale:sr()}],"scale-x":[{"scale-x":sr()}],"scale-y":[{"scale-y":sr()}],"scale-z":[{"scale-z":sr()}],"scale-3d":["scale-3d"],skew:[{skew:fn()}],"skew-x":[{"skew-x":fn()}],"skew-y":[{"skew-y":fn()}],transform:[{transform:[S,k,"","none","gpu","cpu"]}],"transform-origin":[{origin:z()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:ir()}],"translate-x":[{"translate-x":ir()}],"translate-y":[{"translate-y":ir()}],"translate-z":[{"translate-z":ir()}],"translate-none":["translate-none"],zoom:[{zoom:[Te,S,k]}],accent:[{accent:I()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:I()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",S,k]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":I()}],"scrollbar-track-color":[{"scrollbar-track":I()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":v()}],"scroll-mx":[{"scroll-mx":v()}],"scroll-my":[{"scroll-my":v()}],"scroll-ms":[{"scroll-ms":v()}],"scroll-me":[{"scroll-me":v()}],"scroll-mbs":[{"scroll-mbs":v()}],"scroll-mbe":[{"scroll-mbe":v()}],"scroll-mt":[{"scroll-mt":v()}],"scroll-mr":[{"scroll-mr":v()}],"scroll-mb":[{"scroll-mb":v()}],"scroll-ml":[{"scroll-ml":v()}],"scroll-p":[{"scroll-p":v()}],"scroll-px":[{"scroll-px":v()}],"scroll-py":[{"scroll-py":v()}],"scroll-ps":[{"scroll-ps":v()}],"scroll-pe":[{"scroll-pe":v()}],"scroll-pbs":[{"scroll-pbs":v()}],"scroll-pbe":[{"scroll-pbe":v()}],"scroll-pt":[{"scroll-pt":v()}],"scroll-pr":[{"scroll-pr":v()}],"scroll-pb":[{"scroll-pb":v()}],"scroll-pl":[{"scroll-pl":v()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",S,k]}],fill:[{fill:["none",...I()]}],"stroke-w":[{stroke:[F,Pt,it,Rs]}],stroke:[{stroke:["none",...I()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}};var Bs=su(Tu);function N(...e){return Bs(br(e))}var $s="govisual:theme";function Eu(){try{let e=localStorage.getItem($s);if(e==="light"||e==="dark")return e}catch{}return window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}function Nu(e){document.documentElement.classList.toggle("dark",e==="dark")}function qs(){let[e,t]=E(Eu);L(()=>{Nu(e);try{localStorage.setItem($s,e)}catch{}},[e]);let r=W(()=>{t(n=>n==="dark"?"light":"dark")},[]);return[e,r]}var Iu=0;function s(e,t,r,n,o,i){t||(t={});var a,l,c=t;if("ref"in c)for(l in c={},t)l=="ref"?a=t[l]:c[l]=t[l];var u={type:e,props:c,key:r,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Iu,__i:-1,__u:0,__source:o,__self:i};if(typeof e=="function"&&(a=e.defaultProps))for(l in a)c[l]===void 0&&(c[l]=a[l]);return A.vnode&&A.vnode(u),u}var Pu=[{id:"inbox",label:"Inbox",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("path",{d:"M22 12h-6l-2 3h-4l-2-3H2"}),s("path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"})]})},{id:"errors",label:"Errors",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"10"}),s("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),s("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]})},{id:"slow",label:"Slow",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"10"}),s("polyline",{points:"12 6 12 12 16 14"})]})},{id:"analytics",label:"Analytics",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("line",{x1:"18",y1:"20",x2:"18",y2:"10"}),s("line",{x1:"12",y1:"20",x2:"12",y2:"4"}),s("line",{x1:"6",y1:"20",x2:"6",y2:"14"})]})},{id:"agents",label:"Agents",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("path",{d:"M12 8V4H8"}),s("rect",{x:"4",y:"8",width:"16",height:"12",rx:"2"}),s("path",{d:"M2 14h2M20 14h2M15 13v2M9 13v2"})]})},{id:"environment",label:"Environment",icon:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),s("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),s("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]})}];function Gs({active:e,onChange:t,errorCount:r=0}){let[n,o]=qs();return s("aside",{class:"w-14 border-r border-zinc-200 bg-white flex flex-col items-center py-3 gap-1 shrink-0",children:[s("a",{href:"https://github.com/doganarif/GoVisual",target:"_blank",rel:"noopener noreferrer",title:"GoVisual on GitHub",class:"w-8 h-8 rounded bg-zinc-900 text-white flex items-center justify-center text-sm font-bold mb-4",children:"G"}),Pu.map(i=>{let a=e===i.id;return s("button",{onClick:()=>t(i.id),title:i.label,class:N("w-9 h-9 rounded-md flex items-center justify-center relative",a?"bg-zinc-100 text-zinc-900":"text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"),children:[i.icon,i.id==="errors"&&r>0&&s("span",{class:"absolute -top-0.5 -right-0.5 min-w-[16px] h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-medium flex items-center justify-center",children:r>99?"99+":r})]},i.id)}),s("div",{class:"flex-1"}),s("button",{onClick:o,title:n==="dark"?"Switch to light theme":"Switch to dark theme",class:"w-9 h-9 rounded-md hover:bg-zinc-100 flex items-center justify-center text-zinc-500",children:n==="dark"?s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("circle",{cx:"12",cy:"12",r:"5"}),s("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),s("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),s("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),s("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),s("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),s("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),s("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),s("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})]}):s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:s("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})})}),s("a",{href:"https://github.com/doganarif/GoVisual",target:"_blank",rel:"noopener noreferrer",title:"View source",class:"w-9 h-9 rounded-md hover:bg-zinc-100 flex items-center justify-center text-zinc-500",children:s("svg",{class:"w-4 h-4",viewBox:"0 0 24 24",fill:"currentColor",children:s("path",{d:"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.387.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"})})})]})}var Au={GET:"text-blue-700",POST:"text-emerald-700",PUT:"text-amber-700",PATCH:"text-amber-700",DELETE:"text-red-700",HEAD:"text-zinc-500",OPTIONS:"text-zinc-500"},Mu=e=>e>=200&&e<300?"bg-emerald-50 text-emerald-700":e>=300&&e<400?"bg-amber-50 text-amber-700":e>=400&&e<500?"bg-orange-50 text-orange-700":e>=500?"bg-red-50 text-red-700":"bg-zinc-100 text-zinc-700";function zu(e){let t=new Date(e);if(isNaN(t.getTime()))return"";let r=new Date,n=t.getFullYear()===r.getFullYear()&&t.getMonth()===r.getMonth()&&t.getDate()===r.getDate(),o=t.getHours().toString().padStart(2,"0"),i=t.getMinutes().toString().padStart(2,"0");return n?`Today, ${o}:${i}`:t.toLocaleString()}function Vs({title:e,subtitle:t,requests:r,selectedId:n,onSelect:o,statusFilter:i,onStatusFilterChange:a,search:l,onSearchChange:c,live:u}){let p=$(()=>{let f=[],m="";for(let x of r){let b=zu(x.Timestamp);b!==m?(f.push({label:b,items:[x]}),m=b):f[f.length-1].items.push(x)}return f},[r]),d=f=>{let m=new Set(i);m.has(f)?m.delete(f):m.add(f),a(m)};return s("aside",{class:"w-[340px] border-r border-zinc-200 bg-white flex flex-col shrink-0",children:[s("div",{class:"px-4 py-3 border-b border-zinc-200",children:[s("div",{class:"flex items-center justify-between mb-2",children:[s("h2",{class:"text-sm font-semibold tracking-tight",children:e}),s("span",{class:"text-[11px] text-zinc-500 font-mono",children:r.length})]}),t&&s("p",{class:"text-[11px] text-zinc-500 mb-2 -mt-1",children:t}),s("input",{value:l,onInput:f=>c(f.target.value),placeholder:"Filter by path...",class:"w-full text-sm px-2.5 py-1.5 bg-zinc-50 border border-zinc-200 rounded-md focus:outline-none focus:ring-2 focus:ring-zinc-900/10 placeholder:text-zinc-400"}),s("div",{class:"flex items-center gap-1.5 flex-wrap mt-2",children:["2xx","3xx","4xx","5xx"].map(f=>{let m=i.has(f);return s("button",{onClick:()=>d(f),class:N("text-[11px] px-2 py-0.5 rounded-full ring-1",m?f==="2xx"?"bg-emerald-50 text-emerald-700 ring-emerald-600/10":f==="3xx"?"bg-amber-50 text-amber-700 ring-amber-600/10":f==="4xx"?"bg-orange-50 text-orange-700 ring-orange-600/10":"bg-red-50 text-red-700 ring-red-600/10":"bg-zinc-50 text-zinc-500 ring-zinc-200"),children:f},f)})})]}),s("div",{class:"flex-1 overflow-auto",children:p.length===0?s("div",{class:"px-4 py-10 text-center text-xs text-zinc-500",children:"No matching requests yet."}):p.map(f=>s(h,{children:[s("div",{class:"px-4 py-1.5 text-[10px] uppercase tracking-wide text-zinc-500 bg-zinc-50/50 sticky top-0",children:f.label}),f.items.map(m=>{let x=m.ID===n;return s("button",{onClick:()=>o(m),class:N("w-full text-left px-4 py-2.5 border-b border-zinc-100",x?"bg-zinc-50 border-l-2 border-l-zinc-900":"hover:bg-zinc-50 border-l-2 border-l-transparent"),children:[s("div",{class:"flex items-center justify-between mb-0.5",children:[s("span",{class:"flex items-center gap-2 min-w-0",children:[s("span",{class:N("text-[10px] font-semibold shrink-0",Au[m.Method]||"text-zinc-700"),children:m.Method}),s("span",{class:"text-[10px] text-zinc-400",children:"\xB7"}),s("span",{class:N("text-[10px] font-mono px-1.5 py-0.5 rounded shrink-0",Mu(m.StatusCode)),children:m.StatusCode})]}),s("span",{class:"text-[11px] text-zinc-500 font-mono",children:Lu(m.Duration)})]}),s("div",{class:"text-sm font-mono truncate text-zinc-900",children:m.Path})]},m.ID)})]},f.label))}),s("div",{class:"border-t border-zinc-200 px-3 py-2 text-[11px] text-zinc-500 flex items-center justify-between",children:[s("span",{children:[r.length," requests"]}),s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:N("w-1.5 h-1.5 rounded-full",u?"bg-emerald-500 animate-pulse":"bg-zinc-300")}),u?"Live":"Idle"]})]})]})}function Lu(e){return e<1?"<1ms":e<1e3?`${e}ms`:`${(e/1e3).toFixed(2)}s`}var ht=class extends Map{constructor(t,r=Fu){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),t!=null)for(let[n,o]of t)this.set(n,o)}get(t){return super.get(Us(this,t))}has(t){return super.has(Us(this,t))}set(t,r){return super.set(Ou(this,t),r)}delete(t){return super.delete(Du(this,t))}};function Us({_intern:e,_key:t},r){let n=t(r);return e.has(n)?e.get(n):r}function Ou({_intern:e,_key:t},r){let n=t(r);return e.has(n)?e.get(n):(e.set(n,r),r)}function Du({_intern:e,_key:t},r){let n=t(r);return e.has(n)&&(r=e.get(n),e.delete(n)),r}function Fu(e){return e!==null&&typeof e=="object"?e.valueOf():e}var Hu={value:()=>{}};function Ws(){for(var e=0,t=arguments.length,r={},n;e=0&&(n=r.slice(o+1),r=r.slice(0,o)),r&&!t.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}_r.prototype=Ws.prototype={constructor:_r,on:function(e,t){var r=this._,n=Bu(e+"",r),o,i=-1,a=n.length;if(arguments.length<2){for(;++i0)for(var r=new Array(o),n=0,o,i;n=0&&(t=e.slice(0,r))!=="xmlns"&&(e=e.slice(r+1)),In.hasOwnProperty(t)?{space:In[t],local:e}:e}function qu(e){return function(){var t=this.ownerDocument,r=this.namespaceURI;return r===wr&&t.documentElement.namespaceURI===wr?t.createElement(e):t.createElementNS(r,e)}}function Gu(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Rr(e){var t=Be(e);return(t.local?Gu:qu)(t)}function Vu(){}function lt(e){return e==null?Vu:function(){return this.querySelector(e)}}function Xs(e){typeof e!="function"&&(e=lt(e));for(var t=this._groups,r=t.length,n=new Array(r),o=0;o=T&&(T=_+1);!(z=y[T])&&++T=0;)(a=n[o])&&(i&&a.compareDocumentPosition(i)^4&&i.parentNode.insertBefore(a,i),i=a);return this}function ii(e){e||(e=nf);function t(d,f){return d&&f?e(d.__data__,f.__data__):!d-!f}for(var r=this._groups,n=r.length,o=new Array(n),i=0;it?1:e>=t?0:NaN}function ai(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function li(){return Array.from(this)}function ci(){for(var e=this._groups,t=0,r=e.length;t1?this.each((t==null?ff:typeof t=="function"?pf:df)(e,t,r??"")):Qe(this.node(),e)}function Qe(e,t){return e.style.getPropertyValue(t)||Sr(e).getComputedStyle(e,null).getPropertyValue(t)}function mf(e){return function(){delete this[e]}}function hf(e,t){return function(){this[e]=t}}function gf(e,t){return function(){var r=t.apply(this,arguments);r==null?delete this[e]:this[e]=r}}function hi(e,t){return arguments.length>1?this.each((t==null?mf:typeof t=="function"?gf:hf)(e,t)):this.node()[e]}function gi(e){return e.trim().split(/^|\s+/)}function An(e){return e.classList||new xi(e)}function xi(e){this._node=e,this._names=gi(e.getAttribute("class")||"")}xi.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function bi(e,t){for(var r=An(e),n=-1,o=t.length;++n=0&&(r=t.slice(n+1),t=t.slice(0,n)),{type:t,name:r}})}function zf(e){return function(){var t=this.__on;if(t){for(var r=0,n=-1,o=t.length,i;r>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?Er(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?Er(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=Bf.exec(e))?new fe(t[1],t[2],t[3],1):(t=$f.exec(e))?new fe(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=qf.exec(e))?Er(t[1],t[2],t[3],t[4]):(t=Gf.exec(e))?Er(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=Vf.exec(e))?$i(t[1],t[2]/100,t[3]/100,1):(t=Uf.exec(e))?$i(t[1],t[2]/100,t[3]/100,t[4]):Li.hasOwnProperty(e)?Fi(Li[e]):e==="transparent"?new fe(NaN,NaN,NaN,0):null}function Fi(e){return new fe(e>>16&255,e>>8&255,e&255,1)}function Er(e,t,r,n){return n<=0&&(e=t=r=NaN),new fe(e,t,r,n)}function Xf(e){return e instanceof Dt||(e=Je(e)),e?(e=e.rgb(),new fe(e.r,e.g,e.b,e.opacity)):new fe}function xt(e,t,r,n){return arguments.length===1?Xf(e):new fe(e,t,r,n??1)}function fe(e,t,r,n){this.r=+e,this.g=+t,this.b=+r,this.opacity=+n}Tr(fe,xt,Ln(Dt,{brighter(e){return e=e==null?Ir:Math.pow(Ir,e),new fe(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Lt:Math.pow(Lt,e),new fe(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new fe(ut(this.r),ut(this.g),ut(this.b),Pr(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Hi,formatHex:Hi,formatHex8:Yf,formatRgb:Bi,toString:Bi}));function Hi(){return`#${ct(this.r)}${ct(this.g)}${ct(this.b)}`}function Yf(){return`#${ct(this.r)}${ct(this.g)}${ct(this.b)}${ct((isNaN(this.opacity)?1:this.opacity)*255)}`}function Bi(){let e=Pr(this.opacity);return`${e===1?"rgb(":"rgba("}${ut(this.r)}, ${ut(this.g)}, ${ut(this.b)}${e===1?")":`, ${e})`}`}function Pr(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function ut(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function ct(e){return e=ut(e),(e<16?"0":"")+e.toString(16)}function $i(e,t,r,n){return n<=0?e=t=r=NaN:r<=0||r>=1?e=t=NaN:t<=0&&(e=NaN),new ve(e,t,r,n)}function Gi(e){if(e instanceof ve)return new ve(e.h,e.s,e.l,e.opacity);if(e instanceof Dt||(e=Je(e)),!e)return new ve;if(e instanceof ve)return e;e=e.rgb();var t=e.r/255,r=e.g/255,n=e.b/255,o=Math.min(t,r,n),i=Math.max(t,r,n),a=NaN,l=i-o,c=(i+o)/2;return l?(t===i?a=(r-n)/l+(r0&&c<1?0:a,new ve(a,l,c,e.opacity)}function Vi(e,t,r,n){return arguments.length===1?Gi(e):new ve(e,t,r,n??1)}function ve(e,t,r,n){this.h=+e,this.s=+t,this.l=+r,this.opacity=+n}Tr(ve,Vi,Ln(Dt,{brighter(e){return e=e==null?Ir:Math.pow(Ir,e),new ve(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Lt:Math.pow(Lt,e),new ve(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*t,o=2*r-n;return new fe(On(e>=240?e-240:e+120,o,n),On(e,o,n),On(e<120?e+240:e-120,o,n),this.opacity)},clamp(){return new ve(qi(this.h),Nr(this.s),Nr(this.l),Pr(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=Pr(this.opacity);return`${e===1?"hsl(":"hsla("}${qi(this.h)}, ${Nr(this.s)*100}%, ${Nr(this.l)*100}%${e===1?")":`, ${e})`}`}}));function qi(e){return e=(e||0)%360,e<0?e+360:e}function Nr(e){return Math.max(0,Math.min(1,e||0))}function On(e,t,r){return(e<60?t+(r-t)*e/60:e<180?r:e<240?t+(r-t)*(240-e)/60:t)*255}function Dn(e,t,r,n,o){var i=e*e,a=i*e;return((1-3*e+3*i-a)*t+(4-6*i+3*a)*r+(1+3*e+3*i-3*a)*n+a*o)/6}function Ui(e){var t=e.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,t-1):Math.floor(r*t),o=e[n],i=e[n+1],a=n>0?e[n-1]:2*o-i,l=n()=>e;function Kf(e,t){return function(r){return e+r*t}}function Qf(e,t,r){return e=Math.pow(e,r),t=Math.pow(t,r)-e,r=1/r,function(n){return Math.pow(e+n*t,r)}}function Wi(e){return(e=+e)==1?Ar:function(t,r){return r-t?Qf(t,r,e):Fn(isNaN(t)?r:t)}}function Ar(e,t){var r=t-e;return r?Kf(e,r):Fn(isNaN(e)?t:e)}var Mr=(function e(t){var r=Wi(t);function n(o,i){var a=r((o=xt(o)).r,(i=xt(i)).r),l=r(o.g,i.g),c=r(o.b,i.b),u=Ar(o.opacity,i.opacity);return function(p){return o.r=a(p),o.g=l(p),o.b=c(p),o.opacity=u(p),o+""}}return n.gamma=e,n})(1);function Xi(e){return function(t){var r=t.length,n=new Array(r),o=new Array(r),i=new Array(r),a,l;for(a=0;ar&&(i=t.slice(r,i),l[a]?l[a]+=i:l[++a]=i),(n=n[0])===(o=o[0])?l[a]?l[a]+=o:l[++a]=o:(l[++a]=null,c.push({i:a,x:me(n,o)})),r=Hn.lastIndex;return r180?p+=360:p-u>180&&(u+=360),f.push({i:d.push(o(d)+"rotate(",null,n)-2,x:me(u,p)})):p&&d.push(o(d)+"rotate("+p+n)}function l(u,p,d,f){u!==p?f.push({i:d.push(o(d)+"skewX(",null,n)-2,x:me(u,p)}):p&&d.push(o(d)+"skewX("+p+n)}function c(u,p,d,f,m,x){if(u!==d||p!==f){var b=m.push(o(m)+"scale(",null,",",null,")");x.push({i:b-4,x:me(u,d)},{i:b-2,x:me(p,f)})}else(d!==1||f!==1)&&m.push(o(m)+"scale("+d+","+f+")")}return function(u,p){var d=[],f=[];return u=e(u),p=e(p),i(u.translateX,u.translateY,p.translateX,p.translateY,d,f),a(u.rotate,p.rotate,d,f),l(u.skewX,p.skewX,d,f),c(u.scaleX,u.scaleY,p.scaleX,p.scaleY,d,f),u=p=null,function(m){for(var x=-1,b=f.length,y;++x=0&&e._call.call(void 0,t),e=e._next;--bt}function Zi(){ft=(Dr=$t.now())+Fr,bt=Ht=0;try{ra()}finally{bt=0,od(),ft=0}}function nd(){var e=$t.now(),t=e-Dr;t>ea&&(Fr-=t,Dr=e)}function od(){for(var e,t=Or,r,n=1/0;t;)t._call?(n>t._time&&(n=t._time),e=t,t=t._next):(r=t._next,t._next=null,t=e?e._next=r:Or=r);Bt=e,Un(n)}function Un(e){if(!bt){Ht&&(Ht=clearTimeout(Ht));var t=e-ft;t>24?(e<1/0&&(Ht=setTimeout(Zi,e-$t.now()-Fr)),Ft&&(Ft=clearInterval(Ft))):(Ft||(Dr=$t.now(),Ft=setInterval(nd,ea)),bt=1,ta(Zi))}}function Br(e,t,r){var n=new qt;return t=t==null?0:+t,n.restart(o=>{n.stop(),e(o+t)},t,r),n}var sd=Nn("start","end","cancel","interrupt"),id=[],sa=0,na=1,qr=2,$r=3,oa=4,Gr=5,Vt=6;function Ze(e,t,r,n,o,i){var a=e.__transition;if(!a)e.__transition={};else if(r in a)return;ad(e,r,{name:t,index:n,group:o,on:sd,tween:id,time:i.time,delay:i.delay,duration:i.duration,ease:i.ease,timer:null,state:sa})}function Ut(e,t){var r=Q(e,t);if(r.state>sa)throw new Error("too late; already scheduled");return r}function oe(e,t){var r=Q(e,t);if(r.state>$r)throw new Error("too late; already running");return r}function Q(e,t){var r=e.__transition;if(!r||!(r=r[t]))throw new Error("transition not found");return r}function ad(e,t,r){var n=e.__transition,o;n[t]=r,r.timer=Hr(i,0,r.time);function i(u){r.state=na,r.timer.restart(a,r.delay,r.time),r.delay<=u&&a(u-r.delay)}function a(u){var p,d,f,m;if(r.state!==na)return c();for(p in n)if(m=n[p],m.name===r.name){if(m.state===$r)return Br(a);m.state===oa?(m.state=Vt,m.timer.stop(),m.on.call("interrupt",e,e.__data__,m.index,m.group),delete n[p]):+pqr&&n.state=0&&(t=t.slice(0,r)),!t||t==="start"})}function Td(e,t,r){var n,o,i=Sd(t)?Ut:oe;return function(){var a=i(this,e),l=a.on;l!==n&&(o=(n=l).copy()).on(t,r),a.on=o}}function ga(e,t){var r=this._id;return arguments.length<2?Q(this.node(),r).on.on(e):this.each(Td(r,e,t))}function Ed(e){return function(){var t=this.parentNode;for(var r in this.__transition)if(+r!==e)return;t&&t.removeChild(this)}}function xa(){return this.on("end.remove",Ed(this._id))}function ba(e){var t=this._name,r=this._id;typeof e!="function"&&(e=lt(e));for(var n=this._groups,o=n.length,i=new Array(o),a=0;a=0;)t+=r[n].value;e.value=t}function Pa(){return this.eachAfter(Vd)}function Aa(e,t){let r=-1;for(let n of this)e.call(t,n,++r,this);return this}function Ma(e,t){for(var r=this,n=[r],o,i,a=-1;r=n.pop();)if(e.call(t,r,++a,this),o=r.children)for(i=o.length-1;i>=0;--i)n.push(o[i]);return this}function za(e,t){for(var r=this,n=[r],o=[],i,a,l,c=-1;r=n.pop();)if(o.push(r),i=r.children)for(a=0,l=i.length;a=0;)r+=n[o].value;t.value=r})}function Da(e){return this.eachBefore(function(t){t.children&&t.children.sort(e)})}function Fa(e){for(var t=this,r=Ud(t,e),n=[t];t!==r;)t=t.parent,n.push(t);for(var o=n.length;e!==r;)n.splice(o,0,e),e=e.parent;return n}function Ud(e,t){if(e===t)return e;var r=e.ancestors(),n=t.ancestors(),o=null;for(e=r.pop(),t=n.pop();e===t;)o=e,e=r.pop(),t=n.pop();return o}function Ha(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t}function Ba(){return Array.from(this)}function $a(){var e=[];return this.eachBefore(function(t){t.children||e.push(t)}),e}function qa(){var e=this,t=[];return e.each(function(r){r!==e&&t.push({source:r.parent,target:r})}),t}function*Ga(){var e=this,t,r=[e],n,o,i;do for(t=r.reverse(),r=[];e=t.pop();)if(yield e,n=e.children)for(o=0,i=n.length;o=0;--l)o.push(i=a[l]=new jt(a[l])),i.parent=n,i.depth=n.depth+1;return r.eachBefore(Kd)}function jd(){return yt(this).eachBefore(Yd)}function Wd(e){return e.children}function Xd(e){return Array.isArray(e)?e[1]:null}function Yd(e){e.data.value!==void 0&&(e.value=e.data.value),e.data=e.data.data}function Kd(e){var t=0;do e.height=t;while((e=e.parent)&&e.height<++t)}function jt(e){this.data=e,this.depth=this.height=0,this.parent=null}jt.prototype=yt.prototype={constructor:jt,count:Pa,each:Aa,eachAfter:za,eachBefore:Ma,find:La,sum:Oa,sort:Da,path:Fa,ancestors:Ha,descendants:Ba,leaves:$a,links:qa,copy:jd,[Symbol.iterator]:Ga};function Va(e){e.x0=Math.round(e.x0),e.y0=Math.round(e.y0),e.x1=Math.round(e.x1),e.y1=Math.round(e.y1)}function Ua(e,t,r,n,o){for(var i=e.children,a,l=-1,c=i.length,u=e.value&&(n-t)/e.value;++l{if(!e||!n.current)return;let i=zn(n.current);i.selectAll("*").remove();let a=20,l=r||400,c=yt(e).sum(m=>m.value||0).sort((m,x)=>(x.value||0)-(m.value||0)),p=Wn().size([t,l]).padding(1).round(!0)(c),d=Wt(Yn),f=i.selectAll("g").data(p.descendants()).join("g").attr("transform",m=>`translate(${m.x0},${m.depth*a})`);f.append("rect").attr("x",0).attr("width",m=>Math.max(0,m.x1-m.x0)).attr("height",a-1).attr("fill",m=>m.depth?d(m.data.name):"#f3f4f6").style("stroke","#fff").style("cursor","pointer").on("mouseover",function(m,x){if(o.current){let b=((x.value||0)/(p.value||1)*100).toFixed(2);o.current.innerHTML=` +
${x.data.name}
+
${b}% of total
+
Value: ${x.value}
+ `,o.current.style.display="block",o.current.style.left=m.pageX+10+"px",o.current.style.top=m.pageY-28+"px"}}).on("mousemove",function(m){o.current&&(o.current.style.left=m.pageX+10+"px",o.current.style.top=m.pageY-28+"px")}).on("mouseout",function(){o.current&&(o.current.style.display="none")}),f.append("text").attr("x",4).attr("y",a/2).attr("dy","0.32em").text(m=>{let x=m.x1-m.x0;if(x<30)return"";let b=m.data.name,y=Math.floor(x/7);return b.length>y?b.substring(0,y-1)+"\u2026":b}).style("pointer-events","none").style("fill",m=>m.depth?"#fff":"#000").style("font-size","12px").style("font-family","monospace")},[e,t,r]),e?s("div",{className:"relative",children:[s("svg",{ref:n,width:t,height:r,style:{width:"100%",height:"auto"},viewBox:`0 0 ${t} ${r}`}),s("div",{ref:o,className:"absolute bg-gray-900 text-white p-2 rounded shadow-lg text-sm",style:{display:"none",pointerEvents:"none",zIndex:1e3,position:"fixed"}})]}):s("div",{className:"flex items-center justify-center h-64 text-muted-foreground",children:"No flame graph data available"})}function Qa({request:e,onReplay:t,onCompareAdd:r,comparePending:n}){let[o,i]=E("overview"),[a,l]=E(null),[c,u]=E(null),[p,d]=E(!1);if(L(()=>{if(!e?.ID){l(null),u(null),i("overview");return}let b=new AbortController;return i("overview"),l(null),u(null),d(!0),re.getMetrics(e.ID,b.signal).then(y=>l(y)).catch(y=>{if(y?.name!=="AbortError"){if(y instanceof Se&&(y.status===501||y.status===404)){l(null);return}console.error("Failed to load metrics:",y),l(null)}}).finally(()=>{b.signal.aborted||d(!1)}),()=>b.abort()},[e?.ID]),L(()=>{if(o!=="performance"||!e?.ID||c)return;let b=new AbortController;return re.getFlameGraph(e.ID,b.signal).then(u).catch(y=>{if(y?.name!=="AbortError"){if(y instanceof Se&&(y.status===404||y.status===501)){u(null);return}console.error("Failed to load flame graph:",y)}}),()=>b.abort()},[o,e?.ID]),!e)return s("main",{class:"flex-1 flex items-center justify-center bg-zinc-50/40",children:s("div",{class:"text-center max-w-sm",children:[s("div",{class:"w-12 h-12 mx-auto rounded-full bg-zinc-100 flex items-center justify-center mb-3 text-zinc-400",children:s("svg",{class:"w-5 h-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("polyline",{points:"9 11 12 14 22 4"}),s("path",{d:"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"})]})}),s("h3",{class:"text-sm font-medium text-zinc-900",children:"No request selected"}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Pick a request from the list to see headers, body, and timing."})]})});let f=!!a||!!e.PerformanceMetrics,m=a||e.PerformanceMetrics||null,x=!!e.Logs&&e.Logs.length>0;return s("main",{class:"flex-1 flex flex-col bg-white overflow-hidden",children:[s("div",{class:"px-6 py-4 border-b border-zinc-200 flex items-start justify-between gap-4",children:[s("div",{class:"min-w-0",children:[s("div",{class:"flex items-center gap-2 mb-1 flex-wrap",children:[s("span",{class:"text-xs font-semibold text-blue-700 px-1.5 py-0.5 rounded bg-blue-50",children:e.Method}),s("h2",{class:"text-base font-mono truncate",children:e.Path}),s("span",{class:N("text-xs font-mono px-1.5 py-0.5 rounded",Zd(e.StatusCode)),children:e.StatusCode})]}),s("div",{class:"text-xs text-zinc-500 flex items-center gap-3 flex-wrap",children:[s("span",{children:Xt(e.Duration)}),s("span",{children:"\xB7"}),s("span",{children:new Date(e.Timestamp).toLocaleString()}),s("span",{children:"\xB7"}),s("span",{class:"font-mono truncate",title:e.ID,children:[e.ID.slice(0,12),"\u2026"]})]})]}),s("div",{class:"flex items-center gap-1 shrink-0",children:[t&&s("button",{onClick:()=>t(e),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50",children:"Replay"}),r&&s("button",{onClick:()=>r(e),class:N("text-xs border rounded-md px-2.5 py-1.5",n?"bg-zinc-900 text-white border-zinc-900":"border-zinc-200 hover:bg-zinc-50"),children:n?"Selected":"Compare"}),s("button",{onClick:()=>tp(e),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50",title:"Copy as curl",children:"Copy cURL"})]})]}),s("div",{class:"px-6 border-b border-zinc-200",children:s("nav",{class:"flex gap-1 -mb-px",children:[["overview","headers","body","trace"].map(b=>s("button",{onClick:()=>i(b),class:N("px-3 py-2.5 text-sm border-b-2",o===b?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:Jd(b)},b)),x&&s("button",{onClick:()=>i("logs"),class:N("px-3 py-2.5 text-sm border-b-2",o==="logs"?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:["Logs \xB7 ",e.Logs.length]}),f&&s("button",{onClick:()=>i("performance"),class:N("px-3 py-2.5 text-sm border-b-2",o==="performance"?"border-zinc-900 text-zinc-900 font-medium":"border-transparent text-zinc-500 hover:text-zinc-900"),children:"Performance"})]})}),s("div",{class:"flex-1 overflow-auto p-6 space-y-5",children:[o==="overview"&&s(np,{request:e}),o==="headers"&&s(lp,{request:e}),o==="body"&&s(cp,{request:e}),o==="trace"&&s(up,{request:e,metrics:m}),o==="logs"&&s(op,{request:e}),o==="performance"&&s(fp,{metrics:m,flame:c,loading:p})]})]})}function Jd(e){switch(e){case"overview":return"Overview";case"headers":return"Headers";case"body":return"Body";case"trace":return"Trace";case"logs":return"Logs";case"performance":return"Performance"}}function Zd(e){return e>=200&&e<300?"bg-emerald-50 text-emerald-700":e>=300&&e<400?"bg-amber-50 text-amber-700":e>=400&&e<500?"bg-orange-50 text-orange-700":e>=500?"bg-red-50 text-red-700":"bg-zinc-100 text-zinc-700"}function Xt(e){return e<1?"<1ms":e<1e3?`${e}ms`:`${(e/1e3).toFixed(2)}s`}function Yr(e){if(!e)return"0ms";let t=e/1e6;return t<1?Math.round(e/1e3)+"\u03BCs":t<1e3?t.toFixed(2)+"ms":(t/1e3).toFixed(2)+"s"}function Jn(e){if(!e)return"0 B";let t=["B","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(1024));return Math.round(e/Math.pow(1024,r)*100)/100+" "+t[r]}function ep(e){if(!e)return"No body";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function tp(e){let t=`${window.location.origin}${e.RawPath||e.Path}${e.Query?"?"+e.Query:""}`,r=[`curl --request ${Xr(e.Method)} ${Xr(t)}`],n=rp(e.RequestHeaders||{});for(let[i,a]of Object.entries(n))for(let l of a)r.push(`-H ${Xr(`${i}: ${l}`)}`);e.RequestBody&&r.push(`--data-raw ${Xr(e.RequestBody)}`);let o=r.join(` \\ + `);navigator.clipboard.writeText(o).catch(()=>{})}function rp(e){let t=new Set(["connection","content-length","host","keep-alive","proxy-authenticate","proxy-authorization","proxy-connection","te","trailer","transfer-encoding","upgrade"]);for(let[r,n]of Object.entries(e))if(r.toLowerCase()==="connection")for(let o of n)for(let i of o.split(","))t.add(i.trim().toLowerCase());return Object.fromEntries(Object.entries(e).filter(([r])=>!t.has(r.toLowerCase())).map(([r,n])=>[r,n.filter(o=>o!=="[redacted by govisual]")]).filter(([,r])=>r.length>0))}function Xr(e){return`'${e.replace(/'/g,"'\\''")}'`}function np({request:e}){return s(h,{children:[s("section",{class:"grid grid-cols-4 gap-3",children:[s(Ge,{label:"Duration",value:Xt(e.Duration)}),s(Ge,{label:"Status",value:String(e.StatusCode)}),s(Ge,{label:"Response size",value:Jn(e.ResponseBody?.length||0)}),s(Ge,{label:"Query",value:e.Query||"\u2014",mono:!0})]}),s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:"Timeline"}),s("span",{class:"text-xs text-zinc-500",children:["total ",Xt(e.Duration)]})]}),s("div",{class:"p-4",children:s("div",{class:"flex items-center gap-3 text-xs font-mono",children:[s("span",{class:"w-24 text-zinc-500",children:"Duration"}),s("div",{class:"flex-1 h-1.5 bg-zinc-100 rounded-full overflow-hidden",children:s("div",{class:"h-1.5 bg-blue-400 rounded-full",style:{width:"100%"}})}),s("span",{class:"w-16 text-right",children:Xt(e.Duration)})]})})]}),(e.Error||e.PanicStack)&&s("section",{class:"border border-red-200 bg-red-50/50 rounded-lg p-4",children:[s("h3",{class:"text-sm font-medium text-red-800 mb-1",children:"Error"}),e.Error&&s("pre",{class:"text-xs font-mono text-red-700 whitespace-pre-wrap",children:e.Error}),e.PanicStack&&s("pre",{class:"text-[11px] font-mono text-red-600/80 whitespace-pre-wrap break-all mt-3 pt-3 border-t border-red-200 max-h-64 overflow-auto",children:e.PanicStack})]})]})}function op({request:e}){let t=e.Logs||[];return t.length===0?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["No log lines captured. Wrap your slog handler with"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.SlogHandler(...)"})," ","and log with the request context to capture per-request lines here."]}):s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:"Application logs"}),s("span",{class:"text-[11px] text-zinc-500",children:[t.length," lines"]})]}),s("div",{class:"divide-y divide-zinc-100",children:t.map((r,n)=>s(sp,{entry:r},n))})]})}function sp({entry:e}){let t=e.attrs?Object.entries(e.attrs):[],r=new Date(e.time),n=isNaN(r.getTime())?"":r.toLocaleTimeString("en-US",{hour12:!1})+"."+String(r.getMilliseconds()).padStart(3,"0");return s("div",{class:"px-4 py-2 text-xs",children:[s("div",{class:"flex items-baseline gap-2 font-mono",children:[n&&s("span",{class:"text-zinc-400 shrink-0",children:n}),s("span",{class:N("shrink-0 font-semibold",ap(e.level)),children:e.level}),s("span",{class:"text-zinc-900 break-all",children:e.message})]}),t.length>0&&s("div",{class:"mt-1 pl-4 flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] font-mono text-zinc-500",children:t.map(([o,i])=>s("span",{children:[s("span",{class:"text-zinc-400",children:[o,"="]}),s("span",{class:"text-zinc-700",children:ip(i)})]},o))})]})}function ip(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function ap(e){switch(e.toUpperCase()){case"ERROR":return"text-red-600";case"WARN":case"WARNING":return"text-amber-600";case"EVENT":return"text-blue-600";case"DEBUG":return"text-zinc-500";default:return"text-emerald-700"}}function Ge({label:e,value:t,mono:r}){return s("div",{class:"border border-zinc-200 rounded-lg p-3",children:[s("div",{class:"text-[11px] text-zinc-500 mb-1",children:e}),s("div",{class:N("font-semibold truncate",r?"text-sm font-mono":"text-lg"),children:t})]})}function lp({request:e}){return s(h,{children:[s(Ya,{title:"Request headers",headers:e.RequestHeaders}),s(Ya,{title:"Response headers",headers:e.ResponseHeaders})]})}function Ya({title:e,headers:t}){let r=Object.entries(t||{});return s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:e})}),r.length===0?s("div",{class:"px-4 py-3 text-xs text-zinc-500",children:"No headers"}):s("div",{class:"divide-y divide-zinc-100",children:r.map(([n,o])=>s("div",{class:"grid grid-cols-[180px_1fr] gap-3 px-4 py-2 text-xs font-mono",children:[s("div",{class:"text-zinc-500 truncate",title:n,children:n}),s("div",{class:"text-zinc-900 break-all",children:o.join(", ")})]},n))})]})}function cp({request:e}){return s(h,{children:[s(Ka,{title:"Request body",body:e.RequestBody}),s(Ka,{title:"Response body",body:e.ResponseBody})]})}function Ka({title:e,body:t}){return s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200 flex items-center justify-between",children:[s("h3",{class:"text-sm font-medium",children:e}),s("span",{class:"text-[11px] text-zinc-500",children:[t?.length||0," bytes"]})]}),s("pre",{class:"p-4 text-xs font-mono overflow-auto max-h-96 bg-zinc-50/50 rounded-b-lg whitespace-pre-wrap break-all",children:ep(t)})]})}function up({request:e,metrics:t}){let r=e.MiddlewareTrace||[],n=t?.sql_queries||[],o=t?.http_calls||[];return s(h,{children:[r.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"Middleware"})}),s("div",{class:"divide-y divide-zinc-100",children:r.map((i,a)=>s("div",{class:"px-4 py-2 flex items-center justify-between text-xs",children:[s("span",{class:"font-mono",children:i.name||`Middleware ${a+1}`}),s("span",{class:"text-zinc-500 font-mono",children:Xt(i.duration||0)})]},a))})]}),n.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:["SQL queries \xB7 ",n.length]})}),s("div",{class:"divide-y divide-zinc-100",children:n.slice(0,10).map((i,a)=>s("div",{class:"px-4 py-2 text-xs",children:[s("pre",{class:"font-mono text-emerald-700 whitespace-pre-wrap break-all",children:i.query}),s("div",{class:"text-zinc-500 mt-1 font-mono",children:[Yr(i.duration)," \xB7 ",i.rows," rows",i.error&&s("span",{class:"text-red-600 ml-2",children:["\xB7 ",i.error]})]})]},a))})]}),o.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:["HTTP calls \xB7 ",o.length]})}),s("div",{class:"divide-y divide-zinc-100",children:o.slice(0,10).map((i,a)=>s("div",{class:"px-4 py-2 text-xs flex items-center justify-between",children:[s("span",{class:"font-mono truncate",children:[s("span",{class:"text-blue-700 font-semibold mr-2",children:i.method}),i.url]}),s("span",{class:"text-zinc-500 font-mono shrink-0 ml-2",children:[i.status," \xB7 ",Yr(i.duration)]})]},a))})]}),r.length===0&&n.length===0&&o.length===0&&s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["No trace data captured for this request.",s("br",{}),"Enable profiling with ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.WithProfiling(true)"})," to see SQL queries and outbound HTTP calls."]})]})}function fp({metrics:e,flame:t,loading:r}){return r?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:"Loading metrics\u2026"}):e?s(h,{children:[s("section",{class:"grid grid-cols-5 gap-3",children:[s(Ge,{label:"Allocated during window",value:Jn(e.memory_total_alloc)}),s(Ge,{label:"Process heap",value:Jn(e.memory_alloc)}),s(Ge,{label:"Process goroutines",value:String(e.num_goroutines??0)}),s(Ge,{label:"GC runs",value:String(e.num_gc??0)}),s(Ge,{label:"GC pause",value:Yr(e.gc_pause_total)})]}),e.bottlenecks&&e.bottlenecks.length>0&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"Bottlenecks"})}),s("div",{class:"divide-y divide-zinc-100",children:e.bottlenecks.map((n,o)=>s("div",{class:"px-4 py-3",children:[s("div",{class:"flex items-center justify-between mb-1",children:[s("span",{class:"text-xs font-medium uppercase tracking-wide text-zinc-500",children:n.type}),s("span",{class:"text-xs font-mono text-zinc-700",children:[(n.impact*100).toFixed(1),"% \xB7 ",Yr(n.duration)]})]}),s("div",{class:"text-sm text-zinc-900",children:n.description}),n.suggestion&&s("div",{class:"text-xs text-zinc-500 mt-1",children:n.suggestion})]},o))})]}),t&&s("section",{class:"border border-zinc-200 rounded-lg",children:[s("header",{class:"px-4 py-2.5 border-b border-zinc-200",children:s("h3",{class:"text-sm font-medium",children:"CPU flame graph"})}),s("div",{class:"p-4 overflow-x-auto",children:s(Xa,{data:t,width:900,height:400})})]})]}):s("div",{class:"text-xs text-zinc-500 text-center py-8",children:["No retained profile exists for this request. Enable profiling with"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.WithProfiling(true)"})," ","and check the configured profile threshold and profile types."]})}function Ja(){let[e,t]=E([]),[r,n]=E(!0);return L(()=>{let o=!0,i=()=>{re.getAgentActivity().then(l=>{o&&(t(l||[]),n(!1))}).catch(()=>{o&&n(!1)})};i();let a=setInterval(i,3e3);return()=>{o=!1,clearInterval(a)}},[]),s("main",{class:"flex-1 flex flex-col bg-white overflow-hidden",children:[s("div",{class:"px-6 py-4 border-b border-zinc-200",children:[s("h2",{class:"text-base font-medium",children:"Agent activity"}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Recent MCP tool calls, newest first. Refreshes every 3s."})]}),s("div",{class:"flex-1 overflow-auto p-6",children:r?s("div",{class:"text-xs text-zinc-500 text-center py-8",children:"Loading\u2026"}):e.length===0?s(dp,{}):s("ul",{class:"border border-zinc-200 rounded-lg divide-y divide-zinc-100",children:e.map((o,i)=>s("li",{class:"px-4 py-3 text-xs",children:[s("div",{class:"flex items-baseline gap-2 flex-wrap",children:[s("span",{class:"text-zinc-400 font-mono shrink-0",children:pp(o.time)}),s("span",{class:N("px-1.5 py-0.5 rounded font-mono text-[11px]",o.mutating?"bg-amber-50 text-amber-700":"bg-blue-50 text-blue-700"),children:o.tool}),s("span",{class:"text-zinc-500 font-mono",children:mp(o.duration)}),o.error&&s("span",{class:"text-red-600 font-mono truncate",children:o.error})]}),o.args&&Object.keys(o.args).length>0&&s("div",{class:"mt-1 pl-4 flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] font-mono text-zinc-500",children:Object.entries(o.args).map(([a,l])=>s("span",{children:[s("span",{class:"text-zinc-400",children:[a,"="]}),s("span",{class:"text-zinc-700 break-all",children:l})]},a))})]},i))})})]})}function dp(){return s(h,{children:s("div",{class:"text-xs text-zinc-500 max-w-lg mx-auto text-center py-8",children:[s("p",{class:"mb-3",children:"No agent activity yet."}),s("p",{class:"mb-2",children:["Share a"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"store.NewActivityLog(200)"})," ","between"," ",s("code",{class:"font-mono bg-zinc-100 px-1 rounded",children:"govisual.Wrap"})," ","and the MCP handler:"]}),s("pre",{class:"text-left text-[11px] font-mono bg-zinc-50 border border-zinc-200 rounded p-3 overflow-x-auto",children:`log := store.NewActivityLog(200) app := govisual.Wrap(mux, govisual.WithStore(st), govisual.WithActivityLog(log), ) root.Handle("/mcp", gvmcp.Handler(st, gvmcp.WithActivityLog(log), -))`})]})})}function bd(e){let t=new Date(e);return isNaN(t.getTime())?"":t.toLocaleTimeString("en-US",{hour12:!1})+"."+String(t.getMilliseconds()).padStart(3,"0")}function vd(e){if(!e)return"0ms";let t=e/1e6;return t<1?Math.round(e/1e3)+"\u03BCs":t<1e3?t.toFixed(1)+"ms":(t/1e3).toFixed(2)+"s"}function Ma(e,t){for(var r in t)e[r]=t[r];return e}function $n(e,t){for(var r in e)if(r!=="__source"&&!(r in t))return!0;for(var n in t)if(n!=="__source"&&e[n]!==t[n])return!0;return!1}function qn(e,t){var r=t(),n=N({t:{__:r,u:t}}),o=n[0].t,i=n[1];return ke(function(){o.__=r,o.u=t,Bn(o)&&i({t:o})},[e,r,t]),I(function(){return Bn(o)&&i({t:o}),e(function(){Bn(o)&&i({t:o})})},[e]),r}function Bn(e){try{return!((t=e.__)===(r=e.u())&&(t!==0||1/t==1/r)||t!=t&&r!=r)}catch{return!0}var t,r}function Gn(e){e()}function Vn(e){return e}function Un(){return[!1,Gn]}var Wn=ke;function Lr(e,t){this.props=e,this.context=t}function Ia(e,t){function r(o){var i=this.props.ref;return i!=o.ref&&i&&(typeof i=="function"?i(null):i.current=null),t?!t(this.props,o)||i!=o.ref:$n(this.props,o)}function n(o){return this.shouldComponentUpdate=r,g(e,o)}return n.displayName="Memo("+(e.displayName||e.name)+")",n.__f=n.prototype.isReactComponent=!0,n.type=e,n}(Lr.prototype=new ue).isPureReactComponent=!0,Lr.prototype.shouldComponentUpdate=function(e,t){return $n(this.props,e)||$n(this.state,t)};var Ca=z.__b;z.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),Ca&&Ca(e)};var yd=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.forward_ref")||3911;function A(e){function t(r){var n=Ma({},r);return delete n.ref,e(n,r.ref||null)}return t.$$typeof=yd,t.render=e,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(e.displayName||e.name)+")",t}var ka=function(e,t){return e==null?null:he(he(e).map(t))},et={map:ka,forEach:ka,count:function(e){return e?he(e).length:0},only:function(e){var t=he(e);if(t.length!==1)throw"Children.only";return t[0]},toArray:he},_d=z.__e;z.__e=function(e,t,r,n){if(e.then){for(var o,i=t;i=i.__;)if((o=i.__c)&&o.__c)return t.__e==null&&(t.__e=r.__e,t.__k=r.__k),o.__c(e,t)}_d(e,t,r,n)};var Sa=z.unmount;function Pa(e,t,r){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach(function(n){typeof n.__c=="function"&&n.__c()}),e.__c.__H=null),(e=Ma({},e)).__c!=null&&(e.__c.__P===r&&(e.__c.__P=t),e.__c.__e=!0,e.__c=null),e.__k=e.__k&&e.__k.map(function(n){return Pa(n,t,r)})),e}function La(e,t,r){return e&&r&&(e.__v=null,e.__k=e.__k&&e.__k.map(function(n){return La(n,t,r)}),e.__c&&e.__c.__P===t&&(e.__e&&r.appendChild(e.__e),e.__c.__e=!0,e.__c.__P=r)),e}function Ht(){this.__u=0,this.o=null,this.__b=null}function Oa(e){var t=e.__&&e.__.__c;return t&&t.__a&&t.__a(e)}function Da(e){var t,r,n,o=null;function i(a){if(t||(t=e()).then(function(l){l&&(o=l.default||l),n=!0},function(l){r=l,n=!0}),r)throw r;if(!n)throw t;return o?g(o,a):null}return i.displayName="Lazy",i.__f=!0,i}function ft(){this.i=null,this.l=null}z.unmount=function(e){var t=e.__c;t&&(t.__z=!0),t&&t.__R&&t.__R(),t&&32&e.__u&&(e.type=null),Sa&&Sa(e)},(Ht.prototype=new ue).__c=function(e,t){var r=t.__c,n=this;n.o==null&&(n.o=[]),n.o.push(r);var o=Oa(n.__v),i=!1,a=function(){i||n.__z||(i=!0,r.__R=null,o?o(u):u())};r.__R=a;var l=r.__P;r.__P=null;var u=function(){if(!--n.__u){if(n.state.__a){var f=n.state.__a;n.__v.__k[0]=La(f,f.__c.__P,f.__c.__O)}var d;for(n.setState({__a:n.__b=null});d=n.o.pop();)d.__P=l,d.forceUpdate()}};n.__u++||32&t.__u||n.setState({__a:n.__b=n.__v.__k[0]}),e.then(a,a)},Ht.prototype.componentWillUnmount=function(){this.o=[]},Ht.prototype.render=function(e,t){var r=this.__v;if(!r.__m){for(var n=r;n.__;)n=n.__;n=n.__m||(n.__m=[0,0]),r.__m=[n[1]++,0]}if(this.__b){if(r.__k){var o=document.createElement("div"),i=r.__k[0].__c;r.__k[0]=Pa(this.__b,o,i.__O=i.__P)}this.__b=null}var a=t.__a&&g(m,null,e.fallback);return a&&(a.__u&=-33),[g(m,null,t.__a?null:e.children),a]};var Ta=function(e,t,r){if(++r[1]===r[0]&&e.l.delete(t),e.props.revealOrder&&(e.props.revealOrder[0]!=="t"||!e.l.size))for(r=e.i;r;){for(;r.length>3;)r.pop()();if(r[1]>>1,1),t.v.removeChild(o)}}}Ie(g(wd,{context:t.context},e.__v),t.h)}function Fa(e,t){var r=g(Rd,{__v:e,v:t});return r.containerInfo=t,r}(ft.prototype=new ue).__a=function(e){var t=this,r=Oa(t.__v),n=t.l.get(e);return n[0]++,function(o){var i=function(){t.props.revealOrder?(n.push(o),Ta(t,e,n)):o()};r?r(i):i()}},ft.prototype.render=function(e){this.i=null,this.l=new Map;var t=he(e.children);e.revealOrder&&e.revealOrder[0]==="b"&&t.reverse();for(var r=t.length;r--;)this.l.set(t[r],this.i=[1,0,this.i]);return e.children},ft.prototype.componentDidUpdate=ft.prototype.componentDidMount=function(){var e=this;this.l.forEach(function(t,r){Ta(e,r,t)})};var Ha=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.element")||60103,Cd=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,kd=/^on(Ani|Tra|Tou|BeforeInp|Compo)/,Sd=/[A-Z0-9]/g,Td=typeof document<"u",Nd=function(e){return(typeof Symbol<"u"&&typeof Symbol()=="symbol"?/fil|che|rad/:/fil|che|ra/).test(e)};function Ba(e,t,r){return t.__k==null&&(t.textContent=""),Ie(e,t),typeof r=="function"&&r(),e?e.__c:null}function $a(e,t,r){return an(e,t),typeof r=="function"&&r(),e?e.__c:null}ue.prototype.isReactComponent=!0,["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(e){Object.defineProperty(ue.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})});var Na=z.event;z.event=function(e){return Na&&(e=Na(e)),e.persist=function(){},e.isPropagationStopped=function(){return this.cancelBubble},e.isDefaultPrevented=function(){return this.defaultPrevented},e.nativeEvent=e};var Xn,Ed={configurable:!0,get:function(){return this.class}},Ea=z.vnode;z.vnode=function(e){typeof e.type=="string"&&function(t){var r=t.props,n=t.type,o={},i=n.indexOf("-")==-1;for(var a in r){var l=r[a];if(!(a==="value"&&"defaultValue"in r&&l==null||Td&&a==="children"&&n==="noscript"||a==="class"||a==="className")){var u=a.toLowerCase();a==="defaultValue"&&"value"in r&&r.value==null?a="value":a==="download"&&l===!0?l="":u==="translate"&&l==="no"?l=!1:u[0]==="o"&&u[1]==="n"?u==="ondoubleclick"?a="ondblclick":u!=="onchange"||n!=="input"&&n!=="textarea"||Nd(r.type)?u==="onfocus"?a="onfocusin":u==="onblur"?a="onfocusout":kd.test(a)&&(a=u):u=a="oninput":i&&Cd.test(a)?a=a.replace(Sd,"-$&").toLowerCase():l===null&&(l=void 0),u==="oninput"&&o[a=u]&&(a="oninputCapture"),o[a]=l}}n=="select"&&(o.multiple&&Array.isArray(o.value)&&(o.value=he(r.children).forEach(function(f){f.props.selected=o.value.indexOf(f.props.value)!=-1})),o.defaultValue!=null&&(o.value=he(r.children).forEach(function(f){f.props.selected=o.multiple?o.defaultValue.indexOf(f.props.value)!=-1:o.defaultValue==f.props.value}))),r.class&&!r.className?(o.class=r.class,Object.defineProperty(o,"className",Ed)):r.className&&(o.class=o.className=r.className),t.props=o}(e),e.$$typeof=Ha,Ea&&Ea(e)};var za=z.__r;z.__r=function(e){za&&za(e),Xn=e.__c};var Aa=z.diffed;z.diffed=function(e){Aa&&Aa(e);var t=e.props,r=e.__e;r!=null&&e.type==="textarea"&&"value"in t&&t.value!==r.value&&(r.value=t.value==null?"":t.value),Xn=null};var qa={ReactCurrentDispatcher:{current:{readContext:function(e){return Xn.__n[e.__c].props.value},useCallback:X,useContext:Le,useDebugValue:rr,useDeferredValue:Vn,useEffect:I,useId:nr,useImperativeHandle:tr,useInsertionEffect:Wn,useLayoutEffect:ke,useMemo:q,useReducer:Pe,useRef:F,useState:N,useSyncExternalStore:qn,useTransition:Un}}},zd="18.3.1";function Ga(e){return g.bind(null,e)}function ve(e){return!!e&&e.$$typeof===Ha}function Va(e){return ve(e)&&e.type===m}function Ua(e){return!!e&&typeof e.displayName=="string"&&e.displayName.indexOf("Memo(")==0}function Ge(e){return ve(e)?zo.apply(null,arguments):e}function Wa(e){return!!e.__k&&(Ie(null,e),!0)}function Xa(e){return e&&(e.base||e.nodeType===1&&e)||null}var ja=function(e,t){return e(t)},jn=function(e,t){var r=z.debounceRendering;z.debounceRendering=function(o){return o()};var n=e(t);return z.debounceRendering=r,n},Ya=ve,Ka={useState:N,useId:nr,useReducer:Pe,useEffect:I,useLayoutEffect:ke,useInsertionEffect:Wn,useTransition:Un,useDeferredValue:Vn,useSyncExternalStore:qn,startTransition:Gn,useRef:F,useImperativeHandle:tr,useMemo:q,useCallback:X,useContext:Le,useDebugValue:rr,version:"18.3.1",Children:et,render:Ba,hydrate:$a,unmountComponentAtNode:Wa,createPortal:Fa,createElement:g,createContext:Re,createFactory:Ga,cloneElement:Ge,createRef:er,Fragment:m,isValidElement:ve,isElement:Ya,isFragment:Va,isMemo:Ua,findDOMNode:Xa,Component:ue,PureComponent:Lr,memo:Ia,forwardRef:A,flushSync:jn,unstable_batchedUpdates:ja,StrictMode:m,Suspense:Ht,SuspenseList:ft,lazy:Da,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:qa};var Q=A(({className:e,...t},r)=>s("div",{ref:r,className:T("rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm",e),...t}));Q.displayName="Card";var J=A(({className:e,...t},r)=>s("div",{ref:r,className:T("flex flex-col space-y-1.5 p-6",e),...t}));J.displayName="CardHeader";var Z=A(({className:e,...t},r)=>s("div",{ref:r,className:T("text-2xl font-semibold leading-none tracking-tight",e),...t}));Z.displayName="CardTitle";var Bt=A(({className:e,...t},r)=>s("div",{ref:r,className:T("text-sm text-slate-500",e),...t}));Bt.displayName="CardDescription";var oe=A(({className:e,...t},r)=>s("div",{ref:r,className:T("p-6 pt-0",e),...t}));oe.displayName="CardContent";var Ad=A(({className:e,...t},r)=>s("div",{ref:r,className:T("flex items-center p-6 pt-0",e),...t}));Ad.displayName="CardFooter";var B={};Pl(B,{Children:()=>et,Component:()=>ue,Fragment:()=>m,PureComponent:()=>Lr,StrictMode:()=>m,Suspense:()=>Ht,SuspenseList:()=>ft,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:()=>qa,cloneElement:()=>Ge,createContext:()=>Re,createElement:()=>g,createFactory:()=>Ga,createPortal:()=>Fa,createRef:()=>er,default:()=>Ka,findDOMNode:()=>Xa,flushSync:()=>jn,forwardRef:()=>A,hydrate:()=>$a,isElement:()=>Ya,isFragment:()=>Va,isMemo:()=>Ua,isValidElement:()=>ve,lazy:()=>Da,memo:()=>Ia,render:()=>Ba,startTransition:()=>Gn,unmountComponentAtNode:()=>Wa,unstable_batchedUpdates:()=>ja,useCallback:()=>X,useContext:()=>Le,useDebugValue:()=>rr,useDeferredValue:()=>Vn,useEffect:()=>I,useErrorBoundary:()=>ql,useId:()=>nr,useImperativeHandle:()=>tr,useInsertionEffect:()=>Wn,useLayoutEffect:()=>ke,useMemo:()=>q,useReducer:()=>Pe,useRef:()=>F,useState:()=>N,useSyncExternalStore:()=>qn,useTransition:()=>Un,version:()=>zd});var Yn=A(({className:e,...t},r)=>s("div",{className:"relative w-full overflow-auto",children:s("table",{ref:r,className:T("w-full caption-bottom text-sm",e),...t})}));Yn.displayName="Table";var Kn=A(({className:e,...t},r)=>s("thead",{ref:r,className:T("[&_tr]:border-b",e),...t}));Kn.displayName="TableHeader";var Qn=A(({className:e,...t},r)=>s("tbody",{ref:r,className:T("[&_tr:last-child]:border-0",e),...t}));Qn.displayName="TableBody";var Md=A(({className:e,...t},r)=>s("tfoot",{ref:r,className:T("border-t bg-slate-100/50 font-medium [&>tr]:last:border-b-0 dark:bg-slate-800/50",e),...t}));Md.displayName="TableFooter";var Or=A(({className:e,...t},r)=>s("tr",{ref:r,className:T("border-b transition-colors hover:bg-slate-100/50 data-[state=selected]:bg-slate-100 dark:hover:bg-slate-800/50 dark:data-[state=selected]:bg-slate-800",e),...t}));Or.displayName="TableRow";var Dr=A(({className:e,...t},r)=>s("th",{ref:r,className:T("h-12 px-4 text-left align-middle font-medium text-slate-500 [&:has([role=checkbox])]:pr-0 dark:text-slate-400",e),...t}));Dr.displayName="TableHead";var Fr=A(({className:e,...t},r)=>s("td",{ref:r,className:T("p-4 align-middle [&:has([role=checkbox])]:pr-0",e),...t}));Fr.displayName="TableCell";var Id=A(({className:e,...t},r)=>s("caption",{ref:r,className:T("mt-4 text-sm text-slate-500 dark:text-slate-400",e),...t}));Id.displayName="TableCaption";function Qa(){let[e,t]=N({kind:"loading"});if(I(()=>{let i=new AbortController;return te.getSystemInfo(i.signal).then(a=>t({kind:"ready",info:a})).catch(a=>{if(a?.name!=="AbortError"){if(a instanceof ge&&a.isNotFound){t({kind:"disabled"});return}t({kind:"error",message:a instanceof Error?a.message:"Failed to load"})}}),()=>i.abort()},[]),e.kind==="loading")return s("div",{className:"text-sm text-muted-foreground",children:"Loading system information..."});if(e.kind==="disabled")return s(Q,{children:s(J,{children:[s(Z,{children:"System info is disabled"}),s(Bt,{children:["The ",s("code",{children:"/__viz/api/system-info"})," endpoint is off by default. Enable it on the server with"," ",s("code",{children:"govisual.WithSystemInfo(...)"}),", passing the env var allowlist you want exposed."]})]})});if(e.kind==="error")return s(Q,{className:"border-destructive/50 bg-destructive/5",children:s(J,{children:[s(Z,{children:"Failed to load system info"}),s(Bt,{className:"text-destructive",children:e.message})]})});let r=e.info,n=r.memoryTotal>0?r.memoryUsed/r.memoryTotal*100:0,o=Object.entries(r.envVars);return s("div",{className:"space-y-6",children:[s("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:[s(Q,{children:[s(J,{children:s(Z,{children:"Go Environment"})}),s(oe,{className:"space-y-2",children:[s(dt,{label:"Version",value:r.goVersion}),s(dt,{label:"GOOS",value:r.goos}),s(dt,{label:"GOARCH",value:r.goarch})]})]}),s(Q,{children:[s(J,{children:s(Z,{children:"System"})}),s(oe,{className:"space-y-2",children:[s(dt,{label:"Hostname",value:r.hostname}),s(dt,{label:"OS",value:r.goos}),s(dt,{label:"CPU Cores",value:String(r.cpuCores)})]})]}),s(Q,{children:[s(J,{children:s(Z,{children:"Memory Usage"})}),s(oe,{children:s("div",{className:"space-y-2",children:[s("div",{className:"w-full bg-gray-200 rounded-full h-2",children:s("div",{className:"bg-primary h-2 rounded-full transition-all duration-300",style:{width:`${Math.min(100,n)}%`}})}),s("div",{className:"flex justify-between text-sm",children:[s("span",{className:"text-muted-foreground",children:[r.memoryUsed,"MB / ",r.memoryTotal,"MB"]}),s("span",{className:"font-medium",children:[n.toFixed(1),"%"]})]})]})})]})]}),s(Q,{children:[s(J,{children:[s(Z,{children:"Environment Variables"}),s(Bt,{children:"Only variables explicitly allowlisted on the server are shown."})]}),s(oe,{children:o.length===0?s("p",{className:"text-sm text-muted-foreground",children:["No environment variables are exposed. Pass names to",s("code",{className:"mx-1",children:"WithSystemInfo(...)"}),"on the server to surface them here."]}):s("div",{className:"max-h-96 overflow-auto",children:s(Yn,{children:[s(Kn,{children:s(Or,{children:[s(Dr,{children:"Name"}),s(Dr,{children:"Value"})]})}),s(Qn,{children:o.map(([i,a])=>s(Or,{children:[s(Fr,{className:"font-mono text-sm",children:i}),s(Fr,{className:"font-mono text-sm text-muted-foreground break-all",children:a})]},i))})]})})})]})]})}function dt({label:e,value:t}){return s("div",{className:"flex justify-between",children:[s("span",{className:"text-sm text-muted-foreground",children:[e,":"]}),s("span",{className:"text-sm font-medium",children:t})]})}function Ja(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function Pd(...e){return t=>{let r=!1,n=e.map(o=>{let i=Ja(o,t);return!r&&typeof i=="function"&&(r=!0),i});if(r)return()=>{for(let o=0;o{let{children:o,...i}=r,a=null,l=!1,u=[];Za(o)&&typeof Hr=="function"&&(o=Hr(o._payload)),et.forEach(o,c=>{if(Hd(c)){l=!0;let h=c,x="child"in h.props?h.props.child:h.props.children;Za(x)&&typeof Hr=="function"&&(x=Hr(x._payload)),a=Od(h,x),u.push(a?.props?.children)}else u.push(c)}),a?a=Ge(a,void 0,u):!l&&et.count(o)===1&&ve(o)&&(a=o);let f=a?Fd(a):void 0,d=tt(n,f);if(!a){if(o||o===0)throw new Error(l?Gd(e):qd(e));return o}let p=Dd(i,a.props??{});return a.type!==m&&(p.ref=n?d:f),Ge(a,p)});return t.displayName=`${e}.Slot`,t}var el=pt("Slot"),Ld=Symbol.for("radix.slottable");var Od=(e,t)=>{if("child"in e.props){let r=e.props.child;return ve(r)?Ge(r,void 0,e.props.children(r.props.children)):null}return ve(t)?t:null};function Dd(e,t){let r={...t};for(let n in t){let o=e[n],i=t[n];/^on[A-Z]/.test(n)?o&&i?r[n]=(...l)=>{let u=i(...l);return o(...l),u}:o&&(r[n]=o):n==="style"?r[n]={...o,...i}:n==="className"&&(r[n]=[o,i].filter(Boolean).join(" "))}return{...e,...r}}function Fd(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,r=t&&"isReactWarning"in t&&t.isReactWarning;return r?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,r=t&&"isReactWarning"in t&&t.isReactWarning,r?e.props.ref:e.props.ref||e.ref)}function Hd(e){return ve(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Ld}var Bd=Symbol.for("react.lazy");function Za(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===Bd&&"_payload"in e&&$d(e._payload)}function $d(e){return typeof e=="object"&&e!==null&&"then"in e}var qd=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,Gd=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,Hr=B[" use ".trim().toString()];var tl=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,rl=or,Br=(e,t)=>r=>{var n;if(t?.variants==null)return rl(e,r?.class,r?.className);let{variants:o,defaultVariants:i}=t,a=Object.keys(o).map(f=>{let d=r?.[f],p=i?.[f];if(d===null)return null;let c=tl(d)||tl(p);return o[f][c]}),l=r&&Object.entries(r).reduce((f,d)=>{let[p,c]=d;return c===void 0||(f[p]=c),f},{}),u=t==null||(n=t.compoundVariants)===null||n===void 0?void 0:n.reduce((f,d)=>{let{class:p,className:c,...h}=d;return Object.entries(h).every(x=>{let[b,v]=x;return Array.isArray(v)?v.includes({...i,...l}[b]):{...i,...l}[b]===v})?[...f,p,c]:f},[]);return rl(e,a,u,r?.class,r?.className)};var Vd=Br("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",{variants:{variant:{default:"bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90",destructive:"bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90",outline:"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50",secondary:"bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",ghost:"hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50",link:"text-slate-900 underline-offset-4 hover:underline dark:text-slate-50"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),ye=A(({className:e,variant:t,size:r,asChild:n=!1,...o},i)=>s(n?el:"button",{className:T(Vd({variant:t,size:r,className:e})),ref:i,...o}));ye.displayName="Button";var r2=!!(typeof window<"u"&&window.document&&window.document.createElement);function pe(e,t,{checkForDefaultPrevented:r=!0}={}){return function(o){if(e?.(o),r===!1||!o.defaultPrevented)return t?.(o)}}function mt(e,t=[]){let r=[];function n(i,a){let l=Re(a);l.displayName=i+"Context";let u=r.length;r=[...r,a];let f=p=>{let{scope:c,children:h,...x}=p,b=c?.[e]?.[u]||l,v=q(()=>x,Object.values(x));return s(b.Provider,{value:v,children:h})};f.displayName=i+"Provider";function d(p,c){let h=c?.[e]?.[u]||l,x=Le(h);if(x)return x;if(a!==void 0)return a;throw new Error(`\`${p}\` must be used within \`${i}\``)}return[f,d]}let o=()=>{let i=r.map(a=>Re(a));return function(l){let u=l?.[e]||i;return q(()=>({[`__scope${e}`]:{...l,[e]:u}}),[l,u])}};return o.scopeName=e,[n,Ud(o,...t)]}function Ud(...e){let t=e[0];if(e.length===1)return t;let r=()=>{let n=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(i){let a=n.reduce((l,{useScope:u,scopeName:f})=>{let p=u(i)[`__scope${f}`];return{...l,...p}},{});return q(()=>({[`__scope${t.scopeName}`]:a}),[a])}};return r.scopeName=t.scopeName,r}function nl(e){let t=e+"CollectionProvider",[r,n]=mt(t),[o,i]=r(t,{collectionRef:{current:null},itemMap:new Map}),a=b=>{let{scope:v,children:w}=b,R=F(null),S=F(new Map).current;return s(o,{scope:v,itemMap:S,collectionRef:R,children:w})};a.displayName=t;let l=e+"CollectionSlot",u=pt(l),f=A((b,v)=>{let{scope:w,children:R}=b,S=i(l,w),P=tt(v,S.collectionRef);return s(u,{ref:P,children:R})});f.displayName=l;let d=e+"CollectionItemSlot",p="data-radix-collection-item",c=pt(d),h=A((b,v)=>{let{scope:w,children:R,...S}=b,P=F(null),y=tt(v,P),L=i(d,w);return I(()=>(L.itemMap.set(P,{ref:P,...S}),()=>void L.itemMap.delete(P))),s(c,{[p]:"",ref:y,children:R})});h.displayName=d;function x(b){let v=i(e+"CollectionConsumer",b);return X(()=>{let R=v.collectionRef.current;if(!R)return[];let S=Array.from(R.querySelectorAll(`[${p}]`));return Array.from(v.itemMap.values()).sort((L,D)=>S.indexOf(L.ref.current)-S.indexOf(D.ref.current))},[v.collectionRef,v.itemMap])}return[{Provider:a,Slot:f,ItemSlot:h},x,n]}var rt=globalThis?.document?ke:()=>{};var Wd=B[" useId ".trim().toString()]||(()=>{}),Xd=0;function $r(e){let[t,r]=N(Wd());return rt(()=>{e||r(n=>n??String(Xd++))},[e]),e||(t?`radix-${t}`:"")}var jd=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Ve=jd.reduce((e,t)=>{let r=pt(`Primitive.${t}`),n=A((o,i)=>{let{asChild:a,...l}=o,u=a?r:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),s(u,{...l,ref:i})});return n.displayName=`Primitive.${t}`,{...e,[t]:n}},{});function ol(e){let t=F(e);return I(()=>{t.current=e}),q(()=>(...r)=>t.current?.(...r),[])}var Yd=B[" useInsertionEffect ".trim().toString()]||rt;function qr({prop:e,defaultProp:t,onChange:r=()=>{},caller:n}){let[o,i,a]=Kd({defaultProp:t,onChange:r}),l=e!==void 0,u=l?e:o;{let d=F(e!==void 0);I(()=>{let p=d.current;p!==l&&console.warn(`${n} is changing from ${p?"controlled":"uncontrolled"} to ${l?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),d.current=l},[l,n])}let f=X(d=>{if(l){let p=Qd(d)?d(e):d;p!==e&&a.current?.(p)}else i(d)},[l,e,i,a]);return[u,f]}function Kd({defaultProp:e,onChange:t}){let[r,n]=N(e),o=F(r),i=F(t);return Yd(()=>{i.current=t},[t]),I(()=>{o.current!==r&&(i.current?.(r),o.current=r)},[r,o]),[r,n,i]}function Qd(e){return typeof e=="function"}var A2=Symbol("RADIX:SYNC_STATE");var Jd=Re(void 0);function Gr(e){let t=Le(Jd);return e||t||"ltr"}var Jn="rovingFocusGroup.onEntryFocus",Zd={bubbles:!1,cancelable:!0},$t="RovingFocusGroup",[Zn,sl,ep]=nl($t),[tp,eo]=mt($t,[ep]),[rp,np]=tp($t),il=A((e,t)=>s(Zn.Provider,{scope:e.__scopeRovingFocusGroup,children:s(Zn.Slot,{scope:e.__scopeRovingFocusGroup,children:s(op,{...e,ref:t})})}));il.displayName=$t;var op=A((e,t)=>{let{__scopeRovingFocusGroup:r,orientation:n,loop:o=!1,dir:i,currentTabStopId:a,defaultCurrentTabStopId:l,onCurrentTabStopIdChange:u,onEntryFocus:f,preventScrollOnEntryFocus:d=!1,...p}=e,c=F(null),h=tt(t,c),x=Gr(i),[b,v]=qr({prop:a,defaultProp:l??null,onChange:u,caller:$t}),[w,R]=N(!1),S=ol(f),P=sl(r),y=F(!1),[L,D]=N(0);return I(()=>{let _=c.current;if(_)return _.addEventListener(Jn,S),()=>_.removeEventListener(Jn,S)},[S]),s(rp,{scope:r,orientation:n,dir:x,loop:o,currentTabStopId:b,onItemFocus:X(_=>v(_),[v]),onItemShiftTab:X(()=>R(!0),[]),onFocusableItemAdd:X(()=>D(_=>_+1),[]),onFocusableItemRemove:X(()=>D(_=>_-1),[]),children:s(Ve.div,{tabIndex:w||L===0?-1:0,"data-orientation":n,...p,ref:h,style:{outline:"none",...e.style},onMouseDown:pe(e.onMouseDown,()=>{y.current=!0}),onFocus:pe(e.onFocus,_=>{let W=!y.current;if(_.target===_.currentTarget&&W&&!w){let re=new CustomEvent(Jn,Zd);if(_.currentTarget.dispatchEvent(re),!re.defaultPrevented){let M=P().filter(j=>j.focusable),V=M.find(j=>j.active),$=M.find(j=>j.id===b),ce=[V,$,...M].filter(Boolean).map(j=>j.ref.current);cl(ce,d)}}y.current=!1}),onBlur:pe(e.onBlur,()=>R(!1))})})}),al="RovingFocusGroupItem",ll=A((e,t)=>{let{__scopeRovingFocusGroup:r,focusable:n=!0,active:o=!1,tabStopId:i,children:a,...l}=e,u=$r(),f=i||u,d=np(al,r),p=d.currentTabStopId===f,c=sl(r),{onFocusableItemAdd:h,onFocusableItemRemove:x,currentTabStopId:b}=d;return I(()=>{if(n)return h(),()=>x()},[n,h,x]),s(Zn.ItemSlot,{scope:r,id:f,focusable:n,active:o,children:s(Ve.span,{tabIndex:p?0:-1,"data-orientation":d.orientation,...l,ref:t,onMouseDown:pe(e.onMouseDown,v=>{n?d.onItemFocus(f):v.preventDefault()}),onFocus:pe(e.onFocus,()=>d.onItemFocus(f)),onKeyDown:pe(e.onKeyDown,v=>{if(v.key==="Tab"&&v.shiftKey){d.onItemShiftTab();return}if(v.target!==v.currentTarget)return;let w=ap(v,d.orientation,d.dir);if(w!==void 0){if(v.metaKey||v.ctrlKey||v.altKey||v.shiftKey)return;v.preventDefault();let S=c().filter(P=>P.focusable).map(P=>P.ref.current);if(w==="last")S.reverse();else if(w==="prev"||w==="next"){w==="prev"&&S.reverse();let P=S.indexOf(v.currentTarget);S=d.loop?lp(S,P+1):S.slice(P+1)}setTimeout(()=>cl(S))}}),children:typeof a=="function"?a({isCurrentTabStop:p,hasTabStop:b!=null}):a})})});ll.displayName=al;var sp={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function ip(e,t){return t!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}function ap(e,t,r){let n=ip(e.key,r);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(n))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(n)))return sp[n]}function cl(e,t=!1){let r=document.activeElement;for(let n of e)if(n===r||(n.focus({preventScroll:t}),document.activeElement!==r))return}function lp(e,t){return e.map((r,n)=>e[(t+n)%e.length])}var ul=il,fl=ll;function up(e,t){return Pe((r,n)=>t[r][n]??r,e)}var to=e=>{let{present:t,children:r}=e,n=fp(t),o=typeof r=="function"?r({present:n.isPresent}):et.only(r),i=dp(n.ref,pp(o));return typeof r=="function"||n.isPresent?Ge(o,{ref:i}):null};to.displayName="Presence";function fp(e){let[t,r]=N(),n=F(null),o=F(e),i=F("none"),a=e?"mounted":"unmounted",[l,u]=up(a,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return I(()=>{let f=Vr(n.current);i.current=l==="mounted"?f:"none"},[l]),rt(()=>{let f=n.current,d=o.current;if(d!==e){let c=i.current,h=Vr(f);e?u("MOUNT"):h==="none"||f?.display==="none"?u("UNMOUNT"):u(d&&c!==h?"ANIMATION_OUT":"UNMOUNT"),o.current=e}},[e,u]),rt(()=>{if(t){let f,d=t.ownerDocument.defaultView??window,p=h=>{let b=Vr(n.current).includes(CSS.escape(h.animationName));if(h.target===t&&b&&(u("ANIMATION_END"),!o.current)){let v=t.style.animationFillMode;t.style.animationFillMode="forwards",f=d.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=v)})}},c=h=>{h.target===t&&(i.current=Vr(n.current))};return t.addEventListener("animationstart",c),t.addEventListener("animationcancel",p),t.addEventListener("animationend",p),()=>{d.clearTimeout(f),t.removeEventListener("animationstart",c),t.removeEventListener("animationcancel",p),t.removeEventListener("animationend",p)}}else u("ANIMATION_END")},[t,u]),{isPresent:["mounted","unmountSuspended"].includes(l),ref:X(f=>{n.current=f?getComputedStyle(f):null,r(f)},[])}}function dl(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function dp(...e){let t=F(e);return t.current=e,X(r=>{let n=t.current,o=!1,i=n.map(a=>{let l=dl(a,r);return!o&&typeof l=="function"&&(o=!0),l});if(o)return()=>{for(let a=0;a{let{__scopeTabs:r,value:n,onValueChange:o,defaultValue:i,orientation:a="horizontal",dir:l,activationMode:u="automatic",...f}=e,d=Gr(l),[p,c]=qr({prop:n,onChange:o,defaultProp:i??"",caller:Ur});return s(hp,{scope:r,baseId:$r(),value:p,onValueChange:c,orientation:a,dir:d,activationMode:u,children:s(Ve.div,{dir:d,"data-orientation":a,...f,ref:t})})});ml.displayName=Ur;var hl="TabsList",gl=A((e,t)=>{let{__scopeTabs:r,loop:n=!0,...o}=e,i=ro(hl,r),a=pl(r);return s(ul,{asChild:!0,...a,orientation:i.orientation,dir:i.dir,loop:n,children:s(Ve.div,{role:"tablist","aria-orientation":i.orientation,...o,ref:t})})});gl.displayName=hl;var xl="TabsTrigger",bl=A((e,t)=>{let{__scopeTabs:r,value:n,disabled:o=!1,...i}=e,a=ro(xl,r),l=pl(r),u=_l(a.baseId,n),f=wl(a.baseId,n),d=n===a.value;return s(fl,{asChild:!0,...l,focusable:!o,active:d,children:s(Ve.button,{type:"button",role:"tab","aria-selected":d,"aria-controls":f,"data-state":d?"active":"inactive","data-disabled":o?"":void 0,disabled:o,id:u,...i,ref:t,onMouseDown:pe(e.onMouseDown,p=>{!o&&p.button===0&&p.ctrlKey===!1?a.onValueChange(n):p.preventDefault()}),onKeyDown:pe(e.onKeyDown,p=>{[" ","Enter"].includes(p.key)&&a.onValueChange(n)}),onFocus:pe(e.onFocus,()=>{let p=a.activationMode!=="manual";!d&&!o&&p&&a.onValueChange(n)})})})});bl.displayName=xl;var vl="TabsContent",yl=A((e,t)=>{let{__scopeTabs:r,value:n,forceMount:o,children:i,...a}=e,l=ro(vl,r),u=_l(l.baseId,n),f=wl(l.baseId,n),d=n===l.value,p=F(d);return I(()=>{let c=requestAnimationFrame(()=>p.current=!1);return()=>cancelAnimationFrame(c)},[]),s(to,{present:o||d,children:({present:c})=>s(Ve.div,{"data-state":d?"active":"inactive","data-orientation":l.orientation,role:"tabpanel","aria-labelledby":u,hidden:!c,id:f,tabIndex:0,...a,ref:t,style:{...e.style,animationDuration:p.current?"0s":void 0},children:c&&i})})});yl.displayName=vl;function _l(e,t){return`${e}-trigger-${t}`}function wl(e,t){return`${e}-content-${t}`}var Rl=ml,no=gl,oo=bl,so=yl;var Wr=Rl,qt=A(({className:e,...t},r)=>s(no,{ref:r,className:T("inline-flex h-10 items-center justify-center rounded-md bg-slate-100 p-1 text-slate-500 dark:bg-slate-800 dark:text-slate-400",e),...t}));qt.displayName=no.displayName;var _e=A(({className:e,...t},r)=>s(oo,{ref:r,className:T("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-slate-950 data-[state=active]:shadow-sm dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300 dark:data-[state=active]:bg-slate-950 dark:data-[state=active]:text-slate-50",e),...t}));_e.displayName=oo.displayName;var we=A(({className:e,...t},r)=>s(so,{ref:r,className:T("mt-2 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",e),...t}));we.displayName=so.displayName;function Cl({requestIds:e,allRequests:t,onClose:r}){let[n,o]=N([]),[i,a]=N(!0);I(()=>{l()},[e]);let l=async()=>{try{a(!0);let c=await te.compareRequests(e);o(c)}catch(c){console.error("Failed to load comparison data:",c);let h=t.filter(x=>e.includes(x.ID));o(h)}finally{a(!1)}};if(i)return s("div",{className:"flex items-center justify-center h-64",children:s("div",{className:"text-muted-foreground",children:"Loading comparison..."})});if(n.length===0)return s("div",{className:"flex flex-col items-center justify-center h-64",children:[s("div",{className:"text-muted-foreground mb-4",children:"No requests found for comparison"}),s(ye,{onClick:r,children:"Close"})]});let u=c=>c<1e3?`${c}ms`:`${(c/1e3).toFixed(2)}s`,f=c=>new Date(c).toLocaleString(),d=c=>c>=200&&c<300?"text-green-600":c>=300&&c<400?"text-blue-600":c>=400&&c<500?"text-yellow-600":c>=500?"text-red-600":"text-gray-600",p=(c,h)=>{let x=h.every(b=>JSON.stringify(b)===JSON.stringify(h[0]));return s("tr",{children:[s("td",{className:"font-medium text-sm p-2 border-b",children:c}),h.map((b,v)=>s("td",{className:T("text-sm p-2 border-b",!x&&"bg-yellow-50 dark:bg-yellow-900/10"),children:typeof b=="object"?JSON.stringify(b,null,2):b},v))]})};return s("div",{className:"space-y-4",children:[s("div",{className:"flex items-center justify-between mb-4",children:[s("h2",{className:"text-2xl font-bold",children:"Request Comparison"}),s(ye,{onClick:r,variant:"outline",children:"Close"})]}),s(Wr,{defaultValue:"overview",className:"w-full",children:[s(qt,{className:"grid w-full grid-cols-4",children:[s(_e,{value:"overview",children:"Overview"}),s(_e,{value:"headers",children:"Headers"}),s(_e,{value:"body",children:"Body"}),s(_e,{value:"performance",children:"Performance"})]}),s(we,{value:"overview",className:"space-y-4",children:s(Q,{children:[s(J,{children:s(Z,{children:"Request Details"})}),s(oe,{children:s("div",{className:"overflow-x-auto",children:s("table",{className:"w-full",children:[s("thead",{children:s("tr",{children:[s("th",{className:"text-left p-2 border-b",children:"Property"}),n.map((c,h)=>s("th",{className:"text-left p-2 border-b",children:["Request ",h+1]},h))]})}),s("tbody",{children:[p("Method",n.map(c=>c.Method)),p("Path",n.map(c=>c.Path)),p("Query",n.map(c=>c.Query||"None")),p("Status",n.map(c=>s("span",{className:d(c.StatusCode),children:c.StatusCode}))),p("Duration",n.map(c=>u(c.Duration))),p("Timestamp",n.map(c=>f(c.Timestamp)))]})]})})})]})}),s(we,{value:"headers",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s(Q,{children:[s(J,{children:s(Z,{children:"Request Headers"})}),s(oe,{children:s("div",{className:"space-y-4",children:n.map((c,h)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",h+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2 text-xs font-mono",children:Object.entries(c.RequestHeaders||{}).map(([x,b])=>s("div",{children:[s("span",{className:"text-blue-600",children:[x,":"]})," ",Array.isArray(b)?b.join(", "):b]},x))})]},h))})})]}),s(Q,{children:[s(J,{children:s(Z,{children:"Response Headers"})}),s(oe,{children:s("div",{className:"space-y-4",children:n.map((c,h)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",h+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2 text-xs font-mono",children:Object.entries(c.ResponseHeaders||{}).map(([x,b])=>s("div",{children:[s("span",{className:"text-green-600",children:[x,":"]})," ",Array.isArray(b)?b.join(", "):b]},x))})]},h))})})]})]})}),s(we,{value:"body",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s(Q,{children:[s(J,{children:s(Z,{children:"Request Body"})}),s(oe,{children:s("div",{className:"space-y-4",children:n.map((c,h)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",h+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2",children:s("pre",{className:"text-xs overflow-x-auto",children:c.RequestBody||"No request body"})})]},h))})})]}),s(Q,{children:[s(J,{children:s(Z,{children:"Response Body"})}),s(oe,{children:s("div",{className:"space-y-4",children:n.map((c,h)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",h+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2",children:s("pre",{className:"text-xs overflow-x-auto max-h-48 overflow-y-auto",children:c.ResponseBody||"No response body"})})]},h))})})]})]})}),s(we,{value:"performance",className:"space-y-4",children:s(Q,{children:[s(J,{children:s(Z,{children:"Performance Metrics"})}),s(oe,{children:n.some(c=>c.PerformanceMetrics)?s("div",{className:"overflow-x-auto",children:s("table",{className:"w-full",children:[s("thead",{children:s("tr",{children:[s("th",{className:"text-left p-2 border-b",children:"Metric"}),n.map((c,h)=>s("th",{className:"text-left p-2 border-b",children:["Request ",h+1]},h))]})}),s("tbody",{children:[p("CPU Time",n.map(c=>c.PerformanceMetrics?`${c.PerformanceMetrics.cpu_time}ms`:"N/A")),p("Memory Allocated",n.map(c=>c.PerformanceMetrics?`${(c.PerformanceMetrics.memory_alloc/1024/1024).toFixed(2)}MB`:"N/A")),p("Goroutines",n.map(c=>c.PerformanceMetrics?.num_goroutines||"N/A")),p("GC Runs",n.map(c=>c.PerformanceMetrics?.num_gc||"N/A")),p("GC Pause",n.map(c=>c.PerformanceMetrics?`${c.PerformanceMetrics.gc_pause_total}ms`:"N/A"))]})]})}):s("div",{className:"text-center text-muted-foreground py-8",children:"No performance metrics available for these requests"})})]})})]})]})}var xp=Br("inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-slate-900 text-slate-50 hover:bg-slate-900/80",secondary:"border-transparent bg-slate-100 text-slate-900 hover:bg-slate-100/80",destructive:"border-transparent bg-red-500 text-slate-50 hover:bg-red-500/80",outline:"text-slate-950"}},defaultVariants:{variant:"default"}});function kl({className:e,variant:t,...r}){return s("div",{className:T(xp({variant:t}),e),...r})}var Gt=A(({className:e,type:t,...r},n)=>s("input",{type:t,className:T("flex h-10 w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-base ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-slate-950 placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-slate-800 dark:bg-slate-950 dark:ring-offset-slate-950 dark:file:text-slate-50 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",e),ref:n,...r}));Gt.displayName="Input";function Sl({request:e,onClose:t}){let[r,n]=N(e.Path+(e.Query?`?${e.Query}`:"")),[o,i]=N(e.Method),[a,l]=N(()=>{let y={};return e.RequestHeaders&&Object.entries(e.RequestHeaders).forEach(([L,D])=>{y[L]=Array.isArray(D)?D[0]:D}),y}),[u,f]=N(e.RequestBody||""),[d,p]=N(!1),[c,h]=N(null),[x,b]=N(null),v=async()=>{try{p(!0),b(null);let y=r;if(!y.startsWith("http")){let D=e.RequestHeaders?.Host;y="http://"+(D?Array.isArray(D)?D[0]:D:"localhost")+y}let L=await te.replayRequest({requestId:e.ID,url:y,method:o,headers:a,body:u});h(L)}catch(y){y instanceof ge?y.isNotFound?b("Replay is disabled on the server. Enable it with govisual.WithReplayEnabled(true)."):y.isUnauthorized?b(`Replay rejected (${y.status}): ${y.body||"unauthorized"}`):b(`Replay failed (${y.status}): ${y.body||y.message}`):b(y instanceof Error?y.message:"Failed to replay request")}finally{p(!1)}},w=(y,L)=>{l(D=>({...D,[y]:L}))},R=()=>{let y=prompt("Enter header name:");y&&l(L=>({...L,[y]:""}))},S=y=>{l(L=>{let D={...L};return delete D[y],D})},P=y=>y>=200&&y<300?"bg-green-100 text-green-800":y>=300&&y<400?"bg-blue-100 text-blue-800":y>=400&&y<500?"bg-yellow-100 text-yellow-800":y>=500?"bg-red-100 text-red-800":"bg-gray-100 text-gray-800";return s("div",{className:"space-y-4",children:[s("div",{className:"flex items-center justify-between mb-4",children:[s("h2",{className:"text-2xl font-bold",children:"Replay Request"}),s(ye,{onClick:t,variant:"outline",children:"Close"})]}),s(Q,{children:[s(J,{children:s(Z,{children:"Request Configuration"})}),s(oe,{className:"space-y-4",children:[s("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s("div",{children:[s("label",{className:"text-sm font-medium mb-1 block",children:"Method"}),s("select",{value:o,onChange:y=>i(y.target.value),className:"w-full p-2 border rounded-md",children:[s("option",{value:"GET",children:"GET"}),s("option",{value:"POST",children:"POST"}),s("option",{value:"PUT",children:"PUT"}),s("option",{value:"PATCH",children:"PATCH"}),s("option",{value:"DELETE",children:"DELETE"}),s("option",{value:"HEAD",children:"HEAD"}),s("option",{value:"OPTIONS",children:"OPTIONS"})]})]}),s("div",{children:[s("label",{className:"text-sm font-medium mb-1 block",children:"URL"}),s(Gt,{value:r,onChange:y=>n(y.target.value),placeholder:"Enter URL"})]})]}),s("div",{children:[s("div",{className:"flex items-center justify-between mb-2",children:[s("label",{className:"text-sm font-medium",children:"Headers"}),s(ye,{size:"sm",variant:"outline",onClick:R,children:"Add Header"})]}),s("div",{className:"space-y-2 max-h-48 overflow-y-auto",children:Object.entries(a).map(([y,L])=>s("div",{className:"flex items-center gap-2",children:[s(Gt,{value:y,disabled:!0,className:"flex-1 font-mono text-sm"}),s(Gt,{value:L,onChange:D=>w(y,D.target.value),placeholder:"Value",className:"flex-2 font-mono text-sm"}),s(ye,{size:"sm",variant:"ghost",onClick:()=>S(y),className:"text-red-600 hover:text-red-700",children:"Remove"})]},y))})]}),(o==="POST"||o==="PUT"||o==="PATCH")&&s("div",{children:[s("label",{className:"text-sm font-medium mb-1 block",children:"Request Body"}),s("textarea",{value:u,onChange:y=>f(y.target.value),className:"w-full p-2 border rounded-md font-mono text-sm",rows:6,placeholder:"Enter request body (JSON, XML, etc.)"})]}),s("div",{className:"flex justify-end gap-2",children:[s(ye,{onClick:t,variant:"outline",children:"Cancel"}),s(ye,{onClick:v,disabled:d,className:T(d&&"opacity-50 cursor-not-allowed"),children:d?"Replaying...":"Send Request"})]})]})]}),x&&s(Q,{className:"border-red-200 bg-red-50",children:[s(J,{children:s(Z,{className:"text-red-800",children:"Error"})}),s(oe,{children:s("p",{className:"text-red-700",children:x})})]}),c&&s(Q,{children:[s(J,{children:s(Z,{children:"Response"})}),s(oe,{children:s(Wr,{defaultValue:"overview",className:"w-full",children:[s(qt,{children:[s(_e,{value:"overview",children:"Overview"}),s(_e,{value:"headers",children:"Headers"}),s(_e,{value:"body",children:"Body"})]}),s(we,{value:"overview",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Status"}),s("div",{className:"mt-1",children:s(kl,{className:P(c.statusCode),children:c.statusCode})})]}),s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Duration"}),s("div",{className:"mt-1 text-lg font-medium",children:[c.duration,"ms"]})]}),s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Original Request"}),s("div",{className:"mt-1 text-sm font-mono",children:c.originalRequest})]})]})}),s(we,{value:"headers",children:s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-4",children:s("div",{className:"space-y-1 text-sm font-mono",children:Object.entries(c.headers).map(([y,L])=>s("div",{children:[s("span",{className:"text-blue-600",children:[y,":"]})," ",s("span",{className:"text-gray-700 dark:text-gray-300",children:Array.isArray(L)?L.join(", "):L})]},y))})})}),s(we,{value:"body",children:s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-4",children:s("pre",{className:"text-sm font-mono overflow-x-auto max-h-96 overflow-y-auto",children:c.body})})})]})})]})]})}var bp={"5m":1e4,"15m":3e4,"1h":12e4,"6h":6e5,"24h":18e5,all:0},vp={"5m":5*6e4,"15m":15*6e4,"1h":60*6e4,"6h":6*60*6e4,"24h":24*60*6e4,all:Number.POSITIVE_INFINITY};function El({requests:e,onClearAll:t,onImport:r}){let[n,o]=N("15m"),i=q(()=>{if(n==="all")return e;let l=Date.now()-vp[n];return e.filter(u=>new Date(u.Timestamp).getTime()>=l)},[e,n]),a=q(()=>yp(i),[i]);return s("main",{class:"flex-1 overflow-auto",children:[s("header",{class:"px-8 pt-6 pb-4 flex items-start justify-between gap-4 border-b border-zinc-200 bg-white",children:[s("div",{children:[s("h1",{class:"text-2xl font-semibold tracking-tight",children:"Analytics"}),s("p",{class:"text-sm text-zinc-500 mt-1",children:"Throughput, latency distribution, and per-endpoint breakdown."})]}),s("div",{class:"flex items-center gap-3",children:[s("div",{class:"flex items-center gap-1 bg-zinc-100 rounded-md p-0.5",children:["5m","15m","1h","6h","24h","all"].map(l=>s("button",{onClick:()=>o(l),class:T("text-xs px-2.5 py-1 rounded",n===l?"bg-white text-zinc-900 shadow-sm font-medium":"text-zinc-500 hover:text-zinc-900"),children:l},l))}),s(Ap,{requests:i,onImport:r}),s("button",{onClick:t,class:"text-xs text-red-700 border border-red-200 rounded-md px-2.5 py-1.5 hover:bg-red-50",children:"Clear all"})]})]}),s("div",{class:"px-8 py-6 space-y-6",children:i.length===0?s(Mp,{range:n}):s(m,{children:[s(_p,{s:a}),s("div",{class:"grid grid-cols-3 gap-4",children:[s(wp,{requests:i,range:n}),s(Sp,{s:a})]}),s(Np,{requests:i}),s(Ep,{requests:i})]})})]})}function yp(e){let t=e.length;if(t===0)return{total:0,twoXX:0,threeXX:0,fourXX:0,fiveXX:0,errorRate:0,p50:0,p95:0,p99:0,max:0,rps:0,windowSec:0};let r=0,n=0,o=0,i=0;for(let p of e)p.StatusCode>=200&&p.StatusCode<300?r++:p.StatusCode<400?n++:p.StatusCode<500?o++:i++;let a=e.map(p=>p.Duration).sort((p,c)=>p-c),l=p=>a[Math.min(a.length-1,Math.floor(a.length*p))],u=e.map(p=>new Date(p.Timestamp).getTime()),f=(Math.max(...u)-Math.min(...u))/1e3,d=Math.max(f,1);return{total:t,twoXX:r,threeXX:n,fourXX:o,fiveXX:i,errorRate:(o+i)/t,p50:l(.5),p95:l(.95),p99:l(.99),max:a[a.length-1],rps:t/d,windowSec:d}}function _p({s:e}){return s("section",{class:"grid grid-cols-6 gap-3",children:[s(ht,{label:"Total",value:e.total.toLocaleString(),sub:`${e.rps.toFixed(2)} rps`,accent:"dark"}),s(ht,{label:"Error rate",value:`${(e.errorRate*100).toFixed(1)}%`,sub:`${e.fourXX+e.fiveXX} of ${e.total}`,accent:e.errorRate>.05?"red":"default"}),s(ht,{label:"p50",value:Ue(e.p50)}),s(ht,{label:"p95",value:Ue(e.p95),accent:e.p95>500?"amber":"default"}),s(ht,{label:"p99",value:Ue(e.p99),accent:e.p99>1e3?"amber":"default"}),s(ht,{label:"Max",value:Ue(e.max)})]})}function ht({label:e,value:t,sub:r,accent:n}){return s("div",{class:"bg-white border border-zinc-200 rounded-xl p-4",children:[s("div",{class:"text-[11px] uppercase tracking-wide text-zinc-500 mb-1",children:e}),s("div",{class:T("text-2xl font-semibold tabular-nums",n==="dark"?"text-zinc-900":n==="red"?"text-red-700":n==="amber"?"text-amber-700":"text-zinc-900"),children:t}),r&&s("div",{class:"text-[11px] text-zinc-500 mt-1",children:r})]})}function Ue(e){return isFinite(e)?e<1?"<1ms":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(2)}s`:"\u2014"}function wp({requests:e,range:t}){let r=q(()=>Rp(e,t),[e,t]);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5 col-span-2 flex flex-col",children:[s("header",{class:"flex items-center justify-between mb-4",children:[s("div",{children:[s("h3",{class:"text-sm font-semibold",children:"Throughput"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Requests per bucket \xB7 errors overlaid"})]}),s(kp,{})]}),s("div",{class:"flex-1 min-h-[240px]",children:s(Cp,{data:r})})]})}function Rp(e,t){if(e.length===0)return[];let r=e.map(d=>new Date(d.Timestamp).getTime()),n=Math.min(...r),o=Math.max(...r),i=bp[t];i===0&&(i=Math.max(1e3,Math.ceil((o-n)/40)));let a=Math.floor(n/i)*i,l=Math.ceil((o+1)/i)*i,u=Math.max(1,Math.min(120,Math.round((l-a)/i))),f=Array.from({length:u},(d,p)=>({t:a+p*i,total:0,errors:0}));for(let d of e){let p=Math.min(u-1,Math.floor((new Date(d.Timestamp).getTime()-a)/i));p>=0&&(f[p].total++,d.StatusCode>=400&&f[p].errors++)}return f}function Cp({data:e}){if(e.length===0)return s("div",{class:"text-center text-xs text-zinc-500 py-12",children:"No traffic in the selected range."});let t=800,r=220,n=40,o=8,i=12,a=24,l=t-n-o,u=r-i-a,f=Math.max(1,...e.map(w=>w.total)),d=w=>i+(1-w/f)*u,p=l/e.length,c=Math.max(2,Math.min(p-1,24)),h=e.map((w,R)=>{if(w.total===0)return null;let S=n+R*p+(p-c)/2,P=i+u-d(w.total),y=i+u-d(w.errors),L=P-y,D=d(w.total);return s("g",{children:[L>0&&s("rect",{x:S,y:d(w.total),width:c,height:P-y,fill:"#18181b",opacity:.78,children:s("title",{children:`${io(w.t)} \xB7 ${w.total} req${w.total===1?"":"s"}`})}),w.errors>0&&s("rect",{x:S,y:D,width:c,height:y,fill:"#ef4444",children:s("title",{children:`${io(w.t)} \xB7 ${w.errors} error${w.errors===1?"":"s"}`})})]},R)}),x=f<=2?[0,f]:[0,Math.round(f/2),f],b=Math.min(3,e.length),v=Array.from({length:b},(w,R)=>{let S=Math.round(R/Math.max(1,b-1)*(e.length-1));return{x:n+S*p+p/2,label:io(e[S].t),anchor:R===0?"start":R===b-1?"end":"middle"}});return s("svg",{viewBox:`0 0 ${t} ${r}`,class:"w-full h-full",children:[x.map((w,R)=>s("g",{children:[s("line",{x1:n,y1:d(w),x2:t-o,y2:d(w),stroke:"#f4f4f5"}),s("text",{x:n-6,y:d(w)+3,"text-anchor":"end","font-size":"10",fill:"#71717a",children:w})]},R)),h,v.map((w,R)=>s("text",{x:w.x,y:r-8,"text-anchor":w.anchor,"font-size":"10",fill:"#71717a",children:w.label},R))]})}function io(e){let t=new Date(e),r=t.getHours().toString().padStart(2,"0"),n=t.getMinutes().toString().padStart(2,"0"),o=t.getSeconds().toString().padStart(2,"0");return`${r}:${n}:${o}`}function kp(){return s("div",{class:"flex items-center gap-4 text-[11px] text-zinc-500",children:[s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:"w-2.5 h-2.5 rounded-sm bg-zinc-900/80"}),"Requests"]}),s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:"w-2.5 h-2.5 rounded-sm bg-red-500"}),"Errors"]})]})}function Sp({s:e}){let t=[{label:"2xx",value:e.twoXX,color:"#10b981"},{label:"3xx",value:e.threeXX,color:"#f59e0b"},{label:"4xx",value:e.fourXX,color:"#f97316"},{label:"5xx",value:e.fiveXX,color:"#ef4444"}],r=t.reduce((n,o)=>n+o.value,0);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5 flex flex-col",children:[s("header",{class:"mb-4",children:[s("h3",{class:"text-sm font-semibold",children:"Status"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"By response class"})]}),s("div",{class:"flex items-center gap-5",children:[s(Tp,{segments:t,total:r}),s("div",{class:"flex-1 space-y-1.5",children:t.map(n=>{let o=r===0?0:n.value/r*100;return s("div",{class:"flex items-center gap-2 text-xs",children:[s("span",{class:"w-2 h-2 rounded-sm shrink-0",style:{background:n.color}}),s("span",{class:"text-zinc-500 w-8",children:n.label}),s("span",{class:"flex-1 text-right font-mono tabular-nums",children:n.value}),s("span",{class:"text-zinc-500 font-mono tabular-nums w-12 text-right",children:[o.toFixed(0),"%"]})]},n.label)})})]})]})}function Tp({segments:e,total:t}){let n=2*Math.PI*36,o=0;return s("div",{class:"relative shrink-0",children:[s("svg",{width:"100",height:"100",viewBox:"0 0 100 100",class:"-rotate-90",children:[s("circle",{cx:"50",cy:"50",r:36,fill:"none",stroke:"#f4f4f5","stroke-width":"12"}),e.map((i,a)=>{if(t===0||i.value===0)return null;let l=i.value/t*n,u=-o;return o+=l,s("circle",{cx:"50",cy:"50",r:36,fill:"none",stroke:i.color,"stroke-width":"12","stroke-dasharray":`${l} ${n-l}`,"stroke-dashoffset":u},a)})]}),s("div",{class:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[s("span",{class:"text-lg font-semibold tabular-nums",children:t}),s("span",{class:"text-[10px] text-zinc-500 uppercase tracking-wide",children:"total"})]})]})}var ao=[{label:"<10ms",from:0,to:10},{label:"10\u201350ms",from:10,to:50},{label:"50\u2013100ms",from:50,to:100},{label:"100\u2013200ms",from:100,to:200},{label:"200\u2013500ms",from:200,to:500},{label:"500ms\u20131s",from:500,to:1e3},{label:"1\u20132s",from:1e3,to:2e3},{label:"2\u20135s",from:2e3,to:5e3},{label:">5s",from:5e3,to:Number.POSITIVE_INFINITY}];function Np({requests:e}){let t=q(()=>{let n=new Array(ao.length).fill(0);for(let o of e){let i=ao.findIndex(a=>o.Duration>=a.from&&o.Duration=0&&n[i]++}return n},[e]),r=Math.max(1,...t);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5",children:[s("header",{class:"mb-4",children:[s("h3",{class:"text-sm font-semibold",children:"Latency distribution"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Where requests fall on the response-time spectrum"})]}),s("div",{class:"grid grid-cols-9 gap-2 items-end h-32",children:t.map((n,o)=>{let i=n/r*100;return s("div",{class:"flex flex-col items-center gap-1 h-full justify-end",children:[s("span",{class:"text-[10px] font-mono text-zinc-500 tabular-nums",children:n}),s("div",{class:T("w-full rounded-t",o<4?"bg-emerald-200":o<6?"bg-amber-300":"bg-red-400"),style:{height:`${i}%`,minHeight:n>0?"4px":"0"}})]},o)})}),s("div",{class:"grid grid-cols-9 gap-2 mt-2",children:ao.map((n,o)=>s("div",{class:"text-[10px] text-zinc-500 text-center font-mono",children:n.label},o))})]})}function Ep({requests:e}){let t=q(()=>{let r=new Map;for(let n of e){let o=`${n.Method} ${n.Path}`,i=r.get(o);i||(i={method:n.Method,path:n.Path,ds:[],errs:0},r.set(o,i)),i.ds.push(n.Duration),n.StatusCode>=400&&i.errs++}return Array.from(r.entries()).map(([n,o])=>{let i=[...o.ds].sort((l,u)=>l-u),a=l=>i[Math.min(i.length-1,Math.floor(i.length*l))];return{key:n,method:o.method,path:o.path,count:o.ds.length,p50:a(.5),p95:a(.95),p99:a(.99),max:i[i.length-1],errors:o.errs}}).sort((n,o)=>o.p95-n.p95)},[e]);return s("section",{class:"bg-white border border-zinc-200 rounded-xl overflow-hidden",children:[s("header",{class:"px-5 py-3 border-b border-zinc-200 flex items-center justify-between",children:[s("div",{children:[s("h3",{class:"text-sm font-semibold",children:"Endpoints"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Sorted by p95, slowest first"})]}),s("span",{class:"text-xs text-zinc-500 font-mono",children:t.length})]}),s("div",{class:"overflow-x-auto",children:s("table",{class:"w-full text-sm",children:[s("thead",{class:"bg-zinc-50/60 border-b border-zinc-200",children:s("tr",{class:"text-left text-[11px] uppercase tracking-wide text-zinc-500",children:[s("th",{class:"px-5 py-2 font-medium",children:"Endpoint"}),s("th",{class:"px-3 py-2 font-medium text-right w-16",children:"Count"}),s("th",{class:"px-3 py-2 font-medium text-right w-16",children:"Err"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p50"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p95"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p99"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"max"}),s("th",{class:"px-5 py-2 font-medium w-32",children:"Heat"})]})}),s("tbody",{class:"divide-y divide-zinc-100",children:t.slice(0,20).map(r=>{let n=Math.min(1,r.p95/1e3);return s("tr",{class:"hover:bg-zinc-50",children:[s("td",{class:"px-5 py-2",children:[s("span",{class:T("text-[10px] font-semibold mr-2",zp(r.method)),children:r.method}),s("span",{class:"font-mono text-xs",children:r.path})]}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:r.count}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:r.errors>0?s("span",{class:"text-red-700",children:r.errors}):s("span",{class:"text-zinc-400",children:"0"})}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:Ue(r.p50)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:Ue(r.p95)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:Ue(r.p99)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:Ue(r.max)}),s("td",{class:"px-5 py-2",children:s("div",{class:"h-1.5 bg-zinc-100 rounded-full overflow-hidden",children:s("div",{class:T("h-1.5 rounded-full",n<.3?"bg-emerald-400":n<.7?"bg-amber-400":"bg-red-400"),style:{width:`${n*100}%`}})})})]},r.key)})})]})})]})}function zp(e){switch(e){case"GET":return"text-blue-700";case"POST":return"text-emerald-700";case"PUT":case"PATCH":return"text-amber-700";case"DELETE":return"text-red-700";default:return"text-zinc-700"}}function Ap({requests:e,onImport:t}){let r=F(null),[n,o]=N(!1),[i,a]=N(""),l=()=>{let d=new Blob([te.exportRequests(e)],{type:"application/json"});Tl(d,`govisual-${Nl()}.json`),o(!1)},u=()=>{let d=["ID","Timestamp","Method","Path","Status","Duration (ms)","Error"],p=x=>`"${String(x??"").replace(/"/g,'""')}"`,c=e.map(x=>[x.ID,x.Timestamp,x.Method,x.Path,x.StatusCode,x.Duration,x.Error||""]),h=[d.map(p).join(","),...c.map(x=>x.map(p).join(","))].join(` -`);Tl(new Blob([h],{type:"text/csv"}),`govisual-${Nl()}.csv`),o(!1)},f=d=>{let p=d.target.files?.[0];if(!p)return;let c=new FileReader;c.onload=h=>{try{let x=te.importRequests(h.target?.result);t(x),a("imported")}catch(x){console.error("Import failed:",x),a("failed")}setTimeout(()=>a(""),2500)},c.readAsText(p),d.target.value=""};return s("div",{class:"relative",children:[s("button",{onClick:()=>o(d=>!d),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50 flex items-center gap-1.5",children:["Data",s("svg",{class:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:s("polyline",{points:"6 9 12 15 18 9"})})]}),n&&s(m,{children:[s("button",{class:"fixed inset-0 z-30 cursor-default",onClick:()=>o(!1),"aria-label":"Close menu"}),s("div",{class:"absolute right-0 top-full mt-1 w-44 bg-white border border-zinc-200 rounded-md shadow-md z-40 py-1",children:[s(lo,{onClick:l,label:"Export JSON",hint:`${e.length} rows`}),s(lo,{onClick:u,label:"Export CSV",hint:`${e.length} rows`}),s("div",{class:"h-px bg-zinc-100 my-1"}),s(lo,{onClick:()=>{o(!1),r.current?.click()},label:"Import JSON"})]})]}),i&&s("span",{class:T("absolute right-0 -bottom-6 text-[11px]",i==="imported"?"text-emerald-700":"text-red-700"),children:i==="imported"?"Imported \u2713":"Import failed"}),s("input",{ref:r,type:"file",accept:".json,application/json",class:"hidden",onChange:f})]})}function lo({onClick:e,label:t,hint:r}){return s("button",{onClick:e,class:"w-full px-3 py-1.5 text-left text-sm hover:bg-zinc-50 flex items-center justify-between",children:[s("span",{children:t}),r&&s("span",{class:"text-[11px] text-zinc-500 font-mono",children:r})]})}function Tl(e,t){let r=URL.createObjectURL(e),n=document.createElement("a");n.href=r,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}function Nl(){return new Date().toISOString().replace(/[:.]/g,"-").slice(0,19)}function Mp({range:e}){let t=e==="all"?"yet":`in the last ${e}`;return s("div",{class:"bg-white border border-zinc-200 rounded-xl py-16 px-8 text-center",children:[s("div",{class:"w-12 h-12 mx-auto rounded-full bg-zinc-100 flex items-center justify-center mb-3 text-zinc-400",children:s("svg",{class:"w-5 h-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("line",{x1:"18",y1:"20",x2:"18",y2:"10"}),s("line",{x1:"12",y1:"20",x2:"12",y2:"4"}),s("line",{x1:"6",y1:"20",x2:"6",y2:"14"})]})}),s("h3",{class:"text-sm font-medium text-zinc-900",children:["No requests ",t]}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Generate some traffic and the charts will populate live."})]})}var zl=200;function Al(){let[e,t]=N([]),[r,n]=N("inbox"),[o,i]=N(null),[a,l]=N(""),[u,f]=N(new Set),[d,p]=N([]),[c,h]=N(!1),[x,b]=N(null),[v,w]=N(!1),R=F(a),S=F(u),P=F(r);I(()=>{R.current=a},[a]),I(()=>{S.current=u},[u]),I(()=>{P.current=r},[r]),I(()=>{let M=new AbortController;te.getRequests(M.signal).then($=>t($)).catch($=>{$?.name!=="AbortError"&&console.error($)});let V=te.subscribeToEvents($=>{if(w(!0),$.kind==="snapshot"){t($.data);return}t(Ae=>[...$.data,...Ae])},()=>w(!1));return()=>{M.abort(),V.close()}},[]);let y=q(()=>{let M=e;if(r==="errors"?M=M.filter(V=>V.StatusCode>=400):r==="slow"&&(M=M.filter(V=>V.Duration>=zl)),u.size>0&&(M=M.filter(V=>{let $=Ip(V.StatusCode);return $?u.has($):!1})),a.trim()){let V=a.trim().toLowerCase();M=M.filter($=>$.Path.toLowerCase().includes(V))}return M},[e,r,u,a]),L=q(()=>e.filter(M=>M.StatusCode>=400).length,[e]);I(()=>{o&&(y.some(M=>M.ID===o.ID)||i(null))},[y,o?.ID]);let D=async()=>{try{await te.clearRequests(),t([]),i(null),p([])}catch(M){console.error("Failed to clear requests:",M)}},_=M=>{p(V=>V.includes(M.ID)?V.filter($=>$!==M.ID):[...V,M.ID])};return s("div",{class:"h-screen bg-zinc-50 text-zinc-950 flex overflow-hidden",children:[s(ps,{active:r,onChange:n,errorCount:L}),r==="inbox"||r==="errors"||r==="slow"?s(m,{children:[s(ms,{title:Pp(r),subtitle:Lp(r),requests:y,selectedId:o?.ID,onSelect:i,statusFilter:u,onStatusFilterChange:f,search:a,onSearchChange:l,live:v}),s(_a,{request:o,onReplay:M=>b(M),onCompareAdd:_,comparePending:o?d.includes(o.ID):!1})]}):r==="analytics"?s(El,{requests:e,onClearAll:D,onImport:M=>{t(V=>{let $=[...V],Ae=new Set($.map(ce=>ce.ID));for(let ce of M)Ae.has(ce.ID)||$.push(ce);return $})}}):r==="agents"?s(Ra,{}):s(Op,{}),d.length>=2&&s("div",{class:"fixed left-1/2 -translate-x-1/2 bottom-6 bg-zinc-900 text-white rounded-full shadow-xl px-5 py-2.5 flex items-center gap-4 text-sm z-40",children:[s("span",{class:"font-medium",children:[d.length," selected"]}),s("div",{class:"w-px h-4 bg-white/20"}),s("button",{onClick:()=>h(!0),class:"hover:text-zinc-200",children:"Compare"}),s("button",{onClick:()=>p([]),class:"text-zinc-400 hover:text-white text-xs",children:"Clear"})]}),c&&s("div",{class:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-6",children:s("div",{class:"bg-white rounded-lg p-6 max-w-7xl w-full max-h-[90vh] overflow-auto",children:s(Cl,{requestIds:d,allRequests:e,onClose:()=>{h(!1),p([])}})})}),x&&s("div",{class:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-6",children:s("div",{class:"bg-white rounded-lg p-6 max-w-4xl w-full max-h-[90vh] overflow-auto",children:s(Sl,{request:x,onClose:()=>b(null)})})})]})}function Ip(e){return e>=200&&e<300?"2xx":e>=300&&e<400?"3xx":e>=400&&e<500?"4xx":e>=500?"5xx":null}function Pp(e){switch(e){case"inbox":return"Inbox";case"errors":return"Errors";case"slow":return"Slow";case"analytics":return"Analytics";case"agents":return"Agents";case"environment":return"Environment"}}function Lp(e){switch(e){case"errors":return"Status 4xx and 5xx";case"slow":return`Duration \u2265 ${zl}ms`;default:return}}function Op(){return s("main",{class:"flex-1 overflow-auto",children:[s("header",{class:"px-8 pt-6 pb-4",children:[s("h1",{class:"text-2xl font-semibold tracking-tight",children:"Environment"}),s("p",{class:"text-sm text-zinc-500 mt-1",children:"Server runtime and explicitly allowlisted environment variables."})]}),s("div",{class:"px-8 pb-8",children:s(Qa,{})})]})}var Ml=document.getElementById("app");Ml?Ie(s(Al,{}),Ml):console.error("Could not find app root element");})(); +))`})]})})}function pp(e){let t=new Date(e);return isNaN(t.getTime())?"":t.toLocaleTimeString("en-US",{hour12:!1})+"."+String(t.getMilliseconds()).padStart(3,"0")}function mp(e){if(!e)return"0ms";let t=e/1e6;return t<1?Math.round(e/1e3)+"\u03BCs":t<1e3?t.toFixed(1)+"ms":(t/1e3).toFixed(2)+"s"}function al(e,t){for(var r in t)e[r]=t[r];return e}function eo(e,t){for(var r in e)if(r!=="__source"&&!(r in t))return!0;for(var n in t)if(n!=="__source"&&e[n]!==t[n])return!0;return!1}function to(e,t){var r=t(),n=E({t:{__:r,u:t}}),o=n[0].t,i=n[1];return Oe(function(){o.__=r,o.u=t,Zn(o)&&i({t:o})},[e,r,t]),L(function(){return Zn(o)&&i({t:o}),e(function(){Zn(o)&&i({t:o})})},[e]),r}function Zn(e){try{return!((t=e.__)===(r=e.u())&&(t!==0||1/t==1/r)||t!=t&&r!=r)}catch{return!0}var t,r}function ro(e){e()}function no(e){return e}function oo(){return[!1,ro]}var so=Oe;function Kr(e,t){this.props=e,this.context=t}function ll(e,t){function r(o){var i=this.props.ref;return i!=o.ref&&i&&(typeof i=="function"?i(null):i.current=null),t?!t(this.props,o)||i!=o.ref:eo(this.props,o)}function n(o){return this.shouldComponentUpdate=r,g(e,o)}return n.displayName="Memo("+(e.displayName||e.name)+")",n.__f=n.prototype.isReactComponent=!0,n.type=e,n}(Kr.prototype=new de).isPureReactComponent=!0,Kr.prototype.shouldComponentUpdate=function(e,t){return eo(this.props,e)||eo(this.state,t)};var Za=A.__b;A.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),Za&&Za(e)};var hp=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.forward_ref")||3911;function M(e){function t(r){var n=al({},r);return delete n.ref,e(n,r.ref||null)}return t.$$typeof=hp,t.render=e,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(e.displayName||e.name)+")",t}var el=function(e,t){return e==null?null:Ce(Ce(e).map(t))},dt={map:el,forEach:el,count:function(e){return e?Ce(e).length:0},only:function(e){var t=Ce(e);if(t.length!==1)throw"Children.only";return t[0]},toArray:Ce},gp=A.__e;A.__e=function(e,t,r,n){if(e.then){for(var o,i=t;i=i.__;)if((o=i.__c)&&o.__c)return t.__e==null&&(t.__e=r.__e,t.__k=r.__k||[]),o.__c(e,t)}gp(e,t,r,n)};var tl=A.unmount;function cl(e,t,r){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach(function(n){typeof n.__c=="function"&&n.__c()}),e.__c.__H=null),(e=al({},e)).__c!=null&&(e.__c.__P===r&&(e.__c.__P=t),e.__c.__e=!0,e.__c=null),e.__k=e.__k&&e.__k.map(function(n){return cl(n,t,r)})),e}function ul(e,t,r){return e&&r&&(e.__v=null,e.__k=e.__k&&e.__k.map(function(n){return ul(n,t,r)}),e.__c&&e.__c.__P===t&&(e.__e&&r.appendChild(e.__e),e.__c.__e=!0,e.__c.__P=r)),e}function Yt(){this.__u=0,this.o=null,this.__b=null}function fl(e){var t=e.__&&e.__.__c;return t&&t.__a&&t.__a(e)}function dl(e){var t,r,n,o=null;function i(a){if(t||(t=e()).then(function(l){l&&(o=l.default||l),n=!0},function(l){r=l,n=!0}),r)throw r;if(!n)throw t;return o?g(o,a):null}return i.displayName="Lazy",i.__f=!0,i}function _t(){this.i=null,this.l=null}A.unmount=function(e){var t=e.__c;t&&(t.__z=!0),t&&t.__R&&t.__R(),t&&32&e.__u&&(e.type=null),tl&&tl(e)},(Yt.prototype=new de).__c=function(e,t){var r=t.__c,n=this;n.o==null&&(n.o=[]),n.o.push(r);var o=fl(n.__v),i=!1,a=function(){i||n.__z||(i=!0,r.__R=null,o?o(c):c())};r.__R=a;var l=r.__P;r.__P=null;var c=function(){if(!--n.__u){if(n.state.__a){var u=n.state.__a;n.__v.__k[0]=ul(u,u.__c.__P,u.__c.__O)}var p;for(n.setState({__a:n.__b=null});p=n.o.pop();)p.__P=l,p.forceUpdate()}};n.__u++||32&t.__u||n.setState({__a:n.__b=n.__v.__k[0]}),e.then(a,a)},Yt.prototype.componentWillUnmount=function(){this.o=[]},Yt.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var r=document.createElement("div"),n=this.__v.__k[0].__c;this.__v.__k[0]=cl(this.__b,r,n.__O=n.__P)}this.__b=null}var o=t.__a&&g(h,null,e.fallback);return o&&(o.__u&=-33),[g(h,null,t.__a?null:e.children),o]};var rl=function(e,t,r){if(++r[1]===r[0]&&e.l.delete(t),e.props.revealOrder&&(e.props.revealOrder[0]!=="t"||!e.l.size))for(r=e.i;r;){for(;r.length>3;)r.pop()();if(r[1]>>1,1),t.h.removeChild(o)}}}Xe(g(xp,{context:t.context},e.__v),t.v)}function pl(e,t){var r=g(bp,{__v:e,h:t});return r.containerInfo=t,r}(_t.prototype=new de).__a=function(e){var t=this,r=fl(t.__v),n=t.l.get(e);return n[0]++,function(o){var i=function(){t.props.revealOrder?(n.push(o),rl(t,e,n)):o()};r?r(i):i()}},_t.prototype.render=function(e){this.i=null,this.l=new Map;var t=Ce(e.children);e.revealOrder&&e.revealOrder[0]==="b"&&t.reverse();for(var r=t.length;r--;)this.l.set(t[r],this.i=[1,0,this.i]);return e.children},_t.prototype.componentDidUpdate=_t.prototype.componentDidMount=function(){var e=this;this.l.forEach(function(t,r){rl(e,r,t)})};var ml=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.element")||60103,vp=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,yp=/^on(Ani|Tra|Tou|BeforeInp|Compo)/,_p=/[A-Z0-9]/g,wp=typeof document<"u",Rp=function(e){return(typeof Symbol<"u"&&typeof Symbol()=="symbol"?/fil|che|rad/:/fil|che|ra/).test(e)};function hl(e,t,r){return t.__k==null&&(t.textContent=""),Xe(e,t),typeof r=="function"&&r(),e?e.__c:null}function gl(e,t,r){return _n(e,t),typeof r=="function"&&r(),e?e.__c:null}de.prototype.isReactComponent=!0,["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(e){Object.defineProperty(de.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})});var nl=A.event;A.event=function(e){return nl&&(e=nl(e)),e.persist=function(){},e.isPropagationStopped=function(){return this.cancelBubble},e.isDefaultPrevented=function(){return this.defaultPrevented},e.nativeEvent=e};var io,Cp={configurable:!0,get:function(){return this.class}},ol=A.vnode;A.vnode=function(e){typeof e.type=="string"&&(function(t){var r=t.props,n=t.type,o={},i=n.indexOf("-")==-1;for(var a in r){var l=r[a];if(!(a==="value"&&"defaultValue"in r&&l==null||wp&&a==="children"&&n==="noscript"||a==="class"||a==="className")){var c=a.toLowerCase();a==="defaultValue"&&"value"in r&&r.value==null?a="value":a==="download"&&l===!0?l="":c==="translate"&&l==="no"?l=!1:c[0]==="o"&&c[1]==="n"?c==="ondoubleclick"?a="ondblclick":c!=="onchange"||n!=="input"&&n!=="textarea"||Rp(r.type)?c==="onfocus"?a="onfocusin":c==="onblur"?a="onfocusout":yp.test(a)&&(a=c):c=a="oninput":i&&vp.test(a)?a=a.replace(_p,"-$&").toLowerCase():l===null&&(l=void 0),c==="oninput"&&o[a=c]&&(a="oninputCapture"),o[a]=l}}n=="select"&&(o.multiple&&Array.isArray(o.value)&&(o.value=Ce(r.children).forEach(function(u){u.props.selected=o.value.indexOf(u.props.value)!=-1})),o.defaultValue!=null&&(o.value=Ce(r.children).forEach(function(u){u.props.selected=o.multiple?o.defaultValue.indexOf(u.props.value)!=-1:o.defaultValue==u.props.value}))),r.class&&!r.className?(o.class=r.class,Object.defineProperty(o,"className",Cp)):r.className&&(o.class=o.className=r.className),t.props=o})(e),e.$$typeof=ml,ol&&ol(e)};var sl=A.__r;A.__r=function(e){sl&&sl(e),io=e.__c};var il=A.diffed;A.diffed=function(e){il&&il(e);var t=e.props,r=e.__e;r!=null&&e.type==="textarea"&&"value"in t&&t.value!==r.value&&(r.value=t.value==null?"":t.value),io=null};var xl={ReactCurrentDispatcher:{current:{readContext:function(e){return io.__n[e.__c].props.value},useCallback:W,useContext:De,useDebugValue:gr,useDeferredValue:no,useEffect:L,useId:xr,useImperativeHandle:hr,useInsertionEffect:so,useLayoutEffect:Oe,useMemo:$,useReducer:Le,useRef:D,useState:E,useSyncExternalStore:to,useTransition:oo}}},kp="18.3.1";function bl(e){return g.bind(null,e)}function Ne(e){return!!e&&e.$$typeof===ml}function vl(e){return Ne(e)&&e.type===h}function yl(e){return!!e&&typeof e.displayName=="string"&&e.displayName.indexOf("Memo(")==0}function tt(e){return Ne(e)?cs.apply(null,arguments):e}function _l(e){return!!e.__k&&(Xe(null,e),!0)}function wl(e){return e&&(e.base||e.nodeType===1&&e)||null}var Rl=function(e,t){return e(t)},Qr=function(e,t){var r,n=A.debounceRendering;A.debounceRendering=function(i){r=i};try{var o=e(t);return r&&r(),o}finally{A.debounceRendering=n}},Cl=Ne,kl={useState:E,useId:xr,useReducer:Le,useEffect:L,useLayoutEffect:Oe,useInsertionEffect:so,useTransition:oo,useDeferredValue:no,useSyncExternalStore:to,startTransition:ro,useRef:D,useImperativeHandle:hr,useMemo:$,useCallback:W,useContext:De,useDebugValue:gr,version:"18.3.1",Children:dt,render:hl,hydrate:gl,unmountComponentAtNode:_l,createPortal:pl,createElement:g,createContext:ke,createFactory:bl,cloneElement:tt,createRef:pr,Fragment:h,isValidElement:Ne,isElement:Cl,isFragment:vl,isMemo:yl,findDOMNode:wl,Component:de,PureComponent:Kr,memo:ll,forwardRef:M,flushSync:Qr,unstable_batchedUpdates:Rl,StrictMode:h,Suspense:Yt,SuspenseList:_t,lazy:dl,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:xl};var J=M(({className:e,...t},r)=>s("div",{ref:r,className:N("rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm",e),...t}));J.displayName="Card";var Z=M(({className:e,...t},r)=>s("div",{ref:r,className:N("flex flex-col space-y-1.5 p-6",e),...t}));Z.displayName="CardHeader";var ee=M(({className:e,...t},r)=>s("div",{ref:r,className:N("text-2xl font-semibold leading-none tracking-tight",e),...t}));ee.displayName="CardTitle";var Kt=M(({className:e,...t},r)=>s("div",{ref:r,className:N("text-sm text-slate-500",e),...t}));Kt.displayName="CardDescription";var se=M(({className:e,...t},r)=>s("div",{ref:r,className:N("p-6 pt-0",e),...t}));se.displayName="CardContent";var Sp=M(({className:e,...t},r)=>s("div",{ref:r,className:N("flex items-center p-6 pt-0",e),...t}));Sp.displayName="CardFooter";var B={};Tc(B,{Children:()=>dt,Component:()=>de,Fragment:()=>h,PureComponent:()=>Kr,StrictMode:()=>h,Suspense:()=>Yt,SuspenseList:()=>_t,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:()=>xl,cloneElement:()=>tt,createContext:()=>ke,createElement:()=>g,createFactory:()=>bl,createPortal:()=>pl,createRef:()=>pr,default:()=>kl,findDOMNode:()=>wl,flushSync:()=>Qr,forwardRef:()=>M,hydrate:()=>gl,isElement:()=>Cl,isFragment:()=>vl,isMemo:()=>yl,isValidElement:()=>Ne,lazy:()=>dl,memo:()=>ll,render:()=>hl,startTransition:()=>ro,unmountComponentAtNode:()=>_l,unstable_batchedUpdates:()=>Rl,useCallback:()=>W,useContext:()=>De,useDebugValue:()=>gr,useDeferredValue:()=>no,useEffect:()=>L,useErrorBoundary:()=>Lc,useId:()=>xr,useImperativeHandle:()=>hr,useInsertionEffect:()=>so,useLayoutEffect:()=>Oe,useMemo:()=>$,useReducer:()=>Le,useRef:()=>D,useState:()=>E,useSyncExternalStore:()=>to,useTransition:()=>oo,version:()=>kp});var ao=M(({className:e,...t},r)=>s("div",{className:"relative w-full overflow-auto",children:s("table",{ref:r,className:N("w-full caption-bottom text-sm",e),...t})}));ao.displayName="Table";var lo=M(({className:e,...t},r)=>s("thead",{ref:r,className:N("[&_tr]:border-b",e),...t}));lo.displayName="TableHeader";var co=M(({className:e,...t},r)=>s("tbody",{ref:r,className:N("[&_tr:last-child]:border-0",e),...t}));co.displayName="TableBody";var Tp=M(({className:e,...t},r)=>s("tfoot",{ref:r,className:N("border-t bg-slate-100/50 font-medium [&>tr]:last:border-b-0 dark:bg-slate-800/50",e),...t}));Tp.displayName="TableFooter";var Jr=M(({className:e,...t},r)=>s("tr",{ref:r,className:N("border-b transition-colors hover:bg-slate-100/50 data-[state=selected]:bg-slate-100 dark:hover:bg-slate-800/50 dark:data-[state=selected]:bg-slate-800",e),...t}));Jr.displayName="TableRow";var Zr=M(({className:e,...t},r)=>s("th",{ref:r,className:N("h-12 px-4 text-left align-middle font-medium text-slate-500 [&:has([role=checkbox])]:pr-0 dark:text-slate-400",e),...t}));Zr.displayName="TableHead";var en=M(({className:e,...t},r)=>s("td",{ref:r,className:N("p-4 align-middle [&:has([role=checkbox])]:pr-0",e),...t}));en.displayName="TableCell";var Ep=M(({className:e,...t},r)=>s("caption",{ref:r,className:N("mt-4 text-sm text-slate-500 dark:text-slate-400",e),...t}));Ep.displayName="TableCaption";function Sl(){let[e,t]=E({kind:"loading"});if(L(()=>{let i=new AbortController;return re.getSystemInfo(i.signal).then(a=>t({kind:"ready",info:a})).catch(a=>{if(a?.name!=="AbortError"){if(a instanceof Se&&a.isNotFound){t({kind:"disabled"});return}t({kind:"error",message:a instanceof Error?a.message:"Failed to load"})}}),()=>i.abort()},[]),e.kind==="loading")return s("div",{className:"text-sm text-muted-foreground",children:"Loading system information..."});if(e.kind==="disabled")return s(J,{children:s(Z,{children:[s(ee,{children:"System info is disabled"}),s(Kt,{children:["The ",s("code",{children:"/__viz/api/system-info"})," endpoint is off by default. Enable it on the server with"," ",s("code",{children:"govisual.WithSystemInfo(...)"}),", passing the env var allowlist you want exposed."]})]})});if(e.kind==="error")return s(J,{className:"border-destructive/50 bg-destructive/5",children:s(Z,{children:[s(ee,{children:"Failed to load system info"}),s(Kt,{className:"text-destructive",children:e.message})]})});let r=e.info,n=r.memoryTotal>0?r.memoryUsed/r.memoryTotal*100:0,o=Object.entries(r.envVars);return s("div",{className:"space-y-6",children:[s("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:[s(J,{children:[s(Z,{children:s(ee,{children:"Go Environment"})}),s(se,{className:"space-y-2",children:[s(wt,{label:"Version",value:r.goVersion}),s(wt,{label:"GOOS",value:r.goos}),s(wt,{label:"GOARCH",value:r.goarch})]})]}),s(J,{children:[s(Z,{children:s(ee,{children:"System"})}),s(se,{className:"space-y-2",children:[s(wt,{label:"Hostname",value:r.hostname}),s(wt,{label:"OS",value:r.goos}),s(wt,{label:"CPU Cores",value:String(r.cpuCores)})]})]}),s(J,{children:[s(Z,{children:s(ee,{children:"Memory Usage"})}),s(se,{children:s("div",{className:"space-y-2",children:[s("div",{className:"w-full bg-gray-200 rounded-full h-2",children:s("div",{className:"bg-primary h-2 rounded-full transition-all duration-300",style:{width:`${Math.min(100,n)}%`}})}),s("div",{className:"flex justify-between text-sm",children:[s("span",{className:"text-muted-foreground",children:[r.memoryUsed,"MB / ",r.memoryTotal,"MB"]}),s("span",{className:"font-medium",children:[n.toFixed(1),"%"]})]})]})})]})]}),s(J,{children:[s(Z,{children:[s(ee,{children:"Environment Variables"}),s(Kt,{children:"Only variables explicitly allowlisted on the server are shown."})]}),s(se,{children:o.length===0?s("p",{className:"text-sm text-muted-foreground",children:["No environment variables are exposed. Pass names to",s("code",{className:"mx-1",children:"WithSystemInfo(...)"}),"on the server to surface them here."]}):s("div",{className:"max-h-96 overflow-auto",children:s(ao,{children:[s(lo,{children:s(Jr,{children:[s(Zr,{children:"Name"}),s(Zr,{children:"Value"})]})}),s(co,{children:o.map(([i,a])=>s(Jr,{children:[s(en,{className:"font-mono text-sm",children:i}),s(en,{className:"font-mono text-sm text-muted-foreground break-all",children:a})]},i))})]})})})]})]})}function wt({label:e,value:t}){return s("div",{className:"flex justify-between",children:[s("span",{className:"text-sm text-muted-foreground",children:[e,":"]}),s("span",{className:"text-sm font-medium",children:t})]})}var Tl=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,El=br,tn=(e,t)=>r=>{var n;if(t?.variants==null)return El(e,r?.class,r?.className);let{variants:o,defaultVariants:i}=t,a=Object.keys(o).map(u=>{let p=r?.[u],d=i?.[u];if(p===null)return null;let f=Tl(p)||Tl(d);return o[u][f]}),l=r&&Object.entries(r).reduce((u,p)=>{let[d,f]=p;return f===void 0||(u[d]=f),u},{}),c=t==null||(n=t.compoundVariants)===null||n===void 0?void 0:n.reduce((u,p)=>{let{class:d,className:f,...m}=p;return Object.entries(m).every(x=>{let[b,y]=x;return Array.isArray(y)?y.includes({...i,...l}[b]):{...i,...l}[b]===y})?[...u,d,f]:u},[]);return El(e,a,c,r?.class,r?.className)};var Np=tn("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",{variants:{variant:{default:"bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90",destructive:"bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90",outline:"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50",secondary:"bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",ghost:"hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50",link:"text-slate-900 underline-offset-4 hover:underline dark:text-slate-50"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),Ie=M(({className:e,variant:t,size:r,...n},o)=>s("button",{className:N(Np({variant:t,size:r,className:e})),ref:o,...n}));Ie.displayName="Button";var Ip=Object.defineProperty,Rt=(e,t)=>Ip(e,"name",{value:t,configurable:!0}),Nl=!!(typeof window<"u"&&window.document&&window.document.createElement);function he(e,t,{checkForDefaultPrevented:r=!0}={}){return Rt(function(o){if(e?.(o),r===!1||!o||!o.defaultPrevented)return t?.(o)},"handleEvent")}Rt(he,"composeEventHandlers");function Pp(e){if(!Nl)throw new Error("Cannot access window outside of the DOM");return e?.ownerDocument?.defaultView??window}Rt(Pp,"getOwnerWindow");function uo(e){if(!Nl)throw new Error("Cannot access document outside of the DOM");return e?.ownerDocument??document}Rt(uo,"getOwnerDocument");function Il(e,t=!1){let{activeElement:r}=uo(e);if(!r?.nodeName)return null;if(Pl(r)&&r.contentDocument)return Il(r.contentDocument.body,t);if(t){let n=r.getAttribute("aria-activedescendant");if(n){let o=uo(r).getElementById(n);if(o)return o}}return r}Rt(Il,"getActiveElement");function Pl(e){return e.tagName==="IFRAME"}Rt(Pl,"isFrame");var Ap=Object.defineProperty,ge=(e,t)=>Ap(e,"name",{value:t,configurable:!0});function Mp(e,t){let r=ke(t);r.displayName=e+"Context";let n=ge(i=>{let{children:a,...l}=i,c=$(()=>l,Object.values(l));return s(r.Provider,{value:c,children:a})},"Provider");n.displayName=e+"Provider";function o(i,a={}){let{optional:l=!1}=a,c=De(r);if(c)return c;if(t!==void 0)return t;if(!l)throw new Error(`\`${i}\` must be used within \`${e}\``)}return ge(o,"useContext"),[n,o]}ge(Mp,"createContext");function Ve(e,t=[]){let r=[];function n(i,a){let l=ke(a);l.displayName=i+"Context";let c=r.length;r=[...r,a];let u=ge(d=>{let{scope:f,children:m,...x}=d,b=f?.[e]?.[c]||l,y=$(()=>x,Object.values(x));return s(b.Provider,{value:y,children:m})},"Provider");u.displayName=i+"Provider";function p(d,f,m={}){let{optional:x=!1}=m,b=f?.[e]?.[c]||l,y=De(b);if(y)return y;if(a!==void 0)return a;if(!x)throw new Error(`\`${d}\` must be used within \`${i}\``)}return ge(p,"useContext"),[u,p]}ge(n,"createContext");let o=ge(()=>{let i=r.map(a=>ke(a));return ge(function(l){let c=l?.[e]||i;return $(()=>({[`__scope${e}`]:{...l,[e]:c}}),[l,c])},"useScope")},"createScope");return o.scopeName=e,[n,Al(o,...t)]}ge(Ve,"createContextScope");function Al(...e){let t=e[0];if(e.length===1)return t;let r=ge(()=>{let n=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return ge(function(i){let a=n.reduce((l,{useScope:c,scopeName:u})=>{let d=c(i)[`__scope${u}`];return{...l,...d}},{});return $(()=>({[`__scope${t.scopeName}`]:a}),[a])},"useComposedScopes")},"createScope");return r.scopeName=t.scopeName,r}ge(Al,"composeContextScopes");var zp=Object.defineProperty,po=(e,t)=>zp(e,"name",{value:t,configurable:!0});function fo(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}po(fo,"setRef");function Ml(...e){return t=>{let r=!1,n=e.map(o=>{let i=fo(o,t);return!r&&typeof i=="function"&&(r=!0),i});if(r)return()=>{for(let o=0;oLp(e,"name",{value:t,configurable:!0});function Ue(e){let t=M((r,n)=>{let{children:o,...i}=r,a=null,l=!1,c=[];mo(o)&&typeof rn=="function"&&(o=rn(o._payload)),dt.forEach(o,f=>{if(Dl(f)){l=!0;let m=f,x="child"in m.props?m.props.child:m.props.children;mo(x)&&typeof rn=="function"&&(x=rn(x._payload)),a=Dp(m,x),c.push(a?.props?.children)}else c.push(f)}),a?a=tt(a,void 0,c):!l&&dt.count(o)===1&&Ne(o)&&(a=o);let u=a?Ol(a):void 0,p=xe(n,u);if(!a){if(o||o===0)throw new Error(l?Bp(e):Hp(e));return o}let d=Ll(i,a.props??{});return a.type!==h&&(d.ref=n?p:u),tt(a,d)});return t.displayName=`${e}.Slot`,t}ye(Ue,"createSlot");var zl=Symbol.for("radix.slottable");function Op(e){let t=ye(r=>"child"in r?r.children(r.child):r.children,"Slottable");return t.displayName=`${e}.Slottable`,t.__radixId=zl,t}ye(Op,"createSlottable");var Dp=ye((e,t)=>{if("child"in e.props){let r=e.props.child;return Ne(r)?tt(r,void 0,e.props.children(r.props.children)):null}return Ne(t)?t:null},"getSlottableElementFromSlottable");function Ll(e,t){let r={...t};for(let n in t){let o=e[n],i=t[n];/^on[A-Z]/.test(n)?o&&i?r[n]=(...l)=>{let c=i(...l);return o(...l),c}:o&&(r[n]=o):n==="style"?r[n]={...o,...i}:n==="className"&&(r[n]=[o,i].filter(Boolean).join(" "))}return{...e,...r}}ye(Ll,"mergeProps");function Ol(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,r=t&&"isReactWarning"in t&&t.isReactWarning;return r?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,r=t&&"isReactWarning"in t&&t.isReactWarning,r?e.props.ref:e.props.ref||e.ref)}ye(Ol,"getElementRef");function Dl(e){return Ne(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===zl}ye(Dl,"isSlottable");var Fp=Symbol.for("react.lazy");function mo(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===Fp&&"_payload"in e&&Fl(e._payload)}ye(mo,"isLazyComponent");function Fl(e){return typeof e=="object"&&e!==null&&"then"in e}ye(Fl,"isPromiseLike");var Hp=ye(e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,"createSlotError"),Bp=ye(e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,"createSlottableError"),rn=B[" use ".trim().toString()];var $p=Object.defineProperty,ne=(e,t)=>$p(e,"name",{value:t,configurable:!0});function xo(e){let t=e+"CollectionProvider",[r,n]=Ve(t),[o,i]=r(t,{collectionRef:{current:null},itemMap:new Map}),a=ne(b=>{let{scope:y,children:w}=b,_=D(null),T=D(new Map).current;return s(o,{scope:y,itemMap:T,collectionRef:_,children:w})},"CollectionProvider");a.displayName=t;let l=e+"CollectionSlot",c=Ue(l),u=M((b,y)=>{let{scope:w,children:_}=b,T=i(l,w),P=xe(y,T.collectionRef);return s(c,{ref:P,children:_})});u.displayName=l;let p=e+"CollectionItemSlot",d="data-radix-collection-item",f=Ue(p),m=M((b,y)=>{let{scope:w,children:_,...T}=b,P=D(null),z=xe(y,P),O=i(p,w);return L(()=>(O.itemMap.set(P,{ref:P,...T}),()=>{O.itemMap.delete(P)})),s(f,{[d]:"",ref:z,children:_})});m.displayName=p;function x(b){let y=i(e+"CollectionConsumer",b);return W(()=>{let _=y.collectionRef.current;if(!_)return[];let T=Array.from(_.querySelectorAll(`[${d}]`));return Array.from(y.itemMap.values()).sort((O,R)=>T.indexOf(O.ref.current)-T.indexOf(R.ref.current))},[y.collectionRef,y.itemMap])}return ne(x,"useCollection"),[{Provider:a,Slot:u,ItemSlot:m},x,n]}ne(xo,"createCollection");var Hl=new WeakMap,X,pe,ho=(pe=class extends Map{constructor(r){super(r);Wo(this,X);dn(this,X,[...super.keys()]),Hl.set(this,!0)}set(r,n){return Hl.get(this)&&(this.has(r)?ae(this,X)[ae(this,X).indexOf(r)]=r:ae(this,X).push(r)),super.set(r,n),this}insert(r,n,o){let i=this.has(n),a=ae(this,X).length,l=bo(r),c=l>=0?l:a+l,u=c<0||c>=a?-1:c;if(u===this.size||i&&u===this.size-1||u===-1)return this.set(n,o),this;let p=this.size+(i?0:1);l<0&&c++;let d=[...ae(this,X)],f,m=!1;for(let x=c;x=this.size&&(i=this.size-1),this.at(i)}keyFrom(r,n){let o=this.indexOf(r);if(o===-1)return;let i=o+n;return i<0&&(i=0),i>=this.size&&(i=this.size-1),this.keyAt(i)}find(r,n){let o=0;for(let i of this){if(Reflect.apply(r,n,[i,o,this]))return i;o++}}findIndex(r,n){let o=0;for(let i of this){if(Reflect.apply(r,n,[i,o,this]))return o;o++}return-1}filter(r,n){let o=[],i=0;for(let a of this)Reflect.apply(r,n,[a,i,this])&&o.push(a),i++;return new pe(o)}map(r,n){let o=[],i=0;for(let a of this)o.push([a[0],Reflect.apply(r,n,[a,i,this])]),i++;return new pe(o)}reduce(...r){let[n,o]=r,i=0,a=o??this.at(0);for(let l of this)i===0&&r.length===1?a=l:a=Reflect.apply(n,this,[a,l,i,this]),i++;return a}reduceRight(...r){let[n,o]=r,i=o??this.at(-1);for(let a=this.size-1;a>=0;a--){let l=this.at(a);a===this.size-1&&r.length===1?i=l:i=Reflect.apply(n,this,[i,l,a,this])}return i}toSorted(r){let n=[...this.entries()].sort(r);return new pe(n)}toReversed(){let r=new pe;for(let n=this.size-1;n>=0;n--){let o=this.keyAt(n),i=this.get(o);r.set(o,i)}return r}toSpliced(...r){let n=[...this.entries()];return n.splice(...r),new pe(n)}slice(r,n){let o=new pe,i=this.size-1;if(r===void 0)return o;r<0&&(r=r+this.size),n!==void 0&&n>0&&(i=n-1);for(let a=r;a<=i;a++){let l=this.keyAt(a),c=this.get(l);o.set(l,c)}return o}every(r,n){let o=0;for(let i of this){if(!Reflect.apply(r,n,[i,o,this]))return!1;o++}return!0}some(r,n){let o=0;for(let i of this){if(Reflect.apply(r,n,[i,o,this]))return!0;o++}return!1}},X=new WeakMap,ne(pe,"OrderedDict"),pe);function nn(e,t){if("at"in Array.prototype)return Array.prototype.at.call(e,t);let r=Bl(e,t);return r===-1?void 0:e[r]}ne(nn,"at");function Bl(e,t){let r=e.length,n=bo(t),o=n>=0?n:r+n;return o<0||o>=r?-1:o}ne(Bl,"toSafeIndex");function bo(e){return e!==e||e===0?0:Math.trunc(e)}ne(bo,"toSafeInteger");function qp(e){let t=e+"CollectionProvider",[r,n]=Ve(t),[o,i]=r(t,{collectionElement:null,collectionRef:{current:null},collectionRefObject:{current:null},itemMap:new ho,setItemMap:ne(()=>{},"setItemMap")}),a=ne(({state:T,...P})=>T?s(c,{...P,state:T}):s(l,{...P}),"CollectionProvider");a.displayName=t;let l=ne(T=>{let P=y();return s(c,{...T,state:P})},"CollectionInit");l.displayName=t+"Init";let c=ne(T=>{let{scope:P,children:z,state:O}=T,R=D(null),[v,C]=E(null),H=xe(R,C),[q,Y]=O;return L(()=>{if(!v)return;let be=Gl(()=>{});return be.observe(v,{childList:!0,subtree:!0}),()=>{be.disconnect()}},[v]),s(o,{scope:P,itemMap:q,setItemMap:Y,collectionRef:H,collectionRefObject:R,collectionElement:v,children:z})},"CollectionProviderImpl");c.displayName=t+"Impl";let u=e+"CollectionSlot",p=Ue(u),d=M((T,P)=>{let{scope:z,children:O}=T,R=i(u,z),v=xe(P,R.collectionRef);return s(p,{ref:v,children:O})});d.displayName=u;let f=e+"CollectionItemSlot",m="data-radix-collection-item",x=Ue(f),b=M((T,P)=>{let{scope:z,children:O,...R}=T,v=D(null),[C,H]=E(null),q=xe(P,v,H),Y=i(f,z),{setItemMap:be}=Y,Me=D(R);$l(Me.current,R)||(Me.current=R);let we=Me.current;return L(()=>{let ie=we;return be(V=>C?V.has(C)?V.set(C,{...ie,element:C}).toSorted(go):(V.set(C,{...ie,element:C}),V.toSorted(go)):V),()=>{be(V=>!C||!V.has(C)?V:(V.delete(C),new ho(V)))}},[C,we,be]),s(x,{[m]:"",ref:q,children:O})});b.displayName=f;function y(){return E(new ho)}ne(y,"useInitCollection");function w(T){let{itemMap:P}=i(e+"CollectionConsumer",T);return P}return ne(w,"useCollection"),[{Provider:a,Slot:d,ItemSlot:b},{createCollectionScope:n,useCollection:w,useInitCollection:y}]}ne(qp,"createCollection");function $l(e,t){if(e===t)return!0;if(typeof e!="object"||typeof t!="object"||e==null||t==null)return!1;let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let o of r)if(!Object.prototype.hasOwnProperty.call(t,o)||e[o]!==t[o])return!1;return!0}ne($l,"shallowEqual");function ql(e,t){return!!(t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_PRECEDING)}ne(ql,"isElementPreceding");function go(e,t){return!e[1].element||!t[1].element?0:ql(e[1].element,t[1].element)?-1:1}ne(go,"sortByDocumentPosition");function Gl(e){return new MutationObserver(r=>{for(let n of r)if(n.type==="childList"){e();return}})}ne(Gl,"getChildListObserver");var _e=globalThis?.document?Oe:()=>{};var Gp=Object.defineProperty,Vp=(e,t)=>Gp(e,"name",{value:t,configurable:!0}),Up=B[" useId ".trim().toString()]||(()=>{}),jp=0;function Qt(e){let[t,r]=E(Up());return _e(()=>{e||r(n=>n??String(jp++))},[e]),e||(t?`radix-${t}`:"")}Vp(Qt,"useId");var Wp=Object.defineProperty,Xp=(e,t)=>Wp(e,"name",{value:t,configurable:!0}),Yp=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],rt=Yp.reduce((e,t)=>{let r=Ue(`Primitive.${t}`),n=M((o,i)=>{let{asChild:a,...l}=o,c=a?r:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),s(c,{...l,ref:i})});return n.displayName=`Primitive.${t}`,{...e,[t]:n}},{});function Kp(e,t){e&&Qr(()=>e.dispatchEvent(t))}Xp(Kp,"dispatchDiscreteCustomEvent");var Qp=Object.defineProperty,Jp=(e,t)=>Qp(e,"name",{value:t,configurable:!0});function vo(e){let t=D(e);return L(()=>{t.current=e}),$(()=>((...r)=>t.current?.(...r)),[])}Jp(vo,"useCallbackRef");var on=!1;var Zp=Object.defineProperty,em=(e,t)=>Zp(e,"name",{value:t,configurable:!0}),Vl=B[" useEffectEvent ".trim().toString()],Ul=B[" useInsertionEffect ".trim().toString()];function yo(e){if(typeof Vl=="function")return Vl(e);let t=D(()=>{throw new Error("Cannot call an event handler while rendering.")});return typeof Ul=="function"?Ul(()=>{t.current=e}):_e(()=>{t.current=e}),$(()=>((...r)=>t.current?.(...r)),[])}em(yo,"useEffectEvent");var tm=Object.defineProperty,Jt=(e,t)=>tm(e,"name",{value:t,configurable:!0}),rm=B[" useInsertionEffect ".trim().toString()]||_e;function Zt({prop:e,defaultProp:t,onChange:r=Jt(()=>{},"onChange"),caller:n}){let[o,i,a]=Wl({defaultProp:t,onChange:r}),l=e!==void 0,c=l?e:o;if(on){let p=D(e!==void 0);L(()=>{let d=p.current;d!==l&&console.warn(`${n} is changing from ${d?"controlled":"uncontrolled"} to ${l?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),p.current=l},[l,n])}let u=W(p=>{if(l){let d=Xl(p)?p(e):p;d!==e&&a.current?.(d)}else i(p)},[l,e,i,a]);return[c,u]}Jt(Zt,"useControllableState");function Wl({defaultProp:e,onChange:t}){let[r,n]=E(e),o=D(r),i=D(t);return rm(()=>{i.current=t},[t]),L(()=>{o.current!==r&&(i.current?.(r),o.current=r)},[r,o]),[r,n,i]}Jt(Wl,"useUncontrolledState");function Xl(e){return typeof e=="function"}Jt(Xl,"isFunction");var jl=Symbol("RADIX:SYNC_STATE");function nm(e,t,r,n){let{prop:o,defaultProp:i,onChange:a,caller:l}=t,c=o!==void 0,u=yo(a);if(on){let y=D(o!==void 0);L(()=>{let w=y.current;w!==c&&console.warn(`${l} is changing from ${w?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),y.current=c},[c,l])}let p=[{...r,state:i}];n&&p.push(n);let[d,f]=Le((y,w)=>{if(w.type===jl)return{...y,state:w.state};let _=e(y,w);return c&&!Object.is(_.state,y.state)&&u(_.state),_},...p),m=d.state,x=D(m);L(()=>{x.current!==m&&(x.current=m,c||u(m))},[m,x,c]);let b=$(()=>o!==void 0?{...d,state:o}:d,[d,o]);return L(()=>{c&&!Object.is(o,d.state)&&f({type:jl,state:o})},[o,d.state,c]),[b,f]}Jt(nm,"useControllableStateReducer");var om=Object.defineProperty,sm=(e,t)=>om(e,"name",{value:t,configurable:!0}),im=ke(void 0);function er(e){let t=De(im);return e||t||"ltr"}sm(er,"useDirection");var am=Object.defineProperty,wo=(e,t)=>am(e,"name",{value:t,configurable:!0}),_o=!1;function Yl(){let[e,t]=E(_o);return L(()=>{_o||(_o=!0,t(!0))},[]),e}wo(Yl,"useIsHydrated");var Kl=B[" useSyncExternalStore ".trim().toString()];function Ql(){return()=>{}}wo(Ql,"subscribe");function Jl(){return Kl(Ql,()=>!0,()=>!1)}wo(Jl,"useIsHydratedModern");var Zl=typeof Kl=="function"?Jl:Yl;var lm=Object.defineProperty,pt=(e,t)=>lm(e,"name",{value:t,configurable:!0}),Ro="rovingFocusGroup.onEntryFocus",cm={bubbles:!1,cancelable:!0},sn="RovingFocusGroup",[Co,ec,um]=xo(sn),[fm,ko]=Ve(sn,[um]),[dm,pm]=fm(sn),mm=M(pt(function(t,r){return s(Co.Provider,{scope:t.__scopeRovingFocusGroup,children:s(Co.Slot,{scope:t.__scopeRovingFocusGroup,children:s(hm,{...t,ref:r})})})},"RovingFocusGroup")),hm=M(pt(function(t,r){let{__scopeRovingFocusGroup:n,orientation:o,loop:i=!1,dir:a,currentTabStopId:l,defaultCurrentTabStopId:c,onCurrentTabStopIdChange:u,onEntryFocus:p,preventScrollOnEntryFocus:d=!1,...f}=t,m=D(null),x=xe(r,m),b=er(a),[y,w]=Zt({prop:l,defaultProp:c??null,onChange:u,caller:sn}),[_,T]=E(!1),P=vo(p),z=ec(n),O=D(!1),[R,v]=E(0);return L(()=>{let C=m.current;if(C)return C.addEventListener(Ro,P),()=>C.removeEventListener(Ro,P)},[P]),s(dm,{scope:n,orientation:o,dir:b,loop:i,currentTabStopId:y,onItemFocus:W(C=>w(C),[w]),onItemShiftTab:W(()=>T(!0),[]),onFocusableItemAdd:W(()=>v(C=>C+1),[]),onFocusableItemRemove:W(()=>v(C=>C-1),[]),children:s(rt.div,{tabIndex:_||R===0?-1:0,"data-orientation":o,...f,ref:x,style:{outline:"none",...t.style},onMouseDown:he(t.onMouseDown,()=>{O.current=!0}),onFocus:he(t.onFocus,C=>{let H=!O.current;if(C.target===C.currentTarget&&H&&!_){let q=new CustomEvent(Ro,cm);if(C.currentTarget.dispatchEvent(q),!q.defaultPrevented){let Y=z().filter(V=>V.focusable),be=Y.find(V=>V.active),Me=Y.find(V=>V.id===y),ie=[be,Me,...Y].filter(Boolean).map(V=>V.ref.current);So(ie,d)}}O.current=!1}),onBlur:he(t.onBlur,()=>T(!1))})})},"RovingFocusGroupImpl")),gm="RovingFocusGroupItem",xm=M(pt(function(t,r){let{__scopeRovingFocusGroup:n,focusable:o=!0,active:i=!1,tabStopId:a,children:l,...c}=t,u=Qt(),p=a||u,d=pm(gm,n),f=d.currentTabStopId===p,m=ec(n),{onFocusableItemAdd:x,onFocusableItemRemove:b,currentTabStopId:y}=d,w=Zl();return _e(()=>{if(!(!w||!o))return x(),()=>b()},[w,o,x,b]),L(()=>{if(!(w||!o))return x(),()=>b()},[w,o,x,b]),s(Co.ItemSlot,{scope:n,id:p,focusable:o,active:i,children:s(rt.span,{tabIndex:f?0:-1,"data-orientation":d.orientation,...c,ref:r,onMouseDown:he(t.onMouseDown,_=>{o?d.onItemFocus(p):_.preventDefault()}),onFocus:he(t.onFocus,()=>d.onItemFocus(p)),onKeyDown:he(t.onKeyDown,_=>{if(_.key==="Tab"&&_.shiftKey){d.onItemShiftTab();return}if(_.target!==_.currentTarget)return;let T=rc(_,d.orientation,d.dir);if(T!==void 0){if(_.metaKey||_.ctrlKey||_.altKey||_.shiftKey)return;_.preventDefault();let z=m().filter(O=>O.focusable).map(O=>O.ref.current);if(T==="last")z.reverse();else if(T==="prev"||T==="next"){T==="prev"&&z.reverse();let O=z.indexOf(_.currentTarget);z=d.loop?nc(z,O+1):z.slice(O+1)}setTimeout(()=>So(z))}}),children:typeof l=="function"?l({isCurrentTabStop:f,hasTabStop:y!=null}):l})})},"RovingFocusGroupItem")),bm={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function tc(e,t){return t!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}pt(tc,"getDirectionAwareKey");function rc(e,t,r){let n=tc(e.key,r);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(n))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(n)))return bm[n]}pt(rc,"getFocusIntent");function So(e,t=!1){let r=document.activeElement;for(let n of e)if(n===r||(n.focus({preventScroll:t}),document.activeElement!==r))return}pt(So,"focusFirst");function nc(e,t){return e.map((r,n)=>e[(t+n)%e.length])}pt(nc,"wrapArray");var oc=mm,sc=xm;var ym=Object.defineProperty,je=(e,t)=>ym(e,"name",{value:t,configurable:!0});function ic(e,t){return Le((r,n)=>t[r][n]??r,e)}je(ic,"useStateMachine");var ac=je(e=>{let{present:t,children:r}=e,n=lc(t),o=typeof r=="function"?r({present:n.isPresent}):dt.only(r),i=cc(n.ref,uc(o));return typeof r=="function"||n.isPresent?tt(o,{ref:i}):null},"Presence");function lc(e){let[t,r]=E(),n=D(null),o=D(e),i=D("none"),a=D(void 0),l=e?"mounted":"unmounted",[c,u]=ic(l,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return L(()=>{c==="mounted"?(i.current=a.current??Ct(n.current),a.current=void 0):i.current="none"},[c]),_e(()=>{let p=n.current,d=o.current;if(d!==e){let m=i.current,x=Ct(p);e?(a.current=x,u("MOUNT")):x==="none"||p?.display==="none"?u("UNMOUNT"):u(d&&m!==x?"ANIMATION_OUT":"UNMOUNT"),o.current=e}},[e,u]),_e(()=>{if(t){let p,d=t.ownerDocument.defaultView??window,f=je(x=>{let y=Ct(n.current).includes(CSS.escape(x.animationName));if(x.target===t&&y&&(u("ANIMATION_END"),!o.current)){let w=t.style.animationFillMode;t.style.animationFillMode="forwards",p=d.setTimeout(()=>{t.style.animationFillMode==="forwards"&&(t.style.animationFillMode=w)})}},"handleAnimationEnd"),m=je(x=>{x.target===t&&(i.current=Ct(n.current))},"handleAnimationStart");return t.addEventListener("animationstart",m),t.addEventListener("animationcancel",f),t.addEventListener("animationend",f),()=>{d.clearTimeout(p),t.removeEventListener("animationstart",m),t.removeEventListener("animationcancel",f),t.removeEventListener("animationend",f)}}else u("ANIMATION_END")},[t,u]),{isPresent:["mounted","unmountSuspended"].includes(c),ref:W(p=>{if(p){let d=getComputedStyle(p);n.current=d,a.current=Ct(d)}else n.current=null;r(p)},[])}}je(lc,"usePresence");function To(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}je(To,"setRef");function cc(...e){let t=D(e);return t.current=e,W(r=>{let n=t.current,o=!1,i=n.map(a=>{let l=To(a,r);return!o&&typeof l=="function"&&(o=!0),l});if(o)return()=>{for(let a=0;a_m(e,"name",{value:t,configurable:!0}),Eo="Tabs",[wm,PC]=Ve(Eo,[ko]),fc=ko(),[Rm,No]=wm(Eo),Cm=M(kt(function(t,r){let{__scopeTabs:n,value:o,onValueChange:i,defaultValue:a,orientation:l="horizontal",dir:c,activationMode:u="automatic",...p}=t,d=er(c),[f,m]=Zt({prop:o,onChange:i,defaultProp:a??"",caller:Eo});return s(Rm,{scope:n,baseId:Qt(),value:f,onValueChange:m,orientation:l,dir:d,activationMode:u,children:s(rt.div,{dir:d,"data-orientation":l,...p,ref:r})})},"Tabs")),km="TabsList",Sm=M(kt(function(t,r){let{__scopeTabs:n,loop:o=!0,...i}=t,a=No(km,n),l=fc(n);return s(oc,{asChild:!0,...l,orientation:a.orientation,dir:a.dir,loop:o,children:s(rt.div,{role:"tablist","aria-orientation":a.orientation,...i,ref:r})})},"TabsList")),Tm="TabsTrigger",Em=M(kt(function(t,r){let{__scopeTabs:n,value:o,disabled:i=!1,...a}=t,l=No(Tm,n),c=fc(n),u=Io(l.baseId,o),p=Po(l.baseId,o),d=o===l.value;return s(sc,{asChild:!0,...c,focusable:!i,active:d,children:s(rt.button,{type:"button",role:"tab","aria-selected":d,"aria-controls":p,"data-state":d?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:u,...a,ref:r,onMouseDown:he(t.onMouseDown,f=>{!i&&f.button===0&&f.ctrlKey===!1?l.onValueChange(o):f.preventDefault()}),onKeyDown:he(t.onKeyDown,f=>{i||f.target!==f.currentTarget||[" ","Enter"].includes(f.key)&&l.onValueChange(o)}),onFocus:he(t.onFocus,()=>{let f=l.activationMode!=="manual";!d&&!i&&f&&l.onValueChange(o)})})})},"TabsTrigger")),Nm="TabsContent",Im=M(kt(function(t,r){let{__scopeTabs:n,value:o,forceMount:i,children:a,...l}=t,c=No(Nm,n),u=Io(c.baseId,o),p=Po(c.baseId,o),d=o===c.value,f=D(d);return L(()=>{let m=requestAnimationFrame(()=>f.current=!1);return()=>cancelAnimationFrame(m)},[]),s(ac,{present:i||d,children:({present:m})=>s(rt.div,{"data-state":d?"active":"inactive","data-orientation":c.orientation,role:"tabpanel","aria-labelledby":u,hidden:!m,id:p,tabIndex:0,...l,ref:r,style:{...t.style,animationDuration:f.current?"0s":void 0},children:m&&a})})},"TabsContent"));function Io(e,t){return`${e}-trigger-${t}`}kt(Io,"makeTriggerId");function Po(e,t){return`${e}-content-${t}`}kt(Po,"makeContentId");var dc=Cm,Ao=Sm,Mo=Em,zo=Im;var an=dc,tr=M(({className:e,...t},r)=>s(Ao,{ref:r,className:N("inline-flex h-10 items-center justify-center rounded-md bg-slate-100 p-1 text-slate-500 dark:bg-slate-800 dark:text-slate-400",e),...t}));tr.displayName=Ao.displayName;var Pe=M(({className:e,...t},r)=>s(Mo,{ref:r,className:N("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-slate-950 data-[state=active]:shadow-sm dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300 dark:data-[state=active]:bg-slate-950 dark:data-[state=active]:text-slate-50",e),...t}));Pe.displayName=Mo.displayName;var Ae=M(({className:e,...t},r)=>s(zo,{ref:r,className:N("mt-2 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",e),...t}));Ae.displayName=zo.displayName;function gc({requestIds:e,allRequests:t,onClose:r}){let[n,o]=E([]),[i,a]=E(!0);if(L(()=>{let d=new AbortController;return a(!0),re.compareRequests(e,d.signal).then(f=>o(pc(e,f))).catch(f=>{f?.name!=="AbortError"&&(console.error("Failed to load comparison data:",f),o(pc(e,t)))}).finally(()=>{d.signal.aborted||a(!1)}),()=>d.abort()},[e]),i)return s("div",{className:"flex items-center justify-center h-64",children:s("div",{className:"text-muted-foreground",children:"Loading comparison..."})});if(n.length===0)return s("div",{className:"flex flex-col items-center justify-center h-64",children:[s("div",{className:"text-muted-foreground mb-4",children:"No requests found for comparison"}),s(Ie,{onClick:r,children:"Close"})]});let l=d=>d<1e3?`${d}ms`:`${(d/1e3).toFixed(2)}s`,c=d=>new Date(d).toLocaleString(),u=d=>d>=200&&d<300?"text-green-600":d>=300&&d<400?"text-blue-600":d>=400&&d<500?"text-yellow-600":d>=500?"text-red-600":"text-gray-600",p=(d,f,m)=>{let x=f.every(b=>b===f[0]);return s("tr",{children:[s("td",{className:"font-medium text-sm p-2 border-b",children:d}),f.map((b,y)=>s("td",{className:N("text-sm p-2 border-b",!x&&"bg-yellow-50 dark:bg-yellow-900/10",m?.(b)),children:b},y))]})};return s("div",{className:"space-y-4",children:[s("div",{className:"flex items-center justify-between mb-4",children:[s("h2",{className:"text-2xl font-bold",children:"Request Comparison"}),s(Ie,{onClick:r,variant:"outline",children:"Close"})]}),s(an,{defaultValue:"overview",className:"w-full",children:[s(tr,{className:"grid w-full grid-cols-4",children:[s(Pe,{value:"overview",children:"Overview"}),s(Pe,{value:"headers",children:"Headers"}),s(Pe,{value:"body",children:"Body"}),s(Pe,{value:"performance",children:"Performance"})]}),s(Ae,{value:"overview",className:"space-y-4",children:s(J,{children:[s(Z,{children:s(ee,{children:"Request Details"})}),s(se,{children:s("div",{className:"overflow-x-auto",children:s("table",{className:"w-full",children:[s("thead",{children:s("tr",{children:[s("th",{className:"text-left p-2 border-b",children:"Property"}),n.map((d,f)=>s("th",{className:"text-left p-2 border-b",children:["Request ",f+1]},d.ID))]})}),s("tbody",{children:[p("Method",n.map(d=>d.Method)),p("Path",n.map(d=>d.Path)),p("Query",n.map(d=>d.Query||"None")),p("Status",n.map(d=>d.StatusCode),d=>u(Number(d))),p("Duration",n.map(d=>l(d.Duration))),p("Timestamp",n.map(d=>c(d.Timestamp)))]})]})})})]})}),s(Ae,{value:"headers",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s(J,{children:[s(Z,{children:s(ee,{children:"Request Headers"})}),s(se,{children:s("div",{className:"space-y-4",children:n.map((d,f)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",f+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2 text-xs font-mono",children:Object.entries(d.RequestHeaders||{}).map(([m,x])=>s("div",{children:[s("span",{className:"text-blue-600",children:[m,":"]})," ",Array.isArray(x)?x.join(", "):x]},m))})]},d.ID))})})]}),s(J,{children:[s(Z,{children:s(ee,{children:"Response Headers"})}),s(se,{children:s("div",{className:"space-y-4",children:n.map((d,f)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",f+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2 text-xs font-mono",children:Object.entries(d.ResponseHeaders||{}).map(([m,x])=>s("div",{children:[s("span",{className:"text-green-600",children:[m,":"]})," ",Array.isArray(x)?x.join(", "):x]},m))})]},d.ID))})})]})]})}),s(Ae,{value:"body",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s(J,{children:[s(Z,{children:s(ee,{children:"Request Body"})}),s(se,{children:s("div",{className:"space-y-4",children:n.map((d,f)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",f+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2",children:s("pre",{className:"text-xs overflow-x-auto",children:d.RequestBody||"No request body"})})]},d.ID))})})]}),s(J,{children:[s(Z,{children:s(ee,{children:"Response Body"})}),s(se,{children:s("div",{className:"space-y-4",children:n.map((d,f)=>s("div",{children:[s("h4",{className:"font-medium mb-2",children:["Request ",f+1]}),s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-2",children:s("pre",{className:"text-xs overflow-x-auto max-h-48 overflow-y-auto",children:d.ResponseBody||"No response body"})})]},d.ID))})})]})]})}),s(Ae,{value:"performance",className:"space-y-4",children:s(J,{children:[s(Z,{children:s(ee,{children:"Performance Metrics"})}),s(se,{children:n.some(d=>d.PerformanceMetrics)?s("div",{className:"overflow-x-auto",children:s("table",{className:"w-full",children:[s("thead",{children:s("tr",{children:[s("th",{className:"text-left p-2 border-b",children:"Metric"}),n.map((d,f)=>s("th",{className:"text-left p-2 border-b",children:["Request ",f+1]},d.ID))]})}),s("tbody",{children:[p("Profile window",n.map(d=>d.PerformanceMetrics?mc(d.PerformanceMetrics.duration):"N/A")),p("Allocated during window",n.map(d=>d.PerformanceMetrics?hc(d.PerformanceMetrics.memory_total_alloc):"N/A")),p("Process heap",n.map(d=>d.PerformanceMetrics?hc(d.PerformanceMetrics.memory_alloc):"N/A")),p("Process goroutines",n.map(d=>d.PerformanceMetrics?.num_goroutines??"N/A")),p("GC runs",n.map(d=>d.PerformanceMetrics?.num_gc??"N/A")),p("GC pause",n.map(d=>d.PerformanceMetrics?mc(d.PerformanceMetrics.gc_pause_total):"N/A"))]})]})}):s("div",{className:"text-center text-muted-foreground py-8",children:"No performance metrics available for these requests"})})]})})]})]})}function pc(e,t){let r=new Map(t.map(n=>[n.ID,n]));return e.flatMap(n=>{let o=r.get(n);return o?[o]:[]})}function mc(e){if(!e)return"0ms";let t=e/1e6;return t<1?`${Math.round(e/1e3)}\u03BCs`:t<1e3?`${t.toFixed(2)}ms`:`${(t/1e3).toFixed(2)}s`}function hc(e){if(!e)return"0 B";let t=["B","KB","MB","GB"],r=Math.min(Math.floor(Math.log(e)/Math.log(1024)),t.length-1);return`${(e/1024**r).toFixed(r===0?0:2)} ${t[r]}`}var Am=tn("inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-slate-900 text-slate-50 hover:bg-slate-900/80",secondary:"border-transparent bg-slate-100 text-slate-900 hover:bg-slate-100/80",destructive:"border-transparent bg-red-500 text-slate-50 hover:bg-red-500/80",outline:"text-slate-950"}},defaultVariants:{variant:"default"}});function xc({className:e,variant:t,...r}){return s("div",{className:N(Am({variant:t}),e),...r})}var rr=M(({className:e,type:t,...r},n)=>s("input",{type:t,className:N("flex h-10 w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-base ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-slate-950 placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-slate-800 dark:bg-slate-950 dark:ring-offset-slate-950 dark:file:text-slate-50 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",e),ref:n,...r}));rr.displayName="Input";var Mm="[redacted by govisual]",zm="...[truncated by govisual]";function bc({request:e,onClose:t}){let[r,n]=E((e.RawPath||e.Path)+(e.Query?`?${e.Query}`:"")),[o,i]=E(e.Method),[a,l]=E(()=>{let R={};return e.RequestHeaders&&Object.entries(e.RequestHeaders).forEach(([v,C])=>{let H=Array.isArray(C)?C[0]:C;H!==Mm&&(R[v]=H)}),R}),[c,u]=E(e.RequestBody||""),[p,d]=E(!1),[f,m]=E(null),[x,b]=E(null),y=!r.startsWith("/")||r.startsWith("//"),w=e.RequestBody?.endsWith(zm)&&c===e.RequestBody,_=async()=>{try{if(d(!0),b(null),y){b("Replay path must start with a single '/'.");return}if(w){b("The captured request body is truncated. Replace it with the complete body before replaying.");return}let R=await re.replayRequest({requestId:e.ID,method:o,path:r,headers:a,body:c});m(R)}catch(R){R instanceof Se?R.isNotFound&&R.body.includes("replay disabled")?b("Replay is disabled on the server. Enable it with govisual.WithReplayEnabled(true)."):R.isUnauthorized?b(`Replay rejected (${R.status}): ${R.body||"unauthorized"}`):b(`Replay failed (${R.status}): ${R.body||R.message}`):b(R instanceof Error?R.message:"Failed to replay request")}finally{d(!1)}},T=(R,v)=>{l(C=>({...C,[R]:v}))},P=()=>{let R=prompt("Enter header name:");R&&l(v=>({...v,[R]:""}))},z=R=>{l(v=>{let C={...v};return delete C[R],C})},O=R=>R>=200&&R<300?"bg-green-100 text-green-800":R>=300&&R<400?"bg-blue-100 text-blue-800":R>=400&&R<500?"bg-yellow-100 text-yellow-800":R>=500?"bg-red-100 text-red-800":"bg-gray-100 text-gray-800";return s("div",{className:"space-y-4",children:[s("div",{className:"flex items-center justify-between mb-4",children:[s("h2",{className:"text-2xl font-bold",children:"Replay Request"}),s(Ie,{onClick:t,variant:"outline",children:"Close"})]}),s(J,{children:[s(Z,{children:s(ee,{children:"Request Configuration"})}),s(se,{className:"space-y-4",children:[s("p",{className:"text-sm text-muted-foreground",children:["The server sends this to its configured replay base or the dashboard origin. You can change the method, path, headers, and body, but not the destination host.",e.Host?` Captured host: ${e.Host}.`:""]}),s("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s("div",{children:[s("label",{className:"text-sm font-medium mb-1 block",children:"Method"}),s("select",{value:o,onChange:R=>i(R.target.value),className:"w-full p-2 border rounded-md",children:[s("option",{value:"GET",children:"GET"}),s("option",{value:"POST",children:"POST"}),s("option",{value:"PUT",children:"PUT"}),s("option",{value:"PATCH",children:"PATCH"}),s("option",{value:"DELETE",children:"DELETE"}),s("option",{value:"HEAD",children:"HEAD"}),s("option",{value:"OPTIONS",children:"OPTIONS"})]})]}),s("div",{children:[s("label",{htmlFor:"replay-path",className:"text-sm font-medium mb-1 block",children:"Path"}),s(rr,{id:"replay-path",value:r,onChange:R=>n(R.currentTarget.value),placeholder:"/path?query=value","aria-invalid":y,"aria-describedby":x?"replay-error":void 0})]})]}),s("div",{children:[s("div",{className:"flex items-center justify-between mb-2",children:[s("label",{className:"text-sm font-medium",children:"Headers"}),s(Ie,{size:"sm",variant:"outline",onClick:P,children:"Add Header"})]}),s("div",{className:"space-y-2 max-h-48 overflow-y-auto",children:Object.entries(a).map(([R,v])=>s("div",{className:"flex items-center gap-2",children:[s(rr,{value:R,disabled:!0,className:"flex-1 font-mono text-sm"}),s(rr,{value:v,onChange:C=>T(R,C.currentTarget.value),placeholder:"Value",className:"flex-2 font-mono text-sm"}),s(Ie,{size:"sm",variant:"ghost",onClick:()=>z(R),className:"text-red-600 hover:text-red-700",children:"Remove"})]},R))})]}),s("div",{children:[s("label",{className:"text-sm font-medium mb-1 block",children:"Request Body"}),s("textarea",{value:c,onChange:R=>u(R.currentTarget.value),className:"w-full p-2 border rounded-md font-mono text-sm",rows:6,placeholder:"Enter request body (JSON, XML, etc.)"})]}),s("div",{className:"flex justify-end gap-2",children:[s(Ie,{onClick:t,variant:"outline",children:"Cancel"}),s(Ie,{onClick:_,disabled:p,className:N(p&&"opacity-50 cursor-not-allowed"),children:p?"Replaying...":"Send Request"})]})]})]}),x&&s(J,{className:"border-red-200 bg-red-50",role:"alert","aria-live":"assertive",children:[s(Z,{children:s(ee,{className:"text-red-800",children:"Error"})}),s(se,{children:s("p",{id:"replay-error",className:"text-red-700",children:x})})]}),f&&s(J,{children:[s(Z,{children:s(ee,{children:"Response"})}),s(se,{children:s(an,{defaultValue:"overview",className:"w-full",children:[s(tr,{children:[s(Pe,{value:"overview",children:"Overview"}),s(Pe,{value:"headers",children:"Headers"}),s(Pe,{value:"body",children:"Body"})]}),s(Ae,{value:"overview",className:"space-y-4",children:s("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Status"}),s("div",{className:"mt-1",children:s(xc,{className:O(f.statusCode),children:f.statusCode})})]}),s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Duration"}),s("div",{className:"mt-1 text-lg font-medium",children:[f.duration,"ms"]})]}),s("div",{children:[s("span",{className:"text-sm text-muted-foreground",children:"Original Request"}),s("div",{className:"mt-1 text-sm font-mono",children:f.originalRequest})]})]})}),s(Ae,{value:"headers",children:s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-4",children:s("div",{className:"space-y-1 text-sm font-mono",children:Object.entries(f.headers).map(([R,v])=>s("div",{children:[s("span",{className:"text-blue-600",children:[R,":"]})," ",s("span",{className:"text-gray-700 dark:text-gray-300",children:Array.isArray(v)?v.join(", "):v})]},R))})})}),s(Ae,{value:"body",children:s("div",{className:"bg-gray-50 dark:bg-gray-900 rounded p-4",children:[f.bodyTruncated&&s("p",{className:"mb-3 text-sm text-amber-700",role:"status",children:"Response body is truncated at 1 MiB."}),s("pre",{className:"text-sm font-mono overflow-x-auto max-h-96 overflow-y-auto",children:f.body})]})})]})})]})]})}var Lm={"5m":1e4,"15m":3e4,"1h":12e4,"6h":6e5,"24h":18e5,all:0},Om={"5m":5*6e4,"15m":15*6e4,"1h":60*6e4,"6h":360*6e4,"24h":1440*6e4,all:Number.POSITIVE_INFINITY};function _c({requests:e,onClearAll:t,onImport:r}){let[n,o]=E("15m"),i=$(()=>{if(n==="all")return e;let l=Date.now()-Om[n];return e.filter(c=>new Date(c.Timestamp).getTime()>=l)},[e,n]),a=$(()=>Dm(i),[i]);return s("main",{class:"flex-1 overflow-auto",children:[s("header",{class:"px-8 pt-6 pb-4 flex items-start justify-between gap-4 border-b border-zinc-200 bg-white",children:[s("div",{children:[s("h1",{class:"text-2xl font-semibold tracking-tight",children:"Analytics"}),s("p",{class:"text-sm text-zinc-500 mt-1",children:"Throughput, latency distribution, and per-endpoint breakdown."})]}),s("div",{class:"flex items-center gap-3",children:[s("div",{class:"flex items-center gap-1 bg-zinc-100 rounded-md p-0.5",children:["5m","15m","1h","6h","24h","all"].map(l=>s("button",{onClick:()=>o(l),class:N("text-xs px-2.5 py-1 rounded",n===l?"bg-white text-zinc-900 shadow-sm font-medium":"text-zinc-500 hover:text-zinc-900"),children:l},l))}),s(Xm,{requests:i,onImport:r}),s("button",{onClick:t,class:"text-xs text-red-700 border border-red-200 rounded-md px-2.5 py-1.5 hover:bg-red-50",children:"Clear all"})]})]}),s("div",{class:"px-8 py-6 space-y-6",children:i.length===0?s(Ym,{range:n}):s(h,{children:[s(Fm,{s:a}),s("div",{class:"grid grid-cols-3 gap-4",children:[s(Hm,{requests:i,range:n}),s(Gm,{s:a})]}),s(Um,{requests:i}),s(jm,{requests:i})]})})]})}function Dm(e){let t=e.length;if(t===0)return{total:0,twoXX:0,threeXX:0,fourXX:0,fiveXX:0,errorRate:0,p50:0,p95:0,p99:0,max:0,rps:0,windowSec:0};let r=0,n=0,o=0,i=0;for(let d of e)d.StatusCode>=200&&d.StatusCode<300?r++:d.StatusCode<400?n++:d.StatusCode<500?o++:i++;let a=e.map(d=>d.Duration).sort((d,f)=>d-f),l=d=>a[Math.min(a.length-1,Math.floor(a.length*d))],c=e.map(d=>new Date(d.Timestamp).getTime()),u=(Math.max(...c)-Math.min(...c))/1e3,p=Math.max(u,1);return{total:t,twoXX:r,threeXX:n,fourXX:o,fiveXX:i,errorRate:(o+i)/t,p50:l(.5),p95:l(.95),p99:l(.99),max:a[a.length-1],rps:t/p,windowSec:p}}function Fm({s:e}){return s("section",{class:"grid grid-cols-6 gap-3",children:[s(St,{label:"Total",value:e.total.toLocaleString(),sub:`${e.rps.toFixed(2)} rps`,accent:"dark"}),s(St,{label:"Error rate",value:`${(e.errorRate*100).toFixed(1)}%`,sub:`${e.fourXX+e.fiveXX} of ${e.total}`,accent:e.errorRate>.05?"red":"default"}),s(St,{label:"p50",value:nt(e.p50)}),s(St,{label:"p95",value:nt(e.p95),accent:e.p95>500?"amber":"default"}),s(St,{label:"p99",value:nt(e.p99),accent:e.p99>1e3?"amber":"default"}),s(St,{label:"Max",value:nt(e.max)})]})}function St({label:e,value:t,sub:r,accent:n}){return s("div",{class:"bg-white border border-zinc-200 rounded-xl p-4",children:[s("div",{class:"text-[11px] uppercase tracking-wide text-zinc-500 mb-1",children:e}),s("div",{class:N("text-2xl font-semibold tabular-nums",n==="dark"?"text-zinc-900":n==="red"?"text-red-700":n==="amber"?"text-amber-700":"text-zinc-900"),children:t}),r&&s("div",{class:"text-[11px] text-zinc-500 mt-1",children:r})]})}function nt(e){return isFinite(e)?e<1?"<1ms":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(2)}s`:"\u2014"}function Hm({requests:e,range:t}){let r=$(()=>Bm(e,t),[e,t]);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5 col-span-2 flex flex-col",children:[s("header",{class:"flex items-center justify-between mb-4",children:[s("div",{children:[s("h3",{class:"text-sm font-semibold",children:"Throughput"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Requests per bucket \xB7 errors overlaid"})]}),s(qm,{})]}),s("div",{class:"flex-1 min-h-[240px]",children:s($m,{data:r})})]})}function Bm(e,t){if(e.length===0)return[];let r=e.map(p=>new Date(p.Timestamp).getTime()),n=Math.min(...r),o=Math.max(...r),i=Lm[t];i===0&&(i=Math.max(1e3,Math.ceil((o-n)/40)));let a=Math.floor(n/i)*i,l=Math.ceil((o+1)/i)*i,c=Math.max(1,Math.min(120,Math.round((l-a)/i))),u=Array.from({length:c},(p,d)=>({t:a+d*i,total:0,errors:0}));for(let p of e){let d=Math.min(c-1,Math.floor((new Date(p.Timestamp).getTime()-a)/i));d>=0&&(u[d].total++,p.StatusCode>=400&&u[d].errors++)}return u}function $m({data:e}){if(e.length===0)return s("div",{class:"text-center text-xs text-zinc-500 py-12",children:"No traffic in the selected range."});let t=800,r=220,n=40,o=8,i=12,a=24,l=t-n-o,c=r-i-a,u=Math.max(1,...e.map(w=>w.total)),p=w=>i+(1-w/u)*c,d=l/e.length,f=Math.max(2,Math.min(d-1,24)),m=e.map((w,_)=>{if(w.total===0)return null;let T=n+_*d+(d-f)/2,P=i+c-p(w.total),z=i+c-p(w.errors),O=P-z,R=p(w.total);return s("g",{children:[O>0&&s("rect",{x:T,y:p(w.total),width:f,height:P-z,fill:"#18181b",opacity:.78,children:s("title",{children:`${Lo(w.t)} \xB7 ${w.total} req${w.total===1?"":"s"}`})}),w.errors>0&&s("rect",{x:T,y:R,width:f,height:z,fill:"#ef4444",children:s("title",{children:`${Lo(w.t)} \xB7 ${w.errors} error${w.errors===1?"":"s"}`})})]},_)}),x=u<=2?[0,u]:[0,Math.round(u/2),u],b=Math.min(3,e.length),y=Array.from({length:b},(w,_)=>{let T=Math.round(_/Math.max(1,b-1)*(e.length-1));return{x:n+T*d+d/2,label:Lo(e[T].t),anchor:_===0?"start":_===b-1?"end":"middle"}});return s("svg",{viewBox:`0 0 ${t} ${r}`,class:"w-full h-full",children:[x.map((w,_)=>s("g",{children:[s("line",{x1:n,y1:p(w),x2:t-o,y2:p(w),stroke:"#f4f4f5"}),s("text",{x:n-6,y:p(w)+3,"text-anchor":"end","font-size":"10",fill:"#71717a",children:w})]},_)),m,y.map((w,_)=>s("text",{x:w.x,y:r-8,"text-anchor":w.anchor,"font-size":"10",fill:"#71717a",children:w.label},_))]})}function Lo(e){let t=new Date(e),r=t.getHours().toString().padStart(2,"0"),n=t.getMinutes().toString().padStart(2,"0"),o=t.getSeconds().toString().padStart(2,"0");return`${r}:${n}:${o}`}function qm(){return s("div",{class:"flex items-center gap-4 text-[11px] text-zinc-500",children:[s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:"w-2.5 h-2.5 rounded-sm bg-zinc-900/80"}),"Requests"]}),s("span",{class:"flex items-center gap-1.5",children:[s("span",{class:"w-2.5 h-2.5 rounded-sm bg-red-500"}),"Errors"]})]})}function Gm({s:e}){let t=[{label:"2xx",value:e.twoXX,color:"#10b981"},{label:"3xx",value:e.threeXX,color:"#f59e0b"},{label:"4xx",value:e.fourXX,color:"#f97316"},{label:"5xx",value:e.fiveXX,color:"#ef4444"}],r=t.reduce((n,o)=>n+o.value,0);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5 flex flex-col",children:[s("header",{class:"mb-4",children:[s("h3",{class:"text-sm font-semibold",children:"Status"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"By response class"})]}),s("div",{class:"flex items-center gap-5",children:[s(Vm,{segments:t,total:r}),s("div",{class:"flex-1 space-y-1.5",children:t.map(n=>{let o=r===0?0:n.value/r*100;return s("div",{class:"flex items-center gap-2 text-xs",children:[s("span",{class:"w-2 h-2 rounded-sm shrink-0",style:{background:n.color}}),s("span",{class:"text-zinc-500 w-8",children:n.label}),s("span",{class:"flex-1 text-right font-mono tabular-nums",children:n.value}),s("span",{class:"text-zinc-500 font-mono tabular-nums w-12 text-right",children:[o.toFixed(0),"%"]})]},n.label)})})]})]})}function Vm({segments:e,total:t}){let n=2*Math.PI*36,o=0;return s("div",{class:"relative shrink-0",children:[s("svg",{width:"100",height:"100",viewBox:"0 0 100 100",class:"-rotate-90",children:[s("circle",{cx:"50",cy:"50",r:36,fill:"none",stroke:"#f4f4f5","stroke-width":"12"}),e.map((i,a)=>{if(t===0||i.value===0)return null;let l=i.value/t*n,c=-o;return o+=l,s("circle",{cx:"50",cy:"50",r:36,fill:"none",stroke:i.color,"stroke-width":"12","stroke-dasharray":`${l} ${n-l}`,"stroke-dashoffset":c},a)})]}),s("div",{class:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[s("span",{class:"text-lg font-semibold tabular-nums",children:t}),s("span",{class:"text-[10px] text-zinc-500 uppercase tracking-wide",children:"total"})]})]})}var Oo=[{label:"<10ms",from:0,to:10},{label:"10\u201350ms",from:10,to:50},{label:"50\u2013100ms",from:50,to:100},{label:"100\u2013200ms",from:100,to:200},{label:"200\u2013500ms",from:200,to:500},{label:"500ms\u20131s",from:500,to:1e3},{label:"1\u20132s",from:1e3,to:2e3},{label:"2\u20135s",from:2e3,to:5e3},{label:">5s",from:5e3,to:Number.POSITIVE_INFINITY}];function Um({requests:e}){let t=$(()=>{let n=new Array(Oo.length).fill(0);for(let o of e){let i=Oo.findIndex(a=>o.Duration>=a.from&&o.Duration=0&&n[i]++}return n},[e]),r=Math.max(1,...t);return s("section",{class:"bg-white border border-zinc-200 rounded-xl p-5",children:[s("header",{class:"mb-4",children:[s("h3",{class:"text-sm font-semibold",children:"Latency distribution"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Where requests fall on the response-time spectrum"})]}),s("div",{class:"grid grid-cols-9 gap-2 items-end h-32",children:t.map((n,o)=>{let i=n/r*100;return s("div",{class:"flex flex-col items-center gap-1 h-full justify-end",children:[s("span",{class:"text-[10px] font-mono text-zinc-500 tabular-nums",children:n}),s("div",{class:N("w-full rounded-t",o<4?"bg-emerald-200":o<6?"bg-amber-300":"bg-red-400"),style:{height:`${i}%`,minHeight:n>0?"4px":"0"}})]},o)})}),s("div",{class:"grid grid-cols-9 gap-2 mt-2",children:Oo.map((n,o)=>s("div",{class:"text-[10px] text-zinc-500 text-center font-mono",children:n.label},o))})]})}function jm({requests:e}){let t=$(()=>{let r=new Map;for(let n of e){let o=`${n.Method} ${n.Path}`,i=r.get(o);i||(i={method:n.Method,path:n.Path,ds:[],errs:0},r.set(o,i)),i.ds.push(n.Duration),n.StatusCode>=400&&i.errs++}return Array.from(r.entries()).map(([n,o])=>{let i=[...o.ds].sort((l,c)=>l-c),a=l=>i[Math.min(i.length-1,Math.floor(i.length*l))];return{key:n,method:o.method,path:o.path,count:o.ds.length,p50:a(.5),p95:a(.95),p99:a(.99),max:i[i.length-1],errors:o.errs}}).sort((n,o)=>o.p95-n.p95)},[e]);return s("section",{class:"bg-white border border-zinc-200 rounded-xl overflow-hidden",children:[s("header",{class:"px-5 py-3 border-b border-zinc-200 flex items-center justify-between",children:[s("div",{children:[s("h3",{class:"text-sm font-semibold",children:"Endpoints"}),s("p",{class:"text-xs text-zinc-500 mt-0.5",children:"Sorted by p95, slowest first"})]}),s("span",{class:"text-xs text-zinc-500 font-mono",children:t.length})]}),s("div",{class:"overflow-x-auto",children:s("table",{class:"w-full text-sm",children:[s("thead",{class:"bg-zinc-50/60 border-b border-zinc-200",children:s("tr",{class:"text-left text-[11px] uppercase tracking-wide text-zinc-500",children:[s("th",{class:"px-5 py-2 font-medium",children:"Endpoint"}),s("th",{class:"px-3 py-2 font-medium text-right w-16",children:"Count"}),s("th",{class:"px-3 py-2 font-medium text-right w-16",children:"Err"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p50"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p95"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"p99"}),s("th",{class:"px-3 py-2 font-medium text-right w-20",children:"max"}),s("th",{class:"px-5 py-2 font-medium w-32",children:"Heat"})]})}),s("tbody",{class:"divide-y divide-zinc-100",children:t.slice(0,20).map(r=>{let n=Math.min(1,r.p95/1e3);return s("tr",{class:"hover:bg-zinc-50",children:[s("td",{class:"px-5 py-2",children:[s("span",{class:N("text-[10px] font-semibold mr-2",Wm(r.method)),children:r.method}),s("span",{class:"font-mono text-xs",children:r.path})]}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:r.count}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:r.errors>0?s("span",{class:"text-red-700",children:r.errors}):s("span",{class:"text-zinc-400",children:"0"})}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:nt(r.p50)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:nt(r.p95)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:nt(r.p99)}),s("td",{class:"px-3 py-2 text-right font-mono text-xs tabular-nums",children:nt(r.max)}),s("td",{class:"px-5 py-2",children:s("div",{class:"h-1.5 bg-zinc-100 rounded-full overflow-hidden",children:s("div",{class:N("h-1.5 rounded-full",n<.3?"bg-emerald-400":n<.7?"bg-amber-400":"bg-red-400"),style:{width:`${n*100}%`}})})})]},r.key)})})]})})]})}function Wm(e){switch(e){case"GET":return"text-blue-700";case"POST":return"text-emerald-700";case"PUT":case"PATCH":return"text-amber-700";case"DELETE":return"text-red-700";default:return"text-zinc-700"}}function Xm({requests:e,onImport:t}){let r=D(null),[n,o]=E(!1),[i,a]=E(""),l=()=>{let p=new Blob([re.exportRequests(e)],{type:"application/json"});vc(p,`govisual-${yc()}.json`),o(!1)},c=()=>{let p=["ID","Timestamp","Method","Path","Status","Duration (ms)","Error"],d=x=>`"${String(x??"").replace(/"/g,'""')}"`,f=e.map(x=>[x.ID,x.Timestamp,x.Method,x.Path,x.StatusCode,x.Duration,x.Error||""]),m=[p.map(d).join(","),...f.map(x=>x.map(d).join(","))].join(` +`);vc(new Blob([m],{type:"text/csv"}),`govisual-${yc()}.csv`),o(!1)},u=p=>{let d=p.target.files?.[0];if(!d)return;let f=new FileReader;f.onload=m=>{try{let x=re.importRequests(m.target?.result);t(x),a("imported")}catch(x){console.error("Import failed:",x),a("failed")}setTimeout(()=>a(""),2500)},f.readAsText(d),p.target.value=""};return s("div",{class:"relative",children:[s("button",{onClick:()=>o(p=>!p),class:"text-xs border border-zinc-200 rounded-md px-2.5 py-1.5 hover:bg-zinc-50 flex items-center gap-1.5",children:["Data",s("svg",{class:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:s("polyline",{points:"6 9 12 15 18 9"})})]}),n&&s(h,{children:[s("button",{class:"fixed inset-0 z-30 cursor-default",onClick:()=>o(!1),"aria-label":"Close menu"}),s("div",{class:"absolute right-0 top-full mt-1 w-44 bg-white border border-zinc-200 rounded-md shadow-md z-40 py-1",children:[s(Do,{onClick:l,label:"Export JSON",hint:`${e.length} rows`}),s(Do,{onClick:c,label:"Export CSV",hint:`${e.length} rows`}),s("div",{class:"h-px bg-zinc-100 my-1"}),s(Do,{onClick:()=>{o(!1),r.current?.click()},label:"Import JSON"})]})]}),i&&s("span",{class:N("absolute right-0 -bottom-6 text-[11px]",i==="imported"?"text-emerald-700":"text-red-700"),children:i==="imported"?"Imported \u2713":"Import failed"}),s("input",{ref:r,type:"file",accept:".json,application/json",class:"hidden",onChange:u})]})}function Do({onClick:e,label:t,hint:r}){return s("button",{onClick:e,class:"w-full px-3 py-1.5 text-left text-sm hover:bg-zinc-50 flex items-center justify-between",children:[s("span",{children:t}),r&&s("span",{class:"text-[11px] text-zinc-500 font-mono",children:r})]})}function vc(e,t){let r=URL.createObjectURL(e),n=document.createElement("a");n.href=r,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}function yc(){return new Date().toISOString().replace(/[:.]/g,"-").slice(0,19)}function Ym({range:e}){let t=e==="all"?"yet":`in the last ${e}`;return s("div",{class:"bg-white border border-zinc-200 rounded-xl py-16 px-8 text-center",children:[s("div",{class:"w-12 h-12 mx-auto rounded-full bg-zinc-100 flex items-center justify-center mb-3 text-zinc-400",children:s("svg",{class:"w-5 h-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",children:[s("line",{x1:"18",y1:"20",x2:"18",y2:"10"}),s("line",{x1:"12",y1:"20",x2:"12",y2:"4"}),s("line",{x1:"6",y1:"20",x2:"6",y2:"14"})]})}),s("h3",{class:"text-sm font-medium text-zinc-900",children:["No requests ",t]}),s("p",{class:"text-xs text-zinc-500 mt-1",children:"Generate some traffic and the charts will populate live."})]})}var Rc=200;function wc(e){return e.StatusCode>=400||!!e.Error?.trim()||!!e.PanicStack?.trim()}function Fo(e){let t=new Set;return e.filter(r=>t.has(r.ID)?!1:(t.add(r.ID),!0))}function Cc(){let[e,t]=E([]),[r,n]=E("inbox"),[o,i]=E(null),[a,l]=E(""),[c,u]=E(new Set),[p,d]=E([]),[f,m]=E(!1),[x,b]=E(null),[y,w]=E(!1);L(()=>{let v=new AbortController,C=!1;re.getRequests(v.signal).then(q=>{C||t(Fo(q))}).catch(q=>{q?.name!=="AbortError"&&console.error(q)});let H=re.subscribeToEvents(q=>{if(C=!0,w(!0),q.kind==="snapshot"){t(Fo(q.data));return}t(Y=>Fo([...q.data,...Y]))},()=>w(!1));return()=>{v.abort(),H.close()}},[]);let _=$(()=>{let v=e;if(r==="errors"?v=v.filter(wc):r==="slow"&&(v=v.filter(C=>C.Duration>=Rc)),c.size>0&&(v=v.filter(C=>{let H=Km(C.StatusCode);return H?c.has(H):!1})),a.trim()){let C=a.trim().toLowerCase();v=v.filter(H=>H.Path.toLowerCase().includes(C))}return v},[e,r,c,a]),T=$(()=>e.filter(wc).length,[e]);L(()=>{o&&(_.some(v=>v.ID===o.ID)||i(null))},[_,o?.ID]);let P=async()=>{try{await re.clearRequests(),t([]),i(null),d([])}catch(v){console.error("Failed to clear requests:",v)}},z=v=>{d(C=>C.includes(v.ID)?C.filter(H=>H!==v.ID):[...C,v.ID])};return s("div",{class:"h-screen bg-zinc-50 text-zinc-950 flex overflow-hidden",children:[s(Gs,{active:r,onChange:n,errorCount:T}),r==="inbox"||r==="errors"||r==="slow"?s(h,{children:[s(Vs,{title:Qm(r),subtitle:Jm(r),requests:_,selectedId:o?.ID,onSelect:i,statusFilter:c,onStatusFilterChange:u,search:a,onSearchChange:l,live:y}),s(Qa,{request:o,onReplay:v=>b(v),onCompareAdd:z,comparePending:o?p.includes(o.ID):!1})]}):r==="analytics"?s(_c,{requests:e,onClearAll:P,onImport:v=>{t(C=>{let H=[...C],q=new Set(H.map(Y=>Y.ID));for(let Y of v)q.has(Y.ID)||H.push(Y);return H})}}):r==="agents"?s(Ja,{}):s(Zm,{}),p.length>=2&&s("div",{class:"fixed left-1/2 -translate-x-1/2 bottom-6 bg-zinc-900 text-white rounded-full shadow-xl px-5 py-2.5 flex items-center gap-4 text-sm z-40",children:[s("span",{class:"font-medium",children:[p.length," selected"]}),s("div",{class:"w-px h-4 bg-white/20"}),s("button",{onClick:()=>m(!0),class:"hover:text-zinc-200",children:"Compare"}),s("button",{onClick:()=>d([]),class:"text-zinc-400 hover:text-white text-xs",children:"Clear"})]}),f&&s("div",{class:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-6",children:s("div",{class:"bg-white rounded-lg p-6 max-w-7xl w-full max-h-[90vh] overflow-auto",children:s(gc,{requestIds:p,allRequests:e,onClose:()=>{m(!1),d([])}})})}),x&&s("div",{class:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-6",children:s("div",{class:"bg-white rounded-lg p-6 max-w-4xl w-full max-h-[90vh] overflow-auto",children:s(bc,{request:x,onClose:()=>b(null)})})})]})}function Km(e){return e>=200&&e<300?"2xx":e>=300&&e<400?"3xx":e>=400&&e<500?"4xx":e>=500?"5xx":null}function Qm(e){switch(e){case"inbox":return"Inbox";case"errors":return"Errors";case"slow":return"Slow";case"analytics":return"Analytics";case"agents":return"Agents";case"environment":return"Environment"}}function Jm(e){switch(e){case"errors":return"HTTP errors, captured errors, and panics";case"slow":return`Duration \u2265 ${Rc}ms`;default:return}}function Zm(){return s("main",{class:"flex-1 overflow-auto",children:[s("header",{class:"px-8 pt-6 pb-4",children:[s("h1",{class:"text-2xl font-semibold tracking-tight",children:"Environment"}),s("p",{class:"text-sm text-zinc-500 mt-1",children:"Server runtime and explicitly allowlisted environment variables."})]}),s("div",{class:"px-8 pb-8",children:s(Sl,{})})]})}var kc=document.getElementById("app");kc?Xe(s(Cc,{}),kc):console.error("Could not find app root element");})(); diff --git a/internal/dashboard/static/styles.css b/internal/dashboard/static/styles.css index f5942a0..ec25969 100644 --- a/internal/dashboard/static/styles.css +++ b/internal/dashboard/static/styles.css @@ -2758,6 +2758,10 @@ html.dark .text-red-800 { .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } + + .lg\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } } .\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) { diff --git a/internal/dashboard/ui/README.md b/internal/dashboard/ui/README.md index 5ca3dcd..15600a5 100644 --- a/internal/dashboard/ui/README.md +++ b/internal/dashboard/ui/README.md @@ -1,67 +1,27 @@ -# GoVisual Dashboard (Preact) +# GoVisual Dashboard UI -Modern, fast dashboard built with Preact and shadcn-ui components. +The embedded GoVisual v2 dashboard is built with Preact, TypeScript, Tailwind CSS, Radix UI primitives, and esbuild. ## Development -### Prerequisites - -- Node.js 18+ -- npm or yarn - -### Setup +Use Node.js 22 and install the committed dependency graph: ```bash -# Install dependencies -npm install - -# Build for production +npm ci +npm run typecheck npm run build - -# Watch mode for development -npm run dev ``` -## Architecture - -- **Preact**: Lightweight React alternative (3KB) -- **shadcn-ui**: Modern, accessible UI components -- **Tailwind CSS**: Utility-first CSS framework -- **esbuild**: Fast JavaScript bundler -- **TypeScript**: Type safety - -## Project Structure - -``` -src/ -├── components/ -│ ├── ui/ # shadcn-ui components -│ ├── RequestTable.tsx # Request list component -│ ├── RequestDetails.tsx # Request details view -│ └── PerformanceProfiler.tsx # Performance profiling UI -├── lib/ -│ ├── api.ts # API client -│ └── utils.ts # Utility functions -├── App.tsx # Main application component -└── index.tsx # Entry point -``` - -## Features - -- **Real-time Updates**: Live request monitoring via SSE -- **Performance Profiling**: CPU, memory, and goroutine tracking -- **Flame Graphs**: Interactive D3.js visualization -- **Bottleneck Detection**: Automatic performance issue identification -- **Clean UI**: Modern, minimal design with no gradients -- **Fast**: Built with performance in mind +`npm run dev` watches JavaScript and TypeScript changes. Restart it after changing Tailwind classes or `src/styles.css` so the CSS is rebuilt too. -## Building for Production +Source files live under `src/`. The production build writes `dashboard.js` and `styles.css` to `../static/`; both files are committed because the Go dashboard handler embeds them. Include regenerated assets with every UI change. CI rebuilds the assets and fails if the committed output is stale. -The build process: +The main UI is organized around: -1. Compiles TypeScript to JavaScript -2. Bundles all dependencies with esbuild -3. Processes CSS with Tailwind -4. Outputs to `../static/` directory +- `App.tsx` for request state, SSE updates, filters, and top-level views +- `components/RequestList.tsx` and `components/DetailPane.tsx` for request inspection +- `components/RequestComparison.tsx` and `components/RequestReplay.tsx` for request actions +- `components/Analytics.tsx`, `AgentActivity.tsx`, and `EnvironmentInfo.tsx` for secondary views +- `lib/api.ts` for dashboard API and event-stream types -The Go backend embeds these static files for distribution. +The server sends request, replay-response, and top-level middleware-trace durations in milliseconds. Profiling, SQL, outbound HTTP, agent activity, and nested trace durations are Go `time.Duration` values encoded as nanoseconds; format them accordingly in the UI. diff --git a/internal/dashboard/ui/package-lock.json b/internal/dashboard/ui/package-lock.json new file mode 100644 index 0000000..60d91d2 --- /dev/null +++ b/internal/dashboard/ui/package-lock.json @@ -0,0 +1,3221 @@ +{ + "name": "govisual-dashboard", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "govisual-dashboard", + "version": "1.0.0", + "dependencies": { + "@preact/compat": "^18.3.1", + "@preact/signals": "^1.2.2", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.0", + "d3": "^7.8.5", + "lucide-preact": "^0.544.0", + "lucide-react": "^0.544.0", + "preact": "^10.19.3", + "tailwind-merge": "^3.3.1", + "vaul": "^1.1.2" + }, + "devDependencies": { + "@types/d3": "^7.4.3", + "esbuild": "^0.28.2", + "tailwindcss": "^3.4.0", + "typescript": "^5.3.3" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.3.0.tgz", + "integrity": "sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.8.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@preact/compat": { + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@preact/compat/-/compat-18.3.2.tgz", + "integrity": "sha512-5vSl55K5yLMvocT7PBKxDOHGgYPjMrKQqqr6roSNjIXcJOtSgDDMjpiCAF3s7klRdmGrN75b/Przmjw8gmlg/w==", + "license": "MIT", + "peerDependencies": { + "preact": "*" + } + }, + "node_modules/@preact/signals": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.4.tgz", + "integrity": "sha512-TPMkStdT0QpSc8FpB63aOwXoSiZyIrPsP9Uj347KopdS6olZdAYeeird/5FZv/M1Yc1ge5qstub2o8VDbvkT4g==", + "license": "MIT", + "dependencies": { + "@preact/signals-core": "^1.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "preact": "10.x" + } + }, + "node_modules/@preact/signals-core": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.4.tgz", + "integrity": "sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz", + "integrity": "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.15.tgz", + "integrity": "sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.15.tgz", + "integrity": "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz", + "integrity": "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz", + "integrity": "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.4.tgz", + "integrity": "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz", + "integrity": "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-effect-event": "0.0.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz", + "integrity": "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz", + "integrity": "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.4", + "@radix-ui/rect": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz", + "integrity": "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz", + "integrity": "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz", + "integrity": "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.3.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.19.tgz", + "integrity": "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.15.tgz", + "integrity": "sha512-jOLO4lssEzWpoDu7G+Ze4VjwMRUBt291pnZD0gmalREZipnTX3wadQo7Fy48GCTfe14/YRN6rw/rOJqrE85Wxw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz", + "integrity": "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.21.tgz", + "integrity": "sha512-UKxJlZid7FVtsk/WTxj4i4uSEgj2Au+KBbS7SQyTlzMhhn+86Cz3tISZdTa87bfEfcuvZezf2ZsxD4xuEKtkog==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-use-controllable-state": "1.2.6" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.16.tgz", + "integrity": "sha512-6EamKFRRnlpdadndbZ6LMwycfwkwPte1B42hs6QA0gYhjaOKqW4PZ4pjaW9UrlDX5eVt/OjncE7BFTPL5nmZhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.11" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz", + "integrity": "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz", + "integrity": "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.4.tgz", + "integrity": "sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.11.tgz", + "integrity": "sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", + "license": "MIT" + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-65Emv9fQiQQqphLlRkuQ5ypPsOmWPhtBGCMv61JDPEPMvsx+gzhGf74yw1a78xFKPj6zw4AgQICJoQv0vK9M2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.4.tgz", + "integrity": "sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lucide-preact": { + "version": "0.544.0", + "resolved": "https://registry.npmjs.org/lucide-preact/-/lucide-preact-0.544.0.tgz", + "integrity": "sha512-1OYqlRfxlQ6fQ8/e39kiY1btdKGCljwDmYKgF/GnB0ytVYV+PZE5EXmKdA3/Pknqs5A5QQKX+sK9TD7knUzwuw==", + "license": "ISC", + "peerDependencies": { + "preact": "^10.5.13" + } + }, + "node_modules/lucide-react": { + "version": "0.544.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.544.0.tgz", + "integrity": "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "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/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "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/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.29.8", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz", + "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==", + "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/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.2.tgz", + "integrity": "sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT", + "peer": true + }, + "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/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + } + } +} diff --git a/internal/dashboard/ui/package.json b/internal/dashboard/ui/package.json index a079ac4..f0e7d39 100644 --- a/internal/dashboard/ui/package.json +++ b/internal/dashboard/ui/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@types/d3": "^7.4.3", - "esbuild": "^0.19.11", + "esbuild": "^0.28.2", "tailwindcss": "^3.4.0", "typescript": "^5.3.3" } diff --git a/internal/dashboard/ui/src/App.tsx b/internal/dashboard/ui/src/App.tsx index 3478a53..2428750 100644 --- a/internal/dashboard/ui/src/App.tsx +++ b/internal/dashboard/ui/src/App.tsx @@ -1,5 +1,5 @@ import { h, Fragment } from "preact"; -import { useEffect, useMemo, useRef, useState } from "preact/hooks"; +import { useEffect, useMemo, useState } from "preact/hooks"; import { api, RequestLog } from "./lib/api"; import { RailNav, View } from "./components/RailNav"; import { RequestList } from "./components/RequestList"; @@ -17,6 +17,23 @@ type StatusFilter = Set<"2xx" | "3xx" | "4xx" | "5xx">; // 200ms to be useful as a triage tool rather than a profiler. const SLOW_MS = 200; +function isErrorRequest(request: RequestLog): boolean { + return ( + request.StatusCode >= 400 || + Boolean(request.Error?.trim()) || + Boolean(request.PanicStack?.trim()) + ); +} + +function dedupeRequests(requests: RequestLog[]): RequestLog[] { + const seen = new Set(); + return requests.filter((request) => { + if (seen.has(request.ID)) return false; + seen.add(request.ID); + return true; + }); +} + export function App() { const [requests, setRequests] = useState([]); const [view, setView] = useState("inbox"); @@ -33,38 +50,30 @@ export function App() { const [replayRequest, setReplayRequest] = useState(null); const [live, setLive] = useState(false); - // Initial fetch + live subscription. The SSE callback uses refs to read the - // current filters/selection without resubscribing on every keystroke. - const searchRef = useRef(search); - const statusFilterRef = useRef(statusFilter); - const viewRef = useRef(view); - useEffect(() => { - searchRef.current = search; - }, [search]); - useEffect(() => { - statusFilterRef.current = statusFilter; - }, [statusFilter]); - useEffect(() => { - viewRef.current = view; - }, [view]); - + // Initial fetch + live subscription. useEffect(() => { const controller = new AbortController(); + // SSE sends an authoritative snapshot as soon as it connects. If that + // beats the REST request, do not let the older REST response overwrite it. + let receivedLiveEvent = false; api .getRequests(controller.signal) - .then((data) => setRequests(data)) + .then((data) => { + if (!receivedLiveEvent) setRequests(dedupeRequests(data)); + }) .catch((err) => { if (err?.name !== "AbortError") console.error(err); }); const es = api.subscribeToEvents( (event) => { + receivedLiveEvent = true; setLive(true); if (event.kind === "snapshot") { - setRequests(event.data); + setRequests(dedupeRequests(event.data)); return; } - setRequests((prev) => [...event.data, ...prev]); + setRequests((prev) => dedupeRequests([...event.data, ...prev])); }, () => setLive(false) ); @@ -80,7 +89,7 @@ export function App() { const filtered = useMemo(() => { let out = requests; if (view === "errors") { - out = out.filter((r) => r.StatusCode >= 400); + out = out.filter(isErrorRequest); } else if (view === "slow") { out = out.filter((r) => r.Duration >= SLOW_MS); } @@ -98,7 +107,7 @@ export function App() { }, [requests, view, statusFilter, search]); const errorCount = useMemo( - () => requests.filter((r) => r.StatusCode >= 400).length, + () => requests.filter(isErrorRequest).length, [requests] ); @@ -260,7 +269,7 @@ function titleFor(v: View): string { function subtitleFor(v: View): string | undefined { switch (v) { case "errors": - return "Status 4xx and 5xx"; + return "HTTP errors, captured errors, and panics"; case "slow": return `Duration ≥ ${SLOW_MS}ms`; default: diff --git a/internal/dashboard/ui/src/components/DetailPane.tsx b/internal/dashboard/ui/src/components/DetailPane.tsx index a98a68a..a61eb67 100644 --- a/internal/dashboard/ui/src/components/DetailPane.tsx +++ b/internal/dashboard/ui/src/components/DetailPane.tsx @@ -286,21 +286,44 @@ function formatBody(body?: string): string { } function copyAsCurl(req: RequestLog) { - const host = req.RequestHeaders?.Host?.[0] || "localhost"; - const url = `http://${host}${req.Path}${req.Query ? "?" + req.Query : ""}`; - const parts = [`curl -X ${req.Method} ${shellQuote(url)}`]; - for (const [k, values] of Object.entries(req.RequestHeaders || {})) { + const url = `${window.location.origin}${req.RawPath || req.Path}${req.Query ? "?" + req.Query : ""}`; + const parts = [`curl --request ${shellQuote(req.Method)} ${shellQuote(url)}`]; + const headers = safeReplayHeaders(req.RequestHeaders || {}); + for (const [k, values] of Object.entries(headers)) { for (const v of values) { parts.push(`-H ${shellQuote(`${k}: ${v}`)}`); } } if (req.RequestBody) { - parts.push(`-d ${shellQuote(req.RequestBody)}`); + parts.push(`--data-raw ${shellQuote(req.RequestBody)}`); } const cmd = parts.join(" \\\n "); navigator.clipboard.writeText(cmd).catch(() => {}); } +function safeReplayHeaders(headers: Record): Record { + const blocked = new Set([ + "connection", "content-length", "host", "keep-alive", + "proxy-authenticate", "proxy-authorization", "proxy-connection", "te", + "trailer", "transfer-encoding", "upgrade", + ]); + for (const [key, values] of Object.entries(headers)) { + if (key.toLowerCase() !== "connection") continue; + for (const value of values) { + for (const token of value.split(",")) blocked.add(token.trim().toLowerCase()); + } + } + return Object.fromEntries( + Object.entries(headers) + .filter(([key]) => !blocked.has(key.toLowerCase())) + .map(([key, values]) => [ + key, + values.filter((value) => value !== "[redacted by govisual]"), + ]) + .filter(([, values]) => values.length > 0) + ); +} + function shellQuote(s: string): string { return `'${s.replace(/'/g, "'\\''")}'`; } @@ -338,12 +361,14 @@ function Overview({ request }: { request: RequestLog }) { - {request.Error && ( + {(request.Error || request.PanicStack) && (

Error

-
-            {request.Error}
-          
+ {request.Error && ( +
+              {request.Error}
+            
+ )} {request.PanicStack && (
               {request.PanicStack}
@@ -607,20 +632,21 @@ function Performance({
   if (!metrics) {
     return (
       
- Profiling is not enabled. Pass{" "} + No retained profile exists for this request. Enable profiling with{" "} govisual.WithProfiling(true) {" "} - on the server to see CPU and memory metrics here. + and check the configured profile threshold and profile types.
); } return ( -
- - - +
+ + + +
diff --git a/internal/dashboard/ui/src/components/FlameGraph.tsx b/internal/dashboard/ui/src/components/FlameGraph.tsx index d5a42cc..eb1ff47 100644 --- a/internal/dashboard/ui/src/components/FlameGraph.tsx +++ b/internal/dashboard/ui/src/components/FlameGraph.tsx @@ -41,7 +41,7 @@ export function FlameGraph({ .padding(1) .round(true); - partition(root); + const partitioned = partition(root); // Color scale const color = d3.scaleOrdinal(d3.schemeTableau10); @@ -49,7 +49,7 @@ export function FlameGraph({ // Create groups for each node const g = svg .selectAll("g") - .data(root.descendants()) + .data(partitioned.descendants()) .join("g") .attr("transform", (d) => `translate(${d.x0},${d.depth * cellHeight})`); @@ -67,7 +67,7 @@ export function FlameGraph({ .on("mouseover", function (event, d) { if (tooltipRef.current) { const percentage = ( - ((d.value || 0) / (root.value || 1)) * + ((d.value || 0) / (partitioned.value || 1)) * 100 ).toFixed(2); tooltipRef.current.innerHTML = ` diff --git a/internal/dashboard/ui/src/components/PerformanceProfiler.tsx b/internal/dashboard/ui/src/components/PerformanceProfiler.tsx index b3715ca..2c240ec 100644 --- a/internal/dashboard/ui/src/components/PerformanceProfiler.tsx +++ b/internal/dashboard/ui/src/components/PerformanceProfiler.tsx @@ -100,18 +100,20 @@ export function PerformanceProfiler({ {/* Metrics Summary Cards */} -
+
-
CPU Time
+
+ Allocated during window +
- {formatDuration(metrics.cpu_time)} + {formatBytes(metrics.memory_total_alloc)}
-
Memory
+
Process heap
{formatBytes(metrics.memory_alloc)}
@@ -119,15 +121,29 @@ export function PerformanceProfiler({
-
Goroutines
+
+ Process goroutines +
+
+ {metrics.num_goroutines ?? 0} +
+
+
+ + +
+ GC runs +
- {metrics.num_goroutines || 0} + {metrics.num_gc ?? 0}
-
GC Pauses
+
+ GC pause +
{formatDuration(metrics.gc_pause_total)}
@@ -138,7 +154,7 @@ export function PerformanceProfiler({ { + onValueChange={(value: string) => { if (value === "flamegraph") { loadFlameGraph(); } diff --git a/internal/dashboard/ui/src/components/RequestComparison.tsx b/internal/dashboard/ui/src/components/RequestComparison.tsx index 1f3d3d7..7b81a54 100644 --- a/internal/dashboard/ui/src/components/RequestComparison.tsx +++ b/internal/dashboard/ui/src/components/RequestComparison.tsx @@ -3,7 +3,6 @@ import { useState, useEffect } from "preact/hooks"; import { api, RequestLog } from "../lib/api"; import { Card, CardContent, CardHeader, CardTitle } from "./ui/card"; import { Button } from "./ui/button"; -import { Badge } from "./ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs"; import { cn } from "../lib/utils"; @@ -22,25 +21,22 @@ export function RequestComparison({ const [loading, setLoading] = useState(true); useEffect(() => { - loadComparisonData(); - }, [requestIds]); + const controller = new AbortController(); + setLoading(true); + api + .compareRequests(requestIds, controller.signal) + .then((data) => setCompareRequests(orderByIds(requestIds, data))) + .catch((error) => { + if (error?.name === "AbortError") return; + console.error("Failed to load comparison data:", error); + setCompareRequests(orderByIds(requestIds, allRequests)); + }) + .finally(() => { + if (!controller.signal.aborted) setLoading(false); + }); - const loadComparisonData = async () => { - try { - setLoading(true); - const data = await api.compareRequests(requestIds); - setCompareRequests(data); - } catch (error) { - console.error("Failed to load comparison data:", error); - // Fallback to local data - const localData = allRequests.filter((req) => - requestIds.includes(req.ID) - ); - setCompareRequests(localData); - } finally { - setLoading(false); - } - }; + return () => controller.abort(); + }, [requestIds]); if (loading) { return ( @@ -78,10 +74,12 @@ export function RequestComparison({ return "text-gray-600"; }; - const renderComparisonRow = (label: string, values: any[]) => { - const allSame = values.every( - (v) => JSON.stringify(v) === JSON.stringify(values[0]) - ); + const renderComparisonRow = ( + label: string, + values: Array, + valueClass?: (value: string | number) => string + ) => { + const allSame = values.every((value) => value === values[0]); return ( @@ -91,10 +89,11 @@ export function RequestComparison({ key={idx} className={cn( "text-sm p-2 border-b", - !allSame && "bg-yellow-50 dark:bg-yellow-900/10" + !allSame && "bg-yellow-50 dark:bg-yellow-900/10", + valueClass?.(value) )} > - {typeof value === "object" ? JSON.stringify(value, null, 2) : value} + {value} ))} @@ -130,7 +129,7 @@ export function RequestComparison({ Property {compareRequests.map((req, idx) => ( - + Request {idx + 1} ))} @@ -151,11 +150,8 @@ export function RequestComparison({ )} {renderComparisonRow( "Status", - compareRequests.map((r) => ( - - {r.StatusCode} - - )) + compareRequests.map((r) => r.StatusCode), + (value) => getStatusColor(Number(value)) )} {renderComparisonRow( "Duration", @@ -181,7 +177,7 @@ export function RequestComparison({
{compareRequests.map((req, idx) => ( -
+

Request {idx + 1}

{Object.entries(req.RequestHeaders || {}).map( @@ -208,7 +204,7 @@ export function RequestComparison({
{compareRequests.map((req, idx) => ( -
+

Request {idx + 1}

{Object.entries(req.ResponseHeaders || {}).map( @@ -239,7 +235,7 @@ export function RequestComparison({
{compareRequests.map((req, idx) => ( -
+

Request {idx + 1}

@@ -259,7 +255,7 @@ export function RequestComparison({
               
                 
{compareRequests.map((req, idx) => ( -
+

Request {idx + 1}

@@ -287,7 +283,7 @@ export function RequestComparison({
                       
                         Metric
                         {compareRequests.map((req, idx) => (
-                          
+                          
                             Request {idx + 1}
                           
                         ))}
@@ -295,42 +291,46 @@ export function RequestComparison({
                     
                     
                       {renderComparisonRow(
-                        "CPU Time",
+                        "Profile window",
                         compareRequests.map((r) =>
                           r.PerformanceMetrics
-                            ? `${r.PerformanceMetrics.cpu_time}ms`
+                            ? formatNanoseconds(r.PerformanceMetrics.duration)
                             : "N/A"
                         )
                       )}
                       {renderComparisonRow(
-                        "Memory Allocated",
+                        "Allocated during window",
                         compareRequests.map((r) =>
                           r.PerformanceMetrics
-                            ? `${(
-                                r.PerformanceMetrics.memory_alloc /
-                                1024 /
-                                1024
-                              ).toFixed(2)}MB`
+                            ? formatBytes(r.PerformanceMetrics.memory_total_alloc)
                             : "N/A"
                         )
                       )}
                       {renderComparisonRow(
-                        "Goroutines",
+                        "Process heap",
+                        compareRequests.map((r) =>
+                          r.PerformanceMetrics
+                            ? formatBytes(r.PerformanceMetrics.memory_alloc)
+                            : "N/A"
+                        )
+                      )}
+                      {renderComparisonRow(
+                        "Process goroutines",
                         compareRequests.map(
-                          (r) => r.PerformanceMetrics?.num_goroutines || "N/A"
+                          (r) => r.PerformanceMetrics?.num_goroutines ?? "N/A"
                         )
                       )}
                       {renderComparisonRow(
-                        "GC Runs",
+                        "GC runs",
                         compareRequests.map(
-                          (r) => r.PerformanceMetrics?.num_gc || "N/A"
+                          (r) => r.PerformanceMetrics?.num_gc ?? "N/A"
                         )
                       )}
                       {renderComparisonRow(
-                        "GC Pause",
+                        "GC pause",
                         compareRequests.map((r) =>
                           r.PerformanceMetrics
-                            ? `${r.PerformanceMetrics.gc_pause_total}ms`
+                            ? formatNanoseconds(r.PerformanceMetrics.gc_pause_total)
                             : "N/A"
                         )
                       )}
@@ -349,3 +349,29 @@ export function RequestComparison({
     
); } + +function orderByIds(ids: string[], requests: RequestLog[]): RequestLog[] { + const byId = new Map(requests.map((request) => [request.ID, request])); + return ids.flatMap((id) => { + const request = byId.get(id); + return request ? [request] : []; + }); +} + +function formatNanoseconds(ns: number): string { + if (!ns) return "0ms"; + const ms = ns / 1_000_000; + if (ms < 1) return `${Math.round(ns / 1_000)}μs`; + if (ms < 1_000) return `${ms.toFixed(2)}ms`; + return `${(ms / 1_000).toFixed(2)}s`; +} + +function formatBytes(bytes: number): string { + if (!bytes) return "0 B"; + const units = ["B", "KB", "MB", "GB"]; + const unit = Math.min( + Math.floor(Math.log(bytes) / Math.log(1024)), + units.length - 1 + ); + return `${(bytes / 1024 ** unit).toFixed(unit === 0 ? 0 : 2)} ${units[unit]}`; +} diff --git a/internal/dashboard/ui/src/components/RequestReplay.tsx b/internal/dashboard/ui/src/components/RequestReplay.tsx index 52b3a57..e4753fe 100644 --- a/internal/dashboard/ui/src/components/RequestReplay.tsx +++ b/internal/dashboard/ui/src/components/RequestReplay.tsx @@ -1,4 +1,4 @@ -import { h } from "preact"; +import { h, type TargetedEvent } from "preact"; import { useState } from "preact/hooks"; import { api, ApiError, RequestLog, ReplayResponse } from "../lib/api"; import { Card, CardContent, CardHeader, CardTitle } from "./ui/card"; @@ -13,9 +13,12 @@ interface RequestReplayProps { onClose: () => void; } +const REDACTED_HEADER_VALUE = "[redacted by govisual]"; +const TRUNCATION_MARKER = "...[truncated by govisual]"; + export function RequestReplay({ request, onClose }: RequestReplayProps) { - const [replayUrl, setReplayUrl] = useState( - request.Path + (request.Query ? `?${request.Query}` : "") + const [replayPath, setReplayPath] = useState( + (request.RawPath || request.Path) + (request.Query ? `?${request.Query}` : "") ); const [replayMethod, setReplayMethod] = useState(request.Method); const [replayHeaders, setReplayHeaders] = useState>( @@ -23,7 +26,8 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) { const headers: Record = {}; if (request.RequestHeaders) { Object.entries(request.RequestHeaders).forEach(([key, values]) => { - headers[key] = Array.isArray(values) ? values[0] : values; + const value = Array.isArray(values) ? values[0] : values; + if (value !== REDACTED_HEADER_VALUE) headers[key] = value; }); } return headers; @@ -35,30 +39,32 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) { null ); const [replayError, setReplayError] = useState(null); + const replayPathInvalid = + !replayPath.startsWith("/") || replayPath.startsWith("//"); + const replayBodyStillTruncated = + request.RequestBody?.endsWith(TRUNCATION_MARKER) && + replayBody === request.RequestBody; const handleReplay = async () => { try { setIsReplaying(true); setReplayError(null); - // Build full URL if needed - let fullUrl = replayUrl; - if (!fullUrl.startsWith("http")) { - // Try to extract host from original request headers - const hostHeader = request.RequestHeaders?.["Host"]; - const host = hostHeader - ? Array.isArray(hostHeader) - ? hostHeader[0] - : hostHeader - : "localhost"; - const protocol = "http://"; // Default to http, could be made configurable - fullUrl = protocol + host + fullUrl; + if (replayPathInvalid) { + setReplayError("Replay path must start with a single '/'."); + return; + } + if (replayBodyStillTruncated) { + setReplayError( + "The captured request body is truncated. Replace it with the complete body before replaying." + ); + return; } const response = await api.replayRequest({ requestId: request.ID, - url: fullUrl, method: replayMethod, + path: replayPath, headers: replayHeaders, body: replayBody, }); @@ -66,7 +72,7 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) { setReplayResponse(response); } catch (error) { if (error instanceof ApiError) { - if (error.isNotFound) { + if (error.isNotFound && error.body.includes("replay disabled")) { setReplayError( "Replay is disabled on the server. Enable it with " + "govisual.WithReplayEnabled(true)." @@ -137,6 +143,12 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) { Request Configuration +

+ The server sends this to its configured replay base or the + dashboard origin. You can change the method, path, headers, and + body, but not the destination host. + {request.Host ? ` Captured host: ${request.Host}.` : ""} +

@@ -158,13 +170,18 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) {
- + - setReplayUrl((e.target as HTMLInputElement).value) + id="replay-path" + value={replayPath} + onChange={(e: TargetedEvent) => + setReplayPath(e.currentTarget.value) } - placeholder="Enter URL" + placeholder="/path?query=value" + aria-invalid={replayPathInvalid} + aria-describedby={replayError ? "replay-error" : undefined} />
@@ -186,10 +203,10 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) { /> + onChange={(e: TargetedEvent) => handleHeaderChange( key, - (e.target as HTMLInputElement).value + e.currentTarget.value ) } placeholder="Value" @@ -208,24 +225,20 @@ export function RequestReplay({ request, onClose }: RequestReplayProps) {
- {(replayMethod === "POST" || - replayMethod === "PUT" || - replayMethod === "PATCH") && ( -
- -